+/* $OpenBSD: serverloop.c,v 1.145 2006/10/11 12:38:03 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
*/
#include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.124 2005/12/13 15:03:02 reyk Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#include <netinet/in.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <signal.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <stdarg.h>
#include "xmalloc.h"
#include "packet.h"
#include "compat.h"
#include "ssh1.h"
#include "ssh2.h"
+#include "key.h"
+#include "cipher.h"
+#include "kex.h"
+#include "hostfile.h"
#include "auth.h"
#include "session.h"
#include "dispatch.h"
#include "auth-options.h"
#include "serverloop.h"
#include "misc.h"
-#include "kex.h"
extern ServerOptions options;
debug2("notify_done: reading");
}
+/*ARGSUSED*/
static void
sigchld_handler(int sig)
{
int save_errno = errno;
- debug("Received SIGCHLD.");
child_terminated = 1;
#ifndef _UNICOS
mysignal(SIGCHLD, sigchld_handler);
errno = save_errno;
}
+/*ARGSUSED*/
static void
sigterm_handler(int sig)
{
int channel_id;
/* timeout, check to see how many we have had */
- if (++client_alive_timeouts > options.client_alive_count_max)
- packet_disconnect("Timeout, your session not responding.");
+ if (++client_alive_timeouts > options.client_alive_count_max) {
+ logit("Timeout, client not responding.");
+ cleanup_exit(255);
+ }
/*
* send a bogus global/channel request with "wantreply",
* in buffers and processed later.
*/
static void
-process_input(fd_set * readset)
+process_input(fd_set *readset)
{
int len;
char buf[16384];
/* Read and buffer any available stdout data from the program. */
if (!fdout_eof && FD_ISSET(fdout, readset)) {
+ errno = 0;
len = read(fdout, buf, sizeof(buf));
if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
/* do nothing */
+#ifndef PTY_ZEROREAD
} else if (len <= 0) {
+#else
+ } else if ((!isatty(fdout) && len <= 0) ||
+ (isatty(fdout) && (len < 0 || (len == 0 && errno != 0)))) {
+#endif
fdout_eof = 1;
} else {
buffer_append(&stdout_buffer, buf, len);
}
/* Read and buffer any available stderr data from the program. */
if (!fderr_eof && FD_ISSET(fderr, readset)) {
+ errno = 0;
len = read(fderr, buf, sizeof(buf));
if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
/* do nothing */
+#ifndef PTY_ZEROREAD
} else if (len <= 0) {
+#else
+ } else if ((!isatty(fderr) && len <= 0) ||
+ (isatty(fderr) && (len < 0 || (len == 0 && errno != 0)))) {
+#endif
fderr_eof = 1;
} else {
buffer_append(&stderr_buffer, buf, len);
* Sends data from internal buffers to client program stdin.
*/
static void
-process_output(fd_set * writeset)
+process_output(fd_set *writeset)
{
struct termios tio;
u_char *data;
sigaddset(&nset, SIGCHLD);
sigprocmask(SIG_BLOCK, &nset, &oset);
if (child_terminated) {
+ debug("Received SIGCHLD.");
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
(pid < 0 && errno == EINTR))
if (pid > 0)
static void
server_input_window_size(int type, u_int32_t seq, void *ctxt)
{
- int row = packet_get_int();
- int col = packet_get_int();
- int xpixel = packet_get_int();
- int ypixel = packet_get_int();
+ u_int row = packet_get_int();
+ u_int col = packet_get_int();
+ u_int xpixel = packet_get_int();
+ u_int ypixel = packet_get_int();
debug("Window change received.");
packet_check_eom();
xfree(originator);
if (sock < 0)
return NULL;
- c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
- sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
- CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
+ if (options.hpn_disabled)
+ c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
+ sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
+ CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
+ else
+ c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
+ sock, sock, -1, options.hpn_buffer_size,
+ CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
return c;
}
tun = packet_get_int();
if (forced_tun_device != -1) {
- if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
+ if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
goto done;
tun = forced_tun_device;
}
sock = tun_open(tun, mode);
if (sock < 0)
goto done;
- c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
+ if (options.hpn_disabled)
+ c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
+ CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
+ else
+ c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
+ options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
c->datagram = 1;
#if defined(SSH_TUN_FILTER)
if (mode == SSH_TUNMODE_POINTOPOINT)
c = channel_new("session", SSH_CHANNEL_LARVAL,
-1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
0, "server-session", 1);
- if (!(datafellows & SSH_BUG_LARGEWINDOW))
+ if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled))
c->dynamic_window = 1;
if (session_open(the_authctxt, c->self) != 1) {
debug("session open failed, free channel %d", c->self);
} else {
/* Start listening on the port */
success = channel_setup_remote_fwd_listener(
- listen_address, listen_port, options.gateway_ports);
+ listen_address, listen_port, options.gateway_ports,
+ options.hpn_disabled, options.hpn_buffer_size);
}
xfree(listen_address);
} else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
success = channel_cancel_rport_listener(cancel_address,
cancel_port);
+ xfree(cancel_address);
}
if (want_reply) {
packet_start(success ?
}
xfree(rtype);
}
+
static void
server_input_channel_req(int type, u_int32_t seq, void *ctxt)
{