summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c107
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"
62RCSID("$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;
118static int in_non_blocking_mode = 0; 142static int in_non_blocking_mode = 0;
119 143
120/* Common data for the client loop code. */ 144/* Common data for the client loop code. */
121static int quit_pending; /* Set to non-zero to quit the client loop. */ 145static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
122static int escape_char; /* Escape character. */ 146static int escape_char; /* Escape character. */
123static int escape_pending; /* Last character was the escape character */ 147static int escape_pending; /* Last character was the escape character */
124static int last_was_cr; /* Last character was a newline. */ 148static 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 */
182static void 206static void
183window_change_handler(int sig) 207window_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 */
194static void 218static void
195signal_handler(int sig) 219signal_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
441server_alive_check(void) 465server_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
576static void 602static void
577client_process_net_input(fd_set * readset) 603client_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
684static void 710static void
685client_process_control(fd_set * readset) 711client_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
1179static void 1218static void
1180client_process_input(fd_set * readset) 1219client_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
1232static void 1271static void
1233client_process_output(fd_set * writeset) 1272client_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();