- 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
diff --git a/serverloop.c b/serverloop.c
index 2afca76..8bf448c 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_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 @@
}
/*
- * 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 @@
#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 @@
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 @@
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 @@
#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 @@
(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 @@
process_output(&writeset);
}
-quit:
/* Cleanup and termination code. */
/* Wait until all output has been sent to the client. */
@@ -662,3 +577,79 @@
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();
+}