diff options
Diffstat (limited to 'kexgssc.c')
-rw-r--r-- | kexgssc.c | 74 |
1 files changed, 45 insertions, 29 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2001-2005 Simon Wilkinson. All rights reserved. | 2 | * Copyright (c) 2001-2006 Simon Wilkinson. All rights reserved. |
3 | * | 3 | * |
4 | * Redistribution and use in source and binary forms, with or without | 4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions | 5 | * modification, are permitted provided that the following conditions |
@@ -26,24 +26,29 @@ | |||
26 | 26 | ||
27 | #ifdef GSSAPI | 27 | #ifdef GSSAPI |
28 | 28 | ||
29 | #include "includes.h" | ||
30 | |||
29 | #include <openssl/crypto.h> | 31 | #include <openssl/crypto.h> |
30 | #include <openssl/bn.h> | 32 | #include <openssl/bn.h> |
31 | 33 | ||
34 | #include <string.h> | ||
35 | |||
32 | #include "xmalloc.h" | 36 | #include "xmalloc.h" |
33 | #include "buffer.h" | 37 | #include "buffer.h" |
34 | #include "bufaux.h" | 38 | #include "ssh2.h" |
39 | #include "key.h" | ||
40 | #include "cipher.h" | ||
35 | #include "kex.h" | 41 | #include "kex.h" |
36 | #include "log.h" | 42 | #include "log.h" |
37 | #include "packet.h" | 43 | #include "packet.h" |
38 | #include "dh.h" | 44 | #include "dh.h" |
39 | #include "canohost.h" | 45 | |
40 | #include "ssh2.h" | ||
41 | #include "ssh-gss.h" | 46 | #include "ssh-gss.h" |
42 | 47 | ||
43 | void | 48 | void |
44 | kexgss_client(Kex *kex) { | 49 | kexgss_client(Kex *kex) { |
45 | gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; | 50 | gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; |
46 | gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; | 51 | gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; |
47 | Gssctxt *ctxt; | 52 | Gssctxt *ctxt; |
48 | OM_uint32 maj_status, min_status, ret_flags; | 53 | OM_uint32 maj_status, min_status, ret_flags; |
49 | u_int klen, kout, slen = 0, hashlen, strlen; | 54 | u_int klen, kout, slen = 0, hashlen, strlen; |
@@ -58,22 +63,27 @@ kexgss_client(Kex *kex) { | |||
58 | char *lang; | 63 | char *lang; |
59 | int type = 0; | 64 | int type = 0; |
60 | int first = 1; | 65 | int first = 1; |
61 | int gex = 0; | 66 | int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; |
62 | int nbits, min, max; | ||
63 | 67 | ||
64 | /* Initialise our GSSAPI world */ | 68 | /* Initialise our GSSAPI world */ |
65 | ssh_gssapi_build_ctx(&ctxt); | 69 | ssh_gssapi_build_ctx(&ctxt); |
66 | if (ssh_gssapi_id_kex(ctxt, kex->name, &gex) == NULL) | 70 | if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) |
71 | == GSS_C_NO_OID) | ||
67 | fatal("Couldn't identify host exchange"); | 72 | fatal("Couldn't identify host exchange"); |
68 | 73 | ||
69 | if (ssh_gssapi_import_name(ctxt, kex->gss_host)) | 74 | if (ssh_gssapi_import_name(ctxt, kex->gss_host)) |
70 | fatal("Couldn't import hostname"); | 75 | fatal("Couldn't import hostname"); |
71 | 76 | ||
72 | if (gex) { | 77 | switch (kex->kex_type) { |
78 | case KEX_GSS_GRP1_SHA1: | ||
79 | dh = dh_new_group1(); | ||
80 | break; | ||
81 | case KEX_GSS_GRP14_SHA1: | ||
82 | dh = dh_new_group14(); | ||
83 | break; | ||
84 | case KEX_GSS_GEX_SHA1: | ||
73 | debug("Doing group exchange\n"); | 85 | debug("Doing group exchange\n"); |
74 | nbits = dh_estimate(kex->we_need * 8); | 86 | nbits = dh_estimate(kex->we_need * 8); |
75 | min = DH_GRP_MIN; | ||
76 | max = DH_GRP_MAX; | ||
77 | packet_start(SSH2_MSG_KEXGSS_GROUPREQ); | 87 | packet_start(SSH2_MSG_KEXGSS_GROUPREQ); |
78 | packet_put_int(min); | 88 | packet_put_int(min); |
79 | packet_put_int(nbits); | 89 | packet_put_int(nbits); |
@@ -96,8 +106,9 @@ kexgss_client(Kex *kex) { | |||
96 | min, BN_num_bits(p), max); | 106 | min, BN_num_bits(p), max); |
97 | 107 | ||
98 | dh = dh_new_group(g, p); | 108 | dh = dh_new_group(g, p); |
99 | } else { | 109 | break; |
100 | dh = dh_new_group1(); | 110 | default: |
111 | fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); | ||
101 | } | 112 | } |
102 | 113 | ||
103 | /* Step 1 - e is dh->pub_key */ | 114 | /* Step 1 - e is dh->pub_key */ |
@@ -205,7 +216,7 @@ kexgss_client(Kex *kex) { | |||
205 | min_status = packet_get_int(); | 216 | min_status = packet_get_int(); |
206 | msg = packet_get_string(NULL); | 217 | msg = packet_get_string(NULL); |
207 | lang = packet_get_string(NULL); | 218 | lang = packet_get_string(NULL); |
208 | fatal("GSSAPI Error: \n%s",msg); | 219 | fatal("GSSAPI Error: \n%.400s",msg); |
209 | default: | 220 | default: |
210 | packet_disconnect("Protocol error: didn't expect packet type %d", | 221 | packet_disconnect("Protocol error: didn't expect packet type %d", |
211 | type); | 222 | type); |
@@ -240,7 +251,21 @@ kexgss_client(Kex *kex) { | |||
240 | memset(kbuf, 0, klen); | 251 | memset(kbuf, 0, klen); |
241 | xfree(kbuf); | 252 | xfree(kbuf); |
242 | 253 | ||
243 | if (gex) { | 254 | switch (kex->kex_type) { |
255 | case KEX_GSS_GRP1_SHA1: | ||
256 | case KEX_GSS_GRP14_SHA1: | ||
257 | kex_dh_hash( kex->client_version_string, | ||
258 | kex->server_version_string, | ||
259 | buffer_ptr(&kex->my), buffer_len(&kex->my), | ||
260 | buffer_ptr(&kex->peer), buffer_len(&kex->peer), | ||
261 | serverhostkey, slen, /* server host key */ | ||
262 | dh->pub_key, /* e */ | ||
263 | dh_server_pub, /* f */ | ||
264 | shared_secret, /* K */ | ||
265 | &hash, &hashlen | ||
266 | ); | ||
267 | break; | ||
268 | case KEX_GSS_GEX_SHA1: | ||
244 | kexgex_hash( | 269 | kexgex_hash( |
245 | kex->evp_md, | 270 | kex->evp_md, |
246 | kex->client_version_string, | 271 | kex->client_version_string, |
@@ -255,24 +280,15 @@ kexgss_client(Kex *kex) { | |||
255 | shared_secret, | 280 | shared_secret, |
256 | &hash, &hashlen | 281 | &hash, &hashlen |
257 | ); | 282 | ); |
258 | } else { | 283 | break; |
259 | /* The GSS hash is identical to the DH one */ | 284 | default: |
260 | kex_dh_hash( kex->client_version_string, | 285 | fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); |
261 | kex->server_version_string, | 286 | } |
262 | buffer_ptr(&kex->my), buffer_len(&kex->my), | ||
263 | buffer_ptr(&kex->peer), buffer_len(&kex->peer), | ||
264 | serverhostkey, slen, /* server host key */ | ||
265 | dh->pub_key, /* e */ | ||
266 | dh_server_pub, /* f */ | ||
267 | shared_secret, /* K */ | ||
268 | &hash, &hashlen | ||
269 | ); | ||
270 | } | ||
271 | 287 | ||
272 | gssbuf.value = hash; | 288 | gssbuf.value = hash; |
273 | gssbuf.length = hashlen; | 289 | gssbuf.length = hashlen; |
274 | 290 | ||
275 | /* Verify that the hash matches the MIC we just got. */ | 291 | /* Verify that the hash matches the MIC we just got. */ |
276 | if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) | 292 | if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) |
277 | packet_disconnect("Hash's MIC didn't verify"); | 293 | packet_disconnect("Hash's MIC didn't verify"); |
278 | 294 | ||