version 1.320, 2019/01/19 21:33:57 |
version 1.321, 2019/01/19 21:39:12 |
|
|
#include "ssherr.h" |
#include "ssherr.h" |
#include "hostfile.h" |
#include "hostfile.h" |
|
|
#include "opacket.h" /* XXX */ |
|
extern struct ssh *active_state; /* XXX */ |
|
|
|
/* import options */ |
/* import options */ |
extern Options options; |
extern Options options; |
|
|
|
|
static int session_closed; /* In SSH2: login session closed. */ |
static int session_closed; /* In SSH2: login session closed. */ |
static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ |
static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ |
|
|
static void client_init_dispatch(void); |
static void client_init_dispatch(struct ssh *ssh); |
int session_ident = -1; |
int session_ident = -1; |
|
|
/* Track escape per proto2 channel */ |
/* Track escape per proto2 channel */ |
|
|
int r, ret; |
int r, ret; |
|
|
/* Add any selections by the channel mechanism. */ |
/* Add any selections by the channel mechanism. */ |
channel_prepare_select(active_state, readsetp, writesetp, maxfdp, |
channel_prepare_select(ssh, readsetp, writesetp, maxfdp, |
nallocp, &minwait_secs); |
nallocp, &minwait_secs); |
|
|
/* channel_prepare_select could have closed the last channel */ |
/* channel_prepare_select could have closed the last channel */ |
|
|
*/ |
*/ |
|
|
static void |
static void |
client_process_buffered_input_packets(void) |
client_process_buffered_input_packets(struct ssh *ssh) |
{ |
{ |
ssh_dispatch_run_fatal(active_state, DISPATCH_NONBLOCK, &quit_pending); |
ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, &quit_pending); |
} |
} |
|
|
/* scan buf[] for '~' before sending data to the peer */ |
/* scan buf[] for '~' before sending data to the peer */ |
|
|
if ((stderr_buffer = sshbuf_new()) == NULL) |
if ((stderr_buffer = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal("%s: sshbuf_new failed", __func__); |
|
|
client_init_dispatch(); |
client_init_dispatch(ssh); |
|
|
/* |
/* |
* Set signal handlers, (e.g. to restore non-blocking mode) |
* Set signal handlers, (e.g. to restore non-blocking mode) |
|
|
while (!quit_pending) { |
while (!quit_pending) { |
|
|
/* Process buffered packets sent by the server. */ |
/* Process buffered packets sent by the server. */ |
client_process_buffered_input_packets(); |
client_process_buffered_input_packets(ssh); |
|
|
if (session_closed && !channel_still_open(ssh)) |
if (session_closed && !channel_still_open(ssh)) |
break; |
break; |
|
|
{ |
{ |
Channel *c = NULL; |
Channel *c = NULL; |
char *originator; |
char *originator; |
int originator_port; |
u_int originator_port; |
int r, sock; |
int r, sock; |
|
|
if (!options.forward_x11) { |
if (!options.forward_x11) { |
|
|
return NULL; |
return NULL; |
} |
} |
if ((r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 || |
if ((r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 || |
(r = sshpkt_get_u32(ssh, (u_int *)&originator_port)) != 0 || |
(r = sshpkt_get_u32(ssh, &originator_port)) != 0 || |
(r = sshpkt_get_end(ssh)) != 0) |
(r = sshpkt_get_end(ssh)) != 0) |
fatal("%s: %s", __func__, ssh_err(r)); |
fatal("%s: %s", __func__, ssh_err(r)); |
/* XXX check permission */ |
/* XXX check permission */ |
debug("client_request_x11: request from %s %d", originator, |
/* XXX range check originator port? */ |
|
debug("client_request_x11: request from %s %u", originator, |
originator_port); |
originator_port); |
free(originator); |
free(originator); |
sock = x11_connect_display(ssh); |
sock = x11_connect_display(ssh); |
|
|
(r = sshpkt_put_u32(ssh, tun_mode)) != 0 || |
(r = sshpkt_put_u32(ssh, tun_mode)) != 0 || |
(r = sshpkt_put_u32(ssh, remote_tun)) != 0 || |
(r = sshpkt_put_u32(ssh, remote_tun)) != 0 || |
(r = sshpkt_send(ssh)) != 0) |
(r = sshpkt_send(ssh)) != 0) |
fatal("%s: %s", __func__, ssh_err(r)); |
sshpkt_fatal(ssh, r, "%s: send reply", __func__); |
|
|
return ifname; |
return ifname; |
} |
} |
|
|
* HostkeyAlgorithms preference before they are accepted. |
* HostkeyAlgorithms preference before they are accepted. |
*/ |
*/ |
static int |
static int |
client_input_hostkeys(void) |
client_input_hostkeys(struct ssh *ssh) |
{ |
{ |
struct ssh *ssh = active_state; /* XXX */ |
|
const u_char *blob = NULL; |
const u_char *blob = NULL; |
size_t i, len = 0; |
size_t i, len = 0; |
struct sshbuf *buf = NULL; |
struct sshbuf *buf = NULL; |
|
|
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(ssh); |
if (want_reply) { |
if (want_reply) { |
if ((r = sshpkt_start(ssh, success ? SSH2_MSG_REQUEST_SUCCESS : |
if ((r = sshpkt_start(ssh, success ? SSH2_MSG_REQUEST_SUCCESS : |
SSH2_MSG_REQUEST_FAILURE)) != 0 || |
SSH2_MSG_REQUEST_FAILURE)) != 0 || |
|
|
} |
} |
|
|
static void |
static void |
client_init_dispatch(void) |
client_init_dispatch(struct ssh *ssh) |
{ |
{ |
dispatch_init(&dispatch_protocol_error); |
ssh_dispatch_init(ssh, &dispatch_protocol_error); |
|
|
dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); |
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); |
dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); |
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_DATA, &channel_input_data); |
dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); |
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); |
dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); |
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); |
dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); |
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); |
dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); |
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); |
dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); |
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); |
dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); |
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); |
dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); |
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); |
dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm); |
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm); |
dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm); |
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm); |
dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request); |
ssh_dispatch_set(ssh, SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request); |
|
|
/* rekeying */ |
/* rekeying */ |
dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); |
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); |
|
|
/* global request reply messages */ |
/* global request reply messages */ |
dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); |
ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); |
dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); |
ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); |
} |
} |
|
|
void |
void |