summaryrefslogtreecommitdiff
path: root/session.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2007-06-12 16:16:35 +0000
committerColin Watson <cjwatson@debian.org>2007-06-12 16:16:35 +0000
commitb7e40fa9da0b5491534a429dadb321eab5a77558 (patch)
treebed1da11e9f829925797aa093e379fc0b5868ecd /session.c
parent4f84beedf1005e44ff33c854abd6b711ffc0adb7 (diff)
parent086ea76990b1e6287c24b6db74adffd4605eb3b0 (diff)
* New upstream release (closes: #395507, #397961, #420035). Important
changes not previously backported to 4.3p2: - 4.4/4.4p1 (http://www.openssh.org/txt/release-4.4): + On portable OpenSSH, fix a GSSAPI authentication abort that could be used to determine the validity of usernames on some platforms. + Implemented conditional configuration in sshd_config(5) using the "Match" directive. This allows some configuration options to be selectively overridden if specific criteria (based on user, group, hostname and/or address) are met. So far a useful subset of post-authentication options are supported and more are expected to be added in future releases. + Add support for Diffie-Hellman group exchange key agreement with a final hash of SHA256. + Added a "ForceCommand" directive to sshd_config(5). Similar to the command="..." option accepted in ~/.ssh/authorized_keys, this forces the execution of the specified command regardless of what the user requested. This is very useful in conjunction with the new "Match" option. + Add a "PermitOpen" directive to sshd_config(5). This mirrors the permitopen="..." authorized_keys option, allowing fine-grained control over the port-forwardings that a user is allowed to establish. + Add optional logging of transactions to sftp-server(8). + ssh(1) will now record port numbers for hosts stored in ~/.ssh/known_hosts when a non-standard port has been requested (closes: #50612). + Add an "ExitOnForwardFailure" option to cause ssh(1) to exit (with a non-zero exit code) when requested port forwardings could not be established. + Extend sshd_config(5) "SubSystem" declarations to allow the specification of command-line arguments. + Replacement of all integer overflow susceptible invocations of malloc(3) and realloc(3) with overflow-checking equivalents. + Many manpage fixes and improvements. + Add optional support for OpenSSL hardware accelerators (engines), enabled using the --with-ssl-engine configure option. + Tokens in configuration files may be double-quoted in order to contain spaces (closes: #319639). + Move a debug() call out of a SIGCHLD handler, fixing a hang when the session exits very quickly (closes: #307890). + Fix some incorrect buffer allocation calculations (closes: #410599). + ssh-add doesn't ask for a passphrase if key file permissions are too liberal (closes: #103677). + Likewise, ssh doesn't ask either (closes: #99675). - 4.6/4.6p1 (http://www.openssh.org/txt/release-4.6): + sshd now allows the enabling and disabling of authentication methods on a per user, group, host and network basis via the Match directive in sshd_config. + Fixed an inconsistent check for a terminal when displaying scp progress meter (closes: #257524). + Fix "hang on exit" when background processes are running at the time of exit on a ttyful/login session (closes: #88337). * Update to current GSSAPI patch from http://www.sxw.org.uk/computing/patches/openssh-4.6p1-gsskex-20070312.patch; install ChangeLog.gssapi.
Diffstat (limited to 'session.c')
-rw-r--r--session.c104
1 files changed, 71 insertions, 33 deletions
diff --git a/session.c b/session.c
index 73fcb6453..160cb4ecc 100644
--- a/session.c
+++ b/session.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: session.c,v 1.221 2007/01/21 01:41:54 stevesk Exp $ */
1/* 2/*
2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3 * All rights reserved 4 * All rights reserved
@@ -33,12 +34,35 @@
33 */ 34 */
34 35
35#include "includes.h" 36#include "includes.h"
36RCSID("$OpenBSD: session.c,v 1.191 2005/12/24 02:27:41 djm Exp $");
37 37
38#include <sys/types.h>
39#include <sys/param.h>
40#ifdef HAVE_SYS_STAT_H
41# include <sys/stat.h>
42#endif
43#include <sys/socket.h>
44#include <sys/un.h>
45#include <sys/wait.h>
46
47#include <arpa/inet.h>
48
49#include <errno.h>
50#include <grp.h>
51#ifdef HAVE_PATHS_H
52#include <paths.h>
53#endif
54#include <pwd.h>
55#include <signal.h>
56#include <stdarg.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <string.h>
60#include <unistd.h>
61
62#include "xmalloc.h"
38#include "ssh.h" 63#include "ssh.h"
39#include "ssh1.h" 64#include "ssh1.h"
40#include "ssh2.h" 65#include "ssh2.h"
41#include "xmalloc.h"
42#include "sshpty.h" 66#include "sshpty.h"
43#include "packet.h" 67#include "packet.h"
44#include "buffer.h" 68#include "buffer.h"
@@ -46,7 +70,12 @@ RCSID("$OpenBSD: session.c,v 1.191 2005/12/24 02:27:41 djm Exp $");
46#include "uidswap.h" 70#include "uidswap.h"
47#include "compat.h" 71#include "compat.h"
48#include "channels.h" 72#include "channels.h"
49#include "bufaux.h" 73#include "key.h"
74#include "cipher.h"
75#ifdef GSSAPI
76#include "ssh-gss.h"
77#endif
78#include "hostfile.h"
50#include "auth.h" 79#include "auth.h"
51#include "auth-options.h" 80#include "auth-options.h"
52#include "pathnames.h" 81#include "pathnames.h"
@@ -59,16 +88,10 @@ RCSID("$OpenBSD: session.c,v 1.191 2005/12/24 02:27:41 djm Exp $");
59#include "kex.h" 88#include "kex.h"
60#include "monitor_wrap.h" 89#include "monitor_wrap.h"
61 90
62#include "selinux.h"
63
64#if defined(KRB5) && defined(USE_AFS) 91#if defined(KRB5) && defined(USE_AFS)
65#include <kafs.h> 92#include <kafs.h>
66#endif 93#endif
67 94
68#ifdef GSSAPI
69#include "ssh-gss.h"
70#endif
71
72/* func */ 95/* func */
73 96
74Session *session_new(void); 97Session *session_new(void);
@@ -177,7 +200,7 @@ auth_input_request_forwarding(struct passwd * pw)
177 sunaddr.sun_family = AF_UNIX; 200 sunaddr.sun_family = AF_UNIX;
178 strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path)); 201 strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
179 202
180 if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) 203 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0)
181 packet_disconnect("bind: %.100s", strerror(errno)); 204 packet_disconnect("bind: %.100s", strerror(errno));
182 205
183 /* Restore the privileged uid. */ 206 /* Restore the privileged uid. */
@@ -324,7 +347,11 @@ do_authenticated1(Authctxt *authctxt)
324 break; 347 break;
325 } 348 }
326 debug("Received TCP/IP port forwarding request."); 349 debug("Received TCP/IP port forwarding request.");
327 channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports); 350 if (channel_input_port_forward_request(s->pw->pw_uid == 0,
351 options.gateway_ports) < 0) {
352 debug("Port forwarding failed.");
353 break;
354 }
328 success = 1; 355 success = 1;
329 break; 356 break;
330 357
@@ -634,7 +661,7 @@ do_pre_login(Session *s)
634 fromlen = sizeof(from); 661 fromlen = sizeof(from);
635 if (packet_connection_is_on_socket()) { 662 if (packet_connection_is_on_socket()) {
636 if (getpeername(packet_get_connection_in(), 663 if (getpeername(packet_get_connection_in(),
637 (struct sockaddr *) & from, &fromlen) < 0) { 664 (struct sockaddr *)&from, &fromlen) < 0) {
638 debug("getpeername: %.100s", strerror(errno)); 665 debug("getpeername: %.100s", strerror(errno));
639 cleanup_exit(255); 666 cleanup_exit(255);
640 } 667 }
@@ -653,10 +680,14 @@ do_pre_login(Session *s)
653void 680void
654do_exec(Session *s, const char *command) 681do_exec(Session *s, const char *command)
655{ 682{
656 if (forced_command) { 683 if (options.adm_forced_command) {
684 original_command = command;
685 command = options.adm_forced_command;
686 debug("Forced command (config) '%.900s'", command);
687 } else if (forced_command) {
657 original_command = command; 688 original_command = command;
658 command = forced_command; 689 command = forced_command;
659 debug("Forced command '%.900s'", command); 690 debug("Forced command (key option) '%.900s'", command);
660 } 691 }
661 692
662#ifdef SSH_AUDIT_EVENTS 693#ifdef SSH_AUDIT_EVENTS
@@ -828,7 +859,7 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
828 if (envsize >= 1000) 859 if (envsize >= 1000)
829 fatal("child_set_env: too many env vars"); 860 fatal("child_set_env: too many env vars");
830 envsize += 50; 861 envsize += 50;
831 env = (*envp) = xrealloc(env, envsize * sizeof(char *)); 862 env = (*envp) = xrealloc(env, envsize, sizeof(char *));
832 *envsizep = envsize; 863 *envsizep = envsize;
833 } 864 }
834 /* Need to set the NULL pointer at end of array beyond the new slot. */ 865 /* Need to set the NULL pointer at end of array beyond the new slot. */
@@ -969,12 +1000,15 @@ do_setup_env(Session *s, const char *shell)
969{ 1000{
970 char buf[256]; 1001 char buf[256];
971 u_int i, envsize; 1002 u_int i, envsize;
972 char **env, *laddr, *path = NULL; 1003 char **env, *laddr;
973 struct passwd *pw = s->pw; 1004 struct passwd *pw = s->pw;
1005#ifndef HAVE_LOGIN_CAP
1006 char *path = NULL;
1007#endif
974 1008
975 /* Initialize the environment. */ 1009 /* Initialize the environment. */
976 envsize = 100; 1010 envsize = 100;
977 env = xmalloc(envsize * sizeof(char *)); 1011 env = xcalloc(envsize, sizeof(char *));
978 env[0] = NULL; 1012 env[0] = NULL;
979 1013
980#ifdef HAVE_CYGWIN 1014#ifdef HAVE_CYGWIN
@@ -1343,7 +1377,9 @@ do_setusercontext(struct passwd *pw)
1343 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) 1377 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
1344 fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); 1378 fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
1345 1379
1346 setup_selinux_exec_context(pw->pw_name); 1380#ifdef WITH_SELINUX
1381 ssh_selinux_setup_exec_context(pw->pw_name);
1382#endif
1347} 1383}
1348 1384
1349static void 1385static void
@@ -1563,7 +1599,7 @@ do_child(Session *s, const char *command)
1563 do_rc_files(s, shell); 1599 do_rc_files(s, shell);
1564 1600
1565 /* restore SIGPIPE for child */ 1601 /* restore SIGPIPE for child */
1566 signal(SIGPIPE, SIG_DFL); 1602 signal(SIGPIPE, SIG_DFL);
1567 1603
1568 if (options.use_login) { 1604 if (options.use_login) {
1569 launch_login(pw, hostname); 1605 launch_login(pw, hostname);
@@ -1827,7 +1863,7 @@ session_subsystem_req(Session *s)
1827 struct stat st; 1863 struct stat st;
1828 u_int len; 1864 u_int len;
1829 int success = 0; 1865 int success = 0;
1830 char *cmd, *subsys = packet_get_string(&len); 1866 char *prog, *cmd, *subsys = packet_get_string(&len);
1831 u_int i; 1867 u_int i;
1832 1868
1833 packet_check_eom(); 1869 packet_check_eom();
@@ -1835,9 +1871,10 @@ session_subsystem_req(Session *s)
1835 1871
1836 for (i = 0; i < options.num_subsystems; i++) { 1872 for (i = 0; i < options.num_subsystems; i++) {
1837 if (strcmp(subsys, options.subsystem_name[i]) == 0) { 1873 if (strcmp(subsys, options.subsystem_name[i]) == 0) {
1838 cmd = options.subsystem_command[i]; 1874 prog = options.subsystem_command[i];
1839 if (stat(cmd, &st) < 0) { 1875 cmd = options.subsystem_args[i];
1840 error("subsystem: cannot stat %s: %s", cmd, 1876 if (stat(prog, &st) < 0) {
1877 error("subsystem: cannot stat %s: %s", prog,
1841 strerror(errno)); 1878 strerror(errno));
1842 break; 1879 break;
1843 } 1880 }
@@ -1934,8 +1971,8 @@ session_env_req(Session *s)
1934 for (i = 0; i < options.num_accept_env; i++) { 1971 for (i = 0; i < options.num_accept_env; i++) {
1935 if (match_pattern(name, options.accept_env[i])) { 1972 if (match_pattern(name, options.accept_env[i])) {
1936 debug2("Setting env %d: %s=%s", s->num_env, name, val); 1973 debug2("Setting env %d: %s=%s", s->num_env, name, val);
1937 s->env = xrealloc(s->env, sizeof(*s->env) * 1974 s->env = xrealloc(s->env, s->num_env + 1,
1938 (s->num_env + 1)); 1975 sizeof(*s->env));
1939 s->env[s->num_env].name = name; 1976 s->env[s->num_env].name = name;
1940 s->env[s->num_env].val = val; 1977 s->env[s->num_env].val = val;
1941 s->num_env++; 1978 s->num_env++;
@@ -1990,7 +2027,7 @@ session_input_channel_req(Channel *c, const char *rtype)
1990 } else if (strcmp(rtype, "exec") == 0) { 2027 } else if (strcmp(rtype, "exec") == 0) {
1991 success = session_exec_req(s); 2028 success = session_exec_req(s);
1992 } else if (strcmp(rtype, "pty-req") == 0) { 2029 } else if (strcmp(rtype, "pty-req") == 0) {
1993 success = session_pty_req(s); 2030 success = session_pty_req(s);
1994 } else if (strcmp(rtype, "x11-req") == 0) { 2031 } else if (strcmp(rtype, "x11-req") == 0) {
1995 success = session_x11_req(s); 2032 success = session_x11_req(s);
1996 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { 2033 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
@@ -2115,7 +2152,7 @@ session_close_single_x11(int id, void *arg)
2115 2152
2116 debug3("session_close_single_x11: channel %d", id); 2153 debug3("session_close_single_x11: channel %d", id);
2117 channel_cancel_cleanup(id); 2154 channel_cancel_cleanup(id);
2118 if ((s = session_by_x11_channel(id)) == NULL) 2155 if ((s = session_by_x11_channel(id)) == NULL)
2119 fatal("session_close_single_x11: no x11 channel %d", id); 2156 fatal("session_close_single_x11: no x11 channel %d", id);
2120 for (i = 0; s->x11_chanids[i] != -1; i++) { 2157 for (i = 0; s->x11_chanids[i] != -1; i++) {
2121 debug("session_close_single_x11: session %d: " 2158 debug("session_close_single_x11: session %d: "
@@ -2183,7 +2220,7 @@ session_exit_message(Session *s, int status)
2183 2220
2184 /* 2221 /*
2185 * Adjust cleanup callback attachment to send close messages when 2222 * Adjust cleanup callback attachment to send close messages when
2186 * the channel gets EOF. The session will be then be closed 2223 * the channel gets EOF. The session will be then be closed
2187 * by session_close_by_channel when the childs close their fds. 2224 * by session_close_by_channel when the childs close their fds.
2188 */ 2225 */
2189 channel_register_cleanup(c->self, session_close_by_channel, 1); 2226 channel_register_cleanup(c->self, session_close_by_channel, 1);
@@ -2219,12 +2256,13 @@ session_close(Session *s)
2219 if (s->auth_proto) 2256 if (s->auth_proto)
2220 xfree(s->auth_proto); 2257 xfree(s->auth_proto);
2221 s->used = 0; 2258 s->used = 0;
2222 for (i = 0; i < s->num_env; i++) { 2259 if (s->env != NULL) {
2223 xfree(s->env[i].name); 2260 for (i = 0; i < s->num_env; i++) {
2224 xfree(s->env[i].val); 2261 xfree(s->env[i].name);
2225 } 2262 xfree(s->env[i].val);
2226 if (s->env != NULL) 2263 }
2227 xfree(s->env); 2264 xfree(s->env);
2265 }
2228 session_proctitle(s); 2266 session_proctitle(s);
2229} 2267}
2230 2268