diff options
author | Colin Watson <cjwatson@debian.org> | 2019-06-05 06:41:44 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2019-06-05 06:41:44 +0100 |
commit | 102062f825fb26a74295a1c089c00c4c4c76b68a (patch) | |
tree | 3db66bc8c8483cce66516dff36f6ef56065143d9 /session.c | |
parent | 3d246f10429fc9a37b98eabef94fe8dc7c61002b (diff) | |
parent | fd0fa130ecf06d7d092932adcd5d77f1549bfc8d (diff) |
Import openssh_8.0p1.orig.tar.gz
Diffstat (limited to 'session.c')
-rw-r--r-- | session.c | 217 |
1 files changed, 111 insertions, 106 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: session.c,v 1.307 2018/10/04 00:10:11 djm Exp $ */ | 1 | /* $OpenBSD: session.c,v 1.315 2019/02/22 03:37:11 djm 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 |
@@ -123,9 +123,6 @@ int do_exec_no_pty(struct ssh *, Session *, const char *); | |||
123 | int do_exec(struct ssh *, Session *, const char *); | 123 | int do_exec(struct ssh *, Session *, const char *); |
124 | void do_login(struct ssh *, Session *, const char *); | 124 | void do_login(struct ssh *, Session *, const char *); |
125 | void do_child(struct ssh *, Session *, const char *); | 125 | void do_child(struct ssh *, Session *, const char *); |
126 | #ifdef LOGIN_NEEDS_UTMPX | ||
127 | static void do_pre_login(Session *s); | ||
128 | #endif | ||
129 | void do_motd(void); | 126 | void do_motd(void); |
130 | int check_quietlogin(Session *, const char *); | 127 | int check_quietlogin(Session *, const char *); |
131 | 128 | ||
@@ -142,7 +139,7 @@ extern int startup_pipe; | |||
142 | extern void destroy_sensitive_data(void); | 139 | extern void destroy_sensitive_data(void); |
143 | extern struct sshbuf *loginmsg; | 140 | extern struct sshbuf *loginmsg; |
144 | extern struct sshauthopt *auth_opts; | 141 | extern struct sshauthopt *auth_opts; |
145 | char *tun_fwd_ifnames; /* serverloop.c */ | 142 | extern char *tun_fwd_ifnames; /* serverloop.c */ |
146 | 143 | ||
147 | /* original command from peer. */ | 144 | /* original command from peer. */ |
148 | const char *original_command = NULL; | 145 | const char *original_command = NULL; |
@@ -204,7 +201,7 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw) | |||
204 | 201 | ||
205 | /* Create private directory for socket */ | 202 | /* Create private directory for socket */ |
206 | if (mkdtemp(auth_sock_dir) == NULL) { | 203 | if (mkdtemp(auth_sock_dir) == NULL) { |
207 | packet_send_debug("Agent forwarding disabled: " | 204 | ssh_packet_send_debug(ssh, "Agent forwarding disabled: " |
208 | "mkdtemp() failed: %.100s", strerror(errno)); | 205 | "mkdtemp() failed: %.100s", strerror(errno)); |
209 | restore_uid(); | 206 | restore_uid(); |
210 | free(auth_sock_dir); | 207 | free(auth_sock_dir); |
@@ -236,7 +233,9 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw) | |||
236 | authsock_err: | 233 | authsock_err: |
237 | free(auth_sock_name); | 234 | free(auth_sock_name); |
238 | if (auth_sock_dir != NULL) { | 235 | if (auth_sock_dir != NULL) { |
236 | temporarily_use_uid(pw); | ||
239 | rmdir(auth_sock_dir); | 237 | rmdir(auth_sock_dir); |
238 | restore_uid(); | ||
240 | free(auth_sock_dir); | 239 | free(auth_sock_dir); |
241 | } | 240 | } |
242 | if (sock != -1) | 241 | if (sock != -1) |
@@ -359,7 +358,7 @@ do_authenticated(struct ssh *ssh, Authctxt *authctxt) | |||
359 | else | 358 | else |
360 | channel_permit_all(ssh, FORWARD_REMOTE); | 359 | channel_permit_all(ssh, FORWARD_REMOTE); |
361 | } | 360 | } |
362 | auth_debug_send(); | 361 | auth_debug_send(ssh); |
363 | 362 | ||
364 | prepare_auth_info_file(authctxt->pw, authctxt->session_info); | 363 | prepare_auth_info_file(authctxt->pw, authctxt->session_info); |
365 | 364 | ||
@@ -521,7 +520,7 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command) | |||
521 | 520 | ||
522 | s->pid = pid; | 521 | s->pid = pid; |
523 | /* Set interactive/non-interactive mode. */ | 522 | /* Set interactive/non-interactive mode. */ |
524 | packet_set_interactive(s->display != NULL, | 523 | ssh_packet_set_interactive(ssh, s->display != NULL, |
525 | options.ip_qos_interactive, options.ip_qos_bulk); | 524 | options.ip_qos_interactive, options.ip_qos_bulk); |
526 | 525 | ||
527 | /* | 526 | /* |
@@ -548,7 +547,7 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command) | |||
548 | * Enter the interactive session. Note: server_loop must be able to | 547 | * Enter the interactive session. Note: server_loop must be able to |
549 | * handle the case that fdin and fdout are the same. | 548 | * handle the case that fdin and fdout are the same. |
550 | */ | 549 | */ |
551 | session_set_fds(s, inout[1], inout[1], err[1], | 550 | session_set_fds(ssh, s, inout[1], inout[1], err[1], |
552 | s->is_subsystem, 0); | 551 | s->is_subsystem, 0); |
553 | #endif | 552 | #endif |
554 | return 0; | 553 | return 0; |
@@ -650,41 +649,12 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) | |||
650 | 649 | ||
651 | /* Enter interactive session. */ | 650 | /* Enter interactive session. */ |
652 | s->ptymaster = ptymaster; | 651 | s->ptymaster = ptymaster; |
653 | packet_set_interactive(1, | 652 | ssh_packet_set_interactive(ssh, 1, |
654 | options.ip_qos_interactive, options.ip_qos_bulk); | 653 | options.ip_qos_interactive, options.ip_qos_bulk); |
655 | session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1); | 654 | session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1); |
656 | return 0; | 655 | return 0; |
657 | } | 656 | } |
658 | 657 | ||
659 | #ifdef LOGIN_NEEDS_UTMPX | ||
660 | static void | ||
661 | do_pre_login(Session *s) | ||
662 | { | ||
663 | struct ssh *ssh = active_state; /* XXX */ | ||
664 | socklen_t fromlen; | ||
665 | struct sockaddr_storage from; | ||
666 | pid_t pid = getpid(); | ||
667 | |||
668 | /* | ||
669 | * Get IP address of client. If the connection is not a socket, let | ||
670 | * the address be 0.0.0.0. | ||
671 | */ | ||
672 | memset(&from, 0, sizeof(from)); | ||
673 | fromlen = sizeof(from); | ||
674 | if (packet_connection_is_on_socket()) { | ||
675 | if (getpeername(packet_get_connection_in(), | ||
676 | (struct sockaddr *)&from, &fromlen) < 0) { | ||
677 | debug("getpeername: %.100s", strerror(errno)); | ||
678 | cleanup_exit(255); | ||
679 | } | ||
680 | } | ||
681 | |||
682 | record_utmp_only(pid, s->tty, s->pw->pw_name, | ||
683 | session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns), | ||
684 | (struct sockaddr *)&from, fromlen); | ||
685 | } | ||
686 | #endif | ||
687 | |||
688 | /* | 658 | /* |
689 | * This is called to fork and execute a command. If another command is | 659 | * This is called to fork and execute a command. If another command is |
690 | * to be forced, execute that instead. | 660 | * to be forced, execute that instead. |
@@ -783,8 +753,8 @@ do_login(struct ssh *ssh, Session *s, const char *command) | |||
783 | */ | 753 | */ |
784 | memset(&from, 0, sizeof(from)); | 754 | memset(&from, 0, sizeof(from)); |
785 | fromlen = sizeof(from); | 755 | fromlen = sizeof(from); |
786 | if (packet_connection_is_on_socket()) { | 756 | if (ssh_packet_connection_is_on_socket(ssh)) { |
787 | if (getpeername(packet_get_connection_in(), | 757 | if (getpeername(ssh_packet_get_connection_in(ssh), |
788 | (struct sockaddr *)&from, &fromlen) < 0) { | 758 | (struct sockaddr *)&from, &fromlen) < 0) { |
789 | debug("getpeername: %.100s", strerror(errno)); | 759 | debug("getpeername: %.100s", strerror(errno)); |
790 | cleanup_exit(255); | 760 | cleanup_exit(255); |
@@ -1082,8 +1052,11 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) | |||
1082 | # endif /* HAVE_CYGWIN */ | 1052 | # endif /* HAVE_CYGWIN */ |
1083 | #endif /* HAVE_LOGIN_CAP */ | 1053 | #endif /* HAVE_LOGIN_CAP */ |
1084 | 1054 | ||
1085 | snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name); | 1055 | if (!options.use_pam) { |
1086 | child_set_env(&env, &envsize, "MAIL", buf); | 1056 | snprintf(buf, sizeof buf, "%.200s/%.50s", |
1057 | _PATH_MAILDIR, pw->pw_name); | ||
1058 | child_set_env(&env, &envsize, "MAIL", buf); | ||
1059 | } | ||
1087 | 1060 | ||
1088 | /* Normal systems set SHELL by default. */ | 1061 | /* Normal systems set SHELL by default. */ |
1089 | child_set_env(&env, &envsize, "SHELL", shell); | 1062 | child_set_env(&env, &envsize, "SHELL", shell); |
@@ -1162,15 +1135,18 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) | |||
1162 | char **p; | 1135 | char **p; |
1163 | 1136 | ||
1164 | /* | 1137 | /* |
1165 | * Don't allow SSH_AUTH_INFO variables posted to PAM to leak | 1138 | * Don't allow PAM-internal env vars to leak |
1166 | * back into the environment. | 1139 | * back into the session environment. |
1167 | */ | 1140 | */ |
1141 | #define PAM_ENV_BLACKLIST "SSH_AUTH_INFO*,SSH_CONNECTION*" | ||
1168 | p = fetch_pam_child_environment(); | 1142 | p = fetch_pam_child_environment(); |
1169 | copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*"); | 1143 | copy_environment_blacklist(p, &env, &envsize, |
1144 | PAM_ENV_BLACKLIST); | ||
1170 | free_pam_environment(p); | 1145 | free_pam_environment(p); |
1171 | 1146 | ||
1172 | p = fetch_pam_environment(); | 1147 | p = fetch_pam_environment(); |
1173 | copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*"); | 1148 | copy_environment_blacklist(p, &env, &envsize, |
1149 | PAM_ENV_BLACKLIST); | ||
1174 | free_pam_environment(p); | 1150 | free_pam_environment(p); |
1175 | } | 1151 | } |
1176 | #endif /* USE_PAM */ | 1152 | #endif /* USE_PAM */ |
@@ -1192,7 +1168,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) | |||
1192 | ssh_local_port(ssh)); | 1168 | ssh_local_port(ssh)); |
1193 | child_set_env(&env, &envsize, "SSH_CLIENT", buf); | 1169 | child_set_env(&env, &envsize, "SSH_CLIENT", buf); |
1194 | 1170 | ||
1195 | laddr = get_local_ipaddr(packet_get_connection_in()); | 1171 | laddr = get_local_ipaddr(ssh_packet_get_connection_in(ssh)); |
1196 | snprintf(buf, sizeof buf, "%.50s %d %.50s %d", | 1172 | snprintf(buf, sizeof buf, "%.50s %d %.50s %d", |
1197 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), | 1173 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), |
1198 | laddr, ssh_local_port(ssh)); | 1174 | laddr, ssh_local_port(ssh)); |
@@ -1334,7 +1310,7 @@ safely_chroot(const char *path, uid_t uid) | |||
1334 | char component[PATH_MAX]; | 1310 | char component[PATH_MAX]; |
1335 | struct stat st; | 1311 | struct stat st; |
1336 | 1312 | ||
1337 | if (*path != '/') | 1313 | if (!path_absolute(path)) |
1338 | fatal("chroot path does not begin at root"); | 1314 | fatal("chroot path does not begin at root"); |
1339 | if (strlen(path) >= sizeof(component)) | 1315 | if (strlen(path) >= sizeof(component)) |
1340 | fatal("chroot path too long"); | 1316 | fatal("chroot path too long"); |
@@ -1359,7 +1335,7 @@ safely_chroot(const char *path, uid_t uid) | |||
1359 | component, strerror(errno)); | 1335 | component, strerror(errno)); |
1360 | if (st.st_uid != 0 || (st.st_mode & 022) != 0) | 1336 | if (st.st_uid != 0 || (st.st_mode & 022) != 0) |
1361 | fatal("bad ownership or modes for chroot " | 1337 | fatal("bad ownership or modes for chroot " |
1362 | "directory %s\"%s\"", | 1338 | "directory %s\"%s\"", |
1363 | cp == NULL ? "" : "component ", component); | 1339 | cp == NULL ? "" : "component ", component); |
1364 | if (!S_ISDIR(st.st_mode)) | 1340 | if (!S_ISDIR(st.st_mode)) |
1365 | fatal("chroot path %s\"%s\" is not a directory", | 1341 | fatal("chroot path %s\"%s\" is not a directory", |
@@ -1497,11 +1473,12 @@ child_close_fds(struct ssh *ssh) | |||
1497 | auth_sock = -1; | 1473 | auth_sock = -1; |
1498 | } | 1474 | } |
1499 | 1475 | ||
1500 | if (packet_get_connection_in() == packet_get_connection_out()) | 1476 | if (ssh_packet_get_connection_in(ssh) == |
1501 | close(packet_get_connection_in()); | 1477 | ssh_packet_get_connection_out(ssh)) |
1478 | close(ssh_packet_get_connection_in(ssh)); | ||
1502 | else { | 1479 | else { |
1503 | close(packet_get_connection_in()); | 1480 | close(ssh_packet_get_connection_in(ssh)); |
1504 | close(packet_get_connection_out()); | 1481 | close(ssh_packet_get_connection_out(ssh)); |
1505 | } | 1482 | } |
1506 | /* | 1483 | /* |
1507 | * Close all descriptors related to channels. They will still remain | 1484 | * Close all descriptors related to channels. They will still remain |
@@ -1535,15 +1512,16 @@ void | |||
1535 | do_child(struct ssh *ssh, Session *s, const char *command) | 1512 | do_child(struct ssh *ssh, Session *s, const char *command) |
1536 | { | 1513 | { |
1537 | extern char **environ; | 1514 | extern char **environ; |
1538 | char **env; | 1515 | char **env, *argv[ARGV_MAX], remote_id[512]; |
1539 | char *argv[ARGV_MAX]; | ||
1540 | const char *shell, *shell0; | 1516 | const char *shell, *shell0; |
1541 | struct passwd *pw = s->pw; | 1517 | struct passwd *pw = s->pw; |
1542 | int r = 0; | 1518 | int r = 0; |
1543 | 1519 | ||
1520 | sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); | ||
1521 | |||
1544 | /* remove hostkey from the child's memory */ | 1522 | /* remove hostkey from the child's memory */ |
1545 | destroy_sensitive_data(); | 1523 | destroy_sensitive_data(); |
1546 | packet_clear_keys(); | 1524 | ssh_packet_clear_keys(ssh); |
1547 | 1525 | ||
1548 | /* Force a password change */ | 1526 | /* Force a password change */ |
1549 | if (s->authctxt->force_pwchange) { | 1527 | if (s->authctxt->force_pwchange) { |
@@ -1663,6 +1641,8 @@ do_child(struct ssh *ssh, Session *s, const char *command) | |||
1663 | signal(SIGPIPE, SIG_DFL); | 1641 | signal(SIGPIPE, SIG_DFL); |
1664 | 1642 | ||
1665 | if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) { | 1643 | if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) { |
1644 | error("Connection from %s: refusing non-sftp session", | ||
1645 | remote_id); | ||
1666 | printf("This service allows sftp connections only.\n"); | 1646 | printf("This service allows sftp connections only.\n"); |
1667 | fflush(NULL); | 1647 | fflush(NULL); |
1668 | exit(1); | 1648 | exit(1); |
@@ -1905,11 +1885,14 @@ session_by_pid(pid_t pid) | |||
1905 | static int | 1885 | static int |
1906 | session_window_change_req(struct ssh *ssh, Session *s) | 1886 | session_window_change_req(struct ssh *ssh, Session *s) |
1907 | { | 1887 | { |
1908 | s->col = packet_get_int(); | 1888 | int r; |
1909 | s->row = packet_get_int(); | 1889 | |
1910 | s->xpixel = packet_get_int(); | 1890 | if ((r = sshpkt_get_u32(ssh, &s->col)) != 0 || |
1911 | s->ypixel = packet_get_int(); | 1891 | (r = sshpkt_get_u32(ssh, &s->row)) != 0 || |
1912 | packet_check_eom(); | 1892 | (r = sshpkt_get_u32(ssh, &s->xpixel)) != 0 || |
1893 | (r = sshpkt_get_u32(ssh, &s->ypixel)) != 0 || | ||
1894 | (r = sshpkt_get_end(ssh)) != 0) | ||
1895 | sshpkt_fatal(ssh, r, "%s: parse packet", __func__); | ||
1913 | pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); | 1896 | pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); |
1914 | return 1; | 1897 | return 1; |
1915 | } | 1898 | } |
@@ -1917,22 +1900,23 @@ session_window_change_req(struct ssh *ssh, Session *s) | |||
1917 | static int | 1900 | static int |
1918 | session_pty_req(struct ssh *ssh, Session *s) | 1901 | session_pty_req(struct ssh *ssh, Session *s) |
1919 | { | 1902 | { |
1920 | u_int len; | 1903 | int r; |
1921 | 1904 | ||
1922 | if (!auth_opts->permit_pty_flag || !options.permit_tty) { | 1905 | if (!auth_opts->permit_pty_flag || !options.permit_tty) { |
1923 | debug("Allocating a pty not permitted for this connection."); | 1906 | debug("Allocating a pty not permitted for this connection."); |
1924 | return 0; | 1907 | return 0; |
1925 | } | 1908 | } |
1926 | if (s->ttyfd != -1) { | 1909 | if (s->ttyfd != -1) { |
1927 | packet_disconnect("Protocol error: you already have a pty."); | 1910 | ssh_packet_disconnect(ssh, "Protocol error: you already have a pty."); |
1928 | return 0; | 1911 | return 0; |
1929 | } | 1912 | } |
1930 | 1913 | ||
1931 | s->term = packet_get_string(&len); | 1914 | if ((r = sshpkt_get_cstring(ssh, &s->term, NULL)) != 0 || |
1932 | s->col = packet_get_int(); | 1915 | (r = sshpkt_get_u32(ssh, &s->col)) != 0 || |
1933 | s->row = packet_get_int(); | 1916 | (r = sshpkt_get_u32(ssh, &s->row)) != 0 || |
1934 | s->xpixel = packet_get_int(); | 1917 | (r = sshpkt_get_u32(ssh, &s->xpixel)) != 0 || |
1935 | s->ypixel = packet_get_int(); | 1918 | (r = sshpkt_get_u32(ssh, &s->ypixel)) != 0) |
1919 | sshpkt_fatal(ssh, r, "%s: parse packet", __func__); | ||
1936 | 1920 | ||
1937 | if (strcmp(s->term, "") == 0) { | 1921 | if (strcmp(s->term, "") == 0) { |
1938 | free(s->term); | 1922 | free(s->term); |
@@ -1954,13 +1938,15 @@ session_pty_req(struct ssh *ssh, Session *s) | |||
1954 | 1938 | ||
1955 | ssh_tty_parse_modes(ssh, s->ttyfd); | 1939 | ssh_tty_parse_modes(ssh, s->ttyfd); |
1956 | 1940 | ||
1941 | if ((r = sshpkt_get_end(ssh)) != 0) | ||
1942 | sshpkt_fatal(ssh, r, "%s: parse packet", __func__); | ||
1943 | |||
1957 | if (!use_privsep) | 1944 | if (!use_privsep) |
1958 | pty_setowner(s->pw, s->tty); | 1945 | pty_setowner(s->pw, s->tty); |
1959 | 1946 | ||
1960 | /* Set window size from the packet. */ | 1947 | /* Set window size from the packet. */ |
1961 | pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); | 1948 | pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); |
1962 | 1949 | ||
1963 | packet_check_eom(); | ||
1964 | session_proctitle(s); | 1950 | session_proctitle(s); |
1965 | return 1; | 1951 | return 1; |
1966 | } | 1952 | } |
@@ -1969,13 +1955,13 @@ static int | |||
1969 | session_subsystem_req(struct ssh *ssh, Session *s) | 1955 | session_subsystem_req(struct ssh *ssh, Session *s) |
1970 | { | 1956 | { |
1971 | struct stat st; | 1957 | struct stat st; |
1972 | u_int len; | 1958 | int r, success = 0; |
1973 | int success = 0; | ||
1974 | char *prog, *cmd; | 1959 | char *prog, *cmd; |
1975 | u_int i; | 1960 | u_int i; |
1976 | 1961 | ||
1977 | s->subsys = packet_get_string(&len); | 1962 | if ((r = sshpkt_get_cstring(ssh, &s->subsys, NULL)) != 0 || |
1978 | packet_check_eom(); | 1963 | (r = sshpkt_get_end(ssh)) != 0) |
1964 | sshpkt_fatal(ssh, r, "%s: parse packet", __func__); | ||
1979 | debug2("subsystem request for %.100s by user %s", s->subsys, | 1965 | debug2("subsystem request for %.100s by user %s", s->subsys, |
1980 | s->pw->pw_name); | 1966 | s->pw->pw_name); |
1981 | 1967 | ||
@@ -2008,18 +1994,22 @@ session_subsystem_req(struct ssh *ssh, Session *s) | |||
2008 | static int | 1994 | static int |
2009 | session_x11_req(struct ssh *ssh, Session *s) | 1995 | session_x11_req(struct ssh *ssh, Session *s) |
2010 | { | 1996 | { |
2011 | int success; | 1997 | int r, success; |
1998 | u_char single_connection = 0; | ||
2012 | 1999 | ||
2013 | if (s->auth_proto != NULL || s->auth_data != NULL) { | 2000 | if (s->auth_proto != NULL || s->auth_data != NULL) { |
2014 | error("session_x11_req: session %d: " | 2001 | error("session_x11_req: session %d: " |
2015 | "x11 forwarding already active", s->self); | 2002 | "x11 forwarding already active", s->self); |
2016 | return 0; | 2003 | return 0; |
2017 | } | 2004 | } |
2018 | s->single_connection = packet_get_char(); | 2005 | if ((r = sshpkt_get_u8(ssh, &single_connection)) != 0 || |
2019 | s->auth_proto = packet_get_string(NULL); | 2006 | (r = sshpkt_get_cstring(ssh, &s->auth_proto, NULL)) != 0 || |
2020 | s->auth_data = packet_get_string(NULL); | 2007 | (r = sshpkt_get_cstring(ssh, &s->auth_data, NULL)) != 0 || |
2021 | s->screen = packet_get_int(); | 2008 | (r = sshpkt_get_u32(ssh, &s->screen)) != 0 || |
2022 | packet_check_eom(); | 2009 | (r = sshpkt_get_end(ssh)) != 0) |
2010 | sshpkt_fatal(ssh, r, "%s: parse packet", __func__); | ||
2011 | |||
2012 | s->single_connection = single_connection; | ||
2023 | 2013 | ||
2024 | if (xauth_valid_string(s->auth_proto) && | 2014 | if (xauth_valid_string(s->auth_proto) && |
2025 | xauth_valid_string(s->auth_data)) | 2015 | xauth_valid_string(s->auth_data)) |
@@ -2040,17 +2030,24 @@ session_x11_req(struct ssh *ssh, Session *s) | |||
2040 | static int | 2030 | static int |
2041 | session_shell_req(struct ssh *ssh, Session *s) | 2031 | session_shell_req(struct ssh *ssh, Session *s) |
2042 | { | 2032 | { |
2043 | packet_check_eom(); | 2033 | int r; |
2034 | |||
2035 | if ((r = sshpkt_get_end(ssh)) != 0) | ||
2036 | sshpkt_fatal(ssh, r, "%s: parse packet", __func__); | ||
2044 | return do_exec(ssh, s, NULL) == 0; | 2037 | return do_exec(ssh, s, NULL) == 0; |
2045 | } | 2038 | } |
2046 | 2039 | ||
2047 | static int | 2040 | static int |
2048 | session_exec_req(struct ssh *ssh, Session *s) | 2041 | session_exec_req(struct ssh *ssh, Session *s) |
2049 | { | 2042 | { |
2050 | u_int len, success; | 2043 | u_int success; |
2044 | int r; | ||
2045 | char *command = NULL; | ||
2046 | |||
2047 | if ((r = sshpkt_get_cstring(ssh, &command, NULL)) != 0 || | ||
2048 | (r = sshpkt_get_end(ssh)) != 0) | ||
2049 | sshpkt_fatal(ssh, r, "%s: parse packet", __func__); | ||
2051 | 2050 | ||
2052 | char *command = packet_get_string(&len); | ||
2053 | packet_check_eom(); | ||
2054 | success = do_exec(ssh, s, command) == 0; | 2051 | success = do_exec(ssh, s, command) == 0; |
2055 | free(command); | 2052 | free(command); |
2056 | return success; | 2053 | return success; |
@@ -2059,9 +2056,11 @@ session_exec_req(struct ssh *ssh, Session *s) | |||
2059 | static int | 2056 | static int |
2060 | session_break_req(struct ssh *ssh, Session *s) | 2057 | session_break_req(struct ssh *ssh, Session *s) |
2061 | { | 2058 | { |
2059 | int r; | ||
2062 | 2060 | ||
2063 | packet_get_int(); /* ignored */ | 2061 | if ((r = sshpkt_get_u32(ssh, NULL)) != 0 || /* ignore */ |
2064 | packet_check_eom(); | 2062 | (r = sshpkt_get_end(ssh)) != 0) |
2063 | sshpkt_fatal(ssh, r, "%s: parse packet", __func__); | ||
2065 | 2064 | ||
2066 | if (s->ptymaster == -1 || tcsendbreak(s->ptymaster, 0) < 0) | 2065 | if (s->ptymaster == -1 || tcsendbreak(s->ptymaster, 0) < 0) |
2067 | return 0; | 2066 | return 0; |
@@ -2072,11 +2071,13 @@ static int | |||
2072 | session_env_req(struct ssh *ssh, Session *s) | 2071 | session_env_req(struct ssh *ssh, Session *s) |
2073 | { | 2072 | { |
2074 | char *name, *val; | 2073 | char *name, *val; |
2075 | u_int name_len, val_len, i; | 2074 | u_int i; |
2075 | int r; | ||
2076 | 2076 | ||
2077 | name = packet_get_cstring(&name_len); | 2077 | if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0 || |
2078 | val = packet_get_cstring(&val_len); | 2078 | (r = sshpkt_get_cstring(ssh, &val, NULL)) != 0 || |
2079 | packet_check_eom(); | 2079 | (r = sshpkt_get_end(ssh)) != 0) |
2080 | sshpkt_fatal(ssh, r, "%s: parse packet", __func__); | ||
2080 | 2081 | ||
2081 | /* Don't set too many environment variables */ | 2082 | /* Don't set too many environment variables */ |
2082 | if (s->num_env > 128) { | 2083 | if (s->num_env > 128) { |
@@ -2179,8 +2180,10 @@ static int | |||
2179 | session_auth_agent_req(struct ssh *ssh, Session *s) | 2180 | session_auth_agent_req(struct ssh *ssh, Session *s) |
2180 | { | 2181 | { |
2181 | static int called = 0; | 2182 | static int called = 0; |
2183 | int r; | ||
2182 | 2184 | ||
2183 | packet_check_eom(); | 2185 | if ((r = sshpkt_get_end(ssh)) != 0) |
2186 | sshpkt_fatal(ssh, r, "%s: parse packet", __func__); | ||
2184 | if (!auth_opts->permit_agent_forwarding_flag || | 2187 | if (!auth_opts->permit_agent_forwarding_flag || |
2185 | !options.allow_agent_forwarding) { | 2188 | !options.allow_agent_forwarding) { |
2186 | debug("%s: agent forwarding disabled", __func__); | 2189 | debug("%s: agent forwarding disabled", __func__); |
@@ -2370,6 +2373,7 @@ static void | |||
2370 | session_exit_message(struct ssh *ssh, Session *s, int status) | 2373 | session_exit_message(struct ssh *ssh, Session *s, int status) |
2371 | { | 2374 | { |
2372 | Channel *c; | 2375 | Channel *c; |
2376 | int r; | ||
2373 | 2377 | ||
2374 | if ((c = channel_lookup(ssh, s->chanid)) == NULL) | 2378 | if ((c = channel_lookup(ssh, s->chanid)) == NULL) |
2375 | fatal("%s: session %d: no channel %d", | 2379 | fatal("%s: session %d: no channel %d", |
@@ -2379,22 +2383,23 @@ session_exit_message(struct ssh *ssh, Session *s, int status) | |||
2379 | 2383 | ||
2380 | if (WIFEXITED(status)) { | 2384 | if (WIFEXITED(status)) { |
2381 | channel_request_start(ssh, s->chanid, "exit-status", 0); | 2385 | channel_request_start(ssh, s->chanid, "exit-status", 0); |
2382 | packet_put_int(WEXITSTATUS(status)); | 2386 | if ((r = sshpkt_put_u32(ssh, WEXITSTATUS(status))) != 0 || |
2383 | packet_send(); | 2387 | (r = sshpkt_send(ssh)) != 0) |
2388 | sshpkt_fatal(ssh, r, "%s: exit reply", __func__); | ||
2384 | } else if (WIFSIGNALED(status)) { | 2389 | } else if (WIFSIGNALED(status)) { |
2385 | channel_request_start(ssh, s->chanid, "exit-signal", 0); | 2390 | channel_request_start(ssh, s->chanid, "exit-signal", 0); |
2386 | packet_put_cstring(sig2name(WTERMSIG(status))); | 2391 | #ifndef WCOREDUMP |
2387 | #ifdef WCOREDUMP | 2392 | # define WCOREDUMP(x) (0) |
2388 | packet_put_char(WCOREDUMP(status)? 1 : 0); | 2393 | #endif |
2389 | #else /* WCOREDUMP */ | 2394 | if ((r = sshpkt_put_cstring(ssh, sig2name(WTERMSIG(status)))) != 0 || |
2390 | packet_put_char(0); | 2395 | (r = sshpkt_put_u8(ssh, WCOREDUMP(status)? 1 : 0)) != 0 || |
2391 | #endif /* WCOREDUMP */ | 2396 | (r = sshpkt_put_cstring(ssh, "")) != 0 || |
2392 | packet_put_cstring(""); | 2397 | (r = sshpkt_put_cstring(ssh, "")) != 0 || |
2393 | packet_put_cstring(""); | 2398 | (r = sshpkt_send(ssh)) != 0) |
2394 | packet_send(); | 2399 | sshpkt_fatal(ssh, r, "%s: exit reply", __func__); |
2395 | } else { | 2400 | } else { |
2396 | /* Some weird exit cause. Just exit. */ | 2401 | /* Some weird exit cause. Just exit. */ |
2397 | packet_disconnect("wait returned status %04x.", status); | 2402 | ssh_packet_disconnect(ssh, "wait returned status %04x.", status); |
2398 | } | 2403 | } |
2399 | 2404 | ||
2400 | /* disconnect channel */ | 2405 | /* disconnect channel */ |
@@ -2565,7 +2570,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) | |||
2565 | u_int i; | 2570 | u_int i; |
2566 | 2571 | ||
2567 | if (!auth_opts->permit_x11_forwarding_flag) { | 2572 | if (!auth_opts->permit_x11_forwarding_flag) { |
2568 | packet_send_debug("X11 forwarding disabled by key options."); | 2573 | ssh_packet_send_debug(ssh, "X11 forwarding disabled by key options."); |
2569 | return 0; | 2574 | return 0; |
2570 | } | 2575 | } |
2571 | if (!options.x11_forwarding) { | 2576 | if (!options.x11_forwarding) { |
@@ -2574,7 +2579,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) | |||
2574 | } | 2579 | } |
2575 | if (options.xauth_location == NULL || | 2580 | if (options.xauth_location == NULL || |
2576 | (stat(options.xauth_location, &st) == -1)) { | 2581 | (stat(options.xauth_location, &st) == -1)) { |
2577 | packet_send_debug("No xauth program; cannot forward X11."); | 2582 | ssh_packet_send_debug(ssh, "No xauth program; cannot forward X11."); |
2578 | return 0; | 2583 | return 0; |
2579 | } | 2584 | } |
2580 | if (s->display != NULL) { | 2585 | if (s->display != NULL) { |
@@ -2615,7 +2620,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) | |||
2615 | he = gethostbyname(hostname); | 2620 | he = gethostbyname(hostname); |
2616 | if (he == NULL) { | 2621 | if (he == NULL) { |
2617 | error("Can't get IP address for X11 DISPLAY."); | 2622 | error("Can't get IP address for X11 DISPLAY."); |
2618 | packet_send_debug("Can't get IP address for X11 DISPLAY."); | 2623 | ssh_packet_send_debug(ssh, "Can't get IP address for X11 DISPLAY."); |
2619 | return 0; | 2624 | return 0; |
2620 | } | 2625 | } |
2621 | memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); | 2626 | memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); |