Fix bad descriptor in wsssh tunnel and add directional logging

- Prevent socket corruption in wsssh by avoiding accept() on already accepted sockets
- Update socket selection logic in handle_tunnel_data for wsssh
- Add directional debug logging in server to show message flow between tools
- Add [DEBUG - TOREMOVE] markers for easy identification and removal
parent a1300943
...@@ -470,6 +470,7 @@ async def handle_websocket(websocket, path=None): ...@@ -470,6 +470,7 @@ async def handle_websocket(websocket, path=None):
elif data.get('type') == 'tunnel_request': elif data.get('type') == 'tunnel_request':
client_id = data['client_id'] client_id = data['client_id']
request_id = data['request_id'] request_id = data['request_id']
if debug: print(f"[DEBUG] [WebSocket] wsssh/wsscp > server: tunnel_request (client_id: {client_id}, request_id: {request_id})")
if client_id in clients and clients[client_id]['status'] == 'active': if client_id in clients and clients[client_id]['status'] == 'active':
# Store tunnel mapping # Store tunnel mapping
active_tunnels[request_id] = { active_tunnels[request_id] = {
...@@ -478,6 +479,7 @@ async def handle_websocket(websocket, path=None): ...@@ -478,6 +479,7 @@ async def handle_websocket(websocket, path=None):
'client_id': client_id 'client_id': client_id
} }
# Forward tunnel request to client # Forward tunnel request to client
if debug: print(f"[DEBUG] [WebSocket] server > client: tunnel_request (request_id: {request_id})")
await clients[client_id]['websocket'].send(json.dumps({ await clients[client_id]['websocket'].send(json.dumps({
"type": "tunnel_request", "type": "tunnel_request",
"request_id": request_id "request_id": request_id
...@@ -495,10 +497,12 @@ async def handle_websocket(websocket, path=None): ...@@ -495,10 +497,12 @@ async def handle_websocket(websocket, path=None):
elif data.get('type') == 'tunnel_data': elif data.get('type') == 'tunnel_data':
# Forward tunnel data using active tunnel mapping # Forward tunnel data using active tunnel mapping
request_id = data['request_id'] request_id = data['request_id']
if debug: print(f"[DEBUG] [WebSocket] wsssh/wsscp > server: tunnel_data (request_id: {request_id})")
if request_id in active_tunnels: if request_id in active_tunnels:
tunnel = active_tunnels[request_id] tunnel = active_tunnels[request_id]
# Forward to client # Forward to client
if tunnel['client_id'] in clients and clients[tunnel['client_id']]['status'] == 'active': if tunnel['client_id'] in clients and clients[tunnel['client_id']]['status'] == 'active':
if debug: print(f"[DEBUG] [WebSocket] server > client: tunnel_data (request_id: {request_id})")
await tunnel['client_ws'].send(json.dumps({ await tunnel['client_ws'].send(json.dumps({
"type": "tunnel_data", "type": "tunnel_data",
"request_id": request_id, "request_id": request_id,
...@@ -509,8 +513,10 @@ async def handle_websocket(websocket, path=None): ...@@ -509,8 +513,10 @@ async def handle_websocket(websocket, path=None):
elif data.get('type') == 'tunnel_response': elif data.get('type') == 'tunnel_response':
# Forward tunnel response from client to wsssh # Forward tunnel response from client to wsssh
request_id = data['request_id'] request_id = data['request_id']
if debug: print(f"[DEBUG] [WebSocket] wssshc > server: tunnel_response (request_id: {request_id})")
if request_id in active_tunnels: if request_id in active_tunnels:
tunnel = active_tunnels[request_id] tunnel = active_tunnels[request_id]
if debug: print(f"[DEBUG] [WebSocket] server > wsssh/wsscp: tunnel_data (request_id: {request_id})")
await tunnel['wsssh_ws'].send(json.dumps({ await tunnel['wsssh_ws'].send(json.dumps({
"type": "tunnel_data", "type": "tunnel_data",
"request_id": request_id, "request_id": request_id,
......
...@@ -234,17 +234,17 @@ void *forward_tcp_to_ws(void *arg) { ...@@ -234,17 +234,17 @@ void *forward_tcp_to_ws(void *arg) {
continue; continue;
} }
// For wsssh: If this is the listening socket, accept the SSH client connection // For wsscp: If this is the listening socket, accept the SCP client connection
int client_sock = sock; int client_sock = sock;
if (active_tunnel->sock < 0) { if (active_tunnel->sock < 0 && active_tunnel->outgoing_buffer) {
// This is the listening socket, accept SSH client connection // This is the listening socket, accept SCP client connection
struct sockaddr_in client_addr; struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr); socklen_t client_len = sizeof(client_addr);
client_sock = accept(sock, (struct sockaddr *)&client_addr, &client_len); client_sock = accept(sock, (struct sockaddr *)&client_addr, &client_len);
if (client_sock < 0) { if (client_sock < 0) {
if (errno != EAGAIN && errno != EWOULDBLOCK) { if (errno != EAGAIN && errno != EWOULDBLOCK) {
if (debug) { if (debug) {
perror("[DEBUG] Accept SSH client connection failed"); perror("[DEBUG] Accept SCP client connection failed");
fflush(stdout); fflush(stdout);
} }
} }
...@@ -252,28 +252,28 @@ void *forward_tcp_to_ws(void *arg) { ...@@ -252,28 +252,28 @@ void *forward_tcp_to_ws(void *arg) {
usleep(10000); // Sleep 10ms and try again usleep(10000); // Sleep 10ms and try again
continue; continue;
} }
// Store the accepted SSH client socket // Store the accepted SCP client socket
active_tunnel->sock = client_sock; active_tunnel->sock = client_sock;
// Send any buffered data to the SSH client // Send any buffered data to the SCP client
if (active_tunnel->incoming_buffer && active_tunnel->incoming_buffer->used > 0) { if (active_tunnel->incoming_buffer && active_tunnel->incoming_buffer->used > 0) {
if (debug) { if (debug) {
printf("[DEBUG - TCPConnection] Sending %zu bytes of buffered data to SSH client\n", active_tunnel->incoming_buffer->used); printf("[DEBUG - TCPConnection] Sending %zu bytes of buffered data to SCP client\n", active_tunnel->incoming_buffer->used);
fflush(stdout); fflush(stdout);
} }
ssize_t sent = send(client_sock, active_tunnel->incoming_buffer->buffer, active_tunnel->incoming_buffer->used, 0); ssize_t sent = send(client_sock, active_tunnel->incoming_buffer->buffer, active_tunnel->incoming_buffer->used, 0);
if (sent > 0) { if (sent > 0) {
frame_buffer_consume(active_tunnel->incoming_buffer, sent); frame_buffer_consume(active_tunnel->incoming_buffer, sent);
if (debug) { if (debug) {
printf("[DEBUG] Sent %zd bytes of buffered data to SSH client\n", sent); printf("[DEBUG] Sent %zd bytes of buffered data to SCP client\n", sent);
fflush(stdout); fflush(stdout);
} }
} }
} }
if (debug) { if (debug) {
printf("[DEBUG - Tunnel] SSH client connected, starting data forwarding\n"); printf("[DEBUG - Tunnel] SCP client connected, starting data forwarding\n");
fflush(stdout); fflush(stdout);
} }
} }
...@@ -547,10 +547,11 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id ...@@ -547,10 +547,11 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id
if (active_tunnel->outgoing_buffer) { if (active_tunnel->outgoing_buffer) {
// wsscp: Use local_sock (SCP client connection) // wsscp: Use local_sock (SCP client connection)
target_sock = active_tunnel->local_sock; target_sock = active_tunnel->local_sock;
} else if (active_tunnel->sock >= 0) { } else if (active_tunnel->sock >= 0 || active_tunnel->local_sock >= 0) {
// wssshc: Use sock (direct SSH server connection) // wssshc: Use sock (direct SSH server connection)
// wsssh: Use sock (accepted SSH client connection) // wsssh: Use local_sock (accepted SSH client connection)
target_sock = active_tunnel->sock; // wsscp: Use local_sock (accepted SCP client connection)
target_sock = active_tunnel->sock >= 0 ? active_tunnel->sock : active_tunnel->local_sock;
} else { } else {
// No connection established yet - buffer the data // No connection established yet - buffer the data
if (debug) { if (debug) {
...@@ -601,6 +602,7 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id ...@@ -601,6 +602,7 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id
// wsssh/wssshc: Send directly to target socket // wsssh/wssshc: Send directly to target socket
if (debug) { if (debug) {
printf("[DEBUG] Attempting to send %zu bytes to socket %d\n", data_len, target_sock); printf("[DEBUG] Attempting to send %zu bytes to socket %d\n", data_len, target_sock);
printf("[DEBUG - TOREMOVE] Target socket is %d\n", target_sock);
fflush(stdout); fflush(stdout);
} }
ssize_t sent = send(target_sock, data, data_len, 0); ssize_t sent = send(target_sock, data, data_len, 0);
...@@ -635,6 +637,7 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id ...@@ -635,6 +637,7 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id
} else if (errno == EBADF) { } else if (errno == EBADF) {
if (debug) { if (debug) {
printf("[DEBUG] Bad file descriptor - socket may have been closed by SSH client\n"); printf("[DEBUG] Bad file descriptor - socket may have been closed by SSH client\n");
printf("[DEBUG - TOREMOVE] EBADF occurred, marking tunnel inactive\n");
fflush(stdout); fflush(stdout);
} }
// EBADF indicates the socket is invalid - SSH client likely disconnected // EBADF indicates the socket is invalid - SSH client likely disconnected
......
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