X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/a8be9f800cf90e7d296951556739de21d2f93382..60688ef9ba2f7c18351abc5cf7506e8afe3e5c87:/clientloop.c diff --git a/clientloop.c b/clientloop.c index 5d599a28..47ef2fc9 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,17 +1,17 @@ /* - * + * * clientloop.c - * + * * Author: Tatu Ylonen - * + * * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved - * - * + * + * * Created: Sat Sep 23 12:23:57 1995 ylo - * + * * The main loop for the interactive session (client side). - * + * * SSH2 support added by Markus Friedl. */ @@ -83,7 +83,7 @@ int session_ident = -1; /* Returns the user\'s terminal to normal mode if it had been put in raw mode. */ -void +void leave_raw_mode() { if (!in_raw_mode) @@ -97,7 +97,7 @@ leave_raw_mode() /* Puts the user\'s terminal in raw mode. */ -void +void enter_raw_mode() { struct termios tio; @@ -123,7 +123,7 @@ enter_raw_mode() /* Restores stdin to blocking mode. */ -void +void leave_non_blocking() { if (in_non_blocking_mode) { @@ -135,7 +135,7 @@ leave_non_blocking() /* Puts stdin terminal in non-blocking mode. */ -void +void enter_non_blocking() { in_non_blocking_mode = 1; @@ -148,7 +148,7 @@ enter_non_blocking() * flag indicating that the window has changed. */ -void +void window_change_handler(int sig) { received_window_change_signal = 1; @@ -160,7 +160,7 @@ window_change_handler(int sig) * signals must be trapped to restore terminal modes. */ -void +void signal_handler(int sig) { if (in_raw_mode) @@ -177,7 +177,7 @@ signal_handler(int sig) * available resolution. */ -double +double get_current_time() { struct timeval tv; @@ -191,7 +191,7 @@ get_current_time() * not appear to wake up when redirecting from /dev/null. */ -void +void client_check_initial_eof_on_stdin() { int len; @@ -245,7 +245,7 @@ client_check_initial_eof_on_stdin() * connection. */ -void +void client_make_packets_from_stdin_data() { unsigned int len; @@ -276,7 +276,7 @@ client_make_packets_from_stdin_data() * appropriate. */ -void +void client_check_window_change() { struct winsize ws; @@ -313,7 +313,7 @@ client_check_window_change() * one of the file descriptors). */ -void +void client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) { /*debug("client_wait_until_can_do_something"); */ @@ -380,7 +380,7 @@ client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) } } -void +void client_suspend_self() { struct winsize oldws, newws; @@ -425,7 +425,7 @@ client_suspend_self() enter_raw_mode(); } -void +void client_process_net_input(fd_set * readset) { int len; @@ -468,10 +468,11 @@ client_process_net_input(fd_set * readset) } } -void +void client_process_input(fd_set * readset) { - int len, pid; + int len; + pid_t pid; char buf[8192], *s; /* Read input from stdin. */ @@ -657,7 +658,7 @@ Supported escape sequences:\r\n\ } } -void +void client_process_output(fd_set * writeset) { int len; @@ -717,7 +718,7 @@ client_process_output(fd_set * writeset) * preparatory phase. */ -void +void client_process_buffered_input_packets() { dispatch_run(DISPATCH_NONBLOCK, &quit_pending); @@ -730,7 +731,7 @@ client_process_buffered_input_packets() * character for terminating or suspending the session. */ -int +int client_loop(int have_pty, int escape_char_arg) { extern Options options; @@ -953,7 +954,75 @@ client_input_exit_status(int type, int plen) quit_pending = 1; } -void +/* XXXX move to generic input handler */ +void +client_input_channel_open(int type, int plen) +{ + Channel *c = NULL; + char *ctype; + int id; + unsigned int len; + int rchan; + int rmaxpack; + int rwindow; + + ctype = packet_get_string(&len); + rchan = packet_get_int(); + rwindow = packet_get_int(); + rmaxpack = packet_get_int(); + + debug("client_input_channel_open: ctype %s rchan %d win %d max %d", + ctype, rchan, rwindow, rmaxpack); + + if (strcmp(ctype, "x11") == 0) { + int sock; + char *originator; + int originator_port; + originator = packet_get_string(NULL); + if (datafellows & SSH_BUG_X11FWD) { + debug("buggy server: x11 request w/o originator_port"); + originator_port = 0; + } else { + originator_port = packet_get_int(); + } + packet_done(); + /* XXX check permission */ + xfree(originator); + /* XXX move to channels.c */ + sock = x11_connect_display(); + if (sock >= 0) { + id = channel_new("x11", SSH_CHANNEL_X11_OPEN, + sock, sock, -1, 4*1024, 32*1024, 0, + xstrdup("x11")); + c = channel_lookup(id); + } + } +/* XXX duplicate : */ + if (c != NULL) { + debug("confirm %s", ctype); + c->remote_id = rchan; + c->remote_window = rwindow; + c->remote_maxpacket = rmaxpack; + + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + packet_send(); + } else { + debug("failure %s", ctype); + packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(rchan); + packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); + packet_put_cstring("bla bla"); + packet_put_cstring(""); + packet_send(); + } + xfree(ctype); +} + +void client_init_dispatch_20() { dispatch_init(&dispatch_protocol_error); @@ -961,19 +1030,19 @@ client_init_dispatch_20() dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); + dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request); dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); } -void +void client_init_dispatch_13() { dispatch_init(NULL); dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); - dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); @@ -983,14 +1052,14 @@ client_init_dispatch_13() dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data); dispatch_set(SSH_SMSG_X11_OPEN, &x11_input_open); } -void +void client_init_dispatch_15() { client_init_dispatch_13(); dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); } -void +void client_init_dispatch() { if (compat20) @@ -1013,7 +1082,7 @@ client_input_channel_req(int id, void *arg) rtype = packet_get_string(&len); reply = packet_get_char(); - debug("session_input_channel_req: rtype %s reply %d", rtype, reply); + debug("client_input_channel_req: rtype %s reply %d", rtype, reply); c = channel_lookup(id); if (c == NULL) @@ -1027,6 +1096,7 @@ client_input_channel_req(int id, void *arg) } else if (strcmp(rtype, "exit-status") == 0) { success = 1; exit_status = packet_get_int(); + packet_done(); } if (reply) { packet_start(success ?