=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/clientloop.c,v retrieving revision 1.105.2.2 retrieving revision 1.106 diff -u -r1.105.2.2 -r1.106 --- src/usr.bin/ssh/clientloop.c 2004/03/04 18:18:15 1.105.2.2 +++ src/usr.bin/ssh/clientloop.c 2003/04/01 10:10:23 1.106 @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.105.2.2 2004/03/04 18:18:15 brad Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.106 2003/04/01 10:10:23 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -89,9 +89,6 @@ /* Flag indicating that stdin should be redirected from /dev/null. */ extern int stdin_null_flag; -/* Flag indicating that no shell has been requested */ -extern int no_shell_flag; - /* * Name of the host we are connecting to. This is the name given on the * command line, or the HostName specified for the user-supplied name in a @@ -127,7 +124,6 @@ static int connection_out; /* Connection to server (output). */ static int need_rekeying; /* Set to non-zero if rekeying is requested. */ static int session_closed = 0; /* In SSH2: login session closed. */ -static int server_alive_timeouts = 0; static void client_init_dispatch(void); int session_ident = -1; @@ -143,6 +139,7 @@ if (in_non_blocking_mode) { (void) fcntl(fileno(stdin), F_SETFL, 0); in_non_blocking_mode = 0; + fatal_remove_cleanup((void (*) (void *)) leave_non_blocking, NULL); } } @@ -153,6 +150,7 @@ { in_non_blocking_mode = 1; (void) fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + fatal_add_cleanup((void (*) (void *)) leave_non_blocking, NULL); } /* @@ -314,24 +312,6 @@ } } -static void -client_global_request_reply(int type, u_int32_t seq, void *ctxt) -{ - server_alive_timeouts = 0; - client_global_request_reply_fwd(type, seq, ctxt); -} - -static void -server_alive_check(void) -{ - if (++server_alive_timeouts > options.server_alive_count_max) - packet_disconnect("Timeout, server not responding."); - packet_start(SSH2_MSG_GLOBAL_REQUEST); - packet_put_cstring("keepalive@openssh.com"); - packet_put_char(1); /* boolean: want reply */ - packet_send(); -} - /* * Waits until the client can do something (some data becomes available on * one of the file descriptors). @@ -341,9 +321,6 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, int *nallocp, int rekeying) { - struct timeval tv, *tvp; - int ret; - /* Add any selections by the channel mechanism. */ channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying); @@ -385,18 +362,13 @@ /* * Wait for something to happen. This will suspend the process until * some selected descriptor can be read, written, or has some other - * event pending. + * event pending. Note: if you want to implement SSH_MSG_IGNORE + * messages to fool traffic analysis, this might be the place to do + * it: just have a random timeout for the select, and send a random + * SSH_MSG_IGNORE packet when the timeout expires. */ - if (options.server_alive_interval == 0 || !compat20) - tvp = NULL; - else { - tv.tv_sec = options.server_alive_interval; - tv.tv_usec = 0; - tvp = &tv; - } - ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); - if (ret < 0) { + if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) { char buf[100]; /* @@ -413,8 +385,7 @@ snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); buffer_append(&stderr_buffer, buf, strlen(buf)); quit_pending = 1; - } else if (ret == 0) - server_alive_check(); + } } static void @@ -424,9 +395,9 @@ /* Flush stdout and stderr buffers. */ if (buffer_len(bout) > 0) - atomicio(vwrite, fileno(stdout), buffer_ptr(bout), buffer_len(bout)); + atomicio(write, fileno(stdout), buffer_ptr(bout), buffer_len(bout)); if (buffer_len(berr) > 0) - atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); + atomicio(write, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); leave_raw_mode(); @@ -519,13 +490,13 @@ if (*s == 0) goto out; if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) { - logit("Invalid command."); + log("Invalid command."); goto out; } if (s[1] == 'L') local = 1; if (!local && !compat20) { - logit("Not supported for SSH protocol version 1."); + log("Not supported for SSH protocol version 1."); goto out; } s += 2; @@ -536,24 +507,24 @@ sfwd_port, buf, sfwd_host_port) != 3 && sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]", sfwd_port, buf, sfwd_host_port) != 3) { - logit("Bad forwarding specification."); + log("Bad forwarding specification."); goto out; } if ((fwd_port = a2port(sfwd_port)) == 0 || (fwd_host_port = a2port(sfwd_host_port)) == 0) { - logit("Bad forwarding port(s)."); + log("Bad forwarding port(s)."); goto out; } if (local) { if (channel_setup_local_fwd_listener(fwd_port, buf, fwd_host_port, options.gateway_ports) < 0) { - logit("Port forwarding failed."); + log("Port forwarding failed."); goto out; } } else channel_request_remote_forwarding(fwd_port, buf, fwd_host_port); - logit("Forwarding port."); + log("Forwarding port."); out: signal(SIGINT, handler); enter_raw_mode(); @@ -603,23 +574,10 @@ /* We have been continued. */ continue; - case 'B': - if (compat20) { - snprintf(string, sizeof string, - "%cB\r\n", escape_char); - buffer_append(berr, string, - strlen(string)); - channel_request_start(session_ident, - "break", 0); - packet_put_int(1000); - packet_send(); - } - continue; - case 'R': if (compat20) { if (datafellows & SSH_BUG_NOREKEY) - logit("Server does not support re-keying"); + log("Server does not support re-keying"); else need_rekeying = 1; } @@ -678,7 +636,6 @@ "%c?\r\n\ Supported escape sequences:\r\n\ %c. - terminate connection\r\n\ -%cB - send a BREAK to the remote system\r\n\ %cC - open a command line\r\n\ %cR - Request rekey (SSH protocol 2 only)\r\n\ %c^Z - suspend ssh\r\n\ @@ -689,7 +646,7 @@ (Note that escapes are only recognized immediately after newline.)\r\n", escape_char, escape_char, escape_char, escape_char, escape_char, escape_char, escape_char, escape_char, - escape_char, escape_char, escape_char); + escape_char, escape_char); buffer_append(berr, string, strlen(string)); continue; @@ -873,7 +830,8 @@ id, session_ident); channel_cancel_cleanup(id); session_closed = 1; - leave_raw_mode(); + if (in_raw_mode()) + leave_raw_mode(); } /* @@ -1062,19 +1020,12 @@ if (!isatty(fileno(stderr))) unset_nonblock(fileno(stderr)); - /* - * If there was no shell or command requested, there will be no remote - * exit status to be returned. In that case, clear error code if the - * connection was deliberately terminated at this end. - */ - if (no_shell_flag && received_signal == SIGTERM) { - received_signal = 0; - exit_status = 0; + if (received_signal) { + if (in_non_blocking_mode) /* XXX */ + leave_non_blocking(); + fatal("Killed by signal %d.", (int) received_signal); } - if (received_signal) - fatal("Killed by signal %d.", (int) received_signal); - /* * In interactive mode (with pseudo tty) display a message indicating * that the connection has been closed. @@ -1166,47 +1117,7 @@ /* Flag that we want to exit. */ quit_pending = 1; } -static void -client_input_agent_open(int type, u_int32_t seq, void *ctxt) -{ - Channel *c = NULL; - int remote_id, sock; - /* Read the remote channel number from the message. */ - remote_id = packet_get_int(); - packet_check_eom(); - - /* - * Get a connection to the local authentication agent (this may again - * get forwarded). - */ - sock = ssh_get_authentication_socket(); - - /* - * If we could not connect the agent, send an error message back to - * the server. This should never happen unless the agent dies, - * because authentication forwarding is only enabled if we have an - * agent. - */ - if (sock >= 0) { - c = channel_new("", SSH_CHANNEL_OPEN, sock, sock, - -1, 0, 0, 0, "authentication agent connection", 1); - c->remote_id = remote_id; - c->force_drain = 1; - } - if (c == NULL) { - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(remote_id); - } else { - /* Send a confirmation to the remote host. */ - debug("Forwarding authentication connection."); - packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(remote_id); - packet_put_int(c->self); - } - packet_send(); -} - static Channel * client_request_forwarded_tcpip(const char *request_type, int rchan) { @@ -1234,7 +1145,7 @@ c = channel_new("forwarded-tcpip", SSH_CHANNEL_CONNECTING, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, - originator_address, 1); + xstrdup(originator_address), 1); xfree(originator_address); xfree(listen_address); return c; @@ -1270,7 +1181,8 @@ return NULL; c = channel_new("x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); + CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, + xstrdup("x11"), 1); c->force_drain = 1; return c; } @@ -1292,7 +1204,7 @@ c = channel_new("authentication agent connection", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, - "authentication agent connection", 1); + xstrdup("authentication agent connection"), 1); c->force_drain = 1; return c; } @@ -1393,8 +1305,7 @@ rtype = packet_get_string(NULL); want_reply = packet_get_char(); - debug("client_input_global_request: rtype %s want_reply %d", - rtype, want_reply); + debug("client_input_global_request: rtype %s want_reply %d", rtype, want_reply); if (want_reply) { packet_start(success ? SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); @@ -1442,7 +1353,7 @@ dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data); dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ? - &client_input_agent_open : &deny_input_open); + &auth_input_open_request : &deny_input_open); dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ? &x11_input_open : &deny_input_open); } @@ -1462,13 +1373,4 @@ client_init_dispatch_13(); else client_init_dispatch_15(); -} - -/* client specific fatal cleanup */ -void -cleanup_exit(int i) -{ - leave_raw_mode(); - leave_non_blocking(); - _exit(i); }