Add WSSSH version to registration and tunnel request messages

- Add WSSSH_VERSION define to websocket.h
- Include version field in wssshc registration messages to wssshd
- Include version field in wsssht tunnel_request messages
- Resolve function naming conflicts between wssshc and wsssht
- Update function declarations and calls accordingly

This allows for better version compatibility checking and debugging
between WSSSH client and server components.
parent 71a6296d
/*
* WebSocket SSH Tunnel (wsssht) - Mode Functions Implementation
* WSSSH Tunnel (wsssht) - Mode Functions Implementation
* Mode-specific functions for wsssht
*
* Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
......@@ -40,6 +40,8 @@
#include "wssh_ssl.h"
#include "tunnel.h"
#include "modes.h"
#include "control_messages.h"
#include "data_messages.h"
int run_bridge_mode(wsssh_config_t *config, const char *client_id, const char *wssshd_host, int wssshd_port) {
// Bridge mode: Pure transport layer - no tunnel setup, just WebSocket transport
......@@ -689,8 +691,8 @@ int run_pipe_mode(wsssh_config_t *config, const char *client_id, const char *wss
char *best_tunnel_control = select_best_transport(expanded_tunnel_control);
snprintf(tunnel_request_msg, sizeof(tunnel_request_msg),
"{\"type\":\"tunnel_request\",\"client_id\":\"%s\",\"request_id\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\",\"service\":\"ssh\"}",
client_id, request_id, best_tunnel ? best_tunnel : expanded_tunnel, best_tunnel_control ? best_tunnel_control : expanded_tunnel_control);
"{\"type\":\"tunnel_request\",\"client_id\":\"%s\",\"request_id\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\",\"service\":\"ssh\",\"version\":\"%s\"}",
client_id, request_id, best_tunnel ? best_tunnel : expanded_tunnel, best_tunnel_control ? best_tunnel_control : expanded_tunnel_control, WSSSH_VERSION);
if (!send_websocket_frame(ws_ssl, tunnel_request_msg)) {
free(expanded_tunnel);
......@@ -1167,10 +1169,10 @@ void *handle_connection(void *arg) {
char *best_tunnel_control = select_best_transport(expanded_tunnel_control);
snprintf(tunnel_request_msg, sizeof(tunnel_request_msg),
"{\"type\":\"tunnel_request\",\"client_id\":\"%s\",\"request_id\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\",\"service\":\"ssh\"}",
"{\"type\":\"tunnel_request\",\"client_id\":\"%s\",\"request_id\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\",\"service\":\"ssh\",\"version\":\"%s\"}",
client_id, new_tunnel->request_id,
best_tunnel ? best_tunnel : expanded_tunnel,
best_tunnel_control ? best_tunnel_control : expanded_tunnel_control);
best_tunnel_control ? best_tunnel_control : expanded_tunnel_control, WSSSH_VERSION);
if (!send_websocket_frame(ws_ssl, tunnel_request_msg)) {
free(expanded_tunnel);
......
......@@ -21,6 +21,8 @@
#include "wssshlib.h"
#include "websocket.h"
#include "wssh_ssl.h"
#include "control_messages.h"
#include "data_messages.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
......@@ -737,32 +739,11 @@ void *forward_tcp_to_ws(void *arg) {
pthread_mutex_unlock(&tunnel_mutex);
// Send as tunnel_data
size_t msg_size = strlen("{\"type\":\"tunnel_data\",\"request_id\":\"\",\"data\":\"\"}") + strlen(request_id) + actual_hex_len + 1;
char *message = malloc(msg_size);
if (!message) {
if (debug) {
printf("[DEBUG] Failed to allocate memory for message (%zu bytes)\n", msg_size);
fflush(stdout);
}
free(hex_data);
continue;
}
snprintf(message, msg_size,
"{\"type\":\"tunnel_data\",\"request_id\":\"%s\",\"data\":\"%s\"}",
request_id, hex_data);
if (!send_websocket_frame(ssl, message)) {
if (debug) {
printf("[DEBUG] Failed to send WebSocket frame\n");
fflush(stdout);
}
if (!send_tunnel_data_message(ssl, request_id, hex_data, debug)) {
free(hex_data);
free(message);
break;
}
free(hex_data);
free(message);
}
}
......@@ -882,32 +863,11 @@ void *forward_ws_to_ssh_server(void *arg) {
pthread_mutex_unlock(&tunnel_mutex);
// Send as tunnel_response (from target back to WebSocket)
size_t msg_size = strlen("{\"type\":\"tunnel_response\",\"request_id\":\"\",\"data\":\"\"}") + strlen(request_id) + actual_hex_len + 1;
char *message = malloc(msg_size);
if (!message) {
if (debug) {
printf("[DEBUG] Failed to allocate memory for message (%zu bytes)\n", msg_size);
fflush(stdout);
}
if (!send_tunnel_response_message(ssl, request_id, hex_data, debug)) {
free(hex_data);
continue;
}
snprintf(message, msg_size,
"{\"type\":\"tunnel_response\",\"request_id\":\"%s\",\"data\":\"%s\"}",
request_id, hex_data);
if (!send_websocket_frame(ssl, message)) {
if (debug) {
printf("[DEBUG] Failed to send WebSocket frame\n");
fflush(stdout);
}
free(hex_data);
free(message);
break;
}
free(hex_data);
free(message);
}
}
......@@ -937,7 +897,6 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id
}
// Validate hex data length
size_t hex_len = strlen(data_hex);
if (hex_len % 2 != 0) {
if (debug) {
printf("[DEBUG] Invalid hex data length: %zu (must be even), data_hex: %.50s...\n", hex_len, data_hex);
......@@ -1319,8 +1278,8 @@ int reconnect_websocket(tunnel_t *tunnel, const char *wssshd_host, int wssshd_po
char *best_tunnel_control = select_best_transport(expanded_tunnel_control);
snprintf(tunnel_request_msg, sizeof(tunnel_request_msg),
"{\"type\":\"tunnel_request\",\"client_id\":\"%s\",\"request_id\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\",\"service\":\"ssh\"}",
client_id, request_id, best_tunnel ? best_tunnel : expanded_tunnel, best_tunnel_control ? best_tunnel_control : expanded_tunnel_control);
"{\"type\":\"tunnel_request\",\"client_id\":\"%s\",\"request_id\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\",\"service\":\"ssh\",\"version\":\"%s\"}",
client_id, request_id, best_tunnel ? best_tunnel : expanded_tunnel, best_tunnel_control ? best_tunnel_control : expanded_tunnel_control, WSSSH_VERSION);
if (!send_websocket_frame(ssl, tunnel_request_msg)) {
free(expanded_tunnel);
......@@ -1477,8 +1436,8 @@ int setup_tunnel(const char *wssshd_host, int wssshd_port, const char *client_id
char *best_tunnel_control = select_best_transport(expanded_tunnel_control);
snprintf(tunnel_request_msg, sizeof(tunnel_request_msg),
"{\"type\":\"tunnel_request\",\"client_id\":\"%s\",\"request_id\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\",\"service\":\"ssh\"}",
client_id, request_id, best_tunnel ? best_tunnel : expanded_tunnel, best_tunnel_control ? best_tunnel_control : expanded_tunnel_control);
"{\"type\":\"tunnel_request\",\"client_id\":\"%s\",\"request_id\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\",\"service\":\"ssh\",\"version\":\"%s\"}",
client_id, request_id, best_tunnel ? best_tunnel : expanded_tunnel, best_tunnel_control ? best_tunnel_control : expanded_tunnel_control, WSSSH_VERSION);
if (!send_websocket_frame(ssl, tunnel_request_msg)) {
free(expanded_tunnel);
......
/*
* WebSocket SSH Tunnel (wsssht) - Utility Functions Implementation
* WSSSH Tunnel (wsssht) - Utility Functions Implementation
* Utility functions for wsssht
*
* Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
......@@ -26,41 +26,6 @@
#include "wssshlib.h"
#include "utils.h"
void print_usage(const char *program_name) {
fprintf(stderr, "Usage: %s [options] [service://]clientid[@wssshd-host][:wssshd-port]\n", program_name);
fprintf(stderr, "WebSocket SSH Tunnel - Setup WebSocket tunnels for manual connections\n\n");
fprintf(stderr, "Protect the dolls!\n\n");
fprintf(stderr, "Options:\n");
fprintf(stderr, " --config FILE Use custom config file (takes precedence over default)\n");
fprintf(stderr, " --clientid ID Client ID for the tunnel (default: from config)\n");
fprintf(stderr, " --tunnel-port PORT Local tunnel port (default: auto)\n");
fprintf(stderr, " --tunnel-host HOST Local IP address to bind tunnel to (default: 127.0.0.1)\n");
fprintf(stderr, " --wssshd-host HOST wssshd server hostname (required if not in config)\n");
fprintf(stderr, " --wssshd-port PORT wssshd server port (default: 9898)\n");
fprintf(stderr, " --interval SEC Connection retry interval in seconds (default: 5)\n");
fprintf(stderr, " --debug Enable debug output\n");
fprintf(stderr, " --tunnel TRANSPORT Transport for data channel (comma-separated or 'any', or 'websocket' default: any)\n");
fprintf(stderr, " --tunnel-control TYPES Transport types for control channel (comma-separated or 'any', default: any)\n");
fprintf(stderr, " --service SERVICE Service type (default: ssh)\n");
fprintf(stderr, " --mode MODE Operating mode: interactive, silent, bridge, script, pipe (default: interactive)\n");
fprintf(stderr, " --silent Shortcut for --mode silent\n");
fprintf(stderr, " --bridge Shortcut for --mode bridge\n");
fprintf(stderr, " --script Shortcut for --mode script\n");
fprintf(stderr, " --pipe Shortcut for --mode pipe\n");
fprintf(stderr, " --daemon Enable daemon mode for lazy initialization\n");
fprintf(stderr, " --help Show this help\n");
fprintf(stderr, "\nExamples:\n");
fprintf(stderr, " %s --clientid myclient --wssshd-host mbetter.nexlab.net\n", program_name);
fprintf(stderr, " %s myclient@mbetter.nexlab.net:9898\n", program_name);
fprintf(stderr, " %s ssh://myclient@mbetter.nexlab.net\n", program_name);
fprintf(stderr, " %s --tunnel websocket myclient@mbetter.nexlab.net\n", program_name);
fprintf(stderr, " %s --silent myclient@mbetter.nexlab.net\n", program_name);
fprintf(stderr, " %s --daemon --clientid myclient --wssshd-host mbetter.nexlab.net\n", program_name);
fprintf(stderr, "\nDonations:\n");
fprintf(stderr, " BTC: bc1q3zlkpu95amtcltsk85y0eacyzzk29v68tgc5hx\n");
fprintf(stderr, " ETH: 0xdA6dAb526515b5cb556d20269207D43fcc760E51\n");
}
int parse_connection_string(const char *conn_str, char **service, char **client_id, char **wssshd_host, int *wssshd_port) {
char *str = strdup(conn_str);
if (!str) return 0;
......@@ -106,7 +71,42 @@ int parse_connection_string(const char *conn_str, char **service, char **client_
return 1;
}
int parse_args(int argc, char *argv[], wsssh_config_t *config, int *remaining_argc, char ***remaining_argv) {
void print_usage(const char *program_name) {
fprintf(stderr, "Usage: %s [options] [service://]clientid[@wssshd-host][:wssshd-port]\n", program_name);
fprintf(stderr, "WSSSH Tunnel - Setup WebSocket tunnels for manual connections\n\n");
fprintf(stderr, "Protect the dolls!\n\n");
fprintf(stderr, "Options:\n");
fprintf(stderr, " --config FILE Use custom config file (takes precedence over default)\n");
fprintf(stderr, " --clientid ID Client ID for the tunnel (default: from config)\n");
fprintf(stderr, " --tunnel-port PORT Local tunnel port (default: auto)\n");
fprintf(stderr, " --tunnel-host HOST Local IP address to bind tunnel to (default: 127.0.0.1)\n");
fprintf(stderr, " --wssshd-host HOST wssshd server hostname (required if not in config)\n");
fprintf(stderr, " --wssshd-port PORT wssshd server port (default: 9898)\n");
fprintf(stderr, " --interval SEC Connection retry interval in seconds (default: 5)\n");
fprintf(stderr, " --debug Enable debug output\n");
fprintf(stderr, " --tunnel TRANSPORT Transport for data channel (comma-separated or 'any', or 'websocket' default: any)\n");
fprintf(stderr, " --tunnel-control TYPES Transport types for control channel (comma-separated or 'any', default: any)\n");
fprintf(stderr, " --service SERVICE Service type (default: ssh)\n");
fprintf(stderr, " --mode MODE Operating mode: interactive, silent, bridge, script, pipe (default: interactive)\n");
fprintf(stderr, " --silent Shortcut for --mode silent\n");
fprintf(stderr, " --bridge Shortcut for --mode bridge\n");
fprintf(stderr, " --script Shortcut for --mode script\n");
fprintf(stderr, " --pipe Shortcut for --mode pipe\n");
fprintf(stderr, " --daemon Enable daemon mode for lazy initialization\n");
fprintf(stderr, " --help Show this help\n");
fprintf(stderr, "\nExamples:\n");
fprintf(stderr, " %s --clientid myclient --wssshd-host mbetter.nexlab.net\n", program_name);
fprintf(stderr, " %s myclient@mbetter.nexlab.net:9898\n", program_name);
fprintf(stderr, " %s ssh://myclient@mbetter.nexlab.net\n", program_name);
fprintf(stderr, " %s --tunnel websocket myclient@mbetter.nexlab.net\n", program_name);
fprintf(stderr, " %s --silent myclient@mbetter.nexlab.net\n", program_name);
fprintf(stderr, " %s --daemon --clientid myclient --wssshd-host mbetter.nexlab.net\n", program_name);
fprintf(stderr, "\nDonations:\n");
fprintf(stderr, " BTC: bc1q3zlkpu95amtcltsk85y0eacyzzk29v68tgc5hx\n");
fprintf(stderr, " ETH: 0xdA6dAb526515b5cb556d20269207D43fcc760E51\n");
}
int wsssht_parse_args(int argc, char *argv[], wsssh_config_t *config, int *remaining_argc, char ***remaining_argv) {
// Parse wsssht options and optional connection string
int target_start = -1;
char *custom_config = NULL;
......@@ -163,7 +163,6 @@ int parse_args(int argc, char *argv[], wsssh_config_t *config, int *remaining_ar
config->mode = MODE_PIPE;
} else {
fprintf(stderr, "Error: Invalid mode: %s\n", argv[i + 1]);
print_usage(argv[0]);
return 0;
}
i++; // Skip the argument
......
......@@ -20,6 +20,7 @@
#include "websocket.h"
#include "wssshlib.h"
#include "tunnel.h"
#include "control_messages.h"
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <string.h>
......@@ -101,62 +102,6 @@ int websocket_handshake(SSL *ssl, const char *host, int port, const char *path,
return 1;
}
int send_json_message(SSL *ssl, const char *type, const char *client_id, const char *request_id) {
char message[1024];
if (request_id) {
snprintf(message, sizeof(message),
"{\"type\":\"%s\",\"client_id\":\"%s\",\"request_id\":\"%s\"}",
type, client_id, request_id);
} else {
snprintf(message, sizeof(message),
"{\"type\":\"%s\",\"client_id\":\"%s\"}",
type, client_id);
}
// Send as WebSocket frame
return send_websocket_frame(ssl, message);
}
int send_registration_message(SSL *ssl, const char *client_id, const char *password, const char *tunnel, const char *tunnel_control, const char *wssshd_private_ip) {
char message[2048];
if (password && strlen(password) > 0) {
if (wssshd_private_ip && strlen(wssshd_private_ip) > 0) {
snprintf(message, sizeof(message),
"{\"type\":\"register\",\"client_id\":\"%s\",\"password\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\",\"wssshd_private_ip\":\"%s\"}",
client_id, password, tunnel, tunnel_control, wssshd_private_ip);
} else {
snprintf(message, sizeof(message),
"{\"type\":\"register\",\"client_id\":\"%s\",\"password\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\"}",
client_id, password, tunnel, tunnel_control);
}
} else {
if (wssshd_private_ip && strlen(wssshd_private_ip) > 0) {
snprintf(message, sizeof(message),
"{\"type\":\"register\",\"client_id\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\",\"wssshd_private_ip\":\"%s\"}",
client_id, tunnel, tunnel_control, wssshd_private_ip);
} else {
snprintf(message, sizeof(message),
"{\"type\":\"register\",\"client_id\":\"%s\",\"tunnel\":\"%s\",\"tunnel_control\":\"%s\"}",
client_id, tunnel, tunnel_control);
}
}
printf("[DEBUG] Sending registration message: %s\n", message);
fflush(stdout);
// Send as WebSocket frame
int result = send_websocket_frame(ssl, message);
if (result) {
printf("[DEBUG] Registration message sent successfully\n");
fflush(stdout);
} else {
printf("[DEBUG] Failed to send registration message\n");
fflush(stdout);
}
return result;
}
int send_websocket_frame(SSL *ssl, const char *data) {
// Lock SSL mutex to prevent concurrent SSL operations
......@@ -506,177 +451,6 @@ int send_pong_frame_ws(int sock, const char *ping_payload, int payload_len) {
return 1;
}
int send_ping_frame(SSL *ssl, const char *ping_payload, int payload_len) {
// Lock SSL mutex to prevent concurrent SSL operations
pthread_mutex_lock(&ssl_mutex);
char frame[BUFFER_SIZE];
frame[0] = 0x89; // FIN + ping opcode
int header_len = 2;
if (payload_len <= 125) {
frame[1] = 0x80 | payload_len; // MASK + length
} else if (payload_len <= 65535) {
frame[1] = 0x80 | 126; // MASK + extended length
frame[2] = (payload_len >> 8) & 0xFF;
frame[3] = payload_len & 0xFF;
header_len = 4;
} else {
frame[1] = 0x80 | 127; // MASK + extended length
frame[2] = 0;
frame[3] = 0;
frame[4] = 0;
frame[5] = 0;
frame[6] = (payload_len >> 24) & 0xFF;
frame[7] = (payload_len >> 16) & 0xFF;
frame[8] = (payload_len >> 8) & 0xFF;
frame[9] = payload_len & 0xFF;
header_len = 10;
}
// Add mask key
char mask_key[4];
for (int i = 0; i < 4; i++) {
mask_key[i] = rand() % 256;
frame[header_len + i] = mask_key[i];
}
header_len += 4;
// Mask payload
for (int i = 0; i < payload_len; i++) {
frame[header_len + i] = ping_payload[i] ^ mask_key[i % 4];
}
int frame_len = header_len + payload_len;
// Handle partial writes for large frames
int total_written = 0;
int retry_count = 0;
const int max_retries = 3;
while (total_written < frame_len && retry_count < max_retries) {
int to_write = frame_len - total_written;
// Limit to BUFFER_SIZE to avoid issues with very large frames
if (to_write > BUFFER_SIZE) {
to_write = BUFFER_SIZE;
}
int written = SSL_write(ssl, frame + total_written, to_write);
if (written <= 0) {
int ssl_error = SSL_get_error(ssl, written);
// Handle transient SSL errors with retry
if ((ssl_error == SSL_ERROR_WANT_READ || ssl_error == SSL_ERROR_WANT_WRITE) && retry_count < max_retries - 1) {
retry_count++;
usleep(10000); // Wait 10ms before retry
continue; // Retry the write operation
}
fprintf(stderr, "Ping frame SSL_write failed: %d (after %d retries)\n", ssl_error, retry_count);
char error_buf[256];
ERR_error_string_n(ssl_error, error_buf, sizeof(error_buf));
fprintf(stderr, "SSL write error details: %s\n", error_buf);
pthread_mutex_unlock(&ssl_mutex);
return 0; // Write failed
}
total_written += written;
retry_count = 0; // Reset retry count on successful write
}
if (total_written < frame_len) {
fprintf(stderr, "Ping frame write incomplete: %d/%d bytes written\n", total_written, frame_len);
pthread_mutex_unlock(&ssl_mutex);
return 0;
}
pthread_mutex_unlock(&ssl_mutex);
return 1;
}
int send_pong_frame(SSL *ssl, const char *ping_payload, int payload_len) {
// Lock SSL mutex to prevent concurrent SSL operations
pthread_mutex_lock(&ssl_mutex);
char frame[BUFFER_SIZE];
frame[0] = 0x8A; // FIN + pong opcode
int header_len = 2;
if (payload_len <= 125) {
frame[1] = 0x80 | payload_len; // MASK + length
} else if (payload_len <= 65535) {
frame[1] = 0x80 | 126; // MASK + extended length
frame[2] = (payload_len >> 8) & 0xFF;
frame[3] = payload_len & 0xFF;
header_len = 4;
} else {
frame[1] = 0x80 | 127; // MASK + extended length
frame[2] = 0;
frame[3] = 0;
frame[4] = 0;
frame[5] = 0;
frame[6] = (payload_len >> 24) & 0xFF;
frame[7] = (payload_len >> 16) & 0xFF;
frame[8] = (payload_len >> 8) & 0xFF;
frame[9] = payload_len & 0xFF;
header_len = 10;
}
// Add mask key
char mask_key[4];
for (int i = 0; i < 4; i++) {
mask_key[i] = rand() % 256;
frame[header_len + i] = mask_key[i];
}
header_len += 4;
// Mask payload
for (int i = 0; i < payload_len; i++) {
frame[header_len + i] = ping_payload[i] ^ mask_key[i % 4];
}
int frame_len = header_len + payload_len;
// Handle partial writes for large frames
int total_written = 0;
int retry_count = 0;
const int max_retries = 3;
while (total_written < frame_len && retry_count < max_retries) {
int to_write = frame_len - total_written;
// Limit to BUFFER_SIZE to avoid issues with very large frames
if (to_write > BUFFER_SIZE) {
to_write = BUFFER_SIZE;
}
int written = SSL_write(ssl, frame + total_written, to_write);
if (written <= 0) {
int ssl_error = SSL_get_error(ssl, written);
// Handle transient SSL errors with retry
if ((ssl_error == SSL_ERROR_WANT_READ || ssl_error == SSL_ERROR_WANT_WRITE) && retry_count < max_retries - 1) {
retry_count++;
usleep(10000); // Wait 10ms before retry
continue; // Retry the write operation
}
fprintf(stderr, "Pong frame SSL_write failed: %d (after %d retries)\n", ssl_error, retry_count);
char error_buf[256];
ERR_error_string_n(ssl_error, error_buf, sizeof(error_buf));
fprintf(stderr, "SSL write error details: %s\n", error_buf);
pthread_mutex_unlock(&ssl_mutex);
return 0; // Write failed
}
total_written += written;
retry_count = 0; // Reset retry count on successful write
}
if (total_written < frame_len) {
fprintf(stderr, "Pong frame write incomplete: %d/%d bytes written\n", total_written, frame_len);
pthread_mutex_unlock(&ssl_mutex);
return 0;
}
pthread_mutex_unlock(&ssl_mutex);
return 1;
}
int parse_websocket_frame(const char *buffer, int bytes_read, char **payload, int *payload_len) {
if (bytes_read < 2) {
......
/*
* WebSocket SSH Library - WebSocket functions
* WSSSH Library - WebSocket functions
*
* Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
*
......@@ -22,12 +22,12 @@
#include <openssl/ssl.h>
// WSSSH version
#define WSSSH_VERSION "1.6.1"
// Function declarations
int websocket_handshake(SSL *ssl, const char *host, int port, const char *path, int debug);
int send_json_message(SSL *ssl, const char *type, const char *client_id, const char *request_id);
int send_registration_message(SSL *ssl, const char *client_id, const char *password, const char *tunnel, const char *tunnel_control, const char *wssshd_private_ip);
int send_websocket_frame(SSL *ssl, const char *data);
int send_pong_frame(SSL *ssl, const char *ping_payload, int payload_len);
int parse_websocket_frame(const char *buffer, int bytes_read, char **payload, int *payload_len);
// Bridge mode transport layer functions
......
/*
* WebSocket SSH Tunnel (wsssht) - C Implementation
* WSSSH Tunnel (wsssht) - C Implementation
* WebSocket tunnel setup tool for manual connections.
*
* Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
......@@ -53,7 +53,7 @@ typedef struct {
// Function declarations
void print_usage(const char *program_name);
int parse_connection_string(const char *conn_str, char **service, char **client_id, char **wssshd_host, int *wssshd_port);
int parse_args(int argc, char *argv[], wsssh_config_t *config, int *remaining_argc, char ***remaining_argv);
int wsssht_parse_args(int argc, char *argv[], wsssh_config_t *config, int *remaining_argc, char ***remaining_argv);
int run_bridge_mode(wsssh_config_t *config, const char *client_id, const char *wssshd_host, int wssshd_port);
int run_script_mode(wsssh_config_t *config, const char *client_id, const char *wssshd_host, int wssshd_port);
int run_daemon_mode(wsssh_config_t *config, const char *client_id, const char *wssshd_host, int wssshd_port);
......
......@@ -39,6 +39,7 @@
#include "libwsssht/websocket.h"
#include "libwsssht/wssh_ssl.h"
#include "libwsssht/tunnel.h"
#include "libwsssht/control_messages.h"
......@@ -357,7 +358,7 @@ int execute_service_command(const char *command, int debug) {
return -1;
}
}
void print_usage(const char *program_name) {
static void wssshc_print_usage(const char *program_name) {
fprintf(stderr, "Usage: %s [options]\n", program_name);
fprintf(stderr, "WSSSH Client - Register with wssshd server\n\n");
fprintf(stderr, "Protect the dolls!\n\n");
......@@ -484,7 +485,7 @@ int parse_args(int argc, char *argv[], wssshc_config_t *config) {
break;
case 'h':
default:
print_usage(argv[0]);
wssshc_print_usage(argv[0]);
return 0;
}
}
......@@ -492,7 +493,7 @@ int parse_args(int argc, char *argv[], wssshc_config_t *config) {
// Handle --help
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
print_usage(argv[0]);
wssshc_print_usage(argv[0]);
return 0;
}
}
......@@ -1530,7 +1531,7 @@ int main(int argc, char *argv[]) {
// Validate required arguments
if (!config.client_id || !config.password) {
fprintf(stderr, "Error: --id and --password are required\n");
print_usage(argv[0]);
wssshc_print_usage(argv[0]);
if (config.wssshd_server) free(config.wssshd_server);
if (config.ssh_host) free(config.ssh_host);
if (config.client_id) free(config.client_id);
......
......@@ -41,6 +41,7 @@
#include "libwsssht/utils.h"
#include "libwsssht/modes.h"
#include "libwsssht/threads.h"
#include "libwsssht/control_messages.h"
int main(int argc, char *argv[]) {
// Read config from wsssht.conf
......@@ -151,7 +152,7 @@ int main(int argc, char *argv[]) {
// Parse wsssht arguments
int remaining_argc;
char **remaining_argv;
if (!parse_args(argc, argv, &config, &remaining_argc, &remaining_argv)) {
if (!wsssht_parse_args(argc, argv, &config, &remaining_argc, &remaining_argv)) {
pthread_mutex_destroy(&tunnel_mutex);
free(config_domain);
return 1;
......
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