summaryrefslogtreecommitdiff
path: root/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'session.c')
-rw-r--r--session.c240
1 files changed, 148 insertions, 92 deletions
diff --git a/session.c b/session.c
index 58826db16..f2cf52006 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.c,v 1.294 2018/03/03 03:15:51 djm Exp $ */ 1/* $OpenBSD: session.c,v 1.305 2018/07/25 13:56:23 deraadt 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
@@ -69,12 +69,13 @@
69#include "ssh2.h" 69#include "ssh2.h"
70#include "sshpty.h" 70#include "sshpty.h"
71#include "packet.h" 71#include "packet.h"
72#include "buffer.h" 72#include "sshbuf.h"
73#include "ssherr.h"
73#include "match.h" 74#include "match.h"
74#include "uidswap.h" 75#include "uidswap.h"
75#include "compat.h" 76#include "compat.h"
76#include "channels.h" 77#include "channels.h"
77#include "key.h" 78#include "sshkey.h"
78#include "cipher.h" 79#include "cipher.h"
79#ifdef GSSAPI 80#ifdef GSSAPI
80#include "ssh-gss.h" 81#include "ssh-gss.h"
@@ -139,7 +140,7 @@ extern int debug_flag;
139extern u_int utmp_len; 140extern u_int utmp_len;
140extern int startup_pipe; 141extern int startup_pipe;
141extern void destroy_sensitive_data(void); 142extern void destroy_sensitive_data(void);
142extern Buffer loginmsg; 143extern struct sshbuf *loginmsg;
143extern struct sshauthopt *auth_opts; 144extern struct sshauthopt *auth_opts;
144char *tun_fwd_ifnames; /* serverloop.c */ 145char *tun_fwd_ifnames; /* serverloop.c */
145 146
@@ -248,11 +249,14 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
248static void 249static void
249display_loginmsg(void) 250display_loginmsg(void)
250{ 251{
251 if (buffer_len(&loginmsg) > 0) { 252 int r;
252 buffer_append(&loginmsg, "\0", 1); 253
253 printf("%s", (char *)buffer_ptr(&loginmsg)); 254 if (sshbuf_len(loginmsg) == 0)
254 buffer_clear(&loginmsg); 255 return;
255 } 256 if ((r = sshbuf_put_u8(loginmsg, 0)) != 0)
257 fatal("%s: buffer error: %s", __func__, ssh_err(r));
258 printf("%s", (char *)sshbuf_ptr(loginmsg));
259 sshbuf_reset(loginmsg);
256} 260}
257 261
258static void 262static void
@@ -290,26 +294,43 @@ prepare_auth_info_file(struct passwd *pw, struct sshbuf *info)
290} 294}
291 295
292static void 296static void
293set_permitopen_from_authopts(struct ssh *ssh, const struct sshauthopt *opts) 297set_fwdpermit_from_authopts(struct ssh *ssh, const struct sshauthopt *opts)
294{ 298{
295 char *tmp, *cp, *host; 299 char *tmp, *cp, *host;
296 int port; 300 int port;
297 size_t i; 301 size_t i;
298 302
299 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) 303 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0) {
300 return; 304 channel_clear_permission(ssh, FORWARD_USER, FORWARD_LOCAL);
301 channel_clear_permitted_opens(ssh); 305 for (i = 0; i < auth_opts->npermitopen; i++) {
302 for (i = 0; i < auth_opts->npermitopen; i++) { 306 tmp = cp = xstrdup(auth_opts->permitopen[i]);
303 tmp = cp = xstrdup(auth_opts->permitopen[i]); 307 /* This shouldn't fail as it has already been checked */
304 /* This shouldn't fail as it has already been checked */ 308 if ((host = hpdelim(&cp)) == NULL)
305 if ((host = hpdelim(&cp)) == NULL) 309 fatal("%s: internal error: hpdelim", __func__);
306 fatal("%s: internal error: hpdelim", __func__); 310 host = cleanhostname(host);
307 host = cleanhostname(host); 311 if (cp == NULL || (port = permitopen_port(cp)) < 0)
308 if (cp == NULL || (port = permitopen_port(cp)) < 0) 312 fatal("%s: internal error: permitopen port",
309 fatal("%s: internal error: permitopen port", 313 __func__);
310 __func__); 314 channel_add_permission(ssh,
311 channel_add_permitted_opens(ssh, host, port); 315 FORWARD_USER, FORWARD_LOCAL, host, port);
312 free(tmp); 316 free(tmp);
317 }
318 }
319 if ((options.allow_tcp_forwarding & FORWARD_REMOTE) != 0) {
320 channel_clear_permission(ssh, FORWARD_USER, FORWARD_REMOTE);
321 for (i = 0; i < auth_opts->npermitlisten; i++) {
322 tmp = cp = xstrdup(auth_opts->permitlisten[i]);
323 /* This shouldn't fail as it has already been checked */
324 if ((host = hpdelim(&cp)) == NULL)
325 fatal("%s: internal error: hpdelim", __func__);
326 host = cleanhostname(host);
327 if (cp == NULL || (port = permitopen_port(cp)) < 0)
328 fatal("%s: internal error: permitlisten port",
329 __func__);
330 channel_add_permission(ssh,
331 FORWARD_USER, FORWARD_REMOTE, host, port);
332 free(tmp);
333 }
313 } 334 }
314} 335}
315 336
@@ -322,14 +343,22 @@ do_authenticated(struct ssh *ssh, Authctxt *authctxt)
322 343
323 /* setup the channel layer */ 344 /* setup the channel layer */
324 /* XXX - streamlocal? */ 345 /* XXX - streamlocal? */
325 set_permitopen_from_authopts(ssh, auth_opts); 346 set_fwdpermit_from_authopts(ssh, auth_opts);
326 if (!auth_opts->permit_port_forwarding_flag ||
327 options.disable_forwarding ||
328 (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
329 channel_disable_adm_local_opens(ssh);
330 else
331 channel_permit_all_opens(ssh);
332 347
348 if (!auth_opts->permit_port_forwarding_flag ||
349 options.disable_forwarding) {
350 channel_disable_admin(ssh, FORWARD_LOCAL);
351 channel_disable_admin(ssh, FORWARD_REMOTE);
352 } else {
353 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
354 channel_disable_admin(ssh, FORWARD_LOCAL);
355 else
356 channel_permit_all(ssh, FORWARD_LOCAL);
357 if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0)
358 channel_disable_admin(ssh, FORWARD_REMOTE);
359 else
360 channel_permit_all(ssh, FORWARD_REMOTE);
361 }
333 auth_debug_send(); 362 auth_debug_send();
334 363
335 prepare_auth_info_file(authctxt->pw, authctxt->session_info); 364 prepare_auth_info_file(authctxt->pw, authctxt->session_info);
@@ -349,7 +378,7 @@ xauth_valid_string(const char *s)
349 if (!isalnum((u_char)s[i]) && 378 if (!isalnum((u_char)s[i]) &&
350 s[i] != '.' && s[i] != ':' && s[i] != '/' && 379 s[i] != '.' && s[i] != ':' && s[i] != '/' &&
351 s[i] != '-' && s[i] != '_') 380 s[i] != '-' && s[i] != '_')
352 return 0; 381 return 0;
353 } 382 }
354 return 1; 383 return 1;
355} 384}
@@ -500,7 +529,7 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
500 * it to the user, otherwise multiple sessions may accumulate 529 * it to the user, otherwise multiple sessions may accumulate
501 * multiple copies of the login messages. 530 * multiple copies of the login messages.
502 */ 531 */
503 buffer_clear(&loginmsg); 532 sshbuf_reset(loginmsg);
504 533
505#ifdef USE_PIPES 534#ifdef USE_PIPES
506 /* We are the parent. Close the child sides of the pipes. */ 535 /* We are the parent. Close the child sides of the pipes. */
@@ -732,7 +761,7 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
732 * it to the user, otherwise multiple sessions may accumulate 761 * it to the user, otherwise multiple sessions may accumulate
733 * multiple copies of the login messages. 762 * multiple copies of the login messages.
734 */ 763 */
735 buffer_clear(&loginmsg); 764 sshbuf_reset(loginmsg);
736 765
737 return ret; 766 return ret;
738} 767}
@@ -842,24 +871,26 @@ check_quietlogin(Session *s, const char *command)
842 * into the environment. If the file does not exist, this does nothing. 871 * into the environment. If the file does not exist, this does nothing.
843 * Otherwise, it must consist of empty lines, comments (line starts with '#') 872 * Otherwise, it must consist of empty lines, comments (line starts with '#')
844 * and assignments of the form name=value. No other forms are allowed. 873 * and assignments of the form name=value. No other forms are allowed.
874 * If whitelist is not NULL, then it is interpreted as a pattern list and
875 * only variable names that match it will be accepted.
845 */ 876 */
846static void 877static void
847read_environment_file(char ***env, u_int *envsize, 878read_environment_file(char ***env, u_int *envsize,
848 const char *filename) 879 const char *filename, const char *whitelist)
849{ 880{
850 FILE *f; 881 FILE *f;
851 char buf[4096]; 882 char *line = NULL, *cp, *value;
852 char *cp, *value; 883 size_t linesize = 0;
853 u_int lineno = 0; 884 u_int lineno = 0;
854 885
855 f = fopen(filename, "r"); 886 f = fopen(filename, "r");
856 if (!f) 887 if (!f)
857 return; 888 return;
858 889
859 while (fgets(buf, sizeof(buf), f)) { 890 while (getline(&line, &linesize, f) != -1) {
860 if (++lineno > 1000) 891 if (++lineno > 1000)
861 fatal("Too many lines in environment file %s", filename); 892 fatal("Too many lines in environment file %s", filename);
862 for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) 893 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
863 ; 894 ;
864 if (!*cp || *cp == '#' || *cp == '\n') 895 if (!*cp || *cp == '#' || *cp == '\n')
865 continue; 896 continue;
@@ -878,8 +909,12 @@ read_environment_file(char ***env, u_int *envsize,
878 */ 909 */
879 *value = '\0'; 910 *value = '\0';
880 value++; 911 value++;
912 if (whitelist != NULL &&
913 match_pattern_list(cp, whitelist, 0) != 1)
914 continue;
881 child_set_env(env, envsize, cp, value); 915 child_set_env(env, envsize, cp, value);
882 } 916 }
917 free(line);
883 fclose(f); 918 fclose(f);
884} 919}
885 920
@@ -916,7 +951,8 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
916 * so we use a temporary environment and copy the variables we're 951 * so we use a temporary environment and copy the variables we're
917 * interested in. 952 * interested in.
918 */ 953 */
919 read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login"); 954 read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login",
955 options.permit_user_env_whitelist);
920 956
921 if (tmpenv == NULL) 957 if (tmpenv == NULL)
922 return; 958 return;
@@ -978,7 +1014,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
978 char buf[256]; 1014 char buf[256];
979 size_t n; 1015 size_t n;
980 u_int i, envsize; 1016 u_int i, envsize;
981 char *ocp, *cp, **env, *laddr; 1017 char *ocp, *cp, *value, **env, *laddr;
982 struct passwd *pw = s->pw; 1018 struct passwd *pw = s->pw;
983#if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN) 1019#if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN)
984 char *path = NULL; 1020 char *path = NULL;
@@ -1052,46 +1088,10 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
1052 1088
1053 if (getenv("TZ")) 1089 if (getenv("TZ"))
1054 child_set_env(&env, &envsize, "TZ", getenv("TZ")); 1090 child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1055
1056 /* Set custom environment options from pubkey authentication. */
1057 if (options.permit_user_env) {
1058 for (n = 0 ; n < auth_opts->nenv; n++) {
1059 ocp = xstrdup(auth_opts->env[n]);
1060 cp = strchr(ocp, '=');
1061 if (*cp == '=') {
1062 *cp = '\0';
1063 child_set_env(&env, &envsize, ocp, cp + 1);
1064 }
1065 free(ocp);
1066 }
1067 }
1068
1069 /* SSH_CLIENT deprecated */
1070 snprintf(buf, sizeof buf, "%.50s %d %d",
1071 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
1072 ssh_local_port(ssh));
1073 child_set_env(&env, &envsize, "SSH_CLIENT", buf);
1074
1075 laddr = get_local_ipaddr(packet_get_connection_in());
1076 snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
1077 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
1078 laddr, ssh_local_port(ssh));
1079 free(laddr);
1080 child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
1081
1082 if (tun_fwd_ifnames != NULL)
1083 child_set_env(&env, &envsize, "SSH_TUNNEL", tun_fwd_ifnames);
1084 if (auth_info_file != NULL)
1085 child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file);
1086 if (s->ttyfd != -1)
1087 child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1088 if (s->term) 1091 if (s->term)
1089 child_set_env(&env, &envsize, "TERM", s->term); 1092 child_set_env(&env, &envsize, "TERM", s->term);
1090 if (s->display) 1093 if (s->display)
1091 child_set_env(&env, &envsize, "DISPLAY", s->display); 1094 child_set_env(&env, &envsize, "DISPLAY", s->display);
1092 if (original_command)
1093 child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1094 original_command);
1095 1095
1096 /* 1096 /*
1097 * Since we clear KRB5CCNAME at startup, if it's set now then it 1097 * Since we clear KRB5CCNAME at startup, if it's set now then it
@@ -1111,7 +1111,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
1111 1111
1112 if ((cp = getenv("AUTHSTATE")) != NULL) 1112 if ((cp = getenv("AUTHSTATE")) != NULL)
1113 child_set_env(&env, &envsize, "AUTHSTATE", cp); 1113 child_set_env(&env, &envsize, "AUTHSTATE", cp);
1114 read_environment_file(&env, &envsize, "/etc/environment"); 1114 read_environment_file(&env, &envsize, "/etc/environment",
1115 options.permit_user_env_whitelist);
1115 } 1116 }
1116#endif 1117#endif
1117#ifdef KRB5 1118#ifdef KRB5
@@ -1119,6 +1120,37 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
1119 child_set_env(&env, &envsize, "KRB5CCNAME", 1120 child_set_env(&env, &envsize, "KRB5CCNAME",
1120 s->authctxt->krb5_ccname); 1121 s->authctxt->krb5_ccname);
1121#endif 1122#endif
1123 if (auth_sock_name != NULL)
1124 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1125 auth_sock_name);
1126
1127
1128 /* Set custom environment options from pubkey authentication. */
1129 if (options.permit_user_env) {
1130 for (n = 0 ; n < auth_opts->nenv; n++) {
1131 ocp = xstrdup(auth_opts->env[n]);
1132 cp = strchr(ocp, '=');
1133 if (*cp == '=') {
1134 *cp = '\0';
1135 /* Apply PermitUserEnvironment whitelist */
1136 if (options.permit_user_env_whitelist == NULL ||
1137 match_pattern_list(ocp,
1138 options.permit_user_env_whitelist, 0) == 1)
1139 child_set_env(&env, &envsize,
1140 ocp, cp + 1);
1141 }
1142 free(ocp);
1143 }
1144 }
1145
1146 /* read $HOME/.ssh/environment. */
1147 if (options.permit_user_env) {
1148 snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
1149 pw->pw_dir);
1150 read_environment_file(&env, &envsize, buf,
1151 options.permit_user_env_whitelist);
1152 }
1153
1122#ifdef USE_PAM 1154#ifdef USE_PAM
1123 /* 1155 /*
1124 * Pull in any environment variables that may have 1156 * Pull in any environment variables that may have
@@ -1141,16 +1173,40 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
1141 } 1173 }
1142#endif /* USE_PAM */ 1174#endif /* USE_PAM */
1143 1175
1144 if (auth_sock_name != NULL) 1176 /* Environment specified by admin */
1145 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, 1177 for (i = 0; i < options.num_setenv; i++) {
1146 auth_sock_name); 1178 cp = xstrdup(options.setenv[i]);
1147 1179 if ((value = strchr(cp, '=')) == NULL) {
1148 /* read $HOME/.ssh/environment. */ 1180 /* shouldn't happen; vars are checked in servconf.c */
1149 if (options.permit_user_env) { 1181 fatal("Invalid config SetEnv: %s", options.setenv[i]);
1150 snprintf(buf, sizeof buf, "%.200s/.ssh/environment", 1182 }
1151 strcmp(pw->pw_dir, "/") ? pw->pw_dir : ""); 1183 *value++ = '\0';
1152 read_environment_file(&env, &envsize, buf); 1184 child_set_env(&env, &envsize, cp, value);
1153 } 1185 }
1186
1187 /* SSH_CLIENT deprecated */
1188 snprintf(buf, sizeof buf, "%.50s %d %d",
1189 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
1190 ssh_local_port(ssh));
1191 child_set_env(&env, &envsize, "SSH_CLIENT", buf);
1192
1193 laddr = get_local_ipaddr(packet_get_connection_in());
1194 snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
1195 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
1196 laddr, ssh_local_port(ssh));
1197 free(laddr);
1198 child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
1199
1200 if (tun_fwd_ifnames != NULL)
1201 child_set_env(&env, &envsize, "SSH_TUNNEL", tun_fwd_ifnames);
1202 if (auth_info_file != NULL)
1203 child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file);
1204 if (s->ttyfd != -1)
1205 child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1206 if (original_command)
1207 child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1208 original_command);
1209
1154 if (debug_flag) { 1210 if (debug_flag) {
1155 /* dump the environment */ 1211 /* dump the environment */
1156 fprintf(stderr, "Environment:\n"); 1212 fprintf(stderr, "Environment:\n");
@@ -1324,7 +1380,7 @@ safely_chroot(const char *path, uid_t uid)
1324void 1380void
1325do_setusercontext(struct passwd *pw) 1381do_setusercontext(struct passwd *pw)
1326{ 1382{
1327 char *chroot_path, *tmp; 1383 char uidstr[32], *chroot_path, *tmp;
1328 1384
1329 platform_setusercontext(pw); 1385 platform_setusercontext(pw);
1330 1386
@@ -1356,8 +1412,10 @@ do_setusercontext(struct passwd *pw)
1356 strcasecmp(options.chroot_directory, "none") != 0) { 1412 strcasecmp(options.chroot_directory, "none") != 0) {
1357 tmp = tilde_expand_filename(options.chroot_directory, 1413 tmp = tilde_expand_filename(options.chroot_directory,
1358 pw->pw_uid); 1414 pw->pw_uid);
1415 snprintf(uidstr, sizeof(uidstr), "%llu",
1416 (unsigned long long)pw->pw_uid);
1359 chroot_path = percent_expand(tmp, "h", pw->pw_dir, 1417 chroot_path = percent_expand(tmp, "h", pw->pw_dir,
1360 "u", pw->pw_name, (char *)NULL); 1418 "u", pw->pw_name, "U", uidstr, (char *)NULL);
1361 safely_chroot(chroot_path, pw->pw_uid); 1419 safely_chroot(chroot_path, pw->pw_uid);
1362 free(tmp); 1420 free(tmp);
1363 free(chroot_path); 1421 free(chroot_path);
@@ -1858,7 +1916,6 @@ static int
1858session_pty_req(struct ssh *ssh, Session *s) 1916session_pty_req(struct ssh *ssh, Session *s)
1859{ 1917{
1860 u_int len; 1918 u_int len;
1861 int n_bytes;
1862 1919
1863 if (!auth_opts->permit_pty_flag || !options.permit_tty) { 1920 if (!auth_opts->permit_pty_flag || !options.permit_tty) {
1864 debug("Allocating a pty not permitted for this connection."); 1921 debug("Allocating a pty not permitted for this connection.");
@@ -1893,8 +1950,7 @@ session_pty_req(struct ssh *ssh, Session *s)
1893 } 1950 }
1894 debug("session_pty_req: session %d alloc %s", s->self, s->tty); 1951 debug("session_pty_req: session %d alloc %s", s->self, s->tty);
1895 1952
1896 n_bytes = packet_remaining(); 1953 ssh_tty_parse_modes(ssh, s->ttyfd);
1897 tty_parse_modes(s->ttyfd, &n_bytes);
1898 1954
1899 if (!use_privsep) 1955 if (!use_privsep)
1900 pty_setowner(s->pw, s->tty); 1956 pty_setowner(s->pw, s->tty);