X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/30460aeb3d3c027b85eba1e4d45de75fb4b9d356..d9ae70c5856554c6c874b8c12980fff3a32a454a:/openssh/kexgssc.c diff --git a/openssh/kexgssc.c b/openssh/kexgssc.c index 0caa6b6..39be405 100644 --- a/openssh/kexgssc.c +++ b/openssh/kexgssc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2005 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,26 +26,29 @@ #ifdef GSSAPI +#include "includes.h" + #include #include +#include + #include "xmalloc.h" #include "buffer.h" -#include "bufaux.h" -#include "cipher.h" +#include "ssh2.h" #include "key.h" +#include "cipher.h" #include "kex.h" #include "log.h" #include "packet.h" #include "dh.h" -#include "canohost.h" -#include "ssh2.h" + #include "ssh-gss.h" void kexgss_client(Kex *kex) { gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; - gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; + gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; Gssctxt *ctxt; OM_uint32 maj_status, min_status, ret_flags; u_int klen, kout, slen = 0, hashlen, strlen; @@ -56,22 +59,34 @@ kexgss_client(Kex *kex) { BIGNUM *g = NULL; u_char *kbuf, *hash; u_char *serverhostkey = NULL; + u_char *empty = ""; char *msg; char *lang; int type = 0; int first = 1; - int gex = 0; int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; /* Initialise our GSSAPI world */ ssh_gssapi_build_ctx(&ctxt); - if (ssh_gssapi_id_kex(ctxt, kex->name, &gex) == NULL) + if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) + == GSS_C_NO_OID) fatal("Couldn't identify host exchange"); if (ssh_gssapi_import_name(ctxt, kex->gss_host)) fatal("Couldn't import hostname"); - - if (gex) { + + if (kex->gss_client && + ssh_gssapi_client_identity(ctxt, kex->gss_client)) + fatal("Couldn't acquire client credentials"); + + switch (kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + dh = dh_new_group1(); + break; + case KEX_GSS_GRP14_SHA1: + dh = dh_new_group14(); + break; + case KEX_GSS_GEX_SHA1: debug("Doing group exchange\n"); nbits = dh_estimate(kex->we_need * 8); packet_start(SSH2_MSG_KEXGSS_GROUPREQ); @@ -96,8 +111,9 @@ kexgss_client(Kex *kex) { min, BN_num_bits(p), max); dh = dh_new_group(g, p); - } else { - dh = dh_new_group1(); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); } /* Step 1 - e is dh->pub_key */ @@ -205,7 +221,7 @@ kexgss_client(Kex *kex) { min_status = packet_get_int(); msg = packet_get_string(NULL); lang = packet_get_string(NULL); - fatal("GSSAPI Key Exchange Error: \n%s",msg); + fatal("GSSAPI Error: \n%.400s",msg); default: packet_disconnect("Protocol error: didn't expect packet type %d", type); @@ -234,20 +250,41 @@ kexgss_client(Kex *kex) { klen = DH_size(dh); kbuf = xmalloc(klen); kout = DH_compute_key(kbuf, dh_server_pub, dh); + if (kout < 0) + fatal("DH_compute_key: failed"); shared_secret = BN_new(); - BN_bin2bn(kbuf,kout, shared_secret); + if (shared_secret == NULL) + fatal("kexgss_client: BN_new failed"); + + if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) + fatal("kexdh_client: BN_bin2bn failed"); + memset(kbuf, 0, klen); xfree(kbuf); - if (gex) { + switch (kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + case KEX_GSS_GRP14_SHA1: + kex_dh_hash( kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + (serverhostkey ? serverhostkey : empty), slen, + dh->pub_key, /* e */ + dh_server_pub, /* f */ + shared_secret, /* K */ + &hash, &hashlen + ); + break; + case KEX_GSS_GEX_SHA1: kexgex_hash( kex->evp_md, kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->my), buffer_len(&kex->my), buffer_ptr(&kex->peer), buffer_len(&kex->peer), - serverhostkey, slen, + (serverhostkey ? serverhostkey : empty), slen, min, nbits, max, dh->p, dh->g, dh->pub_key, @@ -255,24 +292,15 @@ kexgss_client(Kex *kex) { shared_secret, &hash, &hashlen ); - } else { - /* The GSS hash is identical to the DH one */ - kex_dh_hash( kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->my), buffer_len(&kex->my), - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - serverhostkey, slen, /* server host key */ - dh->pub_key, /* e */ - dh_server_pub, /* f */ - shared_secret, /* K */ - &hash, &hashlen - ); - } + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } gssbuf.value = hash; gssbuf.length = hashlen; - /* Verify that the hash matches the MIC we just got. */ + /* Verify that the hash matches the MIC we just got. */ if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) packet_disconnect("Hash's MIC didn't verify"); @@ -290,6 +318,9 @@ kexgss_client(Kex *kex) { memcpy(kex->session_id, hash, kex->session_id_len); } + if (kex->gss_deleg_creds) + ssh_gssapi_credentials_updated(ctxt); + if (gss_kex_context == NULL) gss_kex_context = ctxt; else