summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c146
1 files changed, 136 insertions, 10 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index dd971a9f9..63e9369b1 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -98,9 +98,34 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
98{ 98{
99 Kex *kex; 99 Kex *kex;
100 100
101#ifdef GSSAPI
102 char *orig = NULL, *gss = NULL;
103 char *gss_host = NULL;
104#endif
105
101 xxx_host = host; 106 xxx_host = host;
102 xxx_hostaddr = hostaddr; 107 xxx_hostaddr = hostaddr;
103 108
109#ifdef GSSAPI
110 if (options.gss_keyex) {
111 /* Add the GSSAPI mechanisms currently supported on this
112 * client to the key exchange algorithm proposal */
113 orig = myproposal[PROPOSAL_KEX_ALGS];
114
115 if (options.gss_trust_dns)
116 gss_host = (char *)get_canonical_hostname(1);
117 else
118 gss_host = host;
119
120 gss = ssh_gssapi_client_mechanisms(gss_host);
121 if (gss) {
122 debug("Offering GSSAPI proposal: %s", gss);
123 xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
124 "%s,%s", gss, orig);
125 }
126 }
127#endif
128
104 if (options.ciphers == (char *)-1) { 129 if (options.ciphers == (char *)-1) {
105 logit("No valid ciphers for protocol version 2 given, using defaults."); 130 logit("No valid ciphers for protocol version 2 given, using defaults.");
106 options.ciphers = NULL; 131 options.ciphers = NULL;
@@ -128,6 +153,16 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
128 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 153 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
129 options.hostkeyalgorithms; 154 options.hostkeyalgorithms;
130 155
156#ifdef GSSAPI
157 /* If we've got GSSAPI algorithms, then we also support the
158 * 'null' hostkey, as a last resort */
159 if (options.gss_keyex && gss) {
160 orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
161 xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
162 "%s,null", orig);
163 }
164#endif
165
131 if (options.rekey_limit) 166 if (options.rekey_limit)
132 packet_set_rekey_limit(options.rekey_limit); 167 packet_set_rekey_limit(options.rekey_limit);
133 168
@@ -137,10 +172,23 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
137 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; 172 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
138 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; 173 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
139 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; 174 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
175#ifdef GSSAPI
176 if (options.gss_keyex) {
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 }
181#endif
140 kex->client_version_string=client_version_string; 182 kex->client_version_string=client_version_string;
141 kex->server_version_string=server_version_string; 183 kex->server_version_string=server_version_string;
142 kex->verify_host_key=&verify_host_key_callback; 184 kex->verify_host_key=&verify_host_key_callback;
143 185
186#ifdef GSSAPI
187 kex->gss_deleg_creds = options.gss_deleg_creds;
188 kex->gss_trust_dns = options.gss_trust_dns;
189 kex->gss_host = gss_host;
190#endif
191
144 xxx_kex = kex; 192 xxx_kex = kex;
145 193
146 dispatch_run(DISPATCH_BLOCK, &kex->done, kex); 194 dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
@@ -223,6 +271,7 @@ void input_gssapi_token(int type, u_int32_t, void *);
223void input_gssapi_hash(int type, u_int32_t, void *); 271void input_gssapi_hash(int type, u_int32_t, void *);
224void input_gssapi_error(int, u_int32_t, void *); 272void input_gssapi_error(int, u_int32_t, void *);
225void input_gssapi_errtok(int, u_int32_t, void *); 273void input_gssapi_errtok(int, u_int32_t, void *);
274int userauth_gsskeyex(Authctxt *authctxt);
226#endif 275#endif
227 276
228void userauth(Authctxt *, char *); 277void userauth(Authctxt *, char *);
@@ -238,10 +287,18 @@ static char *authmethods_get(void);
238 287
239Authmethod authmethods[] = { 288Authmethod authmethods[] = {
240#ifdef GSSAPI 289#ifdef GSSAPI
290 {"gssapi-keyex",
291 userauth_gsskeyex,
292 &options.gss_authentication,
293 NULL},
241 {"gssapi-with-mic", 294 {"gssapi-with-mic",
242 userauth_gssapi, 295 userauth_gssapi,
243 &options.gss_authentication, 296 &options.gss_authentication,
244 NULL}, 297 NULL},
298 {"gssapi",
299 userauth_gssapi,
300 &options.gss_authentication,
301 NULL},
245#endif 302#endif
246 {"hostbased", 303 {"hostbased",
247 userauth_hostbased, 304 userauth_hostbased,
@@ -500,6 +557,13 @@ userauth_gssapi(Authctxt *authctxt)
500 static u_int mech = 0; 557 static u_int mech = 0;
501 OM_uint32 min; 558 OM_uint32 min;
502 int ok = 0; 559 int ok = 0;
560 char *gss_host = NULL;
561 int old_gssapi_method;
562
563 if (options.gss_trust_dns)
564 gss_host = (char *)get_canonical_hostname(1);
565 else
566 gss_host = (char *)authctxt->host;
503 567
504 /* Try one GSSAPI method at a time, rather than sending them all at 568 /* Try one GSSAPI method at a time, rather than sending them all at
505 * once. */ 569 * once. */
@@ -512,7 +576,7 @@ userauth_gssapi(Authctxt *authctxt)
512 /* My DER encoding requires length<128 */ 576 /* My DER encoding requires length<128 */
513 if (gss_supported->elements[mech].length < 128 && 577 if (gss_supported->elements[mech].length < 128 &&
514 ssh_gssapi_check_mechanism(&gssctxt, 578 ssh_gssapi_check_mechanism(&gssctxt,
515 &gss_supported->elements[mech], authctxt->host)) { 579 &gss_supported->elements[mech], gss_host)) {
516 ok = 1; /* Mechanism works */ 580 ok = 1; /* Mechanism works */
517 } else { 581 } else {
518 mech++; 582 mech++;
@@ -529,13 +593,25 @@ userauth_gssapi(Authctxt *authctxt)
529 packet_put_cstring(authctxt->service); 593 packet_put_cstring(authctxt->service);
530 packet_put_cstring(authctxt->method->name); 594 packet_put_cstring(authctxt->method->name);
531 595
532 packet_put_int(1); 596 old_gssapi_method = !strcmp(authctxt->method->name, "gssapi");
597
598 /* Versions of Debian ssh-krb5 prior to 3.8.1p1-1 don't expect
599 * tagged OIDs. As such we include both tagged and untagged oids
600 * for the old gssapi method.
601 * We only include tagged oids for the new gssapi-with-mic method.
602 */
603 packet_put_int(old_gssapi_method ? 2 : 1);
533 604
534 packet_put_int((gss_supported->elements[mech].length) + 2); 605 packet_put_int((gss_supported->elements[mech].length) + 2);
535 packet_put_char(SSH_GSS_OIDTYPE); 606 packet_put_char(SSH_GSS_OIDTYPE);
536 packet_put_char(gss_supported->elements[mech].length); 607 packet_put_char(gss_supported->elements[mech].length);
537 packet_put_raw(gss_supported->elements[mech].elements, 608 packet_put_raw(gss_supported->elements[mech].elements,
538 gss_supported->elements[mech].length); 609 gss_supported->elements[mech].length);
610 if (old_gssapi_method) {
611 packet_put_int(gss_supported->elements[mech].length);
612 packet_put_raw(gss_supported->elements[mech].elements,
613 gss_supported->elements[mech].length);
614 }
539 615
540 packet_send(); 616 packet_send();
541 617
@@ -575,8 +651,10 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
575 } 651 }
576 652
577 if (status == GSS_S_COMPLETE) { 653 if (status == GSS_S_COMPLETE) {
654 int old_gssapi_method = !strcmp(authctxt->method->name,
655 "gssapi");
578 /* send either complete or MIC, depending on mechanism */ 656 /* send either complete or MIC, depending on mechanism */
579 if (!(flags & GSS_C_INTEG_FLAG)) { 657 if (old_gssapi_method || !(flags & GSS_C_INTEG_FLAG)) {
580 packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); 658 packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
581 packet_send(); 659 packet_send();
582 } else { 660 } else {
@@ -608,8 +686,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
608{ 686{
609 Authctxt *authctxt = ctxt; 687 Authctxt *authctxt = ctxt;
610 Gssctxt *gssctxt; 688 Gssctxt *gssctxt;
611 int oidlen; 689 u_int oidlen;
612 char *oidv; 690 u_char *oidv, *oidv_free;
613 691
614 if (authctxt == NULL) 692 if (authctxt == NULL)
615 fatal("input_gssapi_response: no authentication context"); 693 fatal("input_gssapi_response: no authentication context");
@@ -617,22 +695,28 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
617 695
618 /* Setup our OID */ 696 /* Setup our OID */
619 oidv = packet_get_string(&oidlen); 697 oidv = packet_get_string(&oidlen);
698 oidv_free = oidv;
620 699
621 if (oidlen <= 2 || 700 if (oidlen <= 2 ||
622 oidv[0] != SSH_GSS_OIDTYPE || 701 oidv[0] != SSH_GSS_OIDTYPE ||
623 oidv[1] != oidlen - 2) { 702 oidv[1] != oidlen - 2) {
624 xfree(oidv);
625 debug("Badly encoded mechanism OID received"); 703 debug("Badly encoded mechanism OID received");
626 userauth(authctxt, NULL); 704 if (oidlen < 2) {
627 return; 705 xfree(oidv_free);
706 userauth(authctxt, NULL);
707 return;
708 }
709 } else {
710 oidlen -= 2;
711 oidv += 2;
628 } 712 }
629 713
630 if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) 714 if (!ssh_gssapi_check_oid(gssctxt, oidv, oidlen))
631 fatal("Server returned different OID than expected"); 715 fatal("Server returned different OID than expected");
632 716
633 packet_check_eom(); 717 packet_check_eom();
634 718
635 xfree(oidv); 719 xfree(oidv_free);
636 720
637 if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) { 721 if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) {
638 /* Start again with next method on list */ 722 /* Start again with next method on list */
@@ -716,6 +800,48 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt)
716 xfree(msg); 800 xfree(msg);
717 xfree(lang); 801 xfree(lang);
718} 802}
803
804int
805userauth_gsskeyex(Authctxt *authctxt)
806{
807 Buffer b;
808 gss_buffer_desc gssbuf;
809 gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
810 OM_uint32 ms;
811
812 static int attempt = 0;
813 if (attempt++ >= 1)
814 return (0);
815
816 if (gss_kex_context == NULL) {
817 debug("No valid Key exchange context");
818 return (0);
819 }
820
821 ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service,
822 "gssapi-keyex");
823
824 gssbuf.value = buffer_ptr(&b);
825 gssbuf.length = buffer_len(&b);
826
827 if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
828 buffer_free(&b);
829 return (0);
830 }
831
832 packet_start(SSH2_MSG_USERAUTH_REQUEST);
833 packet_put_cstring(authctxt->server_user);
834 packet_put_cstring(authctxt->service);
835 packet_put_cstring(authctxt->method->name);
836 packet_put_string(mic.value, mic.length);
837 packet_send();
838
839 buffer_free(&b);
840 gss_release_buffer(&ms, &mic);
841
842 return (1);
843}
844
719#endif /* GSSAPI */ 845#endif /* GSSAPI */
720 846
721int 847int