diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 83 |
1 files changed, 40 insertions, 43 deletions
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$Id: sshd.c,v 1.51 2000/01/19 03:36:50 damien Exp $"); | 14 | RCSID("$OpenBSD: sshd.c,v 1.79 2000/01/18 13:45:05 markus Exp $"); |
15 | 15 | ||
16 | #include "xmalloc.h" | 16 | #include "xmalloc.h" |
17 | #include "rsa.h" | 17 | #include "rsa.h" |
@@ -131,8 +131,8 @@ int received_sighup = 0; | |||
131 | RSA *public_key; | 131 | RSA *public_key; |
132 | 132 | ||
133 | /* Prototypes for various functions defined later in this file. */ | 133 | /* Prototypes for various functions defined later in this file. */ |
134 | void do_connection(); | 134 | void do_ssh_kex(); |
135 | void do_authentication(char *user); | 135 | void do_authentication(); |
136 | void do_authloop(struct passwd * pw); | 136 | void do_authloop(struct passwd * pw); |
137 | void do_fake_authloop(char *user); | 137 | void do_fake_authloop(char *user); |
138 | void do_authenticated(struct passwd * pw); | 138 | void do_authenticated(struct passwd * pw); |
@@ -835,11 +835,8 @@ main(int ac, char **av) | |||
835 | packet_disconnect("Your ssh version is too old and is no longer supported. Please install a newer version."); | 835 | packet_disconnect("Your ssh version is too old and is no longer supported. Please install a newer version."); |
836 | 836 | ||
837 | if (remote_major == 1 && remote_minor == 3) { | 837 | if (remote_major == 1 && remote_minor == 3) { |
838 | /* note that this disables agent-forwarding */ | ||
838 | enable_compat13(); | 839 | enable_compat13(); |
839 | if (strcmp(remote_version, "OpenSSH-1.1") != 0) { | ||
840 | debug("Agent forwarding disabled, remote version is not compatible."); | ||
841 | no_agent_forwarding_flag = 1; | ||
842 | } | ||
843 | } | 840 | } |
844 | /* | 841 | /* |
845 | * Check that the connection comes from a privileged port. Rhosts- | 842 | * Check that the connection comes from a privileged port. Rhosts- |
@@ -863,8 +860,11 @@ main(int ac, char **av) | |||
863 | 860 | ||
864 | packet_set_nonblocking(); | 861 | packet_set_nonblocking(); |
865 | 862 | ||
866 | /* Handle the connection. */ | 863 | /* perform the key exchange */ |
867 | do_connection(); | 864 | do_ssh_kex(); |
865 | |||
866 | /* authenticate user and start session */ | ||
867 | do_authentication(); | ||
868 | 868 | ||
869 | #ifdef KRB4 | 869 | #ifdef KRB4 |
870 | /* Cleanup user's ticket cache file. */ | 870 | /* Cleanup user's ticket cache file. */ |
@@ -888,20 +888,17 @@ main(int ac, char **av) | |||
888 | } | 888 | } |
889 | 889 | ||
890 | /* | 890 | /* |
891 | * Process an incoming connection. Protocol version identifiers have already | 891 | * SSH1 key exchange |
892 | * been exchanged. This sends server key and performs the key exchange. | ||
893 | * Server and host keys will no longer be needed after this functions. | ||
894 | */ | 892 | */ |
895 | void | 893 | void |
896 | do_connection() | 894 | do_ssh_kex() |
897 | { | 895 | { |
898 | int i, len; | 896 | int i, len; |
897 | int plen, slen; | ||
899 | BIGNUM *session_key_int; | 898 | BIGNUM *session_key_int; |
900 | unsigned char session_key[SSH_SESSION_KEY_LENGTH]; | 899 | unsigned char session_key[SSH_SESSION_KEY_LENGTH]; |
901 | unsigned char check_bytes[8]; | 900 | unsigned char cookie[8]; |
902 | char *user; | ||
903 | unsigned int cipher_type, auth_mask, protocol_flags; | 901 | unsigned int cipher_type, auth_mask, protocol_flags; |
904 | int plen, slen, ulen; | ||
905 | u_int32_t rand = 0; | 902 | u_int32_t rand = 0; |
906 | 903 | ||
907 | /* | 904 | /* |
@@ -916,7 +913,7 @@ do_connection() | |||
916 | for (i = 0; i < 8; i++) { | 913 | for (i = 0; i < 8; i++) { |
917 | if (i % 4 == 0) | 914 | if (i % 4 == 0) |
918 | rand = arc4random(); | 915 | rand = arc4random(); |
919 | check_bytes[i] = rand & 0xff; | 916 | cookie[i] = rand & 0xff; |
920 | rand >>= 8; | 917 | rand >>= 8; |
921 | } | 918 | } |
922 | 919 | ||
@@ -927,7 +924,7 @@ do_connection() | |||
927 | */ | 924 | */ |
928 | packet_start(SSH_SMSG_PUBLIC_KEY); | 925 | packet_start(SSH_SMSG_PUBLIC_KEY); |
929 | for (i = 0; i < 8; i++) | 926 | for (i = 0; i < 8; i++) |
930 | packet_put_char(check_bytes[i]); | 927 | packet_put_char(cookie[i]); |
931 | 928 | ||
932 | /* Store our public server RSA key. */ | 929 | /* Store our public server RSA key. */ |
933 | packet_put_int(BN_num_bits(public_key->n)); | 930 | packet_put_int(BN_num_bits(public_key->n)); |
@@ -990,7 +987,7 @@ do_connection() | |||
990 | /* Get check bytes from the packet. These must match those we | 987 | /* Get check bytes from the packet. These must match those we |
991 | sent earlier with the public key packet. */ | 988 | sent earlier with the public key packet. */ |
992 | for (i = 0; i < 8; i++) | 989 | for (i = 0; i < 8; i++) |
993 | if (check_bytes[i] != packet_get_char()) | 990 | if (cookie[i] != packet_get_char()) |
994 | packet_disconnect("IP Spoofing check bytes do not match."); | 991 | packet_disconnect("IP Spoofing check bytes do not match."); |
995 | 992 | ||
996 | debug("Encryption type: %.200s", cipher_name(cipher_type)); | 993 | debug("Encryption type: %.200s", cipher_name(cipher_type)); |
@@ -1038,10 +1035,15 @@ do_connection() | |||
1038 | sensitive_data.private_key); | 1035 | sensitive_data.private_key); |
1039 | } | 1036 | } |
1040 | 1037 | ||
1041 | compute_session_id(session_id, check_bytes, | 1038 | compute_session_id(session_id, cookie, |
1042 | sensitive_data.host_key->n, | 1039 | sensitive_data.host_key->n, |
1043 | sensitive_data.private_key->n); | 1040 | sensitive_data.private_key->n); |
1044 | 1041 | ||
1042 | /* Destroy the private and public keys. They will no longer be needed. */ | ||
1043 | RSA_free(public_key); | ||
1044 | RSA_free(sensitive_data.private_key); | ||
1045 | RSA_free(sensitive_data.host_key); | ||
1046 | |||
1045 | /* | 1047 | /* |
1046 | * Extract session key from the decrypted integer. The key is in the | 1048 | * Extract session key from the decrypted integer. The key is in the |
1047 | * least significant 256 bits of the integer; the first byte of the | 1049 | * least significant 256 bits of the integer; the first byte of the |
@@ -1056,13 +1058,13 @@ do_connection() | |||
1056 | memset(session_key, 0, sizeof(session_key)); | 1058 | memset(session_key, 0, sizeof(session_key)); |
1057 | BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len); | 1059 | BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len); |
1058 | 1060 | ||
1061 | /* Destroy the decrypted integer. It is no longer needed. */ | ||
1062 | BN_clear_free(session_key_int); | ||
1063 | |||
1059 | /* Xor the first 16 bytes of the session key with the session id. */ | 1064 | /* Xor the first 16 bytes of the session key with the session id. */ |
1060 | for (i = 0; i < 16; i++) | 1065 | for (i = 0; i < 16; i++) |
1061 | session_key[i] ^= session_id[i]; | 1066 | session_key[i] ^= session_id[i]; |
1062 | 1067 | ||
1063 | /* Destroy the decrypted integer. It is no longer needed. */ | ||
1064 | BN_clear_free(session_key_int); | ||
1065 | |||
1066 | /* Set the session key. From this on all communications will be encrypted. */ | 1068 | /* Set the session key. From this on all communications will be encrypted. */ |
1067 | packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); | 1069 | packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); |
1068 | 1070 | ||
@@ -1075,24 +1077,9 @@ do_connection() | |||
1075 | packet_start(SSH_SMSG_SUCCESS); | 1077 | packet_start(SSH_SMSG_SUCCESS); |
1076 | packet_send(); | 1078 | packet_send(); |
1077 | packet_write_wait(); | 1079 | packet_write_wait(); |
1078 | |||
1079 | /* Get the name of the user that we wish to log in as. */ | ||
1080 | packet_read_expect(&plen, SSH_CMSG_USER); | ||
1081 | |||
1082 | /* Get the user name. */ | ||
1083 | user = packet_get_string(&ulen); | ||
1084 | packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER); | ||
1085 | |||
1086 | /* Destroy the private and public keys. They will no longer be needed. */ | ||
1087 | RSA_free(public_key); | ||
1088 | RSA_free(sensitive_data.private_key); | ||
1089 | RSA_free(sensitive_data.host_key); | ||
1090 | |||
1091 | setproctitle("%s", user); | ||
1092 | /* Do the authentication. */ | ||
1093 | do_authentication(user); | ||
1094 | } | 1080 | } |
1095 | 1081 | ||
1082 | |||
1096 | /* | 1083 | /* |
1097 | * Check if the user is allowed to log in via ssh. If user is listed in | 1084 | * Check if the user is allowed to log in via ssh. If user is listed in |
1098 | * DenyUsers or user's primary group is listed in DenyGroups, false will | 1085 | * DenyUsers or user's primary group is listed in DenyGroups, false will |
@@ -1168,13 +1155,23 @@ allowed_user(struct passwd * pw) | |||
1168 | 1155 | ||
1169 | /* | 1156 | /* |
1170 | * Performs authentication of an incoming connection. Session key has already | 1157 | * Performs authentication of an incoming connection. Session key has already |
1171 | * been exchanged and encryption is enabled. User is the user name to log | 1158 | * been exchanged and encryption is enabled. |
1172 | * in as (received from the client). | ||
1173 | */ | 1159 | */ |
1174 | void | 1160 | void |
1175 | do_authentication(char *user) | 1161 | do_authentication() |
1176 | { | 1162 | { |
1177 | struct passwd *pw, pwcopy; | 1163 | struct passwd *pw, pwcopy; |
1164 | int plen, ulen; | ||
1165 | char *user; | ||
1166 | |||
1167 | /* Get the name of the user that we wish to log in as. */ | ||
1168 | packet_read_expect(&plen, SSH_CMSG_USER); | ||
1169 | |||
1170 | /* Get the user name. */ | ||
1171 | user = packet_get_string(&ulen); | ||
1172 | packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER); | ||
1173 | |||
1174 | setproctitle("%s", user); | ||
1178 | 1175 | ||
1179 | #ifdef AFS | 1176 | #ifdef AFS |
1180 | /* If machine has AFS, set process authentication group. */ | 1177 | /* If machine has AFS, set process authentication group. */ |
@@ -1771,7 +1768,7 @@ do_authenticated(struct passwd * pw) | |||
1771 | #endif /* XAUTH_PATH */ | 1768 | #endif /* XAUTH_PATH */ |
1772 | 1769 | ||
1773 | case SSH_CMSG_AGENT_REQUEST_FORWARDING: | 1770 | case SSH_CMSG_AGENT_REQUEST_FORWARDING: |
1774 | if (no_agent_forwarding_flag) { | 1771 | if (no_agent_forwarding_flag || compat13) { |
1775 | debug("Authentication agent forwarding not permitted for this authentication."); | 1772 | debug("Authentication agent forwarding not permitted for this authentication."); |
1776 | goto fail; | 1773 | goto fail; |
1777 | } | 1774 | } |