summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c106
1 files changed, 70 insertions, 36 deletions
diff --git a/clientloop.c b/clientloop.c
index 37cecf5a6..663daae76 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.196 2008/06/12 04:06:00 djm Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.197 2008/06/12 04:17:47 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -147,8 +147,8 @@ static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
147static int escape_char1; /* Escape character. (proto1 only) */ 147static int escape_char1; /* Escape character. (proto1 only) */
148static int escape_pending1; /* Last character was an escape (proto1 only) */ 148static int escape_pending1; /* Last character was an escape (proto1 only) */
149static int last_was_cr; /* Last character was a newline. */ 149static int last_was_cr; /* Last character was a newline. */
150static int exit_status; /* Used to store the exit status of the command. */ 150static int exit_status; /* Used to store the command exit status. */
151static int stdin_eof; /* EOF has been encountered on standard error. */ 151static int stdin_eof; /* EOF has been encountered on stderr. */
152static Buffer stdin_buffer; /* Buffer for stdin data. */ 152static Buffer stdin_buffer; /* Buffer for stdin data. */
153static Buffer stdout_buffer; /* Buffer for stdout data. */ 153static Buffer stdout_buffer; /* Buffer for stdout data. */
154static Buffer stderr_buffer; /* Buffer for stderr data. */ 154static Buffer stderr_buffer; /* Buffer for stderr data. */
@@ -392,7 +392,10 @@ client_check_initial_eof_on_stdin(void)
392 /* Check for immediate EOF on stdin. */ 392 /* Check for immediate EOF on stdin. */
393 len = read(fileno(stdin), buf, 1); 393 len = read(fileno(stdin), buf, 1);
394 if (len == 0) { 394 if (len == 0) {
395 /* EOF. Record that we have seen it and send EOF to server. */ 395 /*
396 * EOF. Record that we have seen it and send
397 * EOF to server.
398 */
396 debug("Sending eof."); 399 debug("Sending eof.");
397 stdin_eof = 1; 400 stdin_eof = 1;
398 packet_start(SSH_CMSG_EOF); 401 packet_start(SSH_CMSG_EOF);
@@ -601,9 +604,11 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
601{ 604{
602 /* Flush stdout and stderr buffers. */ 605 /* Flush stdout and stderr buffers. */
603 if (buffer_len(bout) > 0) 606 if (buffer_len(bout) > 0)
604 atomicio(vwrite, fileno(stdout), buffer_ptr(bout), buffer_len(bout)); 607 atomicio(vwrite, fileno(stdout), buffer_ptr(bout),
608 buffer_len(bout));
605 if (buffer_len(berr) > 0) 609 if (buffer_len(berr) > 0)
606 atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); 610 atomicio(vwrite, fileno(stderr), buffer_ptr(berr),
611 buffer_len(berr));
607 612
608 leave_raw_mode(); 613 leave_raw_mode();
609 614
@@ -643,9 +648,13 @@ client_process_net_input(fd_set *readset)
643 /* Read as much as possible. */ 648 /* Read as much as possible. */
644 len = read(connection_in, buf, sizeof(buf)); 649 len = read(connection_in, buf, sizeof(buf));
645 if (len == 0) { 650 if (len == 0) {
646 /* Received EOF. The remote host has closed the connection. */ 651 /*
647 snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", 652 * Received EOF. The remote host has closed the
648 host); 653 * connection.
654 */
655 snprintf(buf, sizeof buf,
656 "Connection to %.300s closed by remote host.\r\n",
657 host);
649 buffer_append(&stderr_buffer, buf, strlen(buf)); 658 buffer_append(&stderr_buffer, buf, strlen(buf));
650 quit_pending = 1; 659 quit_pending = 1;
651 return; 660 return;
@@ -658,9 +667,13 @@ client_process_net_input(fd_set *readset)
658 len = 0; 667 len = 0;
659 668
660 if (len < 0) { 669 if (len < 0) {
661 /* An error has encountered. Perhaps there is a network problem. */ 670 /*
662 snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n", 671 * An error has encountered. Perhaps there is a
663 host, strerror(errno)); 672 * network problem.
673 */
674 snprintf(buf, sizeof buf,
675 "Read from remote host %.300s: %.100s\r\n",
676 host, strerror(errno));
664 buffer_append(&stderr_buffer, buf, strlen(buf)); 677 buffer_append(&stderr_buffer, buf, strlen(buf));
665 quit_pending = 1; 678 quit_pending = 1;
666 return; 679 return;
@@ -932,8 +945,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
932 strlen(string)); 945 strlen(string));
933 continue; 946 continue;
934 } 947 }
935 /* Suspend the program. */ 948 /* Suspend the program. Inform the user */
936 /* Print a message to that effect to the user. */
937 snprintf(string, sizeof string, 949 snprintf(string, sizeof string,
938 "%c^Z [suspend ssh]\r\n", escape_char); 950 "%c^Z [suspend ssh]\r\n", escape_char);
939 buffer_append(berr, string, strlen(string)); 951 buffer_append(berr, string, strlen(string));
@@ -960,7 +972,8 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
960 case 'R': 972 case 'R':
961 if (compat20) { 973 if (compat20) {
962 if (datafellows & SSH_BUG_NOREKEY) 974 if (datafellows & SSH_BUG_NOREKEY)
963 logit("Server does not support re-keying"); 975 logit("Server does not "
976 "support re-keying");
964 else 977 else
965 need_rekeying = 1; 978 need_rekeying = 1;
966 } 979 }
@@ -970,8 +983,9 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
970 if (c && c->ctl_fd != -1) 983 if (c && c->ctl_fd != -1)
971 goto noescape; 984 goto noescape;
972 /* 985 /*
973 * Detach the program (continue to serve connections, 986 * Detach the program (continue to serve
974 * but put in background and no more new connections). 987 * connections, but put in background and no
988 * more new connections).
975 */ 989 */
976 /* Restore tty modes. */ 990 /* Restore tty modes. */
977 leave_raw_mode(); 991 leave_raw_mode();
@@ -1000,9 +1014,9 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1000 return -1; 1014 return -1;
1001 } else if (!stdin_eof) { 1015 } else if (!stdin_eof) {
1002 /* 1016 /*
1003 * Sending SSH_CMSG_EOF alone does not always appear 1017 * Sending SSH_CMSG_EOF alone does not
1004 * to be enough. So we try to send an EOF character 1018 * always appear to be enough. So we
1005 * first. 1019 * try to send an EOF character first.
1006 */ 1020 */
1007 packet_start(SSH_CMSG_STDIN_DATA); 1021 packet_start(SSH_CMSG_STDIN_DATA);
1008 packet_put_string("\004", 1); 1022 packet_put_string("\004", 1);
@@ -1081,11 +1095,14 @@ Supported escape sequences:\r\n\
1081 } 1095 }
1082 } else { 1096 } else {
1083 /* 1097 /*
1084 * The previous character was not an escape char. Check if this 1098 * The previous character was not an escape char.
1085 * is an escape. 1099 * Check if this is an escape.
1086 */ 1100 */
1087 if (last_was_cr && ch == escape_char) { 1101 if (last_was_cr && ch == escape_char) {
1088 /* It is. Set the flag and continue to next character. */ 1102 /*
1103 * It is. Set the flag and continue to
1104 * next character.
1105 */
1089 *escape_pendingp = 1; 1106 *escape_pendingp = 1;
1090 continue; 1107 continue;
1091 } 1108 }
@@ -1121,7 +1138,8 @@ client_process_input(fd_set *readset)
1121 * if it was an error condition. 1138 * if it was an error condition.
1122 */ 1139 */
1123 if (len < 0) { 1140 if (len < 0) {
1124 snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno)); 1141 snprintf(buf, sizeof buf, "read: %.100s\r\n",
1142 strerror(errno));
1125 buffer_append(&stderr_buffer, buf, strlen(buf)); 1143 buffer_append(&stderr_buffer, buf, strlen(buf));
1126 } 1144 }
1127 /* Mark that we have seen EOF. */ 1145 /* Mark that we have seen EOF. */
@@ -1145,8 +1163,9 @@ client_process_input(fd_set *readset)
1145 buffer_append(&stdin_buffer, buf, len); 1163 buffer_append(&stdin_buffer, buf, len);
1146 } else { 1164 } else {
1147 /* 1165 /*
1148 * Normal, successful read. But we have an escape character 1166 * Normal, successful read. But we have an escape
1149 * and have to process the characters one by one. 1167 * character and have to process the characters one
1168 * by one.
1150 */ 1169 */
1151 if (process_escapes(NULL, &stdin_buffer, 1170 if (process_escapes(NULL, &stdin_buffer,
1152 &stdout_buffer, &stderr_buffer, buf, len) == -1) 1171 &stdout_buffer, &stderr_buffer, buf, len) == -1)
@@ -1174,7 +1193,8 @@ client_process_output(fd_set *writeset)
1174 * An error or EOF was encountered. Put an 1193 * An error or EOF was encountered. Put an
1175 * error message to stderr buffer. 1194 * error message to stderr buffer.
1176 */ 1195 */
1177 snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno)); 1196 snprintf(buf, sizeof buf,
1197 "write stdout: %.50s\r\n", strerror(errno));
1178 buffer_append(&stderr_buffer, buf, strlen(buf)); 1198 buffer_append(&stderr_buffer, buf, strlen(buf));
1179 quit_pending = 1; 1199 quit_pending = 1;
1180 return; 1200 return;
@@ -1193,7 +1213,10 @@ client_process_output(fd_set *writeset)
1193 if (errno == EINTR || errno == EAGAIN) 1213 if (errno == EINTR || errno == EAGAIN)
1194 len = 0; 1214 len = 0;
1195 else { 1215 else {
1196 /* EOF or error, but can't even print error message. */ 1216 /*
1217 * EOF or error, but can't even print
1218 * error message.
1219 */
1197 quit_pending = 1; 1220 quit_pending = 1;
1198 return; 1221 return;
1199 } 1222 }
@@ -1219,7 +1242,8 @@ client_process_output(fd_set *writeset)
1219static void 1242static void
1220client_process_buffered_input_packets(void) 1243client_process_buffered_input_packets(void)
1221{ 1244{
1222 dispatch_run(DISPATCH_NONBLOCK, &quit_pending, compat20 ? xxx_kex : NULL); 1245 dispatch_run(DISPATCH_NONBLOCK, &quit_pending,
1246 compat20 ? xxx_kex : NULL);
1223} 1247}
1224 1248
1225/* scan buf[] for '~' before sending data to the peer */ 1249/* scan buf[] for '~' before sending data to the peer */
@@ -1423,7 +1447,10 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1423 client_process_output(writeset); 1447 client_process_output(writeset);
1424 } 1448 }
1425 1449
1426 /* Send as much buffered packet data as possible to the sender. */ 1450 /*
1451 * Send as much buffered packet data as possible to the
1452 * sender.
1453 */
1427 if (FD_ISSET(connection_out, writeset)) 1454 if (FD_ISSET(connection_out, writeset))
1428 packet_write_poll(); 1455 packet_write_poll();
1429 } 1456 }
@@ -1468,7 +1495,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1468 * that the connection has been closed. 1495 * that the connection has been closed.
1469 */ 1496 */
1470 if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { 1497 if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {
1471 snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host); 1498 snprintf(buf, sizeof buf,
1499 "Connection to %.64s closed.\r\n", host);
1472 buffer_append(&stderr_buffer, buf, strlen(buf)); 1500 buffer_append(&stderr_buffer, buf, strlen(buf));
1473 } 1501 }
1474 1502
@@ -1504,8 +1532,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1504 1532
1505 /* Report bytes transferred, and transfer rates. */ 1533 /* Report bytes transferred, and transfer rates. */
1506 total_time = get_current_time() - start_time; 1534 total_time = get_current_time() - start_time;
1507 debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds", 1535 debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f "
1508 stdin_bytes, stdout_bytes, stderr_bytes, total_time); 1536 "seconds", stdin_bytes, stdout_bytes, stderr_bytes, total_time);
1509 if (total_time > 0) 1537 if (total_time > 0)
1510 debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f", 1538 debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f",
1511 stdin_bytes / total_time, stdout_bytes / total_time, 1539 stdin_bytes / total_time, stdout_bytes / total_time,
@@ -1631,7 +1659,8 @@ client_request_x11(const char *request_type, int rchan)
1631 1659
1632 if (!options.forward_x11) { 1660 if (!options.forward_x11) {
1633 error("Warning: ssh server tried X11 forwarding."); 1661 error("Warning: ssh server tried X11 forwarding.");
1634 error("Warning: this is probably a break-in attempt by a malicious server."); 1662 error("Warning: this is probably a break-in attempt by a "
1663 "malicious server.");
1635 return NULL; 1664 return NULL;
1636 } 1665 }
1637 originator = packet_get_string(NULL); 1666 originator = packet_get_string(NULL);
@@ -1664,7 +1693,8 @@ client_request_agent(const char *request_type, int rchan)
1664 1693
1665 if (!options.forward_agent) { 1694 if (!options.forward_agent) {
1666 error("Warning: ssh server tried agent forwarding."); 1695 error("Warning: ssh server tried agent forwarding.");
1667 error("Warning: this is probably a break-in attempt by a malicious server."); 1696 error("Warning: this is probably a break-in attempt by a "
1697 "malicious server.");
1668 return NULL; 1698 return NULL;
1669 } 1699 }
1670 sock = ssh_get_authentication_socket(); 1700 sock = ssh_get_authentication_socket();
@@ -1790,7 +1820,8 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
1790 if (id == -1) { 1820 if (id == -1) {
1791 error("client_input_channel_req: request for channel -1"); 1821 error("client_input_channel_req: request for channel -1");
1792 } else if ((c = channel_lookup(id)) == NULL) { 1822 } else if ((c = channel_lookup(id)) == NULL) {
1793 error("client_input_channel_req: channel %d: unknown channel", id); 1823 error("client_input_channel_req: channel %d: "
1824 "unknown channel", id);
1794 } else if (strcmp(rtype, "eow@openssh.com") == 0) { 1825 } else if (strcmp(rtype, "eow@openssh.com") == 0) {
1795 packet_check_eom(); 1826 packet_check_eom();
1796 chan_rcvd_eow(c); 1827 chan_rcvd_eow(c);
@@ -1956,6 +1987,7 @@ client_init_dispatch_20(void)
1956 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); 1987 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
1957 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); 1988 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
1958} 1989}
1990
1959static void 1991static void
1960client_init_dispatch_13(void) 1992client_init_dispatch_13(void)
1961{ 1993{
@@ -1975,6 +2007,7 @@ client_init_dispatch_13(void)
1975 dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ? 2007 dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?
1976 &x11_input_open : &deny_input_open); 2008 &x11_input_open : &deny_input_open);
1977} 2009}
2010
1978static void 2011static void
1979client_init_dispatch_15(void) 2012client_init_dispatch_15(void)
1980{ 2013{
@@ -1982,6 +2015,7 @@ client_init_dispatch_15(void)
1982 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); 2015 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
1983 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); 2016 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);
1984} 2017}
2018
1985static void 2019static void
1986client_init_dispatch(void) 2020client_init_dispatch(void)
1987{ 2021{