|
Lines 34-39
Link Here
|
| 34 |
#ifdef HAVE_UTIL_H |
34 |
#ifdef HAVE_UTIL_H |
| 35 |
#include <util.h> |
35 |
#include <util.h> |
| 36 |
#endif |
36 |
#endif |
|
|
37 |
#ifdef USE_SYSTEM_GLOB |
| 38 |
# include <glob.h> |
| 39 |
#else |
| 40 |
# include "openbsd-compat/glob.h" |
| 41 |
#endif |
| 37 |
|
42 |
|
| 38 |
#include "openbsd-compat/sys-queue.h" |
43 |
#include "openbsd-compat/sys-queue.h" |
| 39 |
#include "xmalloc.h" |
44 |
#include "xmalloc.h" |
|
Lines 64-69
static void add_one_listen_addr(ServerOptions *, char *, int);
Link Here
|
| 64 |
/* Use of privilege separation or not */ |
69 |
/* Use of privilege separation or not */ |
| 65 |
extern int use_privsep; |
70 |
extern int use_privsep; |
| 66 |
extern struct sshbuf *cfg; |
71 |
extern struct sshbuf *cfg; |
|
|
72 |
struct include_item *include_list = NULL, *include_last = NULL; |
| 73 |
|
| 74 |
#define INCLUDE_LIST_APPEND(item) \ |
| 75 |
(item)->next = NULL; \ |
| 76 |
if (include_list == NULL) { \ |
| 77 |
include_list = (item); \ |
| 78 |
} else \ |
| 79 |
include_last->next = (item); \ |
| 80 |
include_last = (item); |
| 67 |
|
81 |
|
| 68 |
/* Initializes the server options to their default values. */ |
82 |
/* Initializes the server options to their default values. */ |
| 69 |
|
83 |
|
|
Lines 383-388
fill_default_server_options(ServerOptions *options)
Link Here
|
| 383 |
|
397 |
|
| 384 |
} |
398 |
} |
| 385 |
|
399 |
|
|
|
400 |
int process_server_config_line_depth(ServerOptions *options, char *line, |
| 401 |
const char *filename, int linenum, int *activep, |
| 402 |
struct connection_info *connectinfo, int inc_flags, int depth); |
| 403 |
void parse_server_config_depth(ServerOptions *options, const char *filename, |
| 404 |
struct sshbuf *conf, struct connection_info *connectinfo, |
| 405 |
int flags, int *activep, int depth); |
| 406 |
|
| 386 |
/* Keyword tokens. */ |
407 |
/* Keyword tokens. */ |
| 387 |
typedef enum { |
408 |
typedef enum { |
| 388 |
sBadOption, /* == unknown option */ |
409 |
sBadOption, /* == unknown option */ |
|
Lines 434-440
typedef enum {
Link Here
|
| 434 |
sAcceptEnv, sPermitTunnel, |
455 |
sAcceptEnv, sPermitTunnel, |
| 435 |
sMatch, sPermitOpen, sForceCommand, sChrootDirectory, |
456 |
sMatch, sPermitOpen, sForceCommand, sChrootDirectory, |
| 436 |
sUsePrivilegeSeparation, sAllowAgentForwarding, |
457 |
sUsePrivilegeSeparation, sAllowAgentForwarding, |
| 437 |
sHostCertificate, |
458 |
sHostCertificate, sInclude, |
| 438 |
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
459 |
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
| 439 |
sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, |
460 |
sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, |
| 440 |
sKexAlgorithms, sIPQoS, sVersionAddendum, |
461 |
sKexAlgorithms, sIPQoS, sVersionAddendum, |
|
Lines 429-434
typedef enum {
Link Here
|
| 429 |
#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ |
450 |
#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ |
| 430 |
#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) |
451 |
#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) |
| 431 |
|
452 |
|
|
|
453 |
#define SSHCFG_NEVERMATCH 0x04 /* Match/Host never matches; internal only */ |
| 454 |
|
| 432 |
/* Textual representation of the tokens. */ |
455 |
/* Textual representation of the tokens. */ |
| 433 |
static struct { |
456 |
static struct { |
| 434 |
const char *name; |
457 |
const char *name; |
|
Lines 576-581
static struct {
Link Here
|
| 576 |
{ "noneenabled", sNoneEnabled, SSHCFG_ALL }, |
599 |
{ "noneenabled", sNoneEnabled, SSHCFG_ALL }, |
| 577 |
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, |
600 |
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, |
| 578 |
{ "disableMTAES", sDisableMTAES, SSHCFG_ALL }, |
601 |
{ "disableMTAES", sDisableMTAES, SSHCFG_ALL }, |
|
|
602 |
{ "include", sInclude, SSHCFG_ALL }, |
| 579 |
{ "ipqos", sIPQoS, SSHCFG_ALL }, |
603 |
{ "ipqos", sIPQoS, SSHCFG_ALL }, |
| 580 |
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, |
604 |
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, |
| 581 |
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, |
605 |
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, |
|
Lines 991-999
int
Link Here
|
| 991 |
process_server_config_line(ServerOptions *options, char *line, |
1015 |
process_server_config_line(ServerOptions *options, char *line, |
| 992 |
const char *filename, int linenum, int *activep, |
1016 |
const char *filename, int linenum, int *activep, |
| 993 |
struct connection_info *connectinfo) |
1017 |
struct connection_info *connectinfo) |
|
|
1018 |
{ |
| 1019 |
return process_server_config_line_depth(options, line, filename, linenum, |
| 1020 |
activep, connectinfo, 0, 0); |
| 1021 |
} |
| 1022 |
|
| 1023 |
int |
| 1024 |
process_server_config_line_depth(ServerOptions *options, char *line, |
| 1025 |
const char *filename, int linenum, int *activep, |
| 1026 |
struct connection_info *connectinfo, int inc_flags, int depth) |
| 994 |
{ |
1027 |
{ |
| 995 |
int cmdline = 0, *intptr, value, value2, n, port; |
1028 |
int cmdline = 0, *intptr, value, value2, n, port, oactive; |
| 996 |
SyslogFacility *log_facility_ptr; |
1029 |
SyslogFacility *log_facility_ptr; |
| 997 |
LogLevel *log_level_ptr; |
1030 |
LogLevel *log_level_ptr; |
| 998 |
ServerOpCodes opcode; |
1031 |
ServerOpCodes opcode; |
|
Lines 1033-1038
process_server_config_line_depth(ServerOptions *options, char *line,
Link Here
|
| 1033 |
long long val64; |
1066 |
long long val64; |
| 1034 |
const struct multistate *multistate_ptr; |
1067 |
const struct multistate *multistate_ptr; |
| 1035 |
const char *errstr; |
1068 |
const char *errstr; |
|
|
1069 |
struct include_item *item; |
| 1070 |
int found = 0; |
| 1071 |
glob_t gbuf; |
| 1036 |
|
1072 |
|
| 1037 |
/* Strip trailing whitespace. Allow \f (form feed) at EOL only */ |
1073 |
/* Strip trailing whitespace. Allow \f (form feed) at EOL only */ |
| 1038 |
if ((len = strlen(line)) == 0) |
1074 |
if ((len = strlen(line)) == 0) |
|
Lines 1027-1033
process_server_config_line(ServerOptions *options, char *line,
Link Here
|
| 1027 |
cmdline = 1; |
1063 |
cmdline = 1; |
| 1028 |
activep = &cmdline; |
1064 |
activep = &cmdline; |
| 1029 |
} |
1065 |
} |
| 1030 |
if (*activep && opcode != sMatch) |
1066 |
if (*activep && opcode != sMatch && opcode != sInclude) |
| 1031 |
debug3("%s:%d setting %s %s", filename, linenum, arg, cp); |
1067 |
debug3("%s:%d setting %s %s", filename, linenum, arg, cp); |
| 1032 |
if (*activep == 0 && !(flags & SSHCFG_MATCH)) { |
1068 |
if (*activep == 0 && !(flags & SSHCFG_MATCH)) { |
| 1033 |
if (connectinfo == NULL) { |
1069 |
if (connectinfo == NULL) { |
|
Lines 1647-1652
process_server_config_line(ServerOptions *options, char *line,
Link Here
|
| 1647 |
*intptr = value; |
1683 |
*intptr = value; |
| 1648 |
break; |
1684 |
break; |
| 1649 |
|
1685 |
|
|
|
1686 |
case sInclude: |
| 1687 |
if (cmdline) |
| 1688 |
fatal("Include directive not supported as a command-line " |
| 1689 |
"option"); |
| 1690 |
|
| 1691 |
value = 0; |
| 1692 |
while ((arg = strdelim(&cp)) != NULL && *arg != '\0') { |
| 1693 |
value++; |
| 1694 |
found = 0; |
| 1695 |
if (*arg != '/' && *arg != '~') { |
| 1696 |
xasprintf(&arg2, "%s/%s", |
| 1697 |
SSHDIR, arg); |
| 1698 |
} else |
| 1699 |
arg2 = xstrdup(arg); |
| 1700 |
|
| 1701 |
/* |
| 1702 |
* don't let the Match in Included clobber |
| 1703 |
* the containing file's Match state. |
| 1704 |
*/ |
| 1705 |
oactive = *activep; |
| 1706 |
/* browse cached list of files */ |
| 1707 |
for (item = include_list; item != NULL; item = item->next) { |
| 1708 |
if (strcmp(item->selector, arg2) == 0) { |
| 1709 |
if (item->filename != NULL) |
| 1710 |
parse_server_config_depth(options, item->filename, |
| 1711 |
item->buffer, connectinfo, |
| 1712 |
(oactive ? 0 : SSHCFG_NEVERMATCH), |
| 1713 |
activep, depth + 1); |
| 1714 |
found = 1; |
| 1715 |
*activep = oactive; |
| 1716 |
} |
| 1717 |
} |
| 1718 |
if (found != 0) { |
| 1719 |
free(arg2); |
| 1720 |
continue; |
| 1721 |
} |
| 1722 |
|
| 1723 |
/* not in cache, a new glob */ |
| 1724 |
debug3("Glob configuration file to include %s", arg2); |
| 1725 |
if (glob(arg2, 0, NULL, &gbuf) == 0) { |
| 1726 |
for (i = 0; (int) i < gbuf.gl_pathc; i++) { |
| 1727 |
debug3("Including configuration file %s", |
| 1728 |
gbuf.gl_pathv[i]); |
| 1729 |
item = malloc(sizeof(struct include_item)); |
| 1730 |
item->selector = strdup(arg2); |
| 1731 |
item->filename = strdup(gbuf.gl_pathv[i]); |
| 1732 |
item->buffer = sshbuf_new(); |
| 1733 |
load_server_config(item->filename, item->buffer); |
| 1734 |
parse_server_config_depth(options, item->filename, |
| 1735 |
item->buffer, connectinfo, |
| 1736 |
(oactive ? 0 : SSHCFG_NEVERMATCH), |
| 1737 |
activep, depth + 1); |
| 1738 |
|
| 1739 |
// append item to the end of the list |
| 1740 |
INCLUDE_LIST_APPEND(item) |
| 1741 |
*activep = oactive; |
| 1742 |
} |
| 1743 |
} else { /* no match or other error */ |
| 1744 |
// store placeholder to avoid aditional empty globs |
| 1745 |
item = malloc(sizeof(struct include_item)); |
| 1746 |
item->selector = strdup(arg2); |
| 1747 |
item->filename = NULL; |
| 1748 |
item->buffer = sshbuf_new(); |
| 1749 |
// append item to the end of the list |
| 1750 |
INCLUDE_LIST_APPEND(item) |
| 1751 |
} |
| 1752 |
globfree(&gbuf); |
| 1753 |
free(arg2); |
| 1754 |
} |
| 1755 |
if (value == 0) |
| 1756 |
fatal("%s line %d: missing argument - file to include", |
| 1757 |
filename, linenum); |
| 1758 |
break; |
| 1759 |
|
| 1650 |
case sMatch: |
1760 |
case sMatch: |
| 1651 |
if (cmdline) |
1761 |
if (cmdline) |
| 1652 |
fatal("Match directive not supported as a command-line " |
1762 |
fatal("Match directive not supported as a command-line " |
|
Lines 1655-1661
process_server_config_line(ServerOptions *options, char *line,
Link Here
|
| 1655 |
if (value < 0) |
1765 |
if (value < 0) |
| 1656 |
fatal("%s line %d: Bad Match condition", filename, |
1766 |
fatal("%s line %d: Bad Match condition", filename, |
| 1657 |
linenum); |
1767 |
linenum); |
| 1658 |
*activep = value; |
1768 |
*activep = (inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; |
| 1659 |
break; |
1769 |
break; |
| 1660 |
|
1770 |
|
| 1661 |
case sPermitOpen: |
1771 |
case sPermitOpen: |
|
Lines 2106-2123
void
Link Here
|
| 2106 |
parse_server_config(ServerOptions *options, const char *filename, |
2216 |
parse_server_config(ServerOptions *options, const char *filename, |
| 2107 |
struct sshbuf *conf, struct connection_info *connectinfo) |
2217 |
struct sshbuf *conf, struct connection_info *connectinfo) |
| 2108 |
{ |
2218 |
{ |
| 2109 |
int active, linenum, bad_options = 0; |
2219 |
int active = connectinfo ? 0 : 1; |
|
|
2220 |
parse_server_config_depth(options, filename, conf, connectinfo, |
| 2221 |
0, &active, 0); |
| 2222 |
} |
| 2223 |
|
| 2224 |
#define SERVCONF_MAX_DEPTH 16 |
| 2225 |
|
| 2226 |
void |
| 2227 |
parse_server_config_depth(ServerOptions *options, const char *filename, |
| 2228 |
struct sshbuf *conf, struct connection_info *connectinfo, |
| 2229 |
int flags, int *activep, int depth) |
| 2230 |
{ |
| 2231 |
int linenum, bad_options = 0; |
| 2110 |
char *cp, *obuf, *cbuf; |
2232 |
char *cp, *obuf, *cbuf; |
| 2111 |
|
2233 |
|
|
|
2234 |
if (depth < 0 || depth > SERVCONF_MAX_DEPTH) |
| 2235 |
fatal("Too many recursive configuration includes"); |
| 2236 |
|
| 2112 |
debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf)); |
2237 |
debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf)); |
| 2113 |
|
2238 |
|
| 2114 |
if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) |
2239 |
if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) |
| 2115 |
fatal("%s: sshbuf_dup_string failed", __func__); |
2240 |
fatal("%s: sshbuf_dup_string failed", __func__); |
| 2116 |
active = connectinfo ? 0 : 1; |
|
|
| 2117 |
linenum = 1; |
2241 |
linenum = 1; |
| 2118 |
while ((cp = strsep(&cbuf, "\n")) != NULL) { |
2242 |
while ((cp = strsep(&cbuf, "\n")) != NULL) { |
| 2119 |
if (process_server_config_line(options, cp, filename, |
2243 |
if (process_server_config_line_depth(options, cp, filename, |
| 2120 |
linenum++, &active, connectinfo) != 0) |
2244 |
linenum++, activep, connectinfo, flags, depth) != 0) |
| 2121 |
bad_options++; |
2245 |
bad_options++; |
| 2122 |
} |
2246 |
} |
| 2123 |
free(obuf); |
2247 |
free(obuf); |