diff options
Diffstat (limited to 'servconf.c')
-rw-r--r-- | servconf.c | 272 |
1 files changed, 233 insertions, 39 deletions
diff --git a/servconf.c b/servconf.c index 4464d51a5..470ad3619 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | /* $OpenBSD: servconf.c,v 1.352 2019/09/06 14:45:34 naddy Exp $ */ | 2 | /* $OpenBSD: servconf.c,v 1.360 2020/01/31 22:42:45 djm Exp $ */ |
3 | /* | 3 | /* |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
5 | * All rights reserved | 5 | * All rights reserved |
@@ -40,6 +40,11 @@ | |||
40 | #ifdef HAVE_UTIL_H | 40 | #ifdef HAVE_UTIL_H |
41 | #include <util.h> | 41 | #include <util.h> |
42 | #endif | 42 | #endif |
43 | #ifdef USE_SYSTEM_GLOB | ||
44 | # include <glob.h> | ||
45 | #else | ||
46 | # include "openbsd-compat/glob.h" | ||
47 | #endif | ||
43 | 48 | ||
44 | #include "openbsd-compat/sys-queue.h" | 49 | #include "openbsd-compat/sys-queue.h" |
45 | #include "xmalloc.h" | 50 | #include "xmalloc.h" |
@@ -70,6 +75,9 @@ static void add_listen_addr(ServerOptions *, const char *, | |||
70 | const char *, int); | 75 | const char *, int); |
71 | static void add_one_listen_addr(ServerOptions *, const char *, | 76 | static void add_one_listen_addr(ServerOptions *, const char *, |
72 | const char *, int); | 77 | const char *, int); |
78 | void parse_server_config_depth(ServerOptions *options, const char *filename, | ||
79 | struct sshbuf *conf, struct include_list *includes, | ||
80 | struct connection_info *connectinfo, int flags, int *activep, int depth); | ||
73 | 81 | ||
74 | /* Use of privilege separation or not */ | 82 | /* Use of privilege separation or not */ |
75 | extern int use_privsep; | 83 | extern int use_privsep; |
@@ -119,6 +127,7 @@ initialize_server_options(ServerOptions *options) | |||
119 | options->hostbased_key_types = NULL; | 127 | options->hostbased_key_types = NULL; |
120 | options->hostkeyalgorithms = NULL; | 128 | options->hostkeyalgorithms = NULL; |
121 | options->pubkey_authentication = -1; | 129 | options->pubkey_authentication = -1; |
130 | options->pubkey_auth_options = -1; | ||
122 | options->pubkey_key_types = NULL; | 131 | options->pubkey_key_types = NULL; |
123 | options->kerberos_authentication = -1; | 132 | options->kerberos_authentication = -1; |
124 | options->kerberos_or_local_passwd = -1; | 133 | options->kerberos_or_local_passwd = -1; |
@@ -174,6 +183,7 @@ initialize_server_options(ServerOptions *options) | |||
174 | options->authorized_keys_command = NULL; | 183 | options->authorized_keys_command = NULL; |
175 | options->authorized_keys_command_user = NULL; | 184 | options->authorized_keys_command_user = NULL; |
176 | options->revoked_keys_file = NULL; | 185 | options->revoked_keys_file = NULL; |
186 | options->sk_provider = NULL; | ||
177 | options->trusted_user_ca_keys = NULL; | 187 | options->trusted_user_ca_keys = NULL; |
178 | options->authorized_principals_file = NULL; | 188 | options->authorized_principals_file = NULL; |
179 | options->authorized_principals_command = NULL; | 189 | options->authorized_principals_command = NULL; |
@@ -198,6 +208,7 @@ static void | |||
198 | assemble_algorithms(ServerOptions *o) | 208 | assemble_algorithms(ServerOptions *o) |
199 | { | 209 | { |
200 | char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig; | 210 | char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig; |
211 | char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig; | ||
201 | int r; | 212 | int r; |
202 | 213 | ||
203 | all_cipher = cipher_alg_list(',', 0); | 214 | all_cipher = cipher_alg_list(',', 0); |
@@ -205,24 +216,35 @@ assemble_algorithms(ServerOptions *o) | |||
205 | all_kex = kex_alg_list(','); | 216 | all_kex = kex_alg_list(','); |
206 | all_key = sshkey_alg_list(0, 0, 1, ','); | 217 | all_key = sshkey_alg_list(0, 0, 1, ','); |
207 | all_sig = sshkey_alg_list(0, 1, 1, ','); | 218 | all_sig = sshkey_alg_list(0, 1, 1, ','); |
219 | /* remove unsupported algos from default lists */ | ||
220 | def_cipher = match_filter_whitelist(KEX_SERVER_ENCRYPT, all_cipher); | ||
221 | def_mac = match_filter_whitelist(KEX_SERVER_MAC, all_mac); | ||
222 | def_kex = match_filter_whitelist(KEX_SERVER_KEX, all_kex); | ||
223 | def_key = match_filter_whitelist(KEX_DEFAULT_PK_ALG, all_key); | ||
224 | def_sig = match_filter_whitelist(SSH_ALLOWED_CA_SIGALGS, all_sig); | ||
208 | #define ASSEMBLE(what, defaults, all) \ | 225 | #define ASSEMBLE(what, defaults, all) \ |
209 | do { \ | 226 | do { \ |
210 | if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ | 227 | if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ |
211 | fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ | 228 | fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ |
212 | } while (0) | 229 | } while (0) |
213 | ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher); | 230 | ASSEMBLE(ciphers, def_cipher, all_cipher); |
214 | ASSEMBLE(macs, KEX_SERVER_MAC, all_mac); | 231 | ASSEMBLE(macs, def_mac, all_mac); |
215 | ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); | 232 | ASSEMBLE(kex_algorithms, def_kex, all_kex); |
216 | ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key); | 233 | ASSEMBLE(hostkeyalgorithms, def_key, all_key); |
217 | ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); | 234 | ASSEMBLE(hostbased_key_types, def_key, all_key); |
218 | ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); | 235 | ASSEMBLE(pubkey_key_types, def_key, all_key); |
219 | ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig); | 236 | ASSEMBLE(ca_sign_algorithms, def_sig, all_sig); |
220 | #undef ASSEMBLE | 237 | #undef ASSEMBLE |
221 | free(all_cipher); | 238 | free(all_cipher); |
222 | free(all_mac); | 239 | free(all_mac); |
223 | free(all_kex); | 240 | free(all_kex); |
224 | free(all_key); | 241 | free(all_key); |
225 | free(all_sig); | 242 | free(all_sig); |
243 | free(def_cipher); | ||
244 | free(def_mac); | ||
245 | free(def_kex); | ||
246 | free(def_key); | ||
247 | free(def_sig); | ||
226 | } | 248 | } |
227 | 249 | ||
228 | static void | 250 | static void |
@@ -346,6 +368,8 @@ fill_default_server_options(ServerOptions *options) | |||
346 | options->hostbased_uses_name_from_packet_only = 0; | 368 | options->hostbased_uses_name_from_packet_only = 0; |
347 | if (options->pubkey_authentication == -1) | 369 | if (options->pubkey_authentication == -1) |
348 | options->pubkey_authentication = 1; | 370 | options->pubkey_authentication = 1; |
371 | if (options->pubkey_auth_options == -1) | ||
372 | options->pubkey_auth_options = 0; | ||
349 | if (options->kerberos_authentication == -1) | 373 | if (options->kerberos_authentication == -1) |
350 | options->kerberos_authentication = 0; | 374 | options->kerberos_authentication = 0; |
351 | if (options->kerberos_or_local_passwd == -1) | 375 | if (options->kerberos_or_local_passwd == -1) |
@@ -381,7 +405,12 @@ fill_default_server_options(ServerOptions *options) | |||
381 | options->permit_user_env_whitelist = NULL; | 405 | options->permit_user_env_whitelist = NULL; |
382 | } | 406 | } |
383 | if (options->compression == -1) | 407 | if (options->compression == -1) |
408 | #ifdef WITH_ZLIB | ||
384 | options->compression = COMP_DELAYED; | 409 | options->compression = COMP_DELAYED; |
410 | #else | ||
411 | options->compression = COMP_NONE; | ||
412 | #endif | ||
413 | |||
385 | if (options->rekey_limit == -1) | 414 | if (options->rekey_limit == -1) |
386 | options->rekey_limit = 0; | 415 | options->rekey_limit = 0; |
387 | if (options->rekey_interval == -1) | 416 | if (options->rekey_interval == -1) |
@@ -438,6 +467,8 @@ fill_default_server_options(ServerOptions *options) | |||
438 | options->disable_forwarding = 0; | 467 | options->disable_forwarding = 0; |
439 | if (options->expose_userauth_info == -1) | 468 | if (options->expose_userauth_info == -1) |
440 | options->expose_userauth_info = 0; | 469 | options->expose_userauth_info = 0; |
470 | if (options->sk_provider == NULL) | ||
471 | options->sk_provider = xstrdup("internal"); | ||
441 | if (options->debian_banner == -1) | 472 | if (options->debian_banner == -1) |
442 | options->debian_banner = 1; | 473 | options->debian_banner = 1; |
443 | 474 | ||
@@ -459,10 +490,12 @@ fill_default_server_options(ServerOptions *options) | |||
459 | CLEAR_ON_NONE(options->banner); | 490 | CLEAR_ON_NONE(options->banner); |
460 | CLEAR_ON_NONE(options->trusted_user_ca_keys); | 491 | CLEAR_ON_NONE(options->trusted_user_ca_keys); |
461 | CLEAR_ON_NONE(options->revoked_keys_file); | 492 | CLEAR_ON_NONE(options->revoked_keys_file); |
493 | CLEAR_ON_NONE(options->sk_provider); | ||
462 | CLEAR_ON_NONE(options->authorized_principals_file); | 494 | CLEAR_ON_NONE(options->authorized_principals_file); |
463 | CLEAR_ON_NONE(options->adm_forced_command); | 495 | CLEAR_ON_NONE(options->adm_forced_command); |
464 | CLEAR_ON_NONE(options->chroot_directory); | 496 | CLEAR_ON_NONE(options->chroot_directory); |
465 | CLEAR_ON_NONE(options->routing_domain); | 497 | CLEAR_ON_NONE(options->routing_domain); |
498 | CLEAR_ON_NONE(options->host_key_agent); | ||
466 | for (i = 0; i < options->num_host_key_files; i++) | 499 | for (i = 0; i < options->num_host_key_files; i++) |
467 | CLEAR_ON_NONE(options->host_key_files[i]); | 500 | CLEAR_ON_NONE(options->host_key_files[i]); |
468 | for (i = 0; i < options->num_host_cert_files; i++) | 501 | for (i = 0; i < options->num_host_cert_files; i++) |
@@ -517,7 +550,7 @@ typedef enum { | |||
517 | sAcceptEnv, sSetEnv, sPermitTunnel, | 550 | sAcceptEnv, sSetEnv, sPermitTunnel, |
518 | sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, | 551 | sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, |
519 | sUsePrivilegeSeparation, sAllowAgentForwarding, | 552 | sUsePrivilegeSeparation, sAllowAgentForwarding, |
520 | sHostCertificate, | 553 | sHostCertificate, sInclude, |
521 | sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, | 554 | sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
522 | sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, | 555 | sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, |
523 | sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum, | 556 | sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum, |
@@ -525,14 +558,15 @@ typedef enum { | |||
525 | sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, | 558 | sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, |
526 | sStreamLocalBindMask, sStreamLocalBindUnlink, | 559 | sStreamLocalBindMask, sStreamLocalBindUnlink, |
527 | sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, | 560 | sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, |
528 | sExposeAuthInfo, sRDomain, | 561 | sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, |
529 | sDebianBanner, | 562 | sDebianBanner, |
530 | sDeprecated, sIgnore, sUnsupported | 563 | sDeprecated, sIgnore, sUnsupported |
531 | } ServerOpCodes; | 564 | } ServerOpCodes; |
532 | 565 | ||
533 | #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ | 566 | #define SSHCFG_GLOBAL 0x01 /* allowed in main section of config */ |
534 | #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ | 567 | #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ |
535 | #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) | 568 | #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) |
569 | #define SSHCFG_NEVERMATCH 0x04 /* Match never matches; internal only */ | ||
536 | 570 | ||
537 | /* Textual representation of the tokens. */ | 571 | /* Textual representation of the tokens. */ |
538 | static struct { | 572 | static struct { |
@@ -568,6 +602,7 @@ static struct { | |||
568 | { "rsaauthentication", sDeprecated, SSHCFG_ALL }, | 602 | { "rsaauthentication", sDeprecated, SSHCFG_ALL }, |
569 | { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, | 603 | { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, |
570 | { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL }, | 604 | { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL }, |
605 | { "pubkeyauthoptions", sPubkeyAuthOptions, SSHCFG_ALL }, | ||
571 | { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ | 606 | { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ |
572 | #ifdef KRB5 | 607 | #ifdef KRB5 |
573 | { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, | 608 | { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, |
@@ -671,6 +706,7 @@ static struct { | |||
671 | { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, | 706 | { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, |
672 | { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, | 707 | { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, |
673 | { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, | 708 | { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, |
709 | { "include", sInclude, SSHCFG_ALL }, | ||
674 | { "ipqos", sIPQoS, SSHCFG_ALL }, | 710 | { "ipqos", sIPQoS, SSHCFG_ALL }, |
675 | { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, | 711 | { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, |
676 | { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, | 712 | { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, |
@@ -686,6 +722,7 @@ static struct { | |||
686 | { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, | 722 | { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, |
687 | { "rdomain", sRDomain, SSHCFG_ALL }, | 723 | { "rdomain", sRDomain, SSHCFG_ALL }, |
688 | { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, | 724 | { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, |
725 | { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, | ||
689 | { "debianbanner", sDebianBanner, SSHCFG_GLOBAL }, | 726 | { "debianbanner", sDebianBanner, SSHCFG_GLOBAL }, |
690 | { NULL, sBadOption, 0 } | 727 | { NULL, sBadOption, 0 } |
691 | }; | 728 | }; |
@@ -1220,8 +1257,10 @@ static const struct multistate multistate_permitrootlogin[] = { | |||
1220 | { NULL, -1 } | 1257 | { NULL, -1 } |
1221 | }; | 1258 | }; |
1222 | static const struct multistate multistate_compression[] = { | 1259 | static const struct multistate multistate_compression[] = { |
1260 | #ifdef WITH_ZLIB | ||
1223 | { "yes", COMP_DELAYED }, | 1261 | { "yes", COMP_DELAYED }, |
1224 | { "delayed", COMP_DELAYED }, | 1262 | { "delayed", COMP_DELAYED }, |
1263 | #endif | ||
1225 | { "no", COMP_NONE }, | 1264 | { "no", COMP_NONE }, |
1226 | { NULL, -1 } | 1265 | { NULL, -1 } |
1227 | }; | 1266 | }; |
@@ -1240,13 +1279,14 @@ static const struct multistate multistate_tcpfwd[] = { | |||
1240 | { NULL, -1 } | 1279 | { NULL, -1 } |
1241 | }; | 1280 | }; |
1242 | 1281 | ||
1243 | int | 1282 | static int |
1244 | process_server_config_line(ServerOptions *options, char *line, | 1283 | process_server_config_line_depth(ServerOptions *options, char *line, |
1245 | const char *filename, int linenum, int *activep, | 1284 | const char *filename, int linenum, int *activep, |
1246 | struct connection_info *connectinfo) | 1285 | struct connection_info *connectinfo, int inc_flags, int depth, |
1286 | struct include_list *includes) | ||
1247 | { | 1287 | { |
1248 | char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p; | 1288 | char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p; |
1249 | int cmdline = 0, *intptr, value, value2, n, port; | 1289 | int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found; |
1250 | SyslogFacility *log_facility_ptr; | 1290 | SyslogFacility *log_facility_ptr; |
1251 | LogLevel *log_level_ptr; | 1291 | LogLevel *log_level_ptr; |
1252 | ServerOpCodes opcode; | 1292 | ServerOpCodes opcode; |
@@ -1255,6 +1295,8 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1255 | long long val64; | 1295 | long long val64; |
1256 | const struct multistate *multistate_ptr; | 1296 | const struct multistate *multistate_ptr; |
1257 | const char *errstr; | 1297 | const char *errstr; |
1298 | struct include_item *item; | ||
1299 | glob_t gbuf; | ||
1258 | 1300 | ||
1259 | /* Strip trailing whitespace. Allow \f (form feed) at EOL only */ | 1301 | /* Strip trailing whitespace. Allow \f (form feed) at EOL only */ |
1260 | if ((len = strlen(line)) == 0) | 1302 | if ((len = strlen(line)) == 0) |
@@ -1281,7 +1323,7 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1281 | cmdline = 1; | 1323 | cmdline = 1; |
1282 | activep = &cmdline; | 1324 | activep = &cmdline; |
1283 | } | 1325 | } |
1284 | if (*activep && opcode != sMatch) | 1326 | if (*activep && opcode != sMatch && opcode != sInclude) |
1285 | debug3("%s:%d setting %s %s", filename, linenum, arg, cp); | 1327 | debug3("%s:%d setting %s %s", filename, linenum, arg, cp); |
1286 | if (*activep == 0 && !(flags & SSHCFG_MATCH)) { | 1328 | if (*activep == 0 && !(flags & SSHCFG_MATCH)) { |
1287 | if (connectinfo == NULL) { | 1329 | if (connectinfo == NULL) { |
@@ -1497,6 +1539,24 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1497 | charptr = &options->pubkey_key_types; | 1539 | charptr = &options->pubkey_key_types; |
1498 | goto parse_keytypes; | 1540 | goto parse_keytypes; |
1499 | 1541 | ||
1542 | case sPubkeyAuthOptions: | ||
1543 | intptr = &options->pubkey_auth_options; | ||
1544 | value = 0; | ||
1545 | while ((arg = strdelim(&cp)) && *arg != '\0') { | ||
1546 | if (strcasecmp(arg, "none") == 0) | ||
1547 | continue; | ||
1548 | if (strcasecmp(arg, "touch-required") == 0) | ||
1549 | value |= PUBKEYAUTH_TOUCH_REQUIRED; | ||
1550 | else { | ||
1551 | fatal("%s line %d: unsupported " | ||
1552 | "PubkeyAuthOptions option %s", | ||
1553 | filename, linenum, arg); | ||
1554 | } | ||
1555 | } | ||
1556 | if (*activep && *intptr == -1) | ||
1557 | *intptr = value; | ||
1558 | break; | ||
1559 | |||
1500 | case sKerberosAuthentication: | 1560 | case sKerberosAuthentication: |
1501 | intptr = &options->kerberos_authentication; | 1561 | intptr = &options->kerberos_authentication; |
1502 | goto parse_flag; | 1562 | goto parse_flag; |
@@ -1956,6 +2016,96 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1956 | *intptr = value; | 2016 | *intptr = value; |
1957 | break; | 2017 | break; |
1958 | 2018 | ||
2019 | case sInclude: | ||
2020 | if (cmdline) { | ||
2021 | fatal("Include directive not supported as a " | ||
2022 | "command-line option"); | ||
2023 | } | ||
2024 | value = 0; | ||
2025 | while ((arg2 = strdelim(&cp)) != NULL && *arg2 != '\0') { | ||
2026 | value++; | ||
2027 | found = 0; | ||
2028 | if (*arg2 != '/' && *arg2 != '~') { | ||
2029 | xasprintf(&arg, "%s/%s", SSHDIR, arg); | ||
2030 | } else | ||
2031 | arg = xstrdup(arg2); | ||
2032 | |||
2033 | /* | ||
2034 | * Don't let included files clobber the containing | ||
2035 | * file's Match state. | ||
2036 | */ | ||
2037 | oactive = *activep; | ||
2038 | |||
2039 | /* consult cache of include files */ | ||
2040 | TAILQ_FOREACH(item, includes, entry) { | ||
2041 | if (strcmp(item->selector, arg) != 0) | ||
2042 | continue; | ||
2043 | if (item->filename != NULL) { | ||
2044 | parse_server_config_depth(options, | ||
2045 | item->filename, item->contents, | ||
2046 | includes, connectinfo, | ||
2047 | (oactive ? 0 : SSHCFG_NEVERMATCH), | ||
2048 | activep, depth + 1); | ||
2049 | } | ||
2050 | found = 1; | ||
2051 | *activep = oactive; | ||
2052 | } | ||
2053 | if (found != 0) { | ||
2054 | free(arg); | ||
2055 | continue; | ||
2056 | } | ||
2057 | |||
2058 | /* requested glob was not in cache */ | ||
2059 | debug2("%s line %d: new include %s", | ||
2060 | filename, linenum, arg); | ||
2061 | if ((r = glob(arg, 0, NULL, &gbuf)) != 0) { | ||
2062 | if (r != GLOB_NOMATCH) { | ||
2063 | fatal("%s line %d: include \"%s\" " | ||
2064 | "glob failed", filename, | ||
2065 | linenum, arg); | ||
2066 | } | ||
2067 | /* | ||
2068 | * If no entry matched then record a | ||
2069 | * placeholder to skip later glob calls. | ||
2070 | */ | ||
2071 | debug2("%s line %d: no match for %s", | ||
2072 | filename, linenum, arg); | ||
2073 | item = xcalloc(1, sizeof(*item)); | ||
2074 | item->selector = strdup(arg); | ||
2075 | TAILQ_INSERT_TAIL(includes, | ||
2076 | item, entry); | ||
2077 | } | ||
2078 | if (gbuf.gl_pathc > INT_MAX) | ||
2079 | fatal("%s: too many glob results", __func__); | ||
2080 | for (n = 0; n < (int)gbuf.gl_pathc; n++) { | ||
2081 | debug2("%s line %d: including %s", | ||
2082 | filename, linenum, gbuf.gl_pathv[n]); | ||
2083 | item = xcalloc(1, sizeof(*item)); | ||
2084 | item->selector = strdup(arg); | ||
2085 | item->filename = strdup(gbuf.gl_pathv[n]); | ||
2086 | if ((item->contents = sshbuf_new()) == NULL) { | ||
2087 | fatal("%s: sshbuf_new failed", | ||
2088 | __func__); | ||
2089 | } | ||
2090 | load_server_config(item->filename, | ||
2091 | item->contents); | ||
2092 | parse_server_config_depth(options, | ||
2093 | item->filename, item->contents, | ||
2094 | includes, connectinfo, | ||
2095 | (oactive ? 0 : SSHCFG_NEVERMATCH), | ||
2096 | activep, depth + 1); | ||
2097 | *activep = oactive; | ||
2098 | TAILQ_INSERT_TAIL(includes, item, entry); | ||
2099 | } | ||
2100 | globfree(&gbuf); | ||
2101 | free(arg); | ||
2102 | } | ||
2103 | if (value == 0) { | ||
2104 | fatal("%s line %d: Include missing filename argument", | ||
2105 | filename, linenum); | ||
2106 | } | ||
2107 | break; | ||
2108 | |||
1959 | case sMatch: | 2109 | case sMatch: |
1960 | if (cmdline) | 2110 | if (cmdline) |
1961 | fatal("Match directive not supported as a command-line " | 2111 | fatal("Match directive not supported as a command-line " |
@@ -1964,7 +2114,7 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1964 | if (value < 0) | 2114 | if (value < 0) |
1965 | fatal("%s line %d: Bad Match condition", filename, | 2115 | fatal("%s line %d: Bad Match condition", filename, |
1966 | linenum); | 2116 | linenum); |
1967 | *activep = value; | 2117 | *activep = (inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; |
1968 | break; | 2118 | break; |
1969 | 2119 | ||
1970 | case sPermitListen: | 2120 | case sPermitListen: |
@@ -2052,6 +2202,21 @@ process_server_config_line(ServerOptions *options, char *line, | |||
2052 | charptr = &options->revoked_keys_file; | 2202 | charptr = &options->revoked_keys_file; |
2053 | goto parse_filename; | 2203 | goto parse_filename; |
2054 | 2204 | ||
2205 | case sSecurityKeyProvider: | ||
2206 | charptr = &options->sk_provider; | ||
2207 | arg = strdelim(&cp); | ||
2208 | if (!arg || *arg == '\0') | ||
2209 | fatal("%s line %d: missing file name.", | ||
2210 | filename, linenum); | ||
2211 | if (*activep && *charptr == NULL) { | ||
2212 | *charptr = strcasecmp(arg, "internal") == 0 ? | ||
2213 | xstrdup(arg) : derelativise_path(arg); | ||
2214 | /* increase optional counter */ | ||
2215 | if (intptr != NULL) | ||
2216 | *intptr = *intptr + 1; | ||
2217 | } | ||
2218 | break; | ||
2219 | |||
2055 | case sIPQoS: | 2220 | case sIPQoS: |
2056 | arg = strdelim(&cp); | 2221 | arg = strdelim(&cp); |
2057 | if ((value = parse_ipqos(arg)) == -1) | 2222 | if ((value = parse_ipqos(arg)) == -1) |
@@ -2247,6 +2412,16 @@ process_server_config_line(ServerOptions *options, char *line, | |||
2247 | return 0; | 2412 | return 0; |
2248 | } | 2413 | } |
2249 | 2414 | ||
2415 | int | ||
2416 | process_server_config_line(ServerOptions *options, char *line, | ||
2417 | const char *filename, int linenum, int *activep, | ||
2418 | struct connection_info *connectinfo, struct include_list *includes) | ||
2419 | { | ||
2420 | return process_server_config_line_depth(options, line, filename, | ||
2421 | linenum, activep, connectinfo, 0, 0, includes); | ||
2422 | } | ||
2423 | |||
2424 | |||
2250 | /* Reads the server configuration file. */ | 2425 | /* Reads the server configuration file. */ |
2251 | 2426 | ||
2252 | void | 2427 | void |
@@ -2285,12 +2460,13 @@ load_server_config(const char *filename, struct sshbuf *conf) | |||
2285 | 2460 | ||
2286 | void | 2461 | void |
2287 | parse_server_match_config(ServerOptions *options, | 2462 | parse_server_match_config(ServerOptions *options, |
2288 | struct connection_info *connectinfo) | 2463 | struct include_list *includes, struct connection_info *connectinfo) |
2289 | { | 2464 | { |
2290 | ServerOptions mo; | 2465 | ServerOptions mo; |
2291 | 2466 | ||
2292 | initialize_server_options(&mo); | 2467 | initialize_server_options(&mo); |
2293 | parse_server_config(&mo, "reprocess config", cfg, connectinfo); | 2468 | parse_server_config(&mo, "reprocess config", cfg, includes, |
2469 | connectinfo); | ||
2294 | copy_set_server_options(options, &mo, 0); | 2470 | copy_set_server_options(options, &mo, 0); |
2295 | } | 2471 | } |
2296 | 2472 | ||
@@ -2343,6 +2519,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | |||
2343 | M_CP_INTOPT(password_authentication); | 2519 | M_CP_INTOPT(password_authentication); |
2344 | M_CP_INTOPT(gss_authentication); | 2520 | M_CP_INTOPT(gss_authentication); |
2345 | M_CP_INTOPT(pubkey_authentication); | 2521 | M_CP_INTOPT(pubkey_authentication); |
2522 | M_CP_INTOPT(pubkey_auth_options); | ||
2346 | M_CP_INTOPT(kerberos_authentication); | 2523 | M_CP_INTOPT(kerberos_authentication); |
2347 | M_CP_INTOPT(hostbased_authentication); | 2524 | M_CP_INTOPT(hostbased_authentication); |
2348 | M_CP_INTOPT(hostbased_uses_name_from_packet_only); | 2525 | M_CP_INTOPT(hostbased_uses_name_from_packet_only); |
@@ -2433,22 +2610,27 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | |||
2433 | #undef M_CP_STROPT | 2610 | #undef M_CP_STROPT |
2434 | #undef M_CP_STRARRAYOPT | 2611 | #undef M_CP_STRARRAYOPT |
2435 | 2612 | ||
2613 | #define SERVCONF_MAX_DEPTH 16 | ||
2436 | void | 2614 | void |
2437 | parse_server_config(ServerOptions *options, const char *filename, | 2615 | parse_server_config_depth(ServerOptions *options, const char *filename, |
2438 | struct sshbuf *conf, struct connection_info *connectinfo) | 2616 | struct sshbuf *conf, struct include_list *includes, |
2617 | struct connection_info *connectinfo, int flags, int *activep, int depth) | ||
2439 | { | 2618 | { |
2440 | int active, linenum, bad_options = 0; | 2619 | int linenum, bad_options = 0; |
2441 | char *cp, *obuf, *cbuf; | 2620 | char *cp, *obuf, *cbuf; |
2442 | 2621 | ||
2622 | if (depth < 0 || depth > SERVCONF_MAX_DEPTH) | ||
2623 | fatal("Too many recursive configuration includes"); | ||
2624 | |||
2443 | debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf)); | 2625 | debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf)); |
2444 | 2626 | ||
2445 | if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) | 2627 | if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) |
2446 | fatal("%s: sshbuf_dup_string failed", __func__); | 2628 | fatal("%s: sshbuf_dup_string failed", __func__); |
2447 | active = connectinfo ? 0 : 1; | ||
2448 | linenum = 1; | 2629 | linenum = 1; |
2449 | while ((cp = strsep(&cbuf, "\n")) != NULL) { | 2630 | while ((cp = strsep(&cbuf, "\n")) != NULL) { |
2450 | if (process_server_config_line(options, cp, filename, | 2631 | if (process_server_config_line_depth(options, cp, |
2451 | linenum++, &active, connectinfo) != 0) | 2632 | filename, linenum++, activep, connectinfo, flags, |
2633 | depth, includes) != 0) | ||
2452 | bad_options++; | 2634 | bad_options++; |
2453 | } | 2635 | } |
2454 | free(obuf); | 2636 | free(obuf); |
@@ -2458,6 +2640,16 @@ parse_server_config(ServerOptions *options, const char *filename, | |||
2458 | process_queued_listen_addrs(options); | 2640 | process_queued_listen_addrs(options); |
2459 | } | 2641 | } |
2460 | 2642 | ||
2643 | void | ||
2644 | parse_server_config(ServerOptions *options, const char *filename, | ||
2645 | struct sshbuf *conf, struct include_list *includes, | ||
2646 | struct connection_info *connectinfo) | ||
2647 | { | ||
2648 | int active = connectinfo ? 0 : 1; | ||
2649 | parse_server_config_depth(options, filename, conf, includes, | ||
2650 | connectinfo, 0, &active, 0); | ||
2651 | } | ||
2652 | |||
2461 | static const char * | 2653 | static const char * |
2462 | fmt_multistate_int(int val, const struct multistate *m) | 2654 | fmt_multistate_int(int val, const struct multistate *m) |
2463 | { | 2655 | { |
@@ -2673,13 +2865,14 @@ dump_config(ServerOptions *o) | |||
2673 | /* string arguments */ | 2865 | /* string arguments */ |
2674 | dump_cfg_string(sPidFile, o->pid_file); | 2866 | dump_cfg_string(sPidFile, o->pid_file); |
2675 | dump_cfg_string(sXAuthLocation, o->xauth_location); | 2867 | dump_cfg_string(sXAuthLocation, o->xauth_location); |
2676 | dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); | 2868 | dump_cfg_string(sCiphers, o->ciphers); |
2677 | dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); | 2869 | dump_cfg_string(sMacs, o->macs); |
2678 | dump_cfg_string(sBanner, o->banner); | 2870 | dump_cfg_string(sBanner, o->banner); |
2679 | dump_cfg_string(sForceCommand, o->adm_forced_command); | 2871 | dump_cfg_string(sForceCommand, o->adm_forced_command); |
2680 | dump_cfg_string(sChrootDirectory, o->chroot_directory); | 2872 | dump_cfg_string(sChrootDirectory, o->chroot_directory); |
2681 | dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); | 2873 | dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); |
2682 | dump_cfg_string(sRevokedKeys, o->revoked_keys_file); | 2874 | dump_cfg_string(sRevokedKeys, o->revoked_keys_file); |
2875 | dump_cfg_string(sSecurityKeyProvider, o->sk_provider); | ||
2683 | dump_cfg_string(sAuthorizedPrincipalsFile, | 2876 | dump_cfg_string(sAuthorizedPrincipalsFile, |
2684 | o->authorized_principals_file); | 2877 | o->authorized_principals_file); |
2685 | dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0' | 2878 | dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0' |
@@ -2689,16 +2882,11 @@ dump_config(ServerOptions *o) | |||
2689 | dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); | 2882 | dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); |
2690 | dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); | 2883 | dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); |
2691 | dump_cfg_string(sHostKeyAgent, o->host_key_agent); | 2884 | dump_cfg_string(sHostKeyAgent, o->host_key_agent); |
2692 | dump_cfg_string(sKexAlgorithms, | 2885 | dump_cfg_string(sKexAlgorithms, o->kex_algorithms); |
2693 | o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); | 2886 | dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms); |
2694 | dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms ? | 2887 | dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types); |
2695 | o->ca_sign_algorithms : SSH_ALLOWED_CA_SIGALGS); | 2888 | dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms); |
2696 | dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? | 2889 | dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types); |
2697 | o->hostbased_key_types : KEX_DEFAULT_PK_ALG); | ||
2698 | dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? | ||
2699 | o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); | ||
2700 | dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? | ||
2701 | o->pubkey_key_types : KEX_DEFAULT_PK_ALG); | ||
2702 | dump_cfg_string(sRDomain, o->routing_domain); | 2890 | dump_cfg_string(sRDomain, o->routing_domain); |
2703 | 2891 | ||
2704 | /* string arguments requiring a lookup */ | 2892 | /* string arguments requiring a lookup */ |
@@ -2768,4 +2956,10 @@ dump_config(ServerOptions *o) | |||
2768 | o->permit_user_env_whitelist); | 2956 | o->permit_user_env_whitelist); |
2769 | } | 2957 | } |
2770 | 2958 | ||
2959 | printf("pubkeyauthoptions"); | ||
2960 | if (o->pubkey_auth_options == 0) | ||
2961 | printf(" none"); | ||
2962 | if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED) | ||
2963 | printf(" touch-required"); | ||
2964 | printf("\n"); | ||
2771 | } | 2965 | } |