Mercurial > dropbear
diff cli-session.c @ 801:7dcb46da72d9 ecc
merge in HEAD
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 21 May 2013 12:09:35 +0800 |
parents | 7f604f9b3756 2400b8685762 |
children | c19acba28590 |
line wrap: on
line diff
--- a/cli-session.c Thu May 09 23:27:23 2013 +0800 +++ b/cli-session.c Tue May 21 12:09:35 2013 +0800 @@ -42,6 +42,8 @@ static void cli_sessionloop(); static void cli_session_init(); static void cli_finished(); +static void recv_msg_service_accept(void); +static void cli_session_cleanup(void); struct clientsession cli_ses; /* GLOBAL */ @@ -96,7 +98,7 @@ sessinitdone = 1; /* Exchange identification */ - session_identification(); + send_session_identification(); send_msg_kexinit(); @@ -106,6 +108,12 @@ } +#ifdef USE_KEX_FIRST_FOLLOWS +static void cli_send_kex_first_guess() { + send_msg_kexdh_init(); +} +#endif + static void cli_session_init() { cli_ses.state = STATE_NOTHING; @@ -139,37 +147,61 @@ /* For printing "remote host closed" for the user */ ses.remoteclosed = cli_remoteclosed; - ses.buf_match_algo = cli_buf_match_algo; + + ses.extra_session_cleanup = cli_session_cleanup; /* packet handlers */ ses.packettypes = cli_packettypes; ses.isserver = 0; + +#ifdef USE_KEX_FIRST_FOLLOWS + ses.send_kex_first_guess = cli_send_kex_first_guess; +#endif + +} + +static void send_msg_service_request(char* servicename) { + + TRACE(("enter send_msg_service_request: servicename='%s'", servicename)) + + CHECKCLEARTOWRITE(); + + buf_putbyte(ses.writepayload, SSH_MSG_SERVICE_REQUEST); + buf_putstring(ses.writepayload, servicename, strlen(servicename)); + + encrypt_packet(); + TRACE(("leave send_msg_service_request")) +} + +static void recv_msg_service_accept(void) { + // do nothing, if it failed then the server MUST have disconnected } /* This function drives the progress of the session - it initiates KEX, * service, userauth and channel requests */ static void cli_sessionloop() { - TRACE(("enter cli_sessionloop")) + TRACE2(("enter cli_sessionloop")) - if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) { - cli_ses.kex_state = KEXINIT_RCVD; + if (ses.lastpacket == 0) { + TRACE2(("exit cli_sessionloop: no real packets yet")) + return; } - if (cli_ses.kex_state == KEXINIT_RCVD) { - + if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) { /* We initiate the KEXDH. If DH wasn't the correct type, the KEXINIT * negotiation would have failed. */ - send_msg_kexdh_init(); - cli_ses.kex_state = KEXDH_INIT_SENT; + if (!ses.kexstate.our_first_follows_matches) { + send_msg_kexdh_init(); + } + cli_ses.kex_state = KEXDH_INIT_SENT; TRACE(("leave cli_sessionloop: done with KEXINIT_RCVD")) return; } /* A KEX has finished, so we should go back to our KEX_NOTHING state */ - if (cli_ses.kex_state != KEX_NOTHING && ses.kexstate.recvkexinit == 0 - && ses.kexstate.sentkexinit == 0) { + if (cli_ses.kex_state != KEX_NOTHING && ses.kexstate.sentnewkeys) { cli_ses.kex_state = KEX_NOTHING; } @@ -179,10 +211,10 @@ return; } - /* We should exit if we haven't donefirstkex: we shouldn't reach here - * in normal operation */ if (ses.kexstate.donefirstkex == 0) { - TRACE(("XXX XXX might be bad! leave cli_sessionloop: haven't donefirstkex")) + /* We might reach here if we have partial packet reads or have + * received SSG_MSG_IGNORE etc. Just skip it */ + TRACE2(("donefirstkex false\n")) return; } @@ -192,19 +224,15 @@ /* We've got the transport layer sorted, we now need to request * userauth */ send_msg_service_request(SSH_SERVICE_USERAUTH); - cli_ses.state = SERVICE_AUTH_REQ_SENT; - TRACE(("leave cli_sessionloop: sent userauth service req")) - return; - - /* userauth code */ - case SERVICE_AUTH_ACCEPT_RCVD: cli_auth_getmethods(); cli_ses.state = USERAUTH_REQ_SENT; TRACE(("leave cli_sessionloop: sent userauth methods req")) return; case USERAUTH_FAIL_RCVD: - cli_auth_try(); + if (cli_auth_try() == DROPBEAR_FAILURE) { + dropbear_exit("No auth methods could be used."); + } cli_ses.state = USERAUTH_REQ_SENT; TRACE(("leave cli_sessionloop: cli_auth_try")) return; @@ -235,13 +263,6 @@ } } -#ifdef ENABLE_CLI_LOCALTCPFWD - setup_localtcp(); -#endif -#ifdef ENABLE_CLI_REMOTETCPFWD - setup_remotetcp(); -#endif - #ifdef ENABLE_CLI_NETCAT if (cli_opts.netcat_host) { cli_send_netcat_request(); @@ -250,6 +271,14 @@ if (!cli_opts.no_cmd) { cli_send_chansess_request(); } + +#ifdef ENABLE_CLI_LOCALTCPFWD + setup_localtcp(); +#endif +#ifdef ENABLE_CLI_REMOTETCPFWD + setup_remotetcp(); +#endif + TRACE(("leave cli_sessionloop: running")) cli_ses.state = SESSION_RUNNING; return; @@ -271,11 +300,11 @@ break; } - TRACE(("leave cli_sessionloop: fell out")) + TRACE2(("leave cli_sessionloop: fell out")) } -void cli_session_cleanup() { +static void cli_session_cleanup(void) { if (!sessinitdone) { return; @@ -293,8 +322,7 @@ static void cli_finished() { - cli_session_cleanup(); - common_session_cleanup(); + session_cleanup(); fprintf(stderr, "Connection to %s@%s:%s closed.\n", cli_opts.username, cli_opts.remotehost, cli_opts.remoteport); exit(cli_ses.retval);