feat: Add wsssht - WebSocket SSH Tunnel tool

- Create wsssht.c: Stripped-down tunnel setup tool (like wsssh --dev-tunnel)
- Add separate wssht.conf configuration file support
- Implement read_config_value_from_file() for custom config files
- Create wssht.conf.example with tunnel configuration options
- Update wsssht.1 man page with separate config file documentation
- Add wsssht to build system (configure.sh, Makefile)
- Test successful compilation and functionality

wsssht provides manual tunnel setup without auto-executing SSH/SCP,
displaying connection information for telnet, nc, or any TCP client.
parent cc27f590
# WebSocket SSH Tunnel (wsssht) Configuration Example
#
# This is an example configuration file for wsssht.
# Copy this file to ~/.config/wsssh/wssht.conf
# and modify the settings as needed.
#
# Configuration options:
# port: Default WebSocket server port
# domain: Default domain suffix for hostname parsing
# tunnel: Default transport types for data channel (comma-separated or 'any')
# tunnel-control: Default transport types for control channel (comma-separated or 'any')
# service: Default service type (default: ssh)
# interval: Connection retry interval in seconds (default: 30)
[default]
port=9898
domain=example.com
tunnel=websocket
tunnel-control=websocket
service=ssh
interval=30
\ No newline at end of file
.TH WSSSHT 1 "September 2024" "WebSocket SSH" "User Commands"
.SH NAME
wsssht \- WebSocket SSH Tunnel Setup Tool
.SH SYNOPSIS
.B wsssht
[\fB\-\-local\-port\fR \fIPORT\fR]
[\fB\-\-interval\fR \fISEC\fR]
[\fB\-\-debug\fR]
[\fB\-\-tunnel\fR \fITYPES\fR]
[\fB\-\-tunnel\-control\fR \fITYPES\fR]
[\fB\-\-service\fR \fISERVICE\fR]
[\fB\-\-help\fR]
[\fB\-p\fR \fIPORT\fR]
[\fB\-\-port\fR \fIPORT\fR]
\fIuser\fR@\fIclient\fR.\fIdomain\fR
.SH DESCRIPTION
.B wsssht
is a WebSocket SSH tunnel setup tool that establishes secure tunnels through WebSocket connections without automatically executing SSH/SCP commands. It provides connection information for manual use with any TCP client.
.PP
Unlike
.BR wsssh (1)
and
.BR wsscp (1),
.B wsssht
does not fork and execute external commands. Instead, it sets up the tunnel and displays connection instructions for manual use.
.SH OPTIONS
.TP
.BR \-\-local\-port " \fIPORT\fR"
Specify the local port for the tunnel (default: auto\-assigned)
.TP
.BR \-\-interval " \fISEC\fR"
Connection retry interval in seconds (default: 30)
.TP
.BR \-\-debug
Enable debug output
.TP
.BR \-\-tunnel " \fITYPES\fR"
Transport types for data channel (comma\-separated or 'any', default: any)
.TP
.BR \-\-tunnel\-control " \fITYPES\fR"
Transport types for control channel (comma\-separated or 'any', default: any)
.TP
.BR \-\-service " \fISERVICE\fR"
Service type (default: ssh)
.TP
.BR \-\-help
Display help message and exit
.TP
.BR \-p ", " \-\-port " \fIPORT\fR"
WebSocket SSH daemon server port (default: 9898)
.SH EXAMPLES
.TP
Basic tunnel setup:
.B wsssht user@myclient.example.com
.TP
Specify local port:
.B wsssht \-\-local\-port 2222 user@myclient.example.com
.TP
Use specific transport:
.B wsssht \-\-tunnel websocket user@myclient.example.com
.TP
Debug mode:
.B wsssht \-\-debug user@myclient.example.com
.SH MANUAL CONNECTION
Once the tunnel is established,
.B wsssht
displays connection information:
.PP
.RS
.nf
========================================
WEBSSH TUNNEL READY
========================================
Tunnel established successfully!
Local port: 49234
Target: user@myclient.example.com
Connect manually using one of these commands:
Telnet:
telnet localhost 49234
Netcat:
nc localhost 49234
SSH (if connecting to SSH server):
ssh -p 49234 user@localhost
SCP (if connecting to SSH server):
scp -P 49234 user@localhost:/remote/path ./local/path
Any TCP client:
Connect to localhost:49234
Press Ctrl+C to close the tunnel and exit.
========================================
.fi
.RE
.SH CONFIGURATION
.B wsssht
supports a separate configuration file at
.I ~/.config/wsssh/wssht.conf
with the following options:
.PP
.RS
.nf
[default]
port=9898
domain=example.com
tunnel=websocket
tunnel-control=websocket
service=ssh
interval=30
.fi
.RE
.PP
Note: Unlike
.BR wsssh (1)
and
.BR wsscp (1),
.B wsssht
uses its own configuration file
.I wssht.conf
instead of sharing
.I wsssh.conf.
.SH SEE ALSO
.BR wsssh (1),
.BR wsscp (1),
.BR wssshc (1),
.BR wssshd (1)
.SH AUTHOR
Written by Stefy Lanza <stefy@nexlab.net> and SexHack.me
.SH COPYRIGHT
Copyright \(co 2024 Stefy Lanza and SexHack.me
.PP
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.
.SH BUGS
Report bugs to https://git.nexlab.net/nexlab/wsssh
\ No newline at end of file
...@@ -91,6 +91,50 @@ char *read_config_value(const char *key) { ...@@ -91,6 +91,50 @@ char *read_config_value(const char *key) {
return NULL; return NULL;
} }
char *read_config_value_from_file(const char *key, const char *config_file) {
char *home = getenv("HOME");
if (!home) return NULL;
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/.config/wsssh/%s.conf", home, config_file);
FILE *f = fopen(path, "r");
if (!f) return NULL;
char line[256];
char section[64] = "";
while (fgets(line, sizeof(line), f)) {
// Check for section headers
if (line[0] == '[') {
sscanf(line, "[%63[^]]", section);
continue;
}
// Skip comments and empty lines
if (line[0] == '#' || line[0] == ';' || line[0] == '\n') continue;
char *equals = strchr(line, '=');
if (equals) {
*equals = '\0';
char *config_key = line;
char *value = equals + 1;
// Trim whitespace
while (*config_key == ' ' || *config_key == '\t') config_key++;
char *end = config_key + strlen(config_key) - 1;
while (end > config_key && (*end == ' ' || *end == '\t')) *end-- = '\0';
while (*value == ' ' || *value == '\t') value++;
end = value + strlen(value) - 1;
while (end > value && (*end == ' ' || *end == '\t' || *end == '\n')) *end-- = '\0';
// Check if key matches (case-insensitive for section names)
if (strcmp(config_key, key) == 0) {
fclose(f);
return strdup(value);
}
}
}
fclose(f);
return NULL;
}
void print_trans_flag(void) { void print_trans_flag(void) {
// Transgender pride flag colors using ANSI escape codes // Transgender pride flag colors using ANSI escape codes
const char *colors[] = { const char *colors[] = {
......
...@@ -88,6 +88,7 @@ typedef struct { ...@@ -88,6 +88,7 @@ typedef struct {
// Function declarations // Function declarations
char *read_config_value(const char *key); char *read_config_value(const char *key);
char *read_config_value_from_file(const char *key, const char *config_file);
char *expand_transport_list(const char *transport_spec, int for_relay); char *expand_transport_list(const char *transport_spec, int for_relay);
char *select_best_transport(const char *transport_list); char *select_best_transport(const char *transport_list);
int get_transport_weight(const char *transport); int get_transport_weight(const char *transport);
......
This diff is collapsed.
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