diff options
Diffstat (limited to 'sshconnect2.c')
-rw-r--r-- | sshconnect2.c | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/sshconnect2.c b/sshconnect2.c index f7d34bf02..185e7b204 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -297,6 +297,10 @@ Authmethod authmethods[] = { | |||
297 | userauth_gssapi, | 297 | userauth_gssapi, |
298 | &options.gss_authentication, | 298 | &options.gss_authentication, |
299 | NULL}, | 299 | NULL}, |
300 | {"gssapi", | ||
301 | userauth_gssapi, | ||
302 | &options.gss_authentication, | ||
303 | NULL}, | ||
300 | #endif | 304 | #endif |
301 | {"hostbased", | 305 | {"hostbased", |
302 | userauth_hostbased, | 306 | userauth_hostbased, |
@@ -437,8 +441,9 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt) | |||
437 | if (options.log_level >= SYSLOG_LEVEL_INFO) { | 441 | if (options.log_level >= SYSLOG_LEVEL_INFO) { |
438 | if (len > 65536) | 442 | if (len > 65536) |
439 | len = 65536; | 443 | len = 65536; |
440 | msg = xmalloc(len * 4); /* max expansion from strnvis() */ | 444 | msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ |
441 | strnvis(msg, raw, len * 4, VIS_SAFE|VIS_OCTAL); | 445 | strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL); |
446 | msg[len*4] = '\0'; | ||
442 | fprintf(stderr, "%s", msg); | 447 | fprintf(stderr, "%s", msg); |
443 | xfree(msg); | 448 | xfree(msg); |
444 | } | 449 | } |
@@ -563,6 +568,7 @@ userauth_gssapi(Authctxt *authctxt) | |||
563 | OM_uint32 min; | 568 | OM_uint32 min; |
564 | int ok = 0; | 569 | int ok = 0; |
565 | char *gss_host = NULL; | 570 | char *gss_host = NULL; |
571 | int old_gssapi_method; | ||
566 | 572 | ||
567 | if (options.gss_trust_dns) | 573 | if (options.gss_trust_dns) |
568 | gss_host = (char *)get_canonical_hostname(1); | 574 | gss_host = (char *)get_canonical_hostname(1); |
@@ -597,13 +603,25 @@ userauth_gssapi(Authctxt *authctxt) | |||
597 | packet_put_cstring(authctxt->service); | 603 | packet_put_cstring(authctxt->service); |
598 | packet_put_cstring(authctxt->method->name); | 604 | packet_put_cstring(authctxt->method->name); |
599 | 605 | ||
600 | packet_put_int(1); | 606 | old_gssapi_method = !strcmp(authctxt->method->name, "gssapi"); |
607 | |||
608 | /* Versions of Debian ssh-krb5 prior to 3.8.1p1-1 don't expect | ||
609 | * tagged OIDs. As such we include both tagged and untagged oids | ||
610 | * for the old gssapi method. | ||
611 | * We only include tagged oids for the new gssapi-with-mic method. | ||
612 | */ | ||
613 | packet_put_int(old_gssapi_method ? 2 : 1); | ||
601 | 614 | ||
602 | packet_put_int((gss_supported->elements[mech].length) + 2); | 615 | packet_put_int((gss_supported->elements[mech].length) + 2); |
603 | packet_put_char(SSH_GSS_OIDTYPE); | 616 | packet_put_char(SSH_GSS_OIDTYPE); |
604 | packet_put_char(gss_supported->elements[mech].length); | 617 | packet_put_char(gss_supported->elements[mech].length); |
605 | packet_put_raw(gss_supported->elements[mech].elements, | 618 | packet_put_raw(gss_supported->elements[mech].elements, |
606 | gss_supported->elements[mech].length); | 619 | gss_supported->elements[mech].length); |
620 | if (old_gssapi_method) { | ||
621 | packet_put_int(gss_supported->elements[mech].length); | ||
622 | packet_put_raw(gss_supported->elements[mech].elements, | ||
623 | gss_supported->elements[mech].length); | ||
624 | } | ||
607 | 625 | ||
608 | packet_send(); | 626 | packet_send(); |
609 | 627 | ||
@@ -643,8 +661,10 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok) | |||
643 | } | 661 | } |
644 | 662 | ||
645 | if (status == GSS_S_COMPLETE) { | 663 | if (status == GSS_S_COMPLETE) { |
664 | int old_gssapi_method = !strcmp(authctxt->method->name, | ||
665 | "gssapi"); | ||
646 | /* send either complete or MIC, depending on mechanism */ | 666 | /* send either complete or MIC, depending on mechanism */ |
647 | if (!(flags & GSS_C_INTEG_FLAG)) { | 667 | if (old_gssapi_method || !(flags & GSS_C_INTEG_FLAG)) { |
648 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); | 668 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); |
649 | packet_send(); | 669 | packet_send(); |
650 | } else { | 670 | } else { |
@@ -677,7 +697,7 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) | |||
677 | Authctxt *authctxt = ctxt; | 697 | Authctxt *authctxt = ctxt; |
678 | Gssctxt *gssctxt; | 698 | Gssctxt *gssctxt; |
679 | u_int oidlen; | 699 | u_int oidlen; |
680 | u_char *oidv; | 700 | u_char *oidv, *oidv_free; |
681 | 701 | ||
682 | if (authctxt == NULL) | 702 | if (authctxt == NULL) |
683 | fatal("input_gssapi_response: no authentication context"); | 703 | fatal("input_gssapi_response: no authentication context"); |
@@ -685,22 +705,28 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) | |||
685 | 705 | ||
686 | /* Setup our OID */ | 706 | /* Setup our OID */ |
687 | oidv = packet_get_string(&oidlen); | 707 | oidv = packet_get_string(&oidlen); |
708 | oidv_free = oidv; | ||
688 | 709 | ||
689 | if (oidlen <= 2 || | 710 | if (oidlen <= 2 || |
690 | oidv[0] != SSH_GSS_OIDTYPE || | 711 | oidv[0] != SSH_GSS_OIDTYPE || |
691 | oidv[1] != oidlen - 2) { | 712 | oidv[1] != oidlen - 2) { |
692 | xfree(oidv); | ||
693 | debug("Badly encoded mechanism OID received"); | 713 | debug("Badly encoded mechanism OID received"); |
694 | userauth(authctxt, NULL); | 714 | if (oidlen < 2) { |
695 | return; | 715 | xfree(oidv_free); |
716 | userauth(authctxt, NULL); | ||
717 | return; | ||
718 | } | ||
719 | } else { | ||
720 | oidlen -= 2; | ||
721 | oidv += 2; | ||
696 | } | 722 | } |
697 | 723 | ||
698 | if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) | 724 | if (!ssh_gssapi_check_oid(gssctxt, oidv, oidlen)) |
699 | fatal("Server returned different OID than expected"); | 725 | fatal("Server returned different OID than expected"); |
700 | 726 | ||
701 | packet_check_eom(); | 727 | packet_check_eom(); |
702 | 728 | ||
703 | xfree(oidv); | 729 | xfree(oidv_free); |
704 | 730 | ||
705 | if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) { | 731 | if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) { |
706 | /* Start again with next method on list */ | 732 | /* Start again with next method on list */ |
@@ -1141,6 +1167,8 @@ pubkey_prepare(Authctxt *authctxt) | |||
1141 | 1167 | ||
1142 | /* list of keys stored in the filesystem */ | 1168 | /* list of keys stored in the filesystem */ |
1143 | for (i = 0; i < options.num_identity_files; i++) { | 1169 | for (i = 0; i < options.num_identity_files; i++) { |
1170 | if (options.identity_files[i] == NULL) | ||
1171 | continue; | ||
1144 | key = options.identity_keys[i]; | 1172 | key = options.identity_keys[i]; |
1145 | if (key && key->type == KEY_RSA1) | 1173 | if (key && key->type == KEY_RSA1) |
1146 | continue; | 1174 | continue; |
@@ -1231,7 +1259,7 @@ userauth_pubkey(Authctxt *authctxt) | |||
1231 | if (id->key && id->key->type != KEY_RSA1) { | 1259 | if (id->key && id->key->type != KEY_RSA1) { |
1232 | debug("Offering public key: %s", id->filename); | 1260 | debug("Offering public key: %s", id->filename); |
1233 | sent = send_pubkey_test(authctxt, id); | 1261 | sent = send_pubkey_test(authctxt, id); |
1234 | } else if (id->key == NULL) { | 1262 | } else if (id->key == NULL && id->filename) { |
1235 | debug("Trying private key: %s", id->filename); | 1263 | debug("Trying private key: %s", id->filename); |
1236 | id->key = load_identity_file(id->filename); | 1264 | id->key = load_identity_file(id->filename); |
1237 | if (id->key != NULL) { | 1265 | if (id->key != NULL) { |