Merge pull request #1789 from webmin/dev/xterm-fixes

Add minor clean ups
This commit is contained in:
Jamie Cameron
2022-11-14 15:04:15 -08:00
committed by GitHub
3 changed files with 71 additions and 57 deletions

View File

@@ -138,33 +138,8 @@ EOF
# Print main container
print "<div data-label=\"$text{'index_connecting'}\" id=\"terminal\"></div>\n";
# Find ports already in use
&lock_file(&get_miniserv_config_file());
my %miniserv;
&get_miniserv_config(\%miniserv);
my %inuse;
foreach my $k (keys %miniserv) {
if ($k =~ /^websockets_/ && $miniserv{$k} =~ /port=(\d+)/) {
$inuse{$1} = 1;
}
}
# Pick a port and configure Webmin to proxy it
my $port = $config{'base_port'} || 555;
while(1) {
if (!$inuse{$port}) {
&open_socket("127.0.0.1", $port, my $fh, \$err);
last if ($err);
close($fh);
}
$port++;
}
my $wspath = "/$module_name/ws-".$port;
my $now = time();
$miniserv{'websockets_'.$wspath} = "host=127.0.0.1 port=$port wspath=/ user=$remote_user time=$now";
&put_miniserv_config(\%miniserv);
&unlock_file(&get_miniserv_config_file());
&reload_miniserv();
# Get a free port that can be used for the socket
my $port = &allocate_miniserv_websocket();
# Check permissions for user to run as
my $user = $access{'user'};
@@ -197,7 +172,7 @@ $ENV{'SESSION_ID'} = $main::session_id;
" >$tmpdir/ws-$port.out 2>&1 </dev/null");
# Open the terminal
my $url = "wss://".$ENV{'HTTP_HOST'}.$wspath;
my $url = "wss://$ENV{'HTTP_HOST'}/$module_name/ws-$port";
my $term_script = <<EOF;
(function() {
@@ -254,5 +229,3 @@ else {
}
print "</script>\n";
&ui_print_footer();
&cleanup_old_websockets([$port]);

View File

@@ -14,7 +14,7 @@ my @uinfo = getpwnam($user);
my ($uid, $gid);
if ($user ne "root" && !$<) {
if (!@uinfo) {
&cleanup_miniserv();
&remove_miniserv_websocket($port);
die "User $user does not exist!";
}
$uid = $uinfo[2];
@@ -68,7 +68,7 @@ my ($shellfh, $pid) = &proc::pty_process_exec($shellexec, $uid, $gid, $shelllogi
&reset_environment();
my $shcmd = "'$shellexec".($shelllogin ? " $shelllogin" : "")."'";
if (!$pid) {
&cleanup_miniserv();
&remove_miniserv_websocket($port);
die "Failed to run shell with $shcmd\n";
}
else {
@@ -82,8 +82,9 @@ if (fork()) {
untie(*STDIN);
close(STDIN);
# Clean up when socket is terminated
$SIG{'ALRM'} = sub {
&cleanup_miniserv();
&remove_miniserv_websocket($port);
die "timeout waiting for connection";
};
alarm(60);
@@ -133,13 +134,13 @@ Net::WebSocket::Server->new(
}
if (!syswrite($shellfh, $msg, length($msg))) {
print STDERR "write to shell failed : $!\n";
&cleanup_miniserv();
&remove_miniserv_websocket($port);
exit(1);
}
},
disconnect => sub {
print STDERR "websocket connection closed\n";
&cleanup_miniserv();
&remove_miniserv_websocket($port);
kill('KILL', $pid) if ($pid);
exit(0);
}
@@ -152,7 +153,7 @@ Net::WebSocket::Server->new(
my $ok = sysread($shellfh, $buf, 1024);
if ($ok <= 0) {
print STDERR "end of output from shell\n";
&cleanup_miniserv();
&remove_miniserv_websocket($port);
exit(0);
}
if ($wsconn) {
@@ -165,20 +166,5 @@ Net::WebSocket::Server->new(
],
)->start;
print STDERR "exited websockets server\n";
&cleanup_miniserv();
sub cleanup_miniserv
{
my %miniserv;
if ($port) {
&lock_file(&get_miniserv_config_file());
&get_miniserv_config(\%miniserv);
my $wspath = "/$module_name/ws-".$port;
if ($miniserv{'websockets_'.$wspath}) {
delete($miniserv{'websockets_'.$wspath});
&put_miniserv_config(\%miniserv);
&reload_miniserv();
}
&unlock_file(&get_miniserv_config_file());
}
}
&remove_miniserv_websocket($port);
&cleanup_miniserv_websockets([$port]);

View File

@@ -5,10 +5,65 @@ use WebminCore;
&init_config();
our %access = &get_module_acl();
# cleanup_old_websockets([&skip-ports])
# Called by scheduled status collection to remove any websockets in
# miniserv.conf that are no longer used
sub cleanup_old_websockets
# allocate_miniserv_websocket()
# Allocate a new websocket and
# stores it miniserv.conf file
sub allocate_miniserv_websocket
{
# Find ports already in use
&lock_file(&get_miniserv_config_file());
my %miniserv;
&get_miniserv_config(\%miniserv);
my %inuse;
foreach my $k (keys %miniserv) {
if ($k =~ /^websockets_/ && $miniserv{$k} =~ /port=(\d+)/) {
$inuse{$1} = 1;
}
}
# Pick a port and configure Webmin to proxy it
my $port = $config{'base_port'} || 555;
while(1) {
if (!$inuse{$port}) {
&open_socket("127.0.0.1", $port, my $fh, \$err);
last if ($err);
close($fh);
}
$port++;
}
my $wspath = "/$module_name/ws-".$port;
my $now = time();
$miniserv{'websockets_'.$wspath} = "host=127.0.0.1 port=$port wspath=/ user=$remote_user time=$now";
&put_miniserv_config(\%miniserv);
&unlock_file(&get_miniserv_config_file());
&reload_miniserv();
return $port;
}
# remove_miniserv_websocket(port)
# Remove old websocket
# from miniserv.conf
sub remove_miniserv_websocket
{
my ($port) = @_;
my %miniserv;
if ($port) {
&lock_file(&get_miniserv_config_file());
&get_miniserv_config(\%miniserv);
my $wspath = "/$module_name/ws-".$port;
if ($miniserv{'websockets_'.$wspath}) {
delete($miniserv{'websockets_'.$wspath});
&put_miniserv_config(\%miniserv);
&reload_miniserv();
}
&unlock_file(&get_miniserv_config_file());
}
}
# cleanup_miniserv_websockets([&skip-ports])
# Called by scheduled status collection to remove any
# websockets in miniserv.conf that are no longer used
sub cleanup_miniserv_websockets
{
my ($skip) = @_;
$skip ||= [ ];