summaryrefslogtreecommitdiff
path: root/servconf.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-10-05 15:52:03 +0000
committerDamien Miller <djm@mindrot.org>2017-10-20 12:01:02 +1100
commitdceabc7ad7ebc7769c8214a1647af64c9a1d92e5 (patch)
tree513eb2c60aafcc240cd9bc2027a4f919a2934978 /servconf.c
parent2b4f3ab050c2aaf6977604dd037041372615178d (diff)
upstream commit
replace statically-sized arrays in ServerOptions with dynamic ones managed by xrecallocarray, removing some arbitrary (though large) limits and saving a bit of memory; "much nicer" markus@ Upstream-ID: 1732720b2f478fe929d6687ac7b0a97ff2efe9d2
Diffstat (limited to 'servconf.c')
-rw-r--r--servconf.c210
1 files changed, 115 insertions, 95 deletions
diff --git a/servconf.c b/servconf.c
index 956862959..a96df4f67 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
1 1
2/* $OpenBSD: servconf.c,v 1.313 2017/10/04 18:49:30 djm Exp $ */ 2/* $OpenBSD: servconf.c,v 1.314 2017/10/05 15:52:03 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
@@ -188,10 +188,45 @@ assemble_algorithms(ServerOptions *o)
188 fatal("kex_assemble_names failed"); 188 fatal("kex_assemble_names failed");
189} 189}
190 190
191static void
192array_append(const char *file, const int line, const char *directive,
193 char ***array, u_int *lp, const char *s)
194{
195
196 if (*lp >= INT_MAX)
197 fatal("%s line %d: Too many %s entries", file, line, directive);
198
199 *array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
200 (*array)[*lp] = xstrdup(s);
201 (*lp)++;
202}
203
204void
205servconf_add_hostkey(const char *file, const int line,
206 ServerOptions *options, const char *path)
207{
208 char *apath = derelativise_path(path);
209
210 array_append(file, line, "HostKey",
211 &options->host_key_files, &options->num_host_key_files, apath);
212 free(apath);
213}
214
215void
216servconf_add_hostcert(const char *file, const int line,
217 ServerOptions *options, const char *path)
218{
219 char *apath = derelativise_path(path);
220
221 array_append(file, line, "HostCertificate",
222 &options->host_cert_files, &options->num_host_cert_files, apath);
223 free(apath);
224}
225
191void 226void
192fill_default_server_options(ServerOptions *options) 227fill_default_server_options(ServerOptions *options)
193{ 228{
194 int i; 229 u_int i;
195 230
196 /* Portable-specific options */ 231 /* Portable-specific options */
197 if (options->use_pam == -1) 232 if (options->use_pam == -1)
@@ -200,16 +235,16 @@ fill_default_server_options(ServerOptions *options)
200 /* Standard Options */ 235 /* Standard Options */
201 if (options->num_host_key_files == 0) { 236 if (options->num_host_key_files == 0) {
202 /* fill default hostkeys for protocols */ 237 /* fill default hostkeys for protocols */
203 options->host_key_files[options->num_host_key_files++] = 238 servconf_add_hostkey("[default]", 0, options,
204 _PATH_HOST_RSA_KEY_FILE; 239 _PATH_HOST_RSA_KEY_FILE);
205 options->host_key_files[options->num_host_key_files++] = 240 servconf_add_hostkey("[default]", 0, options,
206 _PATH_HOST_DSA_KEY_FILE; 241 _PATH_HOST_DSA_KEY_FILE);
207#ifdef OPENSSL_HAS_ECC 242#ifdef OPENSSL_HAS_ECC
208 options->host_key_files[options->num_host_key_files++] = 243 servconf_add_hostkey("[default]", 0, options,
209 _PATH_HOST_ECDSA_KEY_FILE; 244 _PATH_HOST_ECDSA_KEY_FILE);
210#endif 245#endif
211 options->host_key_files[options->num_host_key_files++] = 246 servconf_add_hostkey("[default]", 0, options,
212 _PATH_HOST_ED25519_KEY_FILE; 247 _PATH_HOST_ED25519_KEY_FILE);
213 } 248 }
214 /* No certificates by default */ 249 /* No certificates by default */
215 if (options->num_ports == 0) 250 if (options->num_ports == 0)
@@ -313,10 +348,14 @@ fill_default_server_options(ServerOptions *options)
313 if (options->client_alive_count_max == -1) 348 if (options->client_alive_count_max == -1)
314 options->client_alive_count_max = 3; 349 options->client_alive_count_max = 3;
315 if (options->num_authkeys_files == 0) { 350 if (options->num_authkeys_files == 0) {
316 options->authorized_keys_files[options->num_authkeys_files++] = 351 array_append("[default]", 0, "AuthorizedKeysFiles",
317 xstrdup(_PATH_SSH_USER_PERMITTED_KEYS); 352 &options->authorized_keys_files,
318 options->authorized_keys_files[options->num_authkeys_files++] = 353 &options->num_authkeys_files,
319 xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2); 354 _PATH_SSH_USER_PERMITTED_KEYS);
355 array_append("[default]", 0, "AuthorizedKeysFiles",
356 &options->authorized_keys_files,
357 &options->num_authkeys_files,
358 _PATH_SSH_USER_PERMITTED_KEYS2);
320 } 359 }
321 if (options->permit_tun == -1) 360 if (options->permit_tun == -1)
322 options->permit_tun = SSH_TUNMODE_NO; 361 options->permit_tun = SSH_TUNMODE_NO;
@@ -1128,22 +1167,12 @@ process_server_config_line(ServerOptions *options, char *line,
1128 break; 1167 break;
1129 1168
1130 case sHostKeyFile: 1169 case sHostKeyFile:
1131 intptr = &options->num_host_key_files;
1132 if (*intptr >= MAX_HOSTKEYS)
1133 fatal("%s line %d: too many host keys specified (max %d).",
1134 filename, linenum, MAX_HOSTKEYS);
1135 charptr = &options->host_key_files[*intptr];
1136 parse_filename:
1137 arg = strdelim(&cp); 1170 arg = strdelim(&cp);
1138 if (!arg || *arg == '\0') 1171 if (!arg || *arg == '\0')
1139 fatal("%s line %d: missing file name.", 1172 fatal("%s line %d: missing file name.",
1140 filename, linenum); 1173 filename, linenum);
1141 if (*activep && *charptr == NULL) { 1174 if (*activep)
1142 *charptr = derelativise_path(arg); 1175 servconf_add_hostkey(filename, linenum, options, arg);
1143 /* increase optional counter */
1144 if (intptr != NULL)
1145 *intptr = *intptr + 1;
1146 }
1147 break; 1176 break;
1148 1177
1149 case sHostKeyAgent: 1178 case sHostKeyAgent:
@@ -1158,17 +1187,28 @@ process_server_config_line(ServerOptions *options, char *line,
1158 break; 1187 break;
1159 1188
1160 case sHostCertificate: 1189 case sHostCertificate:
1161 intptr = &options->num_host_cert_files; 1190 arg = strdelim(&cp);
1162 if (*intptr >= MAX_HOSTKEYS) 1191 if (!arg || *arg == '\0')
1163 fatal("%s line %d: too many host certificates " 1192 fatal("%s line %d: missing file name.",
1164 "specified (max %d).", filename, linenum, 1193 filename, linenum);
1165 MAX_HOSTCERTS); 1194 if (*activep)
1166 charptr = &options->host_cert_files[*intptr]; 1195 servconf_add_hostcert(filename, linenum, options, arg);
1167 goto parse_filename; 1196 break;
1168 1197
1169 case sPidFile: 1198 case sPidFile:
1170 charptr = &options->pid_file; 1199 charptr = &options->pid_file;
1171 goto parse_filename; 1200 parse_filename:
1201 arg = strdelim(&cp);
1202 if (!arg || *arg == '\0')
1203 fatal("%s line %d: missing file name.",
1204 filename, linenum);
1205 if (*activep && *charptr == NULL) {
1206 *charptr = derelativise_path(arg);
1207 /* increase optional counter */
1208 if (intptr != NULL)
1209 *intptr = *intptr + 1;
1210 }
1211 break;
1172 1212
1173 case sPermitRootLogin: 1213 case sPermitRootLogin:
1174 intptr = &options->permit_root_login; 1214 intptr = &options->permit_root_login;
@@ -1412,55 +1452,47 @@ process_server_config_line(ServerOptions *options, char *line,
1412 1452
1413 case sAllowUsers: 1453 case sAllowUsers:
1414 while ((arg = strdelim(&cp)) && *arg != '\0') { 1454 while ((arg = strdelim(&cp)) && *arg != '\0') {
1415 if (options->num_allow_users >= MAX_ALLOW_USERS)
1416 fatal("%s line %d: too many allow users.",
1417 filename, linenum);
1418 if (match_user(NULL, NULL, NULL, arg) == -1) 1455 if (match_user(NULL, NULL, NULL, arg) == -1)
1419 fatal("%s line %d: invalid AllowUsers pattern: " 1456 fatal("%s line %d: invalid AllowUsers pattern: "
1420 "\"%.100s\"", filename, linenum, arg); 1457 "\"%.100s\"", filename, linenum, arg);
1421 if (!*activep) 1458 if (!*activep)
1422 continue; 1459 continue;
1423 options->allow_users[options->num_allow_users++] = 1460 array_append(filename, linenum, "AllowUsers",
1424 xstrdup(arg); 1461 &options->allow_users, &options->num_allow_users,
1462 arg);
1425 } 1463 }
1426 break; 1464 break;
1427 1465
1428 case sDenyUsers: 1466 case sDenyUsers:
1429 while ((arg = strdelim(&cp)) && *arg != '\0') { 1467 while ((arg = strdelim(&cp)) && *arg != '\0') {
1430 if (options->num_deny_users >= MAX_DENY_USERS)
1431 fatal("%s line %d: too many deny users.",
1432 filename, linenum);
1433 if (match_user(NULL, NULL, NULL, arg) == -1) 1468 if (match_user(NULL, NULL, NULL, arg) == -1)
1434 fatal("%s line %d: invalid DenyUsers pattern: " 1469 fatal("%s line %d: invalid DenyUsers pattern: "
1435 "\"%.100s\"", filename, linenum, arg); 1470 "\"%.100s\"", filename, linenum, arg);
1436 if (!*activep) 1471 if (!*activep)
1437 continue; 1472 continue;
1438 options->deny_users[options->num_deny_users++] = 1473 array_append(filename, linenum, "DenyUsers",
1439 xstrdup(arg); 1474 &options->deny_users, &options->num_deny_users,
1475 arg);
1440 } 1476 }
1441 break; 1477 break;
1442 1478
1443 case sAllowGroups: 1479 case sAllowGroups:
1444 while ((arg = strdelim(&cp)) && *arg != '\0') { 1480 while ((arg = strdelim(&cp)) && *arg != '\0') {
1445 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1446 fatal("%s line %d: too many allow groups.",
1447 filename, linenum);
1448 if (!*activep) 1481 if (!*activep)
1449 continue; 1482 continue;
1450 options->allow_groups[options->num_allow_groups++] = 1483 array_append(filename, linenum, "AllowGroups",
1451 xstrdup(arg); 1484 &options->allow_groups, &options->num_allow_groups,
1485 arg);
1452 } 1486 }
1453 break; 1487 break;
1454 1488
1455 case sDenyGroups: 1489 case sDenyGroups:
1456 while ((arg = strdelim(&cp)) && *arg != '\0') { 1490 while ((arg = strdelim(&cp)) && *arg != '\0') {
1457 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1458 fatal("%s line %d: too many deny groups.",
1459 filename, linenum);
1460 if (!*activep) 1491 if (!*activep)
1461 continue; 1492 continue;
1462 options->deny_groups[options->num_deny_groups++] = 1493 array_append(filename, linenum, "DenyGroups",
1463 xstrdup(arg); 1494 &options->deny_groups, &options->num_deny_groups,
1495 arg);
1464 } 1496 }
1465 break; 1497 break;
1466 1498
@@ -1579,14 +1611,12 @@ process_server_config_line(ServerOptions *options, char *line,
1579 case sAuthorizedKeysFile: 1611 case sAuthorizedKeysFile:
1580 if (*activep && options->num_authkeys_files == 0) { 1612 if (*activep && options->num_authkeys_files == 0) {
1581 while ((arg = strdelim(&cp)) && *arg != '\0') { 1613 while ((arg = strdelim(&cp)) && *arg != '\0') {
1582 if (options->num_authkeys_files >= 1614 arg = tilde_expand_filename(arg, getuid());
1583 MAX_AUTHKEYS_FILES) 1615 array_append(filename, linenum,
1584 fatal("%s line %d: " 1616 "AuthorizedKeysFile",
1585 "too many authorized keys files.", 1617 &options->authorized_keys_files,
1586 filename, linenum); 1618 &options->num_authkeys_files, arg);
1587 options->authorized_keys_files[ 1619 free(arg);
1588 options->num_authkeys_files++] =
1589 tilde_expand_filename(arg, getuid());
1590 } 1620 }
1591 } 1621 }
1592 return 0; 1622 return 0;
@@ -1618,13 +1648,11 @@ process_server_config_line(ServerOptions *options, char *line,
1618 if (strchr(arg, '=') != NULL) 1648 if (strchr(arg, '=') != NULL)
1619 fatal("%s line %d: Invalid environment name.", 1649 fatal("%s line %d: Invalid environment name.",
1620 filename, linenum); 1650 filename, linenum);
1621 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1622 fatal("%s line %d: too many allow env.",
1623 filename, linenum);
1624 if (!*activep) 1651 if (!*activep)
1625 continue; 1652 continue;
1626 options->accept_env[options->num_accept_env++] = 1653 array_append(filename, linenum, "AcceptEnv",
1627 xstrdup(arg); 1654 &options->accept_env, &options->num_accept_env,
1655 arg);
1628 } 1656 }
1629 break; 1657 break;
1630 1658
@@ -1684,15 +1712,12 @@ process_server_config_line(ServerOptions *options, char *line,
1684 fatal("%s line %d: bad port number in " 1712 fatal("%s line %d: bad port number in "
1685 "PermitOpen", filename, linenum); 1713 "PermitOpen", filename, linenum);
1686 if (*activep && value == 0) { 1714 if (*activep && value == 0) {
1687 options->permitted_opens = xrecallocarray( 1715 array_append(filename, linenum,
1688 options->permitted_opens, 1716 "PermitOpen",
1689 options->num_permitted_opens, 1717 &options->permitted_opens,
1690 options->num_permitted_opens + 1, 1718 &options->num_permitted_opens, arg2);
1691 sizeof(*options->permitted_opens)); 1719 }
1692 i = options->num_permitted_opens++; 1720 free(arg2);
1693 options->permitted_opens[i] = arg2;
1694 } else
1695 free(arg2);
1696 } 1721 }
1697 break; 1722 break;
1698 1723
@@ -1815,11 +1840,6 @@ process_server_config_line(ServerOptions *options, char *line,
1815 value = 0; /* seen "any" pseudo-method */ 1840 value = 0; /* seen "any" pseudo-method */
1816 value2 = 0; /* sucessfully parsed any method */ 1841 value2 = 0; /* sucessfully parsed any method */
1817 while ((arg = strdelim(&cp)) && *arg != '\0') { 1842 while ((arg = strdelim(&cp)) && *arg != '\0') {
1818 if (options->num_auth_methods >=
1819 MAX_AUTH_METHODS)
1820 fatal("%s line %d: "
1821 "too many authentication methods.",
1822 filename, linenum);
1823 if (strcmp(arg, "any") == 0) { 1843 if (strcmp(arg, "any") == 0) {
1824 if (options->num_auth_methods > 0) { 1844 if (options->num_auth_methods > 0) {
1825 fatal("%s line %d: \"any\" " 1845 fatal("%s line %d: \"any\" "
@@ -1840,8 +1860,10 @@ process_server_config_line(ServerOptions *options, char *line,
1840 value2 = 1; 1860 value2 = 1;
1841 if (!*activep) 1861 if (!*activep)
1842 continue; 1862 continue;
1843 options->auth_methods[ 1863 array_append(filename, linenum,
1844 options->num_auth_methods++] = xstrdup(arg); 1864 "AuthenticationMethods",
1865 &options->auth_methods,
1866 &options->num_auth_methods, arg);
1845 } 1867 }
1846 if (value2 == 0) { 1868 if (value2 == 0) {
1847 fatal("%s line %d: no AuthenticationMethods " 1869 fatal("%s line %d: no AuthenticationMethods "
@@ -2057,17 +2079,16 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2057 dst->n = src->n; \ 2079 dst->n = src->n; \
2058 } \ 2080 } \
2059} while(0) 2081} while(0)
2060#define M_CP_STRARRAYOPT(n, num_n) do {\ 2082#define M_CP_STRARRAYOPT(s, num_s) do {\
2061 if (src->num_n != 0) { \ 2083 u_int i; \
2062 for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ 2084 if (src->num_s != 0) { \
2063 dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ 2085 for (i = 0; i < dst->num_s; i++) \
2064 } \ 2086 free(dst->s[i]); \
2065} while(0) 2087 free(dst->s); \
2066#define M_CP_STRARRAYOPT_ALLOC(n, num_n) do { \ 2088 dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2067 if (src->num_n != 0) { \ 2089 for (i = 0; i < src->num_s; i++) \
2068 dst->n = xcalloc(src->num_n, sizeof(*dst->n)); \ 2090 dst->s[i] = xstrdup(src->s[i]); \
2069 M_CP_STRARRAYOPT(n, num_n); \ 2091 dst->num_s = src->num_s; \
2070 dst->num_n = src->num_n; \
2071 } \ 2092 } \
2072} while(0) 2093} while(0)
2073 2094
@@ -2100,7 +2121,6 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2100#undef M_CP_INTOPT 2121#undef M_CP_INTOPT
2101#undef M_CP_STROPT 2122#undef M_CP_STROPT
2102#undef M_CP_STRARRAYOPT 2123#undef M_CP_STRARRAYOPT
2103#undef M_CP_STRARRAYOPT_ALLOC
2104 2124
2105void 2125void
2106parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, 2126parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,