diff options
author | Colin Watson <cjwatson@debian.org> | 2016-08-06 10:49:58 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2016-08-06 10:49:58 +0100 |
commit | a8ed8d256b2e2c05b0c15565a7938028c5192277 (patch) | |
tree | 87abbdc914a38b43e4e5bb9581ad1f46eabbf88e /ssh.c | |
parent | f0329aac23c61e1a5197d6d57349a63f459bccb0 (diff) | |
parent | 99522ba7ec6963a05c04a156bf20e3ba3605987c (diff) |
Import openssh_7.3p1.orig.tar.gz
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 140 |
1 files changed, 105 insertions, 35 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.436 2016/02/15 09:47:49 dtucker Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.445 2016/07/17 04:20:16 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 |
@@ -67,6 +67,7 @@ | |||
67 | #include <string.h> | 67 | #include <string.h> |
68 | #include <unistd.h> | 68 | #include <unistd.h> |
69 | #include <limits.h> | 69 | #include <limits.h> |
70 | #include <locale.h> | ||
70 | 71 | ||
71 | #include <netinet/in.h> | 72 | #include <netinet/in.h> |
72 | #include <arpa/inet.h> | 73 | #include <arpa/inet.h> |
@@ -151,10 +152,6 @@ int ostdin_null_flag, ono_shell_flag, otty_flag, orequest_tty; | |||
151 | */ | 152 | */ |
152 | int fork_after_authentication_flag = 0; | 153 | int fork_after_authentication_flag = 0; |
153 | 154 | ||
154 | /* forward stdio to remote host and port */ | ||
155 | char *stdio_forward_host = NULL; | ||
156 | int stdio_forward_port = 0; | ||
157 | |||
158 | /* | 155 | /* |
159 | * General data structure for command line options and options configurable | 156 | * General data structure for command line options and options configurable |
160 | * in configuration files. See readconf.h. | 157 | * in configuration files. See readconf.h. |
@@ -202,10 +199,11 @@ usage(void) | |||
202 | fprintf(stderr, | 199 | fprintf(stderr, |
203 | "usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" | 200 | "usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" |
204 | " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" | 201 | " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" |
205 | " [-F configfile] [-I pkcs11] [-i identity_file] [-L address]\n" | 202 | " [-F configfile] [-I pkcs11] [-i identity_file]\n" |
206 | " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" | 203 | " [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\n" |
207 | " [-Q query_option] [-R address] [-S ctl_path] [-W host:port]\n" | 204 | " [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]\n" |
208 | " [-w local_tun[:remote_tun]] [user@]hostname [command]\n" | 205 | " [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]\n" |
206 | " [user@]hostname [command]\n" | ||
209 | ); | 207 | ); |
210 | exit(255); | 208 | exit(255); |
211 | } | 209 | } |
@@ -334,7 +332,7 @@ resolve_addr(const char *name, int port, char *caddr, size_t clen) | |||
334 | * NB. this function must operate with a options having undefined members. | 332 | * NB. this function must operate with a options having undefined members. |
335 | */ | 333 | */ |
336 | static int | 334 | static int |
337 | check_follow_cname(char **namep, const char *cname) | 335 | check_follow_cname(int direct, char **namep, const char *cname) |
338 | { | 336 | { |
339 | int i; | 337 | int i; |
340 | struct allowed_cname *rule; | 338 | struct allowed_cname *rule; |
@@ -346,9 +344,9 @@ check_follow_cname(char **namep, const char *cname) | |||
346 | return 0; | 344 | return 0; |
347 | /* | 345 | /* |
348 | * Don't attempt to canonicalize names that will be interpreted by | 346 | * Don't attempt to canonicalize names that will be interpreted by |
349 | * a proxy unless the user specifically requests so. | 347 | * a proxy or jump host unless the user specifically requests so. |
350 | */ | 348 | */ |
351 | if (!option_clear_or_none(options.proxy_command) && | 349 | if (!direct && |
352 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) | 350 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) |
353 | return 0; | 351 | return 0; |
354 | debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname); | 352 | debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname); |
@@ -375,7 +373,7 @@ check_follow_cname(char **namep, const char *cname) | |||
375 | static struct addrinfo * | 373 | static struct addrinfo * |
376 | resolve_canonicalize(char **hostp, int port) | 374 | resolve_canonicalize(char **hostp, int port) |
377 | { | 375 | { |
378 | int i, ndots; | 376 | int i, direct, ndots; |
379 | char *cp, *fullhost, newname[NI_MAXHOST]; | 377 | char *cp, *fullhost, newname[NI_MAXHOST]; |
380 | struct addrinfo *addrs; | 378 | struct addrinfo *addrs; |
381 | 379 | ||
@@ -386,7 +384,9 @@ resolve_canonicalize(char **hostp, int port) | |||
386 | * Don't attempt to canonicalize names that will be interpreted by | 384 | * Don't attempt to canonicalize names that will be interpreted by |
387 | * a proxy unless the user specifically requests so. | 385 | * a proxy unless the user specifically requests so. |
388 | */ | 386 | */ |
389 | if (!option_clear_or_none(options.proxy_command) && | 387 | direct = option_clear_or_none(options.proxy_command) && |
388 | options.jump_host == NULL; | ||
389 | if (!direct && | ||
390 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) | 390 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) |
391 | return NULL; | 391 | return NULL; |
392 | 392 | ||
@@ -441,7 +441,7 @@ resolve_canonicalize(char **hostp, int port) | |||
441 | /* Remove trailing '.' */ | 441 | /* Remove trailing '.' */ |
442 | fullhost[strlen(fullhost) - 1] = '\0'; | 442 | fullhost[strlen(fullhost) - 1] = '\0'; |
443 | /* Follow CNAME if requested */ | 443 | /* Follow CNAME if requested */ |
444 | if (!check_follow_cname(&fullhost, newname)) { | 444 | if (!check_follow_cname(direct, &fullhost, newname)) { |
445 | debug("Canonicalized hostname \"%s\" => \"%s\"", | 445 | debug("Canonicalized hostname \"%s\" => \"%s\"", |
446 | *hostp, fullhost); | 446 | *hostp, fullhost); |
447 | } | 447 | } |
@@ -513,7 +513,8 @@ set_addrinfo_port(struct addrinfo *addrs, int port) | |||
513 | int | 513 | int |
514 | main(int ac, char **av) | 514 | main(int ac, char **av) |
515 | { | 515 | { |
516 | int i, r, opt, exit_status, use_syslog, config_test = 0; | 516 | struct ssh *ssh = NULL; |
517 | int i, r, opt, exit_status, use_syslog, direct, config_test = 0; | ||
517 | char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile; | 518 | char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile; |
518 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; | 519 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; |
519 | char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex; | 520 | char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex; |
@@ -592,6 +593,8 @@ main(int ac, char **av) | |||
592 | */ | 593 | */ |
593 | umask(022); | 594 | umask(022); |
594 | 595 | ||
596 | setlocale(LC_CTYPE, ""); | ||
597 | |||
595 | /* | 598 | /* |
596 | * Initialize option structure to indicate that no values have been | 599 | * Initialize option structure to indicate that no values have been |
597 | * set. | 600 | * set. |
@@ -606,7 +609,7 @@ main(int ac, char **av) | |||
606 | 609 | ||
607 | again: | 610 | again: |
608 | while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" | 611 | while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" |
609 | "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { | 612 | "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { |
610 | switch (opt) { | 613 | switch (opt) { |
611 | case '1': | 614 | case '1': |
612 | options.protocol = SSH_PROTO_1; | 615 | options.protocol = SSH_PROTO_1; |
@@ -650,7 +653,7 @@ main(int ac, char **av) | |||
650 | options.fwd_opts.gateway_ports = 1; | 653 | options.fwd_opts.gateway_ports = 1; |
651 | break; | 654 | break; |
652 | case 'O': | 655 | case 'O': |
653 | if (stdio_forward_host != NULL) | 656 | if (options.stdio_forward_host != NULL) |
654 | fatal("Cannot specify multiplexing " | 657 | fatal("Cannot specify multiplexing " |
655 | "command with -W"); | 658 | "command with -W"); |
656 | else if (muxclient_command != 0) | 659 | else if (muxclient_command != 0) |
@@ -731,6 +734,15 @@ main(int ac, char **av) | |||
731 | fprintf(stderr, "no support for PKCS#11.\n"); | 734 | fprintf(stderr, "no support for PKCS#11.\n"); |
732 | #endif | 735 | #endif |
733 | break; | 736 | break; |
737 | case 'J': | ||
738 | if (options.jump_host != NULL) | ||
739 | fatal("Only a single -J option permitted"); | ||
740 | if (options.proxy_command != NULL) | ||
741 | fatal("Cannot specify -J with ProxyCommand"); | ||
742 | if (parse_jump(optarg, &options, 1) == -1) | ||
743 | fatal("Invalid -J argument"); | ||
744 | options.proxy_command = xstrdup("none"); | ||
745 | break; | ||
734 | case 't': | 746 | case 't': |
735 | if (options.request_tty == REQUEST_TTY_YES) | 747 | if (options.request_tty == REQUEST_TTY_YES) |
736 | options.request_tty = REQUEST_TTY_FORCE; | 748 | options.request_tty = REQUEST_TTY_FORCE; |
@@ -742,8 +754,10 @@ main(int ac, char **av) | |||
742 | debug_flag = 1; | 754 | debug_flag = 1; |
743 | options.log_level = SYSLOG_LEVEL_DEBUG1; | 755 | options.log_level = SYSLOG_LEVEL_DEBUG1; |
744 | } else { | 756 | } else { |
745 | if (options.log_level < SYSLOG_LEVEL_DEBUG3) | 757 | if (options.log_level < SYSLOG_LEVEL_DEBUG3) { |
758 | debug_flag++; | ||
746 | options.log_level++; | 759 | options.log_level++; |
760 | } | ||
747 | } | 761 | } |
748 | break; | 762 | break; |
749 | case 'V': | 763 | case 'V': |
@@ -769,13 +783,13 @@ main(int ac, char **av) | |||
769 | } | 783 | } |
770 | break; | 784 | break; |
771 | case 'W': | 785 | case 'W': |
772 | if (stdio_forward_host != NULL) | 786 | if (options.stdio_forward_host != NULL) |
773 | fatal("stdio forward already specified"); | 787 | fatal("stdio forward already specified"); |
774 | if (muxclient_command != 0) | 788 | if (muxclient_command != 0) |
775 | fatal("Cannot specify stdio forward with -O"); | 789 | fatal("Cannot specify stdio forward with -O"); |
776 | if (parse_forward(&fwd, optarg, 1, 0)) { | 790 | if (parse_forward(&fwd, optarg, 1, 0)) { |
777 | stdio_forward_host = fwd.listen_host; | 791 | options.stdio_forward_host = fwd.listen_host; |
778 | stdio_forward_port = fwd.listen_port; | 792 | options.stdio_forward_port = fwd.listen_port; |
779 | free(fwd.connect_host); | 793 | free(fwd.connect_host); |
780 | } else { | 794 | } else { |
781 | fprintf(stderr, | 795 | fprintf(stderr, |
@@ -785,8 +799,6 @@ main(int ac, char **av) | |||
785 | } | 799 | } |
786 | options.request_tty = REQUEST_TTY_NO; | 800 | options.request_tty = REQUEST_TTY_NO; |
787 | no_shell_flag = 1; | 801 | no_shell_flag = 1; |
788 | options.clear_forwardings = 1; | ||
789 | options.exit_on_forward_failure = 1; | ||
790 | break; | 802 | break; |
791 | case 'q': | 803 | case 'q': |
792 | options.log_level = SYSLOG_LEVEL_QUIET; | 804 | options.log_level = SYSLOG_LEVEL_QUIET; |
@@ -1043,9 +1055,10 @@ main(int ac, char **av) | |||
1043 | * has specifically requested canonicalisation for this case via | 1055 | * has specifically requested canonicalisation for this case via |
1044 | * CanonicalizeHostname=always | 1056 | * CanonicalizeHostname=always |
1045 | */ | 1057 | */ |
1046 | if (addrs == NULL && options.num_permitted_cnames != 0 && | 1058 | direct = option_clear_or_none(options.proxy_command) && |
1047 | (option_clear_or_none(options.proxy_command) || | 1059 | options.jump_host == NULL; |
1048 | options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) { | 1060 | if (addrs == NULL && options.num_permitted_cnames != 0 && (direct || |
1061 | options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) { | ||
1049 | if ((addrs = resolve_host(host, options.port, | 1062 | if ((addrs = resolve_host(host, options.port, |
1050 | option_clear_or_none(options.proxy_command), | 1063 | option_clear_or_none(options.proxy_command), |
1051 | cname, sizeof(cname))) == NULL) { | 1064 | cname, sizeof(cname))) == NULL) { |
@@ -1053,7 +1066,7 @@ main(int ac, char **av) | |||
1053 | if (option_clear_or_none(options.proxy_command)) | 1066 | if (option_clear_or_none(options.proxy_command)) |
1054 | cleanup_exit(255); /* logged in resolve_host */ | 1067 | cleanup_exit(255); /* logged in resolve_host */ |
1055 | } else | 1068 | } else |
1056 | check_follow_cname(&host, cname); | 1069 | check_follow_cname(direct, &host, cname); |
1057 | } | 1070 | } |
1058 | 1071 | ||
1059 | /* | 1072 | /* |
@@ -1078,6 +1091,41 @@ main(int ac, char **av) | |||
1078 | /* Fill configuration defaults. */ | 1091 | /* Fill configuration defaults. */ |
1079 | fill_default_options(&options); | 1092 | fill_default_options(&options); |
1080 | 1093 | ||
1094 | /* | ||
1095 | * If ProxyJump option specified, then construct a ProxyCommand now. | ||
1096 | */ | ||
1097 | if (options.jump_host != NULL) { | ||
1098 | char port_s[8]; | ||
1099 | |||
1100 | /* Consistency check */ | ||
1101 | if (options.proxy_command != NULL) | ||
1102 | fatal("inconsistent options: ProxyCommand+ProxyJump"); | ||
1103 | /* Never use FD passing for ProxyJump */ | ||
1104 | options.proxy_use_fdpass = 0; | ||
1105 | snprintf(port_s, sizeof(port_s), "%d", options.jump_port); | ||
1106 | xasprintf(&options.proxy_command, | ||
1107 | "ssh%s%s%s%s%s%s%s%s%s%.*s -W %%h:%%p %s", | ||
1108 | /* Optional "-l user" argument if jump_user set */ | ||
1109 | options.jump_user == NULL ? "" : " -l ", | ||
1110 | options.jump_user == NULL ? "" : options.jump_user, | ||
1111 | /* Optional "-p port" argument if jump_port set */ | ||
1112 | options.jump_port <= 0 ? "" : " -p ", | ||
1113 | options.jump_port <= 0 ? "" : port_s, | ||
1114 | /* Optional additional jump hosts ",..." */ | ||
1115 | options.jump_extra == NULL ? "" : " -J ", | ||
1116 | options.jump_extra == NULL ? "" : options.jump_extra, | ||
1117 | /* Optional "-F" argumment if -F specified */ | ||
1118 | config == NULL ? "" : " -F ", | ||
1119 | config == NULL ? "" : config, | ||
1120 | /* Optional "-v" arguments if -v set */ | ||
1121 | debug_flag ? " -" : "", | ||
1122 | debug_flag, "vvv", | ||
1123 | /* Mandatory hostname */ | ||
1124 | options.jump_host); | ||
1125 | debug("Setting implicit ProxyCommand from ProxyJump: %s", | ||
1126 | options.proxy_command); | ||
1127 | } | ||
1128 | |||
1081 | if (options.port == 0) | 1129 | if (options.port == 0) |
1082 | options.port = default_ssh_port(); | 1130 | options.port = default_ssh_port(); |
1083 | channel_set_af(options.address_family); | 1131 | channel_set_af(options.address_family); |
@@ -1220,6 +1268,8 @@ main(int ac, char **av) | |||
1220 | packet_set_timeout(options.server_alive_interval, | 1268 | packet_set_timeout(options.server_alive_interval, |
1221 | options.server_alive_count_max); | 1269 | options.server_alive_count_max); |
1222 | 1270 | ||
1271 | ssh = active_state; /* XXX */ | ||
1272 | |||
1223 | if (timeout_ms > 0) | 1273 | if (timeout_ms > 0) |
1224 | debug3("timeout: %d ms remain after connect", timeout_ms); | 1274 | debug3("timeout: %d ms remain after connect", timeout_ms); |
1225 | 1275 | ||
@@ -1332,6 +1382,23 @@ main(int ac, char **av) | |||
1332 | /* load options.identity_files */ | 1382 | /* load options.identity_files */ |
1333 | load_public_identity_files(); | 1383 | load_public_identity_files(); |
1334 | 1384 | ||
1385 | /* optionally set the SSH_AUTHSOCKET_ENV_NAME varibale */ | ||
1386 | if (options.identity_agent && | ||
1387 | strcmp(options.identity_agent, SSH_AUTHSOCKET_ENV_NAME) != 0) { | ||
1388 | if (strcmp(options.identity_agent, "none") == 0) { | ||
1389 | unsetenv(SSH_AUTHSOCKET_ENV_NAME); | ||
1390 | } else { | ||
1391 | p = tilde_expand_filename(options.identity_agent, | ||
1392 | original_real_uid); | ||
1393 | cp = percent_expand(p, "d", pw->pw_dir, | ||
1394 | "u", pw->pw_name, "l", thishost, "h", host, | ||
1395 | "r", options.user, (char *)NULL); | ||
1396 | setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1); | ||
1397 | free(cp); | ||
1398 | free(p); | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1335 | /* Expand ~ in known host file names. */ | 1402 | /* Expand ~ in known host file names. */ |
1336 | tilde_expand_paths(options.system_hostfiles, | 1403 | tilde_expand_paths(options.system_hostfiles, |
1337 | options.num_system_hostfiles); | 1404 | options.num_system_hostfiles); |
@@ -1346,7 +1413,7 @@ main(int ac, char **av) | |||
1346 | 1413 | ||
1347 | if (packet_connection_is_on_socket()) { | 1414 | if (packet_connection_is_on_socket()) { |
1348 | verbose("Authenticated to %s ([%s]:%d).", host, | 1415 | verbose("Authenticated to %s ([%s]:%d).", host, |
1349 | get_remote_ipaddr(), get_remote_port()); | 1416 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); |
1350 | } else { | 1417 | } else { |
1351 | verbose("Authenticated to %s (via proxy).", host); | 1418 | verbose("Authenticated to %s (via proxy).", host); |
1352 | } | 1419 | } |
@@ -1392,7 +1459,7 @@ static void | |||
1392 | control_persist_detach(void) | 1459 | control_persist_detach(void) |
1393 | { | 1460 | { |
1394 | pid_t pid; | 1461 | pid_t pid; |
1395 | int devnull; | 1462 | int devnull, keep_stderr; |
1396 | 1463 | ||
1397 | debug("%s: backgrounding master process", __func__); | 1464 | debug("%s: backgrounding master process", __func__); |
1398 | 1465 | ||
@@ -1423,8 +1490,10 @@ control_persist_detach(void) | |||
1423 | error("%s: open(\"/dev/null\"): %s", __func__, | 1490 | error("%s: open(\"/dev/null\"): %s", __func__, |
1424 | strerror(errno)); | 1491 | strerror(errno)); |
1425 | } else { | 1492 | } else { |
1493 | keep_stderr = log_is_on_stderr() && debug_flag; | ||
1426 | if (dup2(devnull, STDIN_FILENO) == -1 || | 1494 | if (dup2(devnull, STDIN_FILENO) == -1 || |
1427 | dup2(devnull, STDOUT_FILENO) == -1) | 1495 | dup2(devnull, STDOUT_FILENO) == -1 || |
1496 | (!keep_stderr && dup2(devnull, STDERR_FILENO) == -1)) | ||
1428 | error("%s: dup2: %s", __func__, strerror(errno)); | 1497 | error("%s: dup2: %s", __func__, strerror(errno)); |
1429 | if (devnull > STDERR_FILENO) | 1498 | if (devnull > STDERR_FILENO) |
1430 | close(devnull); | 1499 | close(devnull); |
@@ -1516,18 +1585,19 @@ ssh_init_stdio_forwarding(void) | |||
1516 | Channel *c; | 1585 | Channel *c; |
1517 | int in, out; | 1586 | int in, out; |
1518 | 1587 | ||
1519 | if (stdio_forward_host == NULL) | 1588 | if (options.stdio_forward_host == NULL) |
1520 | return; | 1589 | return; |
1521 | if (!compat20) | 1590 | if (!compat20) |
1522 | fatal("stdio forwarding require Protocol 2"); | 1591 | fatal("stdio forwarding require Protocol 2"); |
1523 | 1592 | ||
1524 | debug3("%s: %s:%d", __func__, stdio_forward_host, stdio_forward_port); | 1593 | debug3("%s: %s:%d", __func__, options.stdio_forward_host, |
1594 | options.stdio_forward_port); | ||
1525 | 1595 | ||
1526 | if ((in = dup(STDIN_FILENO)) < 0 || | 1596 | if ((in = dup(STDIN_FILENO)) < 0 || |
1527 | (out = dup(STDOUT_FILENO)) < 0) | 1597 | (out = dup(STDOUT_FILENO)) < 0) |
1528 | fatal("channel_connect_stdio_fwd: dup() in/out failed"); | 1598 | fatal("channel_connect_stdio_fwd: dup() in/out failed"); |
1529 | if ((c = channel_connect_stdio_fwd(stdio_forward_host, | 1599 | if ((c = channel_connect_stdio_fwd(options.stdio_forward_host, |
1530 | stdio_forward_port, in, out)) == NULL) | 1600 | options.stdio_forward_port, in, out)) == NULL) |
1531 | fatal("%s: channel_connect_stdio_fwd failed", __func__); | 1601 | fatal("%s: channel_connect_stdio_fwd failed", __func__); |
1532 | channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); | 1602 | channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); |
1533 | channel_register_open_confirm(c->self, ssh_stdio_confirm, NULL); | 1603 | channel_register_open_confirm(c->self, ssh_stdio_confirm, NULL); |