xref: /freebsd/crypto/openssh/serverloop.c (revision 23f282aa31e9b6fceacd449020e936e98d6f2298)
1 /*
2  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  * Created: Sun Sep 10 00:30:37 1995 ylo
6  * Server main loop for handling the interactive session.
7  */
8 
9 #include "includes.h"
10 #include "xmalloc.h"
11 #include "ssh.h"
12 #include "packet.h"
13 #include "buffer.h"
14 #include "servconf.h"
15 #include "pty.h"
16 
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(). */
35 
36 /*
37  * This SIGCHLD kludge is used to detect when the child exits.  The server
38  * will exit after that, as soon as forwarded connections have terminated.
39  */
40 
41 static int child_pid;			/* Pid of the child. */
42 static volatile int child_terminated;	/* The child has terminated. */
43 static volatile int child_wait_status;	/* Status from wait(). */
44 
45 void
46 sigchld_handler(int sig)
47 {
48 	int save_errno = errno;
49 	int wait_pid;
50 	debug("Received SIGCHLD.");
51 	wait_pid = wait((int *) &child_wait_status);
52 	if (wait_pid != -1) {
53 		if (wait_pid != child_pid)
54 			error("Strange, got SIGCHLD and wait returned pid %d but child is %d",
55 			      wait_pid, child_pid);
56 		if (WIFEXITED(child_wait_status) ||
57 		    WIFSIGNALED(child_wait_status))
58 			child_terminated = 1;
59 	}
60 	signal(SIGCHLD, sigchld_handler);
61 	errno = save_errno;
62 }
63 
64 /*
65  * Process any buffered packets that have been received from the client.
66  */
67 void
68 process_buffered_input_packets()
69 {
70 	int type;
71 	char *data;
72 	unsigned int data_len;
73 	int row, col, xpixel, ypixel;
74 	int payload_len;
75 
76 	/* Process buffered packets from the client. */
77 	while ((type = packet_read_poll(&payload_len)) != SSH_MSG_NONE) {
78 		switch (type) {
79 		case SSH_CMSG_STDIN_DATA:
80 			/* Stdin data from the client.  Append it to the buffer. */
81 			/* Ignore any data if the client has closed stdin. */
82 			if (fdin == -1)
83 				break;
84 			data = packet_get_string(&data_len);
85 			packet_integrity_check(payload_len, (4 + data_len), type);
86 			buffer_append(&stdin_buffer, data, data_len);
87 			memset(data, 0, data_len);
88 			xfree(data);
89 			break;
90 
91 		case SSH_CMSG_EOF:
92 			/*
93 			 * Eof from the client.  The stdin descriptor to the
94 			 * program will be closed when all buffered data has
95 			 * drained.
96 			 */
97 			debug("EOF received for stdin.");
98 			packet_integrity_check(payload_len, 0, type);
99 			stdin_eof = 1;
100 			break;
101 
102 		case SSH_CMSG_WINDOW_SIZE:
103 			debug("Window change received.");
104 			packet_integrity_check(payload_len, 4 * 4, type);
105 			row = packet_get_int();
106 			col = packet_get_int();
107 			xpixel = packet_get_int();
108 			ypixel = packet_get_int();
109 			if (fdin != -1)
110 				pty_change_window_size(fdin, row, col, xpixel, ypixel);
111 			break;
112 
113 		case SSH_MSG_PORT_OPEN:
114 			debug("Received port open request.");
115 			channel_input_port_open(payload_len);
116 			break;
117 
118 		case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
119 			debug("Received channel open confirmation.");
120 			packet_integrity_check(payload_len, 4 + 4, type);
121 			channel_input_open_confirmation();
122 			break;
123 
124 		case SSH_MSG_CHANNEL_OPEN_FAILURE:
125 			debug("Received channel open failure.");
126 			packet_integrity_check(payload_len, 4, type);
127 			channel_input_open_failure();
128 			break;
129 
130 		case SSH_MSG_CHANNEL_DATA:
131 			channel_input_data(payload_len);
132 			break;
133 
134 		case SSH_MSG_CHANNEL_CLOSE:
135 			debug("Received channel close.");
136 			packet_integrity_check(payload_len, 4, type);
137 			channel_input_close();
138 			break;
139 
140 		case SSH_MSG_CHANNEL_CLOSE_CONFIRMATION:
141 			debug("Received channel close confirmation.");
142 			packet_integrity_check(payload_len, 4, type);
143 			channel_input_close_confirmation();
144 			break;
145 
146 		default:
147 			/*
148 			 * In this phase, any unexpected messages cause a
149 			 * protocol error.  This is to ease debugging; also,
150 			 * since no confirmations are sent messages,
151 			 * unprocessed unknown messages could cause strange
152 			 * problems.  Any compatible protocol extensions must
153 			 * be negotiated before entering the interactive
154 			 * session.
155 			 */
156 			packet_disconnect("Protocol error during session: type %d",
157 					  type);
158 		}
159 	}
160 }
161 
162 /*
163  * Make packets from buffered stderr data, and buffer it for sending
164  * to the client.
165  */
166 void
167 make_packets_from_stderr_data()
168 {
169 	int len;
170 
171 	/* Send buffered stderr data to the client. */
172 	while (buffer_len(&stderr_buffer) > 0 &&
173 	    packet_not_very_much_data_to_write()) {
174 		len = buffer_len(&stderr_buffer);
175 		if (packet_is_interactive()) {
176 			if (len > 512)
177 				len = 512;
178 		} else {
179 			/* Keep the packets at reasonable size. */
180 			if (len > packet_get_maxsize())
181 				len = packet_get_maxsize();
182 		}
183 		packet_start(SSH_SMSG_STDERR_DATA);
184 		packet_put_string(buffer_ptr(&stderr_buffer), len);
185 		packet_send();
186 		buffer_consume(&stderr_buffer, len);
187 		stderr_bytes += len;
188 	}
189 }
190 
191 /*
192  * Make packets from buffered stdout data, and buffer it for sending to the
193  * client.
194  */
195 void
196 make_packets_from_stdout_data()
197 {
198 	int len;
199 
200 	/* Send buffered stdout data to the client. */
201 	while (buffer_len(&stdout_buffer) > 0 &&
202 	    packet_not_very_much_data_to_write()) {
203 		len = buffer_len(&stdout_buffer);
204 		if (packet_is_interactive()) {
205 			if (len > 512)
206 				len = 512;
207 		} else {
208 			/* Keep the packets at reasonable size. */
209 			if (len > packet_get_maxsize())
210 				len = packet_get_maxsize();
211 		}
212 		packet_start(SSH_SMSG_STDOUT_DATA);
213 		packet_put_string(buffer_ptr(&stdout_buffer), len);
214 		packet_send();
215 		buffer_consume(&stdout_buffer, len);
216 		stdout_bytes += len;
217 	}
218 }
219 
220 /*
221  * Sleep in select() until we can do something.  This will initialize the
222  * select masks.  Upon return, the masks will indicate which descriptors
223  * have data or can accept data.  Optionally, a maximum time can be specified
224  * for the duration of the wait (0 = infinite).
225  */
226 void
227 wait_until_can_do_something(fd_set * readset, fd_set * writeset,
228 			    unsigned int max_time_milliseconds)
229 {
230 	struct timeval tv, *tvp;
231 	int ret;
232 
233 	/* When select fails we restart from here. */
234 retry_select:
235 
236 	/* Initialize select() masks. */
237 	FD_ZERO(readset);
238 
239 	/*
240 	 * Read packets from the client unless we have too much buffered
241 	 * stdin or channel data.
242 	 */
243 	if (buffer_len(&stdin_buffer) < 4096 &&
244 	    channel_not_very_much_buffered_data())
245 		FD_SET(connection_in, readset);
246 
247 	/*
248 	 * If there is not too much data already buffered going to the
249 	 * client, try to get some more data from the program.
250 	 */
251 	if (packet_not_very_much_data_to_write()) {
252 		if (!fdout_eof)
253 			FD_SET(fdout, readset);
254 		if (!fderr_eof)
255 			FD_SET(fderr, readset);
256 	}
257 	FD_ZERO(writeset);
258 
259 	/* Set masks for channel descriptors. */
260 	channel_prepare_select(readset, writeset);
261 
262 	/*
263 	 * If we have buffered packet data going to the client, mark that
264 	 * descriptor.
265 	 */
266 	if (packet_have_data_to_write())
267 		FD_SET(connection_out, writeset);
268 
269 	/* If we have buffered data, try to write some of that data to the
270 	   program. */
271 	if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
272 		FD_SET(fdin, writeset);
273 
274 	/* Update the maximum descriptor number if appropriate. */
275 	if (channel_max_fd() > max_fd)
276 		max_fd = channel_max_fd();
277 
278 	/*
279 	 * If child has terminated and there is enough buffer space to read
280 	 * from it, then read as much as is available and exit.
281 	 */
282 	if (child_terminated && packet_not_very_much_data_to_write())
283 		if (max_time_milliseconds == 0)
284 			max_time_milliseconds = 100;
285 
286 	if (max_time_milliseconds == 0)
287 		tvp = NULL;
288 	else {
289 		tv.tv_sec = max_time_milliseconds / 1000;
290 		tv.tv_usec = 1000 * (max_time_milliseconds % 1000);
291 		tvp = &tv;
292 	}
293 
294 	/* Wait for something to happen, or the timeout to expire. */
295 	ret = select(max_fd + 1, readset, writeset, NULL, tvp);
296 
297 	if (ret < 0) {
298 		if (errno != EINTR)
299 			error("select: %.100s", strerror(errno));
300 		else
301 			goto retry_select;
302 	}
303 }
304 
305 /*
306  * Processes input from the client and the program.  Input data is stored
307  * in buffers and processed later.
308  */
309 void
310 process_input(fd_set * readset)
311 {
312 	int len;
313 	char buf[16384];
314 
315 	/* Read and buffer any input data from the client. */
316 	if (FD_ISSET(connection_in, readset)) {
317 		len = read(connection_in, buf, sizeof(buf));
318 		if (len == 0) {
319 			verbose("Connection closed by remote host.");
320 			fatal_cleanup();
321 		}
322 		/*
323 		 * There is a kernel bug on Solaris that causes select to
324 		 * sometimes wake up even though there is no data available.
325 		 */
326 		if (len < 0 && errno == EAGAIN)
327 			len = 0;
328 
329 		if (len < 0) {
330 			verbose("Read error from remote host: %.100s", strerror(errno));
331 			fatal_cleanup();
332 		}
333 		/* Buffer any received data. */
334 		packet_process_incoming(buf, len);
335 	}
336 	/* Read and buffer any available stdout data from the program. */
337 	if (!fdout_eof && FD_ISSET(fdout, readset)) {
338 		len = read(fdout, buf, sizeof(buf));
339 		if (len <= 0)
340 			fdout_eof = 1;
341 		else {
342 			buffer_append(&stdout_buffer, buf, len);
343 			fdout_bytes += len;
344 		}
345 	}
346 	/* Read and buffer any available stderr data from the program. */
347 	if (!fderr_eof && FD_ISSET(fderr, readset)) {
348 		len = read(fderr, buf, sizeof(buf));
349 		if (len <= 0)
350 			fderr_eof = 1;
351 		else
352 			buffer_append(&stderr_buffer, buf, len);
353 	}
354 }
355 
356 /*
357  * Sends data from internal buffers to client program stdin.
358  */
359 void
360 process_output(fd_set * writeset)
361 {
362 	int len;
363 
364 	/* Write buffered data to program stdin. */
365 	if (fdin != -1 && FD_ISSET(fdin, writeset)) {
366 		len = write(fdin, buffer_ptr(&stdin_buffer),
367 		    buffer_len(&stdin_buffer));
368 		if (len <= 0) {
369 #ifdef USE_PIPES
370 			close(fdin);
371 #else
372 			if (fdout == -1)
373 				close(fdin);
374 			else
375 				shutdown(fdin, SHUT_WR); /* We will no longer send. */
376 #endif
377 			fdin = -1;
378 		} else {
379 			/* Successful write.  Consume the data from the buffer. */
380 			buffer_consume(&stdin_buffer, len);
381 			/* Update the count of bytes written to the program. */
382 			stdin_bytes += len;
383 		}
384 	}
385 	/* Send any buffered packet data to the client. */
386 	if (FD_ISSET(connection_out, writeset))
387 		packet_write_poll();
388 }
389 
390 /*
391  * Wait until all buffered output has been sent to the client.
392  * This is used when the program terminates.
393  */
394 void
395 drain_output()
396 {
397 	/* Send any buffered stdout data to the client. */
398 	if (buffer_len(&stdout_buffer) > 0) {
399 		packet_start(SSH_SMSG_STDOUT_DATA);
400 		packet_put_string(buffer_ptr(&stdout_buffer),
401 				  buffer_len(&stdout_buffer));
402 		packet_send();
403 		/* Update the count of sent bytes. */
404 		stdout_bytes += buffer_len(&stdout_buffer);
405 	}
406 	/* Send any buffered stderr data to the client. */
407 	if (buffer_len(&stderr_buffer) > 0) {
408 		packet_start(SSH_SMSG_STDERR_DATA);
409 		packet_put_string(buffer_ptr(&stderr_buffer),
410 				  buffer_len(&stderr_buffer));
411 		packet_send();
412 		/* Update the count of sent bytes. */
413 		stderr_bytes += buffer_len(&stderr_buffer);
414 	}
415 	/* Wait until all buffered data has been written to the client. */
416 	packet_write_wait();
417 }
418 
419 /*
420  * Performs the interactive session.  This handles data transmission between
421  * the client and the program.  Note that the notion of stdin, stdout, and
422  * stderr in this function is sort of reversed: this function writes to
423  * stdin (of the child program), and reads from stdout and stderr (of the
424  * child program).
425  */
426 void
427 server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
428 {
429 	int wait_status, wait_pid;	/* Status and pid returned by wait(). */
430 	int waiting_termination = 0;	/* Have displayed waiting close message. */
431 	unsigned int max_time_milliseconds;
432 	unsigned int previous_stdout_buffer_bytes;
433 	unsigned int stdout_buffer_bytes;
434 	int type;
435 
436 	debug("Entering interactive session.");
437 
438 	/* Initialize the SIGCHLD kludge. */
439 	child_pid = pid;
440 	child_terminated = 0;
441 	signal(SIGCHLD, sigchld_handler);
442 
443 	/* Initialize our global variables. */
444 	fdin = fdin_arg;
445 	fdout = fdout_arg;
446 	fderr = fderr_arg;
447 	connection_in = packet_get_connection_in();
448 	connection_out = packet_get_connection_out();
449 
450 	previous_stdout_buffer_bytes = 0;
451 
452 	/* Set approximate I/O buffer size. */
453 	if (packet_is_interactive())
454 		buffer_high = 4096;
455 	else
456 		buffer_high = 64 * 1024;
457 
458 	/* Initialize max_fd to the maximum of the known file descriptors. */
459 	max_fd = fdin;
460 	if (fdout > max_fd)
461 		max_fd = fdout;
462 	if (fderr != -1 && fderr > max_fd)
463 		max_fd = fderr;
464 	if (connection_in > max_fd)
465 		max_fd = connection_in;
466 	if (connection_out > max_fd)
467 		max_fd = connection_out;
468 
469 	/* Initialize Initialize buffers. */
470 	buffer_init(&stdin_buffer);
471 	buffer_init(&stdout_buffer);
472 	buffer_init(&stderr_buffer);
473 
474 	/*
475 	 * If we have no separate fderr (which is the case when we have a pty
476 	 * - there we cannot make difference between data sent to stdout and
477 	 * stderr), indicate that we have seen an EOF from stderr.  This way
478 	 * we don\'t need to check the descriptor everywhere.
479 	 */
480 	if (fderr == -1)
481 		fderr_eof = 1;
482 
483 	/* Main loop of the server for the interactive session mode. */
484 	for (;;) {
485 		fd_set readset, writeset;
486 
487 		/* Process buffered packets from the client. */
488 		process_buffered_input_packets();
489 
490 		/*
491 		 * If we have received eof, and there is no more pending
492 		 * input data, cause a real eof by closing fdin.
493 		 */
494 		if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
495 #ifdef USE_PIPES
496 			close(fdin);
497 #else
498 			if (fdout == -1)
499 				close(fdin);
500 			else
501 				shutdown(fdin, SHUT_WR); /* We will no longer send. */
502 #endif
503 			fdin = -1;
504 		}
505 		/* Make packets from buffered stderr data to send to the client. */
506 		make_packets_from_stderr_data();
507 
508 		/*
509 		 * Make packets from buffered stdout data to send to the
510 		 * client. If there is very little to send, this arranges to
511 		 * not send them now, but to wait a short while to see if we
512 		 * are getting more data. This is necessary, as some systems
513 		 * wake up readers from a pty after each separate character.
514 		 */
515 		max_time_milliseconds = 0;
516 		stdout_buffer_bytes = buffer_len(&stdout_buffer);
517 		if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
518 		    stdout_buffer_bytes != previous_stdout_buffer_bytes) {
519 			/* try again after a while */
520 			max_time_milliseconds = 10;
521 		} else {
522 			/* Send it now. */
523 			make_packets_from_stdout_data();
524 		}
525 		previous_stdout_buffer_bytes = buffer_len(&stdout_buffer);
526 
527 		/* Send channel data to the client. */
528 		if (packet_not_very_much_data_to_write())
529 			channel_output_poll();
530 
531 		/*
532 		 * Bail out of the loop if the program has closed its output
533 		 * descriptors, and we have no more data to send to the
534 		 * client, and there is no pending buffered data.
535 		 */
536 		if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
537 		    buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
538 			if (!channel_still_open())
539 				goto quit;
540 			if (!waiting_termination) {
541 				const char *s = "Waiting for forwarded connections to terminate...\r\n";
542 				char *cp;
543 				waiting_termination = 1;
544 				buffer_append(&stderr_buffer, s, strlen(s));
545 
546 				/* Display list of open channels. */
547 				cp = channel_open_message();
548 				buffer_append(&stderr_buffer, cp, strlen(cp));
549 				xfree(cp);
550 			}
551 		}
552 		/* Sleep in select() until we can do something. */
553 		wait_until_can_do_something(&readset, &writeset,
554 					    max_time_milliseconds);
555 
556 		/* Process any channel events. */
557 		channel_after_select(&readset, &writeset);
558 
559 		/* Process input from the client and from program stdout/stderr. */
560 		process_input(&readset);
561 
562 		/* Process output to the client and to program stdin. */
563 		process_output(&writeset);
564 	}
565 
566 quit:
567 	/* Cleanup and termination code. */
568 
569 	/* Wait until all output has been sent to the client. */
570 	drain_output();
571 
572 	debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
573 	      stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);
574 
575 	/* Free and clear the buffers. */
576 	buffer_free(&stdin_buffer);
577 	buffer_free(&stdout_buffer);
578 	buffer_free(&stderr_buffer);
579 
580 	/* Close the file descriptors. */
581 	if (fdout != -1)
582 		close(fdout);
583 	fdout = -1;
584 	fdout_eof = 1;
585 	if (fderr != -1)
586 		close(fderr);
587 	fderr = -1;
588 	fderr_eof = 1;
589 	if (fdin != -1)
590 		close(fdin);
591 	fdin = -1;
592 
593 	/* Stop listening for channels; this removes unix domain sockets. */
594 	channel_stop_listening();
595 
596 	/* Wait for the child to exit.  Get its exit status. */
597 	wait_pid = wait(&wait_status);
598 	if (wait_pid < 0) {
599 		/*
600 		 * It is possible that the wait was handled by SIGCHLD
601 		 * handler.  This may result in either: this call
602 		 * returning with EINTR, or: this call returning ECHILD.
603 		 */
604 		if (child_terminated)
605 			wait_status = child_wait_status;
606 		else
607 			packet_disconnect("wait: %.100s", strerror(errno));
608 	} else {
609 		/* Check if it matches the process we forked. */
610 		if (wait_pid != pid)
611 			error("Strange, wait returned pid %d, expected %d",
612 			       wait_pid, pid);
613 	}
614 
615 	/* We no longer want our SIGCHLD handler to be called. */
616 	signal(SIGCHLD, SIG_DFL);
617 
618 	/* Check if it exited normally. */
619 	if (WIFEXITED(wait_status)) {
620 		/* Yes, normal exit.  Get exit status and send it to the client. */
621 		debug("Command exited with status %d.", WEXITSTATUS(wait_status));
622 		packet_start(SSH_SMSG_EXITSTATUS);
623 		packet_put_int(WEXITSTATUS(wait_status));
624 		packet_send();
625 		packet_write_wait();
626 
627 		/*
628 		 * Wait for exit confirmation.  Note that there might be
629 		 * other packets coming before it; however, the program has
630 		 * already died so we just ignore them.  The client is
631 		 * supposed to respond with the confirmation when it receives
632 		 * the exit status.
633 		 */
634 		do {
635 			int plen;
636 			type = packet_read(&plen);
637 		}
638 		while (type != SSH_CMSG_EXIT_CONFIRMATION);
639 
640 		debug("Received exit confirmation.");
641 		return;
642 	}
643 	/* Check if the program terminated due to a signal. */
644 	if (WIFSIGNALED(wait_status))
645 		packet_disconnect("Command terminated on signal %d.",
646 				  WTERMSIG(wait_status));
647 
648 	/* Some weird exit cause.  Just exit. */
649 	packet_disconnect("wait returned status %04x.", wait_status);
650 	/* NOTREACHED */
651 }
652