diff options
author | djm@openbsd.org <djm@openbsd.org> | 2017-09-12 06:32:07 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-09-12 17:37:02 +1000 |
commit | dbee4119b502e3f8b6cd3282c69c537fd01d8e16 (patch) | |
tree | b8a3263a79e0920e8d08f188654f1ccb7c254406 /clientloop.c | |
parent | abd59663df37a42152e37980113ccaa405b9a282 (diff) |
upstream commit
refactor channels.c
Move static state to a "struct ssh_channels" that is allocated at
runtime and tracked as a member of struct ssh.
Explicitly pass "struct ssh" to all channels functions.
Replace use of the legacy packet APIs in channels.c.
Rework sshd_config PermitOpen handling: previously the configuration
parser would call directly into the channels layer. After the refactor
this is not possible, as the channels structures are allocated at
connection time and aren't available when the configuration is parsed.
The server config parser now tracks PermitOpen itself and explicitly
configures the channels code later.
ok markus@
Upstream-ID: 11828f161656b965cc306576422613614bea2d8f
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 | } |