diff options
author | markus@openbsd.org <markus@openbsd.org> | 2018-07-09 21:03:30 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2018-07-10 15:14:26 +1000 |
commit | cecee2d607099a7bba0a84803e2325d15be4277b (patch) | |
tree | e5f685fb39c9d8512235334afc4b26e8461bfc36 /sshconnect2.c | |
parent | ff55f4ad898137d4703e7a2bcc81167dfe8e9324 (diff) |
upstream: client: switch to sshbuf API; ok djm@
OpenBSD-Commit-ID: 60cb0356114acc7625ab85105f6f6a7cd44a8d05
Diffstat (limited to 'sshconnect2.c')
-rw-r--r-- | sshconnect2.c | 489 |
1 files changed, 277 insertions, 212 deletions
diff --git a/sshconnect2.c b/sshconnect2.c index 4bc0a7034..2194e3a8d 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.277 2018/07/09 13:37:10 sf Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.278 2018/07/09 21:03:30 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
@@ -49,11 +49,11 @@ | |||
49 | #include "xmalloc.h" | 49 | #include "xmalloc.h" |
50 | #include "ssh.h" | 50 | #include "ssh.h" |
51 | #include "ssh2.h" | 51 | #include "ssh2.h" |
52 | #include "buffer.h" | 52 | #include "sshbuf.h" |
53 | #include "packet.h" | 53 | #include "packet.h" |
54 | #include "compat.h" | 54 | #include "compat.h" |
55 | #include "cipher.h" | 55 | #include "cipher.h" |
56 | #include "key.h" | 56 | #include "sshkey.h" |
57 | #include "kex.h" | 57 | #include "kex.h" |
58 | #include "myproposal.h" | 58 | #include "myproposal.h" |
59 | #include "sshconnect.h" | 59 | #include "sshconnect.h" |
@@ -232,10 +232,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) | |||
232 | 232 | ||
233 | #ifdef DEBUG_KEXDH | 233 | #ifdef DEBUG_KEXDH |
234 | /* send 1st encrypted/maced/compressed message */ | 234 | /* send 1st encrypted/maced/compressed message */ |
235 | packet_start(SSH2_MSG_IGNORE); | 235 | if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || |
236 | packet_put_cstring("markus"); | 236 | (r = sshpkt_put_cstring(ssh, "markus")) != 0 || |
237 | packet_send(); | 237 | (r = sshpkt_send(ssh)) != 0) |
238 | packet_write_wait(); | 238 | fatal("%s: %s", __func__, ssh_err(r)); |
239 | ssh_packet_write_wait(ssh); | ||
239 | #endif | 240 | #endif |
240 | } | 241 | } |
241 | 242 | ||
@@ -457,6 +458,8 @@ input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh) | |||
457 | void | 458 | void |
458 | userauth(Authctxt *authctxt, char *authlist) | 459 | userauth(Authctxt *authctxt, char *authlist) |
459 | { | 460 | { |
461 | struct ssh *ssh = active_state; /* XXX */ | ||
462 | |||
460 | if (authctxt->method != NULL && authctxt->method->cleanup != NULL) | 463 | if (authctxt->method != NULL && authctxt->method->cleanup != NULL) |
461 | authctxt->method->cleanup(authctxt); | 464 | authctxt->method->cleanup(authctxt); |
462 | 465 | ||
@@ -476,7 +479,7 @@ userauth(Authctxt *authctxt, char *authlist) | |||
476 | authctxt->method = method; | 479 | authctxt->method = method; |
477 | 480 | ||
478 | /* reset the per method handler */ | 481 | /* reset the per method handler */ |
479 | dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN, | 482 | ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_PER_METHOD_MIN, |
480 | SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL); | 483 | SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL); |
481 | 484 | ||
482 | /* and try new method */ | 485 | /* and try new method */ |
@@ -553,14 +556,16 @@ input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh) | |||
553 | { | 556 | { |
554 | Authctxt *authctxt = ssh->authctxt; | 557 | Authctxt *authctxt = ssh->authctxt; |
555 | char *authlist = NULL; | 558 | char *authlist = NULL; |
556 | int partial; | 559 | u_char partial; |
560 | int r; | ||
557 | 561 | ||
558 | if (authctxt == NULL) | 562 | if (authctxt == NULL) |
559 | fatal("input_userauth_failure: no authentication context"); | 563 | fatal("input_userauth_failure: no authentication context"); |
560 | 564 | ||
561 | authlist = packet_get_string(NULL); | 565 | if ((r = sshpkt_get_cstring(ssh, &authlist, NULL)) != 0 || |
562 | partial = packet_get_char(); | 566 | (r = sshpkt_get_u8(ssh, &partial)) != 0 || |
563 | packet_check_eom(); | 567 | (r = sshpkt_get_end(ssh)) != 0) |
568 | goto out; | ||
564 | 569 | ||
565 | if (partial != 0) { | 570 | if (partial != 0) { |
566 | verbose("Authenticated with partial success."); | 571 | verbose("Authenticated with partial success."); |
@@ -570,6 +575,9 @@ input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh) | |||
570 | debug("Authentications that can continue: %s", authlist); | 575 | debug("Authentications that can continue: %s", authlist); |
571 | 576 | ||
572 | userauth(authctxt, authlist); | 577 | userauth(authctxt, authlist); |
578 | authlist = NULL; | ||
579 | out: | ||
580 | free(authlist); | ||
573 | return 0; | 581 | return 0; |
574 | } | 582 | } |
575 | 583 | ||
@@ -581,25 +589,27 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
581 | struct sshkey *key = NULL; | 589 | struct sshkey *key = NULL; |
582 | Identity *id = NULL; | 590 | Identity *id = NULL; |
583 | int pktype, sent = 0; | 591 | int pktype, sent = 0; |
584 | u_int alen, blen; | 592 | size_t blen; |
585 | char *pkalg, *fp; | 593 | char *pkalg = NULL, *fp; |
586 | u_char *pkblob; | 594 | u_char *pkblob = NULL; |
595 | int r; | ||
587 | 596 | ||
588 | if (authctxt == NULL) | 597 | if (authctxt == NULL) |
589 | fatal("input_userauth_pk_ok: no authentication context"); | 598 | fatal("input_userauth_pk_ok: no authentication context"); |
590 | 599 | ||
591 | pkalg = packet_get_string(&alen); | 600 | if ((r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 || |
592 | pkblob = packet_get_string(&blen); | 601 | (r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 || |
593 | packet_check_eom(); | 602 | (r = sshpkt_get_end(ssh)) != 0) |
603 | goto done; | ||
594 | 604 | ||
595 | debug("Server accepts key: pkalg %s blen %u", pkalg, blen); | 605 | debug("Server accepts key: pkalg %s blen %zu", pkalg, blen); |
596 | 606 | ||
597 | if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) { | 607 | if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) { |
598 | debug("unknown pkalg %s", pkalg); | 608 | debug("unknown pkalg %s", pkalg); |
599 | goto done; | 609 | goto done; |
600 | } | 610 | } |
601 | if ((key = key_from_blob(pkblob, blen)) == NULL) { | 611 | if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { |
602 | debug("no key from blob. pkalg %s", pkalg); | 612 | debug("no key from blob. pkalg %s: %s", pkalg, ssh_err(r)); |
603 | goto done; | 613 | goto done; |
604 | } | 614 | } |
605 | if (key->type != pktype) { | 615 | if (key->type != pktype) { |
@@ -620,31 +630,33 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
620 | * duplicate keys | 630 | * duplicate keys |
621 | */ | 631 | */ |
622 | TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { | 632 | TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { |
623 | if (key_equal(key, id->key)) { | 633 | if (sshkey_equal(key, id->key)) { |
624 | sent = sign_and_send_pubkey(ssh, authctxt, id); | 634 | sent = sign_and_send_pubkey(ssh, authctxt, id); |
625 | break; | 635 | break; |
626 | } | 636 | } |
627 | } | 637 | } |
628 | done: | 638 | r = 0; |
629 | key_free(key); | 639 | done: |
640 | sshkey_free(key); | ||
630 | free(pkalg); | 641 | free(pkalg); |
631 | free(pkblob); | 642 | free(pkblob); |
632 | 643 | ||
633 | /* try another method if we did not send a packet */ | 644 | /* try another method if we did not send a packet */ |
634 | if (sent == 0) | 645 | if (r == 0 && sent == 0) |
635 | userauth(authctxt, NULL); | 646 | userauth(authctxt, NULL); |
636 | return 0; | 647 | return r; |
637 | } | 648 | } |
638 | 649 | ||
639 | #ifdef GSSAPI | 650 | #ifdef GSSAPI |
640 | int | 651 | int |
641 | userauth_gssapi(Authctxt *authctxt) | 652 | userauth_gssapi(Authctxt *authctxt) |
642 | { | 653 | { |
654 | struct ssh *ssh = active_state; /* XXX */ | ||
643 | Gssctxt *gssctxt = NULL; | 655 | Gssctxt *gssctxt = NULL; |
644 | static gss_OID_set gss_supported = NULL; | 656 | static gss_OID_set gss_supported = NULL; |
645 | static u_int mech = 0; | 657 | static u_int mech = 0; |
646 | OM_uint32 min; | 658 | OM_uint32 min; |
647 | int ok = 0; | 659 | int r, ok = 0; |
648 | 660 | ||
649 | /* Try one GSSAPI method at a time, rather than sending them all at | 661 | /* Try one GSSAPI method at a time, rather than sending them all at |
650 | * once. */ | 662 | * once. */ |
@@ -669,25 +681,26 @@ userauth_gssapi(Authctxt *authctxt) | |||
669 | 681 | ||
670 | authctxt->methoddata=(void *)gssctxt; | 682 | authctxt->methoddata=(void *)gssctxt; |
671 | 683 | ||
672 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 684 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
673 | packet_put_cstring(authctxt->server_user); | 685 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
674 | packet_put_cstring(authctxt->service); | 686 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
675 | packet_put_cstring(authctxt->method->name); | 687 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
676 | 688 | (r = sshpkt_put_u32(ssh, 1)) != 0 || | |
677 | packet_put_int(1); | 689 | (r = sshpkt_put_u32(ssh, |
678 | 690 | (gss_supported->elements[mech].length) + 2)) != 0 || | |
679 | packet_put_int((gss_supported->elements[mech].length) + 2); | 691 | (r = sshpkt_put_u8(ssh, SSH_GSS_OIDTYPE)) != 0 || |
680 | packet_put_char(SSH_GSS_OIDTYPE); | 692 | (r = sshpkt_put_u8(ssh, |
681 | packet_put_char(gss_supported->elements[mech].length); | 693 | gss_supported->elements[mech].length)) != 0 || |
682 | packet_put_raw(gss_supported->elements[mech].elements, | 694 | (r = sshpkt_put(ssh, |
683 | gss_supported->elements[mech].length); | 695 | gss_supported->elements[mech].elements, |
684 | 696 | gss_supported->elements[mech].length)) != 0 || | |
685 | packet_send(); | 697 | (r = sshpkt_send(ssh)) != 0) |
698 | fatal("%s: %s", __func__, ssh_err(r)); | ||
686 | 699 | ||
687 | dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response); | 700 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response); |
688 | dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); | 701 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); |
689 | dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); | 702 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); |
690 | dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); | 703 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); |
691 | 704 | ||
692 | mech++; /* Move along to next candidate */ | 705 | mech++; /* Move along to next candidate */ |
693 | 706 | ||
@@ -703,44 +716,56 @@ process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok) | |||
703 | gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; | 716 | gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; |
704 | gss_buffer_desc gssbuf; | 717 | gss_buffer_desc gssbuf; |
705 | OM_uint32 status, ms, flags; | 718 | OM_uint32 status, ms, flags; |
706 | Buffer b; | 719 | int r; |
707 | 720 | ||
708 | status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, | 721 | status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, |
709 | recv_tok, &send_tok, &flags); | 722 | recv_tok, &send_tok, &flags); |
710 | 723 | ||
711 | if (send_tok.length > 0) { | 724 | if (send_tok.length > 0) { |
712 | if (GSS_ERROR(status)) | 725 | u_char type = GSS_ERROR(status) ? |
713 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); | 726 | SSH2_MSG_USERAUTH_GSSAPI_ERRTOK : |
714 | else | 727 | SSH2_MSG_USERAUTH_GSSAPI_TOKEN; |
715 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); | 728 | |
729 | if ((r = sshpkt_start(ssh, type)) != 0 || | ||
730 | (r = sshpkt_put_string(ssh, send_tok.value, | ||
731 | send_tok.length)) != 0 || | ||
732 | (r = sshpkt_send(ssh)) != 0) | ||
733 | fatal("%s: %s", __func__, ssh_err(r)); | ||
716 | 734 | ||
717 | packet_put_string(send_tok.value, send_tok.length); | ||
718 | packet_send(); | ||
719 | gss_release_buffer(&ms, &send_tok); | 735 | gss_release_buffer(&ms, &send_tok); |
720 | } | 736 | } |
721 | 737 | ||
722 | if (status == GSS_S_COMPLETE) { | 738 | if (status == GSS_S_COMPLETE) { |
723 | /* send either complete or MIC, depending on mechanism */ | 739 | /* send either complete or MIC, depending on mechanism */ |
724 | if (!(flags & GSS_C_INTEG_FLAG)) { | 740 | if (!(flags & GSS_C_INTEG_FLAG)) { |
725 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); | 741 | if ((r = sshpkt_start(ssh, |
726 | packet_send(); | 742 | SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || |
743 | (r = sshpkt_send(ssh)) != 0) | ||
744 | fatal("%s: %s", __func__, ssh_err(r)); | ||
727 | } else { | 745 | } else { |
728 | ssh_gssapi_buildmic(&b, authctxt->server_user, | 746 | struct sshbuf *b; |
747 | |||
748 | if ((b = sshbuf_new()) == NULL) | ||
749 | fatal("%s: sshbuf_new failed", __func__); | ||
750 | ssh_gssapi_buildmic(b, authctxt->server_user, | ||
729 | authctxt->service, "gssapi-with-mic"); | 751 | authctxt->service, "gssapi-with-mic"); |
730 | 752 | ||
731 | gssbuf.value = buffer_ptr(&b); | 753 | if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) |
732 | gssbuf.length = buffer_len(&b); | 754 | fatal("%s: sshbuf_mutable_ptr failed", __func__); |
755 | gssbuf.length = sshbuf_len(b); | ||
733 | 756 | ||
734 | status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic); | 757 | status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic); |
735 | 758 | ||
736 | if (!GSS_ERROR(status)) { | 759 | if (!GSS_ERROR(status)) { |
737 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC); | 760 | if ((r = sshpkt_start(ssh, |
738 | packet_put_string(mic.value, mic.length); | 761 | SSH2_MSG_USERAUTH_GSSAPI_MIC)) != 0 || |
739 | 762 | (r = sshpkt_put_string(ssh, mic.value, | |
740 | packet_send(); | 763 | mic.length)) != 0 || |
764 | (r = sshpkt_send(ssh)) != 0) | ||
765 | fatal("%s: %s", __func__, ssh_err(r)); | ||
741 | } | 766 | } |
742 | 767 | ||
743 | buffer_free(&b); | 768 | sshbuf_free(b); |
744 | gss_release_buffer(&ms, &mic); | 769 | gss_release_buffer(&ms, &mic); |
745 | } | 770 | } |
746 | } | 771 | } |
@@ -754,39 +779,43 @@ input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh) | |||
754 | { | 779 | { |
755 | Authctxt *authctxt = ssh->authctxt; | 780 | Authctxt *authctxt = ssh->authctxt; |
756 | Gssctxt *gssctxt; | 781 | Gssctxt *gssctxt; |
757 | int oidlen; | 782 | size_t oidlen; |
758 | char *oidv; | 783 | u_char *oidv = NULL; |
784 | int r; | ||
759 | 785 | ||
760 | if (authctxt == NULL) | 786 | if (authctxt == NULL) |
761 | fatal("input_gssapi_response: no authentication context"); | 787 | fatal("input_gssapi_response: no authentication context"); |
762 | gssctxt = authctxt->methoddata; | 788 | gssctxt = authctxt->methoddata; |
763 | 789 | ||
764 | /* Setup our OID */ | 790 | /* Setup our OID */ |
765 | oidv = packet_get_string(&oidlen); | 791 | if ((r = sshpkt_get_string(ssh, &oidv, &oidlen)) != 0) |
792 | goto done; | ||
766 | 793 | ||
767 | if (oidlen <= 2 || | 794 | if (oidlen <= 2 || |
768 | oidv[0] != SSH_GSS_OIDTYPE || | 795 | oidv[0] != SSH_GSS_OIDTYPE || |
769 | oidv[1] != oidlen - 2) { | 796 | oidv[1] != oidlen - 2) { |
770 | free(oidv); | ||
771 | debug("Badly encoded mechanism OID received"); | 797 | debug("Badly encoded mechanism OID received"); |
772 | userauth(authctxt, NULL); | 798 | userauth(authctxt, NULL); |
773 | return 0; | 799 | goto ok; |
774 | } | 800 | } |
775 | 801 | ||
776 | if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) | 802 | if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) |
777 | fatal("Server returned different OID than expected"); | 803 | fatal("Server returned different OID than expected"); |
778 | 804 | ||
779 | packet_check_eom(); | 805 | if ((r = sshpkt_get_end(ssh)) != 0) |
780 | 806 | goto done; | |
781 | free(oidv); | ||
782 | 807 | ||
783 | if (GSS_ERROR(process_gssapi_token(ssh, GSS_C_NO_BUFFER))) { | 808 | if (GSS_ERROR(process_gssapi_token(ssh, GSS_C_NO_BUFFER))) { |
784 | /* Start again with next method on list */ | 809 | /* Start again with next method on list */ |
785 | debug("Trying to start again"); | 810 | debug("Trying to start again"); |
786 | userauth(authctxt, NULL); | 811 | userauth(authctxt, NULL); |
787 | return 0; | 812 | goto ok; |
788 | } | 813 | } |
789 | return 0; | 814 | ok: |
815 | r = 0; | ||
816 | done: | ||
817 | free(oidv); | ||
818 | return r; | ||
790 | } | 819 | } |
791 | 820 | ||
792 | /* ARGSUSED */ | 821 | /* ARGSUSED */ |
@@ -795,27 +824,31 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) | |||
795 | { | 824 | { |
796 | Authctxt *authctxt = ssh->authctxt; | 825 | Authctxt *authctxt = ssh->authctxt; |
797 | gss_buffer_desc recv_tok; | 826 | gss_buffer_desc recv_tok; |
827 | u_char *p = NULL; | ||
828 | size_t len; | ||
798 | OM_uint32 status; | 829 | OM_uint32 status; |
799 | u_int slen; | 830 | int r; |
800 | 831 | ||
801 | if (authctxt == NULL) | 832 | if (authctxt == NULL) |
802 | fatal("input_gssapi_response: no authentication context"); | 833 | fatal("input_gssapi_response: no authentication context"); |
803 | 834 | ||
804 | recv_tok.value = packet_get_string(&slen); | 835 | if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || |
805 | recv_tok.length = slen; /* safe typecast */ | 836 | (r = sshpkt_get_end(ssh)) != 0) |
806 | 837 | goto out; | |
807 | packet_check_eom(); | ||
808 | 838 | ||
839 | recv_tok.value = p; | ||
840 | recv_tok.length = len; | ||
809 | status = process_gssapi_token(ssh, &recv_tok); | 841 | status = process_gssapi_token(ssh, &recv_tok); |
810 | 842 | ||
811 | free(recv_tok.value); | 843 | /* Start again with the next method in the list */ |
812 | |||
813 | if (GSS_ERROR(status)) { | 844 | if (GSS_ERROR(status)) { |
814 | /* Start again with the next method in the list */ | ||
815 | userauth(authctxt, NULL); | 845 | userauth(authctxt, NULL); |
816 | return 0; | 846 | /* ok */ |
817 | } | 847 | } |
818 | return 0; | 848 | r = 0; |
849 | out: | ||
850 | free(p); | ||
851 | return r; | ||
819 | } | 852 | } |
820 | 853 | ||
821 | /* ARGSUSED */ | 854 | /* ARGSUSED */ |
@@ -827,22 +860,26 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) | |||
827 | gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; | 860 | gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; |
828 | gss_buffer_desc recv_tok; | 861 | gss_buffer_desc recv_tok; |
829 | OM_uint32 ms; | 862 | OM_uint32 ms; |
830 | u_int len; | 863 | u_char *p = NULL; |
864 | size_t len; | ||
865 | int r; | ||
831 | 866 | ||
832 | if (authctxt == NULL) | 867 | if (authctxt == NULL) |
833 | fatal("input_gssapi_response: no authentication context"); | 868 | fatal("input_gssapi_response: no authentication context"); |
834 | gssctxt = authctxt->methoddata; | 869 | gssctxt = authctxt->methoddata; |
835 | 870 | ||
836 | recv_tok.value = packet_get_string(&len); | 871 | if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || |
837 | recv_tok.length = len; | 872 | (r = sshpkt_get_end(ssh)) != 0) { |
838 | 873 | free(p); | |
839 | packet_check_eom(); | 874 | return r; |
875 | } | ||
840 | 876 | ||
841 | /* Stick it into GSSAPI and see what it says */ | 877 | /* Stick it into GSSAPI and see what it says */ |
878 | recv_tok.value = p; | ||
879 | recv_tok.length = len; | ||
842 | (void)ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, | 880 | (void)ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, |
843 | &recv_tok, &send_tok, NULL); | 881 | &recv_tok, &send_tok, NULL); |
844 | 882 | free(p); | |
845 | free(recv_tok.value); | ||
846 | gss_release_buffer(&ms, &send_tok); | 883 | gss_release_buffer(&ms, &send_tok); |
847 | 884 | ||
848 | /* Server will be returning a failed packet after this one */ | 885 | /* Server will be returning a failed packet after this one */ |
@@ -853,43 +890,50 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) | |||
853 | int | 890 | int |
854 | input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) | 891 | input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) |
855 | { | 892 | { |
856 | char *msg; | 893 | char *msg = NULL; |
857 | char *lang; | 894 | char *lang = NULL; |
858 | 895 | int r; | |
859 | /* maj */(void)packet_get_int(); | ||
860 | /* min */(void)packet_get_int(); | ||
861 | msg=packet_get_string(NULL); | ||
862 | lang=packet_get_string(NULL); | ||
863 | |||
864 | packet_check_eom(); | ||
865 | 896 | ||
897 | if ((r = sshpkt_get_u32(ssh, NULL)) != 0 || /* maj */ | ||
898 | (r = sshpkt_get_u32(ssh, NULL)) != 0 || /* min */ | ||
899 | (r = sshpkt_get_cstring(ssh, &msg, NULL)) != 0 || | ||
900 | (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0) | ||
901 | goto out; | ||
902 | r = sshpkt_get_end(ssh); | ||
866 | debug("Server GSSAPI Error:\n%s", msg); | 903 | debug("Server GSSAPI Error:\n%s", msg); |
904 | out: | ||
867 | free(msg); | 905 | free(msg); |
868 | free(lang); | 906 | free(lang); |
869 | return 0; | 907 | return r; |
870 | } | 908 | } |
871 | #endif /* GSSAPI */ | 909 | #endif /* GSSAPI */ |
872 | 910 | ||
873 | int | 911 | int |
874 | userauth_none(Authctxt *authctxt) | 912 | userauth_none(Authctxt *authctxt) |
875 | { | 913 | { |
914 | struct ssh *ssh = active_state; /* XXX */ | ||
915 | int r; | ||
916 | |||
876 | /* initial userauth request */ | 917 | /* initial userauth request */ |
877 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 918 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
878 | packet_put_cstring(authctxt->server_user); | 919 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
879 | packet_put_cstring(authctxt->service); | 920 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
880 | packet_put_cstring(authctxt->method->name); | 921 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
881 | packet_send(); | 922 | (r = sshpkt_send(ssh)) != 0) |
923 | fatal("%s: %s", __func__, ssh_err(r)); | ||
882 | return 1; | 924 | return 1; |
883 | } | 925 | } |
884 | 926 | ||
885 | int | 927 | int |
886 | userauth_passwd(Authctxt *authctxt) | 928 | userauth_passwd(Authctxt *authctxt) |
887 | { | 929 | { |
930 | struct ssh *ssh = active_state; /* XXX */ | ||
888 | static int attempt = 0; | 931 | static int attempt = 0; |
889 | char prompt[256]; | 932 | char prompt[256]; |
890 | char *password; | 933 | char *password; |
891 | const char *host = options.host_key_alias ? options.host_key_alias : | 934 | const char *host = options.host_key_alias ? options.host_key_alias : |
892 | authctxt->host; | 935 | authctxt->host; |
936 | int r; | ||
893 | 937 | ||
894 | if (attempt++ >= options.number_of_password_prompts) | 938 | if (attempt++ >= options.number_of_password_prompts) |
895 | return 0; | 939 | return 0; |
@@ -900,18 +944,20 @@ userauth_passwd(Authctxt *authctxt) | |||
900 | snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", | 944 | snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", |
901 | authctxt->server_user, host); | 945 | authctxt->server_user, host); |
902 | password = read_passphrase(prompt, 0); | 946 | password = read_passphrase(prompt, 0); |
903 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 947 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
904 | packet_put_cstring(authctxt->server_user); | 948 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
905 | packet_put_cstring(authctxt->service); | 949 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
906 | packet_put_cstring(authctxt->method->name); | 950 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
907 | packet_put_char(0); | 951 | (r = sshpkt_put_u8(ssh, 0)) != 0 || |
908 | packet_put_cstring(password); | 952 | (r = sshpkt_put_cstring(ssh, password)) != 0 || |
909 | explicit_bzero(password, strlen(password)); | 953 | (r = sshpkt_add_padding(ssh, 64)) != 0 || |
910 | free(password); | 954 | (r = sshpkt_send(ssh)) != 0) |
911 | packet_add_padding(64); | 955 | fatal("%s: %s", __func__, ssh_err(r)); |
912 | packet_send(); | 956 | |
913 | 957 | if (password) | |
914 | dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, | 958 | freezero(password, strlen(password)); |
959 | |||
960 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, | ||
915 | &input_userauth_passwd_changereq); | 961 | &input_userauth_passwd_changereq); |
916 | 962 | ||
917 | return 1; | 963 | return 1; |
@@ -925,9 +971,10 @@ int | |||
925 | input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) | 971 | input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) |
926 | { | 972 | { |
927 | Authctxt *authctxt = ssh->authctxt; | 973 | Authctxt *authctxt = ssh->authctxt; |
928 | char *info, *lang, *password = NULL, *retype = NULL; | 974 | char *info = NULL, *lang = NULL, *password = NULL, *retype = NULL; |
929 | char prompt[256]; | 975 | char prompt[256]; |
930 | const char *host; | 976 | const char *host; |
977 | int r; | ||
931 | 978 | ||
932 | debug2("input_userauth_passwd_changereq"); | 979 | debug2("input_userauth_passwd_changereq"); |
933 | 980 | ||
@@ -936,24 +983,26 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) | |||
936 | "no authentication context"); | 983 | "no authentication context"); |
937 | host = options.host_key_alias ? options.host_key_alias : authctxt->host; | 984 | host = options.host_key_alias ? options.host_key_alias : authctxt->host; |
938 | 985 | ||
939 | info = packet_get_string(NULL); | 986 | if ((r = sshpkt_get_cstring(ssh, &info, NULL)) != 0 || |
940 | lang = packet_get_string(NULL); | 987 | (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0) |
988 | goto out; | ||
941 | if (strlen(info) > 0) | 989 | if (strlen(info) > 0) |
942 | logit("%s", info); | 990 | logit("%s", info); |
943 | free(info); | 991 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
944 | free(lang); | 992 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
945 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 993 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
946 | packet_put_cstring(authctxt->server_user); | 994 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
947 | packet_put_cstring(authctxt->service); | 995 | (r = sshpkt_put_u8(ssh, 1)) != 0) /* additional info */ |
948 | packet_put_cstring(authctxt->method->name); | 996 | goto out; |
949 | packet_put_char(1); /* additional info */ | 997 | |
950 | snprintf(prompt, sizeof(prompt), | 998 | snprintf(prompt, sizeof(prompt), |
951 | "Enter %.30s@%.128s's old password: ", | 999 | "Enter %.30s@%.128s's old password: ", |
952 | authctxt->server_user, host); | 1000 | authctxt->server_user, host); |
953 | password = read_passphrase(prompt, 0); | 1001 | password = read_passphrase(prompt, 0); |
954 | packet_put_cstring(password); | 1002 | if ((r = sshpkt_put_cstring(ssh, password)) != 0) |
955 | explicit_bzero(password, strlen(password)); | 1003 | goto out; |
956 | free(password); | 1004 | |
1005 | freezero(password, strlen(password)); | ||
957 | password = NULL; | 1006 | password = NULL; |
958 | while (password == NULL) { | 1007 | while (password == NULL) { |
959 | snprintf(prompt, sizeof(prompt), | 1008 | snprintf(prompt, sizeof(prompt), |
@@ -962,30 +1011,34 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) | |||
962 | password = read_passphrase(prompt, RP_ALLOW_EOF); | 1011 | password = read_passphrase(prompt, RP_ALLOW_EOF); |
963 | if (password == NULL) { | 1012 | if (password == NULL) { |
964 | /* bail out */ | 1013 | /* bail out */ |
965 | return 0; | 1014 | r = 0; |
1015 | goto out; | ||
966 | } | 1016 | } |
967 | snprintf(prompt, sizeof(prompt), | 1017 | snprintf(prompt, sizeof(prompt), |
968 | "Retype %.30s@%.128s's new password: ", | 1018 | "Retype %.30s@%.128s's new password: ", |
969 | authctxt->server_user, host); | 1019 | authctxt->server_user, host); |
970 | retype = read_passphrase(prompt, 0); | 1020 | retype = read_passphrase(prompt, 0); |
971 | if (strcmp(password, retype) != 0) { | 1021 | if (strcmp(password, retype) != 0) { |
972 | explicit_bzero(password, strlen(password)); | 1022 | freezero(password, strlen(password)); |
973 | free(password); | ||
974 | logit("Mismatch; try again, EOF to quit."); | 1023 | logit("Mismatch; try again, EOF to quit."); |
975 | password = NULL; | 1024 | password = NULL; |
976 | } | 1025 | } |
977 | explicit_bzero(retype, strlen(retype)); | 1026 | freezero(retype, strlen(retype)); |
978 | free(retype); | ||
979 | } | 1027 | } |
980 | packet_put_cstring(password); | 1028 | if ((r = sshpkt_put_cstring(ssh, password)) != 0 || |
981 | explicit_bzero(password, strlen(password)); | 1029 | (r = sshpkt_add_padding(ssh, 64)) != 0 || |
982 | free(password); | 1030 | (r = sshpkt_send(ssh)) != 0) |
983 | packet_add_padding(64); | 1031 | goto out; |
984 | packet_send(); | ||
985 | 1032 | ||
986 | dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, | 1033 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, |
987 | &input_userauth_passwd_changereq); | 1034 | &input_userauth_passwd_changereq); |
988 | return 0; | 1035 | r = 0; |
1036 | out: | ||
1037 | if (password) | ||
1038 | freezero(password, strlen(password)); | ||
1039 | free(info); | ||
1040 | free(lang); | ||
1041 | return r; | ||
989 | } | 1042 | } |
990 | 1043 | ||
991 | /* | 1044 | /* |
@@ -1192,7 +1245,7 @@ sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id) | |||
1192 | __func__, ssh_err(r)); | 1245 | __func__, ssh_err(r)); |
1193 | } | 1246 | } |
1194 | } | 1247 | } |
1195 | skip = buffer_len(b); | 1248 | skip = sshbuf_len(b); |
1196 | if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || | 1249 | if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
1197 | (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 || | 1250 | (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 || |
1198 | (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || | 1251 | (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || |
@@ -1259,34 +1312,36 @@ static int | |||
1259 | send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id) | 1312 | send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id) |
1260 | { | 1313 | { |
1261 | u_char *blob = NULL; | 1314 | u_char *blob = NULL; |
1262 | u_int bloblen, have_sig = 0; | ||
1263 | char *alg = NULL; | 1315 | char *alg = NULL; |
1264 | int sent = 0; | 1316 | size_t bloblen; |
1317 | u_int have_sig = 0; | ||
1318 | int sent = 0, r; | ||
1265 | 1319 | ||
1266 | if ((alg = key_sig_algorithm(ssh, id->key)) == NULL) { | 1320 | if ((alg = key_sig_algorithm(ssh, id->key)) == NULL) { |
1267 | debug("%s: no mutual signature algorithm", __func__); | 1321 | debug("%s: no mutual signature algorithm", __func__); |
1268 | goto out; | 1322 | goto out; |
1269 | } | 1323 | } |
1270 | 1324 | ||
1271 | if (key_to_blob(id->key, &blob, &bloblen) == 0) { | 1325 | if ((r = sshkey_to_blob(id->key, &blob, &bloblen)) != 0) { |
1272 | /* we cannot handle this key */ | 1326 | /* we cannot handle this key */ |
1273 | debug3("%s: cannot handle key", __func__); | 1327 | debug3("%s: cannot handle key", __func__); |
1274 | goto out; | 1328 | goto out; |
1275 | } | 1329 | } |
1276 | /* register callback for USERAUTH_PK_OK message */ | 1330 | /* register callback for USERAUTH_PK_OK message */ |
1277 | dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); | 1331 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); |
1278 | 1332 | ||
1279 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 1333 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
1280 | packet_put_cstring(authctxt->server_user); | 1334 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
1281 | packet_put_cstring(authctxt->service); | 1335 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
1282 | packet_put_cstring(authctxt->method->name); | 1336 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
1283 | packet_put_char(have_sig); | 1337 | (r = sshpkt_put_u8(ssh, have_sig)) != 0 || |
1284 | packet_put_cstring(alg); | 1338 | (r = sshpkt_put_cstring(ssh, alg)) != 0 || |
1285 | packet_put_string(blob, bloblen); | 1339 | (r = sshpkt_put_string(ssh, blob, bloblen)) != 0 || |
1286 | packet_send(); | 1340 | (r = sshpkt_send(ssh)) != 0) |
1287 | /* success */ | 1341 | fatal("%s: %s", __func__, ssh_err(r)); |
1288 | sent = 1; | 1342 | sent = 1; |
1289 | out: | 1343 | |
1344 | out: | ||
1290 | free(alg); | 1345 | free(alg); |
1291 | free(blob); | 1346 | free(blob); |
1292 | return sent; | 1347 | return sent; |
@@ -1347,10 +1402,8 @@ load_identity_file(Identity *id) | |||
1347 | !(id->key && id->isprivate)) | 1402 | !(id->key && id->isprivate)) |
1348 | maybe_add_key_to_agent(id->filename, private, comment, | 1403 | maybe_add_key_to_agent(id->filename, private, comment, |
1349 | passphrase); | 1404 | passphrase); |
1350 | if (i > 0) { | 1405 | if (i > 0) |
1351 | explicit_bzero(passphrase, strlen(passphrase)); | 1406 | freezero(passphrase, strlen(passphrase)); |
1352 | free(passphrase); | ||
1353 | } | ||
1354 | free(comment); | 1407 | free(comment); |
1355 | if (private != NULL || quit) | 1408 | if (private != NULL || quit) |
1356 | break; | 1409 | break; |
@@ -1427,7 +1480,7 @@ pubkey_prepare(Authctxt *authctxt) | |||
1427 | /* list of certificates specified by user */ | 1480 | /* list of certificates specified by user */ |
1428 | for (i = 0; i < options.num_certificate_files; i++) { | 1481 | for (i = 0; i < options.num_certificate_files; i++) { |
1429 | key = options.certificates[i]; | 1482 | key = options.certificates[i]; |
1430 | if (!key_is_cert(key) || key->cert == NULL || | 1483 | if (!sshkey_is_cert(key) || key->cert == NULL || |
1431 | key->cert->type != SSH2_CERT_TYPE_USER) | 1484 | key->cert->type != SSH2_CERT_TYPE_USER) |
1432 | continue; | 1485 | continue; |
1433 | id = xcalloc(1, sizeof(*id)); | 1486 | id = xcalloc(1, sizeof(*id)); |
@@ -1501,8 +1554,7 @@ pubkey_prepare(Authctxt *authctxt) | |||
1501 | /* If IdentitiesOnly set and key not found then don't use it */ | 1554 | /* If IdentitiesOnly set and key not found then don't use it */ |
1502 | if (!found && options.identities_only) { | 1555 | if (!found && options.identities_only) { |
1503 | TAILQ_REMOVE(&files, id, next); | 1556 | TAILQ_REMOVE(&files, id, next); |
1504 | explicit_bzero(id, sizeof(*id)); | 1557 | freezero(id, sizeof(*id)); |
1505 | free(id); | ||
1506 | } | 1558 | } |
1507 | } | 1559 | } |
1508 | /* append remaining keys from the config file */ | 1560 | /* append remaining keys from the config file */ |
@@ -1609,7 +1661,7 @@ userauth_pubkey(Authctxt *authctxt) | |||
1609 | sent = sign_and_send_pubkey(ssh, | 1661 | sent = sign_and_send_pubkey(ssh, |
1610 | authctxt, id); | 1662 | authctxt, id); |
1611 | } | 1663 | } |
1612 | key_free(id->key); | 1664 | sshkey_free(id->key); |
1613 | id->key = NULL; | 1665 | id->key = NULL; |
1614 | id->isprivate = 0; | 1666 | id->isprivate = 0; |
1615 | } | 1667 | } |
@@ -1626,28 +1678,31 @@ userauth_pubkey(Authctxt *authctxt) | |||
1626 | int | 1678 | int |
1627 | userauth_kbdint(Authctxt *authctxt) | 1679 | userauth_kbdint(Authctxt *authctxt) |
1628 | { | 1680 | { |
1681 | struct ssh *ssh = active_state; /* XXX */ | ||
1629 | static int attempt = 0; | 1682 | static int attempt = 0; |
1683 | int r; | ||
1630 | 1684 | ||
1631 | if (attempt++ >= options.number_of_password_prompts) | 1685 | if (attempt++ >= options.number_of_password_prompts) |
1632 | return 0; | 1686 | return 0; |
1633 | /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */ | 1687 | /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */ |
1634 | if (attempt > 1 && !authctxt->info_req_seen) { | 1688 | if (attempt > 1 && !authctxt->info_req_seen) { |
1635 | debug3("userauth_kbdint: disable: no info_req_seen"); | 1689 | debug3("userauth_kbdint: disable: no info_req_seen"); |
1636 | dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL); | 1690 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST, NULL); |
1637 | return 0; | 1691 | return 0; |
1638 | } | 1692 | } |
1639 | 1693 | ||
1640 | debug2("userauth_kbdint"); | 1694 | debug2("userauth_kbdint"); |
1641 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 1695 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
1642 | packet_put_cstring(authctxt->server_user); | 1696 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
1643 | packet_put_cstring(authctxt->service); | 1697 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
1644 | packet_put_cstring(authctxt->method->name); | 1698 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
1645 | packet_put_cstring(""); /* lang */ | 1699 | (r = sshpkt_put_cstring(ssh, "")) != 0 || /* lang */ |
1646 | packet_put_cstring(options.kbd_interactive_devices ? | 1700 | (r = sshpkt_put_cstring(ssh, options.kbd_interactive_devices ? |
1647 | options.kbd_interactive_devices : ""); | 1701 | options.kbd_interactive_devices : "")) != 0 || |
1648 | packet_send(); | 1702 | (r = sshpkt_send(ssh)) != 0) |
1649 | 1703 | fatal("%s: %s", __func__, ssh_err(r)); | |
1650 | dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req); | 1704 | |
1705 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req); | ||
1651 | return 1; | 1706 | return 1; |
1652 | } | 1707 | } |
1653 | 1708 | ||
@@ -1658,9 +1713,11 @@ int | |||
1658 | input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) | 1713 | input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) |
1659 | { | 1714 | { |
1660 | Authctxt *authctxt = ssh->authctxt; | 1715 | Authctxt *authctxt = ssh->authctxt; |
1661 | char *name, *inst, *lang, *prompt, *response; | 1716 | char *name = NULL, *inst = NULL, *lang = NULL, *prompt = NULL; |
1717 | char *response = NULL; | ||
1718 | u_char echo = 0; | ||
1662 | u_int num_prompts, i; | 1719 | u_int num_prompts, i; |
1663 | int echo = 0; | 1720 | int r; |
1664 | 1721 | ||
1665 | debug2("input_userauth_info_req"); | 1722 | debug2("input_userauth_info_req"); |
1666 | 1723 | ||
@@ -1669,44 +1726,52 @@ input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) | |||
1669 | 1726 | ||
1670 | authctxt->info_req_seen = 1; | 1727 | authctxt->info_req_seen = 1; |
1671 | 1728 | ||
1672 | name = packet_get_string(NULL); | 1729 | if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0 || |
1673 | inst = packet_get_string(NULL); | 1730 | (r = sshpkt_get_cstring(ssh, &inst, NULL)) != 0 || |
1674 | lang = packet_get_string(NULL); | 1731 | (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0) |
1732 | goto out; | ||
1675 | if (strlen(name) > 0) | 1733 | if (strlen(name) > 0) |
1676 | logit("%s", name); | 1734 | logit("%s", name); |
1677 | if (strlen(inst) > 0) | 1735 | if (strlen(inst) > 0) |
1678 | logit("%s", inst); | 1736 | logit("%s", inst); |
1679 | free(name); | ||
1680 | free(inst); | ||
1681 | free(lang); | ||
1682 | 1737 | ||
1683 | num_prompts = packet_get_int(); | 1738 | if ((r = sshpkt_get_u32(ssh, &num_prompts)) != 0) |
1739 | goto out; | ||
1684 | /* | 1740 | /* |
1685 | * Begin to build info response packet based on prompts requested. | 1741 | * Begin to build info response packet based on prompts requested. |
1686 | * We commit to providing the correct number of responses, so if | 1742 | * We commit to providing the correct number of responses, so if |
1687 | * further on we run into a problem that prevents this, we have to | 1743 | * further on we run into a problem that prevents this, we have to |
1688 | * be sure and clean this up and send a correct error response. | 1744 | * be sure and clean this up and send a correct error response. |
1689 | */ | 1745 | */ |
1690 | packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE); | 1746 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE)) != 0 || |
1691 | packet_put_int(num_prompts); | 1747 | (r = sshpkt_put_u32(ssh, num_prompts)) != 0) |
1748 | goto out; | ||
1692 | 1749 | ||
1693 | debug2("input_userauth_info_req: num_prompts %d", num_prompts); | 1750 | debug2("input_userauth_info_req: num_prompts %d", num_prompts); |
1694 | for (i = 0; i < num_prompts; i++) { | 1751 | for (i = 0; i < num_prompts; i++) { |
1695 | prompt = packet_get_string(NULL); | 1752 | if ((r = sshpkt_get_cstring(ssh, &prompt, NULL)) != 0 || |
1696 | echo = packet_get_char(); | 1753 | (r = sshpkt_get_u8(ssh, &echo)) != 0) |
1697 | 1754 | goto out; | |
1698 | response = read_passphrase(prompt, echo ? RP_ECHO : 0); | 1755 | response = read_passphrase(prompt, echo ? RP_ECHO : 0); |
1699 | 1756 | if ((r = sshpkt_put_cstring(ssh, response)) != 0) | |
1700 | packet_put_cstring(response); | 1757 | goto out; |
1701 | explicit_bzero(response, strlen(response)); | 1758 | freezero(response, strlen(response)); |
1702 | free(response); | ||
1703 | free(prompt); | 1759 | free(prompt); |
1760 | response = prompt = NULL; | ||
1704 | } | 1761 | } |
1705 | packet_check_eom(); /* done with parsing incoming message. */ | 1762 | /* done with parsing incoming message. */ |
1706 | 1763 | if ((r = sshpkt_get_end(ssh)) != 0 || | |
1707 | packet_add_padding(64); | 1764 | (r = sshpkt_add_padding(ssh, 64)) != 0) |
1708 | packet_send(); | 1765 | goto out; |
1709 | return 0; | 1766 | r = sshpkt_send(ssh); |
1767 | out: | ||
1768 | if (response) | ||
1769 | freezero(response, strlen(response)); | ||
1770 | free(prompt); | ||
1771 | free(name); | ||
1772 | free(inst); | ||
1773 | free(lang); | ||
1774 | return r; | ||
1710 | } | 1775 | } |
1711 | 1776 | ||
1712 | static int | 1777 | static int |
@@ -1952,10 +2017,8 @@ userauth_hostbased(Authctxt *authctxt) | |||
1952 | success = 1; | 2017 | success = 1; |
1953 | 2018 | ||
1954 | out: | 2019 | out: |
1955 | if (sig != NULL) { | 2020 | if (sig != NULL) |
1956 | explicit_bzero(sig, siglen); | 2021 | freezero(sig, siglen); |
1957 | free(sig); | ||
1958 | } | ||
1959 | free(keyblob); | 2022 | free(keyblob); |
1960 | free(lname); | 2023 | free(lname); |
1961 | free(fp); | 2024 | free(fp); |
@@ -2052,20 +2115,22 @@ static char * | |||
2052 | authmethods_get(void) | 2115 | authmethods_get(void) |
2053 | { | 2116 | { |
2054 | Authmethod *method = NULL; | 2117 | Authmethod *method = NULL; |
2055 | Buffer b; | 2118 | struct sshbuf *b; |
2056 | char *list; | 2119 | char *list; |
2120 | int r; | ||
2057 | 2121 | ||
2058 | buffer_init(&b); | 2122 | if ((b = sshbuf_new()) == NULL) |
2123 | fatal("%s: sshbuf_new failed", __func__); | ||
2059 | for (method = authmethods; method->name != NULL; method++) { | 2124 | for (method = authmethods; method->name != NULL; method++) { |
2060 | if (authmethod_is_enabled(method)) { | 2125 | if (authmethod_is_enabled(method)) { |
2061 | if (buffer_len(&b) > 0) | 2126 | if ((r = sshbuf_putf(b, "%s%s", |
2062 | buffer_append(&b, ",", 1); | 2127 | sshbuf_len(b) ? "," : "", method->name)) != 0) |
2063 | buffer_append(&b, method->name, strlen(method->name)); | 2128 | fatal("%s: buffer error: %s", |
2129 | __func__, ssh_err(r)); | ||
2064 | } | 2130 | } |
2065 | } | 2131 | } |
2066 | if ((list = sshbuf_dup_string(&b)) == NULL) | 2132 | if ((list = sshbuf_dup_string(b)) == NULL) |
2067 | fatal("%s: sshbuf_dup_string failed", __func__); | 2133 | fatal("%s: sshbuf_dup_string failed", __func__); |
2068 | buffer_free(&b); | 2134 | sshbuf_free(b); |
2069 | return list; | 2135 | return list; |
2070 | } | 2136 | } |
2071 | |||