diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 301 |
1 files changed, 229 insertions, 72 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.381 2013/07/25 00:29:10 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.397 2013/12/29 05:42: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 |
@@ -199,11 +199,11 @@ usage(void) | |||
199 | "usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" | 199 | "usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" |
200 | " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" | 200 | " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" |
201 | " [-F configfile] [-I pkcs11] [-i identity_file]\n" | 201 | " [-F configfile] [-I pkcs11] [-i identity_file]\n" |
202 | " [-L [bind_address:]port:host:hostport] [-Q protocol_feature]\n" | 202 | " [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec]\n" |
203 | " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" | 203 | " [-O ctl_cmd] [-o option] [-p port]\n" |
204 | " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" | 204 | " [-Q cipher | cipher-auth | mac | kex | key]\n" |
205 | " [-W host:port] [-w local_tun[:remote_tun]]\n" | 205 | " [-R [bind_address:]port:host:hostport] [-S ctl_path] [-W host:port]\n" |
206 | " [user@]hostname [command]\n" | 206 | " [-w local_tun[:remote_tun]] [user@]hostname [command]\n" |
207 | ); | 207 | ); |
208 | exit(255); | 208 | exit(255); |
209 | } | 209 | } |
@@ -231,6 +231,134 @@ tilde_expand_paths(char **paths, u_int num_paths) | |||
231 | } | 231 | } |
232 | } | 232 | } |
233 | 233 | ||
234 | static struct addrinfo * | ||
235 | resolve_host(const char *name, u_int port, int logerr, char *cname, size_t clen) | ||
236 | { | ||
237 | char strport[NI_MAXSERV]; | ||
238 | struct addrinfo hints, *res; | ||
239 | int gaierr, loglevel = SYSLOG_LEVEL_DEBUG1; | ||
240 | |||
241 | snprintf(strport, sizeof strport, "%u", port); | ||
242 | bzero(&hints, sizeof(hints)); | ||
243 | hints.ai_family = options.address_family; | ||
244 | hints.ai_socktype = SOCK_STREAM; | ||
245 | if (cname != NULL) | ||
246 | hints.ai_flags = AI_CANONNAME; | ||
247 | if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) { | ||
248 | if (logerr || (gaierr != EAI_NONAME && gaierr != EAI_NODATA)) | ||
249 | loglevel = SYSLOG_LEVEL_ERROR; | ||
250 | do_log2(loglevel, "%s: Could not resolve hostname %.100s: %s", | ||
251 | __progname, name, ssh_gai_strerror(gaierr)); | ||
252 | return NULL; | ||
253 | } | ||
254 | if (cname != NULL && res->ai_canonname != NULL) { | ||
255 | if (strlcpy(cname, res->ai_canonname, clen) >= clen) { | ||
256 | error("%s: host \"%s\" cname \"%s\" too long (max %lu)", | ||
257 | __func__, name, res->ai_canonname, (u_long)clen); | ||
258 | if (clen > 0) | ||
259 | *cname = '\0'; | ||
260 | } | ||
261 | } | ||
262 | return res; | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * Check whether the cname is a permitted replacement for the hostname | ||
267 | * and perform the replacement if it is. | ||
268 | */ | ||
269 | static int | ||
270 | check_follow_cname(char **namep, const char *cname) | ||
271 | { | ||
272 | int i; | ||
273 | struct allowed_cname *rule; | ||
274 | |||
275 | if (*cname == '\0' || options.num_permitted_cnames == 0 || | ||
276 | strcmp(*namep, cname) == 0) | ||
277 | return 0; | ||
278 | if (options.canonicalize_hostname == SSH_CANONICALISE_NO) | ||
279 | return 0; | ||
280 | /* | ||
281 | * Don't attempt to canonicalize names that will be interpreted by | ||
282 | * a proxy unless the user specifically requests so. | ||
283 | */ | ||
284 | if (options.proxy_command != NULL && | ||
285 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) | ||
286 | return 0; | ||
287 | debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname); | ||
288 | for (i = 0; i < options.num_permitted_cnames; i++) { | ||
289 | rule = options.permitted_cnames + i; | ||
290 | if (match_pattern_list(*namep, rule->source_list, | ||
291 | strlen(rule->source_list), 1) != 1 || | ||
292 | match_pattern_list(cname, rule->target_list, | ||
293 | strlen(rule->target_list), 1) != 1) | ||
294 | continue; | ||
295 | verbose("Canonicalized DNS aliased hostname " | ||
296 | "\"%s\" => \"%s\"", *namep, cname); | ||
297 | free(*namep); | ||
298 | *namep = xstrdup(cname); | ||
299 | return 1; | ||
300 | } | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * Attempt to resolve the supplied hostname after applying the user's | ||
306 | * canonicalization rules. Returns the address list for the host or NULL | ||
307 | * if no name was found after canonicalization. | ||
308 | */ | ||
309 | static struct addrinfo * | ||
310 | resolve_canonicalize(char **hostp, u_int port) | ||
311 | { | ||
312 | int i, ndots; | ||
313 | char *cp, *fullhost, cname_target[NI_MAXHOST]; | ||
314 | struct addrinfo *addrs; | ||
315 | |||
316 | if (options.canonicalize_hostname == SSH_CANONICALISE_NO) | ||
317 | return NULL; | ||
318 | /* | ||
319 | * Don't attempt to canonicalize names that will be interpreted by | ||
320 | * a proxy unless the user specifically requests so. | ||
321 | */ | ||
322 | if (options.proxy_command != NULL && | ||
323 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) | ||
324 | return NULL; | ||
325 | /* Don't apply canonicalization to sufficiently-qualified hostnames */ | ||
326 | ndots = 0; | ||
327 | for (cp = *hostp; *cp != '\0'; cp++) { | ||
328 | if (*cp == '.') | ||
329 | ndots++; | ||
330 | } | ||
331 | if (ndots > options.canonicalize_max_dots) { | ||
332 | debug3("%s: not canonicalizing hostname \"%s\" (max dots %d)", | ||
333 | __func__, *hostp, options.canonicalize_max_dots); | ||
334 | return NULL; | ||
335 | } | ||
336 | /* Attempt each supplied suffix */ | ||
337 | for (i = 0; i < options.num_canonical_domains; i++) { | ||
338 | *cname_target = '\0'; | ||
339 | xasprintf(&fullhost, "%s.%s.", *hostp, | ||
340 | options.canonical_domains[i]); | ||
341 | if ((addrs = resolve_host(fullhost, options.port, 0, | ||
342 | cname_target, sizeof(cname_target))) == NULL) { | ||
343 | free(fullhost); | ||
344 | continue; | ||
345 | } | ||
346 | /* Remove trailing '.' */ | ||
347 | fullhost[strlen(fullhost) - 1] = '\0'; | ||
348 | /* Follow CNAME if requested */ | ||
349 | if (!check_follow_cname(&fullhost, cname_target)) { | ||
350 | debug("Canonicalized hostname \"%s\" => \"%s\"", | ||
351 | *hostp, fullhost); | ||
352 | } | ||
353 | free(*hostp); | ||
354 | *hostp = fullhost; | ||
355 | return addrs; | ||
356 | } | ||
357 | if (!options.canonicalize_fallback_local) | ||
358 | fatal("%s: Could not resolve host \"%s\"", __progname, host); | ||
359 | return NULL; | ||
360 | } | ||
361 | |||
234 | /* | 362 | /* |
235 | * Main program for the ssh client. | 363 | * Main program for the ssh client. |
236 | */ | 364 | */ |
@@ -240,14 +368,14 @@ main(int ac, char **av) | |||
240 | int i, r, opt, exit_status, use_syslog; | 368 | int i, r, opt, exit_status, use_syslog; |
241 | char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg, *logfile; | 369 | char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg, *logfile; |
242 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; | 370 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; |
371 | char cname[NI_MAXHOST]; | ||
243 | struct stat st; | 372 | struct stat st; |
244 | struct passwd *pw; | 373 | struct passwd *pw; |
245 | int dummy, timeout_ms; | 374 | int timeout_ms; |
246 | extern int optind, optreset; | 375 | extern int optind, optreset; |
247 | extern char *optarg; | 376 | extern char *optarg; |
248 | |||
249 | struct servent *sp; | ||
250 | Forward fwd; | 377 | Forward fwd; |
378 | struct addrinfo *addrs = NULL; | ||
251 | 379 | ||
252 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ | 380 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
253 | sanitise_stdfd(); | 381 | sanitise_stdfd(); |
@@ -389,16 +517,22 @@ main(int ac, char **av) | |||
389 | case 'P': /* deprecated */ | 517 | case 'P': /* deprecated */ |
390 | options.use_privileged_port = 0; | 518 | options.use_privileged_port = 0; |
391 | break; | 519 | break; |
392 | case 'Q': /* deprecated */ | 520 | case 'Q': |
393 | cp = NULL; | 521 | cp = NULL; |
394 | if (strcasecmp(optarg, "cipher") == 0) | 522 | if (strcmp(optarg, "cipher") == 0) |
395 | cp = cipher_alg_list(); | 523 | cp = cipher_alg_list('\n', 0); |
396 | else if (strcasecmp(optarg, "mac") == 0) | 524 | else if (strcmp(optarg, "cipher-auth") == 0) |
397 | cp = mac_alg_list(); | 525 | cp = cipher_alg_list('\n', 1); |
398 | else if (strcasecmp(optarg, "kex") == 0) | 526 | else if (strcmp(optarg, "mac") == 0) |
399 | cp = kex_alg_list(); | 527 | cp = mac_alg_list('\n'); |
400 | else if (strcasecmp(optarg, "key") == 0) | 528 | else if (strcmp(optarg, "kex") == 0) |
401 | cp = key_alg_list(); | 529 | cp = kex_alg_list('\n'); |
530 | else if (strcmp(optarg, "key") == 0) | ||
531 | cp = key_alg_list(0, 0); | ||
532 | else if (strcmp(optarg, "key-cert") == 0) | ||
533 | cp = key_alg_list(1, 0); | ||
534 | else if (strcmp(optarg, "key-plain") == 0) | ||
535 | cp = key_alg_list(0, 1); | ||
402 | if (cp == NULL) | 536 | if (cp == NULL) |
403 | fatal("Unsupported query \"%s\"", optarg); | 537 | fatal("Unsupported query \"%s\"", optarg); |
404 | printf("%s\n", cp); | 538 | printf("%s\n", cp); |
@@ -595,10 +729,9 @@ main(int ac, char **av) | |||
595 | options.request_tty = REQUEST_TTY_NO; | 729 | options.request_tty = REQUEST_TTY_NO; |
596 | break; | 730 | break; |
597 | case 'o': | 731 | case 'o': |
598 | dummy = 1; | ||
599 | line = xstrdup(optarg); | 732 | line = xstrdup(optarg); |
600 | if (process_config_line(&options, host ? host : "", | 733 | if (process_config_line(&options, pw, host ? host : "", |
601 | line, "command-line", 0, &dummy, SSHCONF_USERCONF) | 734 | line, "command-line", 0, NULL, SSHCONF_USERCONF) |
602 | != 0) | 735 | != 0) |
603 | exit(255); | 736 | exit(255); |
604 | free(line); | 737 | free(line); |
@@ -633,9 +766,9 @@ main(int ac, char **av) | |||
633 | usage(); | 766 | usage(); |
634 | options.user = p; | 767 | options.user = p; |
635 | *cp = '\0'; | 768 | *cp = '\0'; |
636 | host = ++cp; | 769 | host = xstrdup(++cp); |
637 | } else | 770 | } else |
638 | host = *av; | 771 | host = xstrdup(*av); |
639 | if (ac > 1) { | 772 | if (ac > 1) { |
640 | optind = optreset = 1; | 773 | optind = optreset = 1; |
641 | goto again; | 774 | goto again; |
@@ -647,6 +780,9 @@ main(int ac, char **av) | |||
647 | if (!host) | 780 | if (!host) |
648 | usage(); | 781 | usage(); |
649 | 782 | ||
783 | lowercase(host); | ||
784 | host_arg = xstrdup(host); | ||
785 | |||
650 | OpenSSL_add_all_algorithms(); | 786 | OpenSSL_add_all_algorithms(); |
651 | ERR_load_crypto_strings(); | 787 | ERR_load_crypto_strings(); |
652 | 788 | ||
@@ -703,18 +839,19 @@ main(int ac, char **av) | |||
703 | */ | 839 | */ |
704 | if (config != NULL) { | 840 | if (config != NULL) { |
705 | if (strcasecmp(config, "none") != 0 && | 841 | if (strcasecmp(config, "none") != 0 && |
706 | !read_config_file(config, host, &options, SSHCONF_USERCONF)) | 842 | !read_config_file(config, pw, host, &options, |
843 | SSHCONF_USERCONF)) | ||
707 | fatal("Can't open user config file %.100s: " | 844 | fatal("Can't open user config file %.100s: " |
708 | "%.100s", config, strerror(errno)); | 845 | "%.100s", config, strerror(errno)); |
709 | } else { | 846 | } else { |
710 | r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, | 847 | r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, |
711 | _PATH_SSH_USER_CONFFILE); | 848 | _PATH_SSH_USER_CONFFILE); |
712 | if (r > 0 && (size_t)r < sizeof(buf)) | 849 | if (r > 0 && (size_t)r < sizeof(buf)) |
713 | (void)read_config_file(buf, host, &options, | 850 | (void)read_config_file(buf, pw, host, &options, |
714 | SSHCONF_CHECKPERM|SSHCONF_USERCONF); | 851 | SSHCONF_CHECKPERM|SSHCONF_USERCONF); |
715 | 852 | ||
716 | /* Read systemwide configuration file after user config. */ | 853 | /* Read systemwide configuration file after user config. */ |
717 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, | 854 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host, |
718 | &options, 0); | 855 | &options, 0); |
719 | } | 856 | } |
720 | 857 | ||
@@ -723,6 +860,18 @@ main(int ac, char **av) | |||
723 | 860 | ||
724 | channel_set_af(options.address_family); | 861 | channel_set_af(options.address_family); |
725 | 862 | ||
863 | /* Tidy and check options */ | ||
864 | if (options.host_key_alias != NULL) | ||
865 | lowercase(options.host_key_alias); | ||
866 | if (options.proxy_command != NULL && | ||
867 | strcmp(options.proxy_command, "-") == 0 && | ||
868 | options.proxy_use_fdpass) | ||
869 | fatal("ProxyCommand=- and ProxyUseFDPass are incompatible"); | ||
870 | #ifndef HAVE_CYGWIN | ||
871 | if (original_effective_uid != 0) | ||
872 | options.use_privileged_port = 0; | ||
873 | #endif | ||
874 | |||
726 | /* reinit */ | 875 | /* reinit */ |
727 | log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog); | 876 | log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog); |
728 | 877 | ||
@@ -752,16 +901,33 @@ main(int ac, char **av) | |||
752 | options.user = xstrdup(pw->pw_name); | 901 | options.user = xstrdup(pw->pw_name); |
753 | 902 | ||
754 | /* Get default port if port has not been set. */ | 903 | /* Get default port if port has not been set. */ |
755 | if (options.port == 0) { | 904 | if (options.port == 0) |
756 | sp = getservbyname(SSH_SERVICE_NAME, "tcp"); | 905 | options.port = default_ssh_port(); |
757 | options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; | ||
758 | } | ||
759 | 906 | ||
760 | /* preserve host name given on command line for %n expansion */ | 907 | /* preserve host name given on command line for %n expansion */ |
761 | host_arg = host; | ||
762 | if (options.hostname != NULL) { | 908 | if (options.hostname != NULL) { |
763 | host = percent_expand(options.hostname, | 909 | /* NB. Please keep in sync with readconf.c:match_cfg_line() */ |
910 | cp = percent_expand(options.hostname, | ||
764 | "h", host, (char *)NULL); | 911 | "h", host, (char *)NULL); |
912 | free(host); | ||
913 | host = cp; | ||
914 | } | ||
915 | |||
916 | /* If canonicalization requested then try to apply it */ | ||
917 | if (options.canonicalize_hostname != SSH_CANONICALISE_NO) | ||
918 | addrs = resolve_canonicalize(&host, options.port); | ||
919 | /* | ||
920 | * If canonicalization not requested, or if it failed then try to | ||
921 | * resolve the bare hostname name using the system resolver's usual | ||
922 | * search rules. Skip the lookup if a ProxyCommand is being used | ||
923 | * unless the user has specifically requested canonicalisation. | ||
924 | */ | ||
925 | if (addrs == NULL && (options.proxy_command == NULL || | ||
926 | options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) { | ||
927 | if ((addrs = resolve_host(host, options.port, 1, | ||
928 | cname, sizeof(cname))) == NULL) | ||
929 | cleanup_exit(255); /* resolve_host logs the error */ | ||
930 | check_follow_cname(&host, cname); | ||
765 | } | 931 | } |
766 | 932 | ||
767 | if (gethostname(thishost, sizeof(thishost)) == -1) | 933 | if (gethostname(thishost, sizeof(thishost)) == -1) |
@@ -781,24 +947,6 @@ main(int ac, char **av) | |||
781 | free(cp); | 947 | free(cp); |
782 | } | 948 | } |
783 | 949 | ||
784 | /* force lowercase for hostkey matching */ | ||
785 | if (options.host_key_alias != NULL) { | ||
786 | for (p = options.host_key_alias; *p; p++) | ||
787 | if (isupper(*p)) | ||
788 | *p = (char)tolower(*p); | ||
789 | } | ||
790 | |||
791 | if (options.proxy_command != NULL && | ||
792 | strcmp(options.proxy_command, "none") == 0) { | ||
793 | free(options.proxy_command); | ||
794 | options.proxy_command = NULL; | ||
795 | } | ||
796 | if (options.control_path != NULL && | ||
797 | strcmp(options.control_path, "none") == 0) { | ||
798 | free(options.control_path); | ||
799 | options.control_path = NULL; | ||
800 | } | ||
801 | |||
802 | if (options.control_path != NULL) { | 950 | if (options.control_path != NULL) { |
803 | cp = tilde_expand_filename(options.control_path, | 951 | cp = tilde_expand_filename(options.control_path, |
804 | original_real_uid); | 952 | original_real_uid); |
@@ -817,16 +965,17 @@ main(int ac, char **av) | |||
817 | timeout_ms = options.connection_timeout * 1000; | 965 | timeout_ms = options.connection_timeout * 1000; |
818 | 966 | ||
819 | /* Open a connection to the remote host. */ | 967 | /* Open a connection to the remote host. */ |
820 | if (ssh_connect(host, &hostaddr, options.port, | 968 | if (ssh_connect(host, addrs, &hostaddr, options.port, |
821 | options.address_family, options.connection_attempts, &timeout_ms, | 969 | options.address_family, options.connection_attempts, |
822 | options.tcp_keep_alive, | 970 | &timeout_ms, options.tcp_keep_alive, |
823 | #ifdef HAVE_CYGWIN | 971 | options.use_privileged_port) != 0) |
824 | options.use_privileged_port, | 972 | exit(255); |
825 | #else | 973 | |
826 | original_effective_uid == 0 && options.use_privileged_port, | 974 | if (addrs != NULL) |
827 | #endif | 975 | freeaddrinfo(addrs); |
828 | options.proxy_command) != 0) | 976 | |
829 | exit(255); | 977 | packet_set_timeout(options.server_alive_interval, |
978 | options.server_alive_count_max); | ||
830 | 979 | ||
831 | if (timeout_ms > 0) | 980 | if (timeout_ms > 0) |
832 | debug3("timeout: %d ms remain after connect", timeout_ms); | 981 | debug3("timeout: %d ms remain after connect", timeout_ms); |
@@ -844,7 +993,7 @@ main(int ac, char **av) | |||
844 | sensitive_data.external_keysign = 0; | 993 | sensitive_data.external_keysign = 0; |
845 | if (options.rhosts_rsa_authentication || | 994 | if (options.rhosts_rsa_authentication || |
846 | options.hostbased_authentication) { | 995 | options.hostbased_authentication) { |
847 | sensitive_data.nkeys = 7; | 996 | sensitive_data.nkeys = 9; |
848 | sensitive_data.keys = xcalloc(sensitive_data.nkeys, | 997 | sensitive_data.keys = xcalloc(sensitive_data.nkeys, |
849 | sizeof(Key)); | 998 | sizeof(Key)); |
850 | for (i = 0; i < sensitive_data.nkeys; i++) | 999 | for (i = 0; i < sensitive_data.nkeys; i++) |
@@ -861,21 +1010,26 @@ main(int ac, char **av) | |||
861 | #endif | 1010 | #endif |
862 | sensitive_data.keys[3] = key_load_private_cert(KEY_RSA, | 1011 | sensitive_data.keys[3] = key_load_private_cert(KEY_RSA, |
863 | _PATH_HOST_RSA_KEY_FILE, "", NULL); | 1012 | _PATH_HOST_RSA_KEY_FILE, "", NULL); |
864 | sensitive_data.keys[4] = key_load_private_type(KEY_DSA, | 1013 | sensitive_data.keys[4] = key_load_private_cert(KEY_ED25519, |
1014 | _PATH_HOST_ED25519_KEY_FILE, "", NULL); | ||
1015 | sensitive_data.keys[5] = key_load_private_type(KEY_DSA, | ||
865 | _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); | 1016 | _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); |
866 | #ifdef OPENSSL_HAS_ECC | 1017 | #ifdef OPENSSL_HAS_ECC |
867 | sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA, | 1018 | sensitive_data.keys[6] = key_load_private_type(KEY_ECDSA, |
868 | _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL); | 1019 | _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL); |
869 | #endif | 1020 | #endif |
870 | sensitive_data.keys[6] = key_load_private_type(KEY_RSA, | 1021 | sensitive_data.keys[7] = key_load_private_type(KEY_RSA, |
871 | _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); | 1022 | _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); |
1023 | sensitive_data.keys[8] = key_load_private_type(KEY_ED25519, | ||
1024 | _PATH_HOST_ED25519_KEY_FILE, "", NULL, NULL); | ||
872 | PRIV_END; | 1025 | PRIV_END; |
873 | 1026 | ||
874 | if (options.hostbased_authentication == 1 && | 1027 | if (options.hostbased_authentication == 1 && |
875 | sensitive_data.keys[0] == NULL && | 1028 | sensitive_data.keys[0] == NULL && |
876 | sensitive_data.keys[4] == NULL && | ||
877 | sensitive_data.keys[5] == NULL && | 1029 | sensitive_data.keys[5] == NULL && |
878 | sensitive_data.keys[6] == NULL) { | 1030 | sensitive_data.keys[6] == NULL && |
1031 | sensitive_data.keys[7] == NULL && | ||
1032 | sensitive_data.keys[8] == NULL) { | ||
879 | sensitive_data.keys[1] = key_load_cert( | 1033 | sensitive_data.keys[1] = key_load_cert( |
880 | _PATH_HOST_DSA_KEY_FILE); | 1034 | _PATH_HOST_DSA_KEY_FILE); |
881 | #ifdef OPENSSL_HAS_ECC | 1035 | #ifdef OPENSSL_HAS_ECC |
@@ -884,14 +1038,18 @@ main(int ac, char **av) | |||
884 | #endif | 1038 | #endif |
885 | sensitive_data.keys[3] = key_load_cert( | 1039 | sensitive_data.keys[3] = key_load_cert( |
886 | _PATH_HOST_RSA_KEY_FILE); | 1040 | _PATH_HOST_RSA_KEY_FILE); |
887 | sensitive_data.keys[4] = key_load_public( | 1041 | sensitive_data.keys[4] = key_load_cert( |
1042 | _PATH_HOST_ED25519_KEY_FILE); | ||
1043 | sensitive_data.keys[5] = key_load_public( | ||
888 | _PATH_HOST_DSA_KEY_FILE, NULL); | 1044 | _PATH_HOST_DSA_KEY_FILE, NULL); |
889 | #ifdef OPENSSL_HAS_ECC | 1045 | #ifdef OPENSSL_HAS_ECC |
890 | sensitive_data.keys[5] = key_load_public( | 1046 | sensitive_data.keys[6] = key_load_public( |
891 | _PATH_HOST_ECDSA_KEY_FILE, NULL); | 1047 | _PATH_HOST_ECDSA_KEY_FILE, NULL); |
892 | #endif | 1048 | #endif |
893 | sensitive_data.keys[6] = key_load_public( | 1049 | sensitive_data.keys[7] = key_load_public( |
894 | _PATH_HOST_RSA_KEY_FILE, NULL); | 1050 | _PATH_HOST_RSA_KEY_FILE, NULL); |
1051 | sensitive_data.keys[8] = key_load_public( | ||
1052 | _PATH_HOST_ED25519_KEY_FILE, NULL); | ||
895 | sensitive_data.external_keysign = 1; | 1053 | sensitive_data.external_keysign = 1; |
896 | } | 1054 | } |
897 | } | 1055 | } |
@@ -1091,7 +1249,7 @@ ssh_init_stdio_forwarding(void) | |||
1091 | 1249 | ||
1092 | if (stdio_forward_host == NULL) | 1250 | if (stdio_forward_host == NULL) |
1093 | return; | 1251 | return; |
1094 | if (!compat20) | 1252 | if (!compat20) |
1095 | fatal("stdio forwarding require Protocol 2"); | 1253 | fatal("stdio forwarding require Protocol 2"); |
1096 | 1254 | ||
1097 | debug3("%s: %s:%d", __func__, stdio_forward_host, stdio_forward_port); | 1255 | debug3("%s: %s:%d", __func__, stdio_forward_host, stdio_forward_port); |
@@ -1263,7 +1421,7 @@ ssh_session(void) | |||
1263 | char *proto, *data; | 1421 | char *proto, *data; |
1264 | /* Get reasonable local authentication information. */ | 1422 | /* Get reasonable local authentication information. */ |
1265 | client_x11_get_proto(display, options.xauth_location, | 1423 | client_x11_get_proto(display, options.xauth_location, |
1266 | options.forward_x11_trusted, | 1424 | options.forward_x11_trusted, |
1267 | options.forward_x11_timeout, | 1425 | options.forward_x11_timeout, |
1268 | &proto, &data); | 1426 | &proto, &data); |
1269 | /* Request forwarding with authentication spoofing. */ | 1427 | /* Request forwarding with authentication spoofing. */ |
@@ -1635,4 +1793,3 @@ main_sigchld_handler(int sig) | |||
1635 | signal(sig, main_sigchld_handler); | 1793 | signal(sig, main_sigchld_handler); |
1636 | errno = save_errno; | 1794 | errno = save_errno; |
1637 | } | 1795 | } |
1638 | |||