upstream: convert session.c to new packet API

with & ok markus@

OpenBSD-Commit-ID: fae817207e23099ddd248960c984f7b7f26ea68e
This commit is contained in:
djm@openbsd.org 2019-01-19 21:41:53 +00:00 committed by Damien Miller
parent 3a00a92159
commit a5e2ad88ac
1 changed files with 87 additions and 64 deletions

149
session.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: session.c,v 1.311 2019/01/19 21:41:18 djm Exp $ */ /* $OpenBSD: session.c,v 1.312 2019/01/19 21:41:53 djm Exp $ */
/* /*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved * All rights reserved
@ -105,9 +105,6 @@
#include <selinux/selinux.h> #include <selinux/selinux.h>
#endif #endif
#include "opacket.h" /* XXX */
extern struct ssh *active_state; /* XXX */
#define IS_INTERNAL_SFTP(c) \ #define IS_INTERNAL_SFTP(c) \
(!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \ (!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \
(c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \ (c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \
@ -207,7 +204,7 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
/* Create private directory for socket */ /* Create private directory for socket */
if (mkdtemp(auth_sock_dir) == NULL) { if (mkdtemp(auth_sock_dir) == NULL) {
packet_send_debug("Agent forwarding disabled: " ssh_packet_send_debug(ssh, "Agent forwarding disabled: "
"mkdtemp() failed: %.100s", strerror(errno)); "mkdtemp() failed: %.100s", strerror(errno));
restore_uid(); restore_uid();
free(auth_sock_dir); free(auth_sock_dir);
@ -524,7 +521,7 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
s->pid = pid; s->pid = pid;
/* Set interactive/non-interactive mode. */ /* Set interactive/non-interactive mode. */
packet_set_interactive(s->display != NULL, ssh_packet_set_interactive(ssh, s->display != NULL,
options.ip_qos_interactive, options.ip_qos_bulk); options.ip_qos_interactive, options.ip_qos_bulk);
/* /*
@ -653,7 +650,7 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command)
/* Enter interactive session. */ /* Enter interactive session. */
s->ptymaster = ptymaster; s->ptymaster = ptymaster;
packet_set_interactive(1, ssh_packet_set_interactive(ssh, 1,
options.ip_qos_interactive, options.ip_qos_bulk); options.ip_qos_interactive, options.ip_qos_bulk);
session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1); session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1);
return 0; return 0;
@ -786,8 +783,8 @@ do_login(struct ssh *ssh, Session *s, const char *command)
*/ */
memset(&from, 0, sizeof(from)); memset(&from, 0, sizeof(from));
fromlen = sizeof(from); fromlen = sizeof(from);
if (packet_connection_is_on_socket()) { if (ssh_packet_connection_is_on_socket(ssh)) {
if (getpeername(packet_get_connection_in(), if (getpeername(ssh_packet_get_connection_in(ssh),
(struct sockaddr *)&from, &fromlen) < 0) { (struct sockaddr *)&from, &fromlen) < 0) {
debug("getpeername: %.100s", strerror(errno)); debug("getpeername: %.100s", strerror(errno));
cleanup_exit(255); cleanup_exit(255);
@ -1198,7 +1195,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
ssh_local_port(ssh)); ssh_local_port(ssh));
child_set_env(&env, &envsize, "SSH_CLIENT", buf); child_set_env(&env, &envsize, "SSH_CLIENT", buf);
laddr = get_local_ipaddr(packet_get_connection_in()); laddr = get_local_ipaddr(ssh_packet_get_connection_in(ssh));
snprintf(buf, sizeof buf, "%.50s %d %.50s %d", snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
laddr, ssh_local_port(ssh)); laddr, ssh_local_port(ssh));
@ -1503,11 +1500,12 @@ child_close_fds(struct ssh *ssh)
auth_sock = -1; auth_sock = -1;
} }
if (packet_get_connection_in() == packet_get_connection_out()) if (ssh_packet_get_connection_in(ssh) ==
close(packet_get_connection_in()); ssh_packet_get_connection_out(ssh))
close(ssh_packet_get_connection_in(ssh));
else { else {
close(packet_get_connection_in()); close(ssh_packet_get_connection_in(ssh));
close(packet_get_connection_out()); close(ssh_packet_get_connection_out(ssh));
} }
/* /*
* Close all descriptors related to channels. They will still remain * Close all descriptors related to channels. They will still remain
@ -1549,7 +1547,7 @@ do_child(struct ssh *ssh, Session *s, const char *command)
/* remove hostkey from the child's memory */ /* remove hostkey from the child's memory */
destroy_sensitive_data(); destroy_sensitive_data();
packet_clear_keys(); ssh_packet_clear_keys(ssh);
/* Force a password change */ /* Force a password change */
if (s->authctxt->force_pwchange) { if (s->authctxt->force_pwchange) {
@ -1911,11 +1909,14 @@ session_by_pid(pid_t pid)
static int static int
session_window_change_req(struct ssh *ssh, Session *s) session_window_change_req(struct ssh *ssh, Session *s)
{ {
s->col = packet_get_int(); int r;
s->row = packet_get_int();
s->xpixel = packet_get_int(); if ((r = sshpkt_get_u32(ssh, &s->col)) != 0 ||
s->ypixel = packet_get_int(); (r = sshpkt_get_u32(ssh, &s->row)) != 0 ||
packet_check_eom(); (r = sshpkt_get_u32(ssh, &s->xpixel)) != 0 ||
(r = sshpkt_get_u32(ssh, &s->ypixel)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
return 1; return 1;
} }
@ -1923,22 +1924,23 @@ session_window_change_req(struct ssh *ssh, Session *s)
static int static int
session_pty_req(struct ssh *ssh, Session *s) session_pty_req(struct ssh *ssh, Session *s)
{ {
u_int len; int r;
if (!auth_opts->permit_pty_flag || !options.permit_tty) { if (!auth_opts->permit_pty_flag || !options.permit_tty) {
debug("Allocating a pty not permitted for this connection."); debug("Allocating a pty not permitted for this connection.");
return 0; return 0;
} }
if (s->ttyfd != -1) { if (s->ttyfd != -1) {
packet_disconnect("Protocol error: you already have a pty."); ssh_packet_disconnect(ssh, "Protocol error: you already have a pty.");
return 0; return 0;
} }
s->term = packet_get_string(&len); if ((r = sshpkt_get_cstring(ssh, &s->term, NULL)) != 0 ||
s->col = packet_get_int(); (r = sshpkt_get_u32(ssh, &s->col)) != 0 ||
s->row = packet_get_int(); (r = sshpkt_get_u32(ssh, &s->row)) != 0 ||
s->xpixel = packet_get_int(); (r = sshpkt_get_u32(ssh, &s->xpixel)) != 0 ||
s->ypixel = packet_get_int(); (r = sshpkt_get_u32(ssh, &s->ypixel)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (strcmp(s->term, "") == 0) { if (strcmp(s->term, "") == 0) {
free(s->term); free(s->term);
@ -1960,13 +1962,15 @@ session_pty_req(struct ssh *ssh, Session *s)
ssh_tty_parse_modes(ssh, s->ttyfd); ssh_tty_parse_modes(ssh, s->ttyfd);
if ((r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (!use_privsep) if (!use_privsep)
pty_setowner(s->pw, s->tty); pty_setowner(s->pw, s->tty);
/* Set window size from the packet. */ /* Set window size from the packet. */
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
packet_check_eom();
session_proctitle(s); session_proctitle(s);
return 1; return 1;
} }
@ -1975,13 +1979,13 @@ static int
session_subsystem_req(struct ssh *ssh, Session *s) session_subsystem_req(struct ssh *ssh, Session *s)
{ {
struct stat st; struct stat st;
u_int len; int r, success = 0;
int success = 0;
char *prog, *cmd; char *prog, *cmd;
u_int i; u_int i;
s->subsys = packet_get_string(&len); if ((r = sshpkt_get_cstring(ssh, &s->subsys, NULL)) != 0 ||
packet_check_eom(); (r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
debug2("subsystem request for %.100s by user %s", s->subsys, debug2("subsystem request for %.100s by user %s", s->subsys,
s->pw->pw_name); s->pw->pw_name);
@ -2014,18 +2018,22 @@ session_subsystem_req(struct ssh *ssh, Session *s)
static int static int
session_x11_req(struct ssh *ssh, Session *s) session_x11_req(struct ssh *ssh, Session *s)
{ {
int success; int r, success;
u_char single_connection = 0;
if (s->auth_proto != NULL || s->auth_data != NULL) { if (s->auth_proto != NULL || s->auth_data != NULL) {
error("session_x11_req: session %d: " error("session_x11_req: session %d: "
"x11 forwarding already active", s->self); "x11 forwarding already active", s->self);
return 0; return 0;
} }
s->single_connection = packet_get_char(); if ((r = sshpkt_get_u8(ssh, &single_connection)) != 0 ||
s->auth_proto = packet_get_string(NULL); (r = sshpkt_get_cstring(ssh, &s->auth_proto, NULL)) != 0 ||
s->auth_data = packet_get_string(NULL); (r = sshpkt_get_cstring(ssh, &s->auth_data, NULL)) != 0 ||
s->screen = packet_get_int(); (r = sshpkt_get_u32(ssh, &s->screen)) != 0 ||
packet_check_eom(); (r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
s->single_connection = single_connection;
if (xauth_valid_string(s->auth_proto) && if (xauth_valid_string(s->auth_proto) &&
xauth_valid_string(s->auth_data)) xauth_valid_string(s->auth_data))
@ -2046,17 +2054,24 @@ session_x11_req(struct ssh *ssh, Session *s)
static int static int
session_shell_req(struct ssh *ssh, Session *s) session_shell_req(struct ssh *ssh, Session *s)
{ {
packet_check_eom(); int r;
if ((r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
return do_exec(ssh, s, NULL) == 0; return do_exec(ssh, s, NULL) == 0;
} }
static int static int
session_exec_req(struct ssh *ssh, Session *s) session_exec_req(struct ssh *ssh, Session *s)
{ {
u_int len, success; u_int success;
int r;
char *command = NULL;
if ((r = sshpkt_get_cstring(ssh, &command, NULL)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
char *command = packet_get_string(&len);
packet_check_eom();
success = do_exec(ssh, s, command) == 0; success = do_exec(ssh, s, command) == 0;
free(command); free(command);
return success; return success;
@ -2065,9 +2080,11 @@ session_exec_req(struct ssh *ssh, Session *s)
static int static int
session_break_req(struct ssh *ssh, Session *s) session_break_req(struct ssh *ssh, Session *s)
{ {
int r;
packet_get_int(); /* ignored */ if ((r = sshpkt_get_u32(ssh, NULL)) != 0 || /* ignore */
packet_check_eom(); (r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (s->ptymaster == -1 || tcsendbreak(s->ptymaster, 0) < 0) if (s->ptymaster == -1 || tcsendbreak(s->ptymaster, 0) < 0)
return 0; return 0;
@ -2078,11 +2095,13 @@ static int
session_env_req(struct ssh *ssh, Session *s) session_env_req(struct ssh *ssh, Session *s)
{ {
char *name, *val; char *name, *val;
u_int name_len, val_len, i; u_int i;
int r;
name = packet_get_cstring(&name_len); if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0 ||
val = packet_get_cstring(&val_len); (r = sshpkt_get_cstring(ssh, &val, NULL)) != 0 ||
packet_check_eom(); (r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
/* Don't set too many environment variables */ /* Don't set too many environment variables */
if (s->num_env > 128) { if (s->num_env > 128) {
@ -2185,8 +2204,10 @@ static int
session_auth_agent_req(struct ssh *ssh, Session *s) session_auth_agent_req(struct ssh *ssh, Session *s)
{ {
static int called = 0; static int called = 0;
int r;
packet_check_eom(); if ((r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (!auth_opts->permit_agent_forwarding_flag || if (!auth_opts->permit_agent_forwarding_flag ||
!options.allow_agent_forwarding) { !options.allow_agent_forwarding) {
debug("%s: agent forwarding disabled", __func__); debug("%s: agent forwarding disabled", __func__);
@ -2376,6 +2397,7 @@ static void
session_exit_message(struct ssh *ssh, Session *s, int status) session_exit_message(struct ssh *ssh, Session *s, int status)
{ {
Channel *c; Channel *c;
int r;
if ((c = channel_lookup(ssh, s->chanid)) == NULL) if ((c = channel_lookup(ssh, s->chanid)) == NULL)
fatal("%s: session %d: no channel %d", fatal("%s: session %d: no channel %d",
@ -2385,22 +2407,23 @@ session_exit_message(struct ssh *ssh, Session *s, int status)
if (WIFEXITED(status)) { if (WIFEXITED(status)) {
channel_request_start(ssh, s->chanid, "exit-status", 0); channel_request_start(ssh, s->chanid, "exit-status", 0);
packet_put_int(WEXITSTATUS(status)); if ((r = sshpkt_put_u32(ssh, WEXITSTATUS(status))) != 0 ||
packet_send(); (r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: exit reply", __func__);
} else if (WIFSIGNALED(status)) { } else if (WIFSIGNALED(status)) {
channel_request_start(ssh, s->chanid, "exit-signal", 0); channel_request_start(ssh, s->chanid, "exit-signal", 0);
packet_put_cstring(sig2name(WTERMSIG(status))); #ifndef WCOREDUMP
#ifdef WCOREDUMP # define WCOREDUMP(x) (0)
packet_put_char(WCOREDUMP(status)? 1 : 0); #endif
#else /* WCOREDUMP */ if ((r = sshpkt_put_cstring(ssh, sig2name(WTERMSIG(status)))) != 0 ||
packet_put_char(0); (r = sshpkt_put_u8(ssh, WCOREDUMP(status)? 1 : 0)) != 0 ||
#endif /* WCOREDUMP */ (r = sshpkt_put_cstring(ssh, "")) != 0 ||
packet_put_cstring(""); (r = sshpkt_put_cstring(ssh, "")) != 0 ||
packet_put_cstring(""); (r = sshpkt_send(ssh)) != 0)
packet_send(); sshpkt_fatal(ssh, r, "%s: exit reply", __func__);
} else { } else {
/* Some weird exit cause. Just exit. */ /* Some weird exit cause. Just exit. */
packet_disconnect("wait returned status %04x.", status); ssh_packet_disconnect(ssh, "wait returned status %04x.", status);
} }
/* disconnect channel */ /* disconnect channel */
@ -2571,7 +2594,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s)
u_int i; u_int i;
if (!auth_opts->permit_x11_forwarding_flag) { if (!auth_opts->permit_x11_forwarding_flag) {
packet_send_debug("X11 forwarding disabled by key options."); ssh_packet_send_debug(ssh, "X11 forwarding disabled by key options.");
return 0; return 0;
} }
if (!options.x11_forwarding) { if (!options.x11_forwarding) {
@ -2580,7 +2603,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s)
} }
if (options.xauth_location == NULL || if (options.xauth_location == NULL ||
(stat(options.xauth_location, &st) == -1)) { (stat(options.xauth_location, &st) == -1)) {
packet_send_debug("No xauth program; cannot forward X11."); ssh_packet_send_debug(ssh, "No xauth program; cannot forward X11.");
return 0; return 0;
} }
if (s->display != NULL) { if (s->display != NULL) {