X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/70c0cbe19796bba2b2266e42477f0ce3bf19386a..8def70c3ec6f81f95673c0de67a75b5a6b2e9e1c:/ssh.c diff --git a/ssh.c b/ssh.c index 63aecbc2..d30626dc 100644 --- a/ssh.c +++ b/ssh.c @@ -12,6 +12,7 @@ #include "putty.h" #include "tree234.h" #include "ssh.h" +#include "sshgss.h" #ifndef FALSE #define FALSE 0 @@ -112,6 +113,12 @@ #define SSH2_MSG_CHANNEL_REQUEST 98 /* 0x62 */ #define SSH2_MSG_CHANNEL_SUCCESS 99 /* 0x63 */ #define SSH2_MSG_CHANNEL_FAILURE 100 /* 0x64 */ +#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60 +#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61 +#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63 +#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64 +#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65 +#define SSH2_MSG_USERAUTH_GSSAPI_MIC 66 /* * Packet type contexts, so that ssh2_pkt_type can correctly decode @@ -127,6 +134,7 @@ typedef enum { SSH2_PKTCTX_NOAUTH, SSH2_PKTCTX_PUBLICKEY, SSH2_PKTCTX_PASSWORD, + SSH2_PKTCTX_GSSAPI, SSH2_PKTCTX_KBDINTER } Pkt_ACtx; @@ -183,6 +191,7 @@ static const char *const ssh2_disconnect_reasons[] = { #define BUG_SSH2_DERIVEKEY 32 #define BUG_SSH2_REKEY 64 #define BUG_SSH2_PK_SESSIONID 128 +#define BUG_SSH2_MAXPKT 256 /* * Codes for terminal modes. @@ -338,6 +347,12 @@ static char *ssh1_pkt_type(int type) } static char *ssh2_pkt_type(Pkt_KCtx pkt_kctx, Pkt_ACtx pkt_actx, int type) { + translatea(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,SSH2_PKTCTX_GSSAPI); + translatea(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,SSH2_PKTCTX_GSSAPI); + translatea(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,SSH2_PKTCTX_GSSAPI); + translatea(SSH2_MSG_USERAUTH_GSSAPI_ERROR,SSH2_PKTCTX_GSSAPI); + translatea(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,SSH2_PKTCTX_GSSAPI); + translatea(SSH2_MSG_USERAUTH_GSSAPI_MIC, SSH2_PKTCTX_GSSAPI); translate(SSH2_MSG_DISCONNECT); translate(SSH2_MSG_IGNORE); translate(SSH2_MSG_UNIMPLEMENTED); @@ -809,7 +824,7 @@ struct ssh_tag { Pkt_KCtx pkt_kctx; Pkt_ACtx pkt_actx; - void *x11auth; + struct X11Display *x11disp; int version; int conn_throttle_count; @@ -895,6 +910,11 @@ struct ssh_tag { int kex_in_progress; long next_rekey, last_rekey; char *deferred_rekey_reason; /* points to STATIC string; don't free */ + + /* + * Fully qualified host name, which we need if doing GSSAPI. + */ + char *fullhostname; }; #define logevent(s) logevent(ssh->frontend, s) @@ -1267,7 +1287,7 @@ static struct Packet *ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen) PKT_INCOMING, st->pktin->type, ssh1_pkt_type(st->pktin->type), st->pktin->body, st->pktin->length, - nblanks, &blank); + nblanks, &blank, NULL); } crFinish(st->pktin); @@ -1427,7 +1447,7 @@ static struct Packet *ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen) ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx, st->pktin->type), st->pktin->data+6, st->pktin->length-6, - nblanks, &blank); + nblanks, &blank, &st->pktin->sequence); } crFinish(st->pktin); @@ -1452,7 +1472,7 @@ static int s_wrpkt_prepare(Ssh ssh, struct Packet *pkt, int *offset_p) log_packet(ssh->logctx, PKT_OUTGOING, pkt->data[12], ssh1_pkt_type(pkt->data[12]), pkt->body, pkt->length - (pkt->body - pkt->data), - pkt->nblanks, pkt->blanks); + pkt->nblanks, pkt->blanks, NULL); sfree(pkt->blanks); pkt->blanks = NULL; pkt->nblanks = 0; @@ -1492,7 +1512,8 @@ static int s_wrpkt_prepare(Ssh ssh, struct Packet *pkt, int *offset_p) static int s_write(Ssh ssh, void *data, int len) { if (ssh->logctx) - log_packet(ssh->logctx, PKT_OUTGOING, -1, NULL, data, len, 0, NULL); + log_packet(ssh->logctx, PKT_OUTGOING, -1, NULL, data, len, + 0, NULL, NULL); return sk_write(ssh->s, (char *)data, len); } @@ -1775,7 +1796,7 @@ static int ssh2_pkt_construct(Ssh ssh, struct Packet *pkt) log_packet(ssh->logctx, PKT_OUTGOING, pkt->data[5], ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx, pkt->data[5]), pkt->body, pkt->length - (pkt->body - pkt->data), - pkt->nblanks, pkt->blanks); + pkt->nblanks, pkt->blanks, &ssh->v2_outgoing_sequence); sfree(pkt->blanks); pkt->blanks = NULL; pkt->nblanks = 0; @@ -2391,6 +2412,17 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring) ssh->remote_bugs |= BUG_SSH2_REKEY; logevent("We believe remote version has SSH-2 rekey bug"); } + + if (ssh->cfg.sshbug_maxpkt2 == FORCE_ON || + (ssh->cfg.sshbug_maxpkt2 == AUTO && + (wc_match("1.36_sshlib GlobalSCAPE", imp) || + wc_match("1.36 sshlib: GlobalScape", imp)))) { + /* + * This version ignores our makpkt and needs to be throttled. + */ + ssh->remote_bugs |= BUG_SSH2_MAXPKT; + logevent("We believe remote version ignores SSH-2 maximum packet size"); + } } /* @@ -2633,7 +2665,7 @@ static void ssh_gotdata(Ssh ssh, unsigned char *data, int datalen) /* Log raw data, if we're in that mode. */ if (ssh->logctx) log_packet(ssh->logctx, PKT_INCOMING, -1, NULL, data, datalen, - 0, NULL); + 0, NULL, NULL); crBegin(ssh->ssh_gotdata_crstate); @@ -2826,12 +2858,30 @@ static const char *connect_to_host(Ssh ssh, char *host, int port, SockAddr addr; const char *err; - ssh->savedhost = snewn(1 + strlen(host), char); - strcpy(ssh->savedhost, host); + if (*ssh->cfg.loghost) { + char *colon; - if (port < 0) - port = 22; /* default ssh port */ - ssh->savedport = port; + ssh->savedhost = dupstr(ssh->cfg.loghost); + ssh->savedport = 22; /* default ssh port */ + + /* + * A colon suffix on savedhost also lets us affect + * savedport. + * + * (FIXME: do something about IPv6 address literals here.) + */ + colon = strrchr(ssh->savedhost, ':'); + if (colon) { + *colon++ = '\0'; + if (*colon) + ssh->savedport = atoi(colon); + } + } else { + ssh->savedhost = dupstr(host); + if (port < 0) + port = 22; /* default ssh port */ + ssh->savedport = port; + } /* * Try to find host. @@ -2845,6 +2895,7 @@ static const char *connect_to_host(Ssh ssh, char *host, int port, sk_addr_free(addr); return err; } + ssh->fullhostname = dupstr(*realhost); /* save in case of GSSAPI */ /* * Open socket. @@ -2869,6 +2920,14 @@ static const char *connect_to_host(Ssh ssh, char *host, int port, ssh_send_verstring(ssh, NULL); } + /* + * loghost, if configured, overrides realhost. + */ + if (*ssh->cfg.loghost) { + sfree(*realhost); + *realhost = dupstr(ssh->cfg.loghost); + } + return NULL; } @@ -4519,8 +4578,8 @@ static void ssh1_smsg_x11_open(Ssh ssh, struct Packet *pktin) c = snew(struct ssh_channel); c->ssh = ssh; - if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c, - ssh->x11auth, NULL, -1, &ssh->cfg) != NULL) { + if (x11_init(&c->u.x11.s, ssh->x11disp, c, + NULL, -1, &ssh->cfg) != NULL) { logevent("Opening X11 forward connection failed"); sfree(c); send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE, @@ -4855,11 +4914,9 @@ static void do_ssh1_connection(Ssh ssh, unsigned char *in, int inlen, } if (ssh->cfg.x11_forward) { - char proto[20], data[64]; logevent("Requesting X11 forwarding"); - ssh->x11auth = x11_invent_auth(proto, sizeof(proto), - data, sizeof(data), ssh->cfg.x11_auth); - x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display); + ssh->x11disp = x11_setup_display(ssh->cfg.x11_display, + ssh->cfg.x11_auth, &ssh->cfg); /* * Note that while we blank the X authentication data here, we don't * take any special action to blank the start of an X11 channel, @@ -4869,14 +4926,19 @@ static void do_ssh1_connection(Ssh ssh, unsigned char *in, int inlen, */ if (ssh->v1_local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER) { send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING, - PKT_STR, proto, - PKTT_PASSWORD, PKT_STR, data, PKTT_OTHER, - PKT_INT, x11_get_screen_number(ssh->cfg.x11_display), + PKT_STR, ssh->x11disp->remoteauthprotoname, + PKTT_PASSWORD, + PKT_STR, ssh->x11disp->remoteauthdatastring, + PKTT_OTHER, + PKT_INT, ssh->x11disp->screennum, PKT_END); } else { send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING, - PKT_STR, proto, - PKTT_PASSWORD, PKT_STR, data, PKTT_OTHER, PKT_END); + PKT_STR, ssh->x11disp->remoteauthprotoname, + PKTT_PASSWORD, + PKT_STR, ssh->x11disp->remoteauthdatastring, + PKTT_OTHER, + PKT_END); } do { crReturnV; @@ -6236,6 +6298,15 @@ static void ssh2_set_window(struct ssh_channel *c, int newwin) return; /* + * If the remote end has a habit of ignoring maxpkt, limit the + * window so that it has no choice (assuming it doesn't ignore the + * window as well). + */ + if ((ssh->remote_bugs & BUG_SSH2_MAXPKT) && newwin > OUR_V2_MAXPKT) + newwin = OUR_V2_MAXPKT; + + + /* * Only send a WINDOW_ADJUST if there's significantly more window * available than the other end thinks there is. This saves us * sending a WINDOW_ADJUST for every character in a shell session. @@ -6677,7 +6748,7 @@ static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin) int msglen = 0, core = FALSE; /* ICK: older versions of OpenSSH (e.g. 3.4p1) * provide an `int' for the signal, despite its - * having been a `string' in the drafts since at + * having been a `string' in the drafts of RFC 4254 since at * least 2001. (Fixed in session.c 1.147.) Try to * infer which we can safely parse it as. */ { @@ -6720,7 +6791,7 @@ static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin) fmt_sig = dupprintf(" %d", signum); ssh->exitcode = 128 + signum; } else { - /* As per the drafts. */ + /* As per RFC 4254. */ char *sig; int siglen; ssh_pkt_getstring(pktin, &sig, &siglen); @@ -6871,9 +6942,8 @@ static void ssh2_msg_channel_open(Ssh ssh, struct Packet *pktin) if (!ssh->X11_fwd_enabled) error = "X11 forwarding is not enabled"; - else if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c, - ssh->x11auth, addrstr, peerport, - &ssh->cfg) != NULL) { + else if (x11_init(&c->u.x11.s, ssh->x11disp, c, + addrstr, peerport, &ssh->cfg) != NULL) { error = "Unable to open an X11 connection"; } else { logevent("Opening X11 forward connection succeeded"); @@ -6996,12 +7066,15 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, AUTH_TYPE_PUBLICKEY_OFFER_LOUD, AUTH_TYPE_PUBLICKEY_OFFER_QUIET, AUTH_TYPE_PASSWORD, + AUTH_TYPE_GSSAPI, AUTH_TYPE_KEYBOARD_INTERACTIVE, AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET } type; int done_service_req; int gotit, need_pw, can_pubkey, can_passwd, can_keyb_inter; int tried_pubkey_config, done_agent; + int can_gssapi; + int tried_gssapi; int kbd_inter_refused; int we_are_in; prompts_t *cur_prompt; @@ -7025,6 +7098,11 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int try_send; int num_env, env_left, env_ok; struct Packet *pktout; + Ssh_gss_ctx gss_ctx; + Ssh_gss_buf gss_buf; + Ssh_gss_buf gss_rcvtok, gss_sndtok; + Ssh_gss_name gss_srv_name; + Ssh_gss_stat gss_stat; }; crState(do_ssh2_authconn_state); @@ -7032,6 +7110,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, s->done_service_req = FALSE; s->we_are_in = FALSE; + s->tried_gssapi = FALSE; + if (!ssh->cfg.ssh_no_userauth) { /* * Request userauth protocol, and await a response to it. @@ -7319,7 +7399,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, break; } - if (pktin->type != SSH2_MSG_USERAUTH_FAILURE) { + if (pktin->type != SSH2_MSG_USERAUTH_FAILURE && s->type != AUTH_TYPE_GSSAPI) { bombout(("Strange packet received during authentication: " "type %d", pktin->type)); crStopV; @@ -7390,6 +7470,11 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, in_commasep_string("password", methods, methlen); s->can_keyb_inter = ssh->cfg.try_ki_auth && in_commasep_string("keyboard-interactive", methods, methlen); +#ifndef NO_GSSAPI + s->can_gssapi = ssh->cfg.try_gssapi_auth && + in_commasep_string("gssapi-with-mic", methods, methlen) && + ssh_gss_init(); +#endif } ssh->pkt_actx = SSH2_PKTCTX_NOAUTH; @@ -7718,6 +7803,157 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, key->alg->freekey(key->data); } +#ifndef NO_GSSAPI + } else if (s->can_gssapi && !s->tried_gssapi) { + + /* GSSAPI Authentication */ + + int micoffset; + Ssh_gss_buf mic; + s->type = AUTH_TYPE_GSSAPI; + s->tried_gssapi = TRUE; + s->gotit = TRUE; + ssh->pkt_actx = SSH2_PKTCTX_GSSAPI; + + /* Sending USERAUTH_REQUEST with "gssapi-with-mic" method */ + s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST); + ssh2_pkt_addstring(s->pktout, s->username); + ssh2_pkt_addstring(s->pktout, "ssh-connection"); + ssh2_pkt_addstring(s->pktout, "gssapi-with-mic"); + + /* add mechanism info */ + ssh_gss_indicate_mech(&s->gss_buf); + + /* number of GSSAPI mechanisms */ + ssh2_pkt_adduint32(s->pktout,1); + + /* length of OID + 2 */ + ssh2_pkt_adduint32(s->pktout, s->gss_buf.len + 2); + ssh2_pkt_addbyte(s->pktout, SSH2_GSS_OIDTYPE); + + /* length of OID */ + ssh2_pkt_addbyte(s->pktout, (unsigned char) s->gss_buf.len); + + ssh_pkt_adddata(s->pktout, s->gss_buf.data, s->gss_buf.len); + ssh2_pkt_send(ssh, s->pktout); + crWaitUntilV(pktin); + if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_RESPONSE) { + logevent("GSSAPI authentication request refused"); + continue; + } + + /* check returned packet ... */ + + ssh_pkt_getstring(pktin,&s->gss_rcvtok.data,&s->gss_rcvtok.len); + if (s->gss_rcvtok.len != s->gss_buf.len + 2 || + s->gss_rcvtok.data[0] != SSH2_GSS_OIDTYPE || + s->gss_rcvtok.data[1] != s->gss_buf.len || + memcmp(s->gss_rcvtok.data+2,s->gss_buf.data,s->gss_buf.len) ) { + logevent("GSSAPI authentication - wrong response from server"); + continue; + } + + /* now start running */ + s->gss_stat = ssh_gss_import_name(ssh->fullhostname, + &s->gss_srv_name); + if (s->gss_stat != SSH_GSS_OK) { + if (s->gss_stat == SSH_GSS_BAD_HOST_NAME) + logevent("GSSAPI import name failed - Bad service name"); + else + logevent("GSSAPI import name failed"); + continue; + } + + /* fetch TGT into GSS engine */ + s->gss_stat = ssh_gss_acquire_cred(&s->gss_ctx); + + if (s->gss_stat != SSH_GSS_OK) { + logevent("GSSAPI authentication failed to get credentials"); + ssh_gss_release_name(&s->gss_srv_name); + continue; + } + + /* initial tokens are empty */ + s->gss_rcvtok.len = s->gss_sndtok.len = 0; + s->gss_rcvtok.data = s->gss_sndtok.data = NULL; + + /* now enter the loop */ + do { + s->gss_stat = ssh_gss_init_sec_context(&s->gss_ctx, + s->gss_srv_name, + ssh->cfg.gssapifwd, + &s->gss_rcvtok, + &s->gss_sndtok); + + if (s->gss_stat!=SSH_GSS_S_COMPLETE && + s->gss_stat!=SSH_GSS_S_CONTINUE_NEEDED) { + logevent("GSSAPI authentication initialisation failed"); + + if (ssh_gss_display_status(s->gss_ctx,&s->gss_buf) == SSH_GSS_OK) { + logevent(s->gss_buf.data); + sfree(s->gss_buf.data); + } + + break; + } + logevent("GSSAPI authentication initialised"); + + /* Client and server now exchange tokens until GSSAPI + * no longer says CONTINUE_NEEDED */ + + if (s->gss_sndtok.len != 0) { + s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); + ssh_pkt_addstring_start(s->pktout); + ssh_pkt_addstring_data(s->pktout,s->gss_sndtok.data,s->gss_sndtok.len); + ssh2_pkt_send(ssh, s->pktout); + ssh_gss_free_tok(&s->gss_sndtok); + } + + if (s->gss_stat == SSH_GSS_S_CONTINUE_NEEDED) { + crWaitUntilV(pktin); + if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_TOKEN) { + logevent("GSSAPI authentication - bad server response"); + s->gss_stat = SSH_GSS_FAILURE; + break; + } + ssh_pkt_getstring(pktin,&s->gss_rcvtok.data,&s->gss_rcvtok.len); + } + } while (s-> gss_stat == SSH_GSS_S_CONTINUE_NEEDED); + + if (s->gss_stat != SSH_GSS_OK) { + ssh_gss_release_name(&s->gss_srv_name); + ssh_gss_release_cred(&s->gss_ctx); + continue; + } + logevent("GSSAPI authentication loop finished OK"); + + /* Now send the MIC */ + + s->pktout = ssh2_pkt_init(0); + micoffset = s->pktout->length; + ssh_pkt_addstring_start(s->pktout); + ssh_pkt_addstring_data(s->pktout, (char *)ssh->v2_session_id, ssh->v2_session_id_len); + ssh_pkt_addbyte(s->pktout, SSH2_MSG_USERAUTH_REQUEST); + ssh_pkt_addstring(s->pktout, s->username); + ssh_pkt_addstring(s->pktout, "ssh-connection"); + ssh_pkt_addstring(s->pktout, "gssapi-with-mic"); + + s->gss_buf.data = (char *)s->pktout->data + micoffset; + s->gss_buf.len = s->pktout->length - micoffset; + + ssh_gss_get_mic(s->gss_ctx, &s->gss_buf, &mic); + s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_GSSAPI_MIC); + ssh_pkt_addstring_start(s->pktout); + ssh_pkt_addstring_data(s->pktout, mic.data, mic.len); + ssh2_pkt_send(ssh, s->pktout); + ssh_gss_free_mic(&mic); + + s->gotit = FALSE; + + ssh_gss_release_name(&s->gss_srv_name); + ssh_gss_release_cred(&s->gss_ctx); + continue; +#endif } else if (s->can_keyb_inter && !s->kbd_inter_refused) { /* @@ -7789,7 +8025,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, s->cur_prompt->instr_reqd = TRUE; /* - * Get the prompts from the packet. + * Get any prompt(s) from the packet. */ s->num_prompts = ssh_pkt_getuint32(pktin); for (i = 0; i < s->num_prompts; i++) { @@ -7811,9 +8047,10 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, } /* - * Get the user's responses. + * Display any instructions, and get the user's + * response(s). */ - if (s->num_prompts) { + { int ret; /* not live over crReturn */ ret = get_userpass_input(s->cur_prompt, NULL, 0); while (ret < 0) { @@ -7835,7 +8072,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, } /* - * Send the responses to the server. + * Send the response(s) to the server. */ s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_INFO_RESPONSE); ssh2_pkt_adduint32(s->pktout, s->num_prompts); @@ -8244,17 +8481,15 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, * Potentially enable X11 forwarding. */ if (ssh->mainchan && !ssh->ncmode && ssh->cfg.x11_forward) { - char proto[20], data[64]; logevent("Requesting X11 forwarding"); - ssh->x11auth = x11_invent_auth(proto, sizeof(proto), - data, sizeof(data), ssh->cfg.x11_auth); - x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display); + ssh->x11disp = x11_setup_display(ssh->cfg.x11_display, + ssh->cfg.x11_auth, &ssh->cfg); s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST); ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); ssh2_pkt_addstring(s->pktout, "x11-req"); ssh2_pkt_addbool(s->pktout, 1); /* want reply */ ssh2_pkt_addbool(s->pktout, 0); /* many connections */ - ssh2_pkt_addstring(s->pktout, proto); + ssh2_pkt_addstring(s->pktout, ssh->x11disp->remoteauthprotoname); /* * Note that while we blank the X authentication data here, we don't * take any special action to blank the start of an X11 channel, @@ -8263,9 +8498,9 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, * cookie into the log. */ dont_log_password(ssh, s->pktout, PKTLOG_BLANK); - ssh2_pkt_addstring(s->pktout, data); + ssh2_pkt_addstring(s->pktout, ssh->x11disp->remoteauthdatastring); end_log_omission(ssh, s->pktout); - ssh2_pkt_adduint32(s->pktout, x11_get_screen_number(ssh->cfg.x11_display)); + ssh2_pkt_adduint32(s->pktout, ssh->x11disp->screennum); ssh2_pkt_send(ssh, s->pktout); crWaitUntilV(pktin); @@ -8549,7 +8784,7 @@ static void ssh2_msg_disconnect(Ssh ssh, struct Packet *pktin) { /* log reason code in disconnect message */ char *buf, *msg; - int nowlen, reason, msglen; + int reason, msglen; reason = ssh_pkt_getuint32(pktin); ssh_pkt_getstring(pktin, &msg, &msglen); @@ -8563,14 +8798,14 @@ static void ssh2_msg_disconnect(Ssh ssh, struct Packet *pktin) } logevent(buf); sfree(buf); - buf = dupprintf("Disconnection message text: %n%.*s", - &nowlen, msglen, msg); + buf = dupprintf("Disconnection message text: %.*s", + msglen, msg); logevent(buf); - bombout(("Server sent disconnect message\ntype %d (%s):\n\"%s\"", + bombout(("Server sent disconnect message\ntype %d (%s):\n\"%.*s\"", reason, (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ? ssh2_disconnect_reasons[reason] : "unknown", - buf+nowlen)); + msglen, msg)); sfree(buf); } @@ -8756,7 +8991,7 @@ static const char *ssh_init(void *frontend_handle, void **backend_handle, ssh->fallback_cmd = 0; ssh->pkt_kctx = SSH2_PKTCTX_NOKEX; ssh->pkt_actx = SSH2_PKTCTX_NOAUTH; - ssh->x11auth = NULL; + ssh->x11disp = NULL; ssh->v1_compressing = FALSE; ssh->v2_outgoing_sequence = 0; ssh->ssh1_rdpkt_crstate = 0; @@ -8894,14 +9129,15 @@ static void ssh_free(void *handle) ssh->rportfwds = NULL; } sfree(ssh->deferred_send_data); - if (ssh->x11auth) - x11_free_auth(ssh->x11auth); + if (ssh->x11disp) + x11_free_display(ssh->x11disp); sfree(ssh->do_ssh_init_state); sfree(ssh->do_ssh1_login_state); sfree(ssh->do_ssh2_transport_state); sfree(ssh->do_ssh2_authconn_state); sfree(ssh->v_c); sfree(ssh->v_s); + sfree(ssh->fullhostname); if (ssh->crcda_ctx) { crcda_free_context(ssh->crcda_ctx); ssh->crcda_ctx = NULL; @@ -9079,7 +9315,7 @@ static const struct telnet_special *ssh_get_specials(void *handle) static const struct telnet_special ssh2_session_specials[] = { {NULL, TS_SEP}, {"Break", TS_BRK}, - /* These are the signal names defined by draft-ietf-secsh-connect-23. + /* These are the signal names defined by RFC 4254. * They include all the ISO C signals, but are a subset of the POSIX * required signals. */ {"SIGINT (Interrupt)", TS_SIGINT},