2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * Created: Sun Sep 10 00:30:37 1995 ylo
6 * Server main loop for handling the interactive session.
17 static Buffer stdin_buffer; /* Buffer for stdin data. */
18 static Buffer stdout_buffer; /* Buffer for stdout data. */
19 static Buffer stderr_buffer; /* Buffer for stderr data. */
20 static int fdin; /* Descriptor for stdin (for writing) */
21 static int fdout; /* Descriptor for stdout (for reading);
22 May be same number as fdin. */
23 static int fderr; /* Descriptor for stderr. May be -1. */
24 static long stdin_bytes = 0; /* Number of bytes written to stdin. */
25 static long stdout_bytes = 0; /* Number of stdout bytes sent to client. */
26 static long stderr_bytes = 0; /* Number of stderr bytes sent to client. */
27 static long fdout_bytes = 0; /* Number of stdout bytes read from program. */
28 static int stdin_eof = 0; /* EOF message received from client. */
29 static int fdout_eof = 0; /* EOF encountered reading from fdout. */
30 static int fderr_eof = 0; /* EOF encountered readung from fderr. */
31 static int connection_in; /* Connection to client (input). */
32 static int connection_out; /* Connection to client (output). */
33 static unsigned int buffer_high;/* "Soft" max buffer size. */
34 static int max_fd; /* Max file descriptor number for select(). */
36 /* This SIGCHLD kludge is used to detect when the child exits. The server
37 will exit after that, as soon as forwarded connections have terminated. */
39 static int child_pid; /* Pid of the child. */
40 static volatile int child_terminated; /* The child has terminated. */
41 static volatile int child_wait_status; /* Status from wait(). */
44 sigchld_handler(int sig)
46 int save_errno = errno;
48 debug("Received SIGCHLD.");
49 wait_pid = wait((int *) &child_wait_status);
51 if (wait_pid != child_pid)
52 error("Strange, got SIGCHLD and wait returned pid %d but child is %d",
54 if (WIFEXITED(child_wait_status) ||
55 WIFSIGNALED(child_wait_status))
58 signal(SIGCHLD, sigchld_handler);
63 * Process any buffered packets that have been received from the client.
66 process_buffered_input_packets()
70 unsigned int data_len;
71 int row, col, xpixel, ypixel;
74 /* Process buffered packets from the client. */
75 while ((type = packet_read_poll(&payload_len)) != SSH_MSG_NONE) {
77 case SSH_CMSG_STDIN_DATA:
78 /* Stdin data from the client. Append it to the buffer. */
79 /* Ignore any data if the client has closed stdin. */
82 data = packet_get_string(&data_len);
83 packet_integrity_check(payload_len, (4 + data_len), type);
84 buffer_append(&stdin_buffer, data, data_len);
85 memset(data, 0, data_len);
90 /* Eof from the client. The stdin descriptor to
91 the program will be closed when all buffered
93 debug("EOF received for stdin.");
94 packet_integrity_check(payload_len, 0, type);
98 case SSH_CMSG_WINDOW_SIZE:
99 debug("Window change received.");
100 packet_integrity_check(payload_len, 4 * 4, type);
101 row = packet_get_int();
102 col = packet_get_int();
103 xpixel = packet_get_int();
104 ypixel = packet_get_int();
106 pty_change_window_size(fdin, row, col, xpixel, ypixel);
109 case SSH_MSG_PORT_OPEN:
110 debug("Received port open request.");
111 channel_input_port_open(payload_len);
114 case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
115 debug("Received channel open confirmation.");
116 packet_integrity_check(payload_len, 4 + 4, type);
117 channel_input_open_confirmation();
120 case SSH_MSG_CHANNEL_OPEN_FAILURE:
121 debug("Received channel open failure.");
122 packet_integrity_check(payload_len, 4, type);
123 channel_input_open_failure();
126 case SSH_MSG_CHANNEL_DATA:
127 channel_input_data(payload_len);
130 case SSH_MSG_CHANNEL_CLOSE:
131 debug("Received channel close.");
132 packet_integrity_check(payload_len, 4, type);
133 channel_input_close();
136 case SSH_MSG_CHANNEL_CLOSE_CONFIRMATION:
137 debug("Received channel close confirmation.");
138 packet_integrity_check(payload_len, 4, type);
139 channel_input_close_confirmation();
143 /* In this phase, any unexpected messages cause a
144 protocol error. This is to ease debugging;
145 also, since no confirmations are sent messages,
146 unprocessed unknown messages could cause
147 strange problems. Any compatible protocol
148 extensions must be negotiated before entering
149 the interactive session. */
150 packet_disconnect("Protocol error during session: type %d",
157 * Make packets from buffered stderr data, and buffer it for sending
161 make_packets_from_stderr_data()
165 /* Send buffered stderr data to the client. */
166 while (buffer_len(&stderr_buffer) > 0 &&
167 packet_not_very_much_data_to_write()) {
168 len = buffer_len(&stderr_buffer);
169 if (packet_is_interactive()) {
173 /* Keep the packets at reasonable size. */
174 if (len > packet_get_maxsize())
175 len = packet_get_maxsize();
177 packet_start(SSH_SMSG_STDERR_DATA);
178 packet_put_string(buffer_ptr(&stderr_buffer), len);
180 buffer_consume(&stderr_buffer, len);
186 * Make packets from buffered stdout data, and buffer it for sending to the
190 make_packets_from_stdout_data()
194 /* Send buffered stdout data to the client. */
195 while (buffer_len(&stdout_buffer) > 0 &&
196 packet_not_very_much_data_to_write()) {
197 len = buffer_len(&stdout_buffer);
198 if (packet_is_interactive()) {
202 /* Keep the packets at reasonable size. */
203 if (len > packet_get_maxsize())
204 len = packet_get_maxsize();
206 packet_start(SSH_SMSG_STDOUT_DATA);
207 packet_put_string(buffer_ptr(&stdout_buffer), len);
209 buffer_consume(&stdout_buffer, len);
215 * Sleep in select() until we can do something. This will initialize the
216 * select masks. Upon return, the masks will indicate which descriptors
217 * have data or can accept data. Optionally, a maximum time can be specified
218 * for the duration of the wait (0 = infinite).
221 wait_until_can_do_something(fd_set * readset, fd_set * writeset,
222 unsigned int max_time_milliseconds)
224 struct timeval tv, *tvp;
227 /* When select fails we restart from here. */
230 /* Initialize select() masks. */
233 /* Read packets from the client unless we have too much buffered
234 stdin or channel data. */
235 if (buffer_len(&stdin_buffer) < 4096 &&
236 channel_not_very_much_buffered_data())
237 FD_SET(connection_in, readset);
239 /* If there is not too much data already buffered going to the
240 client, try to get some more data from the program. */
241 if (packet_not_very_much_data_to_write()) {
243 FD_SET(fdout, readset);
245 FD_SET(fderr, readset);
249 /* Set masks for channel descriptors. */
250 channel_prepare_select(readset, writeset);
252 /* If we have buffered packet data going to the client, mark that
254 if (packet_have_data_to_write())
255 FD_SET(connection_out, writeset);
257 /* If we have buffered data, try to write some of that data to the
259 if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
260 FD_SET(fdin, writeset);
262 /* Update the maximum descriptor number if appropriate. */
263 if (channel_max_fd() > max_fd)
264 max_fd = channel_max_fd();
266 /* If child has terminated and there is enough buffer space to
267 read from it, then read as much as is available and exit. */
268 if (child_terminated && packet_not_very_much_data_to_write())
269 if (max_time_milliseconds == 0)
270 max_time_milliseconds = 100;
272 if (max_time_milliseconds == 0)
275 tv.tv_sec = max_time_milliseconds / 1000;
276 tv.tv_usec = 1000 * (max_time_milliseconds % 1000);
280 /* Wait for something to happen, or the timeout to expire. */
281 ret = select(max_fd + 1, readset, writeset, NULL, tvp);
285 error("select: %.100s", strerror(errno));
292 * Processes input from the client and the program. Input data is stored
293 * in buffers and processed later.
296 process_input(fd_set * readset)
301 /* Read and buffer any input data from the client. */
302 if (FD_ISSET(connection_in, readset)) {
303 len = read(connection_in, buf, sizeof(buf));
305 verbose("Connection closed by remote host.");
308 /* There is a kernel bug on Solaris that causes select to
309 sometimes wake up even though there is no data
311 if (len < 0 && errno == EAGAIN)
315 verbose("Read error from remote host: %.100s", strerror(errno));
318 /* Buffer any received data. */
319 packet_process_incoming(buf, len);
321 /* Read and buffer any available stdout data from the program. */
322 if (!fdout_eof && FD_ISSET(fdout, readset)) {
323 len = read(fdout, buf, sizeof(buf));
327 buffer_append(&stdout_buffer, buf, len);
331 /* Read and buffer any available stderr data from the program. */
332 if (!fderr_eof && FD_ISSET(fderr, readset)) {
333 len = read(fderr, buf, sizeof(buf));
337 buffer_append(&stderr_buffer, buf, len);
342 * Sends data from internal buffers to client program stdin.
345 process_output(fd_set * writeset)
349 /* Write buffered data to program stdin. */
350 if (fdin != -1 && FD_ISSET(fdin, writeset)) {
351 len = write(fdin, buffer_ptr(&stdin_buffer),
352 buffer_len(&stdin_buffer));
360 shutdown(fdin, SHUT_WR); /* We will no longer send. */
364 /* Successful write. Consume the data from the buffer. */
365 buffer_consume(&stdin_buffer, len);
366 /* Update the count of bytes written to the program. */
370 /* Send any buffered packet data to the client. */
371 if (FD_ISSET(connection_out, writeset))
376 * Wait until all buffered output has been sent to the client.
377 * This is used when the program terminates.
382 /* Send any buffered stdout data to the client. */
383 if (buffer_len(&stdout_buffer) > 0) {
384 packet_start(SSH_SMSG_STDOUT_DATA);
385 packet_put_string(buffer_ptr(&stdout_buffer),
386 buffer_len(&stdout_buffer));
388 /* Update the count of sent bytes. */
389 stdout_bytes += buffer_len(&stdout_buffer);
391 /* Send any buffered stderr data to the client. */
392 if (buffer_len(&stderr_buffer) > 0) {
393 packet_start(SSH_SMSG_STDERR_DATA);
394 packet_put_string(buffer_ptr(&stderr_buffer),
395 buffer_len(&stderr_buffer));
397 /* Update the count of sent bytes. */
398 stderr_bytes += buffer_len(&stderr_buffer);
400 /* Wait until all buffered data has been written to the client. */
405 * Performs the interactive session. This handles data transmission between
406 * the client and the program. Note that the notion of stdin, stdout, and
407 * stderr in this function is sort of reversed: this function writes to
408 * stdin (of the child program), and reads from stdout and stderr (of the
412 server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
414 int wait_status, wait_pid; /* Status and pid returned by wait(). */
415 int waiting_termination = 0; /* Have displayed waiting close message. */
416 unsigned int max_time_milliseconds;
417 unsigned int previous_stdout_buffer_bytes;
418 unsigned int stdout_buffer_bytes;
421 debug("Entering interactive session.");
423 /* Initialize the SIGCHLD kludge. */
425 child_terminated = 0;
426 signal(SIGCHLD, sigchld_handler);
428 /* Initialize our global variables. */
432 connection_in = packet_get_connection_in();
433 connection_out = packet_get_connection_out();
435 previous_stdout_buffer_bytes = 0;
437 /* Set approximate I/O buffer size. */
438 if (packet_is_interactive())
441 buffer_high = 64 * 1024;
443 /* Initialize max_fd to the maximum of the known file descriptors. */
447 if (fderr != -1 && fderr > max_fd)
449 if (connection_in > max_fd)
450 max_fd = connection_in;
451 if (connection_out > max_fd)
452 max_fd = connection_out;
454 /* Initialize Initialize buffers. */
455 buffer_init(&stdin_buffer);
456 buffer_init(&stdout_buffer);
457 buffer_init(&stderr_buffer);
459 /* If we have no separate fderr (which is the case when we have a
460 pty - there we cannot make difference between data sent to
461 stdout and stderr), indicate that we have seen an EOF from
462 stderr. This way we don\'t need to check the descriptor
467 /* Main loop of the server for the interactive session mode. */
469 fd_set readset, writeset;
471 /* Process buffered packets from the client. */
472 process_buffered_input_packets();
474 /* If we have received eof, and there is no more pending
475 input data, cause a real eof by closing fdin. */
476 if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
483 shutdown(fdin, SHUT_WR); /* We will no longer send. */
487 /* Make packets from buffered stderr data to send to the
489 make_packets_from_stderr_data();
491 /* Make packets from buffered stdout data to send to the
492 client. If there is very little to send, this arranges
493 to not send them now, but to wait a short while to see
494 if we are getting more data. This is necessary, as some
495 systems wake up readers from a pty after each separate
497 max_time_milliseconds = 0;
498 stdout_buffer_bytes = buffer_len(&stdout_buffer);
499 if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
500 stdout_buffer_bytes != previous_stdout_buffer_bytes) {
501 /* try again after a while */
502 max_time_milliseconds = 10;
505 make_packets_from_stdout_data();
507 previous_stdout_buffer_bytes = buffer_len(&stdout_buffer);
509 /* Send channel data to the client. */
510 if (packet_not_very_much_data_to_write())
511 channel_output_poll();
513 /* Bail out of the loop if the program has closed its
514 output descriptors, and we have no more data to send to
515 the client, and there is no pending buffered data. */
516 if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
517 buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
518 if (!channel_still_open())
520 if (!waiting_termination) {
521 const char *s = "Waiting for forwarded connections to terminate...\r\n";
523 waiting_termination = 1;
524 buffer_append(&stderr_buffer, s, strlen(s));
526 /* Display list of open channels. */
527 cp = channel_open_message();
528 buffer_append(&stderr_buffer, cp, strlen(cp));
532 /* Sleep in select() until we can do something. */
533 wait_until_can_do_something(&readset, &writeset,
534 max_time_milliseconds);
536 /* Process any channel events. */
537 channel_after_select(&readset, &writeset);
539 /* Process input from the client and from program stdout/stderr. */
540 process_input(&readset);
542 /* Process output to the client and to program stdin. */
543 process_output(&writeset);
547 /* Cleanup and termination code. */
549 /* Wait until all output has been sent to the client. */
552 debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
553 stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);
555 /* Free and clear the buffers. */
556 buffer_free(&stdin_buffer);
557 buffer_free(&stdout_buffer);
558 buffer_free(&stderr_buffer);
560 /* Close the file descriptors. */
573 /* Stop listening for channels; this removes unix domain sockets. */
574 channel_stop_listening();
576 /* Wait for the child to exit. Get its exit status. */
577 wait_pid = wait(&wait_status);
580 * It is possible that the wait was handled by SIGCHLD
581 * handler. This may result in either: this call
582 * returning with EINTR, or: this call returning ECHILD.
584 if (child_terminated)
585 wait_status = child_wait_status;
587 packet_disconnect("wait: %.100s", strerror(errno));
589 /* Check if it matches the process we forked. */
591 error("Strange, wait returned pid %d, expected %d",
595 /* We no longer want our SIGCHLD handler to be called. */
596 signal(SIGCHLD, SIG_DFL);
598 /* Check if it exited normally. */
599 if (WIFEXITED(wait_status)) {
600 /* Yes, normal exit. Get exit status and send it to the client. */
601 debug("Command exited with status %d.", WEXITSTATUS(wait_status));
602 packet_start(SSH_SMSG_EXITSTATUS);
603 packet_put_int(WEXITSTATUS(wait_status));
607 /* Wait for exit confirmation. Note that there might be
608 other packets coming before it; however, the program
609 has already died so we just ignore them. The client is
610 supposed to respond with the confirmation when it
611 receives the exit status. */
614 type = packet_read(&plen);
616 while (type != SSH_CMSG_EXIT_CONFIRMATION);
618 debug("Received exit confirmation.");
621 /* Check if the program terminated due to a signal. */
622 if (WIFSIGNALED(wait_status))
623 packet_disconnect("Command terminated on signal %d.",
624 WTERMSIG(wait_status));
626 /* Some weird exit cause. Just exit. */
627 packet_disconnect("wait returned status %04x.", wait_status);