diff options
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | pty.c | 32 | ||||
-rw-r--r-- | pty.h | 4 | ||||
-rw-r--r-- | sshd.c | 102 |
4 files changed, 80 insertions, 59 deletions
@@ -5,6 +5,7 @@ | |||
5 | - Rewrote OpenSSL detection code. Now uses AC_TRY_RUN with a test program | 5 | - Rewrote OpenSSL detection code. Now uses AC_TRY_RUN with a test program |
6 | to detect library and header location _and_ ensure library has proper | 6 | to detect library and header location _and_ ensure library has proper |
7 | RSA support built in (this is a problem with OpenSSL 0.9.5). | 7 | RSA support built in (this is a problem with OpenSSL 0.9.5). |
8 | - Applied pty cleanup patch from markus.friedl@informatik.uni-erlangen.de | ||
8 | 9 | ||
9 | 20000207 | 10 | 20000207 |
10 | - Removed SOCKS code. Will support through a ProxyCommand. | 11 | - Removed SOCKS code. Will support through a ProxyCommand. |
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "includes.h" | 16 | #include "includes.h" |
17 | RCSID("$Id: pty.c,v 1.11 1999/12/21 00:18:08 damien Exp $"); | 17 | RCSID("$Id: pty.c,v 1.12 2000/03/02 12:30:53 damien Exp $"); |
18 | 18 | ||
19 | #ifdef HAVE_UTIL_H | 19 | #ifdef HAVE_UTIL_H |
20 | # include <util.h> | 20 | # include <util.h> |
@@ -188,9 +188,9 @@ void | |||
188 | pty_release(const char *ttyname) | 188 | pty_release(const char *ttyname) |
189 | { | 189 | { |
190 | if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0) | 190 | if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0) |
191 | debug("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno)); | 191 | error("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno)); |
192 | if (chmod(ttyname, (mode_t) 0666) < 0) | 192 | if (chmod(ttyname, (mode_t) 0666) < 0) |
193 | debug("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); | 193 | error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); |
194 | } | 194 | } |
195 | 195 | ||
196 | /* Makes the tty the processes controlling tty and sets it to sane modes. */ | 196 | /* Makes the tty the processes controlling tty and sets it to sane modes. */ |
@@ -259,3 +259,29 @@ pty_change_window_size(int ptyfd, int row, int col, | |||
259 | w.ws_ypixel = ypixel; | 259 | w.ws_ypixel = ypixel; |
260 | (void) ioctl(ptyfd, TIOCSWINSZ, &w); | 260 | (void) ioctl(ptyfd, TIOCSWINSZ, &w); |
261 | } | 261 | } |
262 | |||
263 | void | ||
264 | pty_setowner(struct passwd *pw, const char *ttyname) | ||
265 | { | ||
266 | struct group *grp; | ||
267 | gid_t gid; | ||
268 | mode_t mode; | ||
269 | |||
270 | /* Determine the group to make the owner of the tty. */ | ||
271 | grp = getgrnam("tty"); | ||
272 | if (grp) { | ||
273 | gid = grp->gr_gid; | ||
274 | mode = S_IRUSR | S_IWUSR | S_IWGRP; | ||
275 | } else { | ||
276 | gid = pw->pw_gid; | ||
277 | mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; | ||
278 | } | ||
279 | |||
280 | /* Change ownership of the tty. */ | ||
281 | if (chown(ttyname, pw->pw_uid, gid) < 0) | ||
282 | fatal("chown(%.100s, %d, %d) failed: %.100s", | ||
283 | ttyname, pw->pw_uid, gid, strerror(errno)); | ||
284 | if (chmod(ttyname, mode) < 0) | ||
285 | fatal("chmod(%.100s, 0%o) failed: %.100s", | ||
286 | ttyname, mode, strerror(errno)); | ||
287 | } | ||
@@ -13,7 +13,7 @@ | |||
13 | * tty. | 13 | * tty. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | /* RCSID("$Id: pty.h,v 1.4 1999/12/07 04:38:32 damien Exp $"); */ | 16 | /* RCSID("$Id: pty.h,v 1.5 2000/03/02 12:30:53 damien Exp $"); */ |
17 | 17 | ||
18 | #ifndef PTY_H | 18 | #ifndef PTY_H |
19 | #define PTY_H | 19 | #define PTY_H |
@@ -43,4 +43,6 @@ void | |||
43 | pty_change_window_size(int ptyfd, int row, int col, | 43 | pty_change_window_size(int ptyfd, int row, int col, |
44 | int xpixel, int ypixel); | 44 | int xpixel, int ypixel); |
45 | 45 | ||
46 | void pty_setowner(struct passwd *pw, const char *ttyname); | ||
47 | |||
46 | #endif /* PTY_H */ | 48 | #endif /* PTY_H */ |
@@ -1622,6 +1622,37 @@ xauthfile_cleanup_proc(void *ignore) | |||
1622 | } | 1622 | } |
1623 | } | 1623 | } |
1624 | 1624 | ||
1625 | struct pty_cleanup_context { | ||
1626 | const char *ttyname; | ||
1627 | int pid; | ||
1628 | }; | ||
1629 | |||
1630 | /* | ||
1631 | * Function to perform cleanup if we get aborted abnormally (e.g., due to a | ||
1632 | * dropped connection). | ||
1633 | */ | ||
1634 | void | ||
1635 | pty_cleanup_proc(void *context) | ||
1636 | { | ||
1637 | struct pty_cleanup_context *cu = context; | ||
1638 | |||
1639 | debug("pty_cleanup_proc called"); | ||
1640 | |||
1641 | /* Record that the user has logged out. */ | ||
1642 | record_logout(cu->pid, cu->ttyname); | ||
1643 | |||
1644 | /* Release the pseudo-tty. */ | ||
1645 | pty_release(cu->ttyname); | ||
1646 | } | ||
1647 | |||
1648 | /* simple cleanup: chown tty slave back to root */ | ||
1649 | static void | ||
1650 | pty_release_proc(void *tty) | ||
1651 | { | ||
1652 | char *ttyname = tty; | ||
1653 | pty_release(ttyname); | ||
1654 | } | ||
1655 | |||
1625 | /* | 1656 | /* |
1626 | * Prepares for an interactive session. This is called after the user has | 1657 | * Prepares for an interactive session. This is called after the user has |
1627 | * been successfully authenticated. During this message exchange, pseudo | 1658 | * been successfully authenticated. During this message exchange, pseudo |
@@ -1636,11 +1667,7 @@ do_authenticated(struct passwd * pw) | |||
1636 | int have_pty = 0, ptyfd = -1, ttyfd = -1, xauthfd = -1; | 1667 | int have_pty = 0, ptyfd = -1, ttyfd = -1, xauthfd = -1; |
1637 | int row, col, xpixel, ypixel, screen; | 1668 | int row, col, xpixel, ypixel, screen; |
1638 | char ttyname[64]; | 1669 | char ttyname[64]; |
1639 | char *command, *term = NULL, *display = NULL, *proto = NULL, | 1670 | char *command, *term = NULL, *display = NULL, *proto = NULL, *data = NULL; |
1640 | *data = NULL; | ||
1641 | struct group *grp; | ||
1642 | gid_t tty_gid; | ||
1643 | mode_t tty_mode; | ||
1644 | int n_bytes; | 1671 | int n_bytes; |
1645 | 1672 | ||
1646 | /* | 1673 | /* |
@@ -1698,33 +1725,20 @@ do_authenticated(struct passwd * pw) | |||
1698 | error("Failed to allocate pty."); | 1725 | error("Failed to allocate pty."); |
1699 | goto fail; | 1726 | goto fail; |
1700 | } | 1727 | } |
1701 | /* Determine the group to make the owner of the tty. */ | 1728 | fatal_add_cleanup(pty_release_proc, (void *)ttyname); |
1702 | grp = getgrnam("tty"); | 1729 | pty_setowner(pw, ttyname); |
1703 | if (grp) { | ||
1704 | tty_gid = grp->gr_gid; | ||
1705 | tty_mode = S_IRUSR | S_IWUSR | S_IWGRP; | ||
1706 | } else { | ||
1707 | tty_gid = pw->pw_gid; | ||
1708 | tty_mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; | ||
1709 | } | ||
1710 | |||
1711 | /* Change ownership of the tty. */ | ||
1712 | if (chown(ttyname, pw->pw_uid, tty_gid) < 0) | ||
1713 | fatal("chown(%.100s, %d, %d) failed: %.100s", | ||
1714 | ttyname, pw->pw_uid, tty_gid, strerror(errno)); | ||
1715 | if (chmod(ttyname, tty_mode) < 0) | ||
1716 | fatal("chmod(%.100s, 0%o) failed: %.100s", | ||
1717 | ttyname, tty_mode, strerror(errno)); | ||
1718 | 1730 | ||
1719 | /* Get TERM from the packet. Note that the value may be of arbitrary length. */ | 1731 | /* Get TERM from the packet. Note that the value may be of arbitrary length. */ |
1720 | term = packet_get_string(&dlen); | 1732 | term = packet_get_string(&dlen); |
1721 | packet_integrity_check(dlen, strlen(term), type); | 1733 | packet_integrity_check(dlen, strlen(term), type); |
1722 | /* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */ | 1734 | |
1723 | /* Remaining bytes */ | 1735 | /* Remaining bytes */ |
1724 | n_bytes = plen - (4 + dlen + 4 * 4); | 1736 | n_bytes = plen - (4 + dlen + 4 * 4); |
1725 | 1737 | ||
1726 | if (strcmp(term, "") == 0) | 1738 | if (strcmp(term, "") == 0) { |
1739 | xfree(term); | ||
1727 | term = NULL; | 1740 | term = NULL; |
1741 | } | ||
1728 | 1742 | ||
1729 | /* Get window size from the packet. */ | 1743 | /* Get window size from the packet. */ |
1730 | row = packet_get_int(); | 1744 | row = packet_get_int(); |
@@ -1998,29 +2012,6 @@ do_exec_no_pty(const char *command, struct passwd * pw, | |||
1998 | #endif /* USE_PIPES */ | 2012 | #endif /* USE_PIPES */ |
1999 | } | 2013 | } |
2000 | 2014 | ||
2001 | struct pty_cleanup_context { | ||
2002 | const char *ttyname; | ||
2003 | int pid; | ||
2004 | }; | ||
2005 | |||
2006 | /* | ||
2007 | * Function to perform cleanup if we get aborted abnormally (e.g., due to a | ||
2008 | * dropped connection). | ||
2009 | */ | ||
2010 | void | ||
2011 | pty_cleanup_proc(void *context) | ||
2012 | { | ||
2013 | struct pty_cleanup_context *cu = context; | ||
2014 | |||
2015 | debug("pty_cleanup_proc called"); | ||
2016 | |||
2017 | /* Record that the user has logged out. */ | ||
2018 | record_logout(cu->pid, cu->ttyname); | ||
2019 | |||
2020 | /* Release the pseudo-tty. */ | ||
2021 | pty_release(cu->ttyname); | ||
2022 | } | ||
2023 | |||
2024 | /* | 2015 | /* |
2025 | * This is called to fork and execute a command when we have a tty. This | 2016 | * This is called to fork and execute a command when we have a tty. This |
2026 | * will call do_child from the child, and server_loop from the parent after | 2017 | * will call do_child from the child, and server_loop from the parent after |
@@ -2167,6 +2158,15 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, | |||
2167 | close(ttyfd); | 2158 | close(ttyfd); |
2168 | 2159 | ||
2169 | /* | 2160 | /* |
2161 | * Add a cleanup function to clear the utmp entry and record logout | ||
2162 | * time in case we call fatal() (e.g., the connection gets closed). | ||
2163 | */ | ||
2164 | cleanup_context.pid = pid; | ||
2165 | cleanup_context.ttyname = ttyname; | ||
2166 | fatal_add_cleanup(pty_cleanup_proc, (void *) &cleanup_context); | ||
2167 | fatal_remove_cleanup(pty_release_proc, (void *) ttyname); | ||
2168 | |||
2169 | /* | ||
2170 | * Create another descriptor of the pty master side for use as the | 2170 | * Create another descriptor of the pty master side for use as the |
2171 | * standard input. We could use the original descriptor, but this | 2171 | * standard input. We could use the original descriptor, but this |
2172 | * simplifies code in server_loop. The descriptor is bidirectional. | 2172 | * simplifies code in server_loop. The descriptor is bidirectional. |
@@ -2175,14 +2175,6 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, | |||
2175 | if (fdout < 0) | 2175 | if (fdout < 0) |
2176 | packet_disconnect("dup failed: %.100s", strerror(errno)); | 2176 | packet_disconnect("dup failed: %.100s", strerror(errno)); |
2177 | 2177 | ||
2178 | /* | ||
2179 | * Add a cleanup function to clear the utmp entry and record logout | ||
2180 | * time in case we call fatal() (e.g., the connection gets closed). | ||
2181 | */ | ||
2182 | cleanup_context.pid = pid; | ||
2183 | cleanup_context.ttyname = ttyname; | ||
2184 | fatal_add_cleanup(pty_cleanup_proc, (void *) &cleanup_context); | ||
2185 | |||
2186 | /* Enter interactive session. */ | 2178 | /* Enter interactive session. */ |
2187 | server_loop(pid, ptyfd, fdout, -1); | 2179 | server_loop(pid, ptyfd, fdout, -1); |
2188 | /* server_loop has not closed ptyfd and fdout. */ | 2180 | /* server_loop has not closed ptyfd and fdout. */ |