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 e76f9c39e..70f5f73f0 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" |
@@ -69,6 +74,9 @@ static void add_listen_addr(ServerOptions *, const char *, | |||
69 | const char *, int); | 74 | const char *, int); |
70 | static void add_one_listen_addr(ServerOptions *, const char *, | 75 | static void add_one_listen_addr(ServerOptions *, const char *, |
71 | const char *, int); | 76 | const char *, int); |
77 | void parse_server_config_depth(ServerOptions *options, const char *filename, | ||
78 | struct sshbuf *conf, struct include_list *includes, | ||
79 | struct connection_info *connectinfo, int flags, int *activep, int depth); | ||
72 | 80 | ||
73 | /* Use of privilege separation or not */ | 81 | /* Use of privilege separation or not */ |
74 | extern int use_privsep; | 82 | extern int use_privsep; |
@@ -118,6 +126,7 @@ initialize_server_options(ServerOptions *options) | |||
118 | options->hostbased_key_types = NULL; | 126 | options->hostbased_key_types = NULL; |
119 | options->hostkeyalgorithms = NULL; | 127 | options->hostkeyalgorithms = NULL; |
120 | options->pubkey_authentication = -1; | 128 | options->pubkey_authentication = -1; |
129 | options->pubkey_auth_options = -1; | ||
121 | options->pubkey_key_types = NULL; | 130 | options->pubkey_key_types = NULL; |
122 | options->kerberos_authentication = -1; | 131 | options->kerberos_authentication = -1; |
123 | options->kerberos_or_local_passwd = -1; | 132 | options->kerberos_or_local_passwd = -1; |
@@ -170,6 +179,7 @@ initialize_server_options(ServerOptions *options) | |||
170 | options->authorized_keys_command = NULL; | 179 | options->authorized_keys_command = NULL; |
171 | options->authorized_keys_command_user = NULL; | 180 | options->authorized_keys_command_user = NULL; |
172 | options->revoked_keys_file = NULL; | 181 | options->revoked_keys_file = NULL; |
182 | options->sk_provider = NULL; | ||
173 | options->trusted_user_ca_keys = NULL; | 183 | options->trusted_user_ca_keys = NULL; |
174 | options->authorized_principals_file = NULL; | 184 | options->authorized_principals_file = NULL; |
175 | options->authorized_principals_command = NULL; | 185 | options->authorized_principals_command = NULL; |
@@ -193,6 +203,7 @@ static void | |||
193 | assemble_algorithms(ServerOptions *o) | 203 | assemble_algorithms(ServerOptions *o) |
194 | { | 204 | { |
195 | char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig; | 205 | char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig; |
206 | char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig; | ||
196 | int r; | 207 | int r; |
197 | 208 | ||
198 | all_cipher = cipher_alg_list(',', 0); | 209 | all_cipher = cipher_alg_list(',', 0); |
@@ -200,24 +211,35 @@ assemble_algorithms(ServerOptions *o) | |||
200 | all_kex = kex_alg_list(','); | 211 | all_kex = kex_alg_list(','); |
201 | all_key = sshkey_alg_list(0, 0, 1, ','); | 212 | all_key = sshkey_alg_list(0, 0, 1, ','); |
202 | all_sig = sshkey_alg_list(0, 1, 1, ','); | 213 | all_sig = sshkey_alg_list(0, 1, 1, ','); |
214 | /* remove unsupported algos from default lists */ | ||
215 | def_cipher = match_filter_whitelist(KEX_SERVER_ENCRYPT, all_cipher); | ||
216 | def_mac = match_filter_whitelist(KEX_SERVER_MAC, all_mac); | ||
217 | def_kex = match_filter_whitelist(KEX_SERVER_KEX, all_kex); | ||
218 | def_key = match_filter_whitelist(KEX_DEFAULT_PK_ALG, all_key); | ||
219 | def_sig = match_filter_whitelist(SSH_ALLOWED_CA_SIGALGS, all_sig); | ||
203 | #define ASSEMBLE(what, defaults, all) \ | 220 | #define ASSEMBLE(what, defaults, all) \ |
204 | do { \ | 221 | do { \ |
205 | if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ | 222 | if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ |
206 | fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ | 223 | fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ |
207 | } while (0) | 224 | } while (0) |
208 | ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher); | 225 | ASSEMBLE(ciphers, def_cipher, all_cipher); |
209 | ASSEMBLE(macs, KEX_SERVER_MAC, all_mac); | 226 | ASSEMBLE(macs, def_mac, all_mac); |
210 | ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); | 227 | ASSEMBLE(kex_algorithms, def_kex, all_kex); |
211 | ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key); | 228 | ASSEMBLE(hostkeyalgorithms, def_key, all_key); |
212 | ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); | 229 | ASSEMBLE(hostbased_key_types, def_key, all_key); |
213 | ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); | 230 | ASSEMBLE(pubkey_key_types, def_key, all_key); |
214 | ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig); | 231 | ASSEMBLE(ca_sign_algorithms, def_sig, all_sig); |
215 | #undef ASSEMBLE | 232 | #undef ASSEMBLE |
216 | free(all_cipher); | 233 | free(all_cipher); |
217 | free(all_mac); | 234 | free(all_mac); |
218 | free(all_kex); | 235 | free(all_kex); |
219 | free(all_key); | 236 | free(all_key); |
220 | free(all_sig); | 237 | free(all_sig); |
238 | free(def_cipher); | ||
239 | free(def_mac); | ||
240 | free(def_kex); | ||
241 | free(def_key); | ||
242 | free(def_sig); | ||
221 | } | 243 | } |
222 | 244 | ||
223 | static void | 245 | static void |
@@ -341,6 +363,8 @@ fill_default_server_options(ServerOptions *options) | |||
341 | options->hostbased_uses_name_from_packet_only = 0; | 363 | options->hostbased_uses_name_from_packet_only = 0; |
342 | if (options->pubkey_authentication == -1) | 364 | if (options->pubkey_authentication == -1) |
343 | options->pubkey_authentication = 1; | 365 | options->pubkey_authentication = 1; |
366 | if (options->pubkey_auth_options == -1) | ||
367 | options->pubkey_auth_options = 0; | ||
344 | if (options->kerberos_authentication == -1) | 368 | if (options->kerberos_authentication == -1) |
345 | options->kerberos_authentication = 0; | 369 | options->kerberos_authentication = 0; |
346 | if (options->kerberos_or_local_passwd == -1) | 370 | if (options->kerberos_or_local_passwd == -1) |
@@ -368,7 +392,12 @@ fill_default_server_options(ServerOptions *options) | |||
368 | options->permit_user_env_whitelist = NULL; | 392 | options->permit_user_env_whitelist = NULL; |
369 | } | 393 | } |
370 | if (options->compression == -1) | 394 | if (options->compression == -1) |
395 | #ifdef WITH_ZLIB | ||
371 | options->compression = COMP_DELAYED; | 396 | options->compression = COMP_DELAYED; |
397 | #else | ||
398 | options->compression = COMP_NONE; | ||
399 | #endif | ||
400 | |||
372 | if (options->rekey_limit == -1) | 401 | if (options->rekey_limit == -1) |
373 | options->rekey_limit = 0; | 402 | options->rekey_limit = 0; |
374 | if (options->rekey_interval == -1) | 403 | if (options->rekey_interval == -1) |
@@ -425,6 +454,8 @@ fill_default_server_options(ServerOptions *options) | |||
425 | options->disable_forwarding = 0; | 454 | options->disable_forwarding = 0; |
426 | if (options->expose_userauth_info == -1) | 455 | if (options->expose_userauth_info == -1) |
427 | options->expose_userauth_info = 0; | 456 | options->expose_userauth_info = 0; |
457 | if (options->sk_provider == NULL) | ||
458 | options->sk_provider = xstrdup("internal"); | ||
428 | 459 | ||
429 | assemble_algorithms(options); | 460 | assemble_algorithms(options); |
430 | 461 | ||
@@ -444,10 +475,12 @@ fill_default_server_options(ServerOptions *options) | |||
444 | CLEAR_ON_NONE(options->banner); | 475 | CLEAR_ON_NONE(options->banner); |
445 | CLEAR_ON_NONE(options->trusted_user_ca_keys); | 476 | CLEAR_ON_NONE(options->trusted_user_ca_keys); |
446 | CLEAR_ON_NONE(options->revoked_keys_file); | 477 | CLEAR_ON_NONE(options->revoked_keys_file); |
478 | CLEAR_ON_NONE(options->sk_provider); | ||
447 | CLEAR_ON_NONE(options->authorized_principals_file); | 479 | CLEAR_ON_NONE(options->authorized_principals_file); |
448 | CLEAR_ON_NONE(options->adm_forced_command); | 480 | CLEAR_ON_NONE(options->adm_forced_command); |
449 | CLEAR_ON_NONE(options->chroot_directory); | 481 | CLEAR_ON_NONE(options->chroot_directory); |
450 | CLEAR_ON_NONE(options->routing_domain); | 482 | CLEAR_ON_NONE(options->routing_domain); |
483 | CLEAR_ON_NONE(options->host_key_agent); | ||
451 | for (i = 0; i < options->num_host_key_files; i++) | 484 | for (i = 0; i < options->num_host_key_files; i++) |
452 | CLEAR_ON_NONE(options->host_key_files[i]); | 485 | CLEAR_ON_NONE(options->host_key_files[i]); |
453 | for (i = 0; i < options->num_host_cert_files; i++) | 486 | for (i = 0; i < options->num_host_cert_files; i++) |
@@ -501,7 +534,7 @@ typedef enum { | |||
501 | sAcceptEnv, sSetEnv, sPermitTunnel, | 534 | sAcceptEnv, sSetEnv, sPermitTunnel, |
502 | sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, | 535 | sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, |
503 | sUsePrivilegeSeparation, sAllowAgentForwarding, | 536 | sUsePrivilegeSeparation, sAllowAgentForwarding, |
504 | sHostCertificate, | 537 | sHostCertificate, sInclude, |
505 | sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, | 538 | sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
506 | sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, | 539 | sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, |
507 | sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum, | 540 | sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum, |
@@ -509,13 +542,14 @@ typedef enum { | |||
509 | sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, | 542 | sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, |
510 | sStreamLocalBindMask, sStreamLocalBindUnlink, | 543 | sStreamLocalBindMask, sStreamLocalBindUnlink, |
511 | sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, | 544 | sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, |
512 | sExposeAuthInfo, sRDomain, | 545 | sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, |
513 | sDeprecated, sIgnore, sUnsupported | 546 | sDeprecated, sIgnore, sUnsupported |
514 | } ServerOpCodes; | 547 | } ServerOpCodes; |
515 | 548 | ||
516 | #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ | 549 | #define SSHCFG_GLOBAL 0x01 /* allowed in main section of config */ |
517 | #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ | 550 | #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ |
518 | #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) | 551 | #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) |
552 | #define SSHCFG_NEVERMATCH 0x04 /* Match never matches; internal only */ | ||
519 | 553 | ||
520 | /* Textual representation of the tokens. */ | 554 | /* Textual representation of the tokens. */ |
521 | static struct { | 555 | static struct { |
@@ -551,6 +585,7 @@ static struct { | |||
551 | { "rsaauthentication", sDeprecated, SSHCFG_ALL }, | 585 | { "rsaauthentication", sDeprecated, SSHCFG_ALL }, |
552 | { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, | 586 | { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, |
553 | { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL }, | 587 | { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL }, |
588 | { "pubkeyauthoptions", sPubkeyAuthOptions, SSHCFG_ALL }, | ||
554 | { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ | 589 | { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ |
555 | #ifdef KRB5 | 590 | #ifdef KRB5 |
556 | { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, | 591 | { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, |
@@ -643,6 +678,7 @@ static struct { | |||
643 | { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, | 678 | { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, |
644 | { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, | 679 | { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, |
645 | { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, | 680 | { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, |
681 | { "include", sInclude, SSHCFG_ALL }, | ||
646 | { "ipqos", sIPQoS, SSHCFG_ALL }, | 682 | { "ipqos", sIPQoS, SSHCFG_ALL }, |
647 | { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, | 683 | { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, |
648 | { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, | 684 | { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, |
@@ -658,6 +694,7 @@ static struct { | |||
658 | { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, | 694 | { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, |
659 | { "rdomain", sRDomain, SSHCFG_ALL }, | 695 | { "rdomain", sRDomain, SSHCFG_ALL }, |
660 | { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, | 696 | { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, |
697 | { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, | ||
661 | { NULL, sBadOption, 0 } | 698 | { NULL, sBadOption, 0 } |
662 | }; | 699 | }; |
663 | 700 | ||
@@ -1191,8 +1228,10 @@ static const struct multistate multistate_permitrootlogin[] = { | |||
1191 | { NULL, -1 } | 1228 | { NULL, -1 } |
1192 | }; | 1229 | }; |
1193 | static const struct multistate multistate_compression[] = { | 1230 | static const struct multistate multistate_compression[] = { |
1231 | #ifdef WITH_ZLIB | ||
1194 | { "yes", COMP_DELAYED }, | 1232 | { "yes", COMP_DELAYED }, |
1195 | { "delayed", COMP_DELAYED }, | 1233 | { "delayed", COMP_DELAYED }, |
1234 | #endif | ||
1196 | { "no", COMP_NONE }, | 1235 | { "no", COMP_NONE }, |
1197 | { NULL, -1 } | 1236 | { NULL, -1 } |
1198 | }; | 1237 | }; |
@@ -1211,13 +1250,14 @@ static const struct multistate multistate_tcpfwd[] = { | |||
1211 | { NULL, -1 } | 1250 | { NULL, -1 } |
1212 | }; | 1251 | }; |
1213 | 1252 | ||
1214 | int | 1253 | static int |
1215 | process_server_config_line(ServerOptions *options, char *line, | 1254 | process_server_config_line_depth(ServerOptions *options, char *line, |
1216 | const char *filename, int linenum, int *activep, | 1255 | const char *filename, int linenum, int *activep, |
1217 | struct connection_info *connectinfo) | 1256 | struct connection_info *connectinfo, int inc_flags, int depth, |
1257 | struct include_list *includes) | ||
1218 | { | 1258 | { |
1219 | char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p; | 1259 | char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p; |
1220 | int cmdline = 0, *intptr, value, value2, n, port; | 1260 | int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found; |
1221 | SyslogFacility *log_facility_ptr; | 1261 | SyslogFacility *log_facility_ptr; |
1222 | LogLevel *log_level_ptr; | 1262 | LogLevel *log_level_ptr; |
1223 | ServerOpCodes opcode; | 1263 | ServerOpCodes opcode; |
@@ -1226,6 +1266,8 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1226 | long long val64; | 1266 | long long val64; |
1227 | const struct multistate *multistate_ptr; | 1267 | const struct multistate *multistate_ptr; |
1228 | const char *errstr; | 1268 | const char *errstr; |
1269 | struct include_item *item; | ||
1270 | glob_t gbuf; | ||
1229 | 1271 | ||
1230 | /* Strip trailing whitespace. Allow \f (form feed) at EOL only */ | 1272 | /* Strip trailing whitespace. Allow \f (form feed) at EOL only */ |
1231 | if ((len = strlen(line)) == 0) | 1273 | if ((len = strlen(line)) == 0) |
@@ -1252,7 +1294,7 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1252 | cmdline = 1; | 1294 | cmdline = 1; |
1253 | activep = &cmdline; | 1295 | activep = &cmdline; |
1254 | } | 1296 | } |
1255 | if (*activep && opcode != sMatch) | 1297 | if (*activep && opcode != sMatch && opcode != sInclude) |
1256 | debug3("%s:%d setting %s %s", filename, linenum, arg, cp); | 1298 | debug3("%s:%d setting %s %s", filename, linenum, arg, cp); |
1257 | if (*activep == 0 && !(flags & SSHCFG_MATCH)) { | 1299 | if (*activep == 0 && !(flags & SSHCFG_MATCH)) { |
1258 | if (connectinfo == NULL) { | 1300 | if (connectinfo == NULL) { |
@@ -1468,6 +1510,24 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1468 | charptr = &options->pubkey_key_types; | 1510 | charptr = &options->pubkey_key_types; |
1469 | goto parse_keytypes; | 1511 | goto parse_keytypes; |
1470 | 1512 | ||
1513 | case sPubkeyAuthOptions: | ||
1514 | intptr = &options->pubkey_auth_options; | ||
1515 | value = 0; | ||
1516 | while ((arg = strdelim(&cp)) && *arg != '\0') { | ||
1517 | if (strcasecmp(arg, "none") == 0) | ||
1518 | continue; | ||
1519 | if (strcasecmp(arg, "touch-required") == 0) | ||
1520 | value |= PUBKEYAUTH_TOUCH_REQUIRED; | ||
1521 | else { | ||
1522 | fatal("%s line %d: unsupported " | ||
1523 | "PubkeyAuthOptions option %s", | ||
1524 | filename, linenum, arg); | ||
1525 | } | ||
1526 | } | ||
1527 | if (*activep && *intptr == -1) | ||
1528 | *intptr = value; | ||
1529 | break; | ||
1530 | |||
1471 | case sKerberosAuthentication: | 1531 | case sKerberosAuthentication: |
1472 | intptr = &options->kerberos_authentication; | 1532 | intptr = &options->kerberos_authentication; |
1473 | goto parse_flag; | 1533 | goto parse_flag; |
@@ -1907,6 +1967,96 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1907 | *intptr = value; | 1967 | *intptr = value; |
1908 | break; | 1968 | break; |
1909 | 1969 | ||
1970 | case sInclude: | ||
1971 | if (cmdline) { | ||
1972 | fatal("Include directive not supported as a " | ||
1973 | "command-line option"); | ||
1974 | } | ||
1975 | value = 0; | ||
1976 | while ((arg2 = strdelim(&cp)) != NULL && *arg2 != '\0') { | ||
1977 | value++; | ||
1978 | found = 0; | ||
1979 | if (*arg2 != '/' && *arg2 != '~') { | ||
1980 | xasprintf(&arg, "%s/%s", SSHDIR, arg); | ||
1981 | } else | ||
1982 | arg = xstrdup(arg2); | ||
1983 | |||
1984 | /* | ||
1985 | * Don't let included files clobber the containing | ||
1986 | * file's Match state. | ||
1987 | */ | ||
1988 | oactive = *activep; | ||
1989 | |||
1990 | /* consult cache of include files */ | ||
1991 | TAILQ_FOREACH(item, includes, entry) { | ||
1992 | if (strcmp(item->selector, arg) != 0) | ||
1993 | continue; | ||
1994 | if (item->filename != NULL) { | ||
1995 | parse_server_config_depth(options, | ||
1996 | item->filename, item->contents, | ||
1997 | includes, connectinfo, | ||
1998 | (oactive ? 0 : SSHCFG_NEVERMATCH), | ||
1999 | activep, depth + 1); | ||
2000 | } | ||
2001 | found = 1; | ||
2002 | *activep = oactive; | ||
2003 | } | ||
2004 | if (found != 0) { | ||
2005 | free(arg); | ||
2006 | continue; | ||
2007 | } | ||
2008 | |||
2009 | /* requested glob was not in cache */ | ||
2010 | debug2("%s line %d: new include %s", | ||
2011 | filename, linenum, arg); | ||
2012 | if ((r = glob(arg, 0, NULL, &gbuf)) != 0) { | ||
2013 | if (r != GLOB_NOMATCH) { | ||
2014 | fatal("%s line %d: include \"%s\" " | ||
2015 | "glob failed", filename, | ||
2016 | linenum, arg); | ||
2017 | } | ||
2018 | /* | ||
2019 | * If no entry matched then record a | ||
2020 | * placeholder to skip later glob calls. | ||
2021 | */ | ||
2022 | debug2("%s line %d: no match for %s", | ||
2023 | filename, linenum, arg); | ||
2024 | item = xcalloc(1, sizeof(*item)); | ||
2025 | item->selector = strdup(arg); | ||
2026 | TAILQ_INSERT_TAIL(includes, | ||
2027 | item, entry); | ||
2028 | } | ||
2029 | if (gbuf.gl_pathc > INT_MAX) | ||
2030 | fatal("%s: too many glob results", __func__); | ||
2031 | for (n = 0; n < (int)gbuf.gl_pathc; n++) { | ||
2032 | debug2("%s line %d: including %s", | ||
2033 | filename, linenum, gbuf.gl_pathv[n]); | ||
2034 | item = xcalloc(1, sizeof(*item)); | ||
2035 | item->selector = strdup(arg); | ||
2036 | item->filename = strdup(gbuf.gl_pathv[n]); | ||
2037 | if ((item->contents = sshbuf_new()) == NULL) { | ||
2038 | fatal("%s: sshbuf_new failed", | ||
2039 | __func__); | ||
2040 | } | ||
2041 | load_server_config(item->filename, | ||
2042 | item->contents); | ||
2043 | parse_server_config_depth(options, | ||
2044 | item->filename, item->contents, | ||
2045 | includes, connectinfo, | ||
2046 | (oactive ? 0 : SSHCFG_NEVERMATCH), | ||
2047 | activep, depth + 1); | ||
2048 | *activep = oactive; | ||
2049 | TAILQ_INSERT_TAIL(includes, item, entry); | ||
2050 | } | ||
2051 | globfree(&gbuf); | ||
2052 | free(arg); | ||
2053 | } | ||
2054 | if (value == 0) { | ||
2055 | fatal("%s line %d: Include missing filename argument", | ||
2056 | filename, linenum); | ||
2057 | } | ||
2058 | break; | ||
2059 | |||
1910 | case sMatch: | 2060 | case sMatch: |
1911 | if (cmdline) | 2061 | if (cmdline) |
1912 | fatal("Match directive not supported as a command-line " | 2062 | fatal("Match directive not supported as a command-line " |
@@ -1915,7 +2065,7 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1915 | if (value < 0) | 2065 | if (value < 0) |
1916 | fatal("%s line %d: Bad Match condition", filename, | 2066 | fatal("%s line %d: Bad Match condition", filename, |
1917 | linenum); | 2067 | linenum); |
1918 | *activep = value; | 2068 | *activep = (inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; |
1919 | break; | 2069 | break; |
1920 | 2070 | ||
1921 | case sPermitListen: | 2071 | case sPermitListen: |
@@ -2003,6 +2153,21 @@ process_server_config_line(ServerOptions *options, char *line, | |||
2003 | charptr = &options->revoked_keys_file; | 2153 | charptr = &options->revoked_keys_file; |
2004 | goto parse_filename; | 2154 | goto parse_filename; |
2005 | 2155 | ||
2156 | case sSecurityKeyProvider: | ||
2157 | charptr = &options->sk_provider; | ||
2158 | arg = strdelim(&cp); | ||
2159 | if (!arg || *arg == '\0') | ||
2160 | fatal("%s line %d: missing file name.", | ||
2161 | filename, linenum); | ||
2162 | if (*activep && *charptr == NULL) { | ||
2163 | *charptr = strcasecmp(arg, "internal") == 0 ? | ||
2164 | xstrdup(arg) : derelativise_path(arg); | ||
2165 | /* increase optional counter */ | ||
2166 | if (intptr != NULL) | ||
2167 | *intptr = *intptr + 1; | ||
2168 | } | ||
2169 | break; | ||
2170 | |||
2006 | case sIPQoS: | 2171 | case sIPQoS: |
2007 | arg = strdelim(&cp); | 2172 | arg = strdelim(&cp); |
2008 | if ((value = parse_ipqos(arg)) == -1) | 2173 | if ((value = parse_ipqos(arg)) == -1) |
@@ -2194,6 +2359,16 @@ process_server_config_line(ServerOptions *options, char *line, | |||
2194 | return 0; | 2359 | return 0; |
2195 | } | 2360 | } |
2196 | 2361 | ||
2362 | int | ||
2363 | process_server_config_line(ServerOptions *options, char *line, | ||
2364 | const char *filename, int linenum, int *activep, | ||
2365 | struct connection_info *connectinfo, struct include_list *includes) | ||
2366 | { | ||
2367 | return process_server_config_line_depth(options, line, filename, | ||
2368 | linenum, activep, connectinfo, 0, 0, includes); | ||
2369 | } | ||
2370 | |||
2371 | |||
2197 | /* Reads the server configuration file. */ | 2372 | /* Reads the server configuration file. */ |
2198 | 2373 | ||
2199 | void | 2374 | void |
@@ -2232,12 +2407,13 @@ load_server_config(const char *filename, struct sshbuf *conf) | |||
2232 | 2407 | ||
2233 | void | 2408 | void |
2234 | parse_server_match_config(ServerOptions *options, | 2409 | parse_server_match_config(ServerOptions *options, |
2235 | struct connection_info *connectinfo) | 2410 | struct include_list *includes, struct connection_info *connectinfo) |
2236 | { | 2411 | { |
2237 | ServerOptions mo; | 2412 | ServerOptions mo; |
2238 | 2413 | ||
2239 | initialize_server_options(&mo); | 2414 | initialize_server_options(&mo); |
2240 | parse_server_config(&mo, "reprocess config", cfg, connectinfo); | 2415 | parse_server_config(&mo, "reprocess config", cfg, includes, |
2416 | connectinfo); | ||
2241 | copy_set_server_options(options, &mo, 0); | 2417 | copy_set_server_options(options, &mo, 0); |
2242 | } | 2418 | } |
2243 | 2419 | ||
@@ -2290,6 +2466,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | |||
2290 | M_CP_INTOPT(password_authentication); | 2466 | M_CP_INTOPT(password_authentication); |
2291 | M_CP_INTOPT(gss_authentication); | 2467 | M_CP_INTOPT(gss_authentication); |
2292 | M_CP_INTOPT(pubkey_authentication); | 2468 | M_CP_INTOPT(pubkey_authentication); |
2469 | M_CP_INTOPT(pubkey_auth_options); | ||
2293 | M_CP_INTOPT(kerberos_authentication); | 2470 | M_CP_INTOPT(kerberos_authentication); |
2294 | M_CP_INTOPT(hostbased_authentication); | 2471 | M_CP_INTOPT(hostbased_authentication); |
2295 | M_CP_INTOPT(hostbased_uses_name_from_packet_only); | 2472 | M_CP_INTOPT(hostbased_uses_name_from_packet_only); |
@@ -2380,22 +2557,27 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | |||
2380 | #undef M_CP_STROPT | 2557 | #undef M_CP_STROPT |
2381 | #undef M_CP_STRARRAYOPT | 2558 | #undef M_CP_STRARRAYOPT |
2382 | 2559 | ||
2560 | #define SERVCONF_MAX_DEPTH 16 | ||
2383 | void | 2561 | void |
2384 | parse_server_config(ServerOptions *options, const char *filename, | 2562 | parse_server_config_depth(ServerOptions *options, const char *filename, |
2385 | struct sshbuf *conf, struct connection_info *connectinfo) | 2563 | struct sshbuf *conf, struct include_list *includes, |
2564 | struct connection_info *connectinfo, int flags, int *activep, int depth) | ||
2386 | { | 2565 | { |
2387 | int active, linenum, bad_options = 0; | 2566 | int linenum, bad_options = 0; |
2388 | char *cp, *obuf, *cbuf; | 2567 | char *cp, *obuf, *cbuf; |
2389 | 2568 | ||
2569 | if (depth < 0 || depth > SERVCONF_MAX_DEPTH) | ||
2570 | fatal("Too many recursive configuration includes"); | ||
2571 | |||
2390 | debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf)); | 2572 | debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf)); |
2391 | 2573 | ||
2392 | if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) | 2574 | if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) |
2393 | fatal("%s: sshbuf_dup_string failed", __func__); | 2575 | fatal("%s: sshbuf_dup_string failed", __func__); |
2394 | active = connectinfo ? 0 : 1; | ||
2395 | linenum = 1; | 2576 | linenum = 1; |
2396 | while ((cp = strsep(&cbuf, "\n")) != NULL) { | 2577 | while ((cp = strsep(&cbuf, "\n")) != NULL) { |
2397 | if (process_server_config_line(options, cp, filename, | 2578 | if (process_server_config_line_depth(options, cp, |
2398 | linenum++, &active, connectinfo) != 0) | 2579 | filename, linenum++, activep, connectinfo, flags, |
2580 | depth, includes) != 0) | ||
2399 | bad_options++; | 2581 | bad_options++; |
2400 | } | 2582 | } |
2401 | free(obuf); | 2583 | free(obuf); |
@@ -2405,6 +2587,16 @@ parse_server_config(ServerOptions *options, const char *filename, | |||
2405 | process_queued_listen_addrs(options); | 2587 | process_queued_listen_addrs(options); |
2406 | } | 2588 | } |
2407 | 2589 | ||
2590 | void | ||
2591 | parse_server_config(ServerOptions *options, const char *filename, | ||
2592 | struct sshbuf *conf, struct include_list *includes, | ||
2593 | struct connection_info *connectinfo) | ||
2594 | { | ||
2595 | int active = connectinfo ? 0 : 1; | ||
2596 | parse_server_config_depth(options, filename, conf, includes, | ||
2597 | connectinfo, 0, &active, 0); | ||
2598 | } | ||
2599 | |||
2408 | static const char * | 2600 | static const char * |
2409 | fmt_multistate_int(int val, const struct multistate *m) | 2601 | fmt_multistate_int(int val, const struct multistate *m) |
2410 | { | 2602 | { |
@@ -2616,13 +2808,14 @@ dump_config(ServerOptions *o) | |||
2616 | /* string arguments */ | 2808 | /* string arguments */ |
2617 | dump_cfg_string(sPidFile, o->pid_file); | 2809 | dump_cfg_string(sPidFile, o->pid_file); |
2618 | dump_cfg_string(sXAuthLocation, o->xauth_location); | 2810 | dump_cfg_string(sXAuthLocation, o->xauth_location); |
2619 | dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); | 2811 | dump_cfg_string(sCiphers, o->ciphers); |
2620 | dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); | 2812 | dump_cfg_string(sMacs, o->macs); |
2621 | dump_cfg_string(sBanner, o->banner); | 2813 | dump_cfg_string(sBanner, o->banner); |
2622 | dump_cfg_string(sForceCommand, o->adm_forced_command); | 2814 | dump_cfg_string(sForceCommand, o->adm_forced_command); |
2623 | dump_cfg_string(sChrootDirectory, o->chroot_directory); | 2815 | dump_cfg_string(sChrootDirectory, o->chroot_directory); |
2624 | dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); | 2816 | dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); |
2625 | dump_cfg_string(sRevokedKeys, o->revoked_keys_file); | 2817 | dump_cfg_string(sRevokedKeys, o->revoked_keys_file); |
2818 | dump_cfg_string(sSecurityKeyProvider, o->sk_provider); | ||
2626 | dump_cfg_string(sAuthorizedPrincipalsFile, | 2819 | dump_cfg_string(sAuthorizedPrincipalsFile, |
2627 | o->authorized_principals_file); | 2820 | o->authorized_principals_file); |
2628 | dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0' | 2821 | dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0' |
@@ -2632,16 +2825,11 @@ dump_config(ServerOptions *o) | |||
2632 | dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); | 2825 | dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); |
2633 | dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); | 2826 | dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); |
2634 | dump_cfg_string(sHostKeyAgent, o->host_key_agent); | 2827 | dump_cfg_string(sHostKeyAgent, o->host_key_agent); |
2635 | dump_cfg_string(sKexAlgorithms, | 2828 | dump_cfg_string(sKexAlgorithms, o->kex_algorithms); |
2636 | o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); | 2829 | dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms); |
2637 | dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms ? | 2830 | dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types); |
2638 | o->ca_sign_algorithms : SSH_ALLOWED_CA_SIGALGS); | 2831 | dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms); |
2639 | dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? | 2832 | dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types); |
2640 | o->hostbased_key_types : KEX_DEFAULT_PK_ALG); | ||
2641 | dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? | ||
2642 | o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); | ||
2643 | dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? | ||
2644 | o->pubkey_key_types : KEX_DEFAULT_PK_ALG); | ||
2645 | dump_cfg_string(sRDomain, o->routing_domain); | 2833 | dump_cfg_string(sRDomain, o->routing_domain); |
2646 | 2834 | ||
2647 | /* string arguments requiring a lookup */ | 2835 | /* string arguments requiring a lookup */ |
@@ -2711,4 +2899,10 @@ dump_config(ServerOptions *o) | |||
2711 | o->permit_user_env_whitelist); | 2899 | o->permit_user_env_whitelist); |
2712 | } | 2900 | } |
2713 | 2901 | ||
2902 | printf("pubkeyauthoptions"); | ||
2903 | if (o->pubkey_auth_options == 0) | ||
2904 | printf(" none"); | ||
2905 | if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED) | ||
2906 | printf(" touch-required"); | ||
2907 | printf("\n"); | ||
2714 | } | 2908 | } |