diff options
Diffstat (limited to 'session.c')
-rw-r--r-- | session.c | 240 |
1 files changed, 148 insertions, 92 deletions
@@ -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; | |||
139 | extern u_int utmp_len; | 140 | extern u_int utmp_len; |
140 | extern int startup_pipe; | 141 | extern int startup_pipe; |
141 | extern void destroy_sensitive_data(void); | 142 | extern void destroy_sensitive_data(void); |
142 | extern Buffer loginmsg; | 143 | extern struct sshbuf *loginmsg; |
143 | extern struct sshauthopt *auth_opts; | 144 | extern struct sshauthopt *auth_opts; |
144 | char *tun_fwd_ifnames; /* serverloop.c */ | 145 | char *tun_fwd_ifnames; /* serverloop.c */ |
145 | 146 | ||
@@ -248,11 +249,14 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw) | |||
248 | static void | 249 | static void |
249 | display_loginmsg(void) | 250 | display_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 | ||
258 | static void | 262 | static void |
@@ -290,26 +294,43 @@ prepare_auth_info_file(struct passwd *pw, struct sshbuf *info) | |||
290 | } | 294 | } |
291 | 295 | ||
292 | static void | 296 | static void |
293 | set_permitopen_from_authopts(struct ssh *ssh, const struct sshauthopt *opts) | 297 | set_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 | */ |
846 | static void | 877 | static void |
847 | read_environment_file(char ***env, u_int *envsize, | 878 | read_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) | |||
1324 | void | 1380 | void |
1325 | do_setusercontext(struct passwd *pw) | 1381 | do_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 | |||
1858 | session_pty_req(struct ssh *ssh, Session *s) | 1916 | session_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); |