diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | auth-rsa.c | 17 | ||||
-rw-r--r-- | ssh.1.in | 61 | ||||
-rw-r--r-- | sshconnect.c | 128 | ||||
-rw-r--r-- | sshd.8.in | 14 | ||||
-rw-r--r-- | sshd.c | 83 |
6 files changed, 182 insertions, 132 deletions
@@ -1,5 +1,16 @@ | |||
1 | 20000120 | 1 | 20000120 |
2 | - Don't use getaddrinfo on AIX | 2 | - Don't use getaddrinfo on AIX |
3 | - Update to latest OpenBSD CVS: | ||
4 | - [auth-rsa.c] | ||
5 | - fix user/1056, sshd keeps restrictions; dbt@meat.net | ||
6 | - [sshconnect.c] | ||
7 | - disable agent fwding for proto 1.3, remove abuse of auth-rsa flags. | ||
8 | - destroy keys earlier | ||
9 | - split key exchange (kex) and user authentication (user-auth), ok: provos@ | ||
10 | - [sshd.c] | ||
11 | - no need for poll.h; from bright@wintelcom.net | ||
12 | - disable agent fwding for proto 1.3, remove abuse of auth-rsa flags. | ||
13 | - split key exchange (kex) and user authentication (user-auth), ok: provos@ | ||
3 | 14 | ||
4 | 20000119 | 15 | 20000119 |
5 | - SCO compile fixes from Gary E. Miller <gem@rellim.com> | 16 | - SCO compile fixes from Gary E. Miller <gem@rellim.com> |
diff --git a/auth-rsa.c b/auth-rsa.c index bc53b049b..9d9e74928 100644 --- a/auth-rsa.c +++ b/auth-rsa.c | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include "includes.h" | 18 | #include "includes.h" |
19 | RCSID("$Id: auth-rsa.c,v 1.11 1999/12/06 00:47:28 damien Exp $"); | 19 | RCSID("$Id: auth-rsa.c,v 1.12 2000/01/20 11:44:09 damien Exp $"); |
20 | 20 | ||
21 | #include "rsa.h" | 21 | #include "rsa.h" |
22 | #include "packet.h" | 22 | #include "packet.h" |
@@ -415,7 +415,22 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) | |||
415 | packet_send_debug("Your host '%.200s' is not permitted to use this key for login.", | 415 | packet_send_debug("Your host '%.200s' is not permitted to use this key for login.", |
416 | get_canonical_hostname()); | 416 | get_canonical_hostname()); |
417 | xfree(patterns); | 417 | xfree(patterns); |
418 | /* key invalid for this host, reset flags */ | ||
418 | authenticated = 0; | 419 | authenticated = 0; |
420 | no_agent_forwarding_flag = 0; | ||
421 | no_port_forwarding_flag = 0; | ||
422 | no_pty_flag = 0; | ||
423 | no_x11_forwarding_flag = 0; | ||
424 | while (custom_environment) { | ||
425 | struct envstring *ce = custom_environment; | ||
426 | custom_environment = ce->next; | ||
427 | xfree(ce->s); | ||
428 | xfree(ce); | ||
429 | } | ||
430 | if (forced_command) { | ||
431 | xfree(forced_command); | ||
432 | forced_command = NULL; | ||
433 | } | ||
419 | break; | 434 | break; |
420 | } | 435 | } |
421 | xfree(patterns); | 436 | xfree(patterns); |
@@ -9,7 +9,7 @@ | |||
9 | .\" | 9 | .\" |
10 | .\" Created: Sat Apr 22 21:55:14 1995 ylo | 10 | .\" Created: Sat Apr 22 21:55:14 1995 ylo |
11 | .\" | 11 | .\" |
12 | .\" $Id: ssh.1.in,v 1.2 2000/01/14 04:45:51 damien Exp $ | 12 | .\" $Id: ssh.1.in,v 1.3 2000/01/20 11:44:09 damien Exp $ |
13 | .\" | 13 | .\" |
14 | .Dd September 25, 1999 | 14 | .Dd September 25, 1999 |
15 | .Dt SSH 1 | 15 | .Dt SSH 1 |
@@ -33,16 +33,16 @@ | |||
33 | .Op Fl p Ar port | 33 | .Op Fl p Ar port |
34 | .Oo Fl L Xo | 34 | .Oo Fl L Xo |
35 | .Sm off | 35 | .Sm off |
36 | .Ar host : | ||
37 | .Ar port : | 36 | .Ar port : |
37 | .Ar host : | ||
38 | .Ar hostport | 38 | .Ar hostport |
39 | .Sm on | 39 | .Sm on |
40 | .Xc | 40 | .Xc |
41 | .Oc | 41 | .Oc |
42 | .Oo Fl R Xo | 42 | .Oo Fl R Xo |
43 | .Sm off | 43 | .Sm off |
44 | .Ar host : | ||
45 | .Ar port : | 44 | .Ar port : |
45 | .Ar host : | ||
46 | .Ar hostport | 46 | .Ar hostport |
47 | .Sm on | 47 | .Sm on |
48 | .Xc | 48 | .Xc |
@@ -302,6 +302,8 @@ wants it in the background. This implies | |||
302 | The recommended way to start X11 programs at a remote site is with | 302 | The recommended way to start X11 programs at a remote site is with |
303 | something like | 303 | something like |
304 | .Ic ssh -f host xterm . | 304 | .Ic ssh -f host xterm . |
305 | .It Fl g | ||
306 | Allows remote hosts to connect to local forwarded ports. | ||
305 | .It Fl i Ar identity_file | 307 | .It Fl i Ar identity_file |
306 | Selects the file from which the identity (private key) for | 308 | Selects the file from which the identity (private key) for |
307 | RSA authentication is read. Default is | 309 | RSA authentication is read. Default is |
@@ -312,8 +314,6 @@ multiple | |||
312 | .Fl i | 314 | .Fl i |
313 | options (and multiple identities specified in | 315 | options (and multiple identities specified in |
314 | configuration files). | 316 | configuration files). |
315 | .It Fl g | ||
316 | Allows remote hosts to connect to local forwarded ports. | ||
317 | .It Fl k | 317 | .It Fl k |
318 | Disables forwarding of Kerberos tickets and AFS tokens. This may | 318 | Disables forwarding of Kerberos tickets and AFS tokens. This may |
319 | also be specified on a per-host basis in the configuration file. | 319 | also be specified on a per-host basis in the configuration file. |
@@ -378,7 +378,9 @@ Enables X11 forwarding. | |||
378 | .It Fl C | 378 | .It Fl C |
379 | Requests compression of all data (including stdin, stdout, stderr, and | 379 | Requests compression of all data (including stdin, stdout, stderr, and |
380 | data for forwarded X11 and TCP/IP connections). The compression | 380 | data for forwarded X11 and TCP/IP connections). The compression |
381 | algorithm is the same used by gzip, and the | 381 | algorithm is the same used by |
382 | .Xr gzip 1 , | ||
383 | and the | ||
382 | .Dq level | 384 | .Dq level |
383 | can be controlled by the | 385 | can be controlled by the |
384 | .Cm CompressionLevel | 386 | .Cm CompressionLevel |
@@ -486,6 +488,15 @@ user to supply the password. The argument must be | |||
486 | .Dq yes | 488 | .Dq yes |
487 | or | 489 | or |
488 | .Dq no . | 490 | .Dq no . |
491 | .It Cm CheckHostIP | ||
492 | If this flag is set to | ||
493 | .Dq yes , | ||
494 | ssh will additionally check the host ip address in the | ||
495 | .Pa known_hosts | ||
496 | file. This allows ssh to detect if a host key changed due to DNS spoofing. | ||
497 | If the option is set to | ||
498 | .Dq no , | ||
499 | the check will not be executed. | ||
489 | .It Cm Cipher | 500 | .It Cm Cipher |
490 | Specifies the cipher to use for encrypting the session. Currently, | 501 | Specifies the cipher to use for encrypting the session. Currently, |
491 | .Dq blowfish , | 502 | .Dq blowfish , |
@@ -502,7 +513,8 @@ or | |||
502 | Specifies the compression level to use if compression is enable. The | 513 | Specifies the compression level to use if compression is enable. The |
503 | argument must be an integer from 1 (fast) to 9 (slow, best). The | 514 | argument must be an integer from 1 (fast) to 9 (slow, best). The |
504 | default level is 6, which is good for most applications. The meaning | 515 | default level is 6, which is good for most applications. The meaning |
505 | of the values is the same as in GNU GZIP. | 516 | of the values is the same as in |
517 | .Xr gzip 1 . | ||
506 | .It Cm ConnectionAttempts | 518 | .It Cm ConnectionAttempts |
507 | Specifies the number of tries (one per second) to make before falling | 519 | Specifies the number of tries (one per second) to make before falling |
508 | back to rsh or exiting. The argument must be an integer. This may be | 520 | back to rsh or exiting. The argument must be an integer. This may be |
@@ -610,12 +622,6 @@ first argument must be a port number, and the second must be | |||
610 | host:port. Multiple forwardings may be specified, and additional | 622 | host:port. Multiple forwardings may be specified, and additional |
611 | forwardings can be given on the command line. Only the root can | 623 | forwardings can be given on the command line. Only the root can |
612 | forward privileged ports. | 624 | forward privileged ports. |
613 | .It Cm PasswordAuthentication | ||
614 | Specifies whether to use password authentication. The argument to | ||
615 | this keyword must be | ||
616 | .Dq yes | ||
617 | or | ||
618 | .Dq no . | ||
619 | .It Cm LogLevel | 625 | .It Cm LogLevel |
620 | Gives the verbosity level that is used when logging messages from | 626 | Gives the verbosity level that is used when logging messages from |
621 | .Nm ssh . | 627 | .Nm ssh . |
@@ -625,6 +631,12 @@ The default is INFO. | |||
625 | .It Cm NumberOfPasswordPrompts | 631 | .It Cm NumberOfPasswordPrompts |
626 | Specifies the number of password prompts before giving up. The | 632 | Specifies the number of password prompts before giving up. The |
627 | argument to this keyword must be an integer. Default is 3. | 633 | argument to this keyword must be an integer. Default is 3. |
634 | .It Cm PasswordAuthentication | ||
635 | Specifies whether to use password authentication. The argument to | ||
636 | this keyword must be | ||
637 | .Dq yes | ||
638 | or | ||
639 | .Dq no . | ||
628 | .It Cm Port | 640 | .It Cm Port |
629 | Specifies the port number to connect on the remote host. Default is | 641 | Specifies the port number to connect on the remote host. Default is |
630 | 22. | 642 | 22. |
@@ -689,15 +701,6 @@ or | |||
689 | .Dq no . | 701 | .Dq no . |
690 | The default is | 702 | The default is |
691 | .Dq no . | 703 | .Dq no . |
692 | .It Cm CheckHostIP | ||
693 | If this flag is set to | ||
694 | .Dq yes , | ||
695 | ssh will additionally check the host ip address in the | ||
696 | .Pa known_hosts | ||
697 | file. This allows ssh to detect if a host key changed due to DNS spoofing. | ||
698 | If the option is set to | ||
699 | .Dq no , | ||
700 | the check will not be executed. | ||
701 | .It Cm StrictHostKeyChecking | 704 | .It Cm StrictHostKeyChecking |
702 | If this flag is set to | 705 | If this flag is set to |
703 | .Dq yes , | 706 | .Dq yes , |
@@ -717,13 +720,6 @@ argument must be | |||
717 | .Dq yes | 720 | .Dq yes |
718 | or | 721 | or |
719 | .Dq no . | 722 | .Dq no . |
720 | .It Cm User | ||
721 | Specifies the user to log in as. This can be useful if you have a | ||
722 | different user name in different machines. This saves the trouble of | ||
723 | having to remember to give the user name on the command line. | ||
724 | .It Cm UserKnownHostsFile | ||
725 | Specifies a file to use instead of | ||
726 | .Pa $HOME/.ssh/known_hosts . | ||
727 | .It Cm UsePrivilegedPort | 723 | .It Cm UsePrivilegedPort |
728 | Specifies whether to use a privileged port for outgoing connections. | 724 | Specifies whether to use a privileged port for outgoing connections. |
729 | The argument must be | 725 | The argument must be |
@@ -738,6 +734,13 @@ turns off | |||
738 | .Cm RhostsAuthentication | 734 | .Cm RhostsAuthentication |
739 | and | 735 | and |
740 | .Cm RhostsRSAAuthentication . | 736 | .Cm RhostsRSAAuthentication . |
737 | .It Cm User | ||
738 | Specifies the user to log in as. This can be useful if you have a | ||
739 | different user name in different machines. This saves the trouble of | ||
740 | having to remember to give the user name on the command line. | ||
741 | .It Cm UserKnownHostsFile | ||
742 | Specifies a file to use instead of | ||
743 | .Pa $HOME/.ssh/known_hosts . | ||
741 | .It Cm UseRsh | 744 | .It Cm UseRsh |
742 | Specifies that rlogin/rsh should be used for this host. It is | 745 | Specifies that rlogin/rsh should be used for this host. It is |
743 | possible that the host does not at all support the | 746 | possible that the host does not at all support the |
diff --git a/sshconnect.c b/sshconnect.c index 068c23072..5e2a34497 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -8,7 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include "includes.h" | 10 | #include "includes.h" |
11 | RCSID("$Id: sshconnect.c,v 1.22 2000/01/19 02:45:07 damien Exp $"); | 11 | RCSID("$OpenBSD: sshconnect.c,v 1.53 2000/01/18 09:42:17 markus Exp $"); |
12 | 12 | ||
13 | #ifdef HAVE_OPENSSL | 13 | #ifdef HAVE_OPENSSL |
14 | #include <openssl/bn.h> | 14 | #include <openssl/bn.h> |
@@ -34,6 +34,9 @@ RCSID("$Id: sshconnect.c,v 1.22 2000/01/19 02:45:07 damien Exp $"); | |||
34 | /* Session id for the current session. */ | 34 | /* Session id for the current session. */ |
35 | unsigned char session_id[16]; | 35 | unsigned char session_id[16]; |
36 | 36 | ||
37 | /* authentications supported by server */ | ||
38 | unsigned int supported_authentications; | ||
39 | |||
37 | extern Options options; | 40 | extern Options options; |
38 | extern char *__progname; | 41 | extern char *__progname; |
39 | 42 | ||
@@ -988,9 +991,8 @@ ssh_exchange_identification() | |||
988 | /* We speak 1.3, too. */ | 991 | /* We speak 1.3, too. */ |
989 | if (remote_major == 1 && remote_minor == 3) { | 992 | if (remote_major == 1 && remote_minor == 3) { |
990 | enable_compat13(); | 993 | enable_compat13(); |
991 | if (options.forward_agent && strcmp(remote_version, "OpenSSH-1.1") != 0) { | 994 | if (options.forward_agent) { |
992 | log("Agent forwarding disabled, remote version '%s' is not compatible.", | 995 | log("Agent forwarding disabled for protocol 1.3"); |
993 | remote_version); | ||
994 | options.forward_agent = 0; | 996 | options.forward_agent = 0; |
995 | } | 997 | } |
996 | } | 998 | } |
@@ -1274,63 +1276,31 @@ check_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key) | |||
1274 | } | 1276 | } |
1275 | 1277 | ||
1276 | /* | 1278 | /* |
1277 | * Starts a dialog with the server, and authenticates the current user on the | 1279 | * SSH1 key exchange |
1278 | * server. This does not need any extra privileges. The basic connection | ||
1279 | * to the server must already have been established before this is called. | ||
1280 | * User is the remote user; if it is NULL, the current local user name will | ||
1281 | * be used. Anonymous indicates that no rhosts authentication will be used. | ||
1282 | * If login fails, this function prints an error and never returns. | ||
1283 | * This function does not require super-user privileges. | ||
1284 | */ | 1280 | */ |
1285 | void | 1281 | void |
1286 | ssh_login(int host_key_valid, | 1282 | ssh_kex(char *host, struct sockaddr *hostaddr) |
1287 | RSA *own_host_key, | ||
1288 | const char *orighost, | ||
1289 | struct sockaddr *hostaddr, | ||
1290 | uid_t original_real_uid) | ||
1291 | { | 1283 | { |
1292 | int i, type; | 1284 | int i; |
1293 | struct passwd *pw; | ||
1294 | BIGNUM *key; | 1285 | BIGNUM *key; |
1295 | RSA *host_key; | 1286 | RSA *host_key; |
1296 | RSA *public_key; | 1287 | RSA *public_key; |
1297 | int bits, rbits; | 1288 | int bits, rbits; |
1298 | unsigned char session_key[SSH_SESSION_KEY_LENGTH]; | 1289 | unsigned char session_key[SSH_SESSION_KEY_LENGTH]; |
1299 | const char *server_user, *local_user; | 1290 | unsigned char cookie[8]; |
1300 | char *host, *cp; | 1291 | unsigned int supported_ciphers; |
1301 | unsigned char check_bytes[8]; | ||
1302 | unsigned int supported_ciphers, supported_authentications; | ||
1303 | unsigned int server_flags, client_flags; | 1292 | unsigned int server_flags, client_flags; |
1304 | int payload_len, clen, sum_len = 0; | 1293 | int payload_len, clen, sum_len = 0; |
1305 | u_int32_t rand = 0; | 1294 | u_int32_t rand = 0; |
1306 | 1295 | ||
1307 | /* Convert the user-supplied hostname into all lowercase. */ | ||
1308 | host = xstrdup(orighost); | ||
1309 | for (cp = host; *cp; cp++) | ||
1310 | if (isupper(*cp)) | ||
1311 | *cp = tolower(*cp); | ||
1312 | |||
1313 | /* Exchange protocol version identification strings with the server. */ | ||
1314 | ssh_exchange_identification(); | ||
1315 | |||
1316 | /* Put the connection into non-blocking mode. */ | ||
1317 | packet_set_nonblocking(); | ||
1318 | |||
1319 | /* Get local user name. Use it as server user if no user name was given. */ | ||
1320 | pw = getpwuid(original_real_uid); | ||
1321 | if (!pw) | ||
1322 | fatal("User id %d not found from user database.", original_real_uid); | ||
1323 | local_user = xstrdup(pw->pw_name); | ||
1324 | server_user = options.user ? options.user : local_user; | ||
1325 | |||
1326 | debug("Waiting for server public key."); | 1296 | debug("Waiting for server public key."); |
1327 | 1297 | ||
1328 | /* Wait for a public key packet from the server. */ | 1298 | /* Wait for a public key packet from the server. */ |
1329 | packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); | 1299 | packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); |
1330 | 1300 | ||
1331 | /* Get check bytes from the packet. */ | 1301 | /* Get cookie from the packet. */ |
1332 | for (i = 0; i < 8; i++) | 1302 | for (i = 0; i < 8; i++) |
1333 | check_bytes[i] = packet_get_char(); | 1303 | cookie[i] = packet_get_char(); |
1334 | 1304 | ||
1335 | /* Get the public key. */ | 1305 | /* Get the public key. */ |
1336 | public_key = RSA_new(); | 1306 | public_key = RSA_new(); |
@@ -1383,7 +1353,7 @@ ssh_login(int host_key_valid, | |||
1383 | 1353 | ||
1384 | client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; | 1354 | client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; |
1385 | 1355 | ||
1386 | compute_session_id(session_id, check_bytes, host_key->n, public_key->n); | 1356 | compute_session_id(session_id, cookie, host_key->n, public_key->n); |
1387 | 1357 | ||
1388 | /* Generate a session key. */ | 1358 | /* Generate a session key. */ |
1389 | arc4random_stir(); | 1359 | arc4random_stir(); |
@@ -1445,6 +1415,10 @@ ssh_login(int host_key_valid, | |||
1445 | rsa_public_encrypt(key, key, public_key); | 1415 | rsa_public_encrypt(key, key, public_key); |
1446 | } | 1416 | } |
1447 | 1417 | ||
1418 | /* Destroy the public keys since we no longer need them. */ | ||
1419 | RSA_free(public_key); | ||
1420 | RSA_free(host_key); | ||
1421 | |||
1448 | if (options.cipher == SSH_CIPHER_NOT_SET) { | 1422 | if (options.cipher == SSH_CIPHER_NOT_SET) { |
1449 | if (cipher_mask() & supported_ciphers & (1 << ssh_cipher_default)) | 1423 | if (cipher_mask() & supported_ciphers & (1 << ssh_cipher_default)) |
1450 | options.cipher = ssh_cipher_default; | 1424 | options.cipher = ssh_cipher_default; |
@@ -1466,12 +1440,13 @@ ssh_login(int host_key_valid, | |||
1466 | packet_start(SSH_CMSG_SESSION_KEY); | 1440 | packet_start(SSH_CMSG_SESSION_KEY); |
1467 | packet_put_char(options.cipher); | 1441 | packet_put_char(options.cipher); |
1468 | 1442 | ||
1469 | /* Send the check bytes back to the server. */ | 1443 | /* Send the cookie back to the server. */ |
1470 | for (i = 0; i < 8; i++) | 1444 | for (i = 0; i < 8; i++) |
1471 | packet_put_char(check_bytes[i]); | 1445 | packet_put_char(cookie[i]); |
1472 | 1446 | ||
1473 | /* Send the encrypted encryption key. */ | 1447 | /* Send and destroy the encrypted encryption key integer. */ |
1474 | packet_put_bignum(key); | 1448 | packet_put_bignum(key); |
1449 | BN_clear_free(key); | ||
1475 | 1450 | ||
1476 | /* Send protocol flags. */ | 1451 | /* Send protocol flags. */ |
1477 | packet_put_int(client_flags); | 1452 | packet_put_int(client_flags); |
@@ -1480,11 +1455,6 @@ ssh_login(int host_key_valid, | |||
1480 | packet_send(); | 1455 | packet_send(); |
1481 | packet_write_wait(); | 1456 | packet_write_wait(); |
1482 | 1457 | ||
1483 | /* Destroy the session key integer and the public keys since we no longer need them. */ | ||
1484 | BN_clear_free(key); | ||
1485 | RSA_free(public_key); | ||
1486 | RSA_free(host_key); | ||
1487 | |||
1488 | debug("Sent encrypted session key."); | 1458 | debug("Sent encrypted session key."); |
1489 | 1459 | ||
1490 | /* Set the encryption key. */ | 1460 | /* Set the encryption key. */ |
@@ -1500,6 +1470,26 @@ ssh_login(int host_key_valid, | |||
1500 | packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); | 1470 | packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); |
1501 | 1471 | ||
1502 | debug("Received encrypted confirmation."); | 1472 | debug("Received encrypted confirmation."); |
1473 | } | ||
1474 | |||
1475 | /* | ||
1476 | * Authenticate user | ||
1477 | */ | ||
1478 | void | ||
1479 | ssh_userauth(int host_key_valid, RSA *own_host_key, | ||
1480 | uid_t original_real_uid, char *host) | ||
1481 | { | ||
1482 | int i, type; | ||
1483 | int payload_len; | ||
1484 | struct passwd *pw; | ||
1485 | const char *server_user, *local_user; | ||
1486 | |||
1487 | /* Get local user name. Use it as server user if no user name was given. */ | ||
1488 | pw = getpwuid(original_real_uid); | ||
1489 | if (!pw) | ||
1490 | fatal("User id %d not found from user database.", original_real_uid); | ||
1491 | local_user = xstrdup(pw->pw_name); | ||
1492 | server_user = options.user ? options.user : local_user; | ||
1503 | 1493 | ||
1504 | /* Send the name of the user to log in as on the server. */ | 1494 | /* Send the name of the user to log in as on the server. */ |
1505 | packet_start(SSH_CMSG_USER); | 1495 | packet_start(SSH_CMSG_USER); |
@@ -1618,3 +1608,37 @@ ssh_login(int host_key_valid, | |||
1618 | fatal("Permission denied."); | 1608 | fatal("Permission denied."); |
1619 | /* NOTREACHED */ | 1609 | /* NOTREACHED */ |
1620 | } | 1610 | } |
1611 | |||
1612 | /* | ||
1613 | * Starts a dialog with the server, and authenticates the current user on the | ||
1614 | * server. This does not need any extra privileges. The basic connection | ||
1615 | * to the server must already have been established before this is called. | ||
1616 | * If login fails, this function prints an error and never returns. | ||
1617 | * This function does not require super-user privileges. | ||
1618 | */ | ||
1619 | void | ||
1620 | ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, | ||
1621 | struct sockaddr *hostaddr, uid_t original_real_uid) | ||
1622 | { | ||
1623 | char *host, *cp; | ||
1624 | |||
1625 | /* Convert the user-supplied hostname into all lowercase. */ | ||
1626 | host = xstrdup(orighost); | ||
1627 | for (cp = host; *cp; cp++) | ||
1628 | if (isupper(*cp)) | ||
1629 | *cp = tolower(*cp); | ||
1630 | |||
1631 | /* Exchange protocol version identification strings with the server. */ | ||
1632 | ssh_exchange_identification(); | ||
1633 | |||
1634 | /* Put the connection into non-blocking mode. */ | ||
1635 | packet_set_nonblocking(); | ||
1636 | |||
1637 | supported_authentications = 0; | ||
1638 | /* key exchange */ | ||
1639 | ssh_kex(host, hostaddr); | ||
1640 | if (supported_authentications == 0) | ||
1641 | fatal("supported_authentications == 0."); | ||
1642 | /* authenticate user */ | ||
1643 | ssh_userauth(host_key_valid, own_host_key, original_real_uid, host); | ||
1644 | } | ||
@@ -9,7 +9,7 @@ | |||
9 | .\" | 9 | .\" |
10 | .\" Created: Sat Apr 22 21:55:14 1995 ylo | 10 | .\" Created: Sat Apr 22 21:55:14 1995 ylo |
11 | .\" | 11 | .\" |
12 | .\" $Id: sshd.8.in,v 1.3 2000/01/17 11:02:18 damien Exp $ | 12 | .\" $Id: sshd.8.in,v 1.4 2000/01/20 11:44:10 damien Exp $ |
13 | .\" | 13 | .\" |
14 | .Dd September 25, 1999 | 14 | .Dd September 25, 1999 |
15 | .Dt SSHD 8 | 15 | .Dt SSHD 8 |
@@ -242,7 +242,7 @@ the primary group. | |||
242 | .Pp | 242 | .Pp |
243 | .It Cm DenyUsers | 243 | .It Cm DenyUsers |
244 | This keyword can be followed by a number of user names, separated | 244 | This keyword can be followed by a number of user names, separated |
245 | by spaces. Login is allowed disallowed for user names that match | 245 | by spaces. Login is disallowed for user names that match |
246 | one of the patterns. | 246 | one of the patterns. |
247 | .Ql \&* | 247 | .Ql \&* |
248 | and | 248 | and |
@@ -436,17 +436,17 @@ Specifies whether | |||
436 | .Xr login 1 | 436 | .Xr login 1 |
437 | is used. The default is | 437 | is used. The default is |
438 | .Dq no . | 438 | .Dq no . |
439 | .It Cm X11Forwarding | ||
440 | Specifies whether X11 forwarding is permitted. The default is | ||
441 | .Dq yes . | ||
442 | Note that disabling X11 forwarding does not improve security in any | ||
443 | way, as users can always install their own forwarders. | ||
444 | .It Cm X11DisplayOffset | 439 | .It Cm X11DisplayOffset |
445 | Specifies the first display number available for | 440 | Specifies the first display number available for |
446 | .Nm sshd Ns 's | 441 | .Nm sshd Ns 's |
447 | X11 forwarding. This prevents | 442 | X11 forwarding. This prevents |
448 | .Nm | 443 | .Nm |
449 | from interfering with real X11 servers. | 444 | from interfering with real X11 servers. |
445 | .It Cm X11Forwarding | ||
446 | Specifies whether X11 forwarding is permitted. The default is | ||
447 | .Dq yes . | ||
448 | Note that disabling X11 forwarding does not improve security in any | ||
449 | way, as users can always install their own forwarders. | ||
450 | .El | 450 | .El |
451 | .Sh LOGIN PROCESS | 451 | .Sh LOGIN PROCESS |
452 | When a user successfully logs in, | 452 | When a user successfully logs in, |
@@ -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 | } |