diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | clientloop.c | 40 | ||||
-rw-r--r-- | serverloop.c | 55 | ||||
-rw-r--r-- | sshd.c | 23 |
4 files changed, 50 insertions, 74 deletions
@@ -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 | ||
43 | 20010606 | 47 | 20010606 |
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" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.74 2001/05/31 10:30:15 markus Exp $"); | 62 | RCSID("$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 | */ |
104 | static volatile int received_window_change_signal = 0; | 104 | static volatile int received_window_change_signal = 0; |
105 | static 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. */ |
107 | static int in_non_blocking_mode = 0; | 108 | static int in_non_blocking_mode = 0; |
@@ -171,13 +172,8 @@ window_change_handler(int sig) | |||
171 | void | 172 | void |
172 | signal_handler(int sig) | 173 | signal_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" |
38 | RCSID("$OpenBSD: serverloop.c,v 1.67 2001/05/31 10:30:16 markus Exp $"); | 38 | RCSID("$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 | |||
88 | static pid_t child_pid; /* Pid of the child. */ | ||
89 | static volatile int child_terminated; /* The child has terminated. */ | 87 | static volatile int child_terminated; /* The child has terminated. */ |
90 | static volatile int child_wait_status; /* Status from wait(). */ | ||
91 | 88 | ||
92 | void server_init_dispatch(void); | 89 | void server_init_dispatch(void); |
93 | 90 | ||
@@ -97,28 +94,9 @@ void | |||
97 | sigchld_handler(int sig) | 94 | sigchld_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 | } | ||
115 | void | ||
116 | sigchld_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(); |
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: sshd.c,v 1.198 2001/05/28 23:58:35 markus Exp $"); | 43 | RCSID("$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 | */ |
168 | int key_do_regen = 0; | 168 | int 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. */ |
171 | int received_sighup = 0; | 171 | int received_sighup = 0; |
172 | int received_sigterm = 0; | ||
172 | 173 | ||
173 | /* session identifier, used by RSA-auth */ | 174 | /* session identifier, used by RSA-auth */ |
174 | u_char session_id[16]; | 175 | u_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 | */ |
233 | void | 232 | void |
234 | sigterm_handler(int sig) | 233 | sigterm_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 | */ |
246 | void | 242 | void |
247 | main_sigchld_handler(int sig) | 243 | main_sigchld_handler(int sig) |
@@ -262,6 +258,8 @@ main_sigchld_handler(int sig) | |||
262 | void | 258 | void |
263 | grace_alarm_handler(int sig) | 259 | grace_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; |