diff options
Diffstat (limited to 'sshconnect2.c')
-rw-r--r-- | sshconnect2.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/sshconnect2.c b/sshconnect2.c index a96153903..bb72db5dd 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -312,6 +312,10 @@ Authmethod authmethods[] = { | |||
312 | NULL, | 312 | NULL, |
313 | &options.gss_authentication, | 313 | &options.gss_authentication, |
314 | NULL}, | 314 | NULL}, |
315 | {"gssapi", | ||
316 | userauth_gssapi, | ||
317 | &options.gss_authentication, | ||
318 | NULL}, | ||
315 | #endif | 319 | #endif |
316 | {"hostbased", | 320 | {"hostbased", |
317 | userauth_hostbased, | 321 | userauth_hostbased, |
@@ -599,6 +603,7 @@ userauth_gssapi(Authctxt *authctxt) | |||
599 | OM_uint32 min; | 603 | OM_uint32 min; |
600 | int ok = 0; | 604 | int ok = 0; |
601 | const char *gss_host; | 605 | const char *gss_host; |
606 | int old_gssapi_method; | ||
602 | 607 | ||
603 | if (options.gss_trust_dns) | 608 | if (options.gss_trust_dns) |
604 | gss_host = get_canonical_hostname(1); | 609 | gss_host = get_canonical_hostname(1); |
@@ -637,13 +642,25 @@ userauth_gssapi(Authctxt *authctxt) | |||
637 | packet_put_cstring(authctxt->service); | 642 | packet_put_cstring(authctxt->service); |
638 | packet_put_cstring(authctxt->method->name); | 643 | packet_put_cstring(authctxt->method->name); |
639 | 644 | ||
640 | packet_put_int(1); | 645 | old_gssapi_method = !strcmp(authctxt->method->name, "gssapi"); |
646 | |||
647 | /* Versions of Debian ssh-krb5 prior to 3.8.1p1-1 don't expect | ||
648 | * tagged OIDs. As such we include both tagged and untagged oids | ||
649 | * for the old gssapi method. | ||
650 | * We only include tagged oids for the new gssapi-with-mic method. | ||
651 | */ | ||
652 | packet_put_int(old_gssapi_method ? 2 : 1); | ||
641 | 653 | ||
642 | packet_put_int((gss_supported->elements[mech].length) + 2); | 654 | packet_put_int((gss_supported->elements[mech].length) + 2); |
643 | packet_put_char(SSH_GSS_OIDTYPE); | 655 | packet_put_char(SSH_GSS_OIDTYPE); |
644 | packet_put_char(gss_supported->elements[mech].length); | 656 | packet_put_char(gss_supported->elements[mech].length); |
645 | packet_put_raw(gss_supported->elements[mech].elements, | 657 | packet_put_raw(gss_supported->elements[mech].elements, |
646 | gss_supported->elements[mech].length); | 658 | gss_supported->elements[mech].length); |
659 | if (old_gssapi_method) { | ||
660 | packet_put_int(gss_supported->elements[mech].length); | ||
661 | packet_put_raw(gss_supported->elements[mech].elements, | ||
662 | gss_supported->elements[mech].length); | ||
663 | } | ||
647 | 664 | ||
648 | packet_send(); | 665 | packet_send(); |
649 | 666 | ||
@@ -683,8 +700,10 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok) | |||
683 | } | 700 | } |
684 | 701 | ||
685 | if (status == GSS_S_COMPLETE) { | 702 | if (status == GSS_S_COMPLETE) { |
703 | int old_gssapi_method = !strcmp(authctxt->method->name, | ||
704 | "gssapi"); | ||
686 | /* send either complete or MIC, depending on mechanism */ | 705 | /* send either complete or MIC, depending on mechanism */ |
687 | if (!(flags & GSS_C_INTEG_FLAG)) { | 706 | if (old_gssapi_method || !(flags & GSS_C_INTEG_FLAG)) { |
688 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); | 707 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); |
689 | packet_send(); | 708 | packet_send(); |
690 | } else { | 709 | } else { |
@@ -718,7 +737,7 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) | |||
718 | Authctxt *authctxt = ctxt; | 737 | Authctxt *authctxt = ctxt; |
719 | Gssctxt *gssctxt; | 738 | Gssctxt *gssctxt; |
720 | u_int oidlen; | 739 | u_int oidlen; |
721 | u_char *oidv; | 740 | u_char *oidv, *oidv_free; |
722 | 741 | ||
723 | if (authctxt == NULL) | 742 | if (authctxt == NULL) |
724 | fatal("input_gssapi_response: no authentication context"); | 743 | fatal("input_gssapi_response: no authentication context"); |
@@ -726,22 +745,28 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) | |||
726 | 745 | ||
727 | /* Setup our OID */ | 746 | /* Setup our OID */ |
728 | oidv = packet_get_string(&oidlen); | 747 | oidv = packet_get_string(&oidlen); |
748 | oidv_free = oidv; | ||
729 | 749 | ||
730 | if (oidlen <= 2 || | 750 | if (oidlen <= 2 || |
731 | oidv[0] != SSH_GSS_OIDTYPE || | 751 | oidv[0] != SSH_GSS_OIDTYPE || |
732 | oidv[1] != oidlen - 2) { | 752 | oidv[1] != oidlen - 2) { |
733 | xfree(oidv); | ||
734 | debug("Badly encoded mechanism OID received"); | 753 | debug("Badly encoded mechanism OID received"); |
735 | userauth(authctxt, NULL); | 754 | if (oidlen < 2) { |
736 | return; | 755 | xfree(oidv_free); |
756 | userauth(authctxt, NULL); | ||
757 | return; | ||
758 | } | ||
759 | } else { | ||
760 | oidlen -= 2; | ||
761 | oidv += 2; | ||
737 | } | 762 | } |
738 | 763 | ||
739 | if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) | 764 | if (!ssh_gssapi_check_oid(gssctxt, oidv, oidlen)) |
740 | fatal("Server returned different OID than expected"); | 765 | fatal("Server returned different OID than expected"); |
741 | 766 | ||
742 | packet_check_eom(); | 767 | packet_check_eom(); |
743 | 768 | ||
744 | xfree(oidv); | 769 | xfree(oidv_free); |
745 | 770 | ||
746 | if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) { | 771 | if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) { |
747 | /* Start again with next method on list */ | 772 | /* Start again with next method on list */ |
@@ -1390,6 +1415,8 @@ pubkey_prepare(Authctxt *authctxt) | |||
1390 | 1415 | ||
1391 | /* list of keys stored in the filesystem */ | 1416 | /* list of keys stored in the filesystem */ |
1392 | for (i = 0; i < options.num_identity_files; i++) { | 1417 | for (i = 0; i < options.num_identity_files; i++) { |
1418 | if (options.identity_files[i] == NULL) | ||
1419 | continue; | ||
1393 | key = options.identity_keys[i]; | 1420 | key = options.identity_keys[i]; |
1394 | if (key && key->type == KEY_RSA1) | 1421 | if (key && key->type == KEY_RSA1) |
1395 | continue; | 1422 | continue; |
@@ -1480,7 +1507,7 @@ userauth_pubkey(Authctxt *authctxt) | |||
1480 | if (id->key && id->key->type != KEY_RSA1) { | 1507 | if (id->key && id->key->type != KEY_RSA1) { |
1481 | debug("Offering public key: %s", id->filename); | 1508 | debug("Offering public key: %s", id->filename); |
1482 | sent = send_pubkey_test(authctxt, id); | 1509 | sent = send_pubkey_test(authctxt, id); |
1483 | } else if (id->key == NULL) { | 1510 | } else if (id->key == NULL && id->filename) { |
1484 | debug("Trying private key: %s", id->filename); | 1511 | debug("Trying private key: %s", id->filename); |
1485 | id->key = load_identity_file(id->filename); | 1512 | id->key = load_identity_file(id->filename); |
1486 | if (id->key != NULL) { | 1513 | if (id->key != NULL) { |