diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 362 |
1 files changed, 104 insertions, 258 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.451 2017/03/10 04:07:20 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.464 2017/09/21 19:16:53 markus 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 |
@@ -81,7 +81,6 @@ | |||
81 | 81 | ||
82 | #include "xmalloc.h" | 82 | #include "xmalloc.h" |
83 | #include "ssh.h" | 83 | #include "ssh.h" |
84 | #include "ssh1.h" | ||
85 | #include "ssh2.h" | 84 | #include "ssh2.h" |
86 | #include "canohost.h" | 85 | #include "canohost.h" |
87 | #include "compat.h" | 86 | #include "compat.h" |
@@ -198,7 +197,7 @@ static void | |||
198 | usage(void) | 197 | usage(void) |
199 | { | 198 | { |
200 | fprintf(stderr, | 199 | fprintf(stderr, |
201 | "usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" | 200 | "usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" |
202 | " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" | 201 | " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" |
203 | " [-F configfile] [-I pkcs11] [-i identity_file]\n" | 202 | " [-F configfile] [-I pkcs11] [-i identity_file]\n" |
204 | " [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\n" | 203 | " [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\n" |
@@ -209,8 +208,7 @@ usage(void) | |||
209 | exit(255); | 208 | exit(255); |
210 | } | 209 | } |
211 | 210 | ||
212 | static int ssh_session(void); | 211 | static int ssh_session2(struct ssh *); |
213 | static int ssh_session2(void); | ||
214 | static void load_public_identity_files(void); | 212 | static void load_public_identity_files(void); |
215 | static void main_sigchld_handler(int); | 213 | static void main_sigchld_handler(int); |
216 | 214 | ||
@@ -511,13 +509,13 @@ int | |||
511 | main(int ac, char **av) | 509 | main(int ac, char **av) |
512 | { | 510 | { |
513 | struct ssh *ssh = NULL; | 511 | struct ssh *ssh = NULL; |
514 | int i, r, opt, exit_status, use_syslog, direct, config_test = 0; | 512 | int i, r, opt, exit_status, use_syslog, direct, timeout_ms; |
513 | int config_test = 0, opt_terminated = 0; | ||
515 | char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile; | 514 | char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile; |
516 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; | 515 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; |
517 | char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex; | 516 | char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex; |
518 | struct stat st; | 517 | struct stat st; |
519 | struct passwd *pw; | 518 | struct passwd *pw; |
520 | int timeout_ms; | ||
521 | extern int optind, optreset; | 519 | extern int optind, optreset; |
522 | extern char *optarg; | 520 | extern char *optarg; |
523 | struct Forward fwd; | 521 | struct Forward fwd; |
@@ -598,6 +596,14 @@ main(int ac, char **av) | |||
598 | */ | 596 | */ |
599 | initialize_options(&options); | 597 | initialize_options(&options); |
600 | 598 | ||
599 | /* | ||
600 | * Prepare main ssh transport/connection structures | ||
601 | */ | ||
602 | if ((ssh = ssh_alloc_session_state()) == NULL) | ||
603 | fatal("Couldn't allocate session state"); | ||
604 | channel_init_channels(ssh); | ||
605 | active_state = ssh; /* XXX legacy API compat */ | ||
606 | |||
601 | /* Parse command-line arguments. */ | 607 | /* Parse command-line arguments. */ |
602 | host = NULL; | 608 | host = NULL; |
603 | use_syslog = 0; | 609 | use_syslog = 0; |
@@ -609,10 +615,10 @@ main(int ac, char **av) | |||
609 | "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { | 615 | "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { |
610 | switch (opt) { | 616 | switch (opt) { |
611 | case '1': | 617 | case '1': |
612 | options.protocol = SSH_PROTO_1; | 618 | fatal("SSH protocol v.1 is no longer supported"); |
613 | break; | 619 | break; |
614 | case '2': | 620 | case '2': |
615 | options.protocol = SSH_PROTO_2; | 621 | /* Ignored */ |
616 | break; | 622 | break; |
617 | case '4': | 623 | case '4': |
618 | options.address_family = AF_INET; | 624 | options.address_family = AF_INET; |
@@ -690,11 +696,7 @@ main(int ac, char **av) | |||
690 | else if (strcmp(optarg, "key-plain") == 0) | 696 | else if (strcmp(optarg, "key-plain") == 0) |
691 | cp = sshkey_alg_list(0, 1, 0, '\n'); | 697 | cp = sshkey_alg_list(0, 1, 0, '\n'); |
692 | else if (strcmp(optarg, "protocol-version") == 0) { | 698 | else if (strcmp(optarg, "protocol-version") == 0) { |
693 | #ifdef WITH_SSH1 | ||
694 | cp = xstrdup("1\n2"); | ||
695 | #else | ||
696 | cp = xstrdup("2"); | 699 | cp = xstrdup("2"); |
697 | #endif | ||
698 | } | 700 | } |
699 | if (cp == NULL) | 701 | if (cp == NULL) |
700 | fatal("Unsupported query \"%s\"", optarg); | 702 | fatal("Unsupported query \"%s\"", optarg); |
@@ -818,27 +820,14 @@ main(int ac, char **av) | |||
818 | } | 820 | } |
819 | break; | 821 | break; |
820 | case 'c': | 822 | case 'c': |
821 | if (ciphers_valid(*optarg == '+' ? | 823 | if (!ciphers_valid(*optarg == '+' ? |
822 | optarg + 1 : optarg)) { | 824 | optarg + 1 : optarg)) { |
823 | /* SSH2 only */ | ||
824 | free(options.ciphers); | ||
825 | options.ciphers = xstrdup(optarg); | ||
826 | options.cipher = SSH_CIPHER_INVALID; | ||
827 | break; | ||
828 | } | ||
829 | /* SSH1 only */ | ||
830 | options.cipher = cipher_number(optarg); | ||
831 | if (options.cipher == -1) { | ||
832 | fprintf(stderr, "Unknown cipher type '%s'\n", | 825 | fprintf(stderr, "Unknown cipher type '%s'\n", |
833 | optarg); | 826 | optarg); |
834 | exit(255); | 827 | exit(255); |
835 | } | 828 | } |
836 | if (options.cipher == SSH_CIPHER_3DES) | 829 | free(options.ciphers); |
837 | options.ciphers = xstrdup("3des-cbc"); | 830 | options.ciphers = xstrdup(optarg); |
838 | else if (options.cipher == SSH_CIPHER_BLOWFISH) | ||
839 | options.ciphers = xstrdup("blowfish-cbc"); | ||
840 | else | ||
841 | options.ciphers = xstrdup(KEX_CLIENT_ENCRYPT); | ||
842 | break; | 831 | break; |
843 | case 'm': | 832 | case 'm': |
844 | if (mac_valid(optarg)) { | 833 | if (mac_valid(optarg)) { |
@@ -879,7 +868,8 @@ main(int ac, char **av) | |||
879 | break; | 868 | break; |
880 | 869 | ||
881 | case 'R': | 870 | case 'R': |
882 | if (parse_forward(&fwd, optarg, 0, 1)) { | 871 | if (parse_forward(&fwd, optarg, 0, 1) || |
872 | parse_forward(&fwd, optarg, 1, 1)) { | ||
883 | add_remote_forward(&options, &fwd); | 873 | add_remote_forward(&options, &fwd); |
884 | } else { | 874 | } else { |
885 | fprintf(stderr, | 875 | fprintf(stderr, |
@@ -936,6 +926,9 @@ main(int ac, char **av) | |||
936 | } | 926 | } |
937 | } | 927 | } |
938 | 928 | ||
929 | if (optind > 1 && strcmp(av[optind - 1], "--") == 0) | ||
930 | opt_terminated = 1; | ||
931 | |||
939 | ac -= optind; | 932 | ac -= optind; |
940 | av += optind; | 933 | av += optind; |
941 | 934 | ||
@@ -950,7 +943,7 @@ main(int ac, char **av) | |||
950 | host = xstrdup(++cp); | 943 | host = xstrdup(++cp); |
951 | } else | 944 | } else |
952 | host = xstrdup(*av); | 945 | host = xstrdup(*av); |
953 | if (ac > 1) { | 946 | if (ac > 1 && !opt_terminated) { |
954 | optind = optreset = 1; | 947 | optind = optreset = 1; |
955 | goto again; | 948 | goto again; |
956 | } | 949 | } |
@@ -992,12 +985,6 @@ main(int ac, char **av) | |||
992 | } | 985 | } |
993 | } | 986 | } |
994 | 987 | ||
995 | /* Cannot fork to background if no command. */ | ||
996 | if (fork_after_authentication_flag && buffer_len(&command) == 0 && | ||
997 | !no_shell_flag) | ||
998 | fatal("Cannot fork into background without a command " | ||
999 | "to execute."); | ||
1000 | |||
1001 | /* | 988 | /* |
1002 | * Initialize "log" output. Since we are the client all output | 989 | * Initialize "log" output. Since we are the client all output |
1003 | * goes to stderr unless otherwise specified by -y or -E. | 990 | * goes to stderr unless otherwise specified by -y or -E. |
@@ -1007,8 +994,11 @@ main(int ac, char **av) | |||
1007 | if (logfile != NULL) | 994 | if (logfile != NULL) |
1008 | log_redirect_stderr_to(logfile); | 995 | log_redirect_stderr_to(logfile); |
1009 | log_init(argv0, | 996 | log_init(argv0, |
1010 | options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, | 997 | options.log_level == SYSLOG_LEVEL_NOT_SET ? |
1011 | SYSLOG_FACILITY_USER, !use_syslog); | 998 | SYSLOG_LEVEL_INFO : options.log_level, |
999 | options.log_facility == SYSLOG_FACILITY_NOT_SET ? | ||
1000 | SYSLOG_FACILITY_USER : options.log_facility, | ||
1001 | !use_syslog); | ||
1012 | 1002 | ||
1013 | if (debug_flag) | 1003 | if (debug_flag) |
1014 | logit("%s, %s", SSH_RELEASE, | 1004 | logit("%s, %s", SSH_RELEASE, |
@@ -1127,7 +1117,7 @@ main(int ac, char **av) | |||
1127 | 1117 | ||
1128 | if (options.port == 0) | 1118 | if (options.port == 0) |
1129 | options.port = default_ssh_port(); | 1119 | options.port = default_ssh_port(); |
1130 | channel_set_af(options.address_family); | 1120 | channel_set_af(ssh, options.address_family); |
1131 | 1121 | ||
1132 | /* Tidy and check options */ | 1122 | /* Tidy and check options */ |
1133 | if (options.host_key_alias != NULL) | 1123 | if (options.host_key_alias != NULL) |
@@ -1149,15 +1139,24 @@ main(int ac, char **av) | |||
1149 | options.use_privileged_port = 0; | 1139 | options.use_privileged_port = 0; |
1150 | #endif | 1140 | #endif |
1151 | 1141 | ||
1142 | if (buffer_len(&command) != 0 && options.remote_command != NULL) | ||
1143 | fatal("Cannot execute command-line and remote command."); | ||
1144 | |||
1145 | /* Cannot fork to background if no command. */ | ||
1146 | if (fork_after_authentication_flag && buffer_len(&command) == 0 && | ||
1147 | options.remote_command == NULL && !no_shell_flag) | ||
1148 | fatal("Cannot fork into background without a command " | ||
1149 | "to execute."); | ||
1150 | |||
1152 | /* reinit */ | 1151 | /* reinit */ |
1153 | log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog); | 1152 | log_init(argv0, options.log_level, options.log_facility, !use_syslog); |
1154 | 1153 | ||
1155 | if (options.request_tty == REQUEST_TTY_YES || | 1154 | if (options.request_tty == REQUEST_TTY_YES || |
1156 | options.request_tty == REQUEST_TTY_FORCE) | 1155 | options.request_tty == REQUEST_TTY_FORCE) |
1157 | tty_flag = 1; | 1156 | tty_flag = 1; |
1158 | 1157 | ||
1159 | /* Allocate a tty by default if no command specified. */ | 1158 | /* Allocate a tty by default if no command specified. */ |
1160 | if (buffer_len(&command) == 0) | 1159 | if (buffer_len(&command) == 0 && options.remote_command == NULL) |
1161 | tty_flag = options.request_tty != REQUEST_TTY_NO; | 1160 | tty_flag = options.request_tty != REQUEST_TTY_NO; |
1162 | 1161 | ||
1163 | /* Force no tty */ | 1162 | /* Force no tty */ |
@@ -1213,6 +1212,27 @@ main(int ac, char **av) | |||
1213 | free(cp); | 1212 | free(cp); |
1214 | } | 1213 | } |
1215 | 1214 | ||
1215 | if (options.remote_command != NULL) { | ||
1216 | debug3("expanding RemoteCommand: %s", options.remote_command); | ||
1217 | cp = options.remote_command; | ||
1218 | options.remote_command = percent_expand(cp, | ||
1219 | "C", conn_hash_hex, | ||
1220 | "L", shorthost, | ||
1221 | "d", pw->pw_dir, | ||
1222 | "h", host, | ||
1223 | "l", thishost, | ||
1224 | "n", host_arg, | ||
1225 | "p", portstr, | ||
1226 | "r", options.user, | ||
1227 | "u", pw->pw_name, | ||
1228 | (char *)NULL); | ||
1229 | debug3("expanded RemoteCommand: %s", options.remote_command); | ||
1230 | free(cp); | ||
1231 | buffer_append(&command, options.remote_command, | ||
1232 | strlen(options.remote_command)); | ||
1233 | |||
1234 | } | ||
1235 | |||
1216 | if (options.control_path != NULL) { | 1236 | if (options.control_path != NULL) { |
1217 | cp = tilde_expand_filename(options.control_path, | 1237 | cp = tilde_expand_filename(options.control_path, |
1218 | original_real_uid); | 1238 | original_real_uid); |
@@ -1242,9 +1262,7 @@ main(int ac, char **av) | |||
1242 | if (options.control_path != NULL) { | 1262 | if (options.control_path != NULL) { |
1243 | int sock; | 1263 | int sock; |
1244 | if ((sock = muxclient(options.control_path)) >= 0) { | 1264 | if ((sock = muxclient(options.control_path)) >= 0) { |
1245 | packet_set_connection(sock, sock); | 1265 | ssh_packet_set_connection(ssh, sock, sock); |
1246 | ssh = active_state; /* XXX */ | ||
1247 | enable_compat20(); /* XXX */ | ||
1248 | packet_set_mux(); | 1266 | packet_set_mux(); |
1249 | goto skip_connect; | 1267 | goto skip_connect; |
1250 | } | 1268 | } |
@@ -1264,7 +1282,7 @@ main(int ac, char **av) | |||
1264 | timeout_ms = options.connection_timeout * 1000; | 1282 | timeout_ms = options.connection_timeout * 1000; |
1265 | 1283 | ||
1266 | /* Open a connection to the remote host. */ | 1284 | /* Open a connection to the remote host. */ |
1267 | if (ssh_connect(host, addrs, &hostaddr, options.port, | 1285 | if (ssh_connect(ssh, host, addrs, &hostaddr, options.port, |
1268 | options.address_family, options.connection_attempts, | 1286 | options.address_family, options.connection_attempts, |
1269 | &timeout_ms, options.tcp_keep_alive, | 1287 | &timeout_ms, options.tcp_keep_alive, |
1270 | options.use_privileged_port) != 0) | 1288 | options.use_privileged_port) != 0) |
@@ -1292,19 +1310,14 @@ main(int ac, char **av) | |||
1292 | sensitive_data.nkeys = 0; | 1310 | sensitive_data.nkeys = 0; |
1293 | sensitive_data.keys = NULL; | 1311 | sensitive_data.keys = NULL; |
1294 | sensitive_data.external_keysign = 0; | 1312 | sensitive_data.external_keysign = 0; |
1295 | if (options.rhosts_rsa_authentication || | 1313 | if (options.hostbased_authentication) { |
1296 | options.hostbased_authentication) { | ||
1297 | sensitive_data.nkeys = 9; | 1314 | sensitive_data.nkeys = 9; |
1298 | sensitive_data.keys = xcalloc(sensitive_data.nkeys, | 1315 | sensitive_data.keys = xcalloc(sensitive_data.nkeys, |
1299 | sizeof(Key)); | 1316 | sizeof(struct sshkey)); /* XXX */ |
1300 | for (i = 0; i < sensitive_data.nkeys; i++) | 1317 | for (i = 0; i < sensitive_data.nkeys; i++) |
1301 | sensitive_data.keys[i] = NULL; | 1318 | sensitive_data.keys[i] = NULL; |
1302 | 1319 | ||
1303 | PRIV_START; | 1320 | PRIV_START; |
1304 | #if WITH_SSH1 | ||
1305 | sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, | ||
1306 | _PATH_HOST_KEY_FILE, "", NULL, NULL); | ||
1307 | #endif | ||
1308 | #ifdef OPENSSL_HAS_ECC | 1321 | #ifdef OPENSSL_HAS_ECC |
1309 | sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA, | 1322 | sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA, |
1310 | _PATH_HOST_ECDSA_KEY_FILE, "", NULL); | 1323 | _PATH_HOST_ECDSA_KEY_FILE, "", NULL); |
@@ -1452,7 +1465,7 @@ main(int ac, char **av) | |||
1452 | } | 1465 | } |
1453 | 1466 | ||
1454 | skip_connect: | 1467 | skip_connect: |
1455 | exit_status = compat20 ? ssh_session2() : ssh_session(); | 1468 | exit_status = ssh_session2(ssh); |
1456 | packet_close(); | 1469 | packet_close(); |
1457 | 1470 | ||
1458 | if (options.control_path != NULL && muxserver_sock != -1) | 1471 | if (options.control_path != NULL && muxserver_sock != -1) |
@@ -1525,7 +1538,7 @@ fork_postauth(void) | |||
1525 | 1538 | ||
1526 | /* Callback for remote forward global requests */ | 1539 | /* Callback for remote forward global requests */ |
1527 | static void | 1540 | static void |
1528 | ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | 1541 | ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) |
1529 | { | 1542 | { |
1530 | struct Forward *rfwd = (struct Forward *)ctxt; | 1543 | struct Forward *rfwd = (struct Forward *)ctxt; |
1531 | 1544 | ||
@@ -1543,10 +1556,10 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
1543 | logit("Allocated port %u for remote forward to %s:%d", | 1556 | logit("Allocated port %u for remote forward to %s:%d", |
1544 | rfwd->allocated_port, | 1557 | rfwd->allocated_port, |
1545 | rfwd->connect_host, rfwd->connect_port); | 1558 | rfwd->connect_host, rfwd->connect_port); |
1546 | channel_update_permitted_opens(rfwd->handle, | 1559 | channel_update_permitted_opens(ssh, |
1547 | rfwd->allocated_port); | 1560 | rfwd->handle, rfwd->allocated_port); |
1548 | } else { | 1561 | } else { |
1549 | channel_update_permitted_opens(rfwd->handle, -1); | 1562 | channel_update_permitted_opens(ssh, rfwd->handle, -1); |
1550 | } | 1563 | } |
1551 | } | 1564 | } |
1552 | 1565 | ||
@@ -1575,29 +1588,27 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
1575 | } | 1588 | } |
1576 | 1589 | ||
1577 | static void | 1590 | static void |
1578 | client_cleanup_stdio_fwd(int id, void *arg) | 1591 | client_cleanup_stdio_fwd(struct ssh *ssh, int id, void *arg) |
1579 | { | 1592 | { |
1580 | debug("stdio forwarding: done"); | 1593 | debug("stdio forwarding: done"); |
1581 | cleanup_exit(0); | 1594 | cleanup_exit(0); |
1582 | } | 1595 | } |
1583 | 1596 | ||
1584 | static void | 1597 | static void |
1585 | ssh_stdio_confirm(int id, int success, void *arg) | 1598 | ssh_stdio_confirm(struct ssh *ssh, int id, int success, void *arg) |
1586 | { | 1599 | { |
1587 | if (!success) | 1600 | if (!success) |
1588 | fatal("stdio forwarding failed"); | 1601 | fatal("stdio forwarding failed"); |
1589 | } | 1602 | } |
1590 | 1603 | ||
1591 | static void | 1604 | static void |
1592 | ssh_init_stdio_forwarding(void) | 1605 | ssh_init_stdio_forwarding(struct ssh *ssh) |
1593 | { | 1606 | { |
1594 | Channel *c; | 1607 | Channel *c; |
1595 | int in, out; | 1608 | int in, out; |
1596 | 1609 | ||
1597 | if (options.stdio_forward_host == NULL) | 1610 | if (options.stdio_forward_host == NULL) |
1598 | return; | 1611 | return; |
1599 | if (!compat20) | ||
1600 | fatal("stdio forwarding require Protocol 2"); | ||
1601 | 1612 | ||
1602 | debug3("%s: %s:%d", __func__, options.stdio_forward_host, | 1613 | debug3("%s: %s:%d", __func__, options.stdio_forward_host, |
1603 | options.stdio_forward_port); | 1614 | options.stdio_forward_port); |
@@ -1605,15 +1616,15 @@ ssh_init_stdio_forwarding(void) | |||
1605 | if ((in = dup(STDIN_FILENO)) < 0 || | 1616 | if ((in = dup(STDIN_FILENO)) < 0 || |
1606 | (out = dup(STDOUT_FILENO)) < 0) | 1617 | (out = dup(STDOUT_FILENO)) < 0) |
1607 | fatal("channel_connect_stdio_fwd: dup() in/out failed"); | 1618 | fatal("channel_connect_stdio_fwd: dup() in/out failed"); |
1608 | if ((c = channel_connect_stdio_fwd(options.stdio_forward_host, | 1619 | if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host, |
1609 | options.stdio_forward_port, in, out)) == NULL) | 1620 | options.stdio_forward_port, in, out)) == NULL) |
1610 | fatal("%s: channel_connect_stdio_fwd failed", __func__); | 1621 | fatal("%s: channel_connect_stdio_fwd failed", __func__); |
1611 | channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); | 1622 | channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0); |
1612 | channel_register_open_confirm(c->self, ssh_stdio_confirm, NULL); | 1623 | channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL); |
1613 | } | 1624 | } |
1614 | 1625 | ||
1615 | static void | 1626 | static void |
1616 | ssh_init_forwarding(void) | 1627 | ssh_init_forwarding(struct ssh *ssh) |
1617 | { | 1628 | { |
1618 | int success = 0; | 1629 | int success = 0; |
1619 | int i; | 1630 | int i; |
@@ -1632,7 +1643,7 @@ ssh_init_forwarding(void) | |||
1632 | options.local_forwards[i].connect_path : | 1643 | options.local_forwards[i].connect_path : |
1633 | options.local_forwards[i].connect_host, | 1644 | options.local_forwards[i].connect_host, |
1634 | options.local_forwards[i].connect_port); | 1645 | options.local_forwards[i].connect_port); |
1635 | success += channel_setup_local_fwd_listener( | 1646 | success += channel_setup_local_fwd_listener(ssh, |
1636 | &options.local_forwards[i], &options.fwd_opts); | 1647 | &options.local_forwards[i], &options.fwd_opts); |
1637 | } | 1648 | } |
1638 | if (i > 0 && success != i && options.exit_on_forward_failure) | 1649 | if (i > 0 && success != i && options.exit_on_forward_failure) |
@@ -1654,7 +1665,7 @@ ssh_init_forwarding(void) | |||
1654 | options.remote_forwards[i].connect_host, | 1665 | options.remote_forwards[i].connect_host, |
1655 | options.remote_forwards[i].connect_port); | 1666 | options.remote_forwards[i].connect_port); |
1656 | options.remote_forwards[i].handle = | 1667 | options.remote_forwards[i].handle = |
1657 | channel_request_remote_forwarding( | 1668 | channel_request_remote_forwarding(ssh, |
1658 | &options.remote_forwards[i]); | 1669 | &options.remote_forwards[i]); |
1659 | if (options.remote_forwards[i].handle < 0) { | 1670 | if (options.remote_forwards[i].handle < 0) { |
1660 | if (options.exit_on_forward_failure) | 1671 | if (options.exit_on_forward_failure) |
@@ -1663,14 +1674,15 @@ ssh_init_forwarding(void) | |||
1663 | logit("Warning: Could not request remote " | 1674 | logit("Warning: Could not request remote " |
1664 | "forwarding."); | 1675 | "forwarding."); |
1665 | } else { | 1676 | } else { |
1666 | client_register_global_confirm(ssh_confirm_remote_forward, | 1677 | client_register_global_confirm( |
1678 | ssh_confirm_remote_forward, | ||
1667 | &options.remote_forwards[i]); | 1679 | &options.remote_forwards[i]); |
1668 | } | 1680 | } |
1669 | } | 1681 | } |
1670 | 1682 | ||
1671 | /* Initiate tunnel forwarding. */ | 1683 | /* Initiate tunnel forwarding. */ |
1672 | if (options.tun_open != SSH_TUNMODE_NO) { | 1684 | if (options.tun_open != SSH_TUNMODE_NO) { |
1673 | if (client_request_tun_fwd(options.tun_open, | 1685 | if (client_request_tun_fwd(ssh, options.tun_open, |
1674 | options.tun_local, options.tun_remote) == -1) { | 1686 | options.tun_local, options.tun_remote) == -1) { |
1675 | if (options.exit_on_forward_failure) | 1687 | if (options.exit_on_forward_failure) |
1676 | fatal("Could not request tunnel forwarding."); | 1688 | fatal("Could not request tunnel forwarding."); |
@@ -1696,174 +1708,8 @@ check_agent_present(void) | |||
1696 | } | 1708 | } |
1697 | } | 1709 | } |
1698 | 1710 | ||
1699 | static int | ||
1700 | ssh_session(void) | ||
1701 | { | ||
1702 | int type; | ||
1703 | int interactive = 0; | ||
1704 | int have_tty = 0; | ||
1705 | struct winsize ws; | ||
1706 | char *cp; | ||
1707 | const char *display; | ||
1708 | char *proto = NULL, *data = NULL; | ||
1709 | |||
1710 | /* Enable compression if requested. */ | ||
1711 | if (options.compression) { | ||
1712 | debug("Requesting compression at level %d.", | ||
1713 | options.compression_level); | ||
1714 | |||
1715 | if (options.compression_level < 1 || | ||
1716 | options.compression_level > 9) | ||
1717 | fatal("Compression level must be from 1 (fast) to " | ||
1718 | "9 (slow, best)."); | ||
1719 | |||
1720 | /* Send the request. */ | ||
1721 | packet_start(SSH_CMSG_REQUEST_COMPRESSION); | ||
1722 | packet_put_int(options.compression_level); | ||
1723 | packet_send(); | ||
1724 | packet_write_wait(); | ||
1725 | type = packet_read(); | ||
1726 | if (type == SSH_SMSG_SUCCESS) | ||
1727 | packet_start_compression(options.compression_level); | ||
1728 | else if (type == SSH_SMSG_FAILURE) | ||
1729 | logit("Warning: Remote host refused compression."); | ||
1730 | else | ||
1731 | packet_disconnect("Protocol error waiting for " | ||
1732 | "compression response."); | ||
1733 | } | ||
1734 | /* Allocate a pseudo tty if appropriate. */ | ||
1735 | if (tty_flag) { | ||
1736 | debug("Requesting pty."); | ||
1737 | |||
1738 | /* Start the packet. */ | ||
1739 | packet_start(SSH_CMSG_REQUEST_PTY); | ||
1740 | |||
1741 | /* Store TERM in the packet. There is no limit on the | ||
1742 | length of the string. */ | ||
1743 | cp = getenv("TERM"); | ||
1744 | if (!cp) | ||
1745 | cp = ""; | ||
1746 | packet_put_cstring(cp); | ||
1747 | |||
1748 | /* Store window size in the packet. */ | ||
1749 | if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) | ||
1750 | memset(&ws, 0, sizeof(ws)); | ||
1751 | packet_put_int((u_int)ws.ws_row); | ||
1752 | packet_put_int((u_int)ws.ws_col); | ||
1753 | packet_put_int((u_int)ws.ws_xpixel); | ||
1754 | packet_put_int((u_int)ws.ws_ypixel); | ||
1755 | |||
1756 | /* Store tty modes in the packet. */ | ||
1757 | tty_make_modes(fileno(stdin), NULL); | ||
1758 | |||
1759 | /* Send the packet, and wait for it to leave. */ | ||
1760 | packet_send(); | ||
1761 | packet_write_wait(); | ||
1762 | |||
1763 | /* Read response from the server. */ | ||
1764 | type = packet_read(); | ||
1765 | if (type == SSH_SMSG_SUCCESS) { | ||
1766 | interactive = 1; | ||
1767 | have_tty = 1; | ||
1768 | } else if (type == SSH_SMSG_FAILURE) | ||
1769 | logit("Warning: Remote host failed or refused to " | ||
1770 | "allocate a pseudo tty."); | ||
1771 | else | ||
1772 | packet_disconnect("Protocol error waiting for pty " | ||
1773 | "request response."); | ||
1774 | } | ||
1775 | /* Request X11 forwarding if enabled and DISPLAY is set. */ | ||
1776 | display = getenv("DISPLAY"); | ||
1777 | if (display == NULL && options.forward_x11) | ||
1778 | debug("X11 forwarding requested but DISPLAY not set"); | ||
1779 | if (options.forward_x11 && client_x11_get_proto(display, | ||
1780 | options.xauth_location, options.forward_x11_trusted, | ||
1781 | options.forward_x11_timeout, &proto, &data) == 0) { | ||
1782 | /* Request forwarding with authentication spoofing. */ | ||
1783 | debug("Requesting X11 forwarding with authentication " | ||
1784 | "spoofing."); | ||
1785 | x11_request_forwarding_with_spoofing(0, display, proto, | ||
1786 | data, 0); | ||
1787 | /* Read response from the server. */ | ||
1788 | type = packet_read(); | ||
1789 | if (type == SSH_SMSG_SUCCESS) { | ||
1790 | interactive = 1; | ||
1791 | } else if (type == SSH_SMSG_FAILURE) { | ||
1792 | logit("Warning: Remote host denied X11 forwarding."); | ||
1793 | } else { | ||
1794 | packet_disconnect("Protocol error waiting for X11 " | ||
1795 | "forwarding"); | ||
1796 | } | ||
1797 | } | ||
1798 | /* Tell the packet module whether this is an interactive session. */ | ||
1799 | packet_set_interactive(interactive, | ||
1800 | options.ip_qos_interactive, options.ip_qos_bulk); | ||
1801 | |||
1802 | /* Request authentication agent forwarding if appropriate. */ | ||
1803 | check_agent_present(); | ||
1804 | |||
1805 | if (options.forward_agent) { | ||
1806 | debug("Requesting authentication agent forwarding."); | ||
1807 | auth_request_forwarding(); | ||
1808 | |||
1809 | /* Read response from the server. */ | ||
1810 | type = packet_read(); | ||
1811 | packet_check_eom(); | ||
1812 | if (type != SSH_SMSG_SUCCESS) | ||
1813 | logit("Warning: Remote host denied authentication agent forwarding."); | ||
1814 | } | ||
1815 | |||
1816 | /* Initiate port forwardings. */ | ||
1817 | ssh_init_stdio_forwarding(); | ||
1818 | ssh_init_forwarding(); | ||
1819 | |||
1820 | /* Execute a local command */ | ||
1821 | if (options.local_command != NULL && | ||
1822 | options.permit_local_command) | ||
1823 | ssh_local_cmd(options.local_command); | ||
1824 | |||
1825 | /* | ||
1826 | * If requested and we are not interested in replies to remote | ||
1827 | * forwarding requests, then let ssh continue in the background. | ||
1828 | */ | ||
1829 | if (fork_after_authentication_flag) { | ||
1830 | if (options.exit_on_forward_failure && | ||
1831 | options.num_remote_forwards > 0) { | ||
1832 | debug("deferring postauth fork until remote forward " | ||
1833 | "confirmation received"); | ||
1834 | } else | ||
1835 | fork_postauth(); | ||
1836 | } | ||
1837 | |||
1838 | /* | ||
1839 | * If a command was specified on the command line, execute the | ||
1840 | * command now. Otherwise request the server to start a shell. | ||
1841 | */ | ||
1842 | if (buffer_len(&command) > 0) { | ||
1843 | int len = buffer_len(&command); | ||
1844 | if (len > 900) | ||
1845 | len = 900; | ||
1846 | debug("Sending command: %.*s", len, | ||
1847 | (u_char *)buffer_ptr(&command)); | ||
1848 | packet_start(SSH_CMSG_EXEC_CMD); | ||
1849 | packet_put_string(buffer_ptr(&command), buffer_len(&command)); | ||
1850 | packet_send(); | ||
1851 | packet_write_wait(); | ||
1852 | } else { | ||
1853 | debug("Requesting shell."); | ||
1854 | packet_start(SSH_CMSG_EXEC_SHELL); | ||
1855 | packet_send(); | ||
1856 | packet_write_wait(); | ||
1857 | } | ||
1858 | |||
1859 | /* Enter the interactive session. */ | ||
1860 | return client_loop(have_tty, tty_flag ? | ||
1861 | options.escape_char : SSH_ESCAPECHAR_NONE, 0); | ||
1862 | } | ||
1863 | |||
1864 | /* request pty/x11/agent/tcpfwd/shell for channel */ | ||
1865 | static void | 1711 | static void |
1866 | ssh_session2_setup(int id, int success, void *arg) | 1712 | ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg) |
1867 | { | 1713 | { |
1868 | extern char **environ; | 1714 | extern char **environ; |
1869 | const char *display; | 1715 | const char *display; |
@@ -1876,15 +1722,15 @@ ssh_session2_setup(int id, int success, void *arg) | |||
1876 | display = getenv("DISPLAY"); | 1722 | display = getenv("DISPLAY"); |
1877 | if (display == NULL && options.forward_x11) | 1723 | if (display == NULL && options.forward_x11) |
1878 | debug("X11 forwarding requested but DISPLAY not set"); | 1724 | debug("X11 forwarding requested but DISPLAY not set"); |
1879 | if (options.forward_x11 && client_x11_get_proto(display, | 1725 | if (options.forward_x11 && client_x11_get_proto(ssh, display, |
1880 | options.xauth_location, options.forward_x11_trusted, | 1726 | options.xauth_location, options.forward_x11_trusted, |
1881 | options.forward_x11_timeout, &proto, &data) == 0) { | 1727 | options.forward_x11_timeout, &proto, &data) == 0) { |
1882 | /* Request forwarding with authentication spoofing. */ | 1728 | /* Request forwarding with authentication spoofing. */ |
1883 | debug("Requesting X11 forwarding with authentication " | 1729 | debug("Requesting X11 forwarding with authentication " |
1884 | "spoofing."); | 1730 | "spoofing."); |
1885 | x11_request_forwarding_with_spoofing(id, display, proto, | 1731 | x11_request_forwarding_with_spoofing(ssh, id, display, proto, |
1886 | data, 1); | 1732 | data, 1); |
1887 | client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); | 1733 | client_expect_confirm(ssh, id, "X11 forwarding", CONFIRM_WARN); |
1888 | /* XXX exit_on_forward_failure */ | 1734 | /* XXX exit_on_forward_failure */ |
1889 | interactive = 1; | 1735 | interactive = 1; |
1890 | } | 1736 | } |
@@ -1892,7 +1738,7 @@ ssh_session2_setup(int id, int success, void *arg) | |||
1892 | check_agent_present(); | 1738 | check_agent_present(); |
1893 | if (options.forward_agent) { | 1739 | if (options.forward_agent) { |
1894 | debug("Requesting authentication agent forwarding."); | 1740 | debug("Requesting authentication agent forwarding."); |
1895 | channel_request_start(id, "auth-agent-req@openssh.com", 0); | 1741 | channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0); |
1896 | packet_send(); | 1742 | packet_send(); |
1897 | } | 1743 | } |
1898 | 1744 | ||
@@ -1900,13 +1746,13 @@ ssh_session2_setup(int id, int success, void *arg) | |||
1900 | packet_set_interactive(interactive, | 1746 | packet_set_interactive(interactive, |
1901 | options.ip_qos_interactive, options.ip_qos_bulk); | 1747 | options.ip_qos_interactive, options.ip_qos_bulk); |
1902 | 1748 | ||
1903 | client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), | 1749 | client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"), |
1904 | NULL, fileno(stdin), &command, environ); | 1750 | NULL, fileno(stdin), &command, environ); |
1905 | } | 1751 | } |
1906 | 1752 | ||
1907 | /* open new channel for a session */ | 1753 | /* open new channel for a session */ |
1908 | static int | 1754 | static int |
1909 | ssh_session2_open(void) | 1755 | ssh_session2_open(struct ssh *ssh) |
1910 | { | 1756 | { |
1911 | Channel *c; | 1757 | Channel *c; |
1912 | int window, packetmax, in, out, err; | 1758 | int window, packetmax, in, out, err; |
@@ -1936,34 +1782,34 @@ ssh_session2_open(void) | |||
1936 | window >>= 1; | 1782 | window >>= 1; |
1937 | packetmax >>= 1; | 1783 | packetmax >>= 1; |
1938 | } | 1784 | } |
1939 | c = channel_new( | 1785 | c = channel_new(ssh, |
1940 | "session", SSH_CHANNEL_OPENING, in, out, err, | 1786 | "session", SSH_CHANNEL_OPENING, in, out, err, |
1941 | window, packetmax, CHAN_EXTENDED_WRITE, | 1787 | window, packetmax, CHAN_EXTENDED_WRITE, |
1942 | "client-session", /*nonblock*/0); | 1788 | "client-session", /*nonblock*/0); |
1943 | 1789 | ||
1944 | debug3("ssh_session2_open: channel_new: %d", c->self); | 1790 | debug3("%s: channel_new: %d", __func__, c->self); |
1945 | 1791 | ||
1946 | channel_send_open(c->self); | 1792 | channel_send_open(ssh, c->self); |
1947 | if (!no_shell_flag) | 1793 | if (!no_shell_flag) |
1948 | channel_register_open_confirm(c->self, | 1794 | channel_register_open_confirm(ssh, c->self, |
1949 | ssh_session2_setup, NULL); | 1795 | ssh_session2_setup, NULL); |
1950 | 1796 | ||
1951 | return c->self; | 1797 | return c->self; |
1952 | } | 1798 | } |
1953 | 1799 | ||
1954 | static int | 1800 | static int |
1955 | ssh_session2(void) | 1801 | ssh_session2(struct ssh *ssh) |
1956 | { | 1802 | { |
1957 | int id = -1; | 1803 | int id = -1; |
1958 | 1804 | ||
1959 | /* XXX should be pre-session */ | 1805 | /* XXX should be pre-session */ |
1960 | if (!options.control_persist) | 1806 | if (!options.control_persist) |
1961 | ssh_init_stdio_forwarding(); | 1807 | ssh_init_stdio_forwarding(ssh); |
1962 | ssh_init_forwarding(); | 1808 | ssh_init_forwarding(ssh); |
1963 | 1809 | ||
1964 | /* Start listening for multiplex clients */ | 1810 | /* Start listening for multiplex clients */ |
1965 | if (!packet_get_mux()) | 1811 | if (!packet_get_mux()) |
1966 | muxserver_listen(); | 1812 | muxserver_listen(ssh); |
1967 | 1813 | ||
1968 | /* | 1814 | /* |
1969 | * If we are in control persist mode and have a working mux listen | 1815 | * If we are in control persist mode and have a working mux listen |
@@ -1991,10 +1837,10 @@ ssh_session2(void) | |||
1991 | * stdio forward setup that we skipped earlier. | 1837 | * stdio forward setup that we skipped earlier. |
1992 | */ | 1838 | */ |
1993 | if (options.control_persist && muxserver_sock == -1) | 1839 | if (options.control_persist && muxserver_sock == -1) |
1994 | ssh_init_stdio_forwarding(); | 1840 | ssh_init_stdio_forwarding(ssh); |
1995 | 1841 | ||
1996 | if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) | 1842 | if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) |
1997 | id = ssh_session2_open(); | 1843 | id = ssh_session2_open(ssh); |
1998 | else { | 1844 | else { |
1999 | packet_set_interactive( | 1845 | packet_set_interactive( |
2000 | options.control_master == SSHCTL_MASTER_NO, | 1846 | options.control_master == SSHCTL_MASTER_NO, |
@@ -2029,7 +1875,7 @@ ssh_session2(void) | |||
2029 | fork_postauth(); | 1875 | fork_postauth(); |
2030 | } | 1876 | } |
2031 | 1877 | ||
2032 | return client_loop(tty_flag, tty_flag ? | 1878 | return client_loop(ssh, tty_flag, tty_flag ? |
2033 | options.escape_char : SSH_ESCAPECHAR_NONE, id); | 1879 | options.escape_char : SSH_ESCAPECHAR_NONE, id); |
2034 | } | 1880 | } |
2035 | 1881 | ||
@@ -2039,16 +1885,16 @@ load_public_identity_files(void) | |||
2039 | { | 1885 | { |
2040 | char *filename, *cp, thishost[NI_MAXHOST]; | 1886 | char *filename, *cp, thishost[NI_MAXHOST]; |
2041 | char *pwdir = NULL, *pwname = NULL; | 1887 | char *pwdir = NULL, *pwname = NULL; |
2042 | Key *public; | 1888 | struct sshkey *public; |
2043 | struct passwd *pw; | 1889 | struct passwd *pw; |
2044 | int i; | 1890 | int i; |
2045 | u_int n_ids, n_certs; | 1891 | u_int n_ids, n_certs; |
2046 | char *identity_files[SSH_MAX_IDENTITY_FILES]; | 1892 | char *identity_files[SSH_MAX_IDENTITY_FILES]; |
2047 | Key *identity_keys[SSH_MAX_IDENTITY_FILES]; | 1893 | struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES]; |
2048 | char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; | 1894 | char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; |
2049 | struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; | 1895 | struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; |
2050 | #ifdef ENABLE_PKCS11 | 1896 | #ifdef ENABLE_PKCS11 |
2051 | Key **keys; | 1897 | struct sshkey **keys; |
2052 | int nkeys; | 1898 | int nkeys; |
2053 | #endif /* PKCS11 */ | 1899 | #endif /* PKCS11 */ |
2054 | 1900 | ||