diff options
Diffstat (limited to 'clientloop.c')
-rw-r--r-- | clientloop.c | 191 |
1 files changed, 100 insertions, 91 deletions
diff --git a/clientloop.c b/clientloop.c index 2934c4763..1218b3b71 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.302 2017/08/30 03:59:08 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.c,v 1.303 2017/09/12 06:32:07 djm 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 |
@@ -177,6 +177,7 @@ struct channel_reply_ctx { | |||
177 | }; | 177 | }; |
178 | 178 | ||
179 | /* Global request success/failure callbacks */ | 179 | /* Global request success/failure callbacks */ |
180 | /* XXX move to struct ssh? */ | ||
180 | struct global_confirm { | 181 | struct global_confirm { |
181 | TAILQ_ENTRY(global_confirm) entry; | 182 | TAILQ_ENTRY(global_confirm) entry; |
182 | global_confirm_cb *cb; | 183 | global_confirm_cb *cb; |
@@ -244,13 +245,13 @@ get_current_time(void) | |||
244 | * control master process, or if there is no ControlPersist timeout. | 245 | * control master process, or if there is no ControlPersist timeout. |
245 | */ | 246 | */ |
246 | static void | 247 | static void |
247 | set_control_persist_exit_time(void) | 248 | set_control_persist_exit_time(struct ssh *ssh) |
248 | { | 249 | { |
249 | if (muxserver_sock == -1 || !options.control_persist | 250 | if (muxserver_sock == -1 || !options.control_persist |
250 | || options.control_persist_timeout == 0) { | 251 | || options.control_persist_timeout == 0) { |
251 | /* not using a ControlPersist timeout */ | 252 | /* not using a ControlPersist timeout */ |
252 | control_persist_exit_time = 0; | 253 | control_persist_exit_time = 0; |
253 | } else if (channel_still_open()) { | 254 | } else if (channel_still_open(ssh)) { |
254 | /* some client connections are still open */ | 255 | /* some client connections are still open */ |
255 | if (control_persist_exit_time > 0) | 256 | if (control_persist_exit_time > 0) |
256 | debug2("%s: cancel scheduled exit", __func__); | 257 | debug2("%s: cancel scheduled exit", __func__); |
@@ -288,8 +289,9 @@ client_x11_display_valid(const char *display) | |||
288 | #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" | 289 | #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" |
289 | #define X11_TIMEOUT_SLACK 60 | 290 | #define X11_TIMEOUT_SLACK 60 |
290 | int | 291 | int |
291 | client_x11_get_proto(const char *display, const char *xauth_path, | 292 | client_x11_get_proto(struct ssh *ssh, const char *display, |
292 | u_int trusted, u_int timeout, char **_proto, char **_data) | 293 | const char *xauth_path, u_int trusted, u_int timeout, |
294 | char **_proto, char **_data) | ||
293 | { | 295 | { |
294 | char cmd[1024], line[512], xdisplay[512]; | 296 | char cmd[1024], line[512], xdisplay[512]; |
295 | char xauthfile[PATH_MAX], xauthdir[PATH_MAX]; | 297 | char xauthfile[PATH_MAX], xauthdir[PATH_MAX]; |
@@ -373,7 +375,8 @@ client_x11_get_proto(const char *display, const char *xauth_path, | |||
373 | x11_refuse_time = UINT_MAX; | 375 | x11_refuse_time = UINT_MAX; |
374 | else | 376 | else |
375 | x11_refuse_time = now + timeout; | 377 | x11_refuse_time = now + timeout; |
376 | channel_set_x11_refuse_time(x11_refuse_time); | 378 | channel_set_x11_refuse_time(ssh, |
379 | x11_refuse_time); | ||
377 | } | 380 | } |
378 | if (system(cmd) == 0) | 381 | if (system(cmd) == 0) |
379 | generated = 1; | 382 | generated = 1; |
@@ -446,7 +449,7 @@ client_x11_get_proto(const char *display, const char *xauth_path, | |||
446 | */ | 449 | */ |
447 | 450 | ||
448 | static void | 451 | static void |
449 | client_check_window_change(void) | 452 | client_check_window_change(struct ssh *ssh) |
450 | { | 453 | { |
451 | if (!received_window_change_signal) | 454 | if (!received_window_change_signal) |
452 | return; | 455 | return; |
@@ -455,7 +458,7 @@ client_check_window_change(void) | |||
455 | 458 | ||
456 | debug2("%s: changed", __func__); | 459 | debug2("%s: changed", __func__); |
457 | 460 | ||
458 | channel_send_window_changes(); | 461 | channel_send_window_changes(ssh); |
459 | } | 462 | } |
460 | 463 | ||
461 | static int | 464 | static int |
@@ -466,7 +469,7 @@ client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
466 | if ((gc = TAILQ_FIRST(&global_confirms)) == NULL) | 469 | if ((gc = TAILQ_FIRST(&global_confirms)) == NULL) |
467 | return 0; | 470 | return 0; |
468 | if (gc->cb != NULL) | 471 | if (gc->cb != NULL) |
469 | gc->cb(type, seq, gc->ctx); | 472 | gc->cb(ssh, type, seq, gc->ctx); |
470 | if (--gc->ref_count <= 0) { | 473 | if (--gc->ref_count <= 0) { |
471 | TAILQ_REMOVE(&global_confirms, gc, entry); | 474 | TAILQ_REMOVE(&global_confirms, gc, entry); |
472 | explicit_bzero(gc, sizeof(*gc)); | 475 | explicit_bzero(gc, sizeof(*gc)); |
@@ -497,7 +500,8 @@ server_alive_check(void) | |||
497 | * one of the file descriptors). | 500 | * one of the file descriptors). |
498 | */ | 501 | */ |
499 | static void | 502 | static void |
500 | client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | 503 | client_wait_until_can_do_something(struct ssh *ssh, |
504 | fd_set **readsetp, fd_set **writesetp, | ||
501 | int *maxfdp, u_int *nallocp, int rekeying) | 505 | int *maxfdp, u_int *nallocp, int rekeying) |
502 | { | 506 | { |
503 | struct timeval tv, *tvp; | 507 | struct timeval tv, *tvp; |
@@ -510,7 +514,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | |||
510 | nallocp, &minwait_secs); | 514 | nallocp, &minwait_secs); |
511 | 515 | ||
512 | /* channel_prepare_select could have closed the last channel */ | 516 | /* channel_prepare_select could have closed the last channel */ |
513 | if (session_closed && !channel_still_open() && | 517 | if (session_closed && !channel_still_open(ssh) && |
514 | !packet_have_data_to_write()) { | 518 | !packet_have_data_to_write()) { |
515 | /* clear mask since we did not call select() */ | 519 | /* clear mask since we did not call select() */ |
516 | memset(*readsetp, 0, *nallocp); | 520 | memset(*readsetp, 0, *nallocp); |
@@ -537,7 +541,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | |||
537 | } | 541 | } |
538 | if (options.rekey_interval > 0 && !rekeying) | 542 | if (options.rekey_interval > 0 && !rekeying) |
539 | timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout()); | 543 | timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout()); |
540 | set_control_persist_exit_time(); | 544 | set_control_persist_exit_time(ssh); |
541 | if (control_persist_exit_time > 0) { | 545 | if (control_persist_exit_time > 0) { |
542 | timeout_secs = MINIMUM(timeout_secs, | 546 | timeout_secs = MINIMUM(timeout_secs, |
543 | control_persist_exit_time - now); | 547 | control_persist_exit_time - now); |
@@ -668,7 +672,7 @@ client_process_net_input(fd_set *readset) | |||
668 | } | 672 | } |
669 | 673 | ||
670 | static void | 674 | static void |
671 | client_status_confirm(int type, Channel *c, void *ctx) | 675 | client_status_confirm(struct ssh *ssh, int type, Channel *c, void *ctx) |
672 | { | 676 | { |
673 | struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx; | 677 | struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx; |
674 | char errmsg[256]; | 678 | char errmsg[256]; |
@@ -707,8 +711,7 @@ client_status_confirm(int type, Channel *c, void *ctx) | |||
707 | * their stderr. | 711 | * their stderr. |
708 | */ | 712 | */ |
709 | if (tochan) { | 713 | if (tochan) { |
710 | buffer_append(&c->extended, errmsg, | 714 | buffer_append(c->extended, errmsg, strlen(errmsg)); |
711 | strlen(errmsg)); | ||
712 | } else | 715 | } else |
713 | error("%s", errmsg); | 716 | error("%s", errmsg); |
714 | if (cr->action == CONFIRM_TTY) { | 717 | if (cr->action == CONFIRM_TTY) { |
@@ -719,23 +722,23 @@ client_status_confirm(int type, Channel *c, void *ctx) | |||
719 | if (c->self == session_ident) | 722 | if (c->self == session_ident) |
720 | leave_raw_mode(0); | 723 | leave_raw_mode(0); |
721 | else | 724 | else |
722 | mux_tty_alloc_failed(c); | 725 | mux_tty_alloc_failed(ssh, c); |
723 | } else if (cr->action == CONFIRM_CLOSE) { | 726 | } else if (cr->action == CONFIRM_CLOSE) { |
724 | chan_read_failed(c); | 727 | chan_read_failed(ssh, c); |
725 | chan_write_failed(c); | 728 | chan_write_failed(ssh, c); |
726 | } | 729 | } |
727 | } | 730 | } |
728 | free(cr); | 731 | free(cr); |
729 | } | 732 | } |
730 | 733 | ||
731 | static void | 734 | static void |
732 | client_abandon_status_confirm(Channel *c, void *ctx) | 735 | client_abandon_status_confirm(struct ssh *ssh, Channel *c, void *ctx) |
733 | { | 736 | { |
734 | free(ctx); | 737 | free(ctx); |
735 | } | 738 | } |
736 | 739 | ||
737 | void | 740 | void |
738 | client_expect_confirm(int id, const char *request, | 741 | client_expect_confirm(struct ssh *ssh, int id, const char *request, |
739 | enum confirm_action action) | 742 | enum confirm_action action) |
740 | { | 743 | { |
741 | struct channel_reply_ctx *cr = xcalloc(1, sizeof(*cr)); | 744 | struct channel_reply_ctx *cr = xcalloc(1, sizeof(*cr)); |
@@ -743,7 +746,7 @@ client_expect_confirm(int id, const char *request, | |||
743 | cr->request_type = request; | 746 | cr->request_type = request; |
744 | cr->action = action; | 747 | cr->action = action; |
745 | 748 | ||
746 | channel_register_status_confirm(id, client_status_confirm, | 749 | channel_register_status_confirm(ssh, id, client_status_confirm, |
747 | client_abandon_status_confirm, cr); | 750 | client_abandon_status_confirm, cr); |
748 | } | 751 | } |
749 | 752 | ||
@@ -769,7 +772,7 @@ client_register_global_confirm(global_confirm_cb *cb, void *ctx) | |||
769 | } | 772 | } |
770 | 773 | ||
771 | static void | 774 | static void |
772 | process_cmdline(void) | 775 | process_cmdline(struct ssh *ssh) |
773 | { | 776 | { |
774 | void (*handler)(int); | 777 | void (*handler)(int); |
775 | char *s, *cmd; | 778 | char *s, *cmd; |
@@ -843,12 +846,12 @@ process_cmdline(void) | |||
843 | goto out; | 846 | goto out; |
844 | } | 847 | } |
845 | if (remote) | 848 | if (remote) |
846 | ok = channel_request_rforward_cancel(&fwd) == 0; | 849 | ok = channel_request_rforward_cancel(ssh, &fwd) == 0; |
847 | else if (dynamic) | 850 | else if (dynamic) |
848 | ok = channel_cancel_lport_listener(&fwd, | 851 | ok = channel_cancel_lport_listener(ssh, &fwd, |
849 | 0, &options.fwd_opts) > 0; | 852 | 0, &options.fwd_opts) > 0; |
850 | else | 853 | else |
851 | ok = channel_cancel_lport_listener(&fwd, | 854 | ok = channel_cancel_lport_listener(ssh, &fwd, |
852 | CHANNEL_CANCEL_PORT_STATIC, | 855 | CHANNEL_CANCEL_PORT_STATIC, |
853 | &options.fwd_opts) > 0; | 856 | &options.fwd_opts) > 0; |
854 | if (!ok) { | 857 | if (!ok) { |
@@ -862,13 +865,13 @@ process_cmdline(void) | |||
862 | goto out; | 865 | goto out; |
863 | } | 866 | } |
864 | if (local || dynamic) { | 867 | if (local || dynamic) { |
865 | if (!channel_setup_local_fwd_listener(&fwd, | 868 | if (!channel_setup_local_fwd_listener(ssh, &fwd, |
866 | &options.fwd_opts)) { | 869 | &options.fwd_opts)) { |
867 | logit("Port forwarding failed."); | 870 | logit("Port forwarding failed."); |
868 | goto out; | 871 | goto out; |
869 | } | 872 | } |
870 | } else { | 873 | } else { |
871 | if (channel_request_remote_forwarding(&fwd) < 0) { | 874 | if (channel_request_remote_forwarding(ssh, &fwd) < 0) { |
872 | logit("Port forwarding failed."); | 875 | logit("Port forwarding failed."); |
873 | goto out; | 876 | goto out; |
874 | } | 877 | } |
@@ -945,7 +948,8 @@ print_escape_help(Buffer *b, int escape_char, int mux_client, int using_stderr) | |||
945 | * Process the characters one by one. | 948 | * Process the characters one by one. |
946 | */ | 949 | */ |
947 | static int | 950 | static int |
948 | process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, | 951 | process_escapes(struct ssh *ssh, Channel *c, |
952 | Buffer *bin, Buffer *bout, Buffer *berr, | ||
949 | char *buf, int len) | 953 | char *buf, int len) |
950 | { | 954 | { |
951 | char string[1024]; | 955 | char string[1024]; |
@@ -981,13 +985,15 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, | |||
981 | buffer_append(berr, string, strlen(string)); | 985 | buffer_append(berr, string, strlen(string)); |
982 | 986 | ||
983 | if (c && c->ctl_chan != -1) { | 987 | if (c && c->ctl_chan != -1) { |
984 | chan_read_failed(c); | 988 | chan_read_failed(ssh, c); |
985 | chan_write_failed(c); | 989 | chan_write_failed(ssh, c); |
986 | if (c->detach_user) | 990 | if (c->detach_user) { |
987 | c->detach_user(c->self, NULL); | 991 | c->detach_user(ssh, |
992 | c->self, NULL); | ||
993 | } | ||
988 | c->type = SSH_CHANNEL_ABANDONED; | 994 | c->type = SSH_CHANNEL_ABANDONED; |
989 | buffer_clear(&c->input); | 995 | buffer_clear(c->input); |
990 | chan_ibuf_empty(c); | 996 | chan_ibuf_empty(ssh, c); |
991 | return 0; | 997 | return 0; |
992 | } else | 998 | } else |
993 | quit_pending = 1; | 999 | quit_pending = 1; |
@@ -1025,7 +1031,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, | |||
1025 | snprintf(string, sizeof string, | 1031 | snprintf(string, sizeof string, |
1026 | "%cB\r\n", efc->escape_char); | 1032 | "%cB\r\n", efc->escape_char); |
1027 | buffer_append(berr, string, strlen(string)); | 1033 | buffer_append(berr, string, strlen(string)); |
1028 | channel_request_start(c->self, "break", 0); | 1034 | channel_request_start(ssh, c->self, "break", 0); |
1029 | packet_put_int(1000); | 1035 | packet_put_int(1000); |
1030 | packet_send(); | 1036 | packet_send(); |
1031 | continue; | 1037 | continue; |
@@ -1077,7 +1083,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, | |||
1077 | options.request_tty == REQUEST_TTY_FORCE); | 1083 | options.request_tty == REQUEST_TTY_FORCE); |
1078 | 1084 | ||
1079 | /* Stop listening for new connections. */ | 1085 | /* Stop listening for new connections. */ |
1080 | channel_stop_listening(); | 1086 | channel_stop_listening(ssh); |
1081 | 1087 | ||
1082 | snprintf(string, sizeof string, | 1088 | snprintf(string, sizeof string, |
1083 | "%c& [backgrounded]\n", efc->escape_char); | 1089 | "%c& [backgrounded]\n", efc->escape_char); |
@@ -1107,7 +1113,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, | |||
1107 | snprintf(string, sizeof string, "%c#\r\n", | 1113 | snprintf(string, sizeof string, "%c#\r\n", |
1108 | efc->escape_char); | 1114 | efc->escape_char); |
1109 | buffer_append(berr, string, strlen(string)); | 1115 | buffer_append(berr, string, strlen(string)); |
1110 | s = channel_open_message(); | 1116 | s = channel_open_message(ssh); |
1111 | buffer_append(berr, s, strlen(s)); | 1117 | buffer_append(berr, s, strlen(s)); |
1112 | free(s); | 1118 | free(s); |
1113 | continue; | 1119 | continue; |
@@ -1115,7 +1121,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, | |||
1115 | case 'C': | 1121 | case 'C': |
1116 | if (c && c->ctl_chan != -1) | 1122 | if (c && c->ctl_chan != -1) |
1117 | goto noescape; | 1123 | goto noescape; |
1118 | process_cmdline(); | 1124 | process_cmdline(ssh); |
1119 | continue; | 1125 | continue; |
1120 | 1126 | ||
1121 | default: | 1127 | default: |
@@ -1186,25 +1192,25 @@ client_new_escape_filter_ctx(int escape_char) | |||
1186 | 1192 | ||
1187 | /* Free the escape filter context on channel free */ | 1193 | /* Free the escape filter context on channel free */ |
1188 | void | 1194 | void |
1189 | client_filter_cleanup(int cid, void *ctx) | 1195 | client_filter_cleanup(struct ssh *ssh, int cid, void *ctx) |
1190 | { | 1196 | { |
1191 | free(ctx); | 1197 | free(ctx); |
1192 | } | 1198 | } |
1193 | 1199 | ||
1194 | int | 1200 | int |
1195 | client_simple_escape_filter(Channel *c, char *buf, int len) | 1201 | client_simple_escape_filter(struct ssh *ssh, Channel *c, char *buf, int len) |
1196 | { | 1202 | { |
1197 | if (c->extended_usage != CHAN_EXTENDED_WRITE) | 1203 | if (c->extended_usage != CHAN_EXTENDED_WRITE) |
1198 | return 0; | 1204 | return 0; |
1199 | 1205 | ||
1200 | return process_escapes(c, &c->input, &c->output, &c->extended, | 1206 | return process_escapes(ssh, c, c->input, c->output, c->extended, |
1201 | buf, len); | 1207 | buf, len); |
1202 | } | 1208 | } |
1203 | 1209 | ||
1204 | static void | 1210 | static void |
1205 | client_channel_closed(int id, void *arg) | 1211 | client_channel_closed(struct ssh *ssh, int id, void *arg) |
1206 | { | 1212 | { |
1207 | channel_cancel_cleanup(id); | 1213 | channel_cancel_cleanup(ssh, id); |
1208 | session_closed = 1; | 1214 | session_closed = 1; |
1209 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 1215 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |
1210 | } | 1216 | } |
@@ -1215,9 +1221,9 @@ client_channel_closed(int id, void *arg) | |||
1215 | * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character | 1221 | * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character |
1216 | * used as an escape character for terminating or suspending the session. | 1222 | * used as an escape character for terminating or suspending the session. |
1217 | */ | 1223 | */ |
1218 | |||
1219 | int | 1224 | int |
1220 | client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | 1225 | client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, |
1226 | int ssh2_chan_id) | ||
1221 | { | 1227 | { |
1222 | fd_set *readset = NULL, *writeset = NULL; | 1228 | fd_set *readset = NULL, *writeset = NULL; |
1223 | double start_time, total_time; | 1229 | double start_time, total_time; |
@@ -1295,13 +1301,13 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1295 | session_ident = ssh2_chan_id; | 1301 | session_ident = ssh2_chan_id; |
1296 | if (session_ident != -1) { | 1302 | if (session_ident != -1) { |
1297 | if (escape_char_arg != SSH_ESCAPECHAR_NONE) { | 1303 | if (escape_char_arg != SSH_ESCAPECHAR_NONE) { |
1298 | channel_register_filter(session_ident, | 1304 | channel_register_filter(ssh, session_ident, |
1299 | client_simple_escape_filter, NULL, | 1305 | client_simple_escape_filter, NULL, |
1300 | client_filter_cleanup, | 1306 | client_filter_cleanup, |
1301 | client_new_escape_filter_ctx( | 1307 | client_new_escape_filter_ctx( |
1302 | escape_char_arg)); | 1308 | escape_char_arg)); |
1303 | } | 1309 | } |
1304 | channel_register_cleanup(session_ident, | 1310 | channel_register_cleanup(ssh, session_ident, |
1305 | client_channel_closed, 0); | 1311 | client_channel_closed, 0); |
1306 | } | 1312 | } |
1307 | 1313 | ||
@@ -1311,15 +1317,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1311 | /* Process buffered packets sent by the server. */ | 1317 | /* Process buffered packets sent by the server. */ |
1312 | client_process_buffered_input_packets(); | 1318 | client_process_buffered_input_packets(); |
1313 | 1319 | ||
1314 | if (session_closed && !channel_still_open()) | 1320 | if (session_closed && !channel_still_open(ssh)) |
1315 | break; | 1321 | break; |
1316 | 1322 | ||
1317 | if (ssh_packet_is_rekeying(active_state)) { | 1323 | if (ssh_packet_is_rekeying(ssh)) { |
1318 | debug("rekeying in progress"); | 1324 | debug("rekeying in progress"); |
1319 | } else if (need_rekeying) { | 1325 | } else if (need_rekeying) { |
1320 | /* manual rekey request */ | 1326 | /* manual rekey request */ |
1321 | debug("need rekeying"); | 1327 | debug("need rekeying"); |
1322 | if ((r = kex_start_rekex(active_state)) != 0) | 1328 | if ((r = kex_start_rekex(ssh)) != 0) |
1323 | fatal("%s: kex_start_rekex: %s", __func__, | 1329 | fatal("%s: kex_start_rekex: %s", __func__, |
1324 | ssh_err(r)); | 1330 | ssh_err(r)); |
1325 | need_rekeying = 0; | 1331 | need_rekeying = 0; |
@@ -1329,13 +1335,13 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1329 | * enqueue them for sending to the server. | 1335 | * enqueue them for sending to the server. |
1330 | */ | 1336 | */ |
1331 | if (packet_not_very_much_data_to_write()) | 1337 | if (packet_not_very_much_data_to_write()) |
1332 | channel_output_poll(); | 1338 | channel_output_poll(ssh); |
1333 | 1339 | ||
1334 | /* | 1340 | /* |
1335 | * Check if the window size has changed, and buffer a | 1341 | * Check if the window size has changed, and buffer a |
1336 | * message about it to the server if so. | 1342 | * message about it to the server if so. |
1337 | */ | 1343 | */ |
1338 | client_check_window_change(); | 1344 | client_check_window_change(ssh); |
1339 | 1345 | ||
1340 | if (quit_pending) | 1346 | if (quit_pending) |
1341 | break; | 1347 | break; |
@@ -1345,15 +1351,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1345 | * available on one of the descriptors). | 1351 | * available on one of the descriptors). |
1346 | */ | 1352 | */ |
1347 | max_fd2 = max_fd; | 1353 | max_fd2 = max_fd; |
1348 | client_wait_until_can_do_something(&readset, &writeset, | 1354 | client_wait_until_can_do_something(ssh, &readset, &writeset, |
1349 | &max_fd2, &nalloc, ssh_packet_is_rekeying(active_state)); | 1355 | &max_fd2, &nalloc, ssh_packet_is_rekeying(ssh)); |
1350 | 1356 | ||
1351 | if (quit_pending) | 1357 | if (quit_pending) |
1352 | break; | 1358 | break; |
1353 | 1359 | ||
1354 | /* Do channel operations unless rekeying in progress. */ | 1360 | /* Do channel operations unless rekeying in progress. */ |
1355 | if (!ssh_packet_is_rekeying(active_state)) | 1361 | if (!ssh_packet_is_rekeying(ssh)) |
1356 | channel_after_select(active_state, readset, writeset); | 1362 | channel_after_select(ssh, readset, writeset); |
1357 | 1363 | ||
1358 | /* Buffer input from the connection. */ | 1364 | /* Buffer input from the connection. */ |
1359 | client_process_net_input(readset); | 1365 | client_process_net_input(readset); |
@@ -1395,7 +1401,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1395 | packet_send(); | 1401 | packet_send(); |
1396 | packet_write_wait(); | 1402 | packet_write_wait(); |
1397 | 1403 | ||
1398 | channel_free_all(); | 1404 | channel_free_all(ssh); |
1399 | 1405 | ||
1400 | if (have_pty) | 1406 | if (have_pty) |
1401 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 1407 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |
@@ -1463,8 +1469,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1463 | /*********/ | 1469 | /*********/ |
1464 | 1470 | ||
1465 | static Channel * | 1471 | static Channel * |
1466 | client_request_forwarded_tcpip(const char *request_type, int rchan, | 1472 | client_request_forwarded_tcpip(struct ssh *ssh, const char *request_type, |
1467 | u_int rwindow, u_int rmaxpack) | 1473 | int rchan, u_int rwindow, u_int rmaxpack) |
1468 | { | 1474 | { |
1469 | Channel *c = NULL; | 1475 | Channel *c = NULL; |
1470 | struct sshbuf *b = NULL; | 1476 | struct sshbuf *b = NULL; |
@@ -1482,7 +1488,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan, | |||
1482 | debug("%s: listen %s port %d, originator %s port %d", __func__, | 1488 | debug("%s: listen %s port %d, originator %s port %d", __func__, |
1483 | listen_address, listen_port, originator_address, originator_port); | 1489 | listen_address, listen_port, originator_address, originator_port); |
1484 | 1490 | ||
1485 | c = channel_connect_by_listen_address(listen_address, listen_port, | 1491 | c = channel_connect_by_listen_address(ssh, listen_address, listen_port, |
1486 | "forwarded-tcpip", originator_address); | 1492 | "forwarded-tcpip", originator_address); |
1487 | 1493 | ||
1488 | if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { | 1494 | if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { |
@@ -1501,7 +1507,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan, | |||
1501 | (r = sshbuf_put_u32(b, listen_port)) != 0 || | 1507 | (r = sshbuf_put_u32(b, listen_port)) != 0 || |
1502 | (r = sshbuf_put_cstring(b, originator_address)) != 0 || | 1508 | (r = sshbuf_put_cstring(b, originator_address)) != 0 || |
1503 | (r = sshbuf_put_u32(b, originator_port)) != 0 || | 1509 | (r = sshbuf_put_u32(b, originator_port)) != 0 || |
1504 | (r = sshbuf_put_stringb(&c->output, b)) != 0) { | 1510 | (r = sshbuf_put_stringb(c->output, b)) != 0) { |
1505 | error("%s: compose for muxclient %s", __func__, | 1511 | error("%s: compose for muxclient %s", __func__, |
1506 | ssh_err(r)); | 1512 | ssh_err(r)); |
1507 | goto out; | 1513 | goto out; |
@@ -1516,7 +1522,8 @@ client_request_forwarded_tcpip(const char *request_type, int rchan, | |||
1516 | } | 1522 | } |
1517 | 1523 | ||
1518 | static Channel * | 1524 | static Channel * |
1519 | client_request_forwarded_streamlocal(const char *request_type, int rchan) | 1525 | client_request_forwarded_streamlocal(struct ssh *ssh, |
1526 | const char *request_type, int rchan) | ||
1520 | { | 1527 | { |
1521 | Channel *c = NULL; | 1528 | Channel *c = NULL; |
1522 | char *listen_path; | 1529 | char *listen_path; |
@@ -1530,14 +1537,14 @@ client_request_forwarded_streamlocal(const char *request_type, int rchan) | |||
1530 | 1537 | ||
1531 | debug("%s: %s", __func__, listen_path); | 1538 | debug("%s: %s", __func__, listen_path); |
1532 | 1539 | ||
1533 | c = channel_connect_by_listen_path(listen_path, | 1540 | c = channel_connect_by_listen_path(ssh, listen_path, |
1534 | "forwarded-streamlocal@openssh.com", "forwarded-streamlocal"); | 1541 | "forwarded-streamlocal@openssh.com", "forwarded-streamlocal"); |
1535 | free(listen_path); | 1542 | free(listen_path); |
1536 | return c; | 1543 | return c; |
1537 | } | 1544 | } |
1538 | 1545 | ||
1539 | static Channel * | 1546 | static Channel * |
1540 | client_request_x11(const char *request_type, int rchan) | 1547 | client_request_x11(struct ssh *ssh, const char *request_type, int rchan) |
1541 | { | 1548 | { |
1542 | Channel *c = NULL; | 1549 | Channel *c = NULL; |
1543 | char *originator; | 1550 | char *originator; |
@@ -1567,10 +1574,10 @@ client_request_x11(const char *request_type, int rchan) | |||
1567 | debug("client_request_x11: request from %s %d", originator, | 1574 | debug("client_request_x11: request from %s %d", originator, |
1568 | originator_port); | 1575 | originator_port); |
1569 | free(originator); | 1576 | free(originator); |
1570 | sock = x11_connect_display(); | 1577 | sock = x11_connect_display(ssh); |
1571 | if (sock < 0) | 1578 | if (sock < 0) |
1572 | return NULL; | 1579 | return NULL; |
1573 | c = channel_new("x11", | 1580 | c = channel_new(ssh, "x11", |
1574 | SSH_CHANNEL_X11_OPEN, sock, sock, -1, | 1581 | SSH_CHANNEL_X11_OPEN, sock, sock, -1, |
1575 | CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); | 1582 | CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); |
1576 | c->force_drain = 1; | 1583 | c->force_drain = 1; |
@@ -1578,7 +1585,7 @@ client_request_x11(const char *request_type, int rchan) | |||
1578 | } | 1585 | } |
1579 | 1586 | ||
1580 | static Channel * | 1587 | static Channel * |
1581 | client_request_agent(const char *request_type, int rchan) | 1588 | client_request_agent(struct ssh *ssh, const char *request_type, int rchan) |
1582 | { | 1589 | { |
1583 | Channel *c = NULL; | 1590 | Channel *c = NULL; |
1584 | int r, sock; | 1591 | int r, sock; |
@@ -1595,7 +1602,7 @@ client_request_agent(const char *request_type, int rchan) | |||
1595 | __func__, ssh_err(r)); | 1602 | __func__, ssh_err(r)); |
1596 | return NULL; | 1603 | return NULL; |
1597 | } | 1604 | } |
1598 | c = channel_new("authentication agent connection", | 1605 | c = channel_new(ssh, "authentication agent connection", |
1599 | SSH_CHANNEL_OPEN, sock, sock, -1, | 1606 | SSH_CHANNEL_OPEN, sock, sock, -1, |
1600 | CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, | 1607 | CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, |
1601 | "authentication agent connection", 1); | 1608 | "authentication agent connection", 1); |
@@ -1604,7 +1611,8 @@ client_request_agent(const char *request_type, int rchan) | |||
1604 | } | 1611 | } |
1605 | 1612 | ||
1606 | int | 1613 | int |
1607 | client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun) | 1614 | client_request_tun_fwd(struct ssh *ssh, int tun_mode, |
1615 | int local_tun, int remote_tun) | ||
1608 | { | 1616 | { |
1609 | Channel *c; | 1617 | Channel *c; |
1610 | int fd; | 1618 | int fd; |
@@ -1620,7 +1628,7 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun) | |||
1620 | return -1; | 1628 | return -1; |
1621 | } | 1629 | } |
1622 | 1630 | ||
1623 | c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, | 1631 | c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1, |
1624 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); | 1632 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); |
1625 | c->datagram = 1; | 1633 | c->datagram = 1; |
1626 | 1634 | ||
@@ -1660,14 +1668,14 @@ client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) | |||
1660 | ctype, rchan, rwindow, rmaxpack); | 1668 | ctype, rchan, rwindow, rmaxpack); |
1661 | 1669 | ||
1662 | if (strcmp(ctype, "forwarded-tcpip") == 0) { | 1670 | if (strcmp(ctype, "forwarded-tcpip") == 0) { |
1663 | c = client_request_forwarded_tcpip(ctype, rchan, rwindow, | 1671 | c = client_request_forwarded_tcpip(ssh, ctype, rchan, rwindow, |
1664 | rmaxpack); | 1672 | rmaxpack); |
1665 | } else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) { | 1673 | } else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) { |
1666 | c = client_request_forwarded_streamlocal(ctype, rchan); | 1674 | c = client_request_forwarded_streamlocal(ssh, ctype, rchan); |
1667 | } else if (strcmp(ctype, "x11") == 0) { | 1675 | } else if (strcmp(ctype, "x11") == 0) { |
1668 | c = client_request_x11(ctype, rchan); | 1676 | c = client_request_x11(ssh, ctype, rchan); |
1669 | } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { | 1677 | } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { |
1670 | c = client_request_agent(ctype, rchan); | 1678 | c = client_request_agent(ssh, ctype, rchan); |
1671 | } | 1679 | } |
1672 | if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { | 1680 | if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { |
1673 | debug3("proxied to downstream: %s", ctype); | 1681 | debug3("proxied to downstream: %s", ctype); |
@@ -1707,7 +1715,7 @@ client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) | |||
1707 | char *rtype; | 1715 | char *rtype; |
1708 | 1716 | ||
1709 | id = packet_get_int(); | 1717 | id = packet_get_int(); |
1710 | c = channel_lookup(id); | 1718 | c = channel_lookup(ssh, id); |
1711 | if (channel_proxy_upstream(c, type, seq, ssh)) | 1719 | if (channel_proxy_upstream(c, type, seq, ssh)) |
1712 | return 0; | 1720 | return 0; |
1713 | rtype = packet_get_string(NULL); | 1721 | rtype = packet_get_string(NULL); |
@@ -1723,11 +1731,11 @@ client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) | |||
1723 | "unknown channel", id); | 1731 | "unknown channel", id); |
1724 | } else if (strcmp(rtype, "eow@openssh.com") == 0) { | 1732 | } else if (strcmp(rtype, "eow@openssh.com") == 0) { |
1725 | packet_check_eom(); | 1733 | packet_check_eom(); |
1726 | chan_rcvd_eow(c); | 1734 | chan_rcvd_eow(ssh, c); |
1727 | } else if (strcmp(rtype, "exit-status") == 0) { | 1735 | } else if (strcmp(rtype, "exit-status") == 0) { |
1728 | exitval = packet_get_int(); | 1736 | exitval = packet_get_int(); |
1729 | if (c->ctl_chan != -1) { | 1737 | if (c->ctl_chan != -1) { |
1730 | mux_exit_message(c, exitval); | 1738 | mux_exit_message(ssh, c, exitval); |
1731 | success = 1; | 1739 | success = 1; |
1732 | } else if (id == session_ident) { | 1740 | } else if (id == session_ident) { |
1733 | /* Record exit value of local session */ | 1741 | /* Record exit value of local session */ |
@@ -1895,9 +1903,9 @@ update_known_hosts(struct hostkeys_update_ctx *ctx) | |||
1895 | } | 1903 | } |
1896 | 1904 | ||
1897 | static void | 1905 | static void |
1898 | client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx) | 1906 | client_global_hostkeys_private_confirm(struct ssh *ssh, int type, |
1907 | u_int32_t seq, void *_ctx) | ||
1899 | { | 1908 | { |
1900 | struct ssh *ssh = active_state; /* XXX */ | ||
1901 | struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; | 1909 | struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; |
1902 | size_t i, ndone; | 1910 | size_t i, ndone; |
1903 | struct sshbuf *signdata; | 1911 | struct sshbuf *signdata; |
@@ -2161,7 +2169,7 @@ client_input_global_request(int type, u_int32_t seq, struct ssh *ssh) | |||
2161 | } | 2169 | } |
2162 | 2170 | ||
2163 | void | 2171 | void |
2164 | client_session2_setup(int id, int want_tty, int want_subsystem, | 2172 | client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, |
2165 | const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env) | 2173 | const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env) |
2166 | { | 2174 | { |
2167 | int len; | 2175 | int len; |
@@ -2169,8 +2177,8 @@ client_session2_setup(int id, int want_tty, int want_subsystem, | |||
2169 | 2177 | ||
2170 | debug2("%s: id %d", __func__, id); | 2178 | debug2("%s: id %d", __func__, id); |
2171 | 2179 | ||
2172 | if ((c = channel_lookup(id)) == NULL) | 2180 | if ((c = channel_lookup(ssh, id)) == NULL) |
2173 | fatal("client_session2_setup: channel %d: unknown channel", id); | 2181 | fatal("%s: channel %d: unknown channel", __func__, id); |
2174 | 2182 | ||
2175 | packet_set_interactive(want_tty, | 2183 | packet_set_interactive(want_tty, |
2176 | options.ip_qos_interactive, options.ip_qos_bulk); | 2184 | options.ip_qos_interactive, options.ip_qos_bulk); |
@@ -2182,8 +2190,8 @@ client_session2_setup(int id, int want_tty, int want_subsystem, | |||
2182 | if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) | 2190 | if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) |
2183 | memset(&ws, 0, sizeof(ws)); | 2191 | memset(&ws, 0, sizeof(ws)); |
2184 | 2192 | ||
2185 | channel_request_start(id, "pty-req", 1); | 2193 | channel_request_start(ssh, id, "pty-req", 1); |
2186 | client_expect_confirm(id, "PTY allocation", CONFIRM_TTY); | 2194 | client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY); |
2187 | packet_put_cstring(term != NULL ? term : ""); | 2195 | packet_put_cstring(term != NULL ? term : ""); |
2188 | packet_put_int((u_int)ws.ws_col); | 2196 | packet_put_int((u_int)ws.ws_col); |
2189 | packet_put_int((u_int)ws.ws_row); | 2197 | packet_put_int((u_int)ws.ws_row); |
@@ -2226,7 +2234,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem, | |||
2226 | } | 2234 | } |
2227 | 2235 | ||
2228 | debug("Sending env %s = %s", name, val); | 2236 | debug("Sending env %s = %s", name, val); |
2229 | channel_request_start(id, "env", 0); | 2237 | channel_request_start(ssh, id, "env", 0); |
2230 | packet_put_cstring(name); | 2238 | packet_put_cstring(name); |
2231 | packet_put_cstring(val); | 2239 | packet_put_cstring(val); |
2232 | packet_send(); | 2240 | packet_send(); |
@@ -2241,19 +2249,20 @@ client_session2_setup(int id, int want_tty, int want_subsystem, | |||
2241 | if (want_subsystem) { | 2249 | if (want_subsystem) { |
2242 | debug("Sending subsystem: %.*s", | 2250 | debug("Sending subsystem: %.*s", |
2243 | len, (u_char*)buffer_ptr(cmd)); | 2251 | len, (u_char*)buffer_ptr(cmd)); |
2244 | channel_request_start(id, "subsystem", 1); | 2252 | channel_request_start(ssh, id, "subsystem", 1); |
2245 | client_expect_confirm(id, "subsystem", CONFIRM_CLOSE); | 2253 | client_expect_confirm(ssh, id, "subsystem", |
2254 | CONFIRM_CLOSE); | ||
2246 | } else { | 2255 | } else { |
2247 | debug("Sending command: %.*s", | 2256 | debug("Sending command: %.*s", |
2248 | len, (u_char*)buffer_ptr(cmd)); | 2257 | len, (u_char*)buffer_ptr(cmd)); |
2249 | channel_request_start(id, "exec", 1); | 2258 | channel_request_start(ssh, id, "exec", 1); |
2250 | client_expect_confirm(id, "exec", CONFIRM_CLOSE); | 2259 | client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE); |
2251 | } | 2260 | } |
2252 | packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); | 2261 | packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); |
2253 | packet_send(); | 2262 | packet_send(); |
2254 | } else { | 2263 | } else { |
2255 | channel_request_start(id, "shell", 1); | 2264 | channel_request_start(ssh, id, "shell", 1); |
2256 | client_expect_confirm(id, "shell", CONFIRM_CLOSE); | 2265 | client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE); |
2257 | packet_send(); | 2266 | packet_send(); |
2258 | } | 2267 | } |
2259 | } | 2268 | } |