summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-08 15:30:59 +1100
committerDamien Miller <djm@mindrot.org>1999-11-08 15:30:59 +1100
commit356a0b004aad93ec570b134664522a3a925ba556 (patch)
tree3c7cddb50f71a838947d5fda204b569d879dc757 /sshd.c
parent0aa8e5395ca08c7fa927bccd8a763edc4ae61f7b (diff)
Lots of changes:
- Removed lots of unnecessary checks from autoconf - Added support and autoconf test for openpty() function (Unix98 pty support) - Fix for scp not finding ssh if not installed as /usr/bin/ssh - Added TODO file - Merged parts of Debian patch From Phil Hands <phil@hands.com>: - Added ssh-askpass program - Added ssh-askpass support to ssh-add.c - Create symlinks for slogin on install - Fix "distclean" target in makefile - Added example for ssh-agent to manpage - Added support for PAM_TEXT_INFO messages - Disable internal /etc/nologin support if PAM enabled - Merged latest OpenBSD CVS changes: - [sshd.c] don't send fail-msg but disconnect if too many authentication failures - [sshd.c] replace assert() with error, fatal or packet_disconnect - [sshd.c] remove unused argument. ok dugsong - [sshd.c] typo - [rsa.c] clear buffers used for encryption. ok: niels - [rsa.c] replace assert() with error, fatal or packet_disconnect - Fixed coredump after merge of OpenBSD rsa.c patch
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c85
1 files changed, 64 insertions, 21 deletions
diff --git a/sshd.c b/sshd.c
index 49456cdb5..6cdcf75ed 100644
--- a/sshd.c
+++ b/sshd.c
@@ -18,7 +18,7 @@ agent connections.
18*/ 18*/
19 19
20#include "includes.h" 20#include "includes.h"
21RCSID("$Id: sshd.c,v 1.10 1999/11/02 08:05:02 damien Exp $"); 21RCSID("$Id: sshd.c,v 1.11 1999/11/08 04:30:59 damien Exp $");
22 22
23#include "xmalloc.h" 23#include "xmalloc.h"
24#include "rsa.h" 24#include "rsa.h"
@@ -142,6 +142,7 @@ static struct pam_conv conv = {
142}; 142};
143struct pam_handle_t *pamh = NULL; 143struct pam_handle_t *pamh = NULL;
144const char *pampasswd = NULL; 144const char *pampasswd = NULL;
145char *pamconv_msg = NULL;
145 146
146static int pamconv(int num_msg, const struct pam_message **msg, 147static int pamconv(int num_msg, const struct pam_message **msg,
147 struct pam_response **resp, void *appdata_ptr) 148 struct pam_response **resp, void *appdata_ptr)
@@ -171,6 +172,26 @@ static int pamconv(int num_msg, const struct pam_message **msg,
171 case PAM_TEXT_INFO: 172 case PAM_TEXT_INFO:
172 reply[count].resp_retcode = PAM_SUCCESS; 173 reply[count].resp_retcode = PAM_SUCCESS;
173 reply[count].resp = xstrdup(""); 174 reply[count].resp = xstrdup("");
175
176 if (msg[count]->msg == NULL) break;
177 debug("Adding PAM message: %s", msg[count]->msg);
178 if (pamconv_msg == NULL)
179 {
180 pamconv_msg = malloc(strlen(msg[count]->msg) + 2);
181
182 if (pamconv_msg == NULL)
183 return PAM_CONV_ERR;
184
185 strncpy(pamconv_msg, msg[count]->msg, strlen(msg[count]->msg));
186 pamconv_msg[strlen(msg[count]->msg)] = '\n';
187 pamconv_msg[strlen(msg[count]->msg) + 1] = '\0';
188 } else
189 {
190 pamconv_msg = realloc(pamconv_msg, strlen(pamconv_msg) + strlen(msg[count]->msg) + 2);
191 strncat(pamconv_msg, msg[count]->msg, strlen(msg[count]->msg));
192 pamconv_msg[strlen(pamconv_msg)] = '\n';
193 pamconv_msg[strlen(pamconv_msg) + 1] = '\0';
194 }
174 break; 195 break;
175 196
176 case PAM_PROMPT_ECHO_ON: 197 case PAM_PROMPT_ECHO_ON:
@@ -964,8 +985,14 @@ void do_connection(int privileged_port)
964 if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) 985 if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0)
965 { 986 {
966 /* Private key has bigger modulus. */ 987 /* Private key has bigger modulus. */
967 assert(BN_num_bits(sensitive_data.private_key->n) >= 988 if (BN_num_bits(sensitive_data.private_key->n) <
968 BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED); 989 BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) {
990 fatal("do_connection: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
991 BN_num_bits(sensitive_data.private_key->n),
992 BN_num_bits(sensitive_data.host_key->n),
993 SSH_KEY_BITS_RESERVED);
994 }
995
969 rsa_private_decrypt(session_key_int, session_key_int, 996 rsa_private_decrypt(session_key_int, session_key_int,
970 sensitive_data.private_key); 997 sensitive_data.private_key);
971 rsa_private_decrypt(session_key_int, session_key_int, 998 rsa_private_decrypt(session_key_int, session_key_int,
@@ -974,9 +1001,13 @@ void do_connection(int privileged_port)
974 else 1001 else
975 { 1002 {
976 /* Host key has bigger modulus (or they are equal). */ 1003 /* Host key has bigger modulus (or they are equal). */
977 assert(BN_num_bits(sensitive_data.host_key->n) >= 1004 if (BN_num_bits(sensitive_data.host_key->n) <
978 BN_num_bits(sensitive_data.private_key->n) + 1005 BN_num_bits(sensitive_data.private_key->n) + SSH_KEY_BITS_RESERVED) {
979 SSH_KEY_BITS_RESERVED); 1006 fatal("do_connection: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d",
1007 BN_num_bits(sensitive_data.host_key->n),
1008 BN_num_bits(sensitive_data.private_key->n),
1009 SSH_KEY_BITS_RESERVED);
1010 }
980 rsa_private_decrypt(session_key_int, session_key_int, 1011 rsa_private_decrypt(session_key_int, session_key_int,
981 sensitive_data.host_key); 1012 sensitive_data.host_key);
982 rsa_private_decrypt(session_key_int, session_key_int, 1013 rsa_private_decrypt(session_key_int, session_key_int,
@@ -994,7 +1025,10 @@ void do_connection(int privileged_port)
994 least significant 256 bits of the integer; the first byte of the 1025 least significant 256 bits of the integer; the first byte of the
995 key is in the highest bits. */ 1026 key is in the highest bits. */
996 BN_mask_bits(session_key_int, sizeof(session_key) * 8); 1027 BN_mask_bits(session_key_int, sizeof(session_key) * 8);
997 assert(BN_num_bytes(session_key_int) == sizeof(session_key)); 1028 if (BN_num_bytes(session_key_int) != sizeof(session_key)){
1029 fatal("do_connection: session_key_int %d != sizeof(session_key) %d",
1030 BN_num_bytes(session_key_int), sizeof(session_key));
1031 }
998 BN_bn2bin(session_key_int, session_key); 1032 BN_bn2bin(session_key_int, session_key);
999 1033
1000 /* Xor the first 16 bytes of the session key with the session id. */ 1034 /* Xor the first 16 bytes of the session key with the session id. */
@@ -1243,7 +1277,7 @@ do_authentication(char *user, int privileged_port)
1243 int dlen; 1277 int dlen;
1244 char *token_string = packet_get_string(&dlen); 1278 char *token_string = packet_get_string(&dlen);
1245 packet_integrity_check(plen, 4 + dlen, type); 1279 packet_integrity_check(plen, 4 + dlen, type);
1246 if (!auth_afs_token(user, pw->pw_uid, token_string)) 1280 if (!auth_afs_token(pw, token_string))
1247 debug("AFS token REFUSED for %s", user); 1281 debug("AFS token REFUSED for %s", user);
1248 xfree(token_string); 1282 xfree(token_string);
1249 continue; 1283 continue;
@@ -1478,15 +1512,15 @@ do_authentication(char *user, int privileged_port)
1478 if (authenticated) 1512 if (authenticated)
1479 break; 1513 break;
1480 1514
1481 /* Send a message indicating that the authentication attempt failed. */
1482 packet_start(SSH_SMSG_FAILURE);
1483 packet_send();
1484 packet_write_wait();
1485
1486 if (++authentication_failures >= MAX_AUTH_FAILURES) { 1515 if (++authentication_failures >= MAX_AUTH_FAILURES) {
1487 packet_disconnect("Too many authentication failures for %.100s from %.200s", 1516 packet_disconnect("Too many authentication failures for %.100s from %.200s",
1488 pw->pw_name, get_canonical_hostname()); 1517 pw->pw_name, get_canonical_hostname());
1489 } 1518 }
1519
1520 /* Send a message indicating that the authentication attempt failed. */
1521 packet_start(SSH_SMSG_FAILURE);
1522 packet_send();
1523 packet_write_wait();
1490 } 1524 }
1491 1525
1492 /* Check if the user is logging in as root and root logins are disallowed. */ 1526 /* Check if the user is logging in as root and root logins are disallowed. */
@@ -1556,16 +1590,16 @@ void eat_packets_and_disconnect(const char *user)
1556 packet_send_debug(skeyinfo); 1590 packet_send_debug(skeyinfo);
1557 } 1591 }
1558#endif /* SKEY */ 1592#endif /* SKEY */
1559 /* Send failure. This should be indistinguishable from a failed
1560 authentication. */
1561 packet_start(SSH_SMSG_FAILURE);
1562 packet_send();
1563 packet_write_wait();
1564 if (++authentication_failures >= MAX_AUTH_FAILURES) 1593 if (++authentication_failures >= MAX_AUTH_FAILURES)
1565 { 1594 {
1566 packet_disconnect("Too many authentication failures for %.100s from %.200s", 1595 packet_disconnect("Too many authentication failures for %.100s from %.200s",
1567 user, get_canonical_hostname()); 1596 user, get_canonical_hostname());
1568 } 1597 }
1598 /* Send failure. This should be indistinguishable from a failed
1599 authentication. */
1600 packet_start(SSH_SMSG_FAILURE);
1601 packet_send();
1602 packet_write_wait();
1569 } 1603 }
1570 /*NOTREACHED*/ 1604 /*NOTREACHED*/
1571 abort(); 1605 abort();
@@ -2049,7 +2083,13 @@ void do_exec_pty(const char *command, int ptyfd, int ttyfd,
2049 /* Check if .hushlogin exists. */ 2083 /* Check if .hushlogin exists. */
2050 snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir); 2084 snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir);
2051 quiet_login = stat(line, &st) >= 0; 2085 quiet_login = stat(line, &st) >= 0;
2052 2086
2087#ifdef HAVE_LIBPAM
2088 /* output the results of the pamconv() */
2089 if (!quiet_login && pamconv_msg != NULL)
2090 fprintf(stderr, pamconv_msg);
2091#endif
2092
2053 /* If the user has logged in before, display the time of last login. 2093 /* If the user has logged in before, display the time of last login.
2054 However, don't display anything extra if a command has been 2094 However, don't display anything extra if a command has been
2055 specified (so that ssh can be used to execute commands on a remote 2095 specified (so that ssh can be used to execute commands on a remote
@@ -2238,6 +2278,7 @@ void do_child(const char *command, struct passwd *pw, const char *term,
2238 struct stat st; 2278 struct stat st;
2239 char *argv[10]; 2279 char *argv[10];
2240 2280
2281#ifndef HAVE_LIBPAM /* pam_nologin handles this */
2241 /* Check /etc/nologin. */ 2282 /* Check /etc/nologin. */
2242 f = fopen("/etc/nologin", "r"); 2283 f = fopen("/etc/nologin", "r");
2243 if (f) 2284 if (f)
@@ -2248,6 +2289,7 @@ void do_child(const char *command, struct passwd *pw, const char *term,
2248 if (pw->pw_uid != 0) 2289 if (pw->pw_uid != 0)
2249 exit(254); 2290 exit(254);
2250 } 2291 }
2292#endif
2251 2293
2252 /* Set uid, gid, and groups. */ 2294 /* Set uid, gid, and groups. */
2253 /* Login(1) does this as well, and it needs uid 0 for the "-h" switch, 2295 /* Login(1) does this as well, and it needs uid 0 for the "-h" switch,
@@ -2387,7 +2429,7 @@ void do_child(const char *command, struct passwd *pw, const char *term,
2387 if (auth_get_socket_name() != NULL) 2429 if (auth_get_socket_name() != NULL)
2388 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, 2430 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
2389 auth_get_socket_name()); 2431 auth_get_socket_name());
2390 2432
2391 /* Read $HOME/.ssh/environment. */ 2433 /* Read $HOME/.ssh/environment. */
2392 if(!options.use_login) { 2434 if(!options.use_login) {
2393 snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir); 2435 snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir);
@@ -2525,6 +2567,7 @@ void do_child(const char *command, struct passwd *pw, const char *term,
2525 } 2567 }
2526 } 2568 }
2527 } 2569 }
2570
2528 /* Start the shell. Set initial character to '-'. */ 2571 /* Start the shell. Set initial character to '-'. */
2529 buf[0] = '-'; 2572 buf[0] = '-';
2530 strncpy(buf + 1, cp, sizeof(buf) - 1); 2573 strncpy(buf + 1, cp, sizeof(buf) - 1);
@@ -2540,7 +2583,7 @@ void do_child(const char *command, struct passwd *pw, const char *term,
2540 } else { 2583 } else {
2541 /* Launch login(1). */ 2584 /* Launch login(1). */
2542 2585
2543 execl("/usr/bin/login", "login", "-h", get_remote_ipaddr(), "-p", "-f", "--", pw->pw_name, NULL); 2586 execl(LOGIN_PROGRAM, "login", "-h", get_remote_ipaddr(), "-p", "-f", "--", pw->pw_name, NULL);
2544 2587
2545 /* Login couldn't be executed, die. */ 2588 /* Login couldn't be executed, die. */
2546 2589