Enhance wsssh and wsssht with improved functionality

wsssh improvements:
- Parse SSH arguments for -p option to extract port value
- Automatically add --wssshd-port to ProxyCommand when -p is specified and --wssshd-port is not explicitly set
- Fix build warnings in find_wsssht_path function
- Change debug mode to execute SSH command instead of just printing it

wsssht improvements:
- Modify pipe mode debug output to use stderr instead of stdout
- Prevent debug messages from interfering with piped data streams
- All debug output in pipe mode now goes to stderr to avoid contaminating stdin/stdout

These changes improve the usability and reliability of both wsssh and wsssht applications, especially when used in pipe mode or with SSH port specifications.
parent 382c9c46
...@@ -611,9 +611,8 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -611,9 +611,8 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
// Pipe mode: Negotiate tunnel and redirect raw tunnelled data to stdin/stdout // Pipe mode: Negotiate tunnel and redirect raw tunnelled data to stdin/stdout
// Similar to other modes but doesn't bind to a port - handles data directly // Similar to other modes but doesn't bind to a port - handles data directly
if (config->debug) { if (config->debug) {
printf("[DEBUG] Starting pipe mode (tunnel negotiation + stdin/stdout proxy) with client_id=%s, host=%s, port=%d\n", fprintf(stderr, "[DEBUG] Starting pipe mode (tunnel negotiation + stdin/stdout proxy) with client_id=%s, host=%s, port=%d\n",
client_id, wssshd_host, wssshd_port); client_id, wssshd_host, wssshd_port);
fflush(stdout);
} }
// Establish WebSocket connection and negotiate tunnel (similar to setup_tunnel but without port binding) // Establish WebSocket connection and negotiate tunnel (similar to setup_tunnel but without port binding)
...@@ -677,8 +676,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -677,8 +676,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
} }
if (config->debug) { if (config->debug) {
printf("[DEBUG] WebSocket handshake successful\n"); fprintf(stderr, "[DEBUG] WebSocket handshake successful\n");
fflush(stdout);
} }
// Send tunnel request (same as setup_tunnel) // Send tunnel request (same as setup_tunnel)
...@@ -711,8 +709,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -711,8 +709,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
if (best_tunnel_control) free(best_tunnel_control); if (best_tunnel_control) free(best_tunnel_control);
if (config->debug) { if (config->debug) {
printf("[DEBUG] Tunnel request sent for client: %s, request_id: %s\n", client_id, request_id); fprintf(stderr, "[DEBUG] Tunnel request sent for client: %s, request_id: %s\n", client_id, request_id);
fflush(stdout);
} }
// Read acknowledgment (same as setup_tunnel) // Read acknowledgment (same as setup_tunnel)
...@@ -762,8 +759,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -762,8 +759,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
} }
if (config->debug) { if (config->debug) {
printf("[DEBUG] Tunnel negotiated successfully, request_id: %s\n", request_id); fprintf(stderr, "[DEBUG] Tunnel negotiated successfully, request_id: %s\n", request_id);
fflush(stdout);
} }
// Create tunnel structure (but don't bind to port) // Create tunnel structure (but don't bind to port)
...@@ -803,8 +799,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -803,8 +799,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
SSL_CTX_free(ssl_ctx); SSL_CTX_free(ssl_ctx);
if (config->debug) { if (config->debug) {
printf("[DEBUG] Pipe tunnel established, starting stdin/stdout data forwarding\n"); fprintf(stderr, "[DEBUG] Pipe tunnel established, starting stdin/stdout data forwarding\n");
fflush(stdout);
} }
// Main pipe loop - handle stdin/stdout and WebSocket tunnel data // Main pipe loop - handle stdin/stdout and WebSocket tunnel data
...@@ -823,8 +818,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -823,8 +818,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
if (!tunnel_active) { if (!tunnel_active) {
if (config->debug) { if (config->debug) {
printf("[DEBUG] Tunnel is no longer active, exiting pipe mode\n"); fprintf(stderr, "[DEBUG] Tunnel is no longer active, exiting pipe mode\n");
fflush(stdout);
} }
break; break;
} }
...@@ -847,8 +841,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -847,8 +841,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
if (bytes_read <= 0) { if (bytes_read <= 0) {
// EOF or error on stdin // EOF or error on stdin
if (config->debug) { if (config->debug) {
printf("[DEBUG] EOF on stdin, sending tunnel_close\n"); fprintf(stderr, "[DEBUG] EOF on stdin, sending tunnel_close\n");
fflush(stdout);
} }
// Send tunnel_close before exiting // Send tunnel_close before exiting
send_tunnel_close(ws_ssl, request_id, config->debug); send_tunnel_close(ws_ssl, request_id, config->debug);
...@@ -889,8 +882,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -889,8 +882,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
// Send message via WebSocket // Send message via WebSocket
if (send_websocket_frame(ws_ssl, message)) { if (send_websocket_frame(ws_ssl, message)) {
if (config->debug) { if (config->debug) {
printf("[DEBUG] Sent %zd bytes from stdin to tunnel\n", bytes_read); fprintf(stderr, "[DEBUG] Sent %zd bytes from stdin to tunnel\n", bytes_read);
fflush(stdout);
} }
} else { } else {
if (config->debug) { if (config->debug) {
...@@ -913,8 +905,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -913,8 +905,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
frame_buffer_used += ws_bytes_read; frame_buffer_used += ws_bytes_read;
if (config->debug) { if (config->debug) {
printf("[DEBUG] Accumulated %d bytes from WebSocket\n", frame_buffer_used); fprintf(stderr, "[DEBUG] Accumulated %d bytes from WebSocket\n", frame_buffer_used);
fflush(stdout);
} }
// Try to parse WebSocket frame // Try to parse WebSocket frame
...@@ -963,8 +954,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -963,8 +954,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
// Write binary data to stdout // Write binary data to stdout
ssize_t written = write(STDOUT_FILENO, binary_data, binary_len); ssize_t written = write(STDOUT_FILENO, binary_data, binary_len);
if (written > 0 && config->debug) { if (written > 0 && config->debug) {
printf("[DEBUG] Wrote %zd bytes to stdout\n", written); fprintf(stderr, "[DEBUG] Wrote %zd bytes to stdout\n", written);
fflush(stdout);
} }
free(binary_data); free(binary_data);
...@@ -977,8 +967,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -977,8 +967,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
} else if (strstr(buffer, "tunnel_close")) { } else if (strstr(buffer, "tunnel_close")) {
// Server closed tunnel // Server closed tunnel
if (config->debug) { if (config->debug) {
printf("[DEBUG] Server closed tunnel\n"); fprintf(stderr, "[DEBUG] Server closed tunnel\n");
fflush(stdout);
} }
break; break;
} }
...@@ -986,8 +975,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -986,8 +975,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
} }
} else if (frame_type == 0x88) { // Close frame } else if (frame_type == 0x88) { // Close frame
if (config->debug) { if (config->debug) {
printf("[DEBUG] WebSocket close frame received\n"); fprintf(stderr, "[DEBUG] WebSocket close frame received\n");
fflush(stdout);
} }
break; break;
} else if (frame_type == 0x89) { // Ping frame } else if (frame_type == 0x89) { // Ping frame
...@@ -1012,8 +1000,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -1012,8 +1000,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
} else if (ws_bytes_read == 0) { } else if (ws_bytes_read == 0) {
// Connection closed // Connection closed
if (config->debug) { if (config->debug) {
printf("[DEBUG] WebSocket connection closed by server\n"); fprintf(stderr, "[DEBUG] WebSocket connection closed by server\n");
fflush(stdout);
} }
break; break;
} else { } else {
...@@ -1040,8 +1027,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss ...@@ -1040,8 +1027,7 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
pthread_mutex_unlock(&tunnel_mutex); pthread_mutex_unlock(&tunnel_mutex);
if (config->debug) { if (config->debug) {
printf("[DEBUG] Pipe mode ended\n"); fprintf(stderr, "[DEBUG] Pipe mode ended\n");
fflush(stdout);
} }
return 0; return 0;
......
...@@ -71,6 +71,7 @@ int parse_wsssh_args(int argc, char *argv[], wsssh_config_t *config) { ...@@ -71,6 +71,7 @@ int parse_wsssh_args(int argc, char *argv[], wsssh_config_t *config) {
i++; i++;
} else if (strcmp(argv[i], "--wssshd-port") == 0 && i + 1 < argc) { } else if (strcmp(argv[i], "--wssshd-port") == 0 && i + 1 < argc) {
config->wssshd_port = atoi(argv[i + 1]); config->wssshd_port = atoi(argv[i + 1]);
config->wssshd_port_explicit = 1;
i++; i++;
} else if (strcmp(argv[i], "--debug") == 0) { } else if (strcmp(argv[i], "--debug") == 0) {
config->debug = 1; config->debug = 1;
...@@ -140,6 +141,26 @@ int parse_target_string(const char *target, wsssh_config_t *config) { ...@@ -140,6 +141,26 @@ int parse_target_string(const char *target, wsssh_config_t *config) {
return 1; return 1;
} }
int parse_ssh_port_from_args(wsssh_config_t *config) {
if (!config->remaining_argv || config->remaining_argc < 2) {
return 0;
}
// Look for -p option in remaining arguments
for (int i = 0; i < config->remaining_argc - 1; i++) {
if (strcmp(config->remaining_argv[i], "-p") == 0) {
// Found -p, next argument should be the port
char *endptr;
int port = strtol(config->remaining_argv[i + 1], &endptr, 10);
if (*endptr == '\0' && port > 0 && port <= 65535) {
return port;
}
}
}
return 0; // No valid -p option found
}
char *find_wsssht_path() { char *find_wsssht_path() {
// First check if wsssht is in PATH // First check if wsssht is in PATH
if (system("which wsssht > /dev/null 2>&1") == 0) { if (system("which wsssht > /dev/null 2>&1") == 0) {
...@@ -154,10 +175,15 @@ char *find_wsssht_path() { ...@@ -154,10 +175,15 @@ char *find_wsssht_path() {
char *dir_end = strrchr(wsssh_path, '/'); char *dir_end = strrchr(wsssh_path, '/');
if (dir_end) { if (dir_end) {
*dir_end = '\0'; *dir_end = '\0';
char wsssht_full_path[PATH_MAX]; // Ensure we have enough space for the path + "/wsssht" + null terminator
snprintf(wsssht_full_path, sizeof(wsssht_full_path), "%s/wsssht", wsssh_path); size_t wsssh_path_len = strlen(wsssh_path);
if (access(wsssht_full_path, X_OK) == 0) { if (wsssh_path_len + 8 < PATH_MAX) { // 8 = "/wsssht" + null
return strdup(wsssht_full_path); char wsssht_full_path[PATH_MAX];
strcpy(wsssht_full_path, wsssh_path);
strcat(wsssht_full_path, "/wsssht");
if (access(wsssht_full_path, X_OK) == 0) {
return strdup(wsssht_full_path);
}
} }
} }
} }
...@@ -183,6 +209,16 @@ char *build_proxy_command(wsssh_config_t *config) { ...@@ -183,6 +209,16 @@ char *build_proxy_command(wsssh_config_t *config) {
sprintf(cmd, "%s --pipe", wsssht_path); sprintf(cmd, "%s --pipe", wsssht_path);
free(wsssht_path); free(wsssht_path);
// If --wssshd-port was not explicitly set, check for -p in SSH arguments
if (!config->wssshd_port_explicit) {
int ssh_port = parse_ssh_port_from_args(config);
if (ssh_port > 0) {
char port_str[32];
sprintf(port_str, " --wssshd-port %d", ssh_port);
strcat(cmd, port_str);
}
}
// Add debug if specified // Add debug if specified
if (config->debug) { if (config->debug) {
strcat(cmd, " --debug"); strcat(cmd, " --debug");
...@@ -320,8 +356,8 @@ int main(int argc, char *argv[]) { ...@@ -320,8 +356,8 @@ int main(int argc, char *argv[]) {
// Execute SSH command // Execute SSH command
int result; int result;
if (config.debug) { if (config.debug) {
printf("[DEBUG] Would execute: %s\n", ssh_command); printf("[DEBUG] Executing: %s\n", ssh_command);
result = 0; // Success for debug mode result = execute_ssh_command(ssh_command, config.debug);
} else { } else {
result = execute_ssh_command(ssh_command, config.debug); result = execute_ssh_command(ssh_command, config.debug);
} }
......
...@@ -31,6 +31,7 @@ typedef struct { ...@@ -31,6 +31,7 @@ typedef struct {
char *client_id; char *client_id;
char *wssshd_host; char *wssshd_host;
int wssshd_port; int wssshd_port;
int wssshd_port_explicit; // Flag to track if --wssshd-port was explicitly set
int debug; int debug;
char *tunnel; char *tunnel;
char *tunnel_control; char *tunnel_control;
......
No preview for this file type
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