summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-03-09 21:27:49 +1100
committerDamien Miller <djm@mindrot.org>2000-03-09 21:27:49 +1100
commit98c7ad60ec5725d91da9f9f6d26cd9fe477398c0 (patch)
tree104c3e3474be8e308d05e22d79715c833c6cf837 /sshd.c
parent1a07ebd4d8d39c6814bbd84c1aec4ebf2bd005a2 (diff)
- OpenBSD CVS updates to v1.2.3
[ssh.h atomicio.c] - int atomicio -> ssize_t (for alpha). ok deraadt@ [auth-rsa.c] - delay MD5 computation until client sends response, free() early, cleanup. [cipher.c] - void* -> unsigned char*, ok niels@ [hostfile.c] - remove unused variable 'len'. fix comments. - remove unused variable [log-client.c log-server.c] - rename a cpp symbol, to avoid param.h collision [packet.c] - missing xfree() - getsockname() requires initialized tolen; andy@guildsoftware.com - use getpeername() in packet_connection_is_on_socket(), fixes sshd -i; from Holger.Trapp@Informatik.TU-Chemnitz.DE [pty.c pty.h] - register cleanup for pty earlier. move code for pty-owner handling to pty.c ok provos@, dugsong@ [readconf.c] - turn off x11-fwd for the client, too. [rsa.c] - PKCS#1 padding [scp.c] - allow '.' in usernames; from jedgar@fxp.org [servconf.c] - typo: ignore_user_known_hosts int->flag; naddy@mips.rhein-neckar.de - sync with sshd_config [ssh-keygen.c] - enable ssh-keygen -l -f ~/.ssh/known_hosts, ok deraadt@ [ssh.1] - Change invalid 'CHAT' loglevel to 'VERBOSE' [ssh.c] - suppress AAAA query host when '-4' is used; from shin@nd.net.fujitsu.co.jp - turn off x11-fwd for the client, too. [sshconnect.c] - missing xfree() - retry rresvport_af(), too. from sumikawa@ebina.hitachi.co.jp. - read error vs. "Connection closed by remote host" [sshd.8] - ie. -> i.e., - do not link to a commercial page.. - sync with sshd_config [sshd.c] - no need for poll.h; from bright@wintelcom.net - log with level log() not fatal() if peer behaves badly. - don't panic if client behaves strange. ok deraadt@ - make no-port-forwarding for RSA keys deny both -L and -R style fwding - delay close() of pty until the pty has been chowned back to root - oops, fix comment, too. - missing xfree() - move XAUTHORITY to subdir. ok dugsong@. fixes debian bug #57907, too. (http://cgi.debian.org/cgi-bin/bugreport.cgi?archive=no&bug=57907) - register cleanup for pty earlier. move code for pty-owner handling to pty.c ok provos@, dugsong@ - create x11 cookie file - fix pr 1113, fclose() -> pclose(), todo: remote popen() - version 1.2.3 - Cleaned up
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c116
1 files changed, 74 insertions, 42 deletions
diff --git a/sshd.c b/sshd.c
index 0024440ed..829c0a712 100644
--- a/sshd.c
+++ b/sshd.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13#include "includes.h" 13#include "includes.h"
14RCSID("$OpenBSD: sshd.c,v 1.80 2000/01/20 15:19:22 markus Exp $"); 14RCSID("$OpenBSD: sshd.c,v 1.90 2000/03/06 20:29:04 markus Exp $");
15 15
16#include "xmalloc.h" 16#include "xmalloc.h"
17#include "rsa.h" 17#include "rsa.h"
@@ -148,6 +148,27 @@ void do_child(const char *command, struct passwd * pw, const char *term,
148 const char *auth_data, const char *ttyname); 148 const char *auth_data, const char *ttyname);
149 149
150/* 150/*
151 * Remove local Xauthority file.
152 */
153void
154xauthfile_cleanup_proc(void *ignore)
155{
156 debug("xauthfile_cleanup_proc called");
157
158 if (xauthfile != NULL) {
159 char *p;
160 unlink(xauthfile);
161 p = strrchr(xauthfile, '/');
162 if (p != NULL) {
163 *p = '\0';
164 rmdir(xauthfile);
165 }
166 xfree(xauthfile);
167 xauthfile = NULL;
168 }
169}
170
171/*
151 * Close all listening sockets 172 * Close all listening sockets
152 */ 173 */
153void 174void
@@ -234,6 +255,7 @@ grace_alarm_handler(int sig)
234char * 255char *
235get_authname(int type) 256get_authname(int type)
236{ 257{
258 static char buf[1024];
237 switch (type) { 259 switch (type) {
238 case SSH_CMSG_AUTH_PASSWORD: 260 case SSH_CMSG_AUTH_PASSWORD:
239 return "password"; 261 return "password";
@@ -252,8 +274,8 @@ get_authname(int type)
252 return "s/key"; 274 return "s/key";
253#endif 275#endif
254 } 276 }
255 fatal("get_authname: unknown auth %d: internal error", type); 277 snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
256 return NULL; 278 return buf;
257} 279}
258 280
259/* 281/*
@@ -878,7 +900,7 @@ main(int ac, char **av)
878 900
879 /* Cleanup user's local Xauthority file. */ 901 /* Cleanup user's local Xauthority file. */
880 if (xauthfile) 902 if (xauthfile)
881 unlink(xauthfile); 903 xauthfile_cleanup_proc(NULL);
882 904
883 /* The connection has been terminated. */ 905 /* The connection has been terminated. */
884 verbose("Closing connection to %.100s", remote_ip); 906 verbose("Closing connection to %.100s", remote_ip);
@@ -1089,12 +1111,14 @@ do_ssh_kex()
1089 * DenyUsers or user's primary group is listed in DenyGroups, false will 1111 * DenyUsers or user's primary group is listed in DenyGroups, false will
1090 * be returned. If AllowUsers isn't empty and user isn't listed there, or 1112 * be returned. If AllowUsers isn't empty and user isn't listed there, or
1091 * if AllowGroups isn't empty and user isn't listed there, false will be 1113 * if AllowGroups isn't empty and user isn't listed there, false will be
1092 * returned. Otherwise true is returned. 1114 * returned.
1093 * XXX This function should also check if user has a valid shell 1115 * If the user's shell is not executable, false will be returned.
1116 * Otherwise true is returned.
1094 */ 1117 */
1095static int 1118static int
1096allowed_user(struct passwd * pw) 1119allowed_user(struct passwd * pw)
1097{ 1120{
1121 struct stat st;
1098 struct group *grp; 1122 struct group *grp;
1099 int i; 1123 int i;
1100#ifdef WITH_AIXAUTHENTICATE 1124#ifdef WITH_AIXAUTHENTICATE
@@ -1105,7 +1129,11 @@ allowed_user(struct passwd * pw)
1105 if (!pw) 1129 if (!pw)
1106 return 0; 1130 return 0;
1107 1131
1108 /* XXX Should check for valid login shell */ 1132 /* deny if shell does not exists or is not executable */
1133 if (stat(pw->pw_shell, &st) != 0)
1134 return 0;
1135 if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP))))
1136 return 0;
1109 1137
1110 /* Return false if user is listed in DenyUsers */ 1138 /* Return false if user is listed in DenyUsers */
1111 if (options.num_deny_users > 0) { 1139 if (options.num_deny_users > 0) {
@@ -1202,6 +1230,7 @@ do_authentication()
1202 pw = getpwnam(user); 1230 pw = getpwnam(user);
1203 if (!pw || !allowed_user(pw)) 1231 if (!pw || !allowed_user(pw))
1204 do_fake_authloop(user); 1232 do_fake_authloop(user);
1233 xfree(user);
1205 1234
1206 /* Take a copy of the returned structure. */ 1235 /* Take a copy of the returned structure. */
1207 memset(&pwcopy, 0, sizeof(pwcopy)); 1236 memset(&pwcopy, 0, sizeof(pwcopy));
@@ -1224,7 +1253,7 @@ do_authentication()
1224 if (getuid() != 0 && pw->pw_uid != getuid()) 1253 if (getuid() != 0 && pw->pw_uid != getuid())
1225 packet_disconnect("Cannot change user when server not running as root."); 1254 packet_disconnect("Cannot change user when server not running as root.");
1226 1255
1227 debug("Attempting authentication for %.100s.", user); 1256 debug("Attempting authentication for %.100s.", pw->pw_name);
1228 1257
1229 /* If the user has no password, accept authentication immediately. */ 1258 /* If the user has no password, accept authentication immediately. */
1230 if (options.password_authentication && 1259 if (options.password_authentication &&
@@ -1510,17 +1539,22 @@ do_authloop(struct passwd * pw)
1510 get_remote_port(), 1539 get_remote_port(),
1511 user); 1540 user);
1512 1541
1513 if (authenticated) {
1514#ifdef USE_PAM 1542#ifdef USE_PAM
1543 if (authenticated) {
1515 if (!do_pam_account(pw->pw_name, client_user)) { 1544 if (!do_pam_account(pw->pw_name, client_user)) {
1516 if (client_user != NULL) 1545 if (client_user != NULL) {
1517 xfree(client_user); 1546 xfree(client_user);
1518 1547 client_user = NULL;
1548 }
1519 do_fake_authloop(pw->pw_name); 1549 do_fake_authloop(pw->pw_name);
1520 } 1550 }
1521#endif /* USE_PAM */
1522 return; 1551 return;
1523 } 1552 }
1553#else /* USE_PAM */
1554 if (authenticated) {
1555 return;
1556 }
1557#endif /* USE_PAM */
1524 1558
1525 if (client_user != NULL) { 1559 if (client_user != NULL) {
1526 xfree(client_user); 1560 xfree(client_user);
@@ -1572,6 +1606,7 @@ do_fake_authloop(char *user)
1572 /* Try to send a fake s/key challenge. */ 1606 /* Try to send a fake s/key challenge. */
1573 if (options.skey_authentication == 1 && 1607 if (options.skey_authentication == 1 &&
1574 (skeyinfo = skey_fake_keyinfo(user)) != NULL) { 1608 (skeyinfo = skey_fake_keyinfo(user)) != NULL) {
1609 password = NULL;
1575 if (type == SSH_CMSG_AUTH_TIS) { 1610 if (type == SSH_CMSG_AUTH_TIS) {
1576 packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); 1611 packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
1577 packet_put_string(skeyinfo, strlen(skeyinfo)); 1612 packet_put_string(skeyinfo, strlen(skeyinfo));
@@ -1585,6 +1620,8 @@ do_fake_authloop(char *user)
1585 strncasecmp(password, "s/key", 5) == 0 ) { 1620 strncasecmp(password, "s/key", 5) == 0 ) {
1586 packet_send_debug(skeyinfo); 1621 packet_send_debug(skeyinfo);
1587 } 1622 }
1623 if (password != NULL)
1624 xfree(password);
1588 } 1625 }
1589#endif 1626#endif
1590 if (attempt > AUTH_FAIL_MAX) 1627 if (attempt > AUTH_FAIL_MAX)
@@ -1607,22 +1644,6 @@ do_fake_authloop(char *user)
1607 abort(); 1644 abort();
1608} 1645}
1609 1646
1610
1611/*
1612 * Remove local Xauthority file.
1613 */
1614static void
1615xauthfile_cleanup_proc(void *ignore)
1616{
1617 debug("xauthfile_cleanup_proc called");
1618
1619 if (xauthfile != NULL) {
1620 unlink(xauthfile);
1621 xfree(xauthfile);
1622 xauthfile = NULL;
1623 }
1624}
1625
1626struct pty_cleanup_context { 1647struct pty_cleanup_context {
1627 const char *ttyname; 1648 const char *ttyname;
1628 int pid; 1649 int pid;
@@ -1665,7 +1686,7 @@ do_authenticated(struct passwd * pw)
1665{ 1686{
1666 int type; 1687 int type;
1667 int compression_level = 0, enable_compression_after_reply = 0; 1688 int compression_level = 0, enable_compression_after_reply = 0;
1668 int have_pty = 0, ptyfd = -1, ttyfd = -1, xauthfd = -1; 1689 int have_pty = 0, ptyfd = -1, ttyfd = -1;
1669 int row, col, xpixel, ypixel, screen; 1690 int row, col, xpixel, ypixel, screen;
1670 char ttyname[64]; 1691 char ttyname[64];
1671 char *command, *term = NULL, *display = NULL, *proto = NULL, *data = NULL; 1692 char *command, *term = NULL, *display = NULL, *proto = NULL, *data = NULL;
@@ -1684,7 +1705,8 @@ do_authenticated(struct passwd * pw)
1684 * by the client telling us, so we can equally well trust the client 1705 * by the client telling us, so we can equally well trust the client
1685 * not to request anything bogus.) 1706 * not to request anything bogus.)
1686 */ 1707 */
1687 channel_permit_all_opens(); 1708 if (!no_port_forwarding_flag)
1709 channel_permit_all_opens();
1688 1710
1689 /* 1711 /*
1690 * We stay in this loop until the client requests to execute a shell 1712 * We stay in this loop until the client requests to execute a shell
@@ -1785,16 +1807,20 @@ do_authenticated(struct passwd * pw)
1785 1807
1786 /* Setup to always have a local .Xauthority. */ 1808 /* Setup to always have a local .Xauthority. */
1787 xauthfile = xmalloc(MAXPATHLEN); 1809 xauthfile = xmalloc(MAXPATHLEN);
1788 snprintf(xauthfile, MAXPATHLEN, "/tmp/XauthXXXXXX"); 1810 strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
1789 1811 temporarily_use_uid(pw->pw_uid);
1790 if ((xauthfd = mkstemp(xauthfile)) != -1) { 1812 if (mkdtemp(xauthfile) == NULL) {
1791 fchown(xauthfd, pw->pw_uid, pw->pw_gid); 1813 restore_uid();
1792 close(xauthfd); 1814 error("private X11 dir: mkdtemp %s failed: %s",
1793 fatal_add_cleanup(xauthfile_cleanup_proc, NULL); 1815 xauthfile, strerror(errno));
1794 } else {
1795 xfree(xauthfile); 1816 xfree(xauthfile);
1796 xauthfile = NULL; 1817 xauthfile = NULL;
1818 goto fail;
1797 } 1819 }
1820 strlcat(xauthfile, "/cookies", MAXPATHLEN);
1821 open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600);
1822 restore_uid();
1823 fatal_add_cleanup(xauthfile_cleanup_proc, NULL);
1798 break; 1824 break;
1799#else /* XAUTH_PATH */ 1825#else /* XAUTH_PATH */
1800 packet_send_debug("No xauth program; cannot forward with spoofing."); 1826 packet_send_debug("No xauth program; cannot forward with spoofing.");
@@ -2026,6 +2052,7 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
2026 const char *auth_data) 2052 const char *auth_data)
2027{ 2053{
2028 int pid, fdout; 2054 int pid, fdout;
2055 int ptymaster;
2029 const char *hostname; 2056 const char *hostname;
2030 time_t last_login_time; 2057 time_t last_login_time;
2031 char buf[100], *time_string; 2058 char buf[100], *time_string;
@@ -2174,11 +2201,16 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
2174 */ 2201 */
2175 fdout = dup(ptyfd); 2202 fdout = dup(ptyfd);
2176 if (fdout < 0) 2203 if (fdout < 0)
2177 packet_disconnect("dup failed: %.100s", strerror(errno)); 2204 packet_disconnect("dup #1 failed: %.100s", strerror(errno));
2205
2206 /* we keep a reference to the pty master */
2207 ptymaster = dup(ptyfd);
2208 if (ptymaster < 0)
2209 packet_disconnect("dup #2 failed: %.100s", strerror(errno));
2178 2210
2179 /* Enter interactive session. */ 2211 /* Enter interactive session. */
2180 server_loop(pid, ptyfd, fdout, -1); 2212 server_loop(pid, ptyfd, fdout, -1);
2181 /* server_loop has not closed ptyfd and fdout. */ 2213 /* server_loop _has_ closed ptyfd and fdout. */
2182 2214
2183 /* Cancel the cleanup function. */ 2215 /* Cancel the cleanup function. */
2184 fatal_remove_cleanup(pty_cleanup_proc, (void *) &cleanup_context); 2216 fatal_remove_cleanup(pty_cleanup_proc, (void *) &cleanup_context);
@@ -2194,8 +2226,8 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
2194 * the pty cleanup, so that another process doesn't get this pty 2226 * the pty cleanup, so that another process doesn't get this pty
2195 * while we're still cleaning up. 2227 * while we're still cleaning up.
2196 */ 2228 */
2197 close(ptyfd); 2229 if (close(ptymaster) < 0)
2198 close(fdout); 2230 error("close(ptymaster): %s", strerror(errno));
2199} 2231}
2200 2232
2201/* 2233/*
@@ -2563,7 +2595,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
2563 f = popen(XAUTH_PATH " -q -", "w"); 2595 f = popen(XAUTH_PATH " -q -", "w");
2564 if (f) { 2596 if (f) {
2565 fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data); 2597 fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data);
2566 fclose(f); 2598 pclose(f);
2567 } else 2599 } else
2568 fprintf(stderr, "Could not run %s -q -\n", XAUTH_PATH); 2600 fprintf(stderr, "Could not run %s -q -\n", XAUTH_PATH);
2569 } 2601 }