diff options
author | djm@openbsd.org <djm@openbsd.org> | 2017-10-05 15:52:03 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-10-20 12:01:02 +1100 |
commit | dceabc7ad7ebc7769c8214a1647af64c9a1d92e5 (patch) | |
tree | 513eb2c60aafcc240cd9bc2027a4f919a2934978 /servconf.c | |
parent | 2b4f3ab050c2aaf6977604dd037041372615178d (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.c | 210 |
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 | ||
191 | static void | ||
192 | array_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 | |||
204 | void | ||
205 | servconf_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 | |||
215 | void | ||
216 | servconf_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 | |||
191 | void | 226 | void |
192 | fill_default_server_options(ServerOptions *options) | 227 | fill_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 | ||
2105 | void | 2125 | void |
2106 | parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, | 2126 | parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, |