summaryrefslogtreecommitdiffstats
path: root/serverloop.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-04-01 11:09:21 +1000
committerDamien Miller <djm@mindrot.org>2000-04-01 11:09:21 +1000
commitb38eff8e4ff901df9cf1113a9f14d64c3565a401 (patch)
tree9a856898f15f7760ed95c5d47789a6f954b4ad2f /serverloop.c
parent450a7a1ff40fe7c2d84c93b83cf2df53445d807d (diff)
- Big OpenBSD CVS update (mainly beginnings of SSH2 infrastructure)
- [auth.c session.c sshd.c auth.h] split sshd.c -> auth.c session.c sshd.c plus cleanup and goto-removal - [bufaux.c bufaux.h] support ssh2 bignums - [channels.c channels.h clientloop.c sshd.c nchan.c nchan.h packet.c] [readconf.c ssh.c ssh.h serverloop.c] replace big switch() with function tables (prepare for ssh2) - [ssh2.h] ssh2 message type codes - [sshd.8] reorder Xr to avoid cutting - [serverloop.c] close(fdin) if fdin != fdout, shutdown otherwise, ok theo@ - [channels.c] missing close allow bigger packets - [cipher.c cipher.h] support ssh2 ciphers - [compress.c] cleanup, less code - [dispatch.c dispatch.h] function tables for different message types - [log-server.c] do not log() if debuggin to stderr rename a cpp symbol, to avoid param.h collision - [mpaux.c] KNF - [nchan.c] sync w/ channels.c
Diffstat (limited to 'serverloop.c')
-rw-r--r--serverloop.c195
1 files changed, 93 insertions, 102 deletions
diff --git a/serverloop.c b/serverloop.c
index 2afca763..8bf448ce 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -13,6 +13,10 @@
#include "buffer.h"
#include "servconf.h"
#include "pty.h"
+#include "channels.h"
+
+#include "compat.h"
+#include "dispatch.h"
static Buffer stdin_buffer; /* Buffer for stdin data. */
static Buffer stdout_buffer; /* Buffer for stdout data. */
@@ -47,6 +51,8 @@ static volatile int child_terminated; /* The child has terminated. */
static volatile int child_has_selected; /* Child has had chance to drain. */
static volatile int child_wait_status; /* Status from wait(). */
+void server_init_dispatch(void);
+
void
sigchld_handler(int sig)
{
@@ -68,104 +74,6 @@ sigchld_handler(int sig)
}
/*
- * Process any buffered packets that have been received from the client.
- */
-void
-process_buffered_input_packets()
-{
- int type;
- char *data;
- unsigned int data_len;
- int row, col, xpixel, ypixel;
- int payload_len;
-
- /* Process buffered packets from the client. */
- while ((type = packet_read_poll(&payload_len)) != SSH_MSG_NONE) {
- switch (type) {
- case SSH_CMSG_STDIN_DATA:
- /* Stdin data from the client. Append it to the buffer. */
- /* Ignore any data if the client has closed stdin. */
- if (fdin == -1)
- break;
- data = packet_get_string(&data_len);
- packet_integrity_check(payload_len, (4 + data_len), type);
- buffer_append(&stdin_buffer, data, data_len);
- memset(data, 0, data_len);
- xfree(data);
- break;
-
- case SSH_CMSG_EOF:
- /*
- * Eof from the client. The stdin descriptor to the
- * program will be closed when all buffered data has
- * drained.
- */
- debug("EOF received for stdin.");
- packet_integrity_check(payload_len, 0, type);
- stdin_eof = 1;
- break;
-
- case SSH_CMSG_WINDOW_SIZE:
- debug("Window change received.");
- packet_integrity_check(payload_len, 4 * 4, type);
- row = packet_get_int();
- col = packet_get_int();
- xpixel = packet_get_int();
- ypixel = packet_get_int();
- if (fdin != -1)
- pty_change_window_size(fdin, row, col, xpixel, ypixel);
- break;
-
- case SSH_MSG_PORT_OPEN:
- debug("Received port open request.");
- channel_input_port_open(payload_len);
- break;
-
- case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
- debug("Received channel open confirmation.");
- packet_integrity_check(payload_len, 4 + 4, type);
- channel_input_open_confirmation();
- break;
-
- case SSH_MSG_CHANNEL_OPEN_FAILURE:
- debug("Received channel open failure.");
- packet_integrity_check(payload_len, 4, type);
- channel_input_open_failure();
- break;
-
- case SSH_MSG_CHANNEL_DATA:
- channel_input_data(payload_len);
- break;
-
- case SSH_MSG_CHANNEL_CLOSE:
- debug("Received channel close.");
- packet_integrity_check(payload_len, 4, type);
- channel_input_close();
- break;
-
- case SSH_MSG_CHANNEL_CLOSE_CONFIRMATION:
- debug("Received channel close confirmation.");
- packet_integrity_check(payload_len, 4, type);
- channel_input_close_confirmation();
- break;
-
- default:
- /*
- * In this phase, any unexpected messages cause a
- * protocol error. This is to ease debugging; also,
- * since no confirmations are sent messages,
- * unprocessed unknown messages could cause strange
- * problems. Any compatible protocol extensions must
- * be negotiated before entering the interactive
- * session.
- */
- packet_disconnect("Protocol error during session: type %d",
- type);
- }
- }
-}
-
-/*
* Make packets from buffered stderr data, and buffer it for sending
* to the client.
*/
@@ -378,7 +286,7 @@ process_output(fd_set * writeset)
#ifdef USE_PIPES
close(fdin);
#else
- if (fdout == -1)
+ if (fdin != fdout)
close(fdin);
else
shutdown(fdin, SHUT_WR); /* We will no longer send. */
@@ -425,6 +333,12 @@ drain_output()
packet_write_wait();
}
+void
+process_buffered_input_packets()
+{
+ dispatch_run(DISPATCH_NONBLOCK, NULL);
+}
+
/*
* Performs the interactive session. This handles data transmission between
* the client and the program. Note that the notion of stdin, stdout, and
@@ -490,6 +404,8 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
if (fderr == -1)
fderr_eof = 1;
+ server_init_dispatch();
+
/* Main loop of the server for the interactive session mode. */
for (;;) {
fd_set readset, writeset;
@@ -505,7 +421,7 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
#ifdef USE_PIPES
close(fdin);
#else
- if (fdout == -1)
+ if (fdin != fdout)
close(fdin);
else
shutdown(fdin, SHUT_WR); /* We will no longer send. */
@@ -549,7 +465,7 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
(buffer_len(&stdout_buffer) == 0) &&
(buffer_len(&stderr_buffer) == 0)) {
if (!channel_still_open())
- goto quit;
+ break;
if (!waiting_termination) {
const char *s = "Waiting for forwarded connections to terminate...\r\n";
char *cp;
@@ -576,7 +492,6 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
process_output(&writeset);
}
-quit:
/* Cleanup and termination code. */
/* Wait until all output has been sent to the client. */
@@ -662,3 +577,79 @@ quit:
packet_disconnect("wait returned status %04x.", wait_status);
/* NOTREACHED */
}
+
+void
+server_input_stdin_data(int type, int plen)
+{
+ char *data;
+ unsigned int data_len;
+
+ /* Stdin data from the client. Append it to the buffer. */
+ /* Ignore any data if the client has closed stdin. */
+ if (fdin == -1)
+ return;
+ data = packet_get_string(&data_len);
+ packet_integrity_check(plen, (4 + data_len), type);
+ buffer_append(&stdin_buffer, data, data_len);
+ memset(data, 0, data_len);
+ xfree(data);
+}
+
+void
+server_input_eof(int type, int plen)
+{
+ /*
+ * Eof from the client. The stdin descriptor to the
+ * program will be closed when all buffered data has
+ * drained.
+ */
+ debug("EOF received for stdin.");
+ packet_integrity_check(plen, 0, type);
+ stdin_eof = 1;
+}
+
+void
+server_input_window_size(int type, int plen)
+{
+ int row = packet_get_int();
+ int col = packet_get_int();
+ int xpixel = packet_get_int();
+ int ypixel = packet_get_int();
+
+ debug("Window change received.");
+ packet_integrity_check(plen, 4 * 4, type);
+ if (fdin != -1)
+ pty_change_window_size(fdin, row, col, xpixel, ypixel);
+}
+
+void
+server_init_dispatch_13()
+{
+ debug("server_init_dispatch_13");
+ dispatch_init(NULL);
+ dispatch_set(SSH_CMSG_EOF, &server_input_eof);
+ dispatch_set(SSH_CMSG_STDIN_DATA, &server_input_stdin_data);
+ dispatch_set(SSH_CMSG_WINDOW_SIZE, &server_input_window_size);
+ dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
+ dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
+ dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
+ dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
+ dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
+ dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
+}
+void
+server_init_dispatch_15()
+{
+ server_init_dispatch_13();
+ debug("server_init_dispatch_15");
+ dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
+ dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_oclose);
+}
+void
+server_init_dispatch()
+{
+ if (compat13)
+ server_init_dispatch_13();
+ else
+ server_init_dispatch_15();
+}