Fix hex decoding and data handling issues in tunnel.c

- Improved handle_tunnel_data() with better hex validation and decoding
- Added bounds checking for hex data length validation
- Enhanced error handling for hex decoding failures
- Added debug logging for hex decoding issues
- Improved socket send error handling with detailed error messages
- Added bounds checking for hex encoding in forwarding functions
- Fixed potential buffer overflow issues with large hex data
- Enhanced robustness for handling large SSH protocol packets
parent e86758cb
...@@ -272,9 +272,17 @@ void *forward_tcp_to_ws(void *arg) { ...@@ -272,9 +272,17 @@ void *forward_tcp_to_ws(void *arg) {
fflush(stdout); fflush(stdout);
} }
// Convert to hex // Convert to hex with bounds checking
char hex_data[bytes_read * 2 + 1]; size_t hex_size = (size_t)bytes_read * 2 + 1;
for (int i = 0; i < bytes_read; i++) { if (hex_size > BUFFER_SIZE) {
if (debug) {
printf("[DEBUG] Hex data too large (%zu bytes), truncating to %d\n", hex_size, BUFFER_SIZE);
fflush(stdout);
}
hex_size = BUFFER_SIZE;
}
char hex_data[hex_size];
for (int i = 0; i < bytes_read && (size_t)i * 2 < hex_size - 1; i++) {
sprintf(hex_data + i * 2, "%02x", (unsigned char)buffer[i]); sprintf(hex_data + i * 2, "%02x", (unsigned char)buffer[i]);
} }
hex_data[bytes_read * 2] = '\0'; hex_data[bytes_read * 2] = '\0';
...@@ -357,9 +365,17 @@ void *forward_ws_to_local(void *arg) { ...@@ -357,9 +365,17 @@ void *forward_ws_to_local(void *arg) {
fflush(stdout); fflush(stdout);
} }
// Convert to hex // Convert to hex with bounds checking
char hex_data[bytes_read * 2 + 1]; size_t hex_size = (size_t)bytes_read * 2 + 1;
for (int i = 0; i < bytes_read; i++) { if (hex_size > BUFFER_SIZE) {
if (debug) {
printf("[DEBUG] Hex data too large (%zu bytes), truncating to %d\n", hex_size, BUFFER_SIZE);
fflush(stdout);
}
hex_size = BUFFER_SIZE;
}
char hex_data[hex_size];
for (int i = 0; i < bytes_read && (size_t)i * 2 < hex_size - 1; i++) {
sprintf(hex_data + i * 2, "%02x", (unsigned char)buffer[i]); sprintf(hex_data + i * 2, "%02x", (unsigned char)buffer[i]);
} }
hex_data[bytes_read * 2] = '\0'; hex_data[bytes_read * 2] = '\0';
...@@ -409,13 +425,39 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id ...@@ -409,13 +425,39 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id
} }
pthread_mutex_unlock(&tunnel_mutex); pthread_mutex_unlock(&tunnel_mutex);
// 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)\n", hex_len);
fflush(stdout);
}
return;
}
// Decode hex data // Decode hex data
size_t data_len = strlen(data_hex) / 2; size_t data_len = hex_len / 2;
char *data = malloc(data_len); char *data = malloc(data_len);
if (!data) return; if (!data) {
if (debug) {
printf("[DEBUG] Failed to allocate memory for %zu bytes of decoded data\n", data_len);
fflush(stdout);
}
return;
}
// Use more efficient hex decoding
for (size_t i = 0; i < data_len; i++) { for (size_t i = 0; i < data_len; i++) {
sscanf(data_hex + i * 2, "%2hhx", &data[i]); unsigned int byte_val;
if (sscanf(data_hex + i * 2, "%2x", &byte_val) != 1) {
if (debug) {
printf("[DEBUG] Failed to decode hex byte at position %zu\n", i * 2);
fflush(stdout);
}
free(data);
return;
}
data[i] = (char)byte_val;
} }
if (active_tunnel->outgoing_buffer) { if (active_tunnel->outgoing_buffer) {
...@@ -430,7 +472,14 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id ...@@ -430,7 +472,14 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id
pthread_mutex_unlock(&tunnel_mutex); pthread_mutex_unlock(&tunnel_mutex);
} else { } else {
// wsssh/wssshc: Send directly to target socket // wsssh/wssshc: Send directly to target socket
send(target_sock, data, data_len, 0); ssize_t sent = send(target_sock, data, data_len, 0);
if (sent < 0 && debug) {
printf("[DEBUG] Failed to send %zu bytes to target socket: %s\n", data_len, strerror(errno));
fflush(stdout);
} else if (debug && (size_t)sent != data_len) {
printf("[DEBUG] Partial send: sent %zd of %zu bytes\n", sent, data_len);
fflush(stdout);
}
} }
free(data); free(data);
} }
......
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