diff options
Diffstat (limited to 'clientloop.c')
-rw-r--r-- | clientloop.c | 91 |
1 files changed, 49 insertions, 42 deletions
diff --git a/clientloop.c b/clientloop.c index 2ef816ab3..86695cc16 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.248 2013/01/02 00:32:07 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.c,v 1.253 2013/06/07 15:37:52 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -277,7 +277,7 @@ set_control_persist_exit_time(void) | |||
277 | control_persist_exit_time = 0; | 277 | control_persist_exit_time = 0; |
278 | } else if (control_persist_exit_time <= 0) { | 278 | } else if (control_persist_exit_time <= 0) { |
279 | /* a client connection has recently closed */ | 279 | /* a client connection has recently closed */ |
280 | control_persist_exit_time = time(NULL) + | 280 | control_persist_exit_time = monotime() + |
281 | (time_t)options.control_persist_timeout; | 281 | (time_t)options.control_persist_timeout; |
282 | debug2("%s: schedule exit in %d seconds", __func__, | 282 | debug2("%s: schedule exit in %d seconds", __func__, |
283 | options.control_persist_timeout); | 283 | options.control_persist_timeout); |
@@ -360,7 +360,7 @@ client_x11_get_proto(const char *display, const char *xauth_path, | |||
360 | if (system(cmd) == 0) | 360 | if (system(cmd) == 0) |
361 | generated = 1; | 361 | generated = 1; |
362 | if (x11_refuse_time == 0) { | 362 | if (x11_refuse_time == 0) { |
363 | now = time(NULL) + 1; | 363 | now = monotime() + 1; |
364 | if (UINT_MAX - timeout < now) | 364 | if (UINT_MAX - timeout < now) |
365 | x11_refuse_time = UINT_MAX; | 365 | x11_refuse_time = UINT_MAX; |
366 | else | 366 | else |
@@ -397,10 +397,8 @@ client_x11_get_proto(const char *display, const char *xauth_path, | |||
397 | unlink(xauthfile); | 397 | unlink(xauthfile); |
398 | rmdir(xauthdir); | 398 | rmdir(xauthdir); |
399 | } | 399 | } |
400 | if (xauthdir) | 400 | free(xauthdir); |
401 | xfree(xauthdir); | 401 | free(xauthfile); |
402 | if (xauthfile) | ||
403 | xfree(xauthfile); | ||
404 | 402 | ||
405 | /* | 403 | /* |
406 | * If we didn't get authentication data, just make up some | 404 | * If we didn't get authentication data, just make up some |
@@ -556,7 +554,7 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt) | |||
556 | if (--gc->ref_count <= 0) { | 554 | if (--gc->ref_count <= 0) { |
557 | TAILQ_REMOVE(&global_confirms, gc, entry); | 555 | TAILQ_REMOVE(&global_confirms, gc, entry); |
558 | bzero(gc, sizeof(*gc)); | 556 | bzero(gc, sizeof(*gc)); |
559 | xfree(gc); | 557 | free(gc); |
560 | } | 558 | } |
561 | 559 | ||
562 | packet_set_alive_timeouts(0); | 560 | packet_set_alive_timeouts(0); |
@@ -587,7 +585,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | |||
587 | { | 585 | { |
588 | struct timeval tv, *tvp; | 586 | struct timeval tv, *tvp; |
589 | int timeout_secs; | 587 | int timeout_secs; |
590 | time_t minwait_secs = 0; | 588 | time_t minwait_secs = 0, server_alive_time = 0, now = monotime(); |
591 | int ret; | 589 | int ret; |
592 | 590 | ||
593 | /* Add any selections by the channel mechanism. */ | 591 | /* Add any selections by the channel mechanism. */ |
@@ -636,12 +634,16 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | |||
636 | */ | 634 | */ |
637 | 635 | ||
638 | timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ | 636 | timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ |
639 | if (options.server_alive_interval > 0 && compat20) | 637 | if (options.server_alive_interval > 0 && compat20) { |
640 | timeout_secs = options.server_alive_interval; | 638 | timeout_secs = options.server_alive_interval; |
639 | server_alive_time = now + options.server_alive_interval; | ||
640 | } | ||
641 | if (options.rekey_interval > 0 && compat20 && !rekeying) | ||
642 | timeout_secs = MIN(timeout_secs, packet_get_rekey_timeout()); | ||
641 | set_control_persist_exit_time(); | 643 | set_control_persist_exit_time(); |
642 | if (control_persist_exit_time > 0) { | 644 | if (control_persist_exit_time > 0) { |
643 | timeout_secs = MIN(timeout_secs, | 645 | timeout_secs = MIN(timeout_secs, |
644 | control_persist_exit_time - time(NULL)); | 646 | control_persist_exit_time - now); |
645 | if (timeout_secs < 0) | 647 | if (timeout_secs < 0) |
646 | timeout_secs = 0; | 648 | timeout_secs = 0; |
647 | } | 649 | } |
@@ -673,8 +675,15 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | |||
673 | snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); | 675 | snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); |
674 | buffer_append(&stderr_buffer, buf, strlen(buf)); | 676 | buffer_append(&stderr_buffer, buf, strlen(buf)); |
675 | quit_pending = 1; | 677 | quit_pending = 1; |
676 | } else if (ret == 0) | 678 | } else if (ret == 0) { |
677 | server_alive_check(); | 679 | /* |
680 | * Timeout. Could have been either keepalive or rekeying. | ||
681 | * Keepalive we check here, rekeying is checked in clientloop. | ||
682 | */ | ||
683 | if (server_alive_time != 0 && server_alive_time <= monotime()) | ||
684 | server_alive_check(); | ||
685 | } | ||
686 | |||
678 | } | 687 | } |
679 | 688 | ||
680 | static void | 689 | static void |
@@ -819,13 +828,13 @@ client_status_confirm(int type, Channel *c, void *ctx) | |||
819 | chan_write_failed(c); | 828 | chan_write_failed(c); |
820 | } | 829 | } |
821 | } | 830 | } |
822 | xfree(cr); | 831 | free(cr); |
823 | } | 832 | } |
824 | 833 | ||
825 | static void | 834 | static void |
826 | client_abandon_status_confirm(Channel *c, void *ctx) | 835 | client_abandon_status_confirm(Channel *c, void *ctx) |
827 | { | 836 | { |
828 | xfree(ctx); | 837 | free(ctx); |
829 | } | 838 | } |
830 | 839 | ||
831 | void | 840 | void |
@@ -992,12 +1001,9 @@ process_cmdline(void) | |||
992 | out: | 1001 | out: |
993 | signal(SIGINT, handler); | 1002 | signal(SIGINT, handler); |
994 | enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 1003 | enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |
995 | if (cmd) | 1004 | free(cmd); |
996 | xfree(cmd); | 1005 | free(fwd.listen_host); |
997 | if (fwd.listen_host != NULL) | 1006 | free(fwd.connect_host); |
998 | xfree(fwd.listen_host); | ||
999 | if (fwd.connect_host != NULL) | ||
1000 | xfree(fwd.connect_host); | ||
1001 | } | 1007 | } |
1002 | 1008 | ||
1003 | /* reasons to suppress output of an escape command in help output */ | 1009 | /* reasons to suppress output of an escape command in help output */ |
@@ -1107,8 +1113,11 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, | |||
1107 | if (c && c->ctl_chan != -1) { | 1113 | if (c && c->ctl_chan != -1) { |
1108 | chan_read_failed(c); | 1114 | chan_read_failed(c); |
1109 | chan_write_failed(c); | 1115 | chan_write_failed(c); |
1110 | mux_master_session_cleanup_cb(c->self, | 1116 | if (c->detach_user) |
1111 | NULL); | 1117 | c->detach_user(c->self, NULL); |
1118 | c->type = SSH_CHANNEL_ABANDONED; | ||
1119 | buffer_clear(&c->input); | ||
1120 | chan_ibuf_empty(c); | ||
1112 | return 0; | 1121 | return 0; |
1113 | } else | 1122 | } else |
1114 | quit_pending = 1; | 1123 | quit_pending = 1; |
@@ -1254,7 +1263,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, | |||
1254 | buffer_append(berr, string, strlen(string)); | 1263 | buffer_append(berr, string, strlen(string)); |
1255 | s = channel_open_message(); | 1264 | s = channel_open_message(); |
1256 | buffer_append(berr, s, strlen(s)); | 1265 | buffer_append(berr, s, strlen(s)); |
1257 | xfree(s); | 1266 | free(s); |
1258 | continue; | 1267 | continue; |
1259 | 1268 | ||
1260 | case 'C': | 1269 | case 'C': |
@@ -1443,7 +1452,7 @@ client_new_escape_filter_ctx(int escape_char) | |||
1443 | void | 1452 | void |
1444 | client_filter_cleanup(int cid, void *ctx) | 1453 | client_filter_cleanup(int cid, void *ctx) |
1445 | { | 1454 | { |
1446 | xfree(ctx); | 1455 | free(ctx); |
1447 | } | 1456 | } |
1448 | 1457 | ||
1449 | int | 1458 | int |
@@ -1657,16 +1666,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1657 | * connections, then quit. | 1666 | * connections, then quit. |
1658 | */ | 1667 | */ |
1659 | if (control_persist_exit_time > 0) { | 1668 | if (control_persist_exit_time > 0) { |
1660 | if (time(NULL) >= control_persist_exit_time) { | 1669 | if (monotime() >= control_persist_exit_time) { |
1661 | debug("ControlPersist timeout expired"); | 1670 | debug("ControlPersist timeout expired"); |
1662 | break; | 1671 | break; |
1663 | } | 1672 | } |
1664 | } | 1673 | } |
1665 | } | 1674 | } |
1666 | if (readset) | 1675 | free(readset); |
1667 | xfree(readset); | 1676 | free(writeset); |
1668 | if (writeset) | ||
1669 | xfree(writeset); | ||
1670 | 1677 | ||
1671 | /* Terminate the session. */ | 1678 | /* Terminate the session. */ |
1672 | 1679 | ||
@@ -1768,7 +1775,7 @@ client_input_stdout_data(int type, u_int32_t seq, void *ctxt) | |||
1768 | packet_check_eom(); | 1775 | packet_check_eom(); |
1769 | buffer_append(&stdout_buffer, data, data_len); | 1776 | buffer_append(&stdout_buffer, data, data_len); |
1770 | memset(data, 0, data_len); | 1777 | memset(data, 0, data_len); |
1771 | xfree(data); | 1778 | free(data); |
1772 | } | 1779 | } |
1773 | static void | 1780 | static void |
1774 | client_input_stderr_data(int type, u_int32_t seq, void *ctxt) | 1781 | client_input_stderr_data(int type, u_int32_t seq, void *ctxt) |
@@ -1778,7 +1785,7 @@ client_input_stderr_data(int type, u_int32_t seq, void *ctxt) | |||
1778 | packet_check_eom(); | 1785 | packet_check_eom(); |
1779 | buffer_append(&stderr_buffer, data, data_len); | 1786 | buffer_append(&stderr_buffer, data, data_len); |
1780 | memset(data, 0, data_len); | 1787 | memset(data, 0, data_len); |
1781 | xfree(data); | 1788 | free(data); |
1782 | } | 1789 | } |
1783 | static void | 1790 | static void |
1784 | client_input_exit_status(int type, u_int32_t seq, void *ctxt) | 1791 | client_input_exit_status(int type, u_int32_t seq, void *ctxt) |
@@ -1858,8 +1865,8 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) | |||
1858 | c = channel_connect_by_listen_address(listen_port, | 1865 | c = channel_connect_by_listen_address(listen_port, |
1859 | "forwarded-tcpip", originator_address); | 1866 | "forwarded-tcpip", originator_address); |
1860 | 1867 | ||
1861 | xfree(originator_address); | 1868 | free(originator_address); |
1862 | xfree(listen_address); | 1869 | free(listen_address); |
1863 | return c; | 1870 | return c; |
1864 | } | 1871 | } |
1865 | 1872 | ||
@@ -1877,7 +1884,7 @@ client_request_x11(const char *request_type, int rchan) | |||
1877 | "malicious server."); | 1884 | "malicious server."); |
1878 | return NULL; | 1885 | return NULL; |
1879 | } | 1886 | } |
1880 | if (x11_refuse_time != 0 && time(NULL) >= x11_refuse_time) { | 1887 | if (x11_refuse_time != 0 && monotime() >= x11_refuse_time) { |
1881 | verbose("Rejected X11 connection after ForwardX11Timeout " | 1888 | verbose("Rejected X11 connection after ForwardX11Timeout " |
1882 | "expired"); | 1889 | "expired"); |
1883 | return NULL; | 1890 | return NULL; |
@@ -1893,7 +1900,7 @@ client_request_x11(const char *request_type, int rchan) | |||
1893 | /* XXX check permission */ | 1900 | /* XXX check permission */ |
1894 | debug("client_request_x11: request from %s %d", originator, | 1901 | debug("client_request_x11: request from %s %d", originator, |
1895 | originator_port); | 1902 | originator_port); |
1896 | xfree(originator); | 1903 | free(originator); |
1897 | sock = x11_connect_display(); | 1904 | sock = x11_connect_display(); |
1898 | if (sock < 0) | 1905 | if (sock < 0) |
1899 | return NULL; | 1906 | return NULL; |
@@ -2020,7 +2027,7 @@ client_input_channel_open(int type, u_int32_t seq, void *ctxt) | |||
2020 | } | 2027 | } |
2021 | packet_send(); | 2028 | packet_send(); |
2022 | } | 2029 | } |
2023 | xfree(ctype); | 2030 | free(ctype); |
2024 | } | 2031 | } |
2025 | static void | 2032 | static void |
2026 | client_input_channel_req(int type, u_int32_t seq, void *ctxt) | 2033 | client_input_channel_req(int type, u_int32_t seq, void *ctxt) |
@@ -2066,7 +2073,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) | |||
2066 | packet_put_int(c->remote_id); | 2073 | packet_put_int(c->remote_id); |
2067 | packet_send(); | 2074 | packet_send(); |
2068 | } | 2075 | } |
2069 | xfree(rtype); | 2076 | free(rtype); |
2070 | } | 2077 | } |
2071 | static void | 2078 | static void |
2072 | client_input_global_request(int type, u_int32_t seq, void *ctxt) | 2079 | client_input_global_request(int type, u_int32_t seq, void *ctxt) |
@@ -2085,7 +2092,7 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt) | |||
2085 | packet_send(); | 2092 | packet_send(); |
2086 | packet_write_wait(); | 2093 | packet_write_wait(); |
2087 | } | 2094 | } |
2088 | xfree(rtype); | 2095 | free(rtype); |
2089 | } | 2096 | } |
2090 | 2097 | ||
2091 | void | 2098 | void |
@@ -2135,7 +2142,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem, | |||
2135 | /* Split */ | 2142 | /* Split */ |
2136 | name = xstrdup(env[i]); | 2143 | name = xstrdup(env[i]); |
2137 | if ((val = strchr(name, '=')) == NULL) { | 2144 | if ((val = strchr(name, '=')) == NULL) { |
2138 | xfree(name); | 2145 | free(name); |
2139 | continue; | 2146 | continue; |
2140 | } | 2147 | } |
2141 | *val++ = '\0'; | 2148 | *val++ = '\0'; |
@@ -2149,7 +2156,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem, | |||
2149 | } | 2156 | } |
2150 | if (!matched) { | 2157 | if (!matched) { |
2151 | debug3("Ignored env %s", name); | 2158 | debug3("Ignored env %s", name); |
2152 | xfree(name); | 2159 | free(name); |
2153 | continue; | 2160 | continue; |
2154 | } | 2161 | } |
2155 | 2162 | ||
@@ -2158,7 +2165,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem, | |||
2158 | packet_put_cstring(name); | 2165 | packet_put_cstring(name); |
2159 | packet_put_cstring(val); | 2166 | packet_put_cstring(val); |
2160 | packet_send(); | 2167 | packet_send(); |
2161 | xfree(name); | 2168 | free(name); |
2162 | } | 2169 | } |
2163 | } | 2170 | } |
2164 | 2171 | ||