|
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 Buffer cfg; |
71 |
extern Buffer 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 377-382
fill_default_server_options(ServerOptions *options)
Link Here
|
| 377 |
|
391 |
|
| 378 |
} |
392 |
} |
| 379 |
|
393 |
|
|
|
394 |
int process_server_config_line_depth(ServerOptions *options, char *line, |
| 395 |
const char *filename, int linenum, int *activep, |
| 396 |
struct connection_info *connectinfo, int inc_flags, int depth); |
| 397 |
void parse_server_config_depth(ServerOptions *options, const char *filename, |
| 398 |
Buffer *conf, struct connection_info *connectinfo, |
| 399 |
int flags, int *activep, int depth); |
| 400 |
|
| 380 |
/* Keyword tokens. */ |
401 |
/* Keyword tokens. */ |
| 381 |
typedef enum { |
402 |
typedef enum { |
| 382 |
sBadOption, /* == unknown option */ |
403 |
sBadOption, /* == unknown option */ |
|
Lines 407-413
typedef enum {
Link Here
|
| 407 |
sAcceptEnv, sPermitTunnel, |
428 |
sAcceptEnv, sPermitTunnel, |
| 408 |
sMatch, sPermitOpen, sForceCommand, sChrootDirectory, |
429 |
sMatch, sPermitOpen, sForceCommand, sChrootDirectory, |
| 409 |
sUsePrivilegeSeparation, sAllowAgentForwarding, |
430 |
sUsePrivilegeSeparation, sAllowAgentForwarding, |
| 410 |
sHostCertificate, |
431 |
sHostCertificate, sInclude, |
| 411 |
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
432 |
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
| 412 |
sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, |
433 |
sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, |
| 413 |
sKexAlgorithms, sIPQoS, sVersionAddendum, |
434 |
sKexAlgorithms, sIPQoS, sVersionAddendum, |
|
Lines 422-427
typedef enum {
Link Here
|
| 422 |
#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ |
443 |
#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ |
| 423 |
#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) |
444 |
#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) |
| 424 |
|
445 |
|
|
|
446 |
#define SSHCFG_NEVERMATCH 0x04 /* Match/Host never matches; internal only */ |
| 447 |
|
| 425 |
/* Textual representation of the tokens. */ |
448 |
/* Textual representation of the tokens. */ |
| 426 |
static struct { |
449 |
static struct { |
| 427 |
const char *name; |
450 |
const char *name; |
|
Lines 546-551
static struct {
Link Here
|
| 546 |
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, |
569 |
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, |
| 547 |
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, |
570 |
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, |
| 548 |
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, |
571 |
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, |
|
|
572 |
{ "include", sInclude, SSHCFG_ALL }, |
| 549 |
{ "ipqos", sIPQoS, SSHCFG_ALL }, |
573 |
{ "ipqos", sIPQoS, SSHCFG_ALL }, |
| 550 |
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, |
574 |
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, |
| 551 |
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, |
575 |
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, |
|
Lines 952-959
process_server_config_line(ServerOptions *options, char *line,
Link Here
|
| 952 |
const char *filename, int linenum, int *activep, |
976 |
const char *filename, int linenum, int *activep, |
| 953 |
struct connection_info *connectinfo) |
977 |
struct connection_info *connectinfo) |
| 954 |
{ |
978 |
{ |
| 955 |
char *cp, **charptr, *arg, *p; |
979 |
process_server_config_line_depth(options, line, filename, linenum, |
| 956 |
int cmdline = 0, *intptr, value, value2, n, port; |
980 |
activep, connectinfo, 0, 0); |
|
|
981 |
|
| 982 |
} |
| 983 |
|
| 984 |
int |
| 985 |
process_server_config_line_depth(ServerOptions *options, char *line, |
| 986 |
const char *filename, int linenum, int *activep, |
| 987 |
struct connection_info *connectinfo, int inc_flags, int depth) |
| 988 |
{ |
| 989 |
char *cp, **charptr, *arg, *arg2, *p; |
| 990 |
int cmdline = 0, *intptr, value, value2, n, port, oactive; |
| 957 |
SyslogFacility *log_facility_ptr; |
991 |
SyslogFacility *log_facility_ptr; |
| 958 |
LogLevel *log_level_ptr; |
992 |
LogLevel *log_level_ptr; |
| 959 |
ServerOpCodes opcode; |
993 |
ServerOpCodes opcode; |
|
Lines 961-966
process_server_config_line(ServerOptions *options, char *line,
Link Here
|
| 961 |
size_t len; |
995 |
size_t len; |
| 962 |
long long val64; |
996 |
long long val64; |
| 963 |
const struct multistate *multistate_ptr; |
997 |
const struct multistate *multistate_ptr; |
|
|
998 |
struct include_item *item; |
| 999 |
int found = 0; |
| 1000 |
glob_t gbuf; |
| 964 |
|
1001 |
|
| 965 |
cp = line; |
1002 |
cp = line; |
| 966 |
if ((arg = strdelim(&cp)) == NULL) |
1003 |
if ((arg = strdelim(&cp)) == NULL) |
|
Lines 978-984
process_server_config_line(ServerOptions *options, char *line,
Link Here
|
| 978 |
cmdline = 1; |
1015 |
cmdline = 1; |
| 979 |
activep = &cmdline; |
1016 |
activep = &cmdline; |
| 980 |
} |
1017 |
} |
| 981 |
if (*activep && opcode != sMatch) |
1018 |
if (*activep && opcode != sMatch && opcode != sInclude) |
| 982 |
debug3("%s:%d setting %s %s", filename, linenum, arg, cp); |
1019 |
debug3("%s:%d setting %s %s", filename, linenum, arg, cp); |
| 983 |
if (*activep == 0 && !(flags & SSHCFG_MATCH)) { |
1020 |
if (*activep == 0 && !(flags & SSHCFG_MATCH)) { |
| 984 |
if (connectinfo == NULL) { |
1021 |
if (connectinfo == NULL) { |
|
Lines 1592-1597
process_server_config_line(ServerOptions *options, char *line,
Link Here
|
| 1592 |
*intptr = value; |
1629 |
*intptr = value; |
| 1593 |
break; |
1630 |
break; |
| 1594 |
|
1631 |
|
|
|
1632 |
case sInclude: |
| 1633 |
if (cmdline) |
| 1634 |
fatal("Include directive not supported as a command-line " |
| 1635 |
"option"); |
| 1636 |
|
| 1637 |
value = 0; |
| 1638 |
while ((arg = strdelim(&cp)) != NULL && *arg != '\0') { |
| 1639 |
value++; |
| 1640 |
found = 0; |
| 1641 |
if (*arg != '/' && *arg != '~') { |
| 1642 |
xasprintf(&arg2, "%s/%s", |
| 1643 |
SSHDIR, arg); |
| 1644 |
} else |
| 1645 |
arg2 = xstrdup(arg); |
| 1646 |
|
| 1647 |
/* |
| 1648 |
* don't let the Match in Included clobber |
| 1649 |
* the containing file's Match state. |
| 1650 |
*/ |
| 1651 |
oactive = *activep; |
| 1652 |
/* browse cached list of files */ |
| 1653 |
for (item = include_list; item != NULL; item = item->next) { |
| 1654 |
if (strcmp(item->selector, arg2) == 0) { |
| 1655 |
if (item->filename != NULL) |
| 1656 |
parse_server_config_depth(options, item->filename, |
| 1657 |
&(item->buffer), connectinfo, |
| 1658 |
(oactive ? 0 : SSHCFG_NEVERMATCH), |
| 1659 |
activep, depth + 1); |
| 1660 |
found = 1; |
| 1661 |
*activep = oactive; |
| 1662 |
} |
| 1663 |
} |
| 1664 |
if (found != 0) { |
| 1665 |
free(arg2); |
| 1666 |
continue; |
| 1667 |
} |
| 1668 |
|
| 1669 |
/* not in cache, a new glob */ |
| 1670 |
debug3("Glob configuration file to include %s", arg2); |
| 1671 |
if (glob(arg2, 0, NULL, &gbuf) == 0) { |
| 1672 |
for (i = 0; i < gbuf.gl_pathc; i++) { |
| 1673 |
debug3("Including configuration file %s", |
| 1674 |
gbuf.gl_pathv[i]); |
| 1675 |
item = malloc(sizeof(struct include_item)); |
| 1676 |
item->selector = strdup(arg2); |
| 1677 |
item->filename = strdup(gbuf.gl_pathv[i]); |
| 1678 |
buffer_init(&(item->buffer)); |
| 1679 |
load_server_config(item->filename, &(item->buffer)); |
| 1680 |
parse_server_config_depth(options, item->filename, |
| 1681 |
&(item->buffer), connectinfo, |
| 1682 |
(oactive ? 0 : SSHCFG_NEVERMATCH), |
| 1683 |
activep, depth + 1); |
| 1684 |
|
| 1685 |
// append item to the end of the list |
| 1686 |
INCLUDE_LIST_APPEND(item) |
| 1687 |
*activep = oactive; |
| 1688 |
} |
| 1689 |
} else { /* no match or other error */ |
| 1690 |
// store placeholder to avoid aditional empty globs |
| 1691 |
item = malloc(sizeof(struct include_item)); |
| 1692 |
item->selector = strdup(arg2); |
| 1693 |
item->filename = NULL; |
| 1694 |
buffer_init(&(item->buffer)); |
| 1695 |
// append item to the end of the list |
| 1696 |
INCLUDE_LIST_APPEND(item) |
| 1697 |
} |
| 1698 |
globfree(&gbuf); |
| 1699 |
free(arg2); |
| 1700 |
} |
| 1701 |
if (value == 0) |
| 1702 |
fatal("%s line %d: missing argument - file to include", |
| 1703 |
filename, linenum); |
| 1704 |
break; |
| 1705 |
|
| 1595 |
case sMatch: |
1706 |
case sMatch: |
| 1596 |
if (cmdline) |
1707 |
if (cmdline) |
| 1597 |
fatal("Match directive not supported as a command-line " |
1708 |
fatal("Match directive not supported as a command-line " |
|
Lines 1600-1606
process_server_config_line(ServerOptions *options, char *line,
Link Here
|
| 1600 |
if (value < 0) |
1711 |
if (value < 0) |
| 1601 |
fatal("%s line %d: Bad Match condition", filename, |
1712 |
fatal("%s line %d: Bad Match condition", filename, |
| 1602 |
linenum); |
1713 |
linenum); |
| 1603 |
*activep = value; |
1714 |
*activep = (inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; |
| 1604 |
break; |
1715 |
break; |
| 1605 |
|
1716 |
|
| 1606 |
case sPermitOpen: |
1717 |
case sPermitOpen: |
|
Lines 2033-2050
void
Link Here
|
| 2033 |
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, |
2144 |
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, |
| 2034 |
struct connection_info *connectinfo) |
2145 |
struct connection_info *connectinfo) |
| 2035 |
{ |
2146 |
{ |
| 2036 |
int active, linenum, bad_options = 0; |
2147 |
int active = connectinfo ? 0 : 1; |
|
|
2148 |
parse_server_config_depth(options, filename, conf, connectinfo, |
| 2149 |
0, &active, 0); |
| 2150 |
} |
| 2151 |
|
| 2152 |
#define SERVCONF_MAX_DEPTH 16 |
| 2153 |
|
| 2154 |
void |
| 2155 |
parse_server_config_depth(ServerOptions *options, const char *filename, |
| 2156 |
Buffer *conf, struct connection_info *connectinfo, |
| 2157 |
int flags, int *activep, int depth) |
| 2158 |
{ |
| 2159 |
int linenum, bad_options = 0; |
| 2037 |
char *cp, *obuf, *cbuf; |
2160 |
char *cp, *obuf, *cbuf; |
| 2038 |
|
2161 |
|
|
|
2162 |
if (depth < 0 || depth > SERVCONF_MAX_DEPTH) |
| 2163 |
fatal("Too many recursive configuration includes"); |
| 2164 |
|
| 2039 |
debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); |
2165 |
debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); |
| 2040 |
|
2166 |
|
| 2041 |
if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) |
2167 |
if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) |
| 2042 |
fatal("%s: sshbuf_dup_string failed", __func__); |
2168 |
fatal("%s: sshbuf_dup_string failed", __func__); |
| 2043 |
active = connectinfo ? 0 : 1; |
|
|
| 2044 |
linenum = 1; |
2169 |
linenum = 1; |
| 2045 |
while ((cp = strsep(&cbuf, "\n")) != NULL) { |
2170 |
while ((cp = strsep(&cbuf, "\n")) != NULL) { |
| 2046 |
if (process_server_config_line(options, cp, filename, |
2171 |
if (process_server_config_line_depth(options, cp, filename, |
| 2047 |
linenum++, &active, connectinfo) != 0) |
2172 |
linenum++, activep, connectinfo, flags, depth) != 0) |
| 2048 |
bad_options++; |
2173 |
bad_options++; |
| 2049 |
} |
2174 |
} |
| 2050 |
free(obuf); |
2175 |
free(obuf); |