X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=ssh.c;h=f3ce6fe0f5f4f3c1d5288df87987418c6e73b079;hb=9f9d72ec58642e91b4f93ee4405a8086ee2fb2f0;hp=f56e10a9f11c1f1d441595e07599bf8195c787d1;hpb=e460f3083112ca29024ec48de2815011afd761ff;p=PuTTY.git diff --git a/ssh.c b/ssh.c index f56e10a9..f3ce6fe0 100644 --- a/ssh.c +++ b/ssh.c @@ -3549,35 +3549,20 @@ static void ssh_sent(Plug plug, int bufsize) ssh_throttle_all(ssh, 0, bufsize); } -/* - * Connect to specified host and port. - * Returns an error message, or NULL on success. - * Also places the canonical host name into `realhost'. It must be - * freed by the caller. - */ -static const char *connect_to_host(Ssh ssh, const char *host, int port, - char **realhost, int nodelay, int keepalive) +static void ssh_hostport_setup(const char *host, int port, Conf *conf, + char **savedhost, int *savedport, + char **loghost_ret) { - static const struct plug_function_table fn_table = { - ssh_socket_log, - ssh_closing, - ssh_receive, - ssh_sent, - NULL - }; + char *loghost = conf_get_str(conf, CONF_loghost); + if (loghost_ret) + *loghost_ret = loghost; - SockAddr addr; - const char *err; - char *loghost; - int addressfamily, sshprot; - - loghost = conf_get_str(ssh->conf, CONF_loghost); if (*loghost) { char *tmphost; char *colon; tmphost = dupstr(loghost); - ssh->savedport = 22; /* default ssh port */ + *savedport = 22; /* default ssh port */ /* * A colon suffix on the hostname string also lets us affect @@ -3588,17 +3573,56 @@ static const char *connect_to_host(Ssh ssh, const char *host, int port, if (colon && colon == host_strchr(tmphost, ':')) { *colon++ = '\0'; if (*colon) - ssh->savedport = atoi(colon); + *savedport = atoi(colon); } - ssh->savedhost = host_strduptrim(tmphost); + *savedhost = host_strduptrim(tmphost); sfree(tmphost); } else { - ssh->savedhost = host_strduptrim(host); + *savedhost = host_strduptrim(host); if (port < 0) port = 22; /* default ssh port */ - ssh->savedport = port; + *savedport = port; } +} + +static int ssh_test_for_upstream(const char *host, int port, Conf *conf) +{ + char *savedhost; + int savedport; + int ret; + + ssh_hostport_setup(host, port, conf, &savedhost, &savedport, NULL); + ret = ssh_share_test_for_upstream(savedhost, savedport, conf); + sfree(savedhost); + + return ret; +} + +/* + * Connect to specified host and port. + * Returns an error message, or NULL on success. + * Also places the canonical host name into `realhost'. It must be + * freed by the caller. + */ +static const char *connect_to_host(Ssh ssh, const char *host, int port, + char **realhost, int nodelay, int keepalive) +{ + static const struct plug_function_table fn_table = { + ssh_socket_log, + ssh_closing, + ssh_receive, + ssh_sent, + NULL + }; + + SockAddr addr; + const char *err; + char *loghost; + int addressfamily, sshprot; + + ssh_hostport_setup(host, port, ssh->conf, + &ssh->savedhost, &ssh->savedport, &loghost); ssh->fn = &fn_table; /* make 'ssh' usable as a Plug */ @@ -6568,6 +6592,24 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen, bombout(("KEXINIT packet was incomplete")); crStopV; } + + /* If we've already selected a cipher which requires a + * particular MAC, then just select that, and don't even + * bother looking through the server's KEXINIT string for + * MACs. */ + if (i == KEXLIST_CSMAC && s->cscipher_tobe && + s->cscipher_tobe->required_mac) { + s->csmac_tobe = s->cscipher_tobe->required_mac; + s->csmac_etm_tobe = !!(s->csmac_tobe->etm_name); + goto matched; + } + if (i == KEXLIST_SCMAC && s->sccipher_tobe && + s->sccipher_tobe->required_mac) { + s->scmac_tobe = s->sccipher_tobe->required_mac; + s->scmac_etm_tobe = !!(s->scmac_tobe->etm_name); + goto matched; + } + for (j = 0; j < MAXKEXLIST; j++) { struct kexinit_algorithm *alg = &s->kexlists[i][j]; if (alg->name == NULL) break; @@ -6613,16 +6655,6 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen, matched:; } - /* If the cipher over-rides the mac, then pick it */ - if (s->cscipher_tobe && s->cscipher_tobe->required_mac) { - s->csmac_tobe = s->cscipher_tobe->required_mac; - s->csmac_etm_tobe = !!(s->csmac_tobe->etm_name); - } - if (s->sccipher_tobe && s->sccipher_tobe->required_mac) { - s->scmac_tobe = s->sccipher_tobe->required_mac; - s->scmac_etm_tobe = !!(s->scmac_tobe->etm_name); - } - if (s->pending_compression) { logevent("Server supports delayed compression; " "will try this later"); @@ -6728,8 +6760,8 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen, { int csbits, scbits; - csbits = s->cscipher_tobe->keylen; - scbits = s->sccipher_tobe->keylen; + csbits = s->cscipher_tobe->real_keybits; + scbits = s->sccipher_tobe->real_keybits; s->nbits = (csbits > scbits ? csbits : scbits); } /* The keys only have hlen-bit entropy, since they're based on @@ -7183,9 +7215,9 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen, unsigned char *key; key = ssh2_mkkey(ssh, s->K, s->exchange_hash, 'C', - (ssh->cscipher->keylen+7) / 8); + ssh->cscipher->padded_keybytes); ssh->cscipher->setkey(ssh->cs_cipher_ctx, key); - smemclr(key, (ssh->cscipher->keylen+7) / 8); + smemclr(key, ssh->cscipher->padded_keybytes); sfree(key); key = ssh2_mkkey(ssh, s->K, s->exchange_hash, 'A', @@ -7256,9 +7288,9 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen, unsigned char *key; key = ssh2_mkkey(ssh, s->K, s->exchange_hash, 'D', - (ssh->sccipher->keylen + 7) / 8); + ssh->sccipher->padded_keybytes); ssh->sccipher->setkey(ssh->sc_cipher_ctx, key); - smemclr(key, (ssh->sccipher->keylen + 7) / 8); + smemclr(key, ssh->sccipher->padded_keybytes); sfree(key); key = ssh2_mkkey(ssh, s->K, s->exchange_hash, 'B', @@ -11626,6 +11658,7 @@ Backend ssh_backend = { ssh_provide_logctx, ssh_unthrottle, ssh_cfg_info, + ssh_test_for_upstream, "ssh", PROT_SSH, 22