version 1.319, 2019/01/19 21:31:32 |
version 1.320, 2019/01/19 21:33:57 |
|
|
free(gc); |
free(gc); |
} |
} |
|
|
packet_set_alive_timeouts(0); |
ssh_packet_set_alive_timeouts(ssh, 0); |
return 0; |
return 0; |
} |
} |
|
|
static void |
static void |
server_alive_check(void) |
server_alive_check(struct ssh *ssh) |
{ |
{ |
if (packet_inc_alive_timeouts() > options.server_alive_count_max) { |
int r; |
|
|
|
if (ssh_packet_inc_alive_timeouts(ssh) > options.server_alive_count_max) { |
logit("Timeout, server %s not responding.", host); |
logit("Timeout, server %s not responding.", host); |
cleanup_exit(255); |
cleanup_exit(255); |
} |
} |
packet_start(SSH2_MSG_GLOBAL_REQUEST); |
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || |
packet_put_cstring("keepalive@openssh.com"); |
(r = sshpkt_put_cstring(ssh, "keepalive@openssh.com")) != 0 || |
packet_put_char(1); /* boolean: want reply */ |
(r = sshpkt_put_u8(ssh, 1)) != 0 || /* boolean: want reply */ |
packet_send(); |
(r = sshpkt_send(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
/* Insert an empty placeholder to maintain ordering */ |
/* Insert an empty placeholder to maintain ordering */ |
client_register_global_confirm(NULL, NULL); |
client_register_global_confirm(NULL, NULL); |
} |
} |
|
|
|
|
/* channel_prepare_select could have closed the last channel */ |
/* channel_prepare_select could have closed the last channel */ |
if (session_closed && !channel_still_open(ssh) && |
if (session_closed && !channel_still_open(ssh) && |
!packet_have_data_to_write()) { |
!ssh_packet_have_data_to_write(ssh)) { |
/* clear mask since we did not call select() */ |
/* clear mask since we did not call select() */ |
memset(*readsetp, 0, *nallocp); |
memset(*readsetp, 0, *nallocp); |
memset(*writesetp, 0, *nallocp); |
memset(*writesetp, 0, *nallocp); |
|
|
FD_SET(connection_in, *readsetp); |
FD_SET(connection_in, *readsetp); |
|
|
/* Select server connection if have data to write to the server. */ |
/* Select server connection if have data to write to the server. */ |
if (packet_have_data_to_write()) |
if (ssh_packet_have_data_to_write(ssh)) |
FD_SET(connection_out, *writesetp); |
FD_SET(connection_out, *writesetp); |
|
|
/* |
/* |
|
|
server_alive_time = now + options.server_alive_interval; |
server_alive_time = now + options.server_alive_interval; |
} |
} |
if (options.rekey_interval > 0 && !rekeying) |
if (options.rekey_interval > 0 && !rekeying) |
timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout()); |
timeout_secs = MINIMUM(timeout_secs, |
|
ssh_packet_get_rekey_timeout(ssh)); |
set_control_persist_exit_time(ssh); |
set_control_persist_exit_time(ssh); |
if (control_persist_exit_time > 0) { |
if (control_persist_exit_time > 0) { |
timeout_secs = MINIMUM(timeout_secs, |
timeout_secs = MINIMUM(timeout_secs, |
|
|
* Keepalive we check here, rekeying is checked in clientloop. |
* Keepalive we check here, rekeying is checked in clientloop. |
*/ |
*/ |
if (server_alive_time != 0 && server_alive_time <= monotime()) |
if (server_alive_time != 0 && server_alive_time <= monotime()) |
server_alive_check(); |
server_alive_check(ssh); |
} |
} |
|
|
} |
} |
|
|
} |
} |
|
|
static void |
static void |
client_process_net_input(fd_set *readset) |
client_process_net_input(struct ssh *ssh, fd_set *readset) |
{ |
{ |
char buf[8192]; |
char buf[8192]; |
int r, len; |
int r, len; |
|
|
quit_pending = 1; |
quit_pending = 1; |
return; |
return; |
} |
} |
packet_process_incoming(buf, len); |
ssh_packet_process_incoming(ssh, buf, len); |
} |
} |
} |
} |
|
|
|
|
/* Initialize variables. */ |
/* Initialize variables. */ |
last_was_cr = 1; |
last_was_cr = 1; |
exit_status = -1; |
exit_status = -1; |
connection_in = packet_get_connection_in(); |
connection_in = ssh_packet_get_connection_in(ssh); |
connection_out = packet_get_connection_out(); |
connection_out = ssh_packet_get_connection_out(ssh); |
max_fd = MAXIMUM(connection_in, connection_out); |
max_fd = MAXIMUM(connection_in, connection_out); |
|
|
quit_pending = 0; |
quit_pending = 0; |
|
|
* Make packets from buffered channel data, and |
* Make packets from buffered channel data, and |
* enqueue them for sending to the server. |
* enqueue them for sending to the server. |
*/ |
*/ |
if (packet_not_very_much_data_to_write()) |
if (ssh_packet_not_very_much_data_to_write(ssh)) |
channel_output_poll(ssh); |
channel_output_poll(ssh); |
|
|
/* |
/* |
|
|
channel_after_select(ssh, readset, writeset); |
channel_after_select(ssh, readset, writeset); |
|
|
/* Buffer input from the connection. */ |
/* Buffer input from the connection. */ |
client_process_net_input(readset); |
client_process_net_input(ssh, readset); |
|
|
if (quit_pending) |
if (quit_pending) |
break; |
break; |
|
|
* sender. |
* sender. |
*/ |
*/ |
if (FD_ISSET(connection_out, writeset)) |
if (FD_ISSET(connection_out, writeset)) |
packet_write_poll(); |
ssh_packet_write_poll(ssh); |
|
|
/* |
/* |
* If we are a backgrounded control master, and the |
* If we are a backgrounded control master, and the |
|
|
/* Stop watching for window change. */ |
/* Stop watching for window change. */ |
signal(SIGWINCH, SIG_DFL); |
signal(SIGWINCH, SIG_DFL); |
|
|
packet_start(SSH2_MSG_DISCONNECT); |
if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || |
packet_put_int(SSH2_DISCONNECT_BY_APPLICATION); |
(r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_BY_APPLICATION)) != 0 || |
packet_put_cstring("disconnected by user"); |
(r = sshpkt_put_cstring(ssh, "disconnected by user")) != 0 || |
packet_put_cstring(""); /* language tag */ |
(r = sshpkt_put_cstring(ssh, "")) != 0 || /* language tag */ |
packet_send(); |
(r = sshpkt_send(ssh)) != 0 || |
packet_write_wait(); |
(r = ssh_packet_write_wait(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
|
|
channel_free_all(ssh); |
channel_free_all(ssh); |
|
|
|
|
|
|
/* Report bytes transferred, and transfer rates. */ |
/* Report bytes transferred, and transfer rates. */ |
total_time = monotime_double() - start_time; |
total_time = monotime_double() - start_time; |
packet_get_bytes(&ibytes, &obytes); |
ssh_packet_get_bytes(ssh, &ibytes, &obytes); |
verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds", |
verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds", |
(unsigned long long)obytes, (unsigned long long)ibytes, total_time); |
(unsigned long long)obytes, (unsigned long long)ibytes, total_time); |
if (total_time > 0) |
if (total_time > 0) |
|
|
Channel *c = NULL; |
Channel *c = NULL; |
struct sshbuf *b = NULL; |
struct sshbuf *b = NULL; |
char *listen_address, *originator_address; |
char *listen_address, *originator_address; |
u_short listen_port, originator_port; |
u_int listen_port, originator_port; |
int r; |
int r; |
|
|
/* Get rest of the packet */ |
/* Get rest of the packet */ |
listen_address = packet_get_string(NULL); |
if ((r = sshpkt_get_cstring(ssh, &listen_address, NULL)) != 0 || |
listen_port = packet_get_int(); |
(r = sshpkt_get_u32(ssh, &listen_port)) != 0 || |
originator_address = packet_get_string(NULL); |
(r = sshpkt_get_cstring(ssh, &originator_address, NULL)) != 0 || |
originator_port = packet_get_int(); |
(r = sshpkt_get_u32(ssh, &originator_port)) != 0 || |
packet_check_eom(); |
(r = sshpkt_get_end(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
|
|
debug("%s: listen %s port %d, originator %s port %d", __func__, |
debug("%s: listen %s port %d, originator %s port %d", __func__, |
listen_address, listen_port, originator_address, originator_port); |
listen_address, listen_port, originator_address, originator_port); |
|
|
c = channel_connect_by_listen_address(ssh, listen_address, listen_port, |
if (listen_port > 0xffff) |
"forwarded-tcpip", originator_address); |
error("%s: invalid listen port", __func__); |
|
else if (originator_port > 0xffff) |
|
error("%s: invalid originator port", __func__); |
|
else { |
|
c = channel_connect_by_listen_address(ssh, |
|
listen_address, listen_port, "forwarded-tcpip", |
|
originator_address); |
|
} |
|
|
if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { |
if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { |
if ((b = sshbuf_new()) == NULL) { |
if ((b = sshbuf_new()) == NULL) { |
|
|
{ |
{ |
Channel *c = NULL; |
Channel *c = NULL; |
char *listen_path; |
char *listen_path; |
|
int r; |
|
|
/* Get the remote path. */ |
/* Get the remote path. */ |
listen_path = packet_get_string(NULL); |
if ((r = sshpkt_get_cstring(ssh, &listen_path, NULL)) != 0 || |
/* XXX: Skip reserved field for now. */ |
(r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* reserved */ |
if (packet_get_string_ptr(NULL) == NULL) |
(r = sshpkt_get_end(ssh)) != 0) |
fatal("%s: packet_get_string_ptr failed", __func__); |
fatal("%s: %s", __func__, ssh_err(r)); |
packet_check_eom(); |
|
|
|
debug("%s: %s", __func__, listen_path); |
debug("%s: %s", __func__, listen_path); |
|
|
|
|
{ |
{ |
Channel *c = NULL; |
Channel *c = NULL; |
char *originator; |
char *originator; |
u_short originator_port; |
int originator_port; |
int sock; |
int r, sock; |
|
|
if (!options.forward_x11) { |
if (!options.forward_x11) { |
error("Warning: ssh server tried X11 forwarding."); |
error("Warning: ssh server tried X11 forwarding."); |
|
|
"expired"); |
"expired"); |
return NULL; |
return NULL; |
} |
} |
originator = packet_get_string(NULL); |
if ((r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 || |
originator_port = packet_get_int(); |
(r = sshpkt_get_u32(ssh, (u_int *)&originator_port)) != 0 || |
packet_check_eom(); |
(r = sshpkt_get_end(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
/* XXX check permission */ |
/* XXX check permission */ |
debug("client_request_x11: request from %s %d", originator, |
debug("client_request_x11: request from %s %d", originator, |
originator_port); |
originator_port); |
|
|
int local_tun, int remote_tun) |
int local_tun, int remote_tun) |
{ |
{ |
Channel *c; |
Channel *c; |
int fd; |
int r, fd; |
char *ifname = NULL; |
char *ifname = NULL; |
|
|
if (tun_mode == SSH_TUNMODE_NO) |
if (tun_mode == SSH_TUNMODE_NO) |
|
|
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); |
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); |
c->datagram = 1; |
c->datagram = 1; |
|
|
packet_start(SSH2_MSG_CHANNEL_OPEN); |
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 || |
packet_put_cstring("tun@openssh.com"); |
(r = sshpkt_put_cstring(ssh, "tun@openssh.com")) != 0 || |
packet_put_int(c->self); |
(r = sshpkt_put_u32(ssh, c->self)) != 0 || |
packet_put_int(c->local_window_max); |
(r = sshpkt_put_u32(ssh, c->local_window_max)) != 0 || |
packet_put_int(c->local_maxpacket); |
(r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 || |
packet_put_int(tun_mode); |
(r = sshpkt_put_u32(ssh, tun_mode)) != 0 || |
packet_put_int(remote_tun); |
(r = sshpkt_put_u32(ssh, remote_tun)) != 0 || |
packet_send(); |
(r = sshpkt_send(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
|
|
return ifname; |
return ifname; |
} |
} |
|
|
client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) |
client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
Channel *c = NULL; |
Channel *c = NULL; |
char *ctype; |
char *ctype = NULL; |
int rchan; |
int r; |
u_int rmaxpack, rwindow, len; |
u_int rchan; |
|
size_t len; |
|
u_int rmaxpack, rwindow; |
|
|
ctype = packet_get_string(&len); |
if ((r = sshpkt_get_cstring(ssh, &ctype, &len)) != 0 || |
rchan = packet_get_int(); |
(r = sshpkt_get_u32(ssh, &rchan)) != 0 || |
rwindow = packet_get_int(); |
(r = sshpkt_get_u32(ssh, &rwindow)) != 0 || |
rmaxpack = packet_get_int(); |
(r = sshpkt_get_u32(ssh, &rmaxpack)) != 0) |
|
goto out; |
|
|
debug("client_input_channel_open: ctype %s rchan %d win %d max %d", |
debug("client_input_channel_open: ctype %s rchan %d win %d max %d", |
ctype, rchan, rwindow, rmaxpack); |
ctype, rchan, rwindow, rmaxpack); |
|
|
c->remote_window = rwindow; |
c->remote_window = rwindow; |
c->remote_maxpacket = rmaxpack; |
c->remote_maxpacket = rmaxpack; |
if (c->type != SSH_CHANNEL_CONNECTING) { |
if (c->type != SSH_CHANNEL_CONNECTING) { |
packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); |
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 || |
packet_put_int(c->remote_id); |
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || |
packet_put_int(c->self); |
(r = sshpkt_put_u32(ssh, c->self)) != 0 || |
packet_put_int(c->local_window); |
(r = sshpkt_put_u32(ssh, c->local_window)) != 0 || |
packet_put_int(c->local_maxpacket); |
(r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 || |
packet_send(); |
(r = sshpkt_send(ssh)) != 0) |
|
sshpkt_fatal(ssh, r, "%s: send reply", __func__); |
} |
} |
} else { |
} else { |
debug("failure %s", ctype); |
debug("failure %s", ctype); |
packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); |
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 || |
packet_put_int(rchan); |
(r = sshpkt_put_u32(ssh, rchan)) != 0 || |
packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); |
(r = sshpkt_put_u32(ssh, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED)) != 0 || |
packet_put_cstring("open failed"); |
(r = sshpkt_put_cstring(ssh, "open failed")) != 0 || |
packet_put_cstring(""); |
(r = sshpkt_put_cstring(ssh, "")) != 0 || |
packet_send(); |
(r = sshpkt_send(ssh)) != 0) |
|
sshpkt_fatal(ssh, r, "%s: send failure", __func__); |
} |
} |
|
r = 0; |
|
out: |
free(ctype); |
free(ctype); |
return 0; |
return r; |
} |
} |
|
|
static int |
static int |
client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) |
client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
Channel *c = NULL; |
Channel *c = NULL; |
int exitval, id, reply, success = 0; |
char *rtype = NULL; |
char *rtype; |
u_char reply; |
|
u_int id, exitval; |
|
int r, success = 0; |
|
|
id = packet_get_int(); |
if ((r = sshpkt_get_u32(ssh, &id)) != 0) |
c = channel_lookup(ssh, id); |
return r; |
|
if (id <= INT_MAX) |
|
c = channel_lookup(ssh, id); |
if (channel_proxy_upstream(c, type, seq, ssh)) |
if (channel_proxy_upstream(c, type, seq, ssh)) |
return 0; |
return 0; |
rtype = packet_get_string(NULL); |
if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 || |
reply = packet_get_char(); |
(r = sshpkt_get_u8(ssh, &reply)) != 0) |
|
goto out; |
|
|
debug("client_input_channel_req: channel %d rtype %s reply %d", |
debug("client_input_channel_req: channel %u rtype %s reply %d", |
id, rtype, reply); |
id, rtype, reply); |
|
|
if (id == -1) { |
if (c == NULL) { |
error("client_input_channel_req: request for channel -1"); |
|
} else if (c == NULL) { |
|
error("client_input_channel_req: channel %d: " |
error("client_input_channel_req: channel %d: " |
"unknown channel", id); |
"unknown channel", id); |
} else if (strcmp(rtype, "eow@openssh.com") == 0) { |
} else if (strcmp(rtype, "eow@openssh.com") == 0) { |
packet_check_eom(); |
if ((r = sshpkt_get_end(ssh)) != 0) |
|
goto out; |
chan_rcvd_eow(ssh, c); |
chan_rcvd_eow(ssh, c); |
} else if (strcmp(rtype, "exit-status") == 0) { |
} else if (strcmp(rtype, "exit-status") == 0) { |
exitval = packet_get_int(); |
if ((r = sshpkt_get_u32(ssh, &exitval)) != 0) |
|
goto out; |
if (c->ctl_chan != -1) { |
if (c->ctl_chan != -1) { |
mux_exit_message(ssh, c, exitval); |
mux_exit_message(ssh, c, exitval); |
success = 1; |
success = 1; |
} else if (id == session_ident) { |
} else if ((int)id == session_ident) { |
/* Record exit value of local session */ |
/* Record exit value of local session */ |
success = 1; |
success = 1; |
exit_status = exitval; |
exit_status = exitval; |
|
|
debug("%s: no sink for exit-status on channel %d", |
debug("%s: no sink for exit-status on channel %d", |
__func__, id); |
__func__, id); |
} |
} |
packet_check_eom(); |
if ((r = sshpkt_get_end(ssh)) != 0) |
|
goto out; |
} |
} |
if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) { |
if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) { |
if (!c->have_remote_id) |
if (!c->have_remote_id) |
fatal("%s: channel %d: no remote_id", |
fatal("%s: channel %d: no remote_id", |
__func__, c->self); |
__func__, c->self); |
packet_start(success ? |
if ((r = sshpkt_start(ssh, success ? |
SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); |
SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE)) != 0 || |
packet_put_int(c->remote_id); |
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || |
packet_send(); |
(r = sshpkt_send(ssh)) != 0) |
|
sshpkt_fatal(ssh, r, "%s: send failure", __func__); |
} |
} |
|
r = 0; |
|
out: |
free(rtype); |
free(rtype); |
return 0; |
return r; |
} |
} |
|
|
struct hostkeys_update_ctx { |
struct hostkeys_update_ctx { |
|
|
if (ndone != ctx->nnew) |
if (ndone != ctx->nnew) |
fatal("%s: ndone != ctx->nnew (%zu / %zu)", __func__, |
fatal("%s: ndone != ctx->nnew (%zu / %zu)", __func__, |
ndone, ctx->nnew); /* Shouldn't happen */ |
ndone, ctx->nnew); /* Shouldn't happen */ |
ssh_packet_check_eom(ssh); |
if ((r = sshpkt_get_end(ssh)) != 0) { |
|
error("%s: protocol error", __func__); |
|
goto out; |
|
} |
|
|
/* Make the edits to known_hosts */ |
/* Make the edits to known_hosts */ |
update_known_hosts(ctx); |
update_known_hosts(ctx); |
|
|
client_input_global_request(int type, u_int32_t seq, struct ssh *ssh) |
client_input_global_request(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
char *rtype; |
char *rtype; |
int want_reply; |
u_char want_reply; |
int success = 0; |
int r, success = 0; |
|
|
rtype = packet_get_cstring(NULL); |
if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 || |
want_reply = packet_get_char(); |
(r = sshpkt_get_u8(ssh, &want_reply)) != 0) |
|
goto out; |
debug("client_input_global_request: rtype %s want_reply %d", |
debug("client_input_global_request: rtype %s want_reply %d", |
rtype, want_reply); |
rtype, want_reply); |
if (strcmp(rtype, "hostkeys-00@openssh.com") == 0) |
if (strcmp(rtype, "hostkeys-00@openssh.com") == 0) |
success = client_input_hostkeys(); |
success = client_input_hostkeys(); |
if (want_reply) { |
if (want_reply) { |
packet_start(success ? |
if ((r = sshpkt_start(ssh, success ? SSH2_MSG_REQUEST_SUCCESS : |
SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); |
SSH2_MSG_REQUEST_FAILURE)) != 0 || |
packet_send(); |
(r = sshpkt_send(ssh)) != 0 || |
packet_write_wait(); |
(r = ssh_packet_write_wait(ssh)) != 0) |
|
goto out; |
} |
} |
|
r = 0; |
|
out: |
free(rtype); |
free(rtype); |
return 0; |
return r; |
} |
} |
|
|
void |
void |
|
|
const char *term, struct termios *tiop, int in_fd, struct sshbuf *cmd, |
const char *term, struct termios *tiop, int in_fd, struct sshbuf *cmd, |
char **env) |
char **env) |
{ |
{ |
int i, j, matched, len; |
int i, j, matched, len, r; |
char *name, *val; |
char *name, *val; |
Channel *c = NULL; |
Channel *c = NULL; |
|
|
|
|
if ((c = channel_lookup(ssh, id)) == NULL) |
if ((c = channel_lookup(ssh, id)) == NULL) |
fatal("%s: channel %d: unknown channel", __func__, id); |
fatal("%s: channel %d: unknown channel", __func__, id); |
|
|
packet_set_interactive(want_tty, |
ssh_packet_set_interactive(ssh, want_tty, |
options.ip_qos_interactive, options.ip_qos_bulk); |
options.ip_qos_interactive, options.ip_qos_bulk); |
|
|
if (want_tty) { |
if (want_tty) { |
|
|
|
|
channel_request_start(ssh, id, "pty-req", 1); |
channel_request_start(ssh, id, "pty-req", 1); |
client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY); |
client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY); |
packet_put_cstring(term != NULL ? term : ""); |
if ((r = sshpkt_put_cstring(ssh, term != NULL ? term : "")) |
packet_put_int((u_int)ws.ws_col); |
!= 0 || |
packet_put_int((u_int)ws.ws_row); |
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_col)) != 0 || |
packet_put_int((u_int)ws.ws_xpixel); |
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_row)) != 0 || |
packet_put_int((u_int)ws.ws_ypixel); |
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 || |
|
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
if (tiop == NULL) |
if (tiop == NULL) |
tiop = get_saved_tio(); |
tiop = get_saved_tio(); |
ssh_tty_make_modes(ssh, -1, tiop); |
ssh_tty_make_modes(ssh, -1, tiop); |
packet_send(); |
if ((r = sshpkt_send(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
/* XXX wait for reply */ |
/* XXX wait for reply */ |
c->client_tty = 1; |
c->client_tty = 1; |
} |
} |
|
|
|
|
debug("Sending env %s = %s", name, val); |
debug("Sending env %s = %s", name, val); |
channel_request_start(ssh, id, "env", 0); |
channel_request_start(ssh, id, "env", 0); |
packet_put_cstring(name); |
if ((r = sshpkt_put_cstring(ssh, name)) != 0 || |
packet_put_cstring(val); |
(r = sshpkt_put_cstring(ssh, val)) != 0 || |
packet_send(); |
(r = sshpkt_send(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
free(name); |
free(name); |
} |
} |
} |
} |
|
|
|
|
debug("Setting env %s = %s", name, val); |
debug("Setting env %s = %s", name, val); |
channel_request_start(ssh, id, "env", 0); |
channel_request_start(ssh, id, "env", 0); |
packet_put_cstring(name); |
if ((r = sshpkt_put_cstring(ssh, name)) != 0 || |
packet_put_cstring(val); |
(r = sshpkt_put_cstring(ssh, val)) != 0 || |
packet_send(); |
(r = sshpkt_send(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
free(name); |
free(name); |
} |
} |
|
|
|
|
channel_request_start(ssh, id, "exec", 1); |
channel_request_start(ssh, id, "exec", 1); |
client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE); |
client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE); |
} |
} |
packet_put_string(sshbuf_ptr(cmd), sshbuf_len(cmd)); |
if ((r = sshpkt_put_stringb(ssh, cmd)) != 0 || |
packet_send(); |
(r = sshpkt_send(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
} else { |
} else { |
channel_request_start(ssh, id, "shell", 1); |
channel_request_start(ssh, id, "shell", 1); |
client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE); |
client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE); |
packet_send(); |
if ((r = sshpkt_send(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
} |
} |
} |
} |
|
|