diff --git a/mosh b/mosh new file mode 100755 index 0000000..b4bf559 --- /dev/null +++ b/mosh @@ -0,0 +1,65 @@ +#!/usr/bin/env perl + +use warnings; +use strict; +use Socket; +use IO::Pty; + +$|=1; + +if ( scalar @ARGV != 3 ) { + die "Usage: $0 HOST MOSHCLIENT MOSHSERVER\n"; +} + +my ( $host, $client, $server ) = @ARGV; + +# Resolve hostname +my $packed_ip = gethostbyname $host; +if ( not defined $packed_ip ) { + die "$0: Could not resolve hostname $host\n"; +} +my $ip = inet_ntoa $packed_ip; + +# Run SSH and read password +my $pty = new IO::Pty; +my $pty_slave = $pty->slave; + +$pty_slave->clone_winsize_from( \*STDIN ); + +my $pid = fork; +die "$0: fork: $!\n" unless ( defined $pid ); +if ( $pid == 0 ) { # child + close $pty; + open STDIN, "<&", $pty_slave->fileno() or die; + open STDOUT, ">&", $pty_slave->fileno() or die; + open STDERR, ">&", $pty_slave->fileno() or die; + close $pty_slave; + + exec {'ssh'} ('ssh', '-t', $ip, $server, $ip); + die "Cannot exec ssh: $!\n"; +} else { # server + my ( $port, $key ); + $pty->close_slave(); + LINE: while ( <$pty> ) { + chomp; + if ( m{^MOSH CONNECT} ) { + if ( ( $port, $key ) = m{^MOSH CONNECT (\d+?) (.{22})} ) { + print $pty "\n~."; # Tear down SSH connection + last LINE; + } else { + die "Bad MOSH CONNECT string\n"; + } + } else { + print "$_\n"; + } + } + waitpid $pid, 0; + + if ( not defined $port ) { + die "$0: Did not find mosh server startup message.\n"; + } + + # Now start real mosh client + $ENV{ 'MOSH_KEY' } = $key; + exec {$client} ($client, $ip, $port); +} diff --git a/mosh-client.cpp b/mosh-client.cpp index 7e50b19..878fe2b 100644 --- a/mosh-client.cpp +++ b/mosh-client.cpp @@ -1,8 +1,9 @@ +#include +#include + #include "stmclient.hpp" #include "crypto.hpp" -#include - int main( int argc, char *argv[] ) { /* Get arguments */ @@ -17,10 +18,23 @@ int main( int argc, char *argv[] ) ip = argv[ 1 ]; port = myatoi( argv[ 2 ] ); - /* Read key from standard input */ - cout << "Key: "; - string key; - cin >> key; + /* Read key from environment */ + char *env_key = getenv( "MOSH_KEY" ); + if ( env_key == NULL ) { + fprintf( stderr, "MOSH_KEY environment variable not found.\n" ); + exit( 1 ); + } + + char *key = strdup( env_key ); + if ( key == NULL ) { + perror( "strdup" ); + exit( 1 ); + } + + if ( unsetenv( "MOSH_KEY" ) < 0 ) { + perror( "unsetenv" ); + exit( 1 ); + } /* Adopt native locale */ if ( NULL == setlocale( LC_ALL, "" ) ) { @@ -28,7 +42,7 @@ int main( int argc, char *argv[] ) exit( 1 ); } - STMClient client( ip, port, key.c_str() ); + STMClient client( ip, port, key ); client.init(); @@ -38,5 +52,7 @@ int main( int argc, char *argv[] ) printf( "\n[mosh is exiting.]\n" ); + free( key ); + return 0; }