X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/08822d99de1b1080f8c730bbebc192b5b45bf89b..b8af55e54c7882aef9ee2d6505b2425e21b9caa5:/openssh/kex.c diff --git a/openssh/kex.c b/openssh/kex.c index 407eec3..2633171 100644 --- a/openssh/kex.c +++ b/openssh/kex.c @@ -1,3 +1,4 @@ +/* $OpenBSD: kex.c,v 1.79 2007/06/05 06:52:37 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -23,24 +24,31 @@ */ #include "includes.h" -RCSID("$OpenBSD: kex.c,v 1.65 2005/11/04 05:15:59 djm Exp $"); + +#include + +#include +#include +#include +#include +#include #include -#include "ssh2.h" #include "xmalloc.h" +#include "ssh2.h" #include "buffer.h" -#include "bufaux.h" #include "packet.h" #include "compat.h" #include "cipher.h" -#include "kex.h" #include "key.h" +#include "kex.h" #include "log.h" #include "mac.h" #include "match.h" #include "dispatch.h" #include "monitor.h" +#include "canohost.h" #ifdef GSSAPI #include "ssh-gss.h" @@ -48,11 +56,20 @@ RCSID("$OpenBSD: kex.c,v 1.65 2005/11/04 05:15:59 djm Exp $"); #define KEX_COOKIE_LEN 16 +#if OPENSSL_VERSION_NUMBER >= 0x00907000L +# if defined(HAVE_EVP_SHA256) +# define evp_ssh_sha256 EVP_sha256 +# else +extern const EVP_MD *evp_ssh_sha256(void); +# endif +#endif + /* prototype */ static void kex_kexinit_finish(Kex *); static void kex_choose_conf(Kex *); /* put algorithm proposal into buffer */ +/* used in sshconnect.c as well as kex.c */ void kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) { @@ -76,10 +93,10 @@ static char ** kex_buf2prop(Buffer *raw, int *first_kex_follows) { Buffer b; - int i; + u_int i; char **proposal; - proposal = xmalloc(PROPOSAL_MAX * sizeof(char *)); + proposal = xcalloc(PROPOSAL_MAX, sizeof(char *)); buffer_init(&b); buffer_append(&b, buffer_ptr(raw), buffer_len(raw)); @@ -97,7 +114,7 @@ kex_buf2prop(Buffer *raw, int *first_kex_follows) *first_kex_follows = i; debug2("kex_parse_kexinit: first_kex_follows %d ", i); i = buffer_get_int(&b); - debug2("kex_parse_kexinit: reserved %d ", i); + debug2("kex_parse_kexinit: reserved %u ", i); buffer_free(&b); return proposal; } @@ -112,6 +129,7 @@ kex_prop_free(char **proposal) xfree(proposal); } +/* ARGSUSED */ static void kex_protocol_error(int type, u_int32_t seq, void *ctxt) { @@ -183,6 +201,7 @@ kex_send_kexinit(Kex *kex) kex->flags |= KEX_INIT_SENT; } +/* ARGSUSED */ void kex_input_kexinit(int type, u_int32_t seq, void *ctxt) { @@ -214,8 +233,7 @@ kex_setup(char *proposal[PROPOSAL_MAX]) { Kex *kex; - kex = xmalloc(sizeof(*kex)); - memset(kex, 0, sizeof(*kex)); + kex = xcalloc(1, sizeof(*kex)); buffer_init(&kex->peer); buffer_init(&kex->my); kex_prop2buf(&kex->my, proposal); @@ -248,7 +266,8 @@ choose_enc(Enc *enc, char *client, char *server) { char *name = match_list(client, server, NULL); if (name == NULL) - fatal("no matching cipher found: client %s server %s", client, server); + fatal("no matching cipher found: client %s server %s", + client, server); if ((enc->cipher = cipher_by_name(name)) == NULL) fatal("matching cipher is not supported: %s", name); enc->name = name; @@ -258,13 +277,15 @@ choose_enc(Enc *enc, char *client, char *server) enc->key_len = cipher_keylen(enc->cipher); enc->block_size = cipher_blocksize(enc->cipher); } + static void choose_mac(Mac *mac, char *client, char *server) { char *name = match_list(client, server, NULL); if (name == NULL) - fatal("no matching mac found: client %s server %s", client, server); - if (mac_init(mac, name) < 0) + fatal("no matching mac found: client %s server %s", + client, server); + if (mac_setup(mac, name) < 0) fatal("unsupported mac %s", name); /* truncate the key */ if (datafellows & SSH_BUG_HMAC) @@ -273,6 +294,7 @@ choose_mac(Mac *mac, char *client, char *server) mac->key = NULL; mac->enabled = 0; } + static void choose_comp(Comp *comp, char *client, char *server) { @@ -290,12 +312,13 @@ choose_comp(Comp *comp, char *client, char *server) } comp->name = name; } + static void choose_kex(Kex *k, char *client, char *server) { k->name = match_list(client, server, NULL); if (k->name == NULL) - fatal("no kex alg"); + fatal("Unable to negotiate a key exchange method"); if (strcmp(k->name, KEX_DH1) == 0) { k->kex_type = KEX_DH_GRP1_SHA1; k->evp_md = EVP_sha1(); @@ -305,15 +328,24 @@ choose_kex(Kex *k, char *client, char *server) } else if (strcmp(k->name, KEX_DHGEX_SHA1) == 0) { k->kex_type = KEX_DH_GEX_SHA1; k->evp_md = EVP_sha1(); +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + } else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) { + k->kex_type = KEX_DH_GEX_SHA256; + k->evp_md = evp_ssh_sha256(); +#endif #ifdef GSSAPI } else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID, - sizeof(KEX_GSS_GEX_SHA1_ID)-1) == 0) { + sizeof(KEX_GSS_GEX_SHA1_ID) - 1) == 0) { k->kex_type = KEX_GSS_GEX_SHA1; k->evp_md = EVP_sha1(); - } else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID, - sizeof(KEX_GSS_GRP1_SHA1_ID)-1) == 0) { + } else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID, + sizeof(KEX_GSS_GRP1_SHA1_ID) - 1) == 0) { k->kex_type = KEX_GSS_GRP1_SHA1; k->evp_md = EVP_sha1(); + } else if (strncmp(k->name, KEX_GSS_GRP14_SHA1_ID, + sizeof(KEX_GSS_GRP14_SHA1_ID) - 1) == 0) { + k->kex_type = KEX_GSS_GRP14_SHA1; + k->evp_md = EVP_sha1(); #endif } else fatal("bad kex alg %s", k->name); @@ -364,6 +396,13 @@ kex_choose_conf(Kex *kex) 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); @@ -378,21 +417,44 @@ kex_choose_conf(Kex *kex) /* Algorithm Negotiation */ for (mode = 0; mode < MODE_MAX; mode++) { - newkeys = xmalloc(sizeof(*newkeys)); - memset(newkeys, 0, sizeof(*newkeys)); + newkeys = xcalloc(1, sizeof(*newkeys)); kex->newkeys[mode] = newkeys; - ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); + 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], @@ -434,7 +496,7 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen, if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0) fatal("bad kex md size %d", mdsz); - digest = xmalloc(roundup(need, mdsz)); + digest = xmalloc(roundup(need, mdsz)); buffer_init(&b); buffer_put_bignum2(&b, shared_secret); @@ -487,7 +549,8 @@ kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret) for (mode = 0; mode < MODE_MAX; mode++) { current_keys[mode] = kex->newkeys[mode]; kex->newkeys[mode] = NULL; - ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); + ctos = (!kex->server && mode == MODE_OUT) || + (kex->server && mode == MODE_IN); current_keys[mode]->enc.iv = keys[ctos ? 0 : 1]; current_keys[mode]->enc.key = keys[ctos ? 2 : 3]; current_keys[mode]->mac.key = keys[ctos ? 4 : 5]; @@ -544,7 +607,7 @@ dump_digest(char *msg, u_char *digest, int len) u_int i; fprintf(stderr, "%s\n", msg); - for (i = 0; i< len; i++) { + for (i = 0; i < len; i++) { fprintf(stderr, "%02x", digest[i]); if (i%32 == 31) fprintf(stderr, "\n");