diff options
Diffstat (limited to 'clientloop.c')
-rw-r--r-- | clientloop.c | 107 |
1 files changed, 73 insertions, 34 deletions
diff --git a/clientloop.c b/clientloop.c index 5621768b5..ae93dcdf3 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.178 2007/02/20 10:25:14 djm Exp $ */ | ||
1 | /* | 2 | /* |
2 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -59,20 +60,43 @@ | |||
59 | */ | 60 | */ |
60 | 61 | ||
61 | #include "includes.h" | 62 | #include "includes.h" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.149 2005/12/30 15:56:37 reyk Exp $"); | ||
63 | 63 | ||
64 | #include <sys/types.h> | ||
65 | #include <sys/ioctl.h> | ||
66 | #include <sys/param.h> | ||
67 | #ifdef HAVE_SYS_STAT_H | ||
68 | # include <sys/stat.h> | ||
69 | #endif | ||
70 | #ifdef HAVE_SYS_TIME_H | ||
71 | # include <sys/time.h> | ||
72 | #endif | ||
73 | #include <sys/socket.h> | ||
74 | |||
75 | #include <ctype.h> | ||
76 | #include <errno.h> | ||
77 | #ifdef HAVE_PATHS_H | ||
78 | #include <paths.h> | ||
79 | #endif | ||
80 | #include <signal.h> | ||
81 | #include <stdarg.h> | ||
82 | #include <stdio.h> | ||
83 | #include <stdlib.h> | ||
84 | #include <string.h> | ||
85 | #include <termios.h> | ||
86 | #include <pwd.h> | ||
87 | #include <unistd.h> | ||
88 | |||
89 | #include "xmalloc.h" | ||
64 | #include "ssh.h" | 90 | #include "ssh.h" |
65 | #include "ssh1.h" | 91 | #include "ssh1.h" |
66 | #include "ssh2.h" | 92 | #include "ssh2.h" |
67 | #include "xmalloc.h" | ||
68 | #include "packet.h" | 93 | #include "packet.h" |
69 | #include "buffer.h" | 94 | #include "buffer.h" |
70 | #include "compat.h" | 95 | #include "compat.h" |
71 | #include "channels.h" | 96 | #include "channels.h" |
72 | #include "dispatch.h" | 97 | #include "dispatch.h" |
73 | #include "buffer.h" | ||
74 | #include "bufaux.h" | ||
75 | #include "key.h" | 98 | #include "key.h" |
99 | #include "cipher.h" | ||
76 | #include "kex.h" | 100 | #include "kex.h" |
77 | #include "log.h" | 101 | #include "log.h" |
78 | #include "readconf.h" | 102 | #include "readconf.h" |
@@ -118,7 +142,7 @@ static volatile sig_atomic_t received_signal = 0; | |||
118 | static int in_non_blocking_mode = 0; | 142 | static int in_non_blocking_mode = 0; |
119 | 143 | ||
120 | /* Common data for the client loop code. */ | 144 | /* Common data for the client loop code. */ |
121 | static int quit_pending; /* Set to non-zero to quit the client loop. */ | 145 | static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ |
122 | static int escape_char; /* Escape character. */ | 146 | static int escape_char; /* Escape character. */ |
123 | static int escape_pending; /* Last character was the escape character */ | 147 | static int escape_pending; /* Last character was the escape character */ |
124 | static int last_was_cr; /* Last character was a newline. */ | 148 | static int last_was_cr; /* Last character was a newline. */ |
@@ -178,7 +202,7 @@ enter_non_blocking(void) | |||
178 | * Signal handler for the window change signal (SIGWINCH). This just sets a | 202 | * Signal handler for the window change signal (SIGWINCH). This just sets a |
179 | * flag indicating that the window has changed. | 203 | * flag indicating that the window has changed. |
180 | */ | 204 | */ |
181 | 205 | /*ARGSUSED */ | |
182 | static void | 206 | static void |
183 | window_change_handler(int sig) | 207 | window_change_handler(int sig) |
184 | { | 208 | { |
@@ -190,7 +214,7 @@ window_change_handler(int sig) | |||
190 | * Signal handler for signals that cause the program to terminate. These | 214 | * Signal handler for signals that cause the program to terminate. These |
191 | * signals must be trapped to restore terminal modes. | 215 | * signals must be trapped to restore terminal modes. |
192 | */ | 216 | */ |
193 | 217 | /*ARGSUSED */ | |
194 | static void | 218 | static void |
195 | signal_handler(int sig) | 219 | signal_handler(int sig) |
196 | { | 220 | { |
@@ -422,10 +446,10 @@ client_check_window_change(void) | |||
422 | if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) | 446 | if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) |
423 | return; | 447 | return; |
424 | packet_start(SSH_CMSG_WINDOW_SIZE); | 448 | packet_start(SSH_CMSG_WINDOW_SIZE); |
425 | packet_put_int(ws.ws_row); | 449 | packet_put_int((u_int)ws.ws_row); |
426 | packet_put_int(ws.ws_col); | 450 | packet_put_int((u_int)ws.ws_col); |
427 | packet_put_int(ws.ws_xpixel); | 451 | packet_put_int((u_int)ws.ws_xpixel); |
428 | packet_put_int(ws.ws_ypixel); | 452 | packet_put_int((u_int)ws.ws_ypixel); |
429 | packet_send(); | 453 | packet_send(); |
430 | } | 454 | } |
431 | } | 455 | } |
@@ -441,8 +465,10 @@ static void | |||
441 | server_alive_check(void) | 465 | server_alive_check(void) |
442 | { | 466 | { |
443 | if (compat20) { | 467 | if (compat20) { |
444 | if (++server_alive_timeouts > options.server_alive_count_max) | 468 | if (++server_alive_timeouts > options.server_alive_count_max) { |
445 | packet_disconnect("Timeout, server not responding."); | 469 | logit("Timeout, server not responding."); |
470 | cleanup_exit(255); | ||
471 | } | ||
446 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | 472 | packet_start(SSH2_MSG_GLOBAL_REQUEST); |
447 | packet_put_cstring("keepalive@openssh.com"); | 473 | packet_put_cstring("keepalive@openssh.com"); |
448 | packet_put_char(1); /* boolean: want reply */ | 474 | packet_put_char(1); /* boolean: want reply */ |
@@ -574,7 +600,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) | |||
574 | } | 600 | } |
575 | 601 | ||
576 | static void | 602 | static void |
577 | client_process_net_input(fd_set * readset) | 603 | client_process_net_input(fd_set *readset) |
578 | { | 604 | { |
579 | int len; | 605 | int len; |
580 | char buf[8192]; | 606 | char buf[8192]; |
@@ -682,11 +708,11 @@ client_extra_session2_setup(int id, void *arg) | |||
682 | } | 708 | } |
683 | 709 | ||
684 | static void | 710 | static void |
685 | client_process_control(fd_set * readset) | 711 | client_process_control(fd_set *readset) |
686 | { | 712 | { |
687 | Buffer m; | 713 | Buffer m; |
688 | Channel *c; | 714 | Channel *c; |
689 | int client_fd, new_fd[3], ver, allowed; | 715 | int client_fd, new_fd[3], ver, allowed, window, packetmax; |
690 | socklen_t addrlen; | 716 | socklen_t addrlen; |
691 | struct sockaddr_storage addr; | 717 | struct sockaddr_storage addr; |
692 | struct confirm_ctx *cctx; | 718 | struct confirm_ctx *cctx; |
@@ -813,8 +839,7 @@ client_process_control(fd_set * readset) | |||
813 | return; | 839 | return; |
814 | } | 840 | } |
815 | 841 | ||
816 | cctx = xmalloc(sizeof(*cctx)); | 842 | cctx = xcalloc(1, sizeof(*cctx)); |
817 | memset(cctx, 0, sizeof(*cctx)); | ||
818 | cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; | 843 | cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; |
819 | cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; | 844 | cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; |
820 | cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; | 845 | cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; |
@@ -829,7 +854,7 @@ client_process_control(fd_set * readset) | |||
829 | env_len = MIN(env_len, 4096); | 854 | env_len = MIN(env_len, 4096); |
830 | debug3("%s: receiving %d env vars", __func__, env_len); | 855 | debug3("%s: receiving %d env vars", __func__, env_len); |
831 | if (env_len != 0) { | 856 | if (env_len != 0) { |
832 | cctx->env = xmalloc(sizeof(*cctx->env) * (env_len + 1)); | 857 | cctx->env = xcalloc(env_len + 1, sizeof(*cctx->env)); |
833 | for (i = 0; i < env_len; i++) | 858 | for (i = 0; i < env_len; i++) |
834 | cctx->env[i] = buffer_get_string(&m, &len); | 859 | cctx->env[i] = buffer_get_string(&m, &len); |
835 | cctx->env[i] = NULL; | 860 | cctx->env[i] = NULL; |
@@ -837,6 +862,7 @@ client_process_control(fd_set * readset) | |||
837 | 862 | ||
838 | debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__, | 863 | debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__, |
839 | cctx->want_tty, cctx->want_subsys, cmd); | 864 | cctx->want_tty, cctx->want_subsys, cmd); |
865 | xfree(cmd); | ||
840 | 866 | ||
841 | /* Gather fds from client */ | 867 | /* Gather fds from client */ |
842 | new_fd[0] = mm_receive_fd(client_fd); | 868 | new_fd[0] = mm_receive_fd(client_fd); |
@@ -879,9 +905,15 @@ client_process_control(fd_set * readset) | |||
879 | 905 | ||
880 | set_nonblock(client_fd); | 906 | set_nonblock(client_fd); |
881 | 907 | ||
908 | window = CHAN_SES_WINDOW_DEFAULT; | ||
909 | packetmax = CHAN_SES_PACKET_DEFAULT; | ||
910 | if (cctx->want_tty) { | ||
911 | window >>= 1; | ||
912 | packetmax >>= 1; | ||
913 | } | ||
914 | |||
882 | c = channel_new("session", SSH_CHANNEL_OPENING, | 915 | c = channel_new("session", SSH_CHANNEL_OPENING, |
883 | new_fd[0], new_fd[1], new_fd[2], | 916 | new_fd[0], new_fd[1], new_fd[2], window, packetmax, |
884 | CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT, | ||
885 | CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); | 917 | CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); |
886 | 918 | ||
887 | /* XXX */ | 919 | /* XXX */ |
@@ -917,12 +949,16 @@ process_cmdline(void) | |||
917 | 949 | ||
918 | if (*s == 'h' || *s == 'H' || *s == '?') { | 950 | if (*s == 'h' || *s == 'H' || *s == '?') { |
919 | logit("Commands:"); | 951 | logit("Commands:"); |
920 | logit(" -Lport:host:hostport Request local forward"); | 952 | logit(" -L[bind_address:]port:host:hostport " |
921 | logit(" -Rport:host:hostport Request remote forward"); | 953 | "Request local forward"); |
922 | logit(" -KRhostport Cancel remote forward"); | 954 | logit(" -R[bind_address:]port:host:hostport " |
955 | "Request remote forward"); | ||
956 | logit(" -KR[bind_address:]port " | ||
957 | "Cancel remote forward"); | ||
923 | if (!options.permit_local_command) | 958 | if (!options.permit_local_command) |
924 | goto out; | 959 | goto out; |
925 | logit(" !args Execute local command"); | 960 | logit(" !args " |
961 | "Execute local command"); | ||
926 | goto out; | 962 | goto out; |
927 | } | 963 | } |
928 | 964 | ||
@@ -983,9 +1019,12 @@ process_cmdline(void) | |||
983 | goto out; | 1019 | goto out; |
984 | } | 1020 | } |
985 | } else { | 1021 | } else { |
986 | channel_request_remote_forwarding(fwd.listen_host, | 1022 | if (channel_request_remote_forwarding(fwd.listen_host, |
987 | fwd.listen_port, fwd.connect_host, | 1023 | fwd.listen_port, fwd.connect_host, |
988 | fwd.connect_port); | 1024 | fwd.connect_port) < 0) { |
1025 | logit("Port forwarding failed."); | ||
1026 | goto out; | ||
1027 | } | ||
989 | } | 1028 | } |
990 | 1029 | ||
991 | logit("Forwarding port."); | 1030 | logit("Forwarding port."); |
@@ -1177,7 +1216,7 @@ Supported escape sequences:\r\n\ | |||
1177 | } | 1216 | } |
1178 | 1217 | ||
1179 | static void | 1218 | static void |
1180 | client_process_input(fd_set * readset) | 1219 | client_process_input(fd_set *readset) |
1181 | { | 1220 | { |
1182 | int len; | 1221 | int len; |
1183 | char buf[8192]; | 1222 | char buf[8192]; |
@@ -1230,7 +1269,7 @@ client_process_input(fd_set * readset) | |||
1230 | } | 1269 | } |
1231 | 1270 | ||
1232 | static void | 1271 | static void |
1233 | client_process_output(fd_set * writeset) | 1272 | client_process_output(fd_set *writeset) |
1234 | { | 1273 | { |
1235 | int len; | 1274 | int len; |
1236 | char buf[100]; | 1275 | char buf[100]; |
@@ -1731,7 +1770,7 @@ client_request_agent(const char *request_type, int rchan) | |||
1731 | error("Warning: this is probably a break-in attempt by a malicious server."); | 1770 | error("Warning: this is probably a break-in attempt by a malicious server."); |
1732 | return NULL; | 1771 | return NULL; |
1733 | } | 1772 | } |
1734 | sock = ssh_get_authentication_socket(); | 1773 | sock = ssh_get_authentication_socket(); |
1735 | if (sock < 0) | 1774 | if (sock < 0) |
1736 | return NULL; | 1775 | return NULL; |
1737 | c = channel_new("authentication agent connection", | 1776 | c = channel_new("authentication agent connection", |
@@ -1876,10 +1915,10 @@ client_session2_setup(int id, int want_tty, int want_subsystem, | |||
1876 | 1915 | ||
1877 | channel_request_start(id, "pty-req", 0); | 1916 | channel_request_start(id, "pty-req", 0); |
1878 | packet_put_cstring(term != NULL ? term : ""); | 1917 | packet_put_cstring(term != NULL ? term : ""); |
1879 | packet_put_int(ws.ws_col); | 1918 | packet_put_int((u_int)ws.ws_col); |
1880 | packet_put_int(ws.ws_row); | 1919 | packet_put_int((u_int)ws.ws_row); |
1881 | packet_put_int(ws.ws_xpixel); | 1920 | packet_put_int((u_int)ws.ws_xpixel); |
1882 | packet_put_int(ws.ws_ypixel); | 1921 | packet_put_int((u_int)ws.ws_ypixel); |
1883 | tio = get_saved_tio(); | 1922 | tio = get_saved_tio(); |
1884 | tty_make_modes(-1, tiop != NULL ? tiop : &tio); | 1923 | tty_make_modes(-1, tiop != NULL ? tiop : &tio); |
1885 | packet_send(); | 1924 | packet_send(); |