Add test_rdp_client for RDP tunneling testing

- Created test_rdp_client.c based on test_vnc_client.c
- Implements RDP protocol negotiation including Connection Request/Confirm
- Sends MCS Connect Initial and Client Info PDU with username
- Supports both wsssht --pipe tunneling and direct TCP connection with -p PORT
- Tests RDP connection and reports results in output
parent 599348b7
......@@ -567,6 +567,47 @@ for template in templates/*.html; do
// ${BASENAME} page HTML template
static const char *${BASENAME}_page_html __attribute__((used)) =
EOF
# Process the HTML file, escape quotes and backslashes
sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/\\n"/' "$template" >> "$HEADER_FILE"
elif [ "$BASENAME" = "rdp" ]; then
cat > "$HEADER_FILE" << EOF
/**
* ${BASENAME} page HTML template for wssshd
*
* Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef ${BASENAME^^}_PAGE_H
#define ${BASENAME^^}_PAGE_H
// ${BASENAME} page HTML template
static const char *${BASENAME}_page_html =
EOF
# Use python to properly escape the HTML
python3 -c "
import sys
with open('$template', 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
lines = content.split('\n')
for line in lines:
escaped_line = line.replace('\\\\', '\\\\\\\\').replace('\\\"', '\\\\\"').replace('%c%s', '%%c%%s')
print('\"' + escaped_line + '\\\\n\"')
" >> "$HEADER_FILE"
else
cat > "$HEADER_FILE" << EOF
/**
......@@ -594,10 +635,10 @@ EOF
// ${BASENAME} page HTML template
static const char *${BASENAME}_page_html =
EOF
fi
# Process the HTML file, escape quotes and backslashes
sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/\\n"/' "$template" >> "$HEADER_FILE"
# Process the HTML file, escape quotes and backslashes
sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/\\n"/' "$template" >> "$HEADER_FILE"
fi
# Close the string and header
cat >> "$HEADER_FILE" << EOF
......@@ -610,4 +651,4 @@ EOF
fi
done
echo "Assets embedded successfully"
\ No newline at end of file
echo "Assets embedded successfully"
This diff is collapsed.
This diff is collapsed.
......@@ -18,8 +18,8 @@
#include "html_pages/novnc_input_fixedkeys_js_page.h"
#include "html_pages/novnc_input_gesturehandler_js_page.h"
#include "html_pages/novnc_input_keyboard_js_page.h"
#include "html_pages/novnc_input_keysym_js_page.h"
#include "html_pages/novnc_input_keysymdef_js_page.h"
#include "html_pages/novnc_input_keysym_js_page.h"
#include "html_pages/novnc_input_util_js_page.h"
#include "html_pages/novnc_input_vkeys_js_page.h"
#include "html_pages/novnc_input_xtscancodes_js_page.h"
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -3,8 +3,8 @@
#include "html_pages/rdp_clipboard_js_page.h"
#include "html_pages/rdp_mstsc_js_page.h"
#include "html_pages/rdp_out_stream_js_page.h"
#include "html_pages/rdp_rdp_wasm_js_page.h"
#include "html_pages/rdp_rdp_graphics_js_page.h"
#include "html_pages/rdp_rdp_wasm_js_page.h"
#include "html_pages/rdp_reversed_layouts_js_page.h"
#include "html_pages/rdp_scancodes_js_page.h"
#include "html_pages/rdp_rdp_wasm_page.h"
......
......@@ -7,12 +7,13 @@
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="/rdpwasm/rdp.wasm.js"></script>
<script src="/rdpwasm/clipboard.js"></script>
<script src="/rdpwasm/out_stream.js"></script>
<script src="/rdpwasm/rdp_graphics.js"></script>
<script src="/rdpwasm/reversed_layouts.js"></script>
<script src="/rdpwasm/scancodes.js"></script>
<script src="/rdpwasm/reversed_layouts.js"></script>
<script src="/rdpwasm/rdp_graphics.js"></script>
<script src="/rdpwasm/out_stream.js"></script>
<script src="/rdpwasm/clipboard.js"></script>
<style>
.navbar-brand {
font-weight: bold;
......@@ -307,10 +308,7 @@
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
console.log('RDP page script starting...');
// init kbdlayout_input
let defaultLayoutId;
try {
......@@ -321,7 +319,7 @@ try {
const layout = layouts[i];
const displayName = layout.displayName;
const opt = document.createElement('option');
opt.textContent = `${layout.localeName} 0x${layout.klid.toString(16).padStart(5, '0')} (${displayName})`;
opt.textContent = layout.localeName + ' 0x' + layout.klid.toString(16).padStart(5, '0') + ' (' + displayName + ')';
opt.value = i;
if (displayName === 'United States - English') {
opt.selected = true;
......@@ -329,7 +327,6 @@ try {
}
// Since we don't have kbdlayout_input in this simplified version, we'll use default
}
console.log('Keyboard layouts initialized, defaultLayoutId:', defaultLayoutId);
} catch (error) {
console.error('Error initializing keyboard layouts:', error);
defaultLayoutId = 0; // fallback
......@@ -339,16 +336,13 @@ let kbdInputLayoutEvent = () => {};
let _Module = null;
console.log('Starting WebAssembly module loading...');
if (typeof WallixModule === 'undefined') {
console.error('WallixModule is not defined - rdp.wasm.js may not have loaded');
} else {
WallixModule({
// INITIAL_MEMORY: 16777216, // 16**6
// INITIAL_MEMORY: 268435456, // 16**7
}).then((Module) => {
console.log('WebAssembly module loaded successfully');
}).then((Module) => {
_Module = Module;
// optional
......@@ -370,33 +364,19 @@ if (typeof WallixModule === 'undefined') {
MouseFlags = _Module.MouseFlags;
InputFlags = _Module.InputFlags;
console.log('WebAssembly constants set:', { RdpClient: !!RdpClient, MouseFlags: !!MouseFlags, InputFlags: !!InputFlags });
}).catch((e) => {
}).catch((e) => {
console.error('Failed to load WebAssembly module:', e);
showNotification('Failed to load RDP WebAssembly module', 'danger');
});
});
}
console.log('After WallixModule setup');
// Constants will be set after module loads
let RdpClient, ClipboardChannel, MouseFlags, InputFlags;
// Define constants that will be available after module loads
const KeyAcquire = 0;
const KeyRelease = 0x80;
const SyncFlags = {
ShiftLeft: 0x01,
ShiftRight: 0x02,
ControlLeft: 0x04,
ControlRight: 0x08,
AltLeft: 0x10,
AltRight: 0x20,
OSLeft: 0x40,
OSRight: 0x80,
NumLock: 0x100,
CapsLock: 0x200,
KanaLock: 0x400,
ScrollLock: 0x800
};
// Constants are defined in scancodes.js
console.log('After constants');
function MultiSelectToInt(e, constants)
{
......@@ -559,7 +539,7 @@ class EmulatedKeyboard extends Keyboard
}
compositeKeyEvent(evt, text) {
if (!this._preprocessKeyEvent(evt, flag)) return;
if (!this._preprocessKeyEvent(evt, KeyAcquire)) return;
const scancodes = this._keymap.toScancodesAndFlags(text, text, KeyAcquire);
if (scancodes) {
......@@ -645,6 +625,7 @@ class UnicodeKeyboard extends Keyboard
}
}
}
console.log('After classes');
let rdpclient = null;
let socket = null;
......@@ -789,47 +770,28 @@ const maximizeBtn = document.querySelector('.maximize-btn');
const minimizeBtn = document.querySelector('.minimize-btn');
const zoomBtn = document.getElementById('zoomBtn');
console.log('DOM elements found:', {
connectBtn: !!connectBtn,
disconnectBtn: !!disconnectBtn,
cancelConnectBtn: !!cancelConnectBtn,
startRdpBtn: !!startRdpBtn,
closeBtn: !!closeBtn,
maximizeBtn: !!maximizeBtn,
minimizeBtn: !!minimizeBtn,
zoomBtn: !!zoomBtn
});
if (connectBtn) {
connectBtn.addEventListener('click', function(e) {
console.log('Connect button clicked');
showRdpConfig();
});
console.log('Connect button listener attached');
}
if (disconnectBtn) {
disconnectBtn.addEventListener('click', function(e) {
console.log('Disconnect button clicked');
disconnect();
});
console.log('Disconnect button listener attached');
}
if (cancelConnectBtn) {
cancelConnectBtn.addEventListener('click', function(e) {
console.log('Cancel connect button clicked');
cancelConnect();
});
console.log('Cancel connect button listener attached');
}
if (startRdpBtn) {
startRdpBtn.addEventListener('click', function(e) {
console.log('Start RDP button clicked');
startRdpConnection();
});
console.log('Start RDP button listener attached');
}
// Window control buttons
......@@ -865,8 +827,6 @@ if (zoomBtn) {
console.log('Zoom button listener attached');
}
console.log('Event listeners attachment completed');
// Input event handlers
let ecanvas = document.getElementById('canvas');
let ecanvasFocus = document.getElementById('canvasFocus');
......@@ -939,7 +899,6 @@ function toggleZoom() {
}
function showRdpConfig() {
console.log('showRdpConfig called, connected:', connected);
if (connected) return;
// Show the RDP configuration modal
......@@ -948,7 +907,6 @@ function showRdpConfig() {
}
function startRdpConnection() {
console.log('startRdpConnection called');
// Hide the modal
const modal = bootstrap.Modal.getInstance(document.getElementById('rdpConfigModal'));
modal.hide();
......@@ -1199,4 +1157,4 @@ function cancelConnect() {
}
</script>
</body>
</html>
\ No newline at end of file
</html>
This diff is collapsed.
......@@ -19,7 +19,3 @@ else if (typeof define === 'function' && define['amd'])
define([], function() { return WallixModule; });
else if (typeof exports === 'object')
exports["WallixModule"] = WallixModule;
else {
window.WallixModule = WallixModule;
window.Module = WallixModule;
}
......@@ -1417,7 +1417,7 @@ const newRdpGraphics = function(canvasElement, module, ropError) {
return ctx ? createCtx(ctx, newRdpPointer(canvasElement, module)) : undefined;
};
if (typeof module !== 'undefined' && module.exports) {
try {
module.exports.newRdpGraphics2D = newRdpGraphics2D;
module.exports.newRdpGraphicsGL = newRdpGraphicsGL;
module.exports.newRdpGraphicsGL2 = newRdpGraphicsGL2;
......@@ -1426,13 +1426,7 @@ if (typeof module !== 'undefined' && module.exports) {
module.exports.newRdpGL = newRdpGL;
module.exports.newRdpGL2 = newRdpGL2;
module.exports.newRdpPointer = newRdpPointer;
} else {
window.newRdpGraphics2D = newRdpGraphics2D;
window.newRdpGraphicsGL = newRdpGraphicsGL;
window.newRdpGraphicsGL2 = newRdpGraphicsGL2;
window.newRdpGraphics = newRdpGraphics;
window.newRdpCanvas = newRdpCanvas;
window.newRdpGL = newRdpGL;
window.newRdpGL2 = newRdpGL2;
window.newRdpPointer = newRdpPointer;
}
catch (e) {
// module not found
}
......@@ -2441,9 +2441,9 @@ static int handle_request(int client_fd, const http_request_t *req) {
return 0;
}
// Generate RDP HTML with client_id
char html[65536];
char html[262144];
int len = snprintf(html, sizeof(html), rdp_page_html,
client_id, client_id, client_id, client_id, client_id);
client_id, client_id, client_id, client_id);
// No CSP header for RDP pages to avoid blocking WebAssembly
send_response(client_fd, 200, "OK", "text/html", html, len, NULL, NULL);
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment