summaryrefslogtreecommitdiff
path: root/session.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2010-03-31 10:46:28 +0100
committerColin Watson <cjwatson@debian.org>2010-03-31 10:46:28 +0100
commitefd3d4522636ae029488c2e9730b60c88e257d2e (patch)
tree31e02ac3f16090ce8c53448677356b2b7f423683 /session.c
parentbbec4db36d464ea1d464a707625125f9fd5c7b5e (diff)
parentd1a87e462e1db89f19cd960588d0c6b287cb5ccc (diff)
* New upstream release (LP: #535029).
- After a transition period of about 10 years, this release disables SSH protocol 1 by default. Clients and servers that need to use the legacy protocol must explicitly enable it in ssh_config / sshd_config or on the command-line. - Remove the libsectok/OpenSC-based smartcard code and add support for PKCS#11 tokens. This support is enabled by default in the Debian packaging, since it now doesn't involve additional library dependencies (closes: #231472, LP: #16918). - Add support for certificate authentication of users and hosts using a new, minimal OpenSSH certificate format (closes: #482806). - Added a 'netcat mode' to ssh(1): "ssh -W host:port ...". - Add the ability to revoke keys in sshd(8) and ssh(1). (For the Debian package, this overlaps with the key blacklisting facility added in openssh 1:4.7p1-9, but with different file formats and slightly different scopes; for the moment, I've roughly merged the two.) - Various multiplexing improvements, including support for requesting port-forwardings via the multiplex protocol (closes: #360151). - Allow setting an explicit umask on the sftp-server(8) commandline to override whatever default the user has (closes: #496843). - Many sftp client improvements, including tab-completion, more options, and recursive transfer support for get/put (LP: #33378). The old mget/mput commands never worked properly and have been removed (closes: #270399, #428082). - Do not prompt for a passphrase if we fail to open a keyfile, and log the reason why the open failed to debug (closes: #431538). - Prevent sftp from crashing when given a "-" without a command. Also, allow whitespace to follow a "-" (closes: #531561).
Diffstat (limited to 'session.c')
-rw-r--r--session.c106
1 files changed, 70 insertions, 36 deletions
diff --git a/session.c b/session.c
index 44e0ac5fa..e032de692 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
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/* 2/*
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved 4 * All rights reserved
@@ -142,9 +142,10 @@ static int sessions_first_unused = -1;
142static int sessions_nalloc = 0; 142static int sessions_nalloc = 0;
143static Session *sessions = NULL; 143static Session *sessions = NULL;
144 144
145#define SUBSYSTEM_NONE 0 145#define SUBSYSTEM_NONE 0
146#define SUBSYSTEM_EXT 1 146#define SUBSYSTEM_EXT 1
147#define SUBSYSTEM_INT_SFTP 2 147#define SUBSYSTEM_INT_SFTP 2
148#define SUBSYSTEM_INT_SFTP_ERROR 3
148 149
149#ifdef HAVE_LOGIN_CAP 150#ifdef HAVE_LOGIN_CAP
150login_cap_t *lc; 151login_cap_t *lc;
@@ -270,6 +271,8 @@ do_authenticated(Authctxt *authctxt)
270 if (!no_port_forwarding_flag && options.allow_tcp_forwarding) 271 if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
271 channel_permit_all_opens(); 272 channel_permit_all_opens();
272 273
274 auth_debug_send();
275
273 if (compat20) 276 if (compat20)
274 do_authenticated2(authctxt); 277 do_authenticated2(authctxt);
275 else 278 else
@@ -785,17 +788,19 @@ do_exec(Session *s, const char *command)
785 if (options.adm_forced_command) { 788 if (options.adm_forced_command) {
786 original_command = command; 789 original_command = command;
787 command = options.adm_forced_command; 790 command = options.adm_forced_command;
788 if (IS_INTERNAL_SFTP(command)) 791 if (IS_INTERNAL_SFTP(command)) {
789 s->is_subsystem = SUBSYSTEM_INT_SFTP; 792 s->is_subsystem = s->is_subsystem ?
790 else if (s->is_subsystem) 793 SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
794 } else if (s->is_subsystem)
791 s->is_subsystem = SUBSYSTEM_EXT; 795 s->is_subsystem = SUBSYSTEM_EXT;
792 debug("Forced command (config) '%.900s'", command); 796 debug("Forced command (config) '%.900s'", command);
793 } else if (forced_command) { 797 } else if (forced_command) {
794 original_command = command; 798 original_command = command;
795 command = forced_command; 799 command = forced_command;
796 if (IS_INTERNAL_SFTP(command)) 800 if (IS_INTERNAL_SFTP(command)) {
797 s->is_subsystem = SUBSYSTEM_INT_SFTP; 801 s->is_subsystem = s->is_subsystem ?
798 else if (s->is_subsystem) 802 SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
803 } else if (s->is_subsystem)
799 s->is_subsystem = SUBSYSTEM_EXT; 804 s->is_subsystem = SUBSYSTEM_EXT;
800 debug("Forced command (key option) '%.900s'", command); 805 debug("Forced command (key option) '%.900s'", command);
801 } 806 }
@@ -1374,26 +1379,32 @@ static void
1374do_nologin(struct passwd *pw) 1379do_nologin(struct passwd *pw)
1375{ 1380{
1376 FILE *f = NULL; 1381 FILE *f = NULL;
1377 char buf[1024]; 1382 char buf[1024], *nl, *def_nl = _PATH_NOLOGIN;
1383 struct stat sb;
1378 1384
1379#ifdef HAVE_LOGIN_CAP 1385#ifdef HAVE_LOGIN_CAP
1380 if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) 1386 if (login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
1381 f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN, 1387 return;
1382 _PATH_NOLOGIN), "r"); 1388 nl = login_getcapstr(lc, "nologin", def_nl, def_nl);
1383#else 1389#else
1384 if (pw->pw_uid) 1390 if (pw->pw_uid == 0)
1385 f = fopen(_PATH_NOLOGIN, "r"); 1391 return;
1392 nl = def_nl;
1386#endif 1393#endif
1387 if (f) { 1394 if (stat(nl, &sb) == -1) {
1388 /* /etc/nologin exists. Print its contents and exit. */ 1395 if (nl != def_nl)
1389 logit("User %.100s not allowed because %s exists", 1396 xfree(nl);
1390 pw->pw_name, _PATH_NOLOGIN); 1397 return;
1391 while (fgets(buf, sizeof(buf), f))
1392 fputs(buf, stderr);
1393 fclose(f);
1394 fflush(NULL);
1395 exit(254);
1396 } 1398 }
1399
1400 /* /etc/nologin exists. Print its contents if we can and exit. */
1401 logit("User %.100s not allowed because %s exists", pw->pw_name, nl);
1402 if ((f = fopen(nl, "r")) != NULL) {
1403 while (fgets(buf, sizeof(buf), f))
1404 fputs(buf, stderr);
1405 fclose(f);
1406 }
1407 exit(254);
1397} 1408}
1398 1409
1399/* 1410/*
@@ -1521,6 +1532,24 @@ do_setusercontext(struct passwd *pw)
1521 } 1532 }
1522# endif /* USE_LIBIAF */ 1533# endif /* USE_LIBIAF */
1523#endif 1534#endif
1535#ifdef HAVE_SETPCRED
1536 /*
1537 * If we have a chroot directory, we set all creds except real
1538 * uid which we will need for chroot. If we don't have a
1539 * chroot directory, we don't override anything.
1540 */
1541 {
1542 char **creds = NULL, *chroot_creds[] =
1543 { "REAL_USER=root", NULL };
1544
1545 if (options.chroot_directory != NULL &&
1546 strcasecmp(options.chroot_directory, "none") != 0)
1547 creds = chroot_creds;
1548
1549 if (setpcred(pw->pw_name, creds) == -1)
1550 fatal("Failed to set process credentials");
1551 }
1552#endif /* HAVE_SETPCRED */
1524 1553
1525#ifdef WITH_SELINUX 1554#ifdef WITH_SELINUX
1526 ssh_selinux_setup_exec_context(pw->pw_name); 1555 ssh_selinux_setup_exec_context(pw->pw_name);
@@ -1537,10 +1566,6 @@ do_setusercontext(struct passwd *pw)
1537 free(chroot_path); 1566 free(chroot_path);
1538 } 1567 }
1539 1568
1540#ifdef HAVE_SETPCRED
1541 if (setpcred(pw->pw_name, (char **)NULL) == -1)
1542 fatal("Failed to set process credentials");
1543#endif /* HAVE_SETPCRED */
1544#ifdef HAVE_LOGIN_CAP 1569#ifdef HAVE_LOGIN_CAP
1545 if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) { 1570 if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
1546 perror("unable to set user context (setuser)"); 1571 perror("unable to set user context (setuser)");
@@ -1783,7 +1808,11 @@ do_child(Session *s, const char *command)
1783 /* restore SIGPIPE for child */ 1808 /* restore SIGPIPE for child */
1784 signal(SIGPIPE, SIG_DFL); 1809 signal(SIGPIPE, SIG_DFL);
1785 1810
1786 if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { 1811 if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) {
1812 printf("This service allows sftp connections only.\n");
1813 fflush(NULL);
1814 exit(1);
1815 } else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) {
1787 extern int optind, optreset; 1816 extern int optind, optreset;
1788 int i; 1817 int i;
1789 char *p, *args; 1818 char *p, *args;
@@ -1796,9 +1825,14 @@ do_child(Session *s, const char *command)
1796 argv[i] = NULL; 1825 argv[i] = NULL;
1797 optind = optreset = 1; 1826 optind = optreset = 1;
1798 __progname = argv[0]; 1827 __progname = argv[0];
1828#ifdef WITH_SELINUX
1829 ssh_selinux_change_context("sftpd_t");
1830#endif
1799 exit(sftp_server_main(i, argv, s->pw)); 1831 exit(sftp_server_main(i, argv, s->pw));
1800 } 1832 }
1801 1833
1834 fflush(NULL);
1835
1802 if (options.use_login) { 1836 if (options.use_login) {
1803 launch_login(pw, hostname); 1837 launch_login(pw, hostname);
1804 /* NEVERREACHED */ 1838 /* NEVERREACHED */
@@ -2109,16 +2143,16 @@ session_subsystem_req(Session *s)
2109 if (strcmp(subsys, options.subsystem_name[i]) == 0) { 2143 if (strcmp(subsys, options.subsystem_name[i]) == 0) {
2110 prog = options.subsystem_command[i]; 2144 prog = options.subsystem_command[i];
2111 cmd = options.subsystem_args[i]; 2145 cmd = options.subsystem_args[i];
2112 if (!strcmp(INTERNAL_SFTP_NAME, prog)) { 2146 if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) {
2113 s->is_subsystem = SUBSYSTEM_INT_SFTP; 2147 s->is_subsystem = SUBSYSTEM_INT_SFTP;
2114 } else if (stat(prog, &st) < 0) { 2148 debug("subsystem: %s", prog);
2115 error("subsystem: cannot stat %s: %s", prog,
2116 strerror(errno));
2117 break;
2118 } else { 2149 } else {
2150 if (stat(prog, &st) < 0)
2151 debug("subsystem: cannot stat %s: %s",
2152 prog, strerror(errno));
2119 s->is_subsystem = SUBSYSTEM_EXT; 2153 s->is_subsystem = SUBSYSTEM_EXT;
2154 debug("subsystem: exec() %s", cmd);
2120 } 2155 }
2121 debug("subsystem: exec() %s", cmd);
2122 success = do_exec(s, cmd) == 0; 2156 success = do_exec(s, cmd) == 0;
2123 break; 2157 break;
2124 } 2158 }