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 1a16b2525..35550eb4d 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); |
@@ -592,7 +590,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | |||
592 | { | 590 | { |
593 | struct timeval tv, *tvp; | 591 | struct timeval tv, *tvp; |
594 | int timeout_secs; | 592 | int timeout_secs; |
595 | time_t minwait_secs = 0; | 593 | time_t minwait_secs = 0, server_alive_time = 0, now = monotime(); |
596 | int ret; | 594 | int ret; |
597 | 595 | ||
598 | /* Add any selections by the channel mechanism. */ | 596 | /* Add any selections by the channel mechanism. */ |
@@ -641,12 +639,16 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | |||
641 | */ | 639 | */ |
642 | 640 | ||
643 | timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ | 641 | timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ |
644 | if (options.server_alive_interval > 0) | 642 | if (options.server_alive_interval > 0) { |
645 | timeout_secs = options.server_alive_interval; | 643 | timeout_secs = options.server_alive_interval; |
644 | server_alive_time = now + options.server_alive_interval; | ||
645 | } | ||
646 | if (options.rekey_interval > 0 && compat20 && !rekeying) | ||
647 | timeout_secs = MIN(timeout_secs, packet_get_rekey_timeout()); | ||
646 | set_control_persist_exit_time(); | 648 | set_control_persist_exit_time(); |
647 | if (control_persist_exit_time > 0) { | 649 | if (control_persist_exit_time > 0) { |
648 | timeout_secs = MIN(timeout_secs, | 650 | timeout_secs = MIN(timeout_secs, |
649 | control_persist_exit_time - time(NULL)); | 651 | control_persist_exit_time - now); |
650 | if (timeout_secs < 0) | 652 | if (timeout_secs < 0) |
651 | timeout_secs = 0; | 653 | timeout_secs = 0; |
652 | } | 654 | } |
@@ -678,8 +680,15 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | |||
678 | snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); | 680 | snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); |
679 | buffer_append(&stderr_buffer, buf, strlen(buf)); | 681 | buffer_append(&stderr_buffer, buf, strlen(buf)); |
680 | quit_pending = 1; | 682 | quit_pending = 1; |
681 | } else if (ret == 0) | 683 | } else if (ret == 0) { |
682 | server_alive_check(); | 684 | /* |
685 | * Timeout. Could have been either keepalive or rekeying. | ||
686 | * Keepalive we check here, rekeying is checked in clientloop. | ||
687 | */ | ||
688 | if (server_alive_time != 0 && server_alive_time <= monotime()) | ||
689 | server_alive_check(); | ||
690 | } | ||
691 | |||
683 | } | 692 | } |
684 | 693 | ||
685 | static void | 694 | static void |
@@ -824,13 +833,13 @@ client_status_confirm(int type, Channel *c, void *ctx) | |||
824 | chan_write_failed(c); | 833 | chan_write_failed(c); |
825 | } | 834 | } |
826 | } | 835 | } |
827 | xfree(cr); | 836 | free(cr); |
828 | } | 837 | } |
829 | 838 | ||
830 | static void | 839 | static void |
831 | client_abandon_status_confirm(Channel *c, void *ctx) | 840 | client_abandon_status_confirm(Channel *c, void *ctx) |
832 | { | 841 | { |
833 | xfree(ctx); | 842 | free(ctx); |
834 | } | 843 | } |
835 | 844 | ||
836 | void | 845 | void |
@@ -997,12 +1006,9 @@ process_cmdline(void) | |||
997 | out: | 1006 | out: |
998 | signal(SIGINT, handler); | 1007 | signal(SIGINT, handler); |
999 | enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 1008 | enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |
1000 | if (cmd) | 1009 | free(cmd); |
1001 | xfree(cmd); | 1010 | free(fwd.listen_host); |
1002 | if (fwd.listen_host != NULL) | 1011 | free(fwd.connect_host); |
1003 | xfree(fwd.listen_host); | ||
1004 | if (fwd.connect_host != NULL) | ||
1005 | xfree(fwd.connect_host); | ||
1006 | } | 1012 | } |
1007 | 1013 | ||
1008 | /* reasons to suppress output of an escape command in help output */ | 1014 | /* reasons to suppress output of an escape command in help output */ |
@@ -1112,8 +1118,11 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, | |||
1112 | if (c && c->ctl_chan != -1) { | 1118 | if (c && c->ctl_chan != -1) { |
1113 | chan_read_failed(c); | 1119 | chan_read_failed(c); |
1114 | chan_write_failed(c); | 1120 | chan_write_failed(c); |
1115 | mux_master_session_cleanup_cb(c->self, | 1121 | if (c->detach_user) |
1116 | NULL); | 1122 | c->detach_user(c->self, NULL); |
1123 | c->type = SSH_CHANNEL_ABANDONED; | ||
1124 | buffer_clear(&c->input); | ||
1125 | chan_ibuf_empty(c); | ||
1117 | return 0; | 1126 | return 0; |
1118 | } else | 1127 | } else |
1119 | quit_pending = 1; | 1128 | quit_pending = 1; |
@@ -1259,7 +1268,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, | |||
1259 | buffer_append(berr, string, strlen(string)); | 1268 | buffer_append(berr, string, strlen(string)); |
1260 | s = channel_open_message(); | 1269 | s = channel_open_message(); |
1261 | buffer_append(berr, s, strlen(s)); | 1270 | buffer_append(berr, s, strlen(s)); |
1262 | xfree(s); | 1271 | free(s); |
1263 | continue; | 1272 | continue; |
1264 | 1273 | ||
1265 | case 'C': | 1274 | case 'C': |
@@ -1448,7 +1457,7 @@ client_new_escape_filter_ctx(int escape_char) | |||
1448 | void | 1457 | void |
1449 | client_filter_cleanup(int cid, void *ctx) | 1458 | client_filter_cleanup(int cid, void *ctx) |
1450 | { | 1459 | { |
1451 | xfree(ctx); | 1460 | free(ctx); |
1452 | } | 1461 | } |
1453 | 1462 | ||
1454 | int | 1463 | int |
@@ -1662,16 +1671,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1662 | * connections, then quit. | 1671 | * connections, then quit. |
1663 | */ | 1672 | */ |
1664 | if (control_persist_exit_time > 0) { | 1673 | if (control_persist_exit_time > 0) { |
1665 | if (time(NULL) >= control_persist_exit_time) { | 1674 | if (monotime() >= control_persist_exit_time) { |
1666 | debug("ControlPersist timeout expired"); | 1675 | debug("ControlPersist timeout expired"); |
1667 | break; | 1676 | break; |
1668 | } | 1677 | } |
1669 | } | 1678 | } |
1670 | } | 1679 | } |
1671 | if (readset) | 1680 | free(readset); |
1672 | xfree(readset); | 1681 | free(writeset); |
1673 | if (writeset) | ||
1674 | xfree(writeset); | ||
1675 | 1682 | ||
1676 | /* Terminate the session. */ | 1683 | /* Terminate the session. */ |
1677 | 1684 | ||
@@ -1775,7 +1782,7 @@ client_input_stdout_data(int type, u_int32_t seq, void *ctxt) | |||
1775 | packet_check_eom(); | 1782 | packet_check_eom(); |
1776 | buffer_append(&stdout_buffer, data, data_len); | 1783 | buffer_append(&stdout_buffer, data, data_len); |
1777 | memset(data, 0, data_len); | 1784 | memset(data, 0, data_len); |
1778 | xfree(data); | 1785 | free(data); |
1779 | } | 1786 | } |
1780 | static void | 1787 | static void |
1781 | client_input_stderr_data(int type, u_int32_t seq, void *ctxt) | 1788 | client_input_stderr_data(int type, u_int32_t seq, void *ctxt) |
@@ -1785,7 +1792,7 @@ client_input_stderr_data(int type, u_int32_t seq, void *ctxt) | |||
1785 | packet_check_eom(); | 1792 | packet_check_eom(); |
1786 | buffer_append(&stderr_buffer, data, data_len); | 1793 | buffer_append(&stderr_buffer, data, data_len); |
1787 | memset(data, 0, data_len); | 1794 | memset(data, 0, data_len); |
1788 | xfree(data); | 1795 | free(data); |
1789 | } | 1796 | } |
1790 | static void | 1797 | static void |
1791 | client_input_exit_status(int type, u_int32_t seq, void *ctxt) | 1798 | client_input_exit_status(int type, u_int32_t seq, void *ctxt) |
@@ -1865,8 +1872,8 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) | |||
1865 | c = channel_connect_by_listen_address(listen_port, | 1872 | c = channel_connect_by_listen_address(listen_port, |
1866 | "forwarded-tcpip", originator_address); | 1873 | "forwarded-tcpip", originator_address); |
1867 | 1874 | ||
1868 | xfree(originator_address); | 1875 | free(originator_address); |
1869 | xfree(listen_address); | 1876 | free(listen_address); |
1870 | return c; | 1877 | return c; |
1871 | } | 1878 | } |
1872 | 1879 | ||
@@ -1884,7 +1891,7 @@ client_request_x11(const char *request_type, int rchan) | |||
1884 | "malicious server."); | 1891 | "malicious server."); |
1885 | return NULL; | 1892 | return NULL; |
1886 | } | 1893 | } |
1887 | if (x11_refuse_time != 0 && time(NULL) >= x11_refuse_time) { | 1894 | if (x11_refuse_time != 0 && monotime() >= x11_refuse_time) { |
1888 | verbose("Rejected X11 connection after ForwardX11Timeout " | 1895 | verbose("Rejected X11 connection after ForwardX11Timeout " |
1889 | "expired"); | 1896 | "expired"); |
1890 | return NULL; | 1897 | return NULL; |
@@ -1900,7 +1907,7 @@ client_request_x11(const char *request_type, int rchan) | |||
1900 | /* XXX check permission */ | 1907 | /* XXX check permission */ |
1901 | debug("client_request_x11: request from %s %d", originator, | 1908 | debug("client_request_x11: request from %s %d", originator, |
1902 | originator_port); | 1909 | originator_port); |
1903 | xfree(originator); | 1910 | free(originator); |
1904 | sock = x11_connect_display(); | 1911 | sock = x11_connect_display(); |
1905 | if (sock < 0) | 1912 | if (sock < 0) |
1906 | return NULL; | 1913 | return NULL; |
@@ -2027,7 +2034,7 @@ client_input_channel_open(int type, u_int32_t seq, void *ctxt) | |||
2027 | } | 2034 | } |
2028 | packet_send(); | 2035 | packet_send(); |
2029 | } | 2036 | } |
2030 | xfree(ctype); | 2037 | free(ctype); |
2031 | } | 2038 | } |
2032 | static void | 2039 | static void |
2033 | client_input_channel_req(int type, u_int32_t seq, void *ctxt) | 2040 | client_input_channel_req(int type, u_int32_t seq, void *ctxt) |
@@ -2073,7 +2080,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) | |||
2073 | packet_put_int(c->remote_id); | 2080 | packet_put_int(c->remote_id); |
2074 | packet_send(); | 2081 | packet_send(); |
2075 | } | 2082 | } |
2076 | xfree(rtype); | 2083 | free(rtype); |
2077 | } | 2084 | } |
2078 | static void | 2085 | static void |
2079 | client_input_global_request(int type, u_int32_t seq, void *ctxt) | 2086 | client_input_global_request(int type, u_int32_t seq, void *ctxt) |
@@ -2092,7 +2099,7 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt) | |||
2092 | packet_send(); | 2099 | packet_send(); |
2093 | packet_write_wait(); | 2100 | packet_write_wait(); |
2094 | } | 2101 | } |
2095 | xfree(rtype); | 2102 | free(rtype); |
2096 | } | 2103 | } |
2097 | 2104 | ||
2098 | void | 2105 | void |
@@ -2142,7 +2149,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem, | |||
2142 | /* Split */ | 2149 | /* Split */ |
2143 | name = xstrdup(env[i]); | 2150 | name = xstrdup(env[i]); |
2144 | if ((val = strchr(name, '=')) == NULL) { | 2151 | if ((val = strchr(name, '=')) == NULL) { |
2145 | xfree(name); | 2152 | free(name); |
2146 | continue; | 2153 | continue; |
2147 | } | 2154 | } |
2148 | *val++ = '\0'; | 2155 | *val++ = '\0'; |
@@ -2156,7 +2163,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem, | |||
2156 | } | 2163 | } |
2157 | if (!matched) { | 2164 | if (!matched) { |
2158 | debug3("Ignored env %s", name); | 2165 | debug3("Ignored env %s", name); |
2159 | xfree(name); | 2166 | free(name); |
2160 | continue; | 2167 | continue; |
2161 | } | 2168 | } |
2162 | 2169 | ||
@@ -2165,7 +2172,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem, | |||
2165 | packet_put_cstring(name); | 2172 | packet_put_cstring(name); |
2166 | packet_put_cstring(val); | 2173 | packet_put_cstring(val); |
2167 | packet_send(); | 2174 | packet_send(); |
2168 | xfree(name); | 2175 | free(name); |
2169 | } | 2176 | } |
2170 | } | 2177 | } |
2171 | 2178 | ||