session.c (197679) | session.c (204917) |
---|---|
1/* $OpenBSD: session.c,v 1.246 2009/04/17 19:23:06 stevesk Exp $ */ | 1/* $OpenBSD: session.c,v 1.252 2010/03/07 11:57:13 dtucker Exp $ */ |
2/* 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * 6 * As far as I am concerned, the code I have written for this software 7 * can be used freely for any purpose. Any derived versions of this 8 * software must be clearly marked as such, and if the derived work is 9 * incompatible with the protocol description in the RFC file, it must be --- 19 unchanged lines hidden (view full) --- 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36#include "includes.h" | 2/* 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * 6 * As far as I am concerned, the code I have written for this software 7 * can be used freely for any purpose. Any derived versions of this 8 * software must be clearly marked as such, and if the derived work is 9 * incompatible with the protocol description in the RFC file, it must be --- 19 unchanged lines hidden (view full) --- 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36#include "includes.h" |
37__RCSID("$FreeBSD: head/crypto/openssh/session.c 197679 2009-10-01 17:12:52Z des $"); | 37__RCSID("$FreeBSD: head/crypto/openssh/session.c 204917 2010-03-09 19:16:43Z des $"); |
38 39#include <sys/types.h> 40#include <sys/param.h> 41#ifdef HAVE_SYS_STAT_H 42# include <sys/stat.h> 43#endif 44#include <sys/socket.h> 45#include <sys/un.h> --- 92 unchanged lines hidden (view full) --- 138/* original command from peer. */ 139const char *original_command = NULL; 140 141/* data */ 142static int sessions_first_unused = -1; 143static int sessions_nalloc = 0; 144static Session *sessions = NULL; 145 | 38 39#include <sys/types.h> 40#include <sys/param.h> 41#ifdef HAVE_SYS_STAT_H 42# include <sys/stat.h> 43#endif 44#include <sys/socket.h> 45#include <sys/un.h> --- 92 unchanged lines hidden (view full) --- 138/* original command from peer. */ 139const char *original_command = NULL; 140 141/* data */ 142static int sessions_first_unused = -1; 143static int sessions_nalloc = 0; 144static Session *sessions = NULL; 145 |
146#define SUBSYSTEM_NONE 0 147#define SUBSYSTEM_EXT 1 148#define SUBSYSTEM_INT_SFTP 2 | 146#define SUBSYSTEM_NONE 0 147#define SUBSYSTEM_EXT 1 148#define SUBSYSTEM_INT_SFTP 2 149#define SUBSYSTEM_INT_SFTP_ERROR 3 |
149 150#ifdef HAVE_LOGIN_CAP 151login_cap_t *lc; 152#endif 153 154static int is_child = 0; 155 156/* Name and directory of socket for authentication agent forwarding. */ --- 109 unchanged lines hidden (view full) --- 266do_authenticated(Authctxt *authctxt) 267{ 268 setproctitle("%s", authctxt->pw->pw_name); 269 270 /* setup the channel layer */ 271 if (!no_port_forwarding_flag && options.allow_tcp_forwarding) 272 channel_permit_all_opens(); 273 | 150 151#ifdef HAVE_LOGIN_CAP 152login_cap_t *lc; 153#endif 154 155static int is_child = 0; 156 157/* Name and directory of socket for authentication agent forwarding. */ --- 109 unchanged lines hidden (view full) --- 267do_authenticated(Authctxt *authctxt) 268{ 269 setproctitle("%s", authctxt->pw->pw_name); 270 271 /* setup the channel layer */ 272 if (!no_port_forwarding_flag && options.allow_tcp_forwarding) 273 channel_permit_all_opens(); 274 |
275 auth_debug_send(); 276 |
|
274 if (compat20) 275 do_authenticated2(authctxt); 276 else 277 do_authenticated1(authctxt); 278 279 do_cleanup(authctxt); 280} 281 --- 499 unchanged lines hidden (view full) --- 781int 782do_exec(Session *s, const char *command) 783{ 784 int ret; 785 786 if (options.adm_forced_command) { 787 original_command = command; 788 command = options.adm_forced_command; | 277 if (compat20) 278 do_authenticated2(authctxt); 279 else 280 do_authenticated1(authctxt); 281 282 do_cleanup(authctxt); 283} 284 --- 499 unchanged lines hidden (view full) --- 784int 785do_exec(Session *s, const char *command) 786{ 787 int ret; 788 789 if (options.adm_forced_command) { 790 original_command = command; 791 command = options.adm_forced_command; |
789 if (IS_INTERNAL_SFTP(command)) 790 s->is_subsystem = SUBSYSTEM_INT_SFTP; 791 else if (s->is_subsystem) | 792 if (IS_INTERNAL_SFTP(command)) { 793 s->is_subsystem = s->is_subsystem ? 794 SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR; 795 } else if (s->is_subsystem) |
792 s->is_subsystem = SUBSYSTEM_EXT; 793 debug("Forced command (config) '%.900s'", command); 794 } else if (forced_command) { 795 original_command = command; 796 command = forced_command; | 796 s->is_subsystem = SUBSYSTEM_EXT; 797 debug("Forced command (config) '%.900s'", command); 798 } else if (forced_command) { 799 original_command = command; 800 command = forced_command; |
797 if (IS_INTERNAL_SFTP(command)) 798 s->is_subsystem = SUBSYSTEM_INT_SFTP; 799 else if (s->is_subsystem) | 801 if (IS_INTERNAL_SFTP(command)) { 802 s->is_subsystem = s->is_subsystem ? 803 SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR; 804 } else if (s->is_subsystem) |
800 s->is_subsystem = SUBSYSTEM_EXT; 801 debug("Forced command (key option) '%.900s'", command); 802 } 803 804#ifdef SSH_AUDIT_EVENTS 805 if (command != NULL) 806 PRIVSEP(audit_run_command(command)); 807 else if (s->ttyfd == -1) { --- 591 unchanged lines hidden (view full) --- 1399 } 1400 } 1401} 1402 1403static void 1404do_nologin(struct passwd *pw) 1405{ 1406 FILE *f = NULL; | 805 s->is_subsystem = SUBSYSTEM_EXT; 806 debug("Forced command (key option) '%.900s'", command); 807 } 808 809#ifdef SSH_AUDIT_EVENTS 810 if (command != NULL) 811 PRIVSEP(audit_run_command(command)); 812 else if (s->ttyfd == -1) { --- 591 unchanged lines hidden (view full) --- 1404 } 1405 } 1406} 1407 1408static void 1409do_nologin(struct passwd *pw) 1410{ 1411 FILE *f = NULL; |
1407 char buf[1024]; | 1412 char buf[1024], *nl, *def_nl = _PATH_NOLOGIN; 1413 struct stat sb; |
1408 1409#ifdef HAVE_LOGIN_CAP | 1414 1415#ifdef HAVE_LOGIN_CAP |
1410 if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) 1411 f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN, 1412 _PATH_NOLOGIN), "r"); | 1416 if (login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) 1417 return; 1418 nl = login_getcapstr(lc, "nologin", def_nl, def_nl); |
1413#else | 1419#else |
1414 if (pw->pw_uid) 1415 f = fopen(_PATH_NOLOGIN, "r"); | 1420 if (pw->pw_uid == 0) 1421 return; 1422 nl = def_nl; |
1416#endif | 1423#endif |
1417 if (f) { 1418 /* /etc/nologin exists. Print its contents and exit. */ 1419 logit("User %.100s not allowed because %s exists", 1420 pw->pw_name, _PATH_NOLOGIN); 1421 while (fgets(buf, sizeof(buf), f)) 1422 fputs(buf, stderr); 1423 fclose(f); 1424 fflush(NULL); 1425 exit(254); | 1424 if (stat(nl, &sb) == -1) { 1425 if (nl != def_nl) 1426 xfree(nl); 1427 return; |
1426 } | 1428 } |
1429 1430 /* /etc/nologin exists. Print its contents if we can and exit. */ 1431 logit("User %.100s not allowed because %s exists", pw->pw_name, nl); 1432 if ((f = fopen(nl, "r")) != NULL) { 1433 while (fgets(buf, sizeof(buf), f)) 1434 fputs(buf, stderr); 1435 fclose(f); 1436 } 1437 exit(254); |
|
1427} 1428 1429/* 1430 * Chroot into a directory after checking it for safety: all path components 1431 * must be root-owned directories with strict permissions. 1432 */ 1433static void 1434safely_chroot(const char *path, uid_t uid) --- 111 unchanged lines hidden (view full) --- 1546 aix_usrinfo(pw); 1547# endif /* _AIX */ 1548# ifdef USE_LIBIAF 1549 if (set_id(pw->pw_name) != 0) { 1550 exit(1); 1551 } 1552# endif /* USE_LIBIAF */ 1553#endif | 1438} 1439 1440/* 1441 * Chroot into a directory after checking it for safety: all path components 1442 * must be root-owned directories with strict permissions. 1443 */ 1444static void 1445safely_chroot(const char *path, uid_t uid) --- 111 unchanged lines hidden (view full) --- 1557 aix_usrinfo(pw); 1558# endif /* _AIX */ 1559# ifdef USE_LIBIAF 1560 if (set_id(pw->pw_name) != 0) { 1561 exit(1); 1562 } 1563# endif /* USE_LIBIAF */ 1564#endif |
1565#ifdef HAVE_SETPCRED 1566 /* 1567 * If we have a chroot directory, we set all creds except real 1568 * uid which we will need for chroot. If we don't have a 1569 * chroot directory, we don't override anything. 1570 */ 1571 { 1572 char **creds = NULL, *chroot_creds[] = 1573 { "REAL_USER=root", NULL }; |
|
1554 | 1574 |
1575 if (options.chroot_directory != NULL && 1576 strcasecmp(options.chroot_directory, "none") != 0) 1577 creds = chroot_creds; 1578 1579 if (setpcred(pw->pw_name, creds) == -1) 1580 fatal("Failed to set process credentials"); 1581 } 1582#endif /* HAVE_SETPCRED */ 1583 |
|
1555 if (options.chroot_directory != NULL && 1556 strcasecmp(options.chroot_directory, "none") != 0) { 1557 tmp = tilde_expand_filename(options.chroot_directory, 1558 pw->pw_uid); 1559 chroot_path = percent_expand(tmp, "h", pw->pw_dir, 1560 "u", pw->pw_name, (char *)NULL); 1561 safely_chroot(chroot_path, pw->pw_uid); 1562 free(tmp); 1563 free(chroot_path); 1564 } 1565 | 1584 if (options.chroot_directory != NULL && 1585 strcasecmp(options.chroot_directory, "none") != 0) { 1586 tmp = tilde_expand_filename(options.chroot_directory, 1587 pw->pw_uid); 1588 chroot_path = percent_expand(tmp, "h", pw->pw_dir, 1589 "u", pw->pw_name, (char *)NULL); 1590 safely_chroot(chroot_path, pw->pw_uid); 1591 free(tmp); 1592 free(chroot_path); 1593 } 1594 |
1566#ifdef HAVE_SETPCRED 1567 if (setpcred(pw->pw_name, (char **)NULL) == -1) 1568 fatal("Failed to set process credentials"); 1569#endif /* HAVE_SETPCRED */ | |
1570#ifdef HAVE_LOGIN_CAP 1571 if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) { 1572 perror("unable to set user context (setuser)"); 1573 exit(1); 1574 } 1575#else 1576 /* Permanently switch to the desired uid. */ 1577 permanently_set_uid(pw); --- 230 unchanged lines hidden (view full) --- 1808 closefrom(STDERR_FILENO + 1); 1809 1810 if (!options.use_login) 1811 do_rc_files(s, shell); 1812 1813 /* restore SIGPIPE for child */ 1814 signal(SIGPIPE, SIG_DFL); 1815 | 1595#ifdef HAVE_LOGIN_CAP 1596 if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) { 1597 perror("unable to set user context (setuser)"); 1598 exit(1); 1599 } 1600#else 1601 /* Permanently switch to the desired uid. */ 1602 permanently_set_uid(pw); --- 230 unchanged lines hidden (view full) --- 1833 closefrom(STDERR_FILENO + 1); 1834 1835 if (!options.use_login) 1836 do_rc_files(s, shell); 1837 1838 /* restore SIGPIPE for child */ 1839 signal(SIGPIPE, SIG_DFL); 1840 |
1816 if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { | 1841 if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) { 1842 printf("This service allows sftp connections only.\n"); 1843 fflush(NULL); 1844 exit(1); 1845 } else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { |
1817 extern int optind, optreset; 1818 int i; 1819 char *p, *args; 1820 1821 setproctitle("%s@%s", s->pw->pw_name, INTERNAL_SFTP_NAME); 1822 args = xstrdup(command ? command : "sftp-server"); 1823 for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " "))) 1824 if (i < ARGV_MAX - 1) 1825 argv[i++] = p; 1826 argv[i] = NULL; 1827 optind = optreset = 1; 1828 __progname = argv[0]; | 1846 extern int optind, optreset; 1847 int i; 1848 char *p, *args; 1849 1850 setproctitle("%s@%s", s->pw->pw_name, INTERNAL_SFTP_NAME); 1851 args = xstrdup(command ? command : "sftp-server"); 1852 for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " "))) 1853 if (i < ARGV_MAX - 1) 1854 argv[i++] = p; 1855 argv[i] = NULL; 1856 optind = optreset = 1; 1857 __progname = argv[0]; |
1858#ifdef WITH_SELINUX 1859 ssh_selinux_change_context("sftpd_t"); 1860#endif |
|
1829 exit(sftp_server_main(i, argv, s->pw)); 1830 } 1831 | 1861 exit(sftp_server_main(i, argv, s->pw)); 1862 } 1863 |
1864 fflush(NULL); 1865 |
|
1832 if (options.use_login) { 1833 launch_login(pw, hostname); 1834 /* NEVERREACHED */ 1835 } 1836 1837 /* Get the last component of the shell name. */ 1838 if ((shell0 = strrchr(shell, '/')) != NULL) 1839 shell0++; --- 294 unchanged lines hidden (view full) --- 2134 2135 packet_check_eom(); 2136 logit("subsystem request for %.100s", subsys); 2137 2138 for (i = 0; i < options.num_subsystems; i++) { 2139 if (strcmp(subsys, options.subsystem_name[i]) == 0) { 2140 prog = options.subsystem_command[i]; 2141 cmd = options.subsystem_args[i]; | 1866 if (options.use_login) { 1867 launch_login(pw, hostname); 1868 /* NEVERREACHED */ 1869 } 1870 1871 /* Get the last component of the shell name. */ 1872 if ((shell0 = strrchr(shell, '/')) != NULL) 1873 shell0++; --- 294 unchanged lines hidden (view full) --- 2168 2169 packet_check_eom(); 2170 logit("subsystem request for %.100s", subsys); 2171 2172 for (i = 0; i < options.num_subsystems; i++) { 2173 if (strcmp(subsys, options.subsystem_name[i]) == 0) { 2174 prog = options.subsystem_command[i]; 2175 cmd = options.subsystem_args[i]; |
2142 if (!strcmp(INTERNAL_SFTP_NAME, prog)) { | 2176 if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) { |
2143 s->is_subsystem = SUBSYSTEM_INT_SFTP; | 2177 s->is_subsystem = SUBSYSTEM_INT_SFTP; |
2144 } else if (stat(prog, &st) < 0) { 2145 error("subsystem: cannot stat %s: %s", prog, 2146 strerror(errno)); 2147 break; | 2178 debug("subsystem: %s", prog); |
2148 } else { | 2179 } else { |
2180 if (stat(prog, &st) < 0) 2181 debug("subsystem: cannot stat %s: %s", 2182 prog, strerror(errno)); |
|
2149 s->is_subsystem = SUBSYSTEM_EXT; | 2183 s->is_subsystem = SUBSYSTEM_EXT; |
2184 debug("subsystem: exec() %s", cmd); |
|
2150 } | 2185 } |
2151 debug("subsystem: exec() %s", cmd); | |
2152 success = do_exec(s, cmd) == 0; 2153 break; 2154 } 2155 } 2156 2157 if (!success) 2158 logit("subsystem request for %.100s failed, subsystem not found", 2159 subsys); --- 622 unchanged lines hidden --- | 2186 success = do_exec(s, cmd) == 0; 2187 break; 2188 } 2189 } 2190 2191 if (!success) 2192 logit("subsystem request for %.100s failed, subsystem not found", 2193 subsys); --- 622 unchanged lines hidden --- |