sshconnect.c (fe5fd0173b1983e53ba8dbafb3229b37444e7986) | sshconnect.c (a8f6863aa612ce6941e7bad9cf809a8d0608a7ca) |
---|---|
1/* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * Created: Sat Mar 18 22:15:47 1995 ylo 6 * Code to connect to a remote host, and to perform the client side of the 7 * login (authentication) dialog. | 1/* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * Created: Sat Mar 18 22:15:47 1995 ylo 6 * Code to connect to a remote host, and to perform the client side of the 7 * login (authentication) dialog. |
8 * 9 * $FreeBSD$ | |
10 */ 11 12#include "includes.h" | 8 */ 9 10#include "includes.h" |
13RCSID("$OpenBSD: sshconnect.c,v 1.56 2000/02/18 08:50:33 markus Exp $"); | 11RCSID("$OpenBSD: sshconnect.c,v 1.58 2000/03/23 22:15:33 markus Exp $"); |
14 | 12 |
15#include <openssl/bn.h> | 13#include <ssl/bn.h> |
16#include "xmalloc.h" 17#include "rsa.h" 18#include "ssh.h" 19#include "packet.h" 20#include "authfd.h" 21#include "cipher.h" 22#include "mpaux.h" 23#include "uidswap.h" 24#include "compat.h" 25#include "readconf.h" | 14#include "xmalloc.h" 15#include "rsa.h" 16#include "ssh.h" 17#include "packet.h" 18#include "authfd.h" 19#include "cipher.h" 20#include "mpaux.h" 21#include "uidswap.h" 22#include "compat.h" 23#include "readconf.h" |
26#include "fingerprint.h" | |
27 | 24 |
28#include <openssl/md5.h> | 25#include <ssl/rsa.h> 26#include <ssl/dsa.h> 27#include <ssl/md5.h> 28#include "key.h" 29#include "hostfile.h" |
29 30/* Session id for the current session. */ 31unsigned char session_id[16]; 32 33/* authentications supported by server */ 34unsigned int supported_authentications; 35 36extern Options options; --- 584 unchanged lines hidden (view full) --- 621 if (type != SSH_SMSG_FAILURE) 622 packet_disconnect("Protocol error waiting RSA auth response: %d", type); 623 debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused."); 624 return 0; 625} 626 627#ifdef KRB4 628int | 30 31/* Session id for the current session. */ 32unsigned char session_id[16]; 33 34/* authentications supported by server */ 35unsigned int supported_authentications; 36 37extern Options options; --- 584 unchanged lines hidden (view full) --- 622 if (type != SSH_SMSG_FAILURE) 623 packet_disconnect("Protocol error waiting RSA auth response: %d", type); 624 debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused."); 625 return 0; 626} 627 628#ifdef KRB4 629int |
629try_krb4_authentication() | 630try_kerberos_authentication() |
630{ 631 KTEXT_ST auth; /* Kerberos data */ 632 char *reply; 633 char inst[INST_SZ]; 634 char *realm; 635 CREDENTIALS cred; 636 int r, type, plen; | 631{ 632 KTEXT_ST auth; /* Kerberos data */ 633 char *reply; 634 char inst[INST_SZ]; 635 char *realm; 636 CREDENTIALS cred; 637 int r, type, plen; |
638 socklen_t slen; |
|
637 Key_schedule schedule; 638 u_long checksum, cksum; 639 MSG_DAT msg_data; 640 struct sockaddr_in local, foreign; 641 struct stat st; 642 643 /* Don't do anything if we don't have any tickets. */ 644 if (stat(tkt_string(), &st) < 0) --- 18 unchanged lines hidden (view full) --- 663 r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred); 664 if (r != KSUCCESS) { 665 debug("get_cred failed: %s", krb_err_txt[r]); 666 return 0; 667 } 668 des_key_sched((des_cblock *) cred.session, schedule); 669 670 /* Send authentication info to server. */ | 639 Key_schedule schedule; 640 u_long checksum, cksum; 641 MSG_DAT msg_data; 642 struct sockaddr_in local, foreign; 643 struct stat st; 644 645 /* Don't do anything if we don't have any tickets. */ 646 if (stat(tkt_string(), &st) < 0) --- 18 unchanged lines hidden (view full) --- 665 r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred); 666 if (r != KSUCCESS) { 667 debug("get_cred failed: %s", krb_err_txt[r]); 668 return 0; 669 } 670 des_key_sched((des_cblock *) cred.session, schedule); 671 672 /* Send authentication info to server. */ |
671 packet_start(SSH_CMSG_AUTH_KRB4); | 673 packet_start(SSH_CMSG_AUTH_KERBEROS); |
672 packet_put_string((char *) auth.dat, auth.length); 673 packet_send(); 674 packet_write_wait(); 675 676 /* Zero the buffer. */ 677 (void) memset(auth.dat, 0, MAX_KTXT_LEN); 678 | 674 packet_put_string((char *) auth.dat, auth.length); 675 packet_send(); 676 packet_write_wait(); 677 678 /* Zero the buffer. */ 679 (void) memset(auth.dat, 0, MAX_KTXT_LEN); 680 |
679 r = sizeof(local); | 681 slen = sizeof(local); |
680 memset(&local, 0, sizeof(local)); 681 if (getsockname(packet_get_connection_in(), | 682 memset(&local, 0, sizeof(local)); 683 if (getsockname(packet_get_connection_in(), |
682 (struct sockaddr *) & local, &r) < 0) | 684 (struct sockaddr *) & local, &slen) < 0) |
683 debug("getsockname failed: %s", strerror(errno)); 684 | 685 debug("getsockname failed: %s", strerror(errno)); 686 |
685 r = sizeof(foreign); | 687 slen = sizeof(foreign); |
686 memset(&foreign, 0, sizeof(foreign)); 687 if (getpeername(packet_get_connection_in(), | 688 memset(&foreign, 0, sizeof(foreign)); 689 if (getpeername(packet_get_connection_in(), |
688 (struct sockaddr *) & foreign, &r) < 0) { | 690 (struct sockaddr *) & foreign, &slen) < 0) { |
689 debug("getpeername failed: %s", strerror(errno)); 690 fatal_cleanup(); 691 } 692 /* Get server reply. */ 693 type = packet_read(&plen); 694 switch (type) { 695 case SSH_SMSG_FAILURE: | 691 debug("getpeername failed: %s", strerror(errno)); 692 fatal_cleanup(); 693 } 694 /* Get server reply. */ 695 type = packet_read(&plen); 696 switch (type) { 697 case SSH_SMSG_FAILURE: |
696 /* Should really be SSH_SMSG_AUTH_KRB4_FAILURE */ | 698 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ |
697 debug("Kerberos V4 authentication failed."); 698 return 0; 699 break; 700 | 699 debug("Kerberos V4 authentication failed."); 700 return 0; 701 break; 702 |
701 case SSH_SMSG_AUTH_KRB4_RESPONSE: 702 /* SSH_SMSG_AUTH_KRB4_SUCCESS */ | 703 case SSH_SMSG_AUTH_KERBEROS_RESPONSE: 704 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ |
703 debug("Kerberos V4 authentication accepted."); 704 705 /* Get server's response. */ 706 reply = packet_get_string((unsigned int *) &auth.length); 707 memcpy(auth.dat, reply, auth.length); 708 xfree(reply); 709 710 packet_integrity_check(plen, 4 + auth.length, type); --- 26 unchanged lines hidden (view full) --- 737 } 738 return 0; 739} 740 741#endif /* KRB4 */ 742 743#ifdef AFS 744int | 705 debug("Kerberos V4 authentication accepted."); 706 707 /* Get server's response. */ 708 reply = packet_get_string((unsigned int *) &auth.length); 709 memcpy(auth.dat, reply, auth.length); 710 xfree(reply); 711 712 packet_integrity_check(plen, 4 + auth.length, type); --- 26 unchanged lines hidden (view full) --- 739 } 740 return 0; 741} 742 743#endif /* KRB4 */ 744 745#ifdef AFS 746int |
745send_krb4_tgt() | 747send_kerberos_tgt() |
746{ 747 CREDENTIALS *creds; 748 char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; 749 int r, type, plen; | 748{ 749 CREDENTIALS *creds; 750 char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; 751 int r, type, plen; |
750 unsigned char buffer[8192]; | 752 char buffer[8192]; |
751 struct stat st; 752 753 /* Don't do anything if we don't have any tickets. */ 754 if (stat(tkt_string(), &st) < 0) 755 return 0; 756 757 creds = xmalloc(sizeof(*creds)); 758 --- 4 unchanged lines hidden (view full) --- 763 if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) { 764 debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]); 765 return 0; 766 } 767 if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) { 768 debug("Kerberos V4 ticket expired: %s", TKT_FILE); 769 return 0; 770 } | 753 struct stat st; 754 755 /* Don't do anything if we don't have any tickets. */ 756 if (stat(tkt_string(), &st) < 0) 757 return 0; 758 759 creds = xmalloc(sizeof(*creds)); 760 --- 4 unchanged lines hidden (view full) --- 765 if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) { 766 debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]); 767 return 0; 768 } 769 if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) { 770 debug("Kerberos V4 ticket expired: %s", TKT_FILE); 771 return 0; 772 } |
771 creds_to_radix(creds, buffer); | 773 creds_to_radix(creds, (unsigned char *)buffer); |
772 xfree(creds); 773 | 774 xfree(creds); 775 |
774 packet_start(SSH_CMSG_HAVE_KRB4_TGT); 775 packet_put_string((char *) buffer, strlen(buffer)); | 776 packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); 777 packet_put_string(buffer, strlen(buffer)); |
776 packet_send(); 777 packet_write_wait(); 778 779 type = packet_read(&plen); 780 781 if (type == SSH_SMSG_FAILURE) 782 debug("Kerberos TGT for realm %s rejected.", prealm); 783 else if (type != SSH_SMSG_SUCCESS) --- 5 unchanged lines hidden (view full) --- 789void 790send_afs_tokens(void) 791{ 792 CREDENTIALS creds; 793 struct ViceIoctl parms; 794 struct ClearToken ct; 795 int i, type, len, plen; 796 char buf[2048], *p, *server_cell; | 778 packet_send(); 779 packet_write_wait(); 780 781 type = packet_read(&plen); 782 783 if (type == SSH_SMSG_FAILURE) 784 debug("Kerberos TGT for realm %s rejected.", prealm); 785 else if (type != SSH_SMSG_SUCCESS) --- 5 unchanged lines hidden (view full) --- 791void 792send_afs_tokens(void) 793{ 794 CREDENTIALS creds; 795 struct ViceIoctl parms; 796 struct ClearToken ct; 797 int i, type, len, plen; 798 char buf[2048], *p, *server_cell; |
797 unsigned char buffer[8192]; | 799 char buffer[8192]; |
798 799 /* Move over ktc_GetToken, here's something leaner. */ 800 for (i = 0; i < 100; i++) { /* just in case */ 801 parms.in = (char *) &i; 802 parms.in_size = sizeof(i); 803 parms.out = buf; 804 parms.out_size = sizeof(buf); 805 if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0) --- 25 unchanged lines hidden (view full) --- 831 memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ); 832 creds.issue_date = ct.BeginTimestamp; 833 creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp); 834 creds.kvno = ct.AuthHandle; 835 snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId); 836 creds.pinst[0] = '\0'; 837 838 /* Encode token, ship it off. */ | 800 801 /* Move over ktc_GetToken, here's something leaner. */ 802 for (i = 0; i < 100; i++) { /* just in case */ 803 parms.in = (char *) &i; 804 parms.in_size = sizeof(i); 805 parms.out = buf; 806 parms.out_size = sizeof(buf); 807 if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0) --- 25 unchanged lines hidden (view full) --- 833 memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ); 834 creds.issue_date = ct.BeginTimestamp; 835 creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp); 836 creds.kvno = ct.AuthHandle; 837 snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId); 838 creds.pinst[0] = '\0'; 839 840 /* Encode token, ship it off. */ |
839 if (!creds_to_radix(&creds, buffer)) | 841 if (!creds_to_radix(&creds, (unsigned char*) buffer)) |
840 break; 841 packet_start(SSH_CMSG_HAVE_AFS_TOKEN); | 842 break; 843 packet_start(SSH_CMSG_HAVE_AFS_TOKEN); |
842 packet_put_string((char *) buffer, strlen(buffer)); | 844 packet_put_string(buffer, strlen(buffer)); |
843 packet_send(); 844 packet_write_wait(); 845 846 /* Roger, Roger. Clearance, Clarence. What's your vector, 847 Victor? */ 848 type = packet_read(&plen); 849 850 if (type == SSH_SMSG_FAILURE) 851 debug("AFS token for cell %s rejected.", server_cell); 852 else if (type != SSH_SMSG_SUCCESS) 853 packet_disconnect("Protocol error on AFS token response: %d", type); 854 } 855} 856 857#endif /* AFS */ 858 | 845 packet_send(); 846 packet_write_wait(); 847 848 /* Roger, Roger. Clearance, Clarence. What's your vector, 849 Victor? */ 850 type = packet_read(&plen); 851 852 if (type == SSH_SMSG_FAILURE) 853 debug("AFS token for cell %s rejected.", server_cell); 854 else if (type != SSH_SMSG_SUCCESS) 855 packet_disconnect("Protocol error on AFS token response: %d", type); 856 } 857} 858 859#endif /* AFS */ 860 |
859#ifdef KRB5 860int 861try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context) 862{ 863 krb5_error_code problem; 864 const char *tkfile; 865 struct stat buf; 866 krb5_ccache ccache = NULL; 867 krb5_creds req_creds; 868 krb5_creds *new_creds = NULL; 869 const char *remotehost; 870 krb5_data ap; 871 int type, payload_len; 872 krb5_ap_rep_enc_part *reply = NULL; 873 int ret; 874 875 memset(&ap, 0, sizeof(ap)); 876 877 problem = krb5_init_context(context); 878 if (problem) { 879 ret = 0; 880 goto out; 881 } 882 883 tkfile = krb5_cc_default_name(*context); 884 if (strncmp(tkfile, "FILE:", 5) == 0) 885 tkfile += 5; 886 887 if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) { 888 debug("Kerberos V5: could not get default ccache (permission denied)."); 889 ret = 0; 890 goto out; 891 } 892 893 problem = krb5_cc_default(*context, &ccache); 894 if (problem) { 895 ret = 0; 896 goto out; 897 } 898 899 memset(&req_creds, 0, sizeof(req_creds)); 900 901 remotehost = get_canonical_hostname(); 902 903 problem = krb5_sname_to_principal(*context, remotehost, 904 "host", KRB5_NT_SRV_HST, 905 &req_creds.server); 906 if (problem) { 907 ret = 0; 908 goto out; 909 910 } 911 912 problem = krb5_cc_get_principal(*context, ccache, &req_creds.client); 913 if (problem) { 914 ret = 0; 915 goto out; 916 } 917 918 /* creds.session.keytype=ETYPE_DES_CBC_CRC; */ 919 920 problem = krb5_get_credentials(*context, 0, ccache, &req_creds, &new_creds); 921 if (problem) { 922 ret = 0; 923 goto out; 924 } 925 926 problem = krb5_auth_con_init(*context, auth_context); 927 if (problem) { 928 ret = 0; 929 goto out; 930 } 931 932 /* krb5_auth_con_setflags(ssh_context, auth_context, 933 KRB5_AUTH_CONTEXT_RET_TIME); 934 */ 935 problem = krb5_mk_req_extended(*context, auth_context, 936 AP_OPTS_MUTUAL_REQUIRED /*| AP_OPTS_USE_SUBKEY*/ , 937 NULL, new_creds, &ap); 938 if (problem) { 939 ret = 0; 940 goto out; 941 } 942 943 packet_start(SSH_CMSG_AUTH_KRB5); 944 packet_put_string((char *) ap.data, ap.length); 945 packet_send(); 946 packet_write_wait(); 947 948 xfree(ap.data); 949 ap.length = 0; 950 951 type = packet_read(&payload_len); 952 switch (type) { 953 case SSH_SMSG_FAILURE: 954 /* Should really be SSH_SMSG_AUTH_KRB5_FAILURE */ 955 debug("Kerberos V5 authentication failed."); 956 ret = 0; 957 break; 958 959 case SSH_SMSG_AUTH_KRB5_RESPONSE: 960 /* SSH_SMSG_AUTH_KRB5_SUCCESS */ 961 debug("Kerberos V5 authentication accepted."); 962 963 /* Get server's response. */ 964 ap.data = packet_get_string((unsigned int *) &ap.length); 965 966 packet_integrity_check(payload_len, 4 + ap.length, type); 967 /* XXX je to dobre? */ 968 969 problem = krb5_rd_rep(*context, *auth_context, &ap, &reply); 970 if (problem) { 971 ret = 0; 972 } 973 ret = 1; 974 break; 975 976 default: 977 packet_disconnect("Protocol error on Kerberos V5 response: %d", type); 978 ret = 0; 979 break; 980 981 } 982 983out: 984 if (req_creds.server != NULL) 985 krb5_free_principal(*context, req_creds.server); 986 if (req_creds.client != NULL) 987 krb5_free_principal(*context, req_creds.client); 988 if (new_creds != NULL) 989 krb5_free_creds(*context, new_creds); 990 if (ccache != NULL) 991 krb5_cc_close(*context, ccache); 992 if (reply != NULL) 993 krb5_free_ap_rep_enc_part(*context, reply); 994 if (ap.length > 0) 995 krb5_data_free(&ap); 996 997 return ret; 998 999} 1000 1001void 1002send_krb5_tgt(krb5_context context, krb5_auth_context auth_context) 1003{ 1004 int fd; 1005 int type, payload_len; 1006 krb5_error_code problem; 1007 krb5_data outbuf; 1008 krb5_ccache ccache = NULL; 1009 krb5_creds creds; 1010 krb5_kdc_flags flags; 1011 const char* remotehost = get_canonical_hostname(); 1012 1013 memset(&creds, 0, sizeof(creds)); 1014 memset(&outbuf, 0, sizeof(outbuf)); 1015 1016 fd = packet_get_connection_in(); 1017 problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd); 1018 if (problem) { 1019 goto out; 1020 } 1021 1022#if 0 1023 tkfile = krb5_cc_default_name(context); 1024 if (strncmp(tkfile, "FILE:", 5) == 0) 1025 tkfile += 5; 1026 1027 if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) { 1028 debug("Kerberos V5: could not get default ccache (permission denied)."); 1029 goto out; 1030 } 1031#endif 1032 1033 problem = krb5_cc_default(context, &ccache); 1034 if (problem) { 1035 goto out; 1036 } 1037 1038 problem = krb5_cc_get_principal(context, ccache, &creds.client); 1039 if (problem) { 1040 goto out; 1041 } 1042 1043 problem = krb5_build_principal(context, &creds.server, 1044 strlen(creds.client->realm), 1045 creds.client->realm, 1046 "krbtgt", 1047 creds.client->realm, 1048 NULL); 1049 if (problem) { 1050 goto out; 1051 } 1052 1053 creds.times.endtime = 0; 1054 1055 flags.i = 0; 1056 flags.b.forwarded = 1; 1057 flags.b.forwardable = krb5_config_get_bool(context, NULL, 1058 "libdefaults", "forwardable", NULL); 1059 1060 problem = krb5_get_forwarded_creds (context, 1061 auth_context, 1062 ccache, 1063 flags.i, 1064 remotehost, 1065 &creds, 1066 &outbuf); 1067 if (problem) { 1068 goto out; 1069 } 1070 1071 packet_start(SSH_CMSG_HAVE_KRB5_TGT); 1072 packet_put_string((char *)outbuf.data, outbuf.length); 1073 packet_send(); 1074 packet_write_wait(); 1075 1076 type = packet_read(&payload_len); 1077 switch (type) { 1078 case SSH_SMSG_SUCCESS: 1079 break; 1080 case SSH_SMSG_FAILURE: 1081 break; 1082 default: 1083 break; 1084 } 1085 1086out: 1087 if (creds.client) 1088 krb5_free_principal(context, creds.client); 1089 if (creds.server) 1090 krb5_free_principal(context, creds.server); 1091 if (ccache) 1092 krb5_cc_close(context, ccache); 1093 if (outbuf.data) 1094 xfree(outbuf.data); 1095 1096 return; 1097} 1098#endif /* KRB5 */ 1099 | |
1100/* 1101 * Tries to authenticate with any string-based challenge/response system. 1102 * Note that the client code is not tied to s/key or TIS. 1103 */ 1104int 1105try_skey_authentication() 1106{ | 861/* 862 * Tries to authenticate with any string-based challenge/response system. 863 * Note that the client code is not tied to s/key or TIS. 864 */ 865int 866try_skey_authentication() 867{ |
1107 int type, i, payload_len; | 868 int type, i; 869 int payload_len; 870 unsigned int clen; |
1108 char *challenge, *response; 1109 1110 debug("Doing skey authentication."); 1111 1112 /* request a challenge */ 1113 packet_start(SSH_CMSG_AUTH_TIS); 1114 packet_send(); 1115 packet_write_wait(); 1116 1117 type = packet_read(&payload_len); 1118 if (type != SSH_SMSG_FAILURE && 1119 type != SSH_SMSG_AUTH_TIS_CHALLENGE) { 1120 packet_disconnect("Protocol error: got %d in response " 1121 "to skey-auth", type); 1122 } 1123 if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { 1124 debug("No challenge for skey authentication."); 1125 return 0; 1126 } | 871 char *challenge, *response; 872 873 debug("Doing skey authentication."); 874 875 /* request a challenge */ 876 packet_start(SSH_CMSG_AUTH_TIS); 877 packet_send(); 878 packet_write_wait(); 879 880 type = packet_read(&payload_len); 881 if (type != SSH_SMSG_FAILURE && 882 type != SSH_SMSG_AUTH_TIS_CHALLENGE) { 883 packet_disconnect("Protocol error: got %d in response " 884 "to skey-auth", type); 885 } 886 if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { 887 debug("No challenge for skey authentication."); 888 return 0; 889 } |
1127 challenge = packet_get_string(&payload_len); | 890 challenge = packet_get_string(&clen); 891 packet_integrity_check(payload_len, (4 + clen), type); |
1128 if (options.cipher == SSH_CIPHER_NONE) 1129 log("WARNING: Encryption is disabled! " 1130 "Reponse will be transmitted in clear text."); 1131 fprintf(stderr, "%s\n", challenge); 1132 xfree(challenge); 1133 fflush(stderr); 1134 for (i = 0; i < options.number_of_password_prompts; i++) { 1135 if (i != 0) --- 165 unchanged lines hidden (view full) --- 1301 } 1302} 1303 1304/* 1305 * check whether the supplied host key is valid, return only if ok. 1306 */ 1307 1308void | 892 if (options.cipher == SSH_CIPHER_NONE) 893 log("WARNING: Encryption is disabled! " 894 "Reponse will be transmitted in clear text."); 895 fprintf(stderr, "%s\n", challenge); 896 xfree(challenge); 897 fflush(stderr); 898 for (i = 0; i < options.number_of_password_prompts; i++) { 899 if (i != 0) --- 165 unchanged lines hidden (view full) --- 1065 } 1066} 1067 1068/* 1069 * check whether the supplied host key is valid, return only if ok. 1070 */ 1071 1072void |
1309check_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key) | 1073check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) |
1310{ | 1074{ |
1311 RSA *file_key; | 1075 Key *file_key; |
1312 char *ip = NULL; 1313 char hostline[1000], *hostp; 1314 HostStatus host_status; 1315 HostStatus ip_status; 1316 int local = 0, host_ip_differ = 0; 1317 char ntop[NI_MAXHOST]; 1318 1319 /* --- 33 unchanged lines hidden (view full) --- 1353 fatal("check_host_key: getnameinfo failed"); 1354 ip = xstrdup(ntop); 1355 } 1356 1357 /* 1358 * Store the host key from the known host file in here so that we can 1359 * compare it with the key for the IP address. 1360 */ | 1076 char *ip = NULL; 1077 char hostline[1000], *hostp; 1078 HostStatus host_status; 1079 HostStatus ip_status; 1080 int local = 0, host_ip_differ = 0; 1081 char ntop[NI_MAXHOST]; 1082 1083 /* --- 33 unchanged lines hidden (view full) --- 1117 fatal("check_host_key: getnameinfo failed"); 1118 ip = xstrdup(ntop); 1119 } 1120 1121 /* 1122 * Store the host key from the known host file in here so that we can 1123 * compare it with the key for the IP address. 1124 */ |
1361 file_key = RSA_new(); 1362 file_key->n = BN_new(); 1363 file_key->e = BN_new(); | 1125 file_key = key_new(host_key->type); |
1364 1365 /* 1366 * Check if the host key is present in the user\'s list of known 1367 * hosts or in the systemwide list. 1368 */ | 1126 1127 /* 1128 * Check if the host key is present in the user\'s list of known 1129 * hosts or in the systemwide list. 1130 */ |
1369 host_status = check_host_in_hostfile(options.user_hostfile, host, 1370 host_key->e, host_key->n, 1371 file_key->e, file_key->n); | 1131 host_status = check_host_in_hostfile(options.user_hostfile, host, host_key, file_key); |
1372 if (host_status == HOST_NEW) | 1132 if (host_status == HOST_NEW) |
1373 host_status = check_host_in_hostfile(options.system_hostfile, host, 1374 host_key->e, host_key->n, 1375 file_key->e, file_key->n); | 1133 host_status = check_host_in_hostfile(options.system_hostfile, host, host_key, file_key); |
1376 /* 1377 * Also perform check for the ip address, skip the check if we are 1378 * localhost or the hostname was an ip address to begin with 1379 */ 1380 if (options.check_host_ip && !local && strcmp(host, ip)) { | 1134 /* 1135 * Also perform check for the ip address, skip the check if we are 1136 * localhost or the hostname was an ip address to begin with 1137 */ 1138 if (options.check_host_ip && !local && strcmp(host, ip)) { |
1381 RSA *ip_key = RSA_new(); 1382 ip_key->n = BN_new(); 1383 ip_key->e = BN_new(); 1384 ip_status = check_host_in_hostfile(options.user_hostfile, ip, 1385 host_key->e, host_key->n, 1386 ip_key->e, ip_key->n); | 1139 Key *ip_key = key_new(host_key->type); 1140 ip_status = check_host_in_hostfile(options.user_hostfile, ip, host_key, ip_key); |
1387 1388 if (ip_status == HOST_NEW) | 1141 1142 if (ip_status == HOST_NEW) |
1389 ip_status = check_host_in_hostfile(options.system_hostfile, ip, 1390 host_key->e, host_key->n, 1391 ip_key->e, ip_key->n); | 1143 ip_status = check_host_in_hostfile(options.system_hostfile, ip, host_key, ip_key); |
1392 if (host_status == HOST_CHANGED && | 1144 if (host_status == HOST_CHANGED && |
1393 (ip_status != HOST_CHANGED || 1394 (BN_cmp(ip_key->e, file_key->e) || BN_cmp(ip_key->n, file_key->n)))) | 1145 (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key))) |
1395 host_ip_differ = 1; 1396 | 1146 host_ip_differ = 1; 1147 |
1397 RSA_free(ip_key); | 1148 key_free(ip_key); |
1398 } else 1399 ip_status = host_status; 1400 | 1149 } else 1150 ip_status = host_status; 1151 |
1401 RSA_free(file_key); | 1152 key_free(file_key); |
1402 1403 switch (host_status) { 1404 case HOST_OK: 1405 /* The host is known and the key matches. */ 1406 debug("Host '%.200s' is known and matches the host key.", host); 1407 if (options.check_host_ip) { 1408 if (ip_status == HOST_NEW) { | 1153 1154 switch (host_status) { 1155 case HOST_OK: 1156 /* The host is known and the key matches. */ 1157 debug("Host '%.200s' is known and matches the host key.", host); 1158 if (options.check_host_ip) { 1159 if (ip_status == HOST_NEW) { |
1409 if (!add_host_to_hostfile(options.user_hostfile, ip, 1410 host_key->e, host_key->n)) | 1160 if (!add_host_to_hostfile(options.user_hostfile, ip, host_key)) |
1411 log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).", 1412 ip, options.user_hostfile); 1413 else 1414 log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.", 1415 ip); 1416 } else if (ip_status != HOST_OK) 1417 log("Warning: the host key for '%.200s' differs from the key for the IP address '%.30s'", 1418 host, ip); 1419 } 1420 break; 1421 case HOST_NEW: 1422 /* The host is new. */ 1423 if (options.strict_host_key_checking == 1) { 1424 /* User has requested strict host key checking. We will not add the host key 1425 automatically. The only alternative left is to abort. */ 1426 fatal("No host key is known for %.200s and you have requested strict checking.", host); 1427 } else if (options.strict_host_key_checking == 2) { 1428 /* The default */ 1429 char prompt[1024]; | 1161 log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).", 1162 ip, options.user_hostfile); 1163 else 1164 log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.", 1165 ip); 1166 } else if (ip_status != HOST_OK) 1167 log("Warning: the host key for '%.200s' differs from the key for the IP address '%.30s'", 1168 host, ip); 1169 } 1170 break; 1171 case HOST_NEW: 1172 /* The host is new. */ 1173 if (options.strict_host_key_checking == 1) { 1174 /* User has requested strict host key checking. We will not add the host key 1175 automatically. The only alternative left is to abort. */ 1176 fatal("No host key is known for %.200s and you have requested strict checking.", host); 1177 } else if (options.strict_host_key_checking == 2) { 1178 /* The default */ 1179 char prompt[1024]; |
1430 char *fp = fingerprint(host_key->e, host_key->n); | 1180 char *fp = key_fingerprint(host_key); |
1431 snprintf(prompt, sizeof(prompt), 1432 "The authenticity of host '%.200s' can't be established.\n" | 1181 snprintf(prompt, sizeof(prompt), 1182 "The authenticity of host '%.200s' can't be established.\n" |
1433 "Key fingerprint is %d %s.\n" | 1183 "Key fingerprint is %s.\n" |
1434 "Are you sure you want to continue connecting (yes/no)? ", | 1184 "Are you sure you want to continue connecting (yes/no)? ", |
1435 host, BN_num_bits(host_key->n), fp); | 1185 host, fp); |
1436 if (!read_yes_or_no(prompt, -1)) 1437 fatal("Aborted by user!\n"); 1438 } 1439 if (options.check_host_ip && ip_status == HOST_NEW && strcmp(host, ip)) { 1440 snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); 1441 hostp = hostline; 1442 } else 1443 hostp = host; 1444 1445 /* If not in strict mode, add the key automatically to the local known_hosts file. */ | 1186 if (!read_yes_or_no(prompt, -1)) 1187 fatal("Aborted by user!\n"); 1188 } 1189 if (options.check_host_ip && ip_status == HOST_NEW && strcmp(host, ip)) { 1190 snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); 1191 hostp = hostline; 1192 } else 1193 hostp = host; 1194 1195 /* If not in strict mode, add the key automatically to the local known_hosts file. */ |
1446 if (!add_host_to_hostfile(options.user_hostfile, hostp, 1447 host_key->e, host_key->n)) | 1196 if (!add_host_to_hostfile(options.user_hostfile, hostp, host_key)) |
1448 log("Failed to add the host to the list of known hosts (%.500s).", 1449 options.user_hostfile); 1450 else 1451 log("Warning: Permanently added '%.200s' to the list of known hosts.", 1452 hostp); 1453 break; 1454 case HOST_CHANGED: 1455 if (options.check_host_ip && host_ip_differ) { --- 51 unchanged lines hidden (view full) --- 1507 * by that sentence, and ask the user if he/she whishes to 1508 * accept the authentication. 1509 */ 1510 break; 1511 } 1512 if (options.check_host_ip) 1513 xfree(ip); 1514} | 1197 log("Failed to add the host to the list of known hosts (%.500s).", 1198 options.user_hostfile); 1199 else 1200 log("Warning: Permanently added '%.200s' to the list of known hosts.", 1201 hostp); 1202 break; 1203 case HOST_CHANGED: 1204 if (options.check_host_ip && host_ip_differ) { --- 51 unchanged lines hidden (view full) --- 1256 * by that sentence, and ask the user if he/she whishes to 1257 * accept the authentication. 1258 */ 1259 break; 1260 } 1261 if (options.check_host_ip) 1262 xfree(ip); 1263} |
1264void 1265check_rsa_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key) 1266{ 1267 Key k; 1268 k.type = KEY_RSA; 1269 k.rsa = host_key; 1270 check_host_key(host, hostaddr, &k); 1271} |
|
1515 1516/* 1517 * SSH1 key exchange 1518 */ 1519void 1520ssh_kex(char *host, struct sockaddr *hostaddr) 1521{ 1522 int i; --- 59 unchanged lines hidden (view full) --- 1582 1583 debug("Received server public key (%d bits) and host key (%d bits).", 1584 BN_num_bits(public_key->n), BN_num_bits(host_key->n)); 1585 1586 packet_integrity_check(payload_len, 1587 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, 1588 SSH_SMSG_PUBLIC_KEY); 1589 | 1272 1273/* 1274 * SSH1 key exchange 1275 */ 1276void 1277ssh_kex(char *host, struct sockaddr *hostaddr) 1278{ 1279 int i; --- 59 unchanged lines hidden (view full) --- 1339 1340 debug("Received server public key (%d bits) and host key (%d bits).", 1341 BN_num_bits(public_key->n), BN_num_bits(host_key->n)); 1342 1343 packet_integrity_check(payload_len, 1344 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, 1345 SSH_SMSG_PUBLIC_KEY); 1346 |
1590 check_host_key(host, hostaddr, host_key); | 1347 check_rsa_host_key(host, hostaddr, host_key); |
1591 1592 client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; 1593 1594 compute_session_id(session_id, cookie, host_key->n, public_key->n); 1595 1596 /* Generate a session key. */ 1597 arc4random_stir(); 1598 --- 147 unchanged lines hidden (view full) --- 1746 if (type == SSH_SMSG_SUCCESS) 1747 return; 1748 if (type != SSH_SMSG_FAILURE) 1749 packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", 1750 type); 1751 1752#ifdef AFS 1753 /* Try Kerberos tgt passing if the server supports it. */ | 1348 1349 client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; 1350 1351 compute_session_id(session_id, cookie, host_key->n, public_key->n); 1352 1353 /* Generate a session key. */ 1354 arc4random_stir(); 1355 --- 147 unchanged lines hidden (view full) --- 1503 if (type == SSH_SMSG_SUCCESS) 1504 return; 1505 if (type != SSH_SMSG_FAILURE) 1506 packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", 1507 type); 1508 1509#ifdef AFS 1510 /* Try Kerberos tgt passing if the server supports it. */ |
1754 if ((supported_authentications & (1 << SSH_PASS_KRB4_TGT)) && 1755 options.krb4_tgt_passing) { | 1511 if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) && 1512 options.kerberos_tgt_passing) { |
1756 if (options.cipher == SSH_CIPHER_NONE) 1757 log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); | 1513 if (options.cipher == SSH_CIPHER_NONE) 1514 log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); |
1758 (void) send_krb4_tgt(); | 1515 (void) send_kerberos_tgt(); |
1759 } 1760 /* Try AFS token passing if the server supports it. */ 1761 if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) && 1762 options.afs_token_passing && k_hasafs()) { 1763 if (options.cipher == SSH_CIPHER_NONE) 1764 log("WARNING: Encryption is disabled! Token will be transmitted in the clear!"); 1765 send_afs_tokens(); 1766 } 1767#endif /* AFS */ 1768 1769#ifdef KRB4 | 1516 } 1517 /* Try AFS token passing if the server supports it. */ 1518 if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) && 1519 options.afs_token_passing && k_hasafs()) { 1520 if (options.cipher == SSH_CIPHER_NONE) 1521 log("WARNING: Encryption is disabled! Token will be transmitted in the clear!"); 1522 send_afs_tokens(); 1523 } 1524#endif /* AFS */ 1525 1526#ifdef KRB4 |
1770 if ((supported_authentications & (1 << SSH_AUTH_KRB4)) && 1771 options.krb4_authentication) { | 1527 if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) && 1528 options.kerberos_authentication) { |
1772 debug("Trying Kerberos authentication."); | 1529 debug("Trying Kerberos authentication."); |
1773 if (try_krb4_authentication()) { | 1530 if (try_kerberos_authentication()) { |
1774 /* The server should respond with success or failure. */ 1775 type = packet_read(&payload_len); 1776 if (type == SSH_SMSG_SUCCESS) 1777 return; 1778 if (type != SSH_SMSG_FAILURE) 1779 packet_disconnect("Protocol error: got %d in response to Kerberos auth", type); 1780 } 1781 } 1782#endif /* KRB4 */ 1783 | 1531 /* The server should respond with success or failure. */ 1532 type = packet_read(&payload_len); 1533 if (type == SSH_SMSG_SUCCESS) 1534 return; 1535 if (type != SSH_SMSG_FAILURE) 1536 packet_disconnect("Protocol error: got %d in response to Kerberos auth", type); 1537 } 1538 } 1539#endif /* KRB4 */ 1540 |
1784#ifdef KRB5 1785 if ((supported_authentications & (1 << SSH_AUTH_KRB5)) && 1786 options.krb5_authentication){ 1787 krb5_context ssh_context = NULL; 1788 krb5_auth_context auth_context = NULL; 1789 1790 debug("Trying Kerberos V5 authentication."); 1791 1792 if (try_krb5_authentication(&ssh_context, &auth_context)) { 1793 type = packet_read(&payload_len); 1794 if (type == SSH_SMSG_SUCCESS) { 1795 if ((supported_authentications & (1 << SSH_PASS_KRB5_TGT)) && 1796 options.krb5_tgt_passing) { 1797 if (options.cipher == SSH_CIPHER_NONE) 1798 log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); 1799 send_krb5_tgt(ssh_context, auth_context); 1800 1801 } 1802 krb5_auth_con_free(ssh_context, auth_context); 1803 krb5_free_context(ssh_context); 1804 return; 1805 } 1806 if (type != SSH_SMSG_FAILURE) 1807 packet_disconnect("Protocol error: got %d in response to Kerberos5 auth", type); 1808 1809 } 1810 } 1811#endif /* KRB5 */ 1812 | |
1813 /* 1814 * Use rhosts authentication if running in privileged socket and we 1815 * do not wish to remain anonymous. 1816 */ 1817 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) && 1818 options.rhosts_authentication) { 1819 debug("Trying rhosts authentication."); 1820 packet_start(SSH_CMSG_AUTH_RHOSTS); --- 49 unchanged lines hidden (view full) --- 1870 server_user, host); 1871 if (try_password_authentication(prompt)) 1872 return; 1873 } 1874 /* All authentication methods have failed. Exit with an error message. */ 1875 fatal("Permission denied."); 1876 /* NOTREACHED */ 1877} | 1541 /* 1542 * Use rhosts authentication if running in privileged socket and we 1543 * do not wish to remain anonymous. 1544 */ 1545 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) && 1546 options.rhosts_authentication) { 1547 debug("Trying rhosts authentication."); 1548 packet_start(SSH_CMSG_AUTH_RHOSTS); --- 49 unchanged lines hidden (view full) --- 1598 server_user, host); 1599 if (try_password_authentication(prompt)) 1600 return; 1601 } 1602 /* All authentication methods have failed. Exit with an error message. */ 1603 fatal("Permission denied."); 1604 /* NOTREACHED */ 1605} |
1878 | |
1879/* 1880 * Starts a dialog with the server, and authenticates the current user on the 1881 * server. This does not need any extra privileges. The basic connection 1882 * to the server must already have been established before this is called. 1883 * If login fails, this function prints an error and never returns. 1884 * This function does not require super-user privileges. 1885 */ 1886void --- 14 unchanged lines hidden (view full) --- 1901 /* Put the connection into non-blocking mode. */ 1902 packet_set_nonblocking(); 1903 1904 supported_authentications = 0; 1905 /* key exchange */ 1906 ssh_kex(host, hostaddr); 1907 if (supported_authentications == 0) 1908 fatal("supported_authentications == 0."); | 1606/* 1607 * Starts a dialog with the server, and authenticates the current user on the 1608 * server. This does not need any extra privileges. The basic connection 1609 * to the server must already have been established before this is called. 1610 * If login fails, this function prints an error and never returns. 1611 * This function does not require super-user privileges. 1612 */ 1613void --- 14 unchanged lines hidden (view full) --- 1628 /* Put the connection into non-blocking mode. */ 1629 packet_set_nonblocking(); 1630 1631 supported_authentications = 0; 1632 /* key exchange */ 1633 ssh_kex(host, hostaddr); 1634 if (supported_authentications == 0) 1635 fatal("supported_authentications == 0."); |
1636 |
|
1909 /* authenticate user */ 1910 ssh_userauth(host_key_valid, own_host_key, original_real_uid, host); 1911} | 1637 /* authenticate user */ 1638 ssh_userauth(host_key_valid, own_host_key, original_real_uid, host); 1639} |