Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
wsssh
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexlab
wsssh
Commits
96207bd8
Commit
96207bd8
authored
Sep 17, 2025
by
Stefy Lanza (nextime / spora )
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix wssshc tunnel handling - remove SSH protocol logic, implement raw TCP forwarding
parent
1114c673
Changes
4
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
173 additions
and
197 deletions
+173
-197
tunnel.c
wssshtools/tunnel.c
+102
-170
tunnel.h
wssshtools/tunnel.h
+1
-1
wsssh.c
wssshtools/wsssh.c
+1
-0
wssshc.c
wssshtools/wssshc.c
+69
-26
No files found.
wssshtools/tunnel.c
View file @
96207bd8
This diff is collapsed.
Click to expand it.
wssshtools/tunnel.h
View file @
96207bd8
...
@@ -58,7 +58,7 @@ void *forward_tcp_to_ws(void *arg);
...
@@ -58,7 +58,7 @@ void *forward_tcp_to_ws(void *arg);
void
*
forward_ws_to_local
(
void
*
arg
);
void
*
forward_ws_to_local
(
void
*
arg
);
void
*
forward_ws_to_ssh_server
(
void
*
arg
);
void
*
forward_ws_to_ssh_server
(
void
*
arg
);
void
*
tunnel_thread
(
void
*
arg
);
void
*
tunnel_thread
(
void
*
arg
);
void
handle_tunnel_request
(
SSL
*
ssl
,
const
char
*
request_id
,
int
debug
);
void
handle_tunnel_request
(
SSL
*
ssl
,
const
char
*
request_id
,
int
debug
,
const
char
*
ssh_host
,
int
ssh_port
);
void
handle_tunnel_data
(
SSL
*
ssl
,
const
char
*
request_id
,
const
char
*
data_hex
,
int
debug
);
void
handle_tunnel_data
(
SSL
*
ssl
,
const
char
*
request_id
,
const
char
*
data_hex
,
int
debug
);
void
handle_tunnel_close
(
SSL
*
ssl
,
const
char
*
request_id
,
int
debug
);
void
handle_tunnel_close
(
SSL
*
ssl
,
const
char
*
request_id
,
int
debug
);
void
send_tunnel_close
(
SSL
*
ssl
,
const
char
*
request_id
,
int
debug
);
void
send_tunnel_close
(
SSL
*
ssl
,
const
char
*
request_id
,
int
debug
);
...
...
wssshtools/wsssh.c
View file @
96207bd8
...
@@ -236,6 +236,7 @@ char **modify_ssh_args(int argc, char *argv[], const char *original_host, int lo
...
@@ -236,6 +236,7 @@ char **modify_ssh_args(int argc, char *argv[], const char *original_host, int lo
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
// Read config
// Read config
char
*
config_domain
=
read_config_value
(
"domain"
);
char
*
config_domain
=
read_config_value
(
"domain"
);
...
...
wssshtools/wssshc.c
View file @
96207bd8
...
@@ -41,8 +41,10 @@ int global_debug = 0;
...
@@ -41,8 +41,10 @@ int global_debug = 0;
typedef
struct
{
typedef
struct
{
char
*
server_ip
;
char
*
wssshd_server
;
int
port
;
int
wssshd_port
;
char
*
ssh_host
;
int
ssh_port
;
char
*
client_id
;
char
*
client_id
;
char
*
password
;
char
*
password
;
int
interval
;
int
interval
;
...
@@ -73,12 +75,18 @@ void load_config_file(const char *config_path, wssshc_config_t *config) {
...
@@ -73,12 +75,18 @@ void load_config_file(const char *config_path, wssshc_config_t *config) {
while
(
end
>
value
&&
*
end
==
' '
)
*
end
--
=
0
;
while
(
end
>
value
&&
*
end
==
' '
)
*
end
--
=
0
;
if
(
strcmp
(
key
,
"password"
)
==
0
&&
!
config
->
password
)
{
if
(
strcmp
(
key
,
"password"
)
==
0
&&
!
config
->
password
)
{
config
->
password
=
strdup
(
value
);
config
->
password
=
strdup
(
value
);
}
else
if
(
strcmp
(
key
,
"server-ip"
)
==
0
&&
!
config
->
server_ip
)
{
}
else
if
(
strcmp
(
key
,
"wssshd-server"
)
==
0
&&
!
config
->
wssshd_server
)
{
config
->
server_ip
=
strdup
(
value
);
config
->
wssshd_server
=
strdup
(
value
);
}
else
if
(
strcmp
(
key
,
"domain"
)
==
0
&&
!
config
->
server_ip
)
{
}
else
if
(
strcmp
(
key
,
"domain"
)
==
0
&&
!
config
->
wssshd_server
)
{
config
->
server_ip
=
strdup
(
value
);
config
->
wssshd_server
=
strdup
(
value
);
}
else
if
(
strcmp
(
key
,
"port"
)
==
0
)
{
}
else
if
(
strcmp
(
key
,
"wssshd-port"
)
==
0
)
{
config
->
port
=
atoi
(
value
);
config
->
wssshd_port
=
atoi
(
value
);
}
else
if
(
strcmp
(
key
,
"port"
)
==
0
&&
config
->
wssshd_port
==
9898
)
{
config
->
wssshd_port
=
atoi
(
value
);
}
else
if
(
strcmp
(
key
,
"ssh-host"
)
==
0
&&
!
config
->
ssh_host
)
{
config
->
ssh_host
=
strdup
(
value
);
}
else
if
(
strcmp
(
key
,
"ssh-port"
)
==
0
)
{
config
->
ssh_port
=
atoi
(
value
);
}
else
if
(
strcmp
(
key
,
"id"
)
==
0
&&
!
config
->
client_id
)
{
}
else
if
(
strcmp
(
key
,
"id"
)
==
0
&&
!
config
->
client_id
)
{
config
->
client_id
=
strdup
(
value
);
config
->
client_id
=
strdup
(
value
);
}
else
if
(
strcmp
(
key
,
"interval"
)
==
0
)
{
}
else
if
(
strcmp
(
key
,
"interval"
)
==
0
)
{
...
@@ -117,8 +125,10 @@ void print_usage(const char *program_name) {
...
@@ -117,8 +125,10 @@ void print_usage(const char *program_name) {
fprintf
(
stderr
,
"Protect the dolls!
\n\n
"
);
fprintf
(
stderr
,
"Protect the dolls!
\n\n
"
);
fprintf
(
stderr
,
"Options:
\n
"
);
fprintf
(
stderr
,
"Options:
\n
"
);
fprintf
(
stderr
,
" --config FILE Configuration file path (overrides default hierarchy)
\n
"
);
fprintf
(
stderr
,
" --config FILE Configuration file path (overrides default hierarchy)
\n
"
);
fprintf
(
stderr
,
" --server-ip IP Server IP address
\n
"
);
fprintf
(
stderr
,
" --wssshd-server HOST WSSSHD server host (default: mbeted.nexlab.net)
\n
"
);
fprintf
(
stderr
,
" --port PORT Server port (default: %d)
\n
"
,
DEFAULT_PORT
);
fprintf
(
stderr
,
" --wssshd-port PORT WSSSHD server port (default: 9898)
\n
"
);
fprintf
(
stderr
,
" --ssh-host HOST SSH host to forward tunnel data to (default: 127.0.0.1)
\n
"
);
fprintf
(
stderr
,
" --ssh-port PORT SSH port to forward tunnel data to (default: 22)
\n
"
);
fprintf
(
stderr
,
" --id ID Client identifier
\n
"
);
fprintf
(
stderr
,
" --id ID Client identifier
\n
"
);
fprintf
(
stderr
,
" --password PASS Registration password
\n
"
);
fprintf
(
stderr
,
" --password PASS Registration password
\n
"
);
fprintf
(
stderr
,
" --interval SEC Reconnection interval (default: 30)
\n
"
);
fprintf
(
stderr
,
" --interval SEC Reconnection interval (default: 30)
\n
"
);
...
@@ -136,8 +146,10 @@ void print_usage(const char *program_name) {
...
@@ -136,8 +146,10 @@ void print_usage(const char *program_name) {
int
parse_args
(
int
argc
,
char
*
argv
[],
wssshc_config_t
*
config
)
{
int
parse_args
(
int
argc
,
char
*
argv
[],
wssshc_config_t
*
config
)
{
static
struct
option
long_options
[]
=
{
static
struct
option
long_options
[]
=
{
{
"config"
,
required_argument
,
0
,
'c'
},
{
"config"
,
required_argument
,
0
,
'c'
},
{
"server-ip"
,
required_argument
,
0
,
's'
},
{
"wssshd-server"
,
required_argument
,
0
,
's'
},
{
"port"
,
required_argument
,
0
,
'p'
},
{
"wssshd-port"
,
required_argument
,
0
,
'p'
},
{
"ssh-host"
,
required_argument
,
0
,
'H'
},
{
"ssh-port"
,
required_argument
,
0
,
'P'
},
{
"id"
,
required_argument
,
0
,
'i'
},
{
"id"
,
required_argument
,
0
,
'i'
},
{
"password"
,
required_argument
,
0
,
'w'
},
{
"password"
,
required_argument
,
0
,
'w'
},
{
"interval"
,
required_argument
,
0
,
't'
},
{
"interval"
,
required_argument
,
0
,
't'
},
...
@@ -149,17 +161,24 @@ int parse_args(int argc, char *argv[], wssshc_config_t *config) {
...
@@ -149,17 +161,24 @@ int parse_args(int argc, char *argv[], wssshc_config_t *config) {
int
opt
;
int
opt
;
char
*
custom_config
=
NULL
;
char
*
custom_config
=
NULL
;
while
((
opt
=
getopt_long
(
argc
,
argv
,
"c:s:p:i:w:t:dh"
,
long_options
,
NULL
))
!=
-
1
)
{
while
((
opt
=
getopt_long
(
argc
,
argv
,
"c:s:p:
H:P:
i:w:t:dh"
,
long_options
,
NULL
))
!=
-
1
)
{
switch
(
opt
)
{
switch
(
opt
)
{
case
'c'
:
case
'c'
:
custom_config
=
optarg
;
custom_config
=
optarg
;
break
;
break
;
case
's'
:
case
's'
:
if
(
config
->
server_ip
)
free
(
config
->
server_ip
);
if
(
config
->
wssshd_server
)
free
(
config
->
wssshd_server
);
config
->
server_ip
=
strdup
(
optarg
);
config
->
wssshd_server
=
strdup
(
optarg
);
break
;
break
;
case
'p'
:
case
'p'
:
config
->
port
=
atoi
(
optarg
);
config
->
wssshd_port
=
atoi
(
optarg
);
break
;
case
'H'
:
if
(
config
->
ssh_host
)
free
(
config
->
ssh_host
);
config
->
ssh_host
=
strdup
(
optarg
);
break
;
case
'P'
:
config
->
ssh_port
=
atoi
(
optarg
);
break
;
break
;
case
'i'
:
case
'i'
:
if
(
config
->
client_id
)
free
(
config
->
client_id
);
if
(
config
->
client_id
)
free
(
config
->
client_id
);
...
@@ -215,7 +234,7 @@ int connect_to_server(const wssshc_config_t *config) {
...
@@ -215,7 +234,7 @@ int connect_to_server(const wssshc_config_t *config) {
cleanup_tunnel
(
config
->
debug
);
cleanup_tunnel
(
config
->
debug
);
// Resolve hostname
// Resolve hostname
if
((
he
=
gethostbyname
(
config
->
server_ip
))
==
NULL
)
{
if
((
he
=
gethostbyname
(
config
->
wssshd_server
))
==
NULL
)
{
herror
(
"gethostbyname"
);
herror
(
"gethostbyname"
);
return
1
;
return
1
;
}
}
...
@@ -228,7 +247,7 @@ int connect_to_server(const wssshc_config_t *config) {
...
@@ -228,7 +247,7 @@ int connect_to_server(const wssshc_config_t *config) {
memset
(
&
server_addr
,
0
,
sizeof
(
server_addr
));
memset
(
&
server_addr
,
0
,
sizeof
(
server_addr
));
server_addr
.
sin_family
=
AF_INET
;
server_addr
.
sin_family
=
AF_INET
;
server_addr
.
sin_port
=
htons
(
config
->
port
);
server_addr
.
sin_port
=
htons
(
config
->
wssshd_
port
);
server_addr
.
sin_addr
=
*
((
struct
in_addr
*
)
he
->
h_addr
);
server_addr
.
sin_addr
=
*
((
struct
in_addr
*
)
he
->
h_addr
);
// Connect to server
// Connect to server
...
@@ -257,7 +276,7 @@ int connect_to_server(const wssshc_config_t *config) {
...
@@ -257,7 +276,7 @@ int connect_to_server(const wssshc_config_t *config) {
}
}
// Perform WebSocket handshake
// Perform WebSocket handshake
if
(
!
websocket_handshake
(
ssl
,
config
->
server_ip
,
config
->
port
,
"/"
))
{
if
(
!
websocket_handshake
(
ssl
,
config
->
wssshd_server
,
config
->
wssshd_
port
,
"/"
))
{
SSL_free
(
ssl
);
SSL_free
(
ssl
);
SSL_CTX_free
(
ssl_ctx
);
SSL_CTX_free
(
ssl_ctx
);
close
(
sock
);
close
(
sock
);
...
@@ -456,7 +475,7 @@ int connect_to_server(const wssshc_config_t *config) {
...
@@ -456,7 +475,7 @@ int connect_to_server(const wssshc_config_t *config) {
printf
(
"[DEBUG - WebSockets] Received tunnel_request for ID: %s
\n
"
,
id_start
);
printf
(
"[DEBUG - WebSockets] Received tunnel_request for ID: %s
\n
"
,
id_start
);
fflush
(
stdout
);
fflush
(
stdout
);
}
}
handle_tunnel_request
(
ssl
,
id_start
,
config
->
debug
);
handle_tunnel_request
(
ssl
,
id_start
,
config
->
debug
,
config
->
ssh_host
,
config
->
ssh_port
);
}
}
}
}
}
}
...
@@ -648,8 +667,10 @@ int connect_to_server(const wssshc_config_t *config) {
...
@@ -648,8 +667,10 @@ int connect_to_server(const wssshc_config_t *config) {
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
wssshc_config_t
config
=
{
wssshc_config_t
config
=
{
.
server_ip
=
NULL
,
.
wssshd_server
=
NULL
,
.
port
=
DEFAULT_PORT
,
.
wssshd_port
=
9898
,
.
ssh_host
=
NULL
,
.
ssh_port
=
22
,
.
client_id
=
NULL
,
.
client_id
=
NULL
,
.
password
=
NULL
,
.
password
=
NULL
,
.
interval
=
30
,
.
interval
=
30
,
...
@@ -667,11 +688,20 @@ int main(int argc, char *argv[]) {
...
@@ -667,11 +688,20 @@ int main(int argc, char *argv[]) {
return
1
;
return
1
;
}
}
// Set defaults for optional fields
if
(
!
config
.
wssshd_server
)
{
config
.
wssshd_server
=
strdup
(
"mbeted.nexlab.net"
);
}
if
(
!
config
.
ssh_host
)
{
config
.
ssh_host
=
strdup
(
"127.0.0.1"
);
}
// Validate required arguments
// Validate required arguments
if
(
!
config
.
server_ip
||
!
config
.
client_id
||
!
config
.
password
)
{
if
(
!
config
.
client_id
||
!
config
.
password
)
{
fprintf
(
stderr
,
"Error: --
server-ip, --id,
and --password are required
\n
"
);
fprintf
(
stderr
,
"Error: --
id
and --password are required
\n
"
);
print_usage
(
argv
[
0
]);
print_usage
(
argv
[
0
]);
if
(
config
.
server_ip
)
free
(
config
.
server_ip
);
if
(
config
.
wssshd_server
)
free
(
config
.
wssshd_server
);
if
(
config
.
ssh_host
)
free
(
config
.
ssh_host
);
if
(
config
.
client_id
)
free
(
config
.
client_id
);
if
(
config
.
client_id
)
free
(
config
.
client_id
);
if
(
config
.
password
)
free
(
config
.
password
);
if
(
config
.
password
)
free
(
config
.
password
);
pthread_mutex_destroy
(
&
tunnel_mutex
);
pthread_mutex_destroy
(
&
tunnel_mutex
);
...
@@ -679,7 +709,19 @@ int main(int argc, char *argv[]) {
...
@@ -679,7 +709,19 @@ int main(int argc, char *argv[]) {
}
}
global_debug
=
config
.
debug
;
global_debug
=
config
.
debug
;
// Print configured options
printf
(
"WebSocket SSH Client starting...
\n
"
);
printf
(
"WebSocket SSH Client starting...
\n
"
);
printf
(
"Configuration:
\n
"
);
printf
(
" WSSSHD Server: %s
\n
"
,
config
.
wssshd_server
?
config
.
wssshd_server
:
"(null)"
);
printf
(
" WSSSHD Port: %d
\n
"
,
config
.
wssshd_port
);
printf
(
" SSH Host: %s
\n
"
,
config
.
ssh_host
?
config
.
ssh_host
:
"(null)"
);
printf
(
" SSH Port: %d
\n
"
,
config
.
ssh_port
);
printf
(
" Client ID: %s
\n
"
,
config
.
client_id
?
config
.
client_id
:
"(null)"
);
printf
(
" Password: %s
\n
"
,
config
.
password
?
"***"
:
"(null)"
);
printf
(
" Reconnection Interval: %d seconds
\n
"
,
config
.
interval
);
printf
(
" Debug Mode: %s
\n
"
,
config
.
debug
?
"enabled"
:
"disabled"
);
printf
(
"
\n
"
);
while
(
1
)
{
while
(
1
)
{
int
result
=
connect_to_server
(
&
config
);
int
result
=
connect_to_server
(
&
config
);
...
@@ -699,7 +741,8 @@ int main(int argc, char *argv[]) {
...
@@ -699,7 +741,8 @@ int main(int argc, char *argv[]) {
}
}
// Cleanup
// Cleanup
free
(
config
.
server_ip
);
free
(
config
.
wssshd_server
);
free
(
config
.
ssh_host
);
free
(
config
.
client_id
);
free
(
config
.
client_id
);
free
(
config
.
password
);
free
(
config
.
password
);
pthread_mutex_destroy
(
&
tunnel_mutex
);
pthread_mutex_destroy
(
&
tunnel_mutex
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment