summaryrefslogtreecommitdiff
path: root/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'session.c')
-rw-r--r--session.c104
1 files changed, 73 insertions, 31 deletions
diff --git a/session.c b/session.c
index 0cbd5fbb2..4c97c4a7d 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"
@@ -63,10 +92,6 @@ RCSID("$OpenBSD: session.c,v 1.191 2005/12/24 02:27:41 djm Exp $");
63#include <kafs.h> 92#include <kafs.h>
64#endif 93#endif
65 94
66#ifdef GSSAPI
67#include "ssh-gss.h"
68#endif
69
70/* func */ 95/* func */
71 96
72Session *session_new(void); 97Session *session_new(void);
@@ -175,7 +200,7 @@ auth_input_request_forwarding(struct passwd * pw)
175 sunaddr.sun_family = AF_UNIX; 200 sunaddr.sun_family = AF_UNIX;
176 strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path)); 201 strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
177 202
178 if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) 203 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0)
179 packet_disconnect("bind: %.100s", strerror(errno)); 204 packet_disconnect("bind: %.100s", strerror(errno));
180 205
181 /* Restore the privileged uid. */ 206 /* Restore the privileged uid. */
@@ -322,7 +347,11 @@ do_authenticated1(Authctxt *authctxt)
322 break; 347 break;
323 } 348 }
324 debug("Received TCP/IP port forwarding request."); 349 debug("Received TCP/IP port forwarding request.");
325 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 }
326 success = 1; 355 success = 1;
327 break; 356 break;
328 357
@@ -632,7 +661,7 @@ do_pre_login(Session *s)
632 fromlen = sizeof(from); 661 fromlen = sizeof(from);
633 if (packet_connection_is_on_socket()) { 662 if (packet_connection_is_on_socket()) {
634 if (getpeername(packet_get_connection_in(), 663 if (getpeername(packet_get_connection_in(),
635 (struct sockaddr *) & from, &fromlen) < 0) { 664 (struct sockaddr *)&from, &fromlen) < 0) {
636 debug("getpeername: %.100s", strerror(errno)); 665 debug("getpeername: %.100s", strerror(errno));
637 cleanup_exit(255); 666 cleanup_exit(255);
638 } 667 }
@@ -651,10 +680,14 @@ do_pre_login(Session *s)
651void 680void
652do_exec(Session *s, const char *command) 681do_exec(Session *s, const char *command)
653{ 682{
654 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) {
655 original_command = command; 688 original_command = command;
656 command = forced_command; 689 command = forced_command;
657 debug("Forced command '%.900s'", command); 690 debug("Forced command (key option) '%.900s'", command);
658 } 691 }
659 692
660#ifdef SSH_AUDIT_EVENTS 693#ifdef SSH_AUDIT_EVENTS
@@ -826,7 +859,7 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
826 if (envsize >= 1000) 859 if (envsize >= 1000)
827 fatal("child_set_env: too many env vars"); 860 fatal("child_set_env: too many env vars");
828 envsize += 50; 861 envsize += 50;
829 env = (*envp) = xrealloc(env, envsize * sizeof(char *)); 862 env = (*envp) = xrealloc(env, envsize, sizeof(char *));
830 *envsizep = envsize; 863 *envsizep = envsize;
831 } 864 }
832 /* 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. */
@@ -967,12 +1000,15 @@ do_setup_env(Session *s, const char *shell)
967{ 1000{
968 char buf[256]; 1001 char buf[256];
969 u_int i, envsize; 1002 u_int i, envsize;
970 char **env, *laddr, *path = NULL; 1003 char **env, *laddr;
971 struct passwd *pw = s->pw; 1004 struct passwd *pw = s->pw;
1005#ifndef HAVE_LOGIN_CAP
1006 char *path = NULL;
1007#endif
972 1008
973 /* Initialize the environment. */ 1009 /* Initialize the environment. */
974 envsize = 100; 1010 envsize = 100;
975 env = xmalloc(envsize * sizeof(char *)); 1011 env = xcalloc(envsize, sizeof(char *));
976 env[0] = NULL; 1012 env[0] = NULL;
977 1013
978#ifdef HAVE_CYGWIN 1014#ifdef HAVE_CYGWIN
@@ -1340,6 +1376,10 @@ do_setusercontext(struct passwd *pw)
1340#endif 1376#endif
1341 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) 1377 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
1342 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);
1379
1380#ifdef WITH_SELINUX
1381 ssh_selinux_setup_exec_context(pw->pw_name);
1382#endif
1343} 1383}
1344 1384
1345static void 1385static void
@@ -1559,7 +1599,7 @@ do_child(Session *s, const char *command)
1559 do_rc_files(s, shell); 1599 do_rc_files(s, shell);
1560 1600
1561 /* restore SIGPIPE for child */ 1601 /* restore SIGPIPE for child */
1562 signal(SIGPIPE, SIG_DFL); 1602 signal(SIGPIPE, SIG_DFL);
1563 1603
1564 if (options.use_login) { 1604 if (options.use_login) {
1565 launch_login(pw, hostname); 1605 launch_login(pw, hostname);
@@ -1823,7 +1863,7 @@ session_subsystem_req(Session *s)
1823 struct stat st; 1863 struct stat st;
1824 u_int len; 1864 u_int len;
1825 int success = 0; 1865 int success = 0;
1826 char *cmd, *subsys = packet_get_string(&len); 1866 char *prog, *cmd, *subsys = packet_get_string(&len);
1827 u_int i; 1867 u_int i;
1828 1868
1829 packet_check_eom(); 1869 packet_check_eom();
@@ -1831,9 +1871,10 @@ session_subsystem_req(Session *s)
1831 1871
1832 for (i = 0; i < options.num_subsystems; i++) { 1872 for (i = 0; i < options.num_subsystems; i++) {
1833 if (strcmp(subsys, options.subsystem_name[i]) == 0) { 1873 if (strcmp(subsys, options.subsystem_name[i]) == 0) {
1834 cmd = options.subsystem_command[i]; 1874 prog = options.subsystem_command[i];
1835 if (stat(cmd, &st) < 0) { 1875 cmd = options.subsystem_args[i];
1836 error("subsystem: cannot stat %s: %s", cmd, 1876 if (stat(prog, &st) < 0) {
1877 error("subsystem: cannot stat %s: %s", prog,
1837 strerror(errno)); 1878 strerror(errno));
1838 break; 1879 break;
1839 } 1880 }
@@ -1930,8 +1971,8 @@ session_env_req(Session *s)
1930 for (i = 0; i < options.num_accept_env; i++) { 1971 for (i = 0; i < options.num_accept_env; i++) {
1931 if (match_pattern(name, options.accept_env[i])) { 1972 if (match_pattern(name, options.accept_env[i])) {
1932 debug2("Setting env %d: %s=%s", s->num_env, name, val); 1973 debug2("Setting env %d: %s=%s", s->num_env, name, val);
1933 s->env = xrealloc(s->env, sizeof(*s->env) * 1974 s->env = xrealloc(s->env, s->num_env + 1,
1934 (s->num_env + 1)); 1975 sizeof(*s->env));
1935 s->env[s->num_env].name = name; 1976 s->env[s->num_env].name = name;
1936 s->env[s->num_env].val = val; 1977 s->env[s->num_env].val = val;
1937 s->num_env++; 1978 s->num_env++;
@@ -1986,7 +2027,7 @@ session_input_channel_req(Channel *c, const char *rtype)
1986 } else if (strcmp(rtype, "exec") == 0) { 2027 } else if (strcmp(rtype, "exec") == 0) {
1987 success = session_exec_req(s); 2028 success = session_exec_req(s);
1988 } else if (strcmp(rtype, "pty-req") == 0) { 2029 } else if (strcmp(rtype, "pty-req") == 0) {
1989 success = session_pty_req(s); 2030 success = session_pty_req(s);
1990 } else if (strcmp(rtype, "x11-req") == 0) { 2031 } else if (strcmp(rtype, "x11-req") == 0) {
1991 success = session_x11_req(s); 2032 success = session_x11_req(s);
1992 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { 2033 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
@@ -2111,7 +2152,7 @@ session_close_single_x11(int id, void *arg)
2111 2152
2112 debug3("session_close_single_x11: channel %d", id); 2153 debug3("session_close_single_x11: channel %d", id);
2113 channel_cancel_cleanup(id); 2154 channel_cancel_cleanup(id);
2114 if ((s = session_by_x11_channel(id)) == NULL) 2155 if ((s = session_by_x11_channel(id)) == NULL)
2115 fatal("session_close_single_x11: no x11 channel %d", id); 2156 fatal("session_close_single_x11: no x11 channel %d", id);
2116 for (i = 0; s->x11_chanids[i] != -1; i++) { 2157 for (i = 0; s->x11_chanids[i] != -1; i++) {
2117 debug("session_close_single_x11: session %d: " 2158 debug("session_close_single_x11: session %d: "
@@ -2179,7 +2220,7 @@ session_exit_message(Session *s, int status)
2179 2220
2180 /* 2221 /*
2181 * Adjust cleanup callback attachment to send close messages when 2222 * Adjust cleanup callback attachment to send close messages when
2182 * the channel gets EOF. The session will be then be closed 2223 * the channel gets EOF. The session will be then be closed
2183 * by session_close_by_channel when the childs close their fds. 2224 * by session_close_by_channel when the childs close their fds.
2184 */ 2225 */
2185 channel_register_cleanup(c->self, session_close_by_channel, 1); 2226 channel_register_cleanup(c->self, session_close_by_channel, 1);
@@ -2215,12 +2256,13 @@ session_close(Session *s)
2215 if (s->auth_proto) 2256 if (s->auth_proto)
2216 xfree(s->auth_proto); 2257 xfree(s->auth_proto);
2217 s->used = 0; 2258 s->used = 0;
2218 for (i = 0; i < s->num_env; i++) { 2259 if (s->env != NULL) {
2219 xfree(s->env[i].name); 2260 for (i = 0; i < s->num_env; i++) {
2220 xfree(s->env[i].val); 2261 xfree(s->env[i].name);
2221 } 2262 xfree(s->env[i].val);
2222 if (s->env != NULL) 2263 }
2223 xfree(s->env); 2264 xfree(s->env);
2265 }
2224 session_proctitle(s); 2266 session_proctitle(s);
2225} 2267}
2226 2268
@@ -2436,7 +2478,7 @@ do_cleanup(Authctxt *authctxt)
2436 return; 2478 return;
2437 called = 1; 2479 called = 1;
2438 2480
2439 if (authctxt == NULL) 2481 if (authctxt == NULL || !authctxt->authenticated)
2440 return; 2482 return;
2441#ifdef KRB5 2483#ifdef KRB5
2442 if (options.kerberos_ticket_cleanup && 2484 if (options.kerberos_ticket_cleanup &&