version 1.155.2.2, 2006/11/08 00:17:14 |
version 1.156, 2006/03/19 18:51:18 |
|
|
/* $OpenBSD$ */ |
|
/* |
/* |
* Author: Tatu Ylonen <ylo@cs.hut.fi> |
* Author: Tatu Ylonen <ylo@cs.hut.fi> |
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
*/ |
|
|
|
#include "includes.h" |
|
|
#include <sys/types.h> |
|
#include <sys/ioctl.h> |
#include <sys/ioctl.h> |
|
#include <sys/types.h> |
#include <sys/stat.h> |
#include <sys/stat.h> |
#include <sys/socket.h> |
|
#include <sys/time.h> |
|
#include <sys/param.h> |
|
|
|
#include <ctype.h> |
#include <ctype.h> |
#include <errno.h> |
|
#include <paths.h> |
#include <paths.h> |
#include <signal.h> |
#include <signal.h> |
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <termios.h> |
#include <termios.h> |
#include <pwd.h> |
|
#include <unistd.h> |
|
|
|
#include "xmalloc.h" |
|
#include "ssh.h" |
#include "ssh.h" |
#include "ssh1.h" |
#include "ssh1.h" |
#include "ssh2.h" |
#include "ssh2.h" |
|
#include "xmalloc.h" |
#include "packet.h" |
#include "packet.h" |
#include "buffer.h" |
#include "buffer.h" |
#include "compat.h" |
#include "compat.h" |
#include "channels.h" |
#include "channels.h" |
#include "dispatch.h" |
#include "dispatch.h" |
|
#include "buffer.h" |
|
#include "bufaux.h" |
#include "key.h" |
#include "key.h" |
#include "cipher.h" |
|
#include "kex.h" |
#include "kex.h" |
#include "log.h" |
#include "log.h" |
#include "readconf.h" |
#include "readconf.h" |
|
|
static int in_non_blocking_mode = 0; |
static int in_non_blocking_mode = 0; |
|
|
/* Common data for the client loop code. */ |
/* Common data for the client loop code. */ |
static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ |
static int quit_pending; /* Set to non-zero to quit the client loop. */ |
static int escape_char; /* Escape character. */ |
static int escape_char; /* Escape character. */ |
static int escape_pending; /* Last character was the escape character */ |
static int escape_pending; /* Last character was the escape character */ |
static int last_was_cr; /* Last character was a newline. */ |
static int last_was_cr; /* Last character was a newline. */ |
|
|
* Signal handler for the window change signal (SIGWINCH). This just sets a |
* Signal handler for the window change signal (SIGWINCH). This just sets a |
* flag indicating that the window has changed. |
* flag indicating that the window has changed. |
*/ |
*/ |
/*ARGSUSED */ |
|
static void |
static void |
window_change_handler(int sig) |
window_change_handler(int sig) |
{ |
{ |
|
|
* Signal handler for signals that cause the program to terminate. These |
* Signal handler for signals that cause the program to terminate. These |
* signals must be trapped to restore terminal modes. |
* signals must be trapped to restore terminal modes. |
*/ |
*/ |
/*ARGSUSED */ |
|
static void |
static void |
signal_handler(int sig) |
signal_handler(int sig) |
{ |
{ |
|
|
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) |
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) |
return; |
return; |
packet_start(SSH_CMSG_WINDOW_SIZE); |
packet_start(SSH_CMSG_WINDOW_SIZE); |
packet_put_int((u_int)ws.ws_row); |
packet_put_int(ws.ws_row); |
packet_put_int((u_int)ws.ws_col); |
packet_put_int(ws.ws_col); |
packet_put_int((u_int)ws.ws_xpixel); |
packet_put_int(ws.ws_xpixel); |
packet_put_int((u_int)ws.ws_ypixel); |
packet_put_int(ws.ws_ypixel); |
packet_send(); |
packet_send(); |
} |
} |
} |
} |
|
|
static void |
static void |
server_alive_check(void) |
server_alive_check(void) |
{ |
{ |
if (++server_alive_timeouts > options.server_alive_count_max) { |
if (++server_alive_timeouts > options.server_alive_count_max) |
logit("Timeout, server not responding."); |
packet_disconnect("Timeout, server not responding."); |
cleanup_exit(255); |
|
} |
|
packet_start(SSH2_MSG_GLOBAL_REQUEST); |
packet_start(SSH2_MSG_GLOBAL_REQUEST); |
packet_put_cstring("keepalive@openssh.com"); |
packet_put_cstring("keepalive@openssh.com"); |
packet_put_char(1); /* boolean: want reply */ |
packet_put_char(1); /* boolean: want reply */ |
|
|
} |
} |
|
|
static void |
static void |
client_process_net_input(fd_set *readset) |
client_process_net_input(fd_set * readset) |
{ |
{ |
int len; |
int len; |
char buf[8192]; |
char buf[8192]; |
|
|
} |
} |
|
|
static void |
static void |
client_process_control(fd_set *readset) |
client_process_control(fd_set * readset) |
{ |
{ |
Buffer m; |
Buffer m; |
Channel *c; |
Channel *c; |
|
|
return; |
return; |
} |
} |
|
|
cctx = xcalloc(1, sizeof(*cctx)); |
cctx = xmalloc(sizeof(*cctx)); |
|
memset(cctx, 0, sizeof(*cctx)); |
cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; |
cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; |
cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; |
cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; |
cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; |
cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; |
|
|
env_len = MIN(env_len, 4096); |
env_len = MIN(env_len, 4096); |
debug3("%s: receiving %d env vars", __func__, env_len); |
debug3("%s: receiving %d env vars", __func__, env_len); |
if (env_len != 0) { |
if (env_len != 0) { |
cctx->env = xcalloc(env_len + 1, sizeof(*cctx->env)); |
cctx->env = xmalloc(sizeof(*cctx->env) * (env_len + 1)); |
for (i = 0; i < env_len; i++) |
for (i = 0; i < env_len; i++) |
cctx->env[i] = buffer_get_string(&m, &len); |
cctx->env[i] = buffer_get_string(&m, &len); |
cctx->env[i] = NULL; |
cctx->env[i] = NULL; |
|
|
|
|
debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__, |
debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__, |
cctx->want_tty, cctx->want_subsys, cmd); |
cctx->want_tty, cctx->want_subsys, cmd); |
xfree(cmd); |
|
|
|
/* Gather fds from client */ |
/* Gather fds from client */ |
new_fd[0] = mm_receive_fd(client_fd); |
new_fd[0] = mm_receive_fd(client_fd); |
|
|
|
|
if (*s == 'h' || *s == 'H' || *s == '?') { |
if (*s == 'h' || *s == 'H' || *s == '?') { |
logit("Commands:"); |
logit("Commands:"); |
logit(" -L[bind_address:]port:host:hostport " |
logit(" -Lport:host:hostport Request local forward"); |
"Request local forward"); |
logit(" -Rport:host:hostport Request remote forward"); |
logit(" -R[bind_address:]port:host:hostport " |
logit(" -KRhostport Cancel remote forward"); |
"Request remote forward"); |
|
logit(" -KR[bind_address:]port " |
|
"Cancel remote forward"); |
|
if (!options.permit_local_command) |
if (!options.permit_local_command) |
goto out; |
goto out; |
logit(" !args " |
logit(" !args Execute local command"); |
"Execute local command"); |
|
goto out; |
goto out; |
} |
} |
|
|
|
|
goto out; |
goto out; |
} |
} |
} else { |
} else { |
if (channel_request_remote_forwarding(fwd.listen_host, |
channel_request_remote_forwarding(fwd.listen_host, |
fwd.listen_port, fwd.connect_host, |
fwd.listen_port, fwd.connect_host, |
fwd.connect_port) < 0) { |
fwd.connect_port); |
logit("Port forwarding failed."); |
|
goto out; |
|
} |
|
} |
} |
|
|
logit("Forwarding port."); |
logit("Forwarding port."); |
|
|
} |
} |
|
|
static void |
static void |
client_process_input(fd_set *readset) |
client_process_input(fd_set * readset) |
{ |
{ |
int len; |
int len; |
char buf[8192]; |
char buf[8192]; |
|
|
} |
} |
|
|
static void |
static void |
client_process_output(fd_set *writeset) |
client_process_output(fd_set * writeset) |
{ |
{ |
int len; |
int len; |
char buf[100]; |
char buf[100]; |
|
|
|
|
channel_request_start(id, "pty-req", 0); |
channel_request_start(id, "pty-req", 0); |
packet_put_cstring(term != NULL ? term : ""); |
packet_put_cstring(term != NULL ? term : ""); |
packet_put_int((u_int)ws.ws_col); |
packet_put_int(ws.ws_col); |
packet_put_int((u_int)ws.ws_row); |
packet_put_int(ws.ws_row); |
packet_put_int((u_int)ws.ws_xpixel); |
packet_put_int(ws.ws_xpixel); |
packet_put_int((u_int)ws.ws_ypixel); |
packet_put_int(ws.ws_ypixel); |
tio = get_saved_tio(); |
tio = get_saved_tio(); |
tty_make_modes(-1, tiop != NULL ? tiop : &tio); |
tty_make_modes(-1, tiop != NULL ? tiop : &tio); |
packet_send(); |
packet_send(); |