diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 218 |
1 files changed, 141 insertions, 77 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.492 2017/09/12 06:32:07 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.506 2018/03/03 03:15:51 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 |
@@ -119,6 +119,7 @@ | |||
119 | #endif | 119 | #endif |
120 | #include "monitor_wrap.h" | 120 | #include "monitor_wrap.h" |
121 | #include "ssh-sandbox.h" | 121 | #include "ssh-sandbox.h" |
122 | #include "auth-options.h" | ||
122 | #include "version.h" | 123 | #include "version.h" |
123 | #include "ssherr.h" | 124 | #include "ssherr.h" |
124 | 125 | ||
@@ -144,7 +145,12 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; | |||
144 | */ | 145 | */ |
145 | int debug_flag = 0; | 146 | int debug_flag = 0; |
146 | 147 | ||
147 | /* Flag indicating that the daemon should only test the configuration and keys. */ | 148 | /* |
149 | * Indicating that the daemon should only test the configuration and keys. | ||
150 | * If test_flag > 1 ("-T" flag), then sshd will also dump the effective | ||
151 | * configuration, optionally using connection information provided by the | ||
152 | * "-C" flag. | ||
153 | */ | ||
148 | int test_flag = 0; | 154 | int test_flag = 0; |
149 | 155 | ||
150 | /* Flag indicating that the daemon is being started from inetd. */ | 156 | /* Flag indicating that the daemon is being started from inetd. */ |
@@ -227,6 +233,9 @@ static int privsep_chroot = 1; | |||
227 | /* global authentication context */ | 233 | /* global authentication context */ |
228 | Authctxt *the_authctxt = NULL; | 234 | Authctxt *the_authctxt = NULL; |
229 | 235 | ||
236 | /* global key/cert auth options. XXX move to permanent ssh->authctxt? */ | ||
237 | struct sshauthopt *auth_opts = NULL; | ||
238 | |||
230 | /* sshd_config buffer */ | 239 | /* sshd_config buffer */ |
231 | Buffer cfg; | 240 | Buffer cfg; |
232 | 241 | ||
@@ -278,7 +287,6 @@ sighup_handler(int sig) | |||
278 | int save_errno = errno; | 287 | int save_errno = errno; |
279 | 288 | ||
280 | received_sighup = 1; | 289 | received_sighup = 1; |
281 | signal(SIGHUP, sighup_handler); | ||
282 | errno = save_errno; | 290 | errno = save_errno; |
283 | } | 291 | } |
284 | 292 | ||
@@ -328,8 +336,6 @@ main_sigchld_handler(int sig) | |||
328 | while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || | 336 | while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || |
329 | (pid < 0 && errno == EINTR)) | 337 | (pid < 0 && errno == EINTR)) |
330 | ; | 338 | ; |
331 | |||
332 | signal(SIGCHLD, main_sigchld_handler); | ||
333 | errno = save_errno; | 339 | errno = save_errno; |
334 | } | 340 | } |
335 | 341 | ||
@@ -441,16 +447,12 @@ sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out) | |||
441 | logit("Client version \"%.100s\" uses unsafe RSA signature " | 447 | logit("Client version \"%.100s\" uses unsafe RSA signature " |
442 | "scheme; disabling use of RSA keys", remote_version); | 448 | "scheme; disabling use of RSA keys", remote_version); |
443 | } | 449 | } |
444 | if ((ssh->compat & SSH_BUG_DERIVEKEY) != 0) { | ||
445 | fatal("Client version \"%.100s\" uses unsafe key agreement; " | ||
446 | "refusing connection", remote_version); | ||
447 | } | ||
448 | 450 | ||
449 | chop(server_version_string); | 451 | chop(server_version_string); |
450 | debug("Local version string %.200s", server_version_string); | 452 | debug("Local version string %.200s", server_version_string); |
451 | 453 | ||
452 | if (remote_major != 2 || | 454 | if (remote_major != 2 && |
453 | (remote_major == 1 && remote_minor != 99)) { | 455 | !(remote_major == 1 && remote_minor == 99)) { |
454 | s = "Protocol major versions differ.\n"; | 456 | s = "Protocol major versions differ.\n"; |
455 | (void) atomicio(vwrite, sock_out, s, strlen(s)); | 457 | (void) atomicio(vwrite, sock_out, s, strlen(s)); |
456 | close(sock_in); | 458 | close(sock_in); |
@@ -467,7 +469,7 @@ sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out) | |||
467 | void | 469 | void |
468 | destroy_sensitive_data(void) | 470 | destroy_sensitive_data(void) |
469 | { | 471 | { |
470 | int i; | 472 | u_int i; |
471 | 473 | ||
472 | for (i = 0; i < options.num_host_key_files; i++) { | 474 | for (i = 0; i < options.num_host_key_files; i++) { |
473 | if (sensitive_data.host_keys[i]) { | 475 | if (sensitive_data.host_keys[i]) { |
@@ -486,7 +488,7 @@ void | |||
486 | demote_sensitive_data(void) | 488 | demote_sensitive_data(void) |
487 | { | 489 | { |
488 | struct sshkey *tmp; | 490 | struct sshkey *tmp; |
489 | int i; | 491 | u_int i; |
490 | 492 | ||
491 | for (i = 0; i < options.num_host_key_files; i++) { | 493 | for (i = 0; i < options.num_host_key_files; i++) { |
492 | if (sensitive_data.host_keys[i]) { | 494 | if (sensitive_data.host_keys[i]) { |
@@ -685,7 +687,7 @@ list_hostkey_types(void) | |||
685 | Buffer b; | 687 | Buffer b; |
686 | const char *p; | 688 | const char *p; |
687 | char *ret; | 689 | char *ret; |
688 | int i; | 690 | u_int i; |
689 | struct sshkey *key; | 691 | struct sshkey *key; |
690 | 692 | ||
691 | buffer_init(&b); | 693 | buffer_init(&b); |
@@ -707,6 +709,7 @@ list_hostkey_types(void) | |||
707 | case KEY_DSA: | 709 | case KEY_DSA: |
708 | case KEY_ECDSA: | 710 | case KEY_ECDSA: |
709 | case KEY_ED25519: | 711 | case KEY_ED25519: |
712 | case KEY_XMSS: | ||
710 | if (buffer_len(&b) > 0) | 713 | if (buffer_len(&b) > 0) |
711 | buffer_append(&b, ",", 1); | 714 | buffer_append(&b, ",", 1); |
712 | p = key_ssh_name(key); | 715 | p = key_ssh_name(key); |
@@ -728,6 +731,7 @@ list_hostkey_types(void) | |||
728 | case KEY_DSA_CERT: | 731 | case KEY_DSA_CERT: |
729 | case KEY_ECDSA_CERT: | 732 | case KEY_ECDSA_CERT: |
730 | case KEY_ED25519_CERT: | 733 | case KEY_ED25519_CERT: |
734 | case KEY_XMSS_CERT: | ||
731 | if (buffer_len(&b) > 0) | 735 | if (buffer_len(&b) > 0) |
732 | buffer_append(&b, ",", 1); | 736 | buffer_append(&b, ",", 1); |
733 | p = key_ssh_name(key); | 737 | p = key_ssh_name(key); |
@@ -745,7 +749,7 @@ list_hostkey_types(void) | |||
745 | static struct sshkey * | 749 | static struct sshkey * |
746 | get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) | 750 | get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) |
747 | { | 751 | { |
748 | int i; | 752 | u_int i; |
749 | struct sshkey *key; | 753 | struct sshkey *key; |
750 | 754 | ||
751 | for (i = 0; i < options.num_host_key_files; i++) { | 755 | for (i = 0; i < options.num_host_key_files; i++) { |
@@ -754,6 +758,7 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) | |||
754 | case KEY_DSA_CERT: | 758 | case KEY_DSA_CERT: |
755 | case KEY_ECDSA_CERT: | 759 | case KEY_ECDSA_CERT: |
756 | case KEY_ED25519_CERT: | 760 | case KEY_ED25519_CERT: |
761 | case KEY_XMSS_CERT: | ||
757 | key = sensitive_data.host_certificates[i]; | 762 | key = sensitive_data.host_certificates[i]; |
758 | break; | 763 | break; |
759 | default: | 764 | default: |
@@ -785,7 +790,7 @@ get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) | |||
785 | struct sshkey * | 790 | struct sshkey * |
786 | get_hostkey_by_index(int ind) | 791 | get_hostkey_by_index(int ind) |
787 | { | 792 | { |
788 | if (ind < 0 || ind >= options.num_host_key_files) | 793 | if (ind < 0 || (u_int)ind >= options.num_host_key_files) |
789 | return (NULL); | 794 | return (NULL); |
790 | return (sensitive_data.host_keys[ind]); | 795 | return (sensitive_data.host_keys[ind]); |
791 | } | 796 | } |
@@ -793,7 +798,7 @@ get_hostkey_by_index(int ind) | |||
793 | struct sshkey * | 798 | struct sshkey * |
794 | get_hostkey_public_by_index(int ind, struct ssh *ssh) | 799 | get_hostkey_public_by_index(int ind, struct ssh *ssh) |
795 | { | 800 | { |
796 | if (ind < 0 || ind >= options.num_host_key_files) | 801 | if (ind < 0 || (u_int)ind >= options.num_host_key_files) |
797 | return (NULL); | 802 | return (NULL); |
798 | return (sensitive_data.host_pubkeys[ind]); | 803 | return (sensitive_data.host_pubkeys[ind]); |
799 | } | 804 | } |
@@ -801,7 +806,7 @@ get_hostkey_public_by_index(int ind, struct ssh *ssh) | |||
801 | int | 806 | int |
802 | get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh) | 807 | get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh) |
803 | { | 808 | { |
804 | int i; | 809 | u_int i; |
805 | 810 | ||
806 | for (i = 0; i < options.num_host_key_files; i++) { | 811 | for (i = 0; i < options.num_host_key_files; i++) { |
807 | if (key_is_cert(key)) { | 812 | if (key_is_cert(key)) { |
@@ -830,7 +835,8 @@ notify_hostkeys(struct ssh *ssh) | |||
830 | { | 835 | { |
831 | struct sshbuf *buf; | 836 | struct sshbuf *buf; |
832 | struct sshkey *key; | 837 | struct sshkey *key; |
833 | int i, nkeys, r; | 838 | u_int i, nkeys; |
839 | int r; | ||
834 | char *fp; | 840 | char *fp; |
835 | 841 | ||
836 | /* Some clients cannot cope with the hostkeys message, skip those. */ | 842 | /* Some clients cannot cope with the hostkeys message, skip those. */ |
@@ -861,7 +867,7 @@ notify_hostkeys(struct ssh *ssh) | |||
861 | packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf)); | 867 | packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf)); |
862 | nkeys++; | 868 | nkeys++; |
863 | } | 869 | } |
864 | debug3("%s: sent %d hostkeys", __func__, nkeys); | 870 | debug3("%s: sent %u hostkeys", __func__, nkeys); |
865 | if (nkeys == 0) | 871 | if (nkeys == 0) |
866 | fatal("%s: no hostkeys", __func__); | 872 | fatal("%s: no hostkeys", __func__); |
867 | packet_send(); | 873 | packet_send(); |
@@ -1014,13 +1020,13 @@ server_accept_inetd(int *sock_in, int *sock_out) | |||
1014 | * Listen for TCP connections | 1020 | * Listen for TCP connections |
1015 | */ | 1021 | */ |
1016 | static void | 1022 | static void |
1017 | server_listen(void) | 1023 | listen_on_addrs(struct listenaddr *la) |
1018 | { | 1024 | { |
1019 | int ret, listen_sock, on = 1; | 1025 | int ret, listen_sock; |
1020 | struct addrinfo *ai; | 1026 | struct addrinfo *ai; |
1021 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; | 1027 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
1022 | 1028 | ||
1023 | for (ai = options.listen_addrs; ai; ai = ai->ai_next) { | 1029 | for (ai = la->addrs; ai; ai = ai->ai_next) { |
1024 | if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) | 1030 | if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) |
1025 | continue; | 1031 | continue; |
1026 | if (num_listen_socks >= MAX_LISTEN_SOCKS) | 1032 | if (num_listen_socks >= MAX_LISTEN_SOCKS) |
@@ -1050,13 +1056,13 @@ server_listen(void) | |||
1050 | close(listen_sock); | 1056 | close(listen_sock); |
1051 | continue; | 1057 | continue; |
1052 | } | 1058 | } |
1053 | /* | 1059 | /* Socket options */ |
1054 | * Set socket options. | 1060 | set_reuseaddr(listen_sock); |
1055 | * Allow local port reuse in TIME_WAIT. | 1061 | if (la->rdomain != NULL && |
1056 | */ | 1062 | set_rdomain(listen_sock, la->rdomain) == -1) { |
1057 | if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, | 1063 | close(listen_sock); |
1058 | &on, sizeof(on)) == -1) | 1064 | continue; |
1059 | error("setsockopt SO_REUSEADDR: %s", strerror(errno)); | 1065 | } |
1060 | 1066 | ||
1061 | /* Only communicate in IPv6 over AF_INET6 sockets. */ | 1067 | /* Only communicate in IPv6 over AF_INET6 sockets. */ |
1062 | if (ai->ai_family == AF_INET6) | 1068 | if (ai->ai_family == AF_INET6) |
@@ -1078,9 +1084,28 @@ server_listen(void) | |||
1078 | if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0) | 1084 | if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0) |
1079 | fatal("listen on [%s]:%s: %.100s", | 1085 | fatal("listen on [%s]:%s: %.100s", |
1080 | ntop, strport, strerror(errno)); | 1086 | ntop, strport, strerror(errno)); |
1081 | logit("Server listening on %s port %s.", ntop, strport); | 1087 | logit("Server listening on %s port %s%s%s.", |
1088 | ntop, strport, | ||
1089 | la->rdomain == NULL ? "" : " rdomain ", | ||
1090 | la->rdomain == NULL ? "" : la->rdomain); | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | static void | ||
1095 | server_listen(void) | ||
1096 | { | ||
1097 | u_int i; | ||
1098 | |||
1099 | for (i = 0; i < options.num_listen_addrs; i++) { | ||
1100 | listen_on_addrs(&options.listen_addrs[i]); | ||
1101 | freeaddrinfo(options.listen_addrs[i].addrs); | ||
1102 | free(options.listen_addrs[i].rdomain); | ||
1103 | memset(&options.listen_addrs[i], 0, | ||
1104 | sizeof(options.listen_addrs[i])); | ||
1082 | } | 1105 | } |
1083 | freeaddrinfo(options.listen_addrs); | 1106 | free(options.listen_addrs); |
1107 | options.listen_addrs = NULL; | ||
1108 | options.num_listen_addrs = 0; | ||
1084 | 1109 | ||
1085 | if (!num_listen_socks) | 1110 | if (!num_listen_socks) |
1086 | fatal("Cannot bind any address."); | 1111 | fatal("Cannot bind any address."); |
@@ -1348,6 +1373,46 @@ check_ip_options(struct ssh *ssh) | |||
1348 | #endif /* IP_OPTIONS */ | 1373 | #endif /* IP_OPTIONS */ |
1349 | } | 1374 | } |
1350 | 1375 | ||
1376 | /* Set the routing domain for this process */ | ||
1377 | static void | ||
1378 | set_process_rdomain(struct ssh *ssh, const char *name) | ||
1379 | { | ||
1380 | #if defined(HAVE_SYS_SET_PROCESS_RDOMAIN) | ||
1381 | if (name == NULL) | ||
1382 | return; /* default */ | ||
1383 | |||
1384 | if (strcmp(name, "%D") == 0) { | ||
1385 | /* "expands" to routing domain of connection */ | ||
1386 | if ((name = ssh_packet_rdomain_in(ssh)) == NULL) | ||
1387 | return; | ||
1388 | } | ||
1389 | /* NB. We don't pass 'ssh' to sys_set_process_rdomain() */ | ||
1390 | return sys_set_process_rdomain(name); | ||
1391 | #elif defined(__OpenBSD__) | ||
1392 | int rtable, ortable = getrtable(); | ||
1393 | const char *errstr; | ||
1394 | |||
1395 | if (name == NULL) | ||
1396 | return; /* default */ | ||
1397 | |||
1398 | if (strcmp(name, "%D") == 0) { | ||
1399 | /* "expands" to routing domain of connection */ | ||
1400 | if ((name = ssh_packet_rdomain_in(ssh)) == NULL) | ||
1401 | return; | ||
1402 | } | ||
1403 | |||
1404 | rtable = (int)strtonum(name, 0, 255, &errstr); | ||
1405 | if (errstr != NULL) /* Shouldn't happen */ | ||
1406 | fatal("Invalid routing domain \"%s\": %s", name, errstr); | ||
1407 | if (rtable != ortable && setrtable(rtable) != 0) | ||
1408 | fatal("Unable to set routing domain %d: %s", | ||
1409 | rtable, strerror(errno)); | ||
1410 | debug("%s: set routing domain %d (was %d)", __func__, rtable, ortable); | ||
1411 | #else /* defined(__OpenBSD__) */ | ||
1412 | fatal("Unable to set routing domain: not supported in this platform"); | ||
1413 | #endif | ||
1414 | } | ||
1415 | |||
1351 | /* | 1416 | /* |
1352 | * Main program for the daemon. | 1417 | * Main program for the daemon. |
1353 | */ | 1418 | */ |
@@ -1357,20 +1422,19 @@ main(int ac, char **av) | |||
1357 | struct ssh *ssh = NULL; | 1422 | struct ssh *ssh = NULL; |
1358 | extern char *optarg; | 1423 | extern char *optarg; |
1359 | extern int optind; | 1424 | extern int optind; |
1360 | int r, opt, i, j, on = 1, already_daemon; | 1425 | int r, opt, on = 1, already_daemon, remote_port; |
1361 | int sock_in = -1, sock_out = -1, newsock = -1; | 1426 | int sock_in = -1, sock_out = -1, newsock = -1; |
1362 | const char *remote_ip; | 1427 | const char *remote_ip, *rdomain; |
1363 | int remote_port; | ||
1364 | char *fp, *line, *laddr, *logfile = NULL; | 1428 | char *fp, *line, *laddr, *logfile = NULL; |
1365 | int config_s[2] = { -1 , -1 }; | 1429 | int config_s[2] = { -1 , -1 }; |
1366 | u_int n; | 1430 | u_int i, j; |
1367 | u_int64_t ibytes, obytes; | 1431 | u_int64_t ibytes, obytes; |
1368 | mode_t new_umask; | 1432 | mode_t new_umask; |
1369 | struct sshkey *key; | 1433 | struct sshkey *key; |
1370 | struct sshkey *pubkey; | 1434 | struct sshkey *pubkey; |
1371 | int keytype; | 1435 | int keytype; |
1372 | Authctxt *authctxt; | 1436 | Authctxt *authctxt; |
1373 | struct connection_info *connection_info = get_connection_info(0, 0); | 1437 | struct connection_info *connection_info = NULL; |
1374 | 1438 | ||
1375 | ssh_malloc_init(); /* must be called before any mallocs */ | 1439 | ssh_malloc_init(); /* must be called before any mallocs */ |
1376 | 1440 | ||
@@ -1383,7 +1447,7 @@ main(int ac, char **av) | |||
1383 | saved_argc = ac; | 1447 | saved_argc = ac; |
1384 | rexec_argc = ac; | 1448 | rexec_argc = ac; |
1385 | saved_argv = xcalloc(ac + 1, sizeof(*saved_argv)); | 1449 | saved_argv = xcalloc(ac + 1, sizeof(*saved_argv)); |
1386 | for (i = 0; i < ac; i++) | 1450 | for (i = 0; (int)i < ac; i++) |
1387 | saved_argv[i] = xstrdup(av[i]); | 1451 | saved_argv[i] = xstrdup(av[i]); |
1388 | saved_argv[i] = NULL; | 1452 | saved_argv[i] = NULL; |
1389 | 1453 | ||
@@ -1416,12 +1480,8 @@ main(int ac, char **av) | |||
1416 | config_file_name = optarg; | 1480 | config_file_name = optarg; |
1417 | break; | 1481 | break; |
1418 | case 'c': | 1482 | case 'c': |
1419 | if (options.num_host_cert_files >= MAX_HOSTCERTS) { | 1483 | servconf_add_hostcert("[command-line]", 0, |
1420 | fprintf(stderr, "too many host certificates.\n"); | 1484 | &options, optarg); |
1421 | exit(1); | ||
1422 | } | ||
1423 | options.host_cert_files[options.num_host_cert_files++] = | ||
1424 | derelativise_path(optarg); | ||
1425 | break; | 1485 | break; |
1426 | case 'd': | 1486 | case 'd': |
1427 | if (debug_flag == 0) { | 1487 | if (debug_flag == 0) { |
@@ -1480,12 +1540,8 @@ main(int ac, char **av) | |||
1480 | /* protocol 1, ignored */ | 1540 | /* protocol 1, ignored */ |
1481 | break; | 1541 | break; |
1482 | case 'h': | 1542 | case 'h': |
1483 | if (options.num_host_key_files >= MAX_HOSTKEYS) { | 1543 | servconf_add_hostkey("[command-line]", 0, |
1484 | fprintf(stderr, "too many host keys.\n"); | 1544 | &options, optarg); |
1485 | exit(1); | ||
1486 | } | ||
1487 | options.host_key_files[options.num_host_key_files++] = | ||
1488 | derelativise_path(optarg); | ||
1489 | break; | 1545 | break; |
1490 | case 't': | 1546 | case 't': |
1491 | test_flag = 1; | 1547 | test_flag = 1; |
@@ -1494,6 +1550,7 @@ main(int ac, char **av) | |||
1494 | test_flag = 2; | 1550 | test_flag = 2; |
1495 | break; | 1551 | break; |
1496 | case 'C': | 1552 | case 'C': |
1553 | connection_info = get_connection_info(0, 0); | ||
1497 | if (parse_server_match_testspec(connection_info, | 1554 | if (parse_server_match_testspec(connection_info, |
1498 | optarg) == -1) | 1555 | optarg) == -1) |
1499 | exit(1); | 1556 | exit(1); |
@@ -1552,24 +1609,13 @@ main(int ac, char **av) | |||
1552 | if (getenv("KRB5CCNAME") != NULL) | 1609 | if (getenv("KRB5CCNAME") != NULL) |
1553 | (void) unsetenv("KRB5CCNAME"); | 1610 | (void) unsetenv("KRB5CCNAME"); |
1554 | 1611 | ||
1555 | #ifdef _UNICOS | ||
1556 | /* Cray can define user privs drop all privs now! | ||
1557 | * Not needed on PRIV_SU systems! | ||
1558 | */ | ||
1559 | drop_cray_privs(); | ||
1560 | #endif | ||
1561 | |||
1562 | sensitive_data.have_ssh2_key = 0; | 1612 | sensitive_data.have_ssh2_key = 0; |
1563 | 1613 | ||
1564 | /* | 1614 | /* |
1565 | * If we're doing an extended config test, make sure we have all of | 1615 | * If we're not doing an extended test do not silently ignore connection |
1566 | * the parameters we need. If we're not doing an extended test, | 1616 | * test params. |
1567 | * do not silently ignore connection test params. | ||
1568 | */ | 1617 | */ |
1569 | if (test_flag >= 2 && server_match_spec_complete(connection_info) == 0) | 1618 | if (test_flag < 2 && connection_info != NULL) |
1570 | fatal("user, host and addr are all required when testing " | ||
1571 | "Match configs"); | ||
1572 | if (test_flag < 2 && server_match_spec_complete(connection_info) >= 0) | ||
1573 | fatal("Config test connection parameter (-C) provided without " | 1619 | fatal("Config test connection parameter (-C) provided without " |
1574 | "test mode (-T)"); | 1620 | "test mode (-T)"); |
1575 | 1621 | ||
@@ -1611,12 +1657,12 @@ main(int ac, char **av) | |||
1611 | * and warns for trivial misconfigurations that could break login. | 1657 | * and warns for trivial misconfigurations that could break login. |
1612 | */ | 1658 | */ |
1613 | if (options.num_auth_methods != 0) { | 1659 | if (options.num_auth_methods != 0) { |
1614 | for (n = 0; n < options.num_auth_methods; n++) { | 1660 | for (i = 0; i < options.num_auth_methods; i++) { |
1615 | if (auth2_methods_valid(options.auth_methods[n], | 1661 | if (auth2_methods_valid(options.auth_methods[i], |
1616 | 1) == 0) | 1662 | 1) == 0) |
1617 | break; | 1663 | break; |
1618 | } | 1664 | } |
1619 | if (n >= options.num_auth_methods) | 1665 | if (i >= options.num_auth_methods) |
1620 | fatal("AuthenticationMethods cannot be satisfied by " | 1666 | fatal("AuthenticationMethods cannot be satisfied by " |
1621 | "enabled authentication methods"); | 1667 | "enabled authentication methods"); |
1622 | } | 1668 | } |
@@ -1642,10 +1688,8 @@ main(int ac, char **av) | |||
1642 | fatal("Privilege separation user %s does not exist", | 1688 | fatal("Privilege separation user %s does not exist", |
1643 | SSH_PRIVSEP_USER); | 1689 | SSH_PRIVSEP_USER); |
1644 | } else { | 1690 | } else { |
1645 | explicit_bzero(privsep_pw->pw_passwd, | ||
1646 | strlen(privsep_pw->pw_passwd)); | ||
1647 | privsep_pw = pwcopy(privsep_pw); | 1691 | privsep_pw = pwcopy(privsep_pw); |
1648 | free(privsep_pw->pw_passwd); | 1692 | freezero(privsep_pw->pw_passwd, strlen(privsep_pw->pw_passwd)); |
1649 | privsep_pw->pw_passwd = xstrdup("*"); | 1693 | privsep_pw->pw_passwd = xstrdup("*"); |
1650 | } | 1694 | } |
1651 | endpwent(); | 1695 | endpwent(); |
@@ -1697,6 +1741,7 @@ main(int ac, char **av) | |||
1697 | case KEY_DSA: | 1741 | case KEY_DSA: |
1698 | case KEY_ECDSA: | 1742 | case KEY_ECDSA: |
1699 | case KEY_ED25519: | 1743 | case KEY_ED25519: |
1744 | case KEY_XMSS: | ||
1700 | if (have_agent || key != NULL) | 1745 | if (have_agent || key != NULL) |
1701 | sensitive_data.have_ssh2_key = 1; | 1746 | sensitive_data.have_ssh2_key = 1; |
1702 | break; | 1747 | break; |
@@ -1752,7 +1797,7 @@ main(int ac, char **av) | |||
1752 | continue; | 1797 | continue; |
1753 | } | 1798 | } |
1754 | sensitive_data.host_certificates[j] = key; | 1799 | sensitive_data.host_certificates[j] = key; |
1755 | debug("host certificate: #%d type %d %s", j, key->type, | 1800 | debug("host certificate: #%u type %d %s", j, key->type, |
1756 | key_type(key)); | 1801 | key_type(key)); |
1757 | } | 1802 | } |
1758 | 1803 | ||
@@ -1776,8 +1821,13 @@ main(int ac, char **av) | |||
1776 | } | 1821 | } |
1777 | 1822 | ||
1778 | if (test_flag > 1) { | 1823 | if (test_flag > 1) { |
1779 | if (server_match_spec_complete(connection_info) == 1) | 1824 | /* |
1780 | parse_server_match_config(&options, connection_info); | 1825 | * If no connection info was provided by -C then use |
1826 | * use a blank one that will cause no predicate to match. | ||
1827 | */ | ||
1828 | if (connection_info == NULL) | ||
1829 | connection_info = get_connection_info(0, 0); | ||
1830 | parse_server_match_config(&options, connection_info); | ||
1781 | dump_config(&options); | 1831 | dump_config(&options); |
1782 | } | 1832 | } |
1783 | 1833 | ||
@@ -1796,8 +1846,10 @@ main(int ac, char **av) | |||
1796 | debug("setgroups() failed: %.200s", strerror(errno)); | 1846 | debug("setgroups() failed: %.200s", strerror(errno)); |
1797 | 1847 | ||
1798 | if (rexec_flag) { | 1848 | if (rexec_flag) { |
1849 | if (rexec_argc < 0) | ||
1850 | fatal("rexec_argc %d < 0", rexec_argc); | ||
1799 | rexec_argv = xcalloc(rexec_argc + 2, sizeof(char *)); | 1851 | rexec_argv = xcalloc(rexec_argc + 2, sizeof(char *)); |
1800 | for (i = 0; i < rexec_argc; i++) { | 1852 | for (i = 0; i < (u_int)rexec_argc; i++) { |
1801 | debug("rexec_argv[%d]='%s'", i, saved_argv[i]); | 1853 | debug("rexec_argv[%d]='%s'", i, saved_argv[i]); |
1802 | rexec_argv[i] = saved_argv[i]; | 1854 | rexec_argv[i] = saved_argv[i]; |
1803 | } | 1855 | } |
@@ -1970,6 +2022,9 @@ main(int ac, char **av) | |||
1970 | cleanup_exit(255); | 2022 | cleanup_exit(255); |
1971 | } | 2023 | } |
1972 | 2024 | ||
2025 | if (options.routing_domain != NULL) | ||
2026 | set_process_rdomain(ssh, options.routing_domain); | ||
2027 | |||
1973 | /* | 2028 | /* |
1974 | * The rest of the code depends on the fact that | 2029 | * The rest of the code depends on the fact that |
1975 | * ssh_remote_ipaddr() caches the remote ip, even if | 2030 | * ssh_remote_ipaddr() caches the remote ip, even if |
@@ -1981,10 +2036,15 @@ main(int ac, char **av) | |||
1981 | audit_connection_from(remote_ip, remote_port); | 2036 | audit_connection_from(remote_ip, remote_port); |
1982 | #endif | 2037 | #endif |
1983 | 2038 | ||
2039 | rdomain = ssh_packet_rdomain_in(ssh); | ||
2040 | |||
1984 | /* Log the connection. */ | 2041 | /* Log the connection. */ |
1985 | laddr = get_local_ipaddr(sock_in); | 2042 | laddr = get_local_ipaddr(sock_in); |
1986 | verbose("Connection from %s port %d on %s port %d", | 2043 | verbose("Connection from %s port %d on %s port %d%s%s%s", |
1987 | remote_ip, remote_port, laddr, ssh_local_port(ssh)); | 2044 | remote_ip, remote_port, laddr, ssh_local_port(ssh), |
2045 | rdomain == NULL ? "" : " rdomain \"", | ||
2046 | rdomain == NULL ? "" : rdomain, | ||
2047 | rdomain == NULL ? "" : "\""); | ||
1988 | free(laddr); | 2048 | free(laddr); |
1989 | 2049 | ||
1990 | /* | 2050 | /* |
@@ -2010,6 +2070,10 @@ main(int ac, char **av) | |||
2010 | /* XXX global for cleanup, access from other modules */ | 2070 | /* XXX global for cleanup, access from other modules */ |
2011 | the_authctxt = authctxt; | 2071 | the_authctxt = authctxt; |
2012 | 2072 | ||
2073 | /* Set default key authentication options */ | ||
2074 | if ((auth_opts = sshauthopt_new_with_keys_defaults()) == NULL) | ||
2075 | fatal("allocation failed"); | ||
2076 | |||
2013 | /* prepare buffer to collect messages to display to user after login */ | 2077 | /* prepare buffer to collect messages to display to user after login */ |
2014 | buffer_init(&loginmsg); | 2078 | buffer_init(&loginmsg); |
2015 | auth_debug_reset(); | 2079 | auth_debug_reset(); |
@@ -2066,7 +2130,7 @@ main(int ac, char **av) | |||
2066 | #ifdef USE_PAM | 2130 | #ifdef USE_PAM |
2067 | if (options.use_pam) { | 2131 | if (options.use_pam) { |
2068 | do_pam_setcred(1); | 2132 | do_pam_setcred(1); |
2069 | do_pam_session(); | 2133 | do_pam_session(ssh); |
2070 | } | 2134 | } |
2071 | #endif | 2135 | #endif |
2072 | 2136 | ||