diff options
Diffstat (limited to 'sshconnect2.c')
-rw-r--r-- | sshconnect2.c | 105 |
1 files changed, 102 insertions, 3 deletions
diff --git a/sshconnect2.c b/sshconnect2.c index 208df078c..a28b06502 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -99,9 +99,34 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
99 | { | 99 | { |
100 | Kex *kex; | 100 | Kex *kex; |
101 | 101 | ||
102 | #ifdef GSSAPI | ||
103 | char *orig = NULL, *gss = NULL; | ||
104 | char *gss_host = NULL; | ||
105 | #endif | ||
106 | |||
102 | xxx_host = host; | 107 | xxx_host = host; |
103 | xxx_hostaddr = hostaddr; | 108 | xxx_hostaddr = hostaddr; |
104 | 109 | ||
110 | #ifdef GSSAPI | ||
111 | if (options.gss_keyex) { | ||
112 | /* Add the GSSAPI mechanisms currently supported on this | ||
113 | * client to the key exchange algorithm proposal */ | ||
114 | orig = myproposal[PROPOSAL_KEX_ALGS]; | ||
115 | |||
116 | if (options.gss_trust_dns) | ||
117 | gss_host = (char *)get_canonical_hostname(1); | ||
118 | else | ||
119 | gss_host = host; | ||
120 | |||
121 | gss = ssh_gssapi_client_mechanisms(gss_host); | ||
122 | if (gss) { | ||
123 | debug("Offering GSSAPI proposal: %s", gss); | ||
124 | xasprintf(&myproposal[PROPOSAL_KEX_ALGS], | ||
125 | "%s,%s", gss, orig); | ||
126 | } | ||
127 | } | ||
128 | #endif | ||
129 | |||
105 | if (options.ciphers == (char *)-1) { | 130 | if (options.ciphers == (char *)-1) { |
106 | logit("No valid ciphers for protocol version 2 given, using defaults."); | 131 | logit("No valid ciphers for protocol version 2 given, using defaults."); |
107 | options.ciphers = NULL; | 132 | options.ciphers = NULL; |
@@ -129,6 +154,16 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
129 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = | 154 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = |
130 | options.hostkeyalgorithms; | 155 | options.hostkeyalgorithms; |
131 | 156 | ||
157 | #ifdef GSSAPI | ||
158 | /* If we've got GSSAPI algorithms, then we also support the | ||
159 | * 'null' hostkey, as a last resort */ | ||
160 | if (options.gss_keyex && gss) { | ||
161 | orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; | ||
162 | xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], | ||
163 | "%s,null", orig); | ||
164 | } | ||
165 | #endif | ||
166 | |||
132 | if (options.rekey_limit) | 167 | if (options.rekey_limit) |
133 | packet_set_rekey_limit(options.rekey_limit); | 168 | packet_set_rekey_limit(options.rekey_limit); |
134 | 169 | ||
@@ -138,10 +173,21 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
138 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; | 173 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; |
139 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; | 174 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; |
140 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; | 175 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; |
176 | #ifdef GSSAPI | ||
177 | kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; | ||
178 | kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; | ||
179 | kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; | ||
180 | #endif | ||
141 | kex->client_version_string=client_version_string; | 181 | kex->client_version_string=client_version_string; |
142 | kex->server_version_string=server_version_string; | 182 | kex->server_version_string=server_version_string; |
143 | kex->verify_host_key=&verify_host_key_callback; | 183 | kex->verify_host_key=&verify_host_key_callback; |
144 | 184 | ||
185 | #ifdef GSSAPI | ||
186 | kex->gss_deleg_creds = options.gss_deleg_creds; | ||
187 | kex->gss_trust_dns = options.gss_trust_dns; | ||
188 | kex->gss_host = gss_host; | ||
189 | #endif | ||
190 | |||
145 | xxx_kex = kex; | 191 | xxx_kex = kex; |
146 | 192 | ||
147 | dispatch_run(DISPATCH_BLOCK, &kex->done, kex); | 193 | dispatch_run(DISPATCH_BLOCK, &kex->done, kex); |
@@ -224,6 +270,7 @@ void input_gssapi_token(int type, u_int32_t, void *); | |||
224 | void input_gssapi_hash(int type, u_int32_t, void *); | 270 | void input_gssapi_hash(int type, u_int32_t, void *); |
225 | void input_gssapi_error(int, u_int32_t, void *); | 271 | void input_gssapi_error(int, u_int32_t, void *); |
226 | void input_gssapi_errtok(int, u_int32_t, void *); | 272 | void input_gssapi_errtok(int, u_int32_t, void *); |
273 | int userauth_gsskeyex(Authctxt *authctxt); | ||
227 | #endif | 274 | #endif |
228 | 275 | ||
229 | void userauth(Authctxt *, char *); | 276 | void userauth(Authctxt *, char *); |
@@ -239,6 +286,10 @@ static char *authmethods_get(void); | |||
239 | 286 | ||
240 | Authmethod authmethods[] = { | 287 | Authmethod authmethods[] = { |
241 | #ifdef GSSAPI | 288 | #ifdef GSSAPI |
289 | {"gssapi-keyex", | ||
290 | userauth_gsskeyex, | ||
291 | &options.gss_authentication, | ||
292 | NULL}, | ||
242 | {"gssapi-with-mic", | 293 | {"gssapi-with-mic", |
243 | userauth_gssapi, | 294 | userauth_gssapi, |
244 | &options.gss_authentication, | 295 | &options.gss_authentication, |
@@ -501,6 +552,12 @@ userauth_gssapi(Authctxt *authctxt) | |||
501 | static u_int mech = 0; | 552 | static u_int mech = 0; |
502 | OM_uint32 min; | 553 | OM_uint32 min; |
503 | int ok = 0; | 554 | int ok = 0; |
555 | char *gss_host = NULL; | ||
556 | |||
557 | if (options.gss_trust_dns) | ||
558 | gss_host = (char *)get_canonical_hostname(1); | ||
559 | else | ||
560 | gss_host = (char *)authctxt->host; | ||
504 | 561 | ||
505 | /* Try one GSSAPI method at a time, rather than sending them all at | 562 | /* Try one GSSAPI method at a time, rather than sending them all at |
506 | * once. */ | 563 | * once. */ |
@@ -513,7 +570,7 @@ userauth_gssapi(Authctxt *authctxt) | |||
513 | /* My DER encoding requires length<128 */ | 570 | /* My DER encoding requires length<128 */ |
514 | if (gss_supported->elements[mech].length < 128 && | 571 | if (gss_supported->elements[mech].length < 128 && |
515 | ssh_gssapi_check_mechanism(&gssctxt, | 572 | ssh_gssapi_check_mechanism(&gssctxt, |
516 | &gss_supported->elements[mech], authctxt->host)) { | 573 | &gss_supported->elements[mech], gss_host)) { |
517 | ok = 1; /* Mechanism works */ | 574 | ok = 1; /* Mechanism works */ |
518 | } else { | 575 | } else { |
519 | mech++; | 576 | mech++; |
@@ -609,8 +666,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) | |||
609 | { | 666 | { |
610 | Authctxt *authctxt = ctxt; | 667 | Authctxt *authctxt = ctxt; |
611 | Gssctxt *gssctxt; | 668 | Gssctxt *gssctxt; |
612 | int oidlen; | 669 | u_int oidlen; |
613 | char *oidv; | 670 | u_char *oidv; |
614 | 671 | ||
615 | if (authctxt == NULL) | 672 | if (authctxt == NULL) |
616 | fatal("input_gssapi_response: no authentication context"); | 673 | fatal("input_gssapi_response: no authentication context"); |
@@ -717,6 +774,48 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt) | |||
717 | xfree(msg); | 774 | xfree(msg); |
718 | xfree(lang); | 775 | xfree(lang); |
719 | } | 776 | } |
777 | |||
778 | int | ||
779 | userauth_gsskeyex(Authctxt *authctxt) | ||
780 | { | ||
781 | Buffer b; | ||
782 | gss_buffer_desc gssbuf; | ||
783 | gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; | ||
784 | OM_uint32 ms; | ||
785 | |||
786 | static int attempt = 0; | ||
787 | if (attempt++ >= 1) | ||
788 | return (0); | ||
789 | |||
790 | if (gss_kex_context == NULL) { | ||
791 | debug("No valid Key exchange context"); | ||
792 | return (0); | ||
793 | } | ||
794 | |||
795 | ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, | ||
796 | "gssapi-keyex"); | ||
797 | |||
798 | gssbuf.value = buffer_ptr(&b); | ||
799 | gssbuf.length = buffer_len(&b); | ||
800 | |||
801 | if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { | ||
802 | buffer_free(&b); | ||
803 | return (0); | ||
804 | } | ||
805 | |||
806 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | ||
807 | packet_put_cstring(authctxt->server_user); | ||
808 | packet_put_cstring(authctxt->service); | ||
809 | packet_put_cstring(authctxt->method->name); | ||
810 | packet_put_string(mic.value, mic.length); | ||
811 | packet_send(); | ||
812 | |||
813 | buffer_free(&b); | ||
814 | gss_release_buffer(&ms, &mic); | ||
815 | |||
816 | return (1); | ||
817 | } | ||
818 | |||
720 | #endif /* GSSAPI */ | 819 | #endif /* GSSAPI */ |
721 | 820 | ||
722 | int | 821 | int |