for (i = 0; i < lenof(ciphers) + 1; i++) { const struct ssh2_ciphers *c = i == 0 ? preferred_cipher : ciphers[i - 1]; for (j = 0; j < c->nciphers; j++) { if (in_commasep_string(c->list[j]->name, str, len)) { cscipher_tobe = c->list[j]; break;
warn = 0; for (i = 0; i < n_preferred_ciphers; i++) { const struct ssh2_ciphers *c = preferred_ciphers[i]; if (!c) { warn = 1; } else { for (j = 0; j < c->nciphers; j++) { if (in_commasep_string(c->list[j]->name, str, len)) { cscipher_tobe = c->list[j]; break; }
static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt){    static int i, j, len, nbits, pbits;    static char *str;    static Bignum p, g, e, f, K;    static int kex_init_value, kex_reply_value;    static const struct ssh_mac **maclist;    static int nmacs;    static const struct ssh2_cipher *cscipher_tobe = NULL;    static const struct ssh2_cipher *sccipher_tobe = NULL;    static const struct ssh_mac *csmac_tobe = NULL;    static const struct ssh_mac *scmac_tobe = NULL;    static const struct ssh_compress *cscomp_tobe = NULL;    static const struct ssh_compress *sccomp_tobe = NULL;    static char *hostkeydata, *sigdata, *keystr, *fingerprint;    static int hostkeylen, siglen;    static void *hkey;		       /* actual host key */    static unsigned char exchange_hash[20];    static unsigned char keyspace[40];    static const struct ssh2_ciphers *preferred_cipher;    static const struct ssh_compress *preferred_comp;    static int first_kex;    crBegin;    random_init();    first_kex = 1;    /*     * Set up the preferred cipher and compression.     */    if (cfg.cipher == CIPHER_BLOWFISH) {	preferred_cipher = &ssh2_blowfish;    } else if (cfg.cipher == CIPHER_DES) {	logevent("Single DES not supported in SSH2; using 3DES");	preferred_cipher = &ssh2_3des;    } else if (cfg.cipher == CIPHER_3DES) {	preferred_cipher = &ssh2_3des;    } else if (cfg.cipher == CIPHER_AES) {	preferred_cipher = &ssh2_aes;    } else {	/* Shouldn't happen, but we do want to initialise to _something_. */	preferred_cipher = &ssh2_3des;    }    if (cfg.compression)	preferred_comp = &ssh_zlib;    else	preferred_comp = &ssh_comp_none;    /*     * Be prepared to work around the buggy MAC problem.     */    if (cfg.buggymac || (ssh_remote_bugs & BUG_SSH2_HMAC))	maclist = buggymacs, nmacs = lenof(buggymacs);    else	maclist = macs, nmacs = lenof(macs);  begin_key_exchange:    /*     * Construct and send our key exchange packet.     */    ssh2_pkt_init(SSH2_MSG_KEXINIT);    for (i = 0; i < 16; i++)	ssh2_pkt_addbyte((unsigned char) random_byte());    /* List key exchange algorithms. */    ssh2_pkt_addstring_start();    for (i = 0; i < lenof(kex_algs); i++) {	ssh2_pkt_addstring_str(kex_algs[i]->name);	if (i < lenof(kex_algs) - 1)	    ssh2_pkt_addstring_str(",");    }    /* List server host key algorithms. */    ssh2_pkt_addstring_start();    for (i = 0; i < lenof(hostkey_algs); i++) {	ssh2_pkt_addstring_str(hostkey_algs[i]->name);	if (i < lenof(hostkey_algs) - 1)	    ssh2_pkt_addstring_str(",");    }    /* List client->server encryption algorithms. */    ssh2_pkt_addstring_start();    for (i = 0; i < lenof(ciphers) + 1; i++) {	const struct ssh2_ciphers *c =	    i == 0 ? preferred_cipher : ciphers[i - 1];	for (j = 0; j < c->nciphers; j++) {	    ssh2_pkt_addstring_str(c->list[j]->name);	    if (i < lenof(ciphers) || j < c->nciphers - 1)		ssh2_pkt_addstring_str(",");	}    }    /* List server->client encryption algorithms. */    ssh2_pkt_addstring_start();    for (i = 0; i < lenof(ciphers) + 1; i++) {	const struct ssh2_ciphers *c =	    i == 0 ? preferred_cipher : ciphers[i - 1];	for (j = 0; j < c->nciphers; j++) {	    ssh2_pkt_addstring_str(c->list[j]->name);	    if (i < lenof(ciphers) || j < c->nciphers - 1)		ssh2_pkt_addstring_str(",");	}    }    /* List client->server MAC algorithms. */    ssh2_pkt_addstring_start();    for (i = 0; i < nmacs; i++) {	ssh2_pkt_addstring_str(maclist[i]->name);	if (i < nmacs - 1)	    ssh2_pkt_addstring_str(",");    }    /* List server->client MAC algorithms. */    ssh2_pkt_addstring_start();    for (i = 0; i < nmacs; i++) {	ssh2_pkt_addstring_str(maclist[i]->name);	if (i < nmacs - 1)	    ssh2_pkt_addstring_str(",");    }    /* List client->server compression algorithms. */    ssh2_pkt_addstring_start();    for (i = 0; i < lenof(compressions) + 1; i++) {	const struct ssh_compress *c =	    i == 0 ? preferred_comp : compressions[i - 1];	ssh2_pkt_addstring_str(c->name);	if (i < lenof(compressions))	    ssh2_pkt_addstring_str(",");    }    /* List server->client compression algorithms. */    ssh2_pkt_addstring_start();    for (i = 0; i < lenof(compressions) + 1; i++) {	const struct ssh_compress *c =	    i == 0 ? preferred_comp : compressions[i - 1];	ssh2_pkt_addstring_str(c->name);	if (i < lenof(compressions))	    ssh2_pkt_addstring_str(",");    }    /* List client->server languages. Empty list. */    ssh2_pkt_addstring_start();    /* List server->client languages. Empty list. */    ssh2_pkt_addstring_start();    /* First KEX packet does _not_ follow, because we're not that brave. */    ssh2_pkt_addbool(FALSE);    /* Reserved. */    ssh2_pkt_adduint32(0);    exhash = exhashbase;    sha_string(&exhash, pktout.data + 5, pktout.length - 5);    ssh2_pkt_send();    if (!ispkt)	crWaitUntil(ispkt);    sha_string(&exhash, pktin.data + 5, pktin.length - 5);    /*     * Now examine the other side's KEXINIT to see what we're up     * to.     */    if (pktin.type != SSH2_MSG_KEXINIT) {	bombout(("expected key exchange packet from server"));	crReturn(0);    }    kex = NULL;    hostkey = NULL;    cscipher_tobe = NULL;    sccipher_tobe = NULL;    csmac_tobe = NULL;    scmac_tobe = NULL;    cscomp_tobe = NULL;    sccomp_tobe = NULL;    pktin.savedpos += 16;	       /* skip garbage cookie */    ssh2_pkt_getstring(&str, &len);    /* key exchange algorithms */    for (i = 0; i < lenof(kex_algs); i++) {	if (in_commasep_string(kex_algs[i]->name, str, len)) {	    kex = kex_algs[i];	    break;	}    }    ssh2_pkt_getstring(&str, &len);    /* host key algorithms */    for (i = 0; i < lenof(hostkey_algs); i++) {	if (in_commasep_string(hostkey_algs[i]->name, str, len)) {	    hostkey = hostkey_algs[i];	    break;	}    }    ssh2_pkt_getstring(&str, &len);    /* client->server cipher */    for (i = 0; i < lenof(ciphers) + 1; i++) {	const struct ssh2_ciphers *c =	    i == 0 ? preferred_cipher : ciphers[i - 1];	for (j = 0; j < c->nciphers; j++) {	    if (in_commasep_string(c->list[j]->name, str, len)) {		cscipher_tobe = c->list[j];		break;	    }	}	if (cscipher_tobe)	    break;    }    ssh2_pkt_getstring(&str, &len);    /* server->client cipher */    for (i = 0; i < lenof(ciphers) + 1; i++) {	const struct ssh2_ciphers *c =	    i == 0 ? preferred_cipher : ciphers[i - 1];	for (j = 0; j < c->nciphers; j++) {	    if (in_commasep_string(c->list[j]->name, str, len)) {		sccipher_tobe = c->list[j];		break;	    }	}	if (sccipher_tobe)	    break;    }    ssh2_pkt_getstring(&str, &len);    /* client->server mac */    for (i = 0; i < nmacs; i++) {	if (in_commasep_string(maclist[i]->name, str, len)) {	    csmac_tobe = maclist[i];	    break;	}    }    ssh2_pkt_getstring(&str, &len);    /* server->client mac */    for (i = 0; i < nmacs; i++) {	if (in_commasep_string(maclist[i]->name, str, len)) {	    scmac_tobe = maclist[i];	    break;	}    }    ssh2_pkt_getstring(&str, &len);    /* client->server compression */    for (i = 0; i < lenof(compressions) + 1; i++) {	const struct ssh_compress *c =	    i == 0 ? preferred_comp : compressions[i - 1];	if (in_commasep_string(c->name, str, len)) {	    cscomp_tobe = c;	    break;	}    }    ssh2_pkt_getstring(&str, &len);    /* server->client compression */    for (i = 0; i < lenof(compressions) + 1; i++) {	const struct ssh_compress *c =	    i == 0 ? preferred_comp : compressions[i - 1];	if (in_commasep_string(c->name, str, len)) {	    sccomp_tobe = c;	    break;	}    }    /*     * Work out the number of bits of key we will need from the key     * exchange. We start with the maximum key length of either     * cipher...     */    {	int csbits, scbits;	csbits = cscipher_tobe->keylen;	scbits = sccipher_tobe->keylen;	nbits = (csbits > scbits ? csbits : scbits);    }    /* The keys only have 160-bit entropy, since they're based on     * a SHA-1 hash. So cap the key size at 160 bits. */    if (nbits > 160)	nbits = 160;    /*     * If we're doing Diffie-Hellman group exchange, start by     * requesting a group.     */    if (kex == &ssh_diffiehellman_gex) {	logevent("Doing Diffie-Hellman group exchange");	/*	 * Work out how big a DH group we will need to allow that	 * much data.	 */	pbits = 512 << ((nbits - 1) / 64);	ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);	ssh2_pkt_adduint32(pbits);	ssh2_pkt_send();	crWaitUntil(ispkt);	if (pktin.type != SSH2_MSG_KEX_DH_GEX_GROUP) {	    bombout(("expected key exchange group packet from server"));	    crReturn(0);	}	p = ssh2_pkt_getmp();	g = ssh2_pkt_getmp();	dh_setup_group(p, g);	kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;	kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;    } else {	dh_setup_group1();	kex_init_value = SSH2_MSG_KEXDH_INIT;	kex_reply_value = SSH2_MSG_KEXDH_REPLY;    }    logevent("Doing Diffie-Hellman key exchange");    /*     * Now generate and send e for Diffie-Hellman.     */    e = dh_create_e(nbits * 2);    ssh2_pkt_init(kex_init_value);    ssh2_pkt_addmp(e);    ssh2_pkt_send();    crWaitUntil(ispkt);    if (pktin.type != kex_reply_value) {	bombout(("expected key exchange reply packet from server"));	crReturn(0);    }    ssh2_pkt_getstring(&hostkeydata, &hostkeylen);    f = ssh2_pkt_getmp();    ssh2_pkt_getstring(&sigdata, &siglen);    K = dh_find_K(f);    sha_string(&exhash, hostkeydata, hostkeylen);    if (kex == &ssh_diffiehellman_gex) {	sha_uint32(&exhash, pbits);	sha_mpint(&exhash, p);	sha_mpint(&exhash, g);    }    sha_mpint(&exhash, e);    sha_mpint(&exhash, f);    sha_mpint(&exhash, K);    SHA_Final(&exhash, exchange_hash);    dh_cleanup();#if 0    debug(("Exchange hash is:\n"));    dmemdump(exchange_hash, 20);#endif    hkey = hostkey->newkey(hostkeydata, hostkeylen);    if (!hkey ||	!hostkey->verifysig(hkey, sigdata, siglen, exchange_hash, 20)) {	bombout(("Server's host key did not match the signature supplied"));	crReturn(0);    }    /*     * Expect SSH2_MSG_NEWKEYS from server.     */    crWaitUntil(ispkt);    if (pktin.type != SSH2_MSG_NEWKEYS) {	bombout(("expected new-keys packet from server"));	crReturn(0);    }    /*     * Authenticate remote host: verify host key. (We've already     * checked the signature of the exchange hash.)     */    keystr = hostkey->fmtkey(hkey);    fingerprint = hostkey->fingerprint(hkey);    verify_ssh_host_key(savedhost, savedport, hostkey->keytype,			keystr, fingerprint);    if (first_kex) {		       /* don't bother logging this in rekeys */	logevent("Host key fingerprint is:");	logevent(fingerprint);    }    sfree(fingerprint);    sfree(keystr);    hostkey->freekey(hkey);    /*     * Send SSH2_MSG_NEWKEYS.     */    ssh2_pkt_init(SSH2_MSG_NEWKEYS);    ssh2_pkt_send();    /*     * Create and initialise session keys.     */    cscipher = cscipher_tobe;    sccipher = sccipher_tobe;    csmac = csmac_tobe;    scmac = scmac_tobe;    cscomp = cscomp_tobe;    sccomp = sccomp_tobe;    cscomp->compress_init();    sccomp->decompress_init();    /*     * Set IVs after keys. Here we use the exchange hash from the     * _first_ key exchange.     */    if (first_kex)	memcpy(ssh2_session_id, exchange_hash, sizeof(exchange_hash));    ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'C', keyspace);    cscipher->setcskey(keyspace);    ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'D', keyspace);    sccipher->setsckey(keyspace);    ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'A', keyspace);    cscipher->setcsiv(keyspace);    ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'B', keyspace);    sccipher->setsciv(keyspace);    ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'E', keyspace);    csmac->setcskey(keyspace);    ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'F', keyspace);    scmac->setsckey(keyspace);    /*     * If this is the first key exchange phase, we must pass the     * SSH2_MSG_NEWKEYS packet to the next layer, not because it     * wants to see it but because it will need time to initialise     * itself before it sees an actual packet. In subsequent key     * exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because     * it would only confuse the layer above.     */    if (!first_kex) {	crReturn(0);    }    first_kex = 0;    /*     * Now we're encrypting. Begin returning 1 to the protocol main     * function so that other things can run on top of the     * transport. If we ever see a KEXINIT, we must go back to the     * start.     */    while (!(ispkt && pktin.type == SSH2_MSG_KEXINIT)) {	crReturn(1);    }    logevent("Server initiated key re-exchange");    goto begin_key_exchange;    crFinish(1);}