summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--clientloop.c40
-rw-r--r--serverloop.c55
-rw-r--r--sshd.c23
4 files changed, 50 insertions, 74 deletions
diff --git a/ChangeLog b/ChangeLog
index ba70812f0..84538fe6b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -39,6 +39,10 @@
39 [channels.c channels.h session.c] 39 [channels.c channels.h session.c]
40 switch uid when cleaning up tmp files and sockets; reported by 40 switch uid when cleaning up tmp files and sockets; reported by
41 zen-parse@gmx.net on bugtraq 41 zen-parse@gmx.net on bugtraq
42 - markus@cvs.openbsd.org 2001/06/04 23:07:21
43 [clientloop.c serverloop.c sshd.c]
44 set flags in the signal handlers, do real work in the main loop,
45 ok provos@
42 46
4320010606 4720010606
44 - OpenBSD CVS Sync 48 - OpenBSD CVS Sync
@@ -5550,4 +5554,4 @@
5550 - Wrote replacements for strlcpy and mkdtemp 5554 - Wrote replacements for strlcpy and mkdtemp
5551 - Released 1.0pre1 5555 - Released 1.0pre1
5552 5556
5553$Id: ChangeLog,v 1.1258 2001/06/09 01:20:06 mouring Exp $ 5557$Id: ChangeLog,v 1.1259 2001/06/09 01:27:31 mouring Exp $
diff --git a/clientloop.c b/clientloop.c
index 70abee8fd..3a1b43dda 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
59 */ 59 */
60 60
61#include "includes.h" 61#include "includes.h"
62RCSID("$OpenBSD: clientloop.c,v 1.74 2001/05/31 10:30:15 markus Exp $"); 62RCSID("$OpenBSD: clientloop.c,v 1.75 2001/06/04 23:07:20 markus Exp $");
63 63
64#include "ssh.h" 64#include "ssh.h"
65#include "ssh1.h" 65#include "ssh1.h"
@@ -102,6 +102,7 @@ extern char *host;
102 * because this is updated in a signal handler. 102 * because this is updated in a signal handler.
103 */ 103 */
104static volatile int received_window_change_signal = 0; 104static volatile int received_window_change_signal = 0;
105static volatile int received_signal = 0;
105 106
106/* Flag indicating whether the user\'s terminal is in non-blocking mode. */ 107/* Flag indicating whether the user\'s terminal is in non-blocking mode. */
107static int in_non_blocking_mode = 0; 108static int in_non_blocking_mode = 0;
@@ -171,13 +172,8 @@ window_change_handler(int sig)
171void 172void
172signal_handler(int sig) 173signal_handler(int sig)
173{ 174{
174 if (in_raw_mode()) 175 received_signal = sig;
175 leave_raw_mode(); 176 quit_pending = 1;
176 if (in_non_blocking_mode)
177 leave_non_blocking();
178 channel_stop_listening();
179 packet_close();
180 fatal("Killed by signal %d.", sig);
181} 177}
182 178
183/* 179/*
@@ -933,14 +929,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
933 /* Stop listening for connections. */ 929 /* Stop listening for connections. */
934 channel_stop_listening(); 930 channel_stop_listening();
935 931
936 /* 932 if (have_pty)
937 * In interactive mode (with pseudo tty) display a message indicating 933 leave_raw_mode();
938 * that the connection has been closed.
939 */
940 if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {
941 snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host);
942 buffer_append(&stderr_buffer, buf, strlen(buf));
943 }
944 934
945 /* restore blocking io */ 935 /* restore blocking io */
946 if (!isatty(fileno(stdin))) 936 if (!isatty(fileno(stdin)))
@@ -950,6 +940,21 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
950 if (!isatty(fileno(stderr))) 940 if (!isatty(fileno(stderr)))
951 unset_nonblock(fileno(stderr)); 941 unset_nonblock(fileno(stderr));
952 942
943 if (received_signal) {
944 if (in_non_blocking_mode) /* XXX */
945 leave_non_blocking();
946 fatal("Killed by signal %d.", received_signal);
947 }
948
949 /*
950 * In interactive mode (with pseudo tty) display a message indicating
951 * that the connection has been closed.
952 */
953 if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {
954 snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host);
955 buffer_append(&stderr_buffer, buf, strlen(buf));
956 }
957
953 /* Output any buffered data for stdout. */ 958 /* Output any buffered data for stdout. */
954 while (buffer_len(&stdout_buffer) > 0) { 959 while (buffer_len(&stdout_buffer) > 0) {
955 len = write(fileno(stdout), buffer_ptr(&stdout_buffer), 960 len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
@@ -974,9 +979,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
974 stderr_bytes += len; 979 stderr_bytes += len;
975 } 980 }
976 981
977 if (have_pty)
978 leave_raw_mode();
979
980 /* Clear and free any buffers. */ 982 /* Clear and free any buffers. */
981 memset(buf, 0, sizeof(buf)); 983 memset(buf, 0, sizeof(buf));
982 buffer_free(&stdin_buffer); 984 buffer_free(&stdin_buffer);
diff --git a/serverloop.c b/serverloop.c
index d8026ec5a..bafbfb0ac 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: serverloop.c,v 1.67 2001/05/31 10:30:16 markus Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.68 2001/06/04 23:07:20 markus Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "packet.h" 41#include "packet.h"
@@ -84,10 +84,7 @@ static u_int buffer_high; /* "Soft" max buffer size. */
84 * This SIGCHLD kludge is used to detect when the child exits. The server 84 * This SIGCHLD kludge is used to detect when the child exits. The server
85 * will exit after that, as soon as forwarded connections have terminated. 85 * will exit after that, as soon as forwarded connections have terminated.
86 */ 86 */
87
88static pid_t child_pid; /* Pid of the child. */
89static volatile int child_terminated; /* The child has terminated. */ 87static volatile int child_terminated; /* The child has terminated. */
90static volatile int child_wait_status; /* Status from wait(). */
91 88
92void server_init_dispatch(void); 89void server_init_dispatch(void);
93 90
@@ -97,28 +94,9 @@ void
97sigchld_handler(int sig) 94sigchld_handler(int sig)
98{ 95{
99 int save_errno = errno; 96 int save_errno = errno;
100 pid_t wait_pid;
101
102 debug("Received SIGCHLD.");
103 wait_pid = wait((int *) &child_wait_status);
104 if (wait_pid != -1) {
105 if (wait_pid != child_pid)
106 error("Strange, got SIGCHLD and wait returned pid %d but child is %d",
107 wait_pid, child_pid);
108 if (WIFEXITED(child_wait_status) ||
109 WIFSIGNALED(child_wait_status))
110 child_terminated = 1;
111 }
112 signal(SIGCHLD, sigchld_handler);
113 errno = save_errno;
114}
115void
116sigchld_handler2(int sig)
117{
118 int save_errno = errno;
119 debug("Received SIGCHLD."); 97 debug("Received SIGCHLD.");
120 child_terminated = 1; 98 child_terminated = 1;
121 mysignal(SIGCHLD, sigchld_handler2); 99 mysignal(SIGCHLD, sigchld_handler);
122 errno = save_errno; 100 errno = save_errno;
123} 101}
124 102
@@ -466,7 +444,6 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
466 debug("Entering interactive session."); 444 debug("Entering interactive session.");
467 445
468 /* Initialize the SIGCHLD kludge. */ 446 /* Initialize the SIGCHLD kludge. */
469 child_pid = pid;
470 child_terminated = 0; 447 child_terminated = 0;
471 signal(SIGCHLD, sigchld_handler); 448 signal(SIGCHLD, sigchld_handler);
472 449
@@ -634,28 +611,16 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
634 /* Stop listening for channels; this removes unix domain sockets. */ 611 /* Stop listening for channels; this removes unix domain sockets. */
635 channel_stop_listening(); 612 channel_stop_listening();
636 613
637 /* Wait for the child to exit. Get its exit status. */
638 wait_pid = wait(&wait_status);
639 if (wait_pid == -1) {
640 /*
641 * It is possible that the wait was handled by SIGCHLD
642 * handler. This may result in either: this call
643 * returning with EINTR, or: this call returning ECHILD.
644 */
645 if (child_terminated)
646 wait_status = child_wait_status;
647 else
648 packet_disconnect("wait: %.100s", strerror(errno));
649 } else {
650 /* Check if it matches the process we forked. */
651 if (wait_pid != pid)
652 error("Strange, wait returned pid %d, expected %d",
653 wait_pid, pid);
654 }
655
656 /* We no longer want our SIGCHLD handler to be called. */ 614 /* We no longer want our SIGCHLD handler to be called. */
657 signal(SIGCHLD, SIG_DFL); 615 signal(SIGCHLD, SIG_DFL);
658 616
617 wait_pid = waitpid(-1, &wait_status, child_terminated ? WNOHANG : 0);
618 if (wait_pid == -1)
619 packet_disconnect("wait: %.100s", strerror(errno));
620 else if (wait_pid != pid)
621 error("Strange, wait returned pid %d, expected %d",
622 wait_pid, pid);
623
659 /* Check if it exited normally. */ 624 /* Check if it exited normally. */
660 if (WIFEXITED(wait_status)) { 625 if (WIFEXITED(wait_status)) {
661 /* Yes, normal exit. Get exit status and send it to the client. */ 626 /* Yes, normal exit. Get exit status and send it to the client. */
@@ -700,7 +665,7 @@ server_loop2(void)
700 665
701 debug("Entering interactive session for SSH2."); 666 debug("Entering interactive session for SSH2.");
702 667
703 mysignal(SIGCHLD, sigchld_handler2); 668 mysignal(SIGCHLD, sigchld_handler);
704 child_terminated = 0; 669 child_terminated = 0;
705 connection_in = packet_get_connection_in(); 670 connection_in = packet_get_connection_in();
706 connection_out = packet_get_connection_out(); 671 connection_out = packet_get_connection_out();
diff --git a/sshd.c b/sshd.c
index 869c12011..1dfcac0d7 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: sshd.c,v 1.198 2001/05/28 23:58:35 markus Exp $"); 43RCSID("$OpenBSD: sshd.c,v 1.199 2001/06/04 23:07:21 markus Exp $");
44 44
45#include <openssl/dh.h> 45#include <openssl/dh.h>
46#include <openssl/bn.h> 46#include <openssl/bn.h>
@@ -167,8 +167,9 @@ struct {
167 */ 167 */
168int key_do_regen = 0; 168int key_do_regen = 0;
169 169
170/* This is set to true when SIGHUP is received. */ 170/* This is set to true when a signal is received. */
171int received_sighup = 0; 171int received_sighup = 0;
172int received_sigterm = 0;
172 173
173/* session identifier, used by RSA-auth */ 174/* session identifier, used by RSA-auth */
174u_char session_id[16]; 175u_char session_id[16];
@@ -227,21 +228,16 @@ sighup_restart(void)
227 228
228/* 229/*
229 * Generic signal handler for terminating signals in the master daemon. 230 * Generic signal handler for terminating signals in the master daemon.
230 * These close the listen socket; not closing it seems to cause "Address
231 * already in use" problems on some machines, which is inconvenient.
232 */ 231 */
233void 232void
234sigterm_handler(int sig) 233sigterm_handler(int sig)
235{ 234{
236 log("Received signal %d; terminating.", sig); 235 received_sigterm = sig;
237 close_listen_socks();
238 unlink(options.pid_file);
239 exit(255);
240} 236}
241 237
242/* 238/*
243 * SIGCHLD handler. This is called whenever a child dies. This will then 239 * SIGCHLD handler. This is called whenever a child dies. This will then
244 * reap any zombies left by exited c. 240 * reap any zombies left by exited children.
245 */ 241 */
246void 242void
247main_sigchld_handler(int sig) 243main_sigchld_handler(int sig)
@@ -262,6 +258,8 @@ main_sigchld_handler(int sig)
262void 258void
263grace_alarm_handler(int sig) 259grace_alarm_handler(int sig)
264{ 260{
261 /* XXX no idea how fix this signal handler */
262
265 /* Close the connection. */ 263 /* Close the connection. */
266 packet_close(); 264 packet_close();
267 265
@@ -939,6 +937,13 @@ main(int ac, char **av)
939 ret = select(maxfd+1, fdset, NULL, NULL, NULL); 937 ret = select(maxfd+1, fdset, NULL, NULL, NULL);
940 if (ret < 0 && errno != EINTR) 938 if (ret < 0 && errno != EINTR)
941 error("select: %.100s", strerror(errno)); 939 error("select: %.100s", strerror(errno));
940 if (received_sigterm) {
941 log("Received signal %d; terminating.",
942 received_sigterm);
943 close_listen_socks();
944 unlink(options.pid_file);
945 exit(255);
946 }
942 if (key_used && key_do_regen) { 947 if (key_used && key_do_regen) {
943 generate_ephemeral_server_key(); 948 generate_ephemeral_server_key();
944 key_used = 0; 949 key_used = 0;