static void kex_choose_conf(Kex *kex) { Newkeys *newkeys; char **my, **peer; char **cprop, **sprop; int nenc, nmac, ncomp; u_int mode, ctos, need; int first_kex_follows, type; int log_flag = 0; int auth_flag; auth_flag = packet_authentication_state(); debug ("AUTH STATE IS %d", auth_flag); my = kex_buf2prop(&kex->my, NULL); peer = kex_buf2prop(&kex->peer, &first_kex_follows); if (kex->server) { cprop=peer; sprop=my; } else { cprop=my; sprop=peer; } /* Check whether server offers roaming */ if (!kex->server) { char *roaming; roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL); if (roaming) { kex->roaming = 1; xfree(roaming); } } /* Algorithm Negotiation */ for (mode = 0; mode < MODE_MAX; mode++) { newkeys = xcalloc(1, sizeof(*newkeys)); kex->newkeys[mode] = newkeys; ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; choose_enc (&newkeys->enc, cprop[nenc], sprop[nenc]); choose_mac (&newkeys->mac, cprop[nmac], sprop[nmac]); choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]); debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name); if (strcmp(newkeys->enc.name, "none") == 0) { debug("Requesting NONE. Authflag is %d", auth_flag); if (auth_flag == 1) { debug("None requested post authentication."); } else { fatal("Pre-authentication none cipher requests are not allowed."); } } debug("kex: %s %s %s %s", ctos ? "client->server" : "server->client", newkeys->enc.name, newkeys->mac.name, newkeys->comp.name); /* client starts withctos = 0 && log flag = 0 and no log*/ /* 2nd client pass ctos=1 and flag = 1 so no log*/ /* server starts with ctos =1 && log_flag = 0 so log */ /* 2nd sever pass ctos = 1 && log flag = 1 so no log*/ /* -cjr*/ if (ctos && !log_flag) { logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s", get_remote_ipaddr(), get_remote_port(), newkeys->enc.name, newkeys->mac.name, newkeys->comp.name); } log_flag = 1; } choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); need = 0; for (mode = 0; mode < MODE_MAX; mode++) { newkeys = kex->newkeys[mode]; if (need < newkeys->enc.key_len) need = newkeys->enc.key_len; if (need < newkeys->enc.block_size) need = newkeys->enc.block_size; if (need < newkeys->mac.key_len) need = newkeys->mac.key_len; } /* XXX need runden? */ kex->we_need = need; /* ignore the next message if the proposals do not match */ if (first_kex_follows && !proposals_match(my, peer) && !(datafellows & SSH_BUG_FIRSTKEX)) { type = packet_read(); debug2("skipping next packet (type %u)", type); } kex_prop_free(my); kex_prop_free(peer); }
static void kex_choose_conf(Kex *kex) { Newkeys *newkeys; char **my, **peer; char **cprop, **sprop; int nenc, nmac, ncomp; u_int mode, ctos, need, dh_need, authlen; int first_kex_follows, type; int auth_flag; auth_flag = packet_authentication_state(); debug ("AUTH STATE IS %d", auth_flag); my = kex_buf2prop(&kex->my, NULL); peer = kex_buf2prop(&kex->peer, &first_kex_follows); if (kex->server) { cprop=peer; sprop=my; } else { cprop=my; sprop=peer; } /* Check whether server offers roaming */ if (!kex->server) { char *roaming; roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL); if (roaming) { kex->roaming = 1; free(roaming); } } /* Algorithm Negotiation */ for (mode = 0; mode < MODE_MAX; mode++) { newkeys = xcalloc(1, sizeof(*newkeys)); kex->newkeys[mode] = newkeys; ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; choose_enc(&newkeys->enc, cprop[nenc], sprop[nenc]); /* ignore mac for authenticated encryption */ authlen = cipher_authlen(newkeys->enc.cipher); if (authlen == 0) choose_mac(&newkeys->mac, cprop[nmac], sprop[nmac]); choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]); debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name); if (strcmp(newkeys->enc.name, "none") == 0) { debug("Requesting NONE. Authflag is %d", auth_flag); if (auth_flag == 1) { debug("None requested post authentication."); } else { fatal("Pre-authentication none cipher requests are not allowed."); } } debug("kex: %s %s %s %s", ctos ? "client->server" : "server->client", newkeys->enc.name, authlen == 0 ? newkeys->mac.name : "<implicit>", newkeys->comp.name); #ifdef NERSC_MOD if ( ctos ) { char* t1buf = encode_string(newkeys->enc.name, strlen(newkeys->enc.name)); char* t2buf = encode_string(newkeys->mac.name, strlen(newkeys->mac.name)); char* t3buf = encode_string(newkeys->comp.name, strlen(newkeys->comp.name)); char* t4buf = encode_string(kex->client_version_string, strlen(kex->client_version_string)); s_audit("session_key_exchange", "count=%i uristring=%s_%s_%s_%s", client_session_id, t4buf, t1buf, t2buf, t3buf); free(t1buf); free(t2buf); free(t3buf); free(t4buf); } #endif } choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { newkeys = kex->newkeys[mode]; need = MAX(need, newkeys->enc.key_len); need = MAX(need, newkeys->enc.block_size); need = MAX(need, newkeys->enc.iv_len); need = MAX(need, newkeys->mac.key_len); dh_need = MAX(dh_need, cipher_seclen(newkeys->enc.cipher)); dh_need = MAX(dh_need, newkeys->enc.block_size); dh_need = MAX(dh_need, newkeys->enc.iv_len); dh_need = MAX(dh_need, newkeys->mac.key_len); } /* XXX need runden? */ kex->we_need = need; kex->dh_need = dh_need; /* ignore the next message if the proposals do not match */ if (first_kex_follows && !proposals_match(my, peer) && !(datafellows & SSH_BUG_FIRSTKEX)) { type = packet_read(); debug2("skipping next packet (type %u)", type); } kex_prop_free(my); kex_prop_free(peer); }