diff options
author | Damien Miller <djm@mindrot.org> | 1999-11-25 11:54:57 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 1999-11-25 11:54:57 +1100 |
commit | 5428f646ad32da88ddd04a8c287d595524674fbf (patch) | |
tree | cc1f1e5d7852e1f44d41077f776abf7dab7ac06d /sshd.c | |
parent | 9072e1889648988da38b7b81bce95291c1dc3a23 (diff) |
- More reformatting merged from OpenBSD CVS
- Merged OpenBSD CVS changes:
- [channels.c]
report from mrwizard@psu.edu via djm@ibs.com.au
- [channels.c]
set SO_REUSEADDR and SO_LINGER for forwarded ports.
chip@valinux.com via damien@ibs.com.au
- [nchan.c]
it's not an error() if shutdown_write failes in nchan.
- [readconf.c]
remove dead #ifdef-0-code
- [readconf.c servconf.c]
strcasecmp instead of tolower
- [scp.c]
progress meter overflow fix from damien@ibs.com.au
- [ssh-add.1 ssh-add.c]
SSH_ASKPASS support
- [ssh.1 ssh.c]
postpone fork_after_authentication until command execution,
request/patch from jahakala@cc.jyu.fi via damien@ibs.com.au
plus: use daemon() for backgrounding
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 499 |
1 files changed, 286 insertions, 213 deletions
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$Id: sshd.c,v 1.31 1999/11/24 23:42:08 damien Exp $"); | 14 | RCSID("$Id: sshd.c,v 1.32 1999/11/25 00:54:59 damien Exp $"); |
15 | 15 | ||
16 | #include "xmalloc.h" | 16 | #include "xmalloc.h" |
17 | #include "rsa.h" | 17 | #include "rsa.h" |
@@ -65,12 +65,16 @@ char *av0; | |||
65 | /* Saved arguments to main(). */ | 65 | /* Saved arguments to main(). */ |
66 | char **saved_argv; | 66 | char **saved_argv; |
67 | 67 | ||
68 | /* This is set to the socket that the server is listening; this is used in | 68 | /* |
69 | the SIGHUP signal handler. */ | 69 | * This is set to the socket that the server is listening; this is used in |
70 | * the SIGHUP signal handler. | ||
71 | */ | ||
70 | int listen_sock; | 72 | int listen_sock; |
71 | 73 | ||
72 | /* the client's version string, passed by sshd2 in compat mode. | 74 | /* |
73 | if != NULL, sshd will skip the version-number exchange */ | 75 | * the client's version string, passed by sshd2 in compat mode. if != NULL, |
76 | * sshd will skip the version-number exchange | ||
77 | */ | ||
74 | char *client_version_string = NULL; | 78 | char *client_version_string = NULL; |
75 | 79 | ||
76 | /* Flags set in auth-rsa from authorized_keys flags. These are set in auth-rsa.c. */ | 80 | /* Flags set in auth-rsa from authorized_keys flags. These are set in auth-rsa.c. */ |
@@ -88,19 +92,23 @@ struct envstring *custom_environment = NULL; | |||
88 | /* Session id for the current session. */ | 92 | /* Session id for the current session. */ |
89 | unsigned char session_id[16]; | 93 | unsigned char session_id[16]; |
90 | 94 | ||
91 | /* Any really sensitive data in the application is contained in this structure. | 95 | /* |
92 | The idea is that this structure could be locked into memory so that the | 96 | * Any really sensitive data in the application is contained in this |
93 | pages do not get written into swap. However, there are some problems. | 97 | * structure. The idea is that this structure could be locked into memory so |
94 | The private key contains BIGNUMs, and we do not (in principle) have | 98 | * that the pages do not get written into swap. However, there are some |
95 | access to the internals of them, and locking just the structure is not | 99 | * problems. The private key contains BIGNUMs, and we do not (in principle) |
96 | very useful. Currently, memory locking is not implemented. */ | 100 | * have access to the internals of them, and locking just the structure is |
101 | * not very useful. Currently, memory locking is not implemented. | ||
102 | */ | ||
97 | struct { | 103 | struct { |
98 | RSA *private_key; /* Private part of server key. */ | 104 | RSA *private_key; /* Private part of server key. */ |
99 | RSA *host_key; /* Private part of host key. */ | 105 | RSA *host_key; /* Private part of host key. */ |
100 | } sensitive_data; | 106 | } sensitive_data; |
101 | 107 | ||
102 | /* Flag indicating whether the current session key has been used. This flag | 108 | /* |
103 | is set whenever the key is used, and cleared when the key is regenerated. */ | 109 | * Flag indicating whether the current session key has been used. This flag |
110 | * is set whenever the key is used, and cleared when the key is regenerated. | ||
111 | */ | ||
104 | int key_used = 0; | 112 | int key_used = 0; |
105 | 113 | ||
106 | /* This is set to true when SIGHUP is received. */ | 114 | /* This is set to true when SIGHUP is received. */ |
@@ -466,7 +474,7 @@ main(int ac, char **av) | |||
466 | fprintf(stderr, "sshd version %s\n", SSH_VERSION); | 474 | fprintf(stderr, "sshd version %s\n", SSH_VERSION); |
467 | fprintf(stderr, "Usage: %s [options]\n", av0); | 475 | fprintf(stderr, "Usage: %s [options]\n", av0); |
468 | fprintf(stderr, "Options:\n"); | 476 | fprintf(stderr, "Options:\n"); |
469 | fprintf(stderr, " -f file Configuration file (default %s/sshd_config)\n", ETCDIR); | 477 | fprintf(stderr, " -f file Configuration file (default %s)\n", SERVER_CONFIG_FILE); |
470 | fprintf(stderr, " -d Debugging mode\n"); | 478 | fprintf(stderr, " -d Debugging mode\n"); |
471 | fprintf(stderr, " -i Started from inetd\n"); | 479 | fprintf(stderr, " -i Started from inetd\n"); |
472 | fprintf(stderr, " -q Quiet (no logging)\n"); | 480 | fprintf(stderr, " -q Quiet (no logging)\n"); |
@@ -614,13 +622,11 @@ main(int ac, char **av) | |||
614 | setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *) &linger, | 622 | setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *) &linger, |
615 | sizeof(linger)); | 623 | sizeof(linger)); |
616 | 624 | ||
617 | /* Initialize the socket address. */ | ||
618 | memset(&sin, 0, sizeof(sin)); | 625 | memset(&sin, 0, sizeof(sin)); |
619 | sin.sin_family = AF_INET; | 626 | sin.sin_family = AF_INET; |
620 | sin.sin_addr = options.listen_addr; | 627 | sin.sin_addr = options.listen_addr; |
621 | sin.sin_port = htons(options.port); | 628 | sin.sin_port = htons(options.port); |
622 | 629 | ||
623 | /* Bind the socket to the desired port. */ | ||
624 | if (bind(listen_sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) { | 630 | if (bind(listen_sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) { |
625 | error("bind: %.100s", strerror(errno)); | 631 | error("bind: %.100s", strerror(errno)); |
626 | shutdown(listen_sock, SHUT_RDWR); | 632 | shutdown(listen_sock, SHUT_RDWR); |
@@ -628,12 +634,13 @@ main(int ac, char **av) | |||
628 | fatal("Bind to port %d failed.", options.port); | 634 | fatal("Bind to port %d failed.", options.port); |
629 | } | 635 | } |
630 | if (!debug_flag) { | 636 | if (!debug_flag) { |
631 | /* Record our pid in /etc/sshd_pid to make it | 637 | /* |
632 | easier to kill the correct sshd. We don\'t | 638 | * Record our pid in /etc/sshd_pid to make it easier |
633 | want to do this before the bind above because | 639 | * to kill the correct sshd. We don\'t want to do |
634 | the bind will fail if there already is a | 640 | * this before the bind above because the bind will |
635 | daemon, and this will overwrite any old pid in | 641 | * fail if there already is a daemon, and this will |
636 | the file. */ | 642 | * overwrite any old pid in the file. |
643 | */ | ||
637 | f = fopen(SSH_DAEMON_PID_FILE, "w"); | 644 | f = fopen(SSH_DAEMON_PID_FILE, "w"); |
638 | if (f) { | 645 | if (f) { |
639 | fprintf(f, "%u\n", (unsigned int) getpid()); | 646 | fprintf(f, "%u\n", (unsigned int) getpid()); |
@@ -666,8 +673,10 @@ main(int ac, char **av) | |||
666 | /* Arrange SIGCHLD to be caught. */ | 673 | /* Arrange SIGCHLD to be caught. */ |
667 | signal(SIGCHLD, main_sigchld_handler); | 674 | signal(SIGCHLD, main_sigchld_handler); |
668 | 675 | ||
669 | /* Stay listening for connections until the system crashes | 676 | /* |
670 | or the daemon is killed with a signal. */ | 677 | * Stay listening for connections until the system crashes or |
678 | * the daemon is killed with a signal. | ||
679 | */ | ||
671 | for (;;) { | 680 | for (;;) { |
672 | if (received_sighup) | 681 | if (received_sighup) |
673 | sighup_restart(); | 682 | sighup_restart(); |
@@ -682,12 +691,16 @@ main(int ac, char **av) | |||
682 | error("accept: %.100s", strerror(errno)); | 691 | error("accept: %.100s", strerror(errno)); |
683 | continue; | 692 | continue; |
684 | } | 693 | } |
685 | /* Got connection. Fork a child to handle it, | 694 | /* |
686 | unless we are in debugging mode. */ | 695 | * Got connection. Fork a child to handle it, unless |
696 | * we are in debugging mode. | ||
697 | */ | ||
687 | if (debug_flag) { | 698 | if (debug_flag) { |
688 | /* In debugging mode. Close the listening | 699 | /* |
689 | socket, and start processing the | 700 | * In debugging mode. Close the listening |
690 | connection without forking. */ | 701 | * socket, and start processing the |
702 | * connection without forking. | ||
703 | */ | ||
691 | debug("Server will not fork when running in debugging mode."); | 704 | debug("Server will not fork when running in debugging mode."); |
692 | close(listen_sock); | 705 | close(listen_sock); |
693 | sock_in = newsock; | 706 | sock_in = newsock; |
@@ -695,16 +708,17 @@ main(int ac, char **av) | |||
695 | pid = getpid(); | 708 | pid = getpid(); |
696 | break; | 709 | break; |
697 | } else { | 710 | } else { |
698 | /* Normal production daemon. Fork, and | 711 | /* |
699 | have the child process the connection. | 712 | * Normal production daemon. Fork, and have |
700 | The parent continues listening. */ | 713 | * the child process the connection. The |
714 | * parent continues listening. | ||
715 | */ | ||
701 | if ((pid = fork()) == 0) { | 716 | if ((pid = fork()) == 0) { |
702 | /* Child. Close the listening | 717 | /* |
703 | socket, and start using the | 718 | * Child. Close the listening socket, and start using the |
704 | accepted socket. Reinitialize | 719 | * accepted socket. Reinitialize logging (since our pid has |
705 | logging (since our pid has | 720 | * changed). We break out of the loop to handle the connection. |
706 | changed). We break out of the | 721 | */ |
707 | loop to handle the connection. */ | ||
708 | close(listen_sock); | 722 | close(listen_sock); |
709 | sock_in = newsock; | 723 | sock_in = newsock; |
710 | sock_out = newsock; | 724 | sock_out = newsock; |
@@ -731,9 +745,11 @@ main(int ac, char **av) | |||
731 | 745 | ||
732 | /* This is the child processing a new connection. */ | 746 | /* This is the child processing a new connection. */ |
733 | 747 | ||
734 | /* Disable the key regeneration alarm. We will not regenerate the | 748 | /* |
735 | key since we are no longer in a position to give it to anyone. | 749 | * Disable the key regeneration alarm. We will not regenerate the |
736 | We will not restart on SIGHUP since it no longer makes sense. */ | 750 | * key since we are no longer in a position to give it to anyone. We |
751 | * will not restart on SIGHUP since it no longer makes sense. | ||
752 | */ | ||
737 | alarm(0); | 753 | alarm(0); |
738 | signal(SIGALRM, SIG_DFL); | 754 | signal(SIGALRM, SIG_DFL); |
739 | signal(SIGHUP, SIG_DFL); | 755 | signal(SIGHUP, SIG_DFL); |
@@ -741,17 +757,20 @@ main(int ac, char **av) | |||
741 | signal(SIGQUIT, SIG_DFL); | 757 | signal(SIGQUIT, SIG_DFL); |
742 | signal(SIGCHLD, SIG_DFL); | 758 | signal(SIGCHLD, SIG_DFL); |
743 | 759 | ||
744 | /* Set socket options for the connection. We want the socket to | 760 | /* |
745 | close as fast as possible without waiting for anything. If the | 761 | * Set socket options for the connection. We want the socket to |
746 | connection is not a socket, these will do nothing. */ | 762 | * close as fast as possible without waiting for anything. If the |
747 | /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, | 763 | * connection is not a socket, these will do nothing. |
748 | sizeof(on)); */ | 764 | */ |
765 | /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ | ||
749 | linger.l_onoff = 1; | 766 | linger.l_onoff = 1; |
750 | linger.l_linger = 5; | 767 | linger.l_linger = 5; |
751 | setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); | 768 | setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); |
752 | 769 | ||
753 | /* Register our connection. This turns encryption off because we | 770 | /* |
754 | do not have a key. */ | 771 | * Register our connection. This turns encryption off because we do |
772 | * not have a key. | ||
773 | */ | ||
755 | packet_set_connection(sock_in, sock_out); | 774 | packet_set_connection(sock_in, sock_out); |
756 | 775 | ||
757 | remote_port = get_remote_port(); | 776 | remote_port = get_remote_port(); |
@@ -777,12 +796,14 @@ main(int ac, char **av) | |||
777 | verbose("Connection from %.500s port %d", remote_ip, remote_port); | 796 | verbose("Connection from %.500s port %d", remote_ip, remote_port); |
778 | #endif /* LIBWRAP */ | 797 | #endif /* LIBWRAP */ |
779 | 798 | ||
780 | /* We don\'t want to listen forever unless the other side | 799 | /* |
781 | successfully authenticates itself. So we set up an alarm which | 800 | * We don\'t want to listen forever unless the other side |
782 | is cleared after successful authentication. A limit of zero | 801 | * successfully authenticates itself. So we set up an alarm which is |
783 | indicates no limit. Note that we don\'t set the alarm in | 802 | * cleared after successful authentication. A limit of zero |
784 | debugging mode; it is just annoying to have the server exit | 803 | * indicates no limit. Note that we don\'t set the alarm in debugging |
785 | just when you are about to discover the bug. */ | 804 | * mode; it is just annoying to have the server exit just when you |
805 | * are about to discover the bug. | ||
806 | */ | ||
786 | signal(SIGALRM, grace_alarm_handler); | 807 | signal(SIGALRM, grace_alarm_handler); |
787 | if (!debug_flag) | 808 | if (!debug_flag) |
788 | alarm(options.login_grace_time); | 809 | alarm(options.login_grace_time); |
@@ -815,8 +836,10 @@ main(int ac, char **av) | |||
815 | buf[sizeof(buf) - 1] = 0; | 836 | buf[sizeof(buf) - 1] = 0; |
816 | } | 837 | } |
817 | 838 | ||
818 | /* Check that the versions match. In future this might accept | 839 | /* |
819 | several versions and set appropriate flags to handle them. */ | 840 | * Check that the versions match. In future this might accept |
841 | * several versions and set appropriate flags to handle them. | ||
842 | */ | ||
820 | if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, | 843 | if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, |
821 | remote_version) != 3) { | 844 | remote_version) != 3) { |
822 | const char *s = "Protocol mismatch.\n"; | 845 | const char *s = "Protocol mismatch.\n"; |
@@ -848,11 +871,13 @@ main(int ac, char **av) | |||
848 | no_agent_forwarding_flag = 1; | 871 | no_agent_forwarding_flag = 1; |
849 | } | 872 | } |
850 | } | 873 | } |
851 | /* Check that the connection comes from a privileged port. Rhosts- | 874 | /* |
852 | and Rhosts-RSA-Authentication only make sense from priviledged | 875 | * Check that the connection comes from a privileged port. Rhosts- |
853 | programs. Of course, if the intruder has root access on his | 876 | * and Rhosts-RSA-Authentication only make sense from priviledged |
854 | local machine, he can connect from any port. So do not use | 877 | * programs. Of course, if the intruder has root access on his local |
855 | these authentication methods from machines that you do not trust. */ | 878 | * machine, he can connect from any port. So do not use these |
879 | * authentication methods from machines that you do not trust. | ||
880 | */ | ||
856 | if (remote_port >= IPPORT_RESERVED || | 881 | if (remote_port >= IPPORT_RESERVED || |
857 | remote_port < IPPORT_RESERVED / 2) { | 882 | remote_port < IPPORT_RESERVED / 2) { |
858 | options.rhosts_authentication = 0; | 883 | options.rhosts_authentication = 0; |
@@ -914,13 +939,15 @@ do_connection() | |||
914 | int plen, slen; | 939 | int plen, slen; |
915 | u_int32_t rand = 0; | 940 | u_int32_t rand = 0; |
916 | 941 | ||
917 | /* Generate check bytes that the client must send back in the user | 942 | /* |
918 | packet in order for it to be accepted; this is used to defy ip | 943 | * Generate check bytes that the client must send back in the user |
919 | spoofing attacks. Note that this only works against somebody | 944 | * packet in order for it to be accepted; this is used to defy ip |
920 | doing IP spoofing from a remote machine; any machine on the | 945 | * spoofing attacks. Note that this only works against somebody |
921 | local network can still see outgoing packets and catch the | 946 | * doing IP spoofing from a remote machine; any machine on the local |
922 | random cookie. This only affects rhosts authentication, and | 947 | * network can still see outgoing packets and catch the random |
923 | this is one of the reasons why it is inherently insecure. */ | 948 | * cookie. This only affects rhosts authentication, and this is one |
949 | * of the reasons why it is inherently insecure. | ||
950 | */ | ||
924 | for (i = 0; i < 8; i++) { | 951 | for (i = 0; i < 8; i++) { |
925 | if (i % 4 == 0) | 952 | if (i % 4 == 0) |
926 | rand = arc4random(); | 953 | rand = arc4random(); |
@@ -928,9 +955,11 @@ do_connection() | |||
928 | rand >>= 8; | 955 | rand >>= 8; |
929 | } | 956 | } |
930 | 957 | ||
931 | /* Send our public key. We include in the packet 64 bits of | 958 | /* |
932 | random data that must be matched in the reply in order to | 959 | * Send our public key. We include in the packet 64 bits of random |
933 | prevent IP spoofing. */ | 960 | * data that must be matched in the reply in order to prevent IP |
961 | * spoofing. | ||
962 | */ | ||
934 | packet_start(SSH_SMSG_PUBLIC_KEY); | 963 | packet_start(SSH_SMSG_PUBLIC_KEY); |
935 | for (i = 0; i < 8; i++) | 964 | for (i = 0; i < 8; i++) |
936 | packet_put_char(check_bytes[i]); | 965 | packet_put_char(check_bytes[i]); |
@@ -1002,14 +1031,15 @@ do_connection() | |||
1002 | session_key_int = BN_new(); | 1031 | session_key_int = BN_new(); |
1003 | packet_get_bignum(session_key_int, &slen); | 1032 | packet_get_bignum(session_key_int, &slen); |
1004 | 1033 | ||
1005 | /* Get protocol flags. */ | ||
1006 | protocol_flags = packet_get_int(); | 1034 | protocol_flags = packet_get_int(); |
1007 | packet_set_protocol_flags(protocol_flags); | 1035 | packet_set_protocol_flags(protocol_flags); |
1008 | 1036 | ||
1009 | packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY); | 1037 | packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY); |
1010 | 1038 | ||
1011 | /* Decrypt it using our private server key and private host key | 1039 | /* |
1012 | (key with larger modulus first). */ | 1040 | * Decrypt it using our private server key and private host key (key |
1041 | * with larger modulus first). | ||
1042 | */ | ||
1013 | if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) { | 1043 | if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) { |
1014 | /* Private key has bigger modulus. */ | 1044 | /* Private key has bigger modulus. */ |
1015 | if (BN_num_bits(sensitive_data.private_key->n) < | 1045 | if (BN_num_bits(sensitive_data.private_key->n) < |
@@ -1040,14 +1070,15 @@ do_connection() | |||
1040 | sensitive_data.private_key); | 1070 | sensitive_data.private_key); |
1041 | } | 1071 | } |
1042 | 1072 | ||
1043 | /* Compute session id for this session. */ | ||
1044 | compute_session_id(session_id, check_bytes, | 1073 | compute_session_id(session_id, check_bytes, |
1045 | sensitive_data.host_key->n, | 1074 | sensitive_data.host_key->n, |
1046 | sensitive_data.private_key->n); | 1075 | sensitive_data.private_key->n); |
1047 | 1076 | ||
1048 | /* Extract session key from the decrypted integer. The key is in | 1077 | /* |
1049 | the least significant 256 bits of the integer; the first byte | 1078 | * Extract session key from the decrypted integer. The key is in the |
1050 | of the key is in the highest bits. */ | 1079 | * least significant 256 bits of the integer; the first byte of the |
1080 | * key is in the highest bits. | ||
1081 | */ | ||
1051 | BN_mask_bits(session_key_int, sizeof(session_key) * 8); | 1082 | BN_mask_bits(session_key_int, sizeof(session_key) * 8); |
1052 | len = BN_num_bytes(session_key_int); | 1083 | len = BN_num_bytes(session_key_int); |
1053 | if (len < 0 || len > sizeof(session_key)) | 1084 | if (len < 0 || len > sizeof(session_key)) |
@@ -1125,8 +1156,7 @@ allowed_user(struct passwd * pw) | |||
1125 | if (match_pattern(pw->pw_name, options.deny_users[i])) | 1156 | if (match_pattern(pw->pw_name, options.deny_users[i])) |
1126 | return 0; | 1157 | return 0; |
1127 | } | 1158 | } |
1128 | /* Return false if AllowUsers isn't empty and user isn't listed | 1159 | /* Return false if AllowUsers isn't empty and user isn't listed there */ |
1129 | there */ | ||
1130 | if (options.num_allow_users > 0) { | 1160 | if (options.num_allow_users > 0) { |
1131 | if (!pw->pw_name) | 1161 | if (!pw->pw_name) |
1132 | return 0; | 1162 | return 0; |
@@ -1151,8 +1181,10 @@ allowed_user(struct passwd * pw) | |||
1151 | if (match_pattern(grp->gr_name, options.deny_groups[i])) | 1181 | if (match_pattern(grp->gr_name, options.deny_groups[i])) |
1152 | return 0; | 1182 | return 0; |
1153 | } | 1183 | } |
1154 | /* Return false if AllowGroups isn't empty and user's | 1184 | /* |
1155 | group isn't listed there */ | 1185 | * Return false if AllowGroups isn't empty and user's group |
1186 | * isn't listed there | ||
1187 | */ | ||
1156 | if (options.num_allow_groups > 0) { | 1188 | if (options.num_allow_groups > 0) { |
1157 | if (!grp->gr_name) | 1189 | if (!grp->gr_name) |
1158 | return 0; | 1190 | return 0; |
@@ -1216,8 +1248,10 @@ do_authentication(char *user) | |||
1216 | } | 1248 | } |
1217 | #endif | 1249 | #endif |
1218 | 1250 | ||
1219 | /* If we are not running as root, the user must have the same uid | 1251 | /* |
1220 | as the server. */ | 1252 | * If we are not running as root, the user must have the same uid as |
1253 | * the server. | ||
1254 | */ | ||
1221 | if (getuid() != 0 && pw->pw_uid != getuid()) | 1255 | if (getuid() != 0 && pw->pw_uid != getuid()) |
1222 | packet_disconnect("Cannot change user when server not running as root."); | 1256 | packet_disconnect("Cannot change user when server not running as root."); |
1223 | 1257 | ||
@@ -1357,10 +1391,12 @@ do_authloop(struct passwd * pw) | |||
1357 | verbose("Rhosts authentication disabled."); | 1391 | verbose("Rhosts authentication disabled."); |
1358 | break; | 1392 | break; |
1359 | } | 1393 | } |
1360 | /* Get client user name. Note that we just have | 1394 | /* |
1361 | to trust the client; this is one reason why | 1395 | * Get client user name. Note that we just have to |
1362 | rhosts authentication is insecure. (Another is | 1396 | * trust the client; this is one reason why rhosts |
1363 | IP-spoofing on a local network.) */ | 1397 | * authentication is insecure. (Another is |
1398 | * IP-spoofing on a local network.) | ||
1399 | */ | ||
1364 | client_user = packet_get_string(&ulen); | 1400 | client_user = packet_get_string(&ulen); |
1365 | packet_integrity_check(plen, 4 + ulen, type); | 1401 | packet_integrity_check(plen, 4 + ulen, type); |
1366 | 1402 | ||
@@ -1379,9 +1415,11 @@ do_authloop(struct passwd * pw) | |||
1379 | verbose("Rhosts with RSA authentication disabled."); | 1415 | verbose("Rhosts with RSA authentication disabled."); |
1380 | break; | 1416 | break; |
1381 | } | 1417 | } |
1382 | /* Get client user name. Note that we just have | 1418 | /* |
1383 | to trust the client; root on the client machine | 1419 | * Get client user name. Note that we just have to |
1384 | can claim to be any user. */ | 1420 | * trust the client; root on the client machine can |
1421 | * claim to be any user. | ||
1422 | */ | ||
1385 | client_user = packet_get_string(&ulen); | 1423 | client_user = packet_get_string(&ulen); |
1386 | 1424 | ||
1387 | /* Get the client host key. */ | 1425 | /* Get the client host key. */ |
@@ -1425,9 +1463,11 @@ do_authloop(struct passwd * pw) | |||
1425 | verbose("Password authentication disabled."); | 1463 | verbose("Password authentication disabled."); |
1426 | break; | 1464 | break; |
1427 | } | 1465 | } |
1428 | /* Read user password. It is in plain text, but | 1466 | /* |
1429 | was transmitted over the encrypted channel so | 1467 | * Read user password. It is in plain text, but was |
1430 | it is not visible to an outside observer. */ | 1468 | * transmitted over the encrypted channel so it is |
1469 | * not visible to an outside observer. | ||
1470 | */ | ||
1431 | password = packet_get_string(&dlen); | 1471 | password = packet_get_string(&dlen); |
1432 | packet_integrity_check(plen, 4 + dlen, type); | 1472 | packet_integrity_check(plen, 4 + dlen, type); |
1433 | 1473 | ||
@@ -1463,8 +1503,7 @@ do_authloop(struct passwd * pw) | |||
1463 | skeyinfo = skey_fake_keyinfo(pw->pw_name); | 1503 | skeyinfo = skey_fake_keyinfo(pw->pw_name); |
1464 | } | 1504 | } |
1465 | if (skeyinfo != NULL) { | 1505 | if (skeyinfo != NULL) { |
1466 | /* we send our s/key- in | 1506 | /* we send our s/key- in tis-challenge messages */ |
1467 | tis-challenge messages */ | ||
1468 | debug("sending challenge '%s'", skeyinfo); | 1507 | debug("sending challenge '%s'", skeyinfo); |
1469 | packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); | 1508 | packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); |
1470 | packet_put_string(skeyinfo, strlen(skeyinfo)); | 1509 | packet_put_string(skeyinfo, strlen(skeyinfo)); |
@@ -1493,8 +1532,10 @@ do_authloop(struct passwd * pw) | |||
1493 | #endif | 1532 | #endif |
1494 | 1533 | ||
1495 | default: | 1534 | default: |
1496 | /* Any unknown messages will be ignored (and | 1535 | /* |
1497 | failure returned) during authentication. */ | 1536 | * Any unknown messages will be ignored (and failure |
1537 | * returned) during authentication. | ||
1538 | */ | ||
1498 | log("Unknown message during authentication: type %d", type); | 1539 | log("Unknown message during authentication: type %d", type); |
1499 | break; | 1540 | break; |
1500 | } | 1541 | } |
@@ -1559,11 +1600,12 @@ do_fake_authloop(char *user) | |||
1559 | packet_send(); | 1600 | packet_send(); |
1560 | packet_write_wait(); | 1601 | packet_write_wait(); |
1561 | 1602 | ||
1562 | /* Keep reading packets, and always respond with a failure. This | 1603 | /* |
1563 | is to avoid disclosing whether such a user really exists. */ | 1604 | * Keep reading packets, and always respond with a failure. This is |
1605 | * to avoid disclosing whether such a user really exists. | ||
1606 | */ | ||
1564 | for (attempt = 1;; attempt++) { | 1607 | for (attempt = 1;; attempt++) { |
1565 | /* Read a packet. This will not return if the client | 1608 | /* Read a packet. This will not return if the client disconnects. */ |
1566 | disconnects. */ | ||
1567 | int plen; | 1609 | int plen; |
1568 | int type = packet_read(&plen); | 1610 | int type = packet_read(&plen); |
1569 | #ifdef SKEY | 1611 | #ifdef SKEY |
@@ -1583,8 +1625,10 @@ do_fake_authloop(char *user) | |||
1583 | if (attempt > AUTH_FAIL_MAX) | 1625 | if (attempt > AUTH_FAIL_MAX) |
1584 | packet_disconnect(AUTH_FAIL_MSG, user); | 1626 | packet_disconnect(AUTH_FAIL_MSG, user); |
1585 | 1627 | ||
1586 | /* Send failure. This should be indistinguishable from a | 1628 | /* |
1587 | failed authentication. */ | 1629 | * Send failure. This should be indistinguishable from a |
1630 | * failed authentication. | ||
1631 | */ | ||
1588 | packet_start(SSH_SMSG_FAILURE); | 1632 | packet_start(SSH_SMSG_FAILURE); |
1589 | packet_send(); | 1633 | packet_send(); |
1590 | packet_write_wait(); | 1634 | packet_write_wait(); |
@@ -1630,19 +1674,25 @@ do_authenticated(struct passwd * pw) | |||
1630 | mode_t tty_mode; | 1674 | mode_t tty_mode; |
1631 | int n_bytes; | 1675 | int n_bytes; |
1632 | 1676 | ||
1633 | /* Cancel the alarm we set to limit the time taken for | 1677 | /* |
1634 | authentication. */ | 1678 | * Cancel the alarm we set to limit the time taken for |
1679 | * authentication. | ||
1680 | */ | ||
1635 | alarm(0); | 1681 | alarm(0); |
1636 | 1682 | ||
1637 | /* Inform the channel mechanism that we are the server side and | 1683 | /* |
1638 | that the client may request to connect to any port at all. | 1684 | * Inform the channel mechanism that we are the server side and that |
1639 | (The user could do it anyway, and we wouldn\'t know what is | 1685 | * the client may request to connect to any port at all. (The user |
1640 | permitted except by the client telling us, so we can equally | 1686 | * could do it anyway, and we wouldn\'t know what is permitted except |
1641 | well trust the client not to request anything bogus.) */ | 1687 | * by the client telling us, so we can equally well trust the client |
1688 | * not to request anything bogus.) | ||
1689 | */ | ||
1642 | channel_permit_all_opens(); | 1690 | channel_permit_all_opens(); |
1643 | 1691 | ||
1644 | /* We stay in this loop until the client requests to execute a | 1692 | /* |
1645 | shell or a command. */ | 1693 | * We stay in this loop until the client requests to execute a shell |
1694 | * or a command. | ||
1695 | */ | ||
1646 | while (1) { | 1696 | while (1) { |
1647 | int plen, dlen; | 1697 | int plen, dlen; |
1648 | 1698 | ||
@@ -1826,8 +1876,10 @@ do_authenticated(struct passwd * pw) | |||
1826 | return; | 1876 | return; |
1827 | 1877 | ||
1828 | default: | 1878 | default: |
1829 | /* Any unknown messages in this phase are ignored, | 1879 | /* |
1830 | and a failure message is returned. */ | 1880 | * Any unknown messages in this phase are ignored, |
1881 | * and a failure message is returned. | ||
1882 | */ | ||
1831 | log("Unknown packet type received after authentication: %d", type); | 1883 | log("Unknown packet type received after authentication: %d", type); |
1832 | goto fail; | 1884 | goto fail; |
1833 | } | 1885 | } |
@@ -1852,8 +1904,10 @@ fail: | |||
1852 | continue; | 1904 | continue; |
1853 | 1905 | ||
1854 | do_forced_command: | 1906 | do_forced_command: |
1855 | /* There is a forced command specified for this login. | 1907 | /* |
1856 | Execute it. */ | 1908 | * There is a forced command specified for this login. |
1909 | * Execute it. | ||
1910 | */ | ||
1857 | debug("Executing forced command: %.900s", forced_command); | 1911 | debug("Executing forced command: %.900s", forced_command); |
1858 | if (have_pty) | 1912 | if (have_pty) |
1859 | do_exec_pty(forced_command, ptyfd, ttyfd, ttyname, pw, term, display, proto, data); | 1913 | do_exec_pty(forced_command, ptyfd, ttyfd, ttyname, pw, term, display, proto, data); |
@@ -1897,14 +1951,18 @@ do_exec_no_pty(const char *command, struct passwd * pw, | |||
1897 | /* Child. Reinitialize the log since the pid has changed. */ | 1951 | /* Child. Reinitialize the log since the pid has changed. */ |
1898 | log_init(av0, options.log_level, options.log_facility, log_stderr); | 1952 | log_init(av0, options.log_level, options.log_facility, log_stderr); |
1899 | 1953 | ||
1900 | /* Create a new session and process group since the 4.4BSD | 1954 | /* |
1901 | setlogin() affects the entire process group. */ | 1955 | * Create a new session and process group since the 4.4BSD |
1956 | * setlogin() affects the entire process group. | ||
1957 | */ | ||
1902 | if (setsid() < 0) | 1958 | if (setsid() < 0) |
1903 | error("setsid failed: %.100s", strerror(errno)); | 1959 | error("setsid failed: %.100s", strerror(errno)); |
1904 | 1960 | ||
1905 | #ifdef USE_PIPES | 1961 | #ifdef USE_PIPES |
1906 | /* Redirect stdin. We close the parent side of the socket | 1962 | /* |
1907 | pair, and make the child side the standard input. */ | 1963 | * Redirect stdin. We close the parent side of the socket |
1964 | * pair, and make the child side the standard input. | ||
1965 | */ | ||
1908 | close(pin[1]); | 1966 | close(pin[1]); |
1909 | if (dup2(pin[0], 0) < 0) | 1967 | if (dup2(pin[0], 0) < 0) |
1910 | perror("dup2 stdin"); | 1968 | perror("dup2 stdin"); |
@@ -1922,9 +1980,11 @@ do_exec_no_pty(const char *command, struct passwd * pw, | |||
1922 | perror("dup2 stderr"); | 1980 | perror("dup2 stderr"); |
1923 | close(perr[1]); | 1981 | close(perr[1]); |
1924 | #else /* USE_PIPES */ | 1982 | #else /* USE_PIPES */ |
1925 | /* Redirect stdin, stdout, and stderr. Stdin and stdout | 1983 | /* |
1926 | will use the same socket, as some programs | 1984 | * Redirect stdin, stdout, and stderr. Stdin and stdout will |
1927 | (particularly rdist) seem to depend on it. */ | 1985 | * use the same socket, as some programs (particularly rdist) |
1986 | * seem to depend on it. | ||
1987 | */ | ||
1928 | close(inout[1]); | 1988 | close(inout[1]); |
1929 | close(err[1]); | 1989 | close(err[1]); |
1930 | if (dup2(inout[0], 0) < 0) /* stdin */ | 1990 | if (dup2(inout[0], 0) < 0) /* stdin */ |
@@ -1955,8 +2015,10 @@ do_exec_no_pty(const char *command, struct passwd * pw, | |||
1955 | close(inout[0]); | 2015 | close(inout[0]); |
1956 | close(err[0]); | 2016 | close(err[0]); |
1957 | 2017 | ||
1958 | /* Enter the interactive session. Note: server_loop must be able | 2018 | /* |
1959 | to handle the case that fdin and fdout are the same. */ | 2019 | * Enter the interactive session. Note: server_loop must be able to |
2020 | * handle the case that fdin and fdout are the same. | ||
2021 | */ | ||
1960 | server_loop(pid, inout[1], inout[1], err[1]); | 2022 | server_loop(pid, inout[1], inout[1], err[1]); |
1961 | /* server_loop has closed inout[1] and err[1]. */ | 2023 | /* server_loop has closed inout[1] and err[1]. */ |
1962 | #endif /* USE_PIPES */ | 2024 | #endif /* USE_PIPES */ |
@@ -2012,8 +2074,10 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, | |||
2012 | /* Get remote host name. */ | 2074 | /* Get remote host name. */ |
2013 | hostname = get_canonical_hostname(); | 2075 | hostname = get_canonical_hostname(); |
2014 | 2076 | ||
2015 | /* Get the time when the user last logged in. Buf will be set to | 2077 | /* |
2016 | contain the hostname the last login was from. */ | 2078 | * Get the time when the user last logged in. Buf will be set to |
2079 | * contain the hostname the last login was from. | ||
2080 | */ | ||
2017 | if (!options.use_login) { | 2081 | if (!options.use_login) { |
2018 | last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, | 2082 | last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, |
2019 | buf, sizeof(buf)); | 2083 | buf, sizeof(buf)); |
@@ -2049,9 +2113,11 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, | |||
2049 | /* Close the extra descriptor for the pseudo tty. */ | 2113 | /* Close the extra descriptor for the pseudo tty. */ |
2050 | close(ttyfd); | 2114 | close(ttyfd); |
2051 | 2115 | ||
2052 | /* Get IP address of client. This is needed because we | 2116 | /* |
2053 | want to record where the user logged in from. If the | 2117 | * Get IP address of client. This is needed because we want |
2054 | connection is not a socket, let the ip address be 0.0.0.0. */ | 2118 | * to record where the user logged in from. If the |
2119 | * connection is not a socket, let the ip address be 0.0.0.0. | ||
2120 | */ | ||
2055 | memset(&from, 0, sizeof(from)); | 2121 | memset(&from, 0, sizeof(from)); |
2056 | if (packet_get_connection_in() == packet_get_connection_out()) { | 2122 | if (packet_get_connection_in() == packet_get_connection_out()) { |
2057 | fromlen = sizeof(from); | 2123 | fromlen = sizeof(from); |
@@ -2075,12 +2141,14 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, | |||
2075 | fprintf(stderr, pamconv_msg); | 2141 | fprintf(stderr, pamconv_msg); |
2076 | #endif | 2142 | #endif |
2077 | 2143 | ||
2078 | /* If the user has logged in before, display the time of | 2144 | /* |
2079 | last login. However, don't display anything extra if a | 2145 | * If the user has logged in before, display the time of last |
2080 | command has been specified (so that ssh can be used to | 2146 | * login. However, don't display anything extra if a command |
2081 | execute commands on a remote machine without users | 2147 | * has been specified (so that ssh can be used to execute |
2082 | knowing they are going to another machine). Login(1) | 2148 | * commands on a remote machine without users knowing they |
2083 | will do this for us as well, so check if login(1) is used */ | 2149 | * are going to another machine). Login(1) will do this for |
2150 | * us as well, so check if login(1) is used | ||
2151 | */ | ||
2084 | if (command == NULL && last_login_time != 0 && !quiet_login && | 2152 | if (command == NULL && last_login_time != 0 && !quiet_login && |
2085 | !options.use_login) { | 2153 | !options.use_login) { |
2086 | /* Convert the date to a string. */ | 2154 | /* Convert the date to a string. */ |
@@ -2095,10 +2163,12 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, | |||
2095 | else | 2163 | else |
2096 | printf("Last login: %s from %s\r\n", time_string, buf); | 2164 | printf("Last login: %s from %s\r\n", time_string, buf); |
2097 | } | 2165 | } |
2098 | /* Print /etc/motd unless a command was specified or | 2166 | /* |
2099 | printing it was disabled in server options or login(1) | 2167 | * Print /etc/motd unless a command was specified or printing |
2100 | will be used. Note that some machines appear to print | 2168 | * it was disabled in server options or login(1) will be |
2101 | it in /etc/profile or similar. */ | 2169 | * used. Note that some machines appear to print it in |
2170 | * /etc/profile or similar. | ||
2171 | */ | ||
2102 | if (command == NULL && options.print_motd && !quiet_login && | 2172 | if (command == NULL && options.print_motd && !quiet_login && |
2103 | !options.use_login) { | 2173 | !options.use_login) { |
2104 | /* Print /etc/motd if it exists. */ | 2174 | /* Print /etc/motd if it exists. */ |
@@ -2118,15 +2188,19 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, | |||
2118 | /* Parent. Close the slave side of the pseudo tty. */ | 2188 | /* Parent. Close the slave side of the pseudo tty. */ |
2119 | close(ttyfd); | 2189 | close(ttyfd); |
2120 | 2190 | ||
2121 | /* Create another descriptor of the pty master side for use as the | 2191 | /* |
2122 | standard input. We could use the original descriptor, but this | 2192 | * Create another descriptor of the pty master side for use as the |
2123 | simplifies code in server_loop. The descriptor is bidirectional. */ | 2193 | * standard input. We could use the original descriptor, but this |
2194 | * simplifies code in server_loop. The descriptor is bidirectional. | ||
2195 | */ | ||
2124 | fdout = dup(ptyfd); | 2196 | fdout = dup(ptyfd); |
2125 | if (fdout < 0) | 2197 | if (fdout < 0) |
2126 | packet_disconnect("dup failed: %.100s", strerror(errno)); | 2198 | packet_disconnect("dup failed: %.100s", strerror(errno)); |
2127 | 2199 | ||
2128 | /* Add a cleanup function to clear the utmp entry and record logout | 2200 | /* |
2129 | time in case we call fatal() (e.g., the connection gets closed). */ | 2201 | * Add a cleanup function to clear the utmp entry and record logout |
2202 | * time in case we call fatal() (e.g., the connection gets closed). | ||
2203 | */ | ||
2130 | cleanup_context.pid = pid; | 2204 | cleanup_context.pid = pid; |
2131 | cleanup_context.ttyname = ttyname; | 2205 | cleanup_context.ttyname = ttyname; |
2132 | fatal_add_cleanup(pty_cleanup_proc, (void *) &cleanup_context); | 2206 | fatal_add_cleanup(pty_cleanup_proc, (void *) &cleanup_context); |
@@ -2144,9 +2218,11 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, | |||
2144 | /* Release the pseudo-tty. */ | 2218 | /* Release the pseudo-tty. */ |
2145 | pty_release(ttyname); | 2219 | pty_release(ttyname); |
2146 | 2220 | ||
2147 | /* Close the server side of the socket pairs. We must do this | 2221 | /* |
2148 | after the pty cleanup, so that another process doesn't get this | 2222 | * Close the server side of the socket pairs. We must do this after |
2149 | pty while we're still cleaning up. */ | 2223 | * the pty cleanup, so that another process doesn't get this pty |
2224 | * while we're still cleaning up. | ||
2225 | */ | ||
2150 | close(ptyfd); | 2226 | close(ptyfd); |
2151 | close(fdout); | 2227 | close(fdout); |
2152 | } | 2228 | } |
@@ -2162,19 +2238,21 @@ child_set_env(char ***envp, unsigned int *envsizep, const char *name, | |||
2162 | unsigned int i, namelen; | 2238 | unsigned int i, namelen; |
2163 | char **env; | 2239 | char **env; |
2164 | 2240 | ||
2165 | /* Find the slot where the value should be stored. If the | 2241 | /* |
2166 | variable already exists, we reuse the slot; otherwise we append | 2242 | * Find the slot where the value should be stored. If the variable |
2167 | a new slot at the end of the array, expanding if necessary. */ | 2243 | * already exists, we reuse the slot; otherwise we append a new slot |
2244 | * at the end of the array, expanding if necessary. | ||
2245 | */ | ||
2168 | env = *envp; | 2246 | env = *envp; |
2169 | namelen = strlen(name); | 2247 | namelen = strlen(name); |
2170 | for (i = 0; env[i]; i++) | 2248 | for (i = 0; env[i]; i++) |
2171 | if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') | 2249 | if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') |
2172 | break; | 2250 | break; |
2173 | if (env[i]) { | 2251 | if (env[i]) { |
2174 | /* Name already exists. Reuse the slot. */ | 2252 | /* Reuse the slot. */ |
2175 | xfree(env[i]); | 2253 | xfree(env[i]); |
2176 | } else { | 2254 | } else { |
2177 | /* New variable. Expand the array if necessary. */ | 2255 | /* New variable. Expand if necessary. */ |
2178 | if (i >= (*envsizep) - 1) { | 2256 | if (i >= (*envsizep) - 1) { |
2179 | (*envsizep) += 50; | 2257 | (*envsizep) += 50; |
2180 | env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *)); | 2258 | env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *)); |
@@ -2202,40 +2280,27 @@ read_environment_file(char ***env, unsigned int *envsize, | |||
2202 | char buf[4096]; | 2280 | char buf[4096]; |
2203 | char *cp, *value; | 2281 | char *cp, *value; |
2204 | 2282 | ||
2205 | /* Open the environment file. */ | ||
2206 | f = fopen(filename, "r"); | 2283 | f = fopen(filename, "r"); |
2207 | if (!f) | 2284 | if (!f) |
2208 | return; | 2285 | return; |
2209 | 2286 | ||
2210 | /* Process each line. */ | ||
2211 | while (fgets(buf, sizeof(buf), f)) { | 2287 | while (fgets(buf, sizeof(buf), f)) { |
2212 | /* Skip leading whitespace. */ | 2288 | for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) |
2213 | for (cp = buf; *cp == ' ' || *cp == '\t'; cp++); | 2289 | ; |
2214 | |||
2215 | /* Ignore empty and comment lines. */ | ||
2216 | if (!*cp || *cp == '#' || *cp == '\n') | 2290 | if (!*cp || *cp == '#' || *cp == '\n') |
2217 | continue; | 2291 | continue; |
2218 | |||
2219 | /* Remove newline. */ | ||
2220 | if (strchr(cp, '\n')) | 2292 | if (strchr(cp, '\n')) |
2221 | *strchr(cp, '\n') = '\0'; | 2293 | *strchr(cp, '\n') = '\0'; |
2222 | |||
2223 | /* Find the equals sign. Its lack indicates badly | ||
2224 | formatted line. */ | ||
2225 | value = strchr(cp, '='); | 2294 | value = strchr(cp, '='); |
2226 | if (value == NULL) { | 2295 | if (value == NULL) { |
2227 | fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf); | 2296 | fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf); |
2228 | continue; | 2297 | continue; |
2229 | } | 2298 | } |
2230 | /* Replace the equals sign by nul, and advance value to | 2299 | /* Replace the equals sign by nul, and advance value to the value string. */ |
2231 | the value string. */ | ||
2232 | *value = '\0'; | 2300 | *value = '\0'; |
2233 | value++; | 2301 | value++; |
2234 | |||
2235 | /* Set the value in environment. */ | ||
2236 | child_set_env(env, envsize, cp, value); | 2302 | child_set_env(env, envsize, cp, value); |
2237 | } | 2303 | } |
2238 | |||
2239 | fclose(f); | 2304 | fclose(f); |
2240 | } | 2305 | } |
2241 | 2306 | ||
@@ -2299,8 +2364,10 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
2299 | if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) | 2364 | if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) |
2300 | fatal("Failed to set uids to %d.", (int) pw->pw_uid); | 2365 | fatal("Failed to set uids to %d.", (int) pw->pw_uid); |
2301 | } | 2366 | } |
2302 | /* Get the shell from the password data. An empty shell field is | 2367 | /* |
2303 | legal, and means /bin/sh. */ | 2368 | * Get the shell from the password data. An empty shell field is |
2369 | * legal, and means /bin/sh. | ||
2370 | */ | ||
2304 | shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; | 2371 | shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; |
2305 | 2372 | ||
2306 | #ifdef AFS | 2373 | #ifdef AFS |
@@ -2315,8 +2382,7 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
2315 | } | 2382 | } |
2316 | #endif /* AFS */ | 2383 | #endif /* AFS */ |
2317 | 2384 | ||
2318 | /* Initialize the environment. In the first part we allocate | 2385 | /* Initialize the environment. */ |
2319 | space for all environment variables. */ | ||
2320 | envsize = 100; | 2386 | envsize = 100; |
2321 | env = xmalloc(envsize * sizeof(char *)); | 2387 | env = xmalloc(envsize * sizeof(char *)); |
2322 | env[0] = NULL; | 2388 | env[0] = NULL; |
@@ -2335,7 +2401,6 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
2335 | /* Normal systems set SHELL by default. */ | 2401 | /* Normal systems set SHELL by default. */ |
2336 | child_set_env(&env, &envsize, "SHELL", shell); | 2402 | child_set_env(&env, &envsize, "SHELL", shell); |
2337 | } | 2403 | } |
2338 | /* Let it inherit timezone if we have one. */ | ||
2339 | if (getenv("TZ")) | 2404 | if (getenv("TZ")) |
2340 | child_set_env(&env, &envsize, "TZ", getenv("TZ")); | 2405 | child_set_env(&env, &envsize, "TZ", getenv("TZ")); |
2341 | 2406 | ||
@@ -2354,20 +2419,14 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
2354 | xfree(ce); | 2419 | xfree(ce); |
2355 | } | 2420 | } |
2356 | 2421 | ||
2357 | /* Set SSH_CLIENT. */ | ||
2358 | snprintf(buf, sizeof buf, "%.50s %d %d", | 2422 | snprintf(buf, sizeof buf, "%.50s %d %d", |
2359 | get_remote_ipaddr(), get_remote_port(), options.port); | 2423 | get_remote_ipaddr(), get_remote_port(), options.port); |
2360 | child_set_env(&env, &envsize, "SSH_CLIENT", buf); | 2424 | child_set_env(&env, &envsize, "SSH_CLIENT", buf); |
2361 | 2425 | ||
2362 | /* Set SSH_TTY if we have a pty. */ | ||
2363 | if (ttyname) | 2426 | if (ttyname) |
2364 | child_set_env(&env, &envsize, "SSH_TTY", ttyname); | 2427 | child_set_env(&env, &envsize, "SSH_TTY", ttyname); |
2365 | |||
2366 | /* Set TERM if we have a pty. */ | ||
2367 | if (term) | 2428 | if (term) |
2368 | child_set_env(&env, &envsize, "TERM", term); | 2429 | child_set_env(&env, &envsize, "TERM", term); |
2369 | |||
2370 | /* Set DISPLAY if we have one. */ | ||
2371 | if (display) | 2430 | if (display) |
2372 | child_set_env(&env, &envsize, "DISPLAY", display); | 2431 | child_set_env(&env, &envsize, "DISPLAY", display); |
2373 | 2432 | ||
@@ -2400,52 +2459,57 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
2400 | } | 2459 | } |
2401 | #endif /* HAVE_LIBPAM */ | 2460 | #endif /* HAVE_LIBPAM */ |
2402 | 2461 | ||
2403 | /* Set XAUTHORITY to always be a local file. */ | ||
2404 | if (xauthfile) | 2462 | if (xauthfile) |
2405 | child_set_env(&env, &envsize, "XAUTHORITY", xauthfile); | 2463 | child_set_env(&env, &envsize, "XAUTHORITY", xauthfile); |
2406 | 2464 | ||
2407 | /* Set variable for forwarded authentication connection, if we | ||
2408 | have one. */ | ||
2409 | if (auth_get_socket_name() != NULL) | 2465 | if (auth_get_socket_name() != NULL) |
2410 | child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, | 2466 | child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, |
2411 | auth_get_socket_name()); | 2467 | auth_get_socket_name()); |
2412 | 2468 | ||
2413 | /* Read $HOME/.ssh/environment. */ | 2469 | /* read $HOME/.ssh/environment. */ |
2414 | if (!options.use_login) { | 2470 | if (!options.use_login) { |
2415 | snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir); | 2471 | snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir); |
2416 | read_environment_file(&env, &envsize, buf); | 2472 | read_environment_file(&env, &envsize, buf); |
2417 | } | 2473 | } |
2418 | /* If debugging, dump the environment to stderr. */ | ||
2419 | if (debug_flag) { | 2474 | if (debug_flag) { |
2475 | /* dump the environment */ | ||
2420 | fprintf(stderr, "Environment:\n"); | 2476 | fprintf(stderr, "Environment:\n"); |
2421 | for (i = 0; env[i]; i++) | 2477 | for (i = 0; env[i]; i++) |
2422 | fprintf(stderr, " %.200s\n", env[i]); | 2478 | fprintf(stderr, " %.200s\n", env[i]); |
2423 | } | 2479 | } |
2424 | /* Close the connection descriptors; note that this is the child, | 2480 | /* |
2425 | and the server will still have the socket open, and it is | 2481 | * Close the connection descriptors; note that this is the child, and |
2426 | important that we do not shutdown it. Note that the | 2482 | * the server will still have the socket open, and it is important |
2427 | descriptors cannot be closed before building the environment, | 2483 | * that we do not shutdown it. Note that the descriptors cannot be |
2428 | as we call get_remote_ipaddr there. */ | 2484 | * closed before building the environment, as we call |
2485 | * get_remote_ipaddr there. | ||
2486 | */ | ||
2429 | if (packet_get_connection_in() == packet_get_connection_out()) | 2487 | if (packet_get_connection_in() == packet_get_connection_out()) |
2430 | close(packet_get_connection_in()); | 2488 | close(packet_get_connection_in()); |
2431 | else { | 2489 | else { |
2432 | close(packet_get_connection_in()); | 2490 | close(packet_get_connection_in()); |
2433 | close(packet_get_connection_out()); | 2491 | close(packet_get_connection_out()); |
2434 | } | 2492 | } |
2435 | /* Close all descriptors related to channels. They will still | 2493 | /* |
2436 | remain open in the parent. */ | 2494 | * Close all descriptors related to channels. They will still remain |
2495 | * open in the parent. | ||
2496 | */ | ||
2497 | /* XXX better use close-on-exec? -markus */ | ||
2437 | channel_close_all(); | 2498 | channel_close_all(); |
2438 | 2499 | ||
2439 | /* Close any extra file descriptors. Note that there may still be | 2500 | /* |
2440 | descriptors left by system functions. They will be closed | 2501 | * Close any extra file descriptors. Note that there may still be |
2441 | later. */ | 2502 | * descriptors left by system functions. They will be closed later. |
2503 | */ | ||
2442 | endpwent(); | 2504 | endpwent(); |
2443 | endhostent(); | 2505 | endhostent(); |
2444 | 2506 | ||
2445 | /* Close any extra open file descriptors so that we don\'t have | 2507 | /* |
2446 | them hanging around in clients. Note that we want to do this | 2508 | * Close any extra open file descriptors so that we don\'t have them |
2447 | after initgroups, because at least on Solaris 2.3 it leaves | 2509 | * hanging around in clients. Note that we want to do this after |
2448 | file descriptors open. */ | 2510 | * initgroups, because at least on Solaris 2.3 it leaves file |
2511 | * descriptors open. | ||
2512 | */ | ||
2449 | for (i = 3; i < 64; i++) | 2513 | for (i = 3; i < 64; i++) |
2450 | close(i); | 2514 | close(i); |
2451 | 2515 | ||
@@ -2454,12 +2518,16 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
2454 | fprintf(stderr, "Could not chdir to home directory %s: %s\n", | 2518 | fprintf(stderr, "Could not chdir to home directory %s: %s\n", |
2455 | pw->pw_dir, strerror(errno)); | 2519 | pw->pw_dir, strerror(errno)); |
2456 | 2520 | ||
2457 | /* Must take new environment into use so that .ssh/rc, /etc/sshrc | 2521 | /* |
2458 | and xauth are run in the proper environment. */ | 2522 | * Must take new environment into use so that .ssh/rc, /etc/sshrc and |
2523 | * xauth are run in the proper environment. | ||
2524 | */ | ||
2459 | environ = env; | 2525 | environ = env; |
2460 | 2526 | ||
2461 | /* Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found | 2527 | /* |
2462 | first in this order). */ | 2528 | * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first |
2529 | * in this order). | ||
2530 | */ | ||
2463 | if (!options.use_login) { | 2531 | if (!options.use_login) { |
2464 | if (stat(SSH_USER_RC, &st) >= 0) { | 2532 | if (stat(SSH_USER_RC, &st) >= 0) { |
2465 | if (debug_flag) | 2533 | if (debug_flag) |
@@ -2486,8 +2554,7 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
2486 | } | 2554 | } |
2487 | #ifdef XAUTH_PATH | 2555 | #ifdef XAUTH_PATH |
2488 | else { | 2556 | else { |
2489 | /* Add authority data to .Xauthority if | 2557 | /* Add authority data to .Xauthority if appropriate. */ |
2490 | appropriate. */ | ||
2491 | if (auth_proto != NULL && auth_data != NULL) { | 2558 | if (auth_proto != NULL && auth_data != NULL) { |
2492 | if (debug_flag) | 2559 | if (debug_flag) |
2493 | fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n", | 2560 | fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n", |
@@ -2510,15 +2577,19 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
2510 | else | 2577 | else |
2511 | cp = shell; | 2578 | cp = shell; |
2512 | } | 2579 | } |
2513 | /* If we have no command, execute the shell. In this case, the | 2580 | /* |
2514 | shell name to be passed in argv[0] is preceded by '-' to | 2581 | * If we have no command, execute the shell. In this case, the shell |
2515 | indicate that this is a login shell. */ | 2582 | * name to be passed in argv[0] is preceded by '-' to indicate that |
2583 | * this is a login shell. | ||
2584 | */ | ||
2516 | if (!command) { | 2585 | if (!command) { |
2517 | if (!options.use_login) { | 2586 | if (!options.use_login) { |
2518 | char buf[256]; | 2587 | char buf[256]; |
2519 | 2588 | ||
2520 | /* Check for mail if we have a tty and it was | 2589 | /* |
2521 | enabled in server options. */ | 2590 | * Check for mail if we have a tty and it was enabled |
2591 | * in server options. | ||
2592 | */ | ||
2522 | if (ttyname && options.check_mail) { | 2593 | if (ttyname && options.check_mail) { |
2523 | char *mailbox; | 2594 | char *mailbox; |
2524 | struct stat mailstat; | 2595 | struct stat mailstat; |
@@ -2558,8 +2629,10 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
2558 | exit(1); | 2629 | exit(1); |
2559 | } | 2630 | } |
2560 | } | 2631 | } |
2561 | /* Execute the command using the user's shell. This uses the -c | 2632 | /* |
2562 | option to execute the command. */ | 2633 | * Execute the command using the user's shell. This uses the -c |
2634 | * option to execute the command. | ||
2635 | */ | ||
2563 | argv[0] = (char *) cp; | 2636 | argv[0] = (char *) cp; |
2564 | argv[1] = "-c"; | 2637 | argv[1] = "-c"; |
2565 | argv[2] = (char *) command; | 2638 | argv[2] = (char *) command; |