diff options
author | Colin Watson <cjwatson@debian.org> | 2018-08-24 12:49:36 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2018-08-24 12:49:36 +0100 |
commit | e6547182a54f0f268ee36e7c99319eeddffbaff2 (patch) | |
tree | 417527229ad3f3764ba71ea383f478a168895087 /servconf.c | |
parent | ed6ae9c1a014a08ff5db3d768f01f2e427eeb476 (diff) | |
parent | 71508e06fab14bc415a79a08f5535ad7bffa93d9 (diff) |
Import openssh_7.8p1.orig.tar.gz
Diffstat (limited to 'servconf.c')
-rw-r--r-- | servconf.c | 288 |
1 files changed, 201 insertions, 87 deletions
diff --git a/servconf.c b/servconf.c index 0f0d09068..c0f6af0be 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | /* $OpenBSD: servconf.c,v 1.326 2018/03/01 20:32:16 markus Exp $ */ | 2 | /* $OpenBSD: servconf.c,v 1.340 2018/08/12 20:19:13 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 |
@@ -45,13 +45,13 @@ | |||
45 | #include "xmalloc.h" | 45 | #include "xmalloc.h" |
46 | #include "ssh.h" | 46 | #include "ssh.h" |
47 | #include "log.h" | 47 | #include "log.h" |
48 | #include "buffer.h" | 48 | #include "sshbuf.h" |
49 | #include "misc.h" | 49 | #include "misc.h" |
50 | #include "servconf.h" | 50 | #include "servconf.h" |
51 | #include "compat.h" | 51 | #include "compat.h" |
52 | #include "pathnames.h" | 52 | #include "pathnames.h" |
53 | #include "cipher.h" | 53 | #include "cipher.h" |
54 | #include "key.h" | 54 | #include "sshkey.h" |
55 | #include "kex.h" | 55 | #include "kex.h" |
56 | #include "mac.h" | 56 | #include "mac.h" |
57 | #include "match.h" | 57 | #include "match.h" |
@@ -59,6 +59,7 @@ | |||
59 | #include "groupaccess.h" | 59 | #include "groupaccess.h" |
60 | #include "canohost.h" | 60 | #include "canohost.h" |
61 | #include "packet.h" | 61 | #include "packet.h" |
62 | #include "ssherr.h" | ||
62 | #include "hostfile.h" | 63 | #include "hostfile.h" |
63 | #include "auth.h" | 64 | #include "auth.h" |
64 | #include "myproposal.h" | 65 | #include "myproposal.h" |
@@ -71,7 +72,7 @@ static void add_one_listen_addr(ServerOptions *, const char *, | |||
71 | 72 | ||
72 | /* Use of privilege separation or not */ | 73 | /* Use of privilege separation or not */ |
73 | extern int use_privsep; | 74 | extern int use_privsep; |
74 | extern Buffer cfg; | 75 | extern struct sshbuf *cfg; |
75 | 76 | ||
76 | /* Initializes the server options to their default values. */ | 77 | /* Initializes the server options to their default values. */ |
77 | 78 | ||
@@ -130,6 +131,7 @@ initialize_server_options(ServerOptions *options) | |||
130 | options->challenge_response_authentication = -1; | 131 | options->challenge_response_authentication = -1; |
131 | options->permit_empty_passwd = -1; | 132 | options->permit_empty_passwd = -1; |
132 | options->permit_user_env = -1; | 133 | options->permit_user_env = -1; |
134 | options->permit_user_env_whitelist = NULL; | ||
133 | options->compression = -1; | 135 | options->compression = -1; |
134 | options->rekey_limit = -1; | 136 | options->rekey_limit = -1; |
135 | options->rekey_interval = -1; | 137 | options->rekey_interval = -1; |
@@ -158,8 +160,10 @@ initialize_server_options(ServerOptions *options) | |||
158 | options->client_alive_count_max = -1; | 160 | options->client_alive_count_max = -1; |
159 | options->num_authkeys_files = 0; | 161 | options->num_authkeys_files = 0; |
160 | options->num_accept_env = 0; | 162 | options->num_accept_env = 0; |
163 | options->num_setenv = 0; | ||
161 | options->permit_tun = -1; | 164 | options->permit_tun = -1; |
162 | options->permitted_opens = NULL; | 165 | options->permitted_opens = NULL; |
166 | options->permitted_listens = NULL; | ||
163 | options->adm_forced_command = NULL; | 167 | options->adm_forced_command = NULL; |
164 | options->chroot_directory = NULL; | 168 | options->chroot_directory = NULL; |
165 | options->authorized_keys_command = NULL; | 169 | options->authorized_keys_command = NULL; |
@@ -187,15 +191,29 @@ option_clear_or_none(const char *o) | |||
187 | static void | 191 | static void |
188 | assemble_algorithms(ServerOptions *o) | 192 | assemble_algorithms(ServerOptions *o) |
189 | { | 193 | { |
190 | if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 || | 194 | char *all_cipher, *all_mac, *all_kex, *all_key; |
191 | kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 || | 195 | int r; |
192 | kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 || | 196 | |
193 | kex_assemble_names(KEX_DEFAULT_PK_ALG, | 197 | all_cipher = cipher_alg_list(',', 0); |
194 | &o->hostkeyalgorithms) != 0 || | 198 | all_mac = mac_alg_list(','); |
195 | kex_assemble_names(KEX_DEFAULT_PK_ALG, | 199 | all_kex = kex_alg_list(','); |
196 | &o->hostbased_key_types) != 0 || | 200 | all_key = sshkey_alg_list(0, 0, 1, ','); |
197 | kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0) | 201 | #define ASSEMBLE(what, defaults, all) \ |
198 | fatal("kex_assemble_names failed"); | 202 | do { \ |
203 | if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ | ||
204 | fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ | ||
205 | } while (0) | ||
206 | ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher); | ||
207 | ASSEMBLE(macs, KEX_SERVER_MAC, all_mac); | ||
208 | ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); | ||
209 | ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key); | ||
210 | ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); | ||
211 | ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); | ||
212 | #undef ASSEMBLE | ||
213 | free(all_cipher); | ||
214 | free(all_mac); | ||
215 | free(all_kex); | ||
216 | free(all_key); | ||
199 | } | 217 | } |
200 | 218 | ||
201 | static void | 219 | static void |
@@ -327,8 +345,10 @@ fill_default_server_options(ServerOptions *options) | |||
327 | options->challenge_response_authentication = 1; | 345 | options->challenge_response_authentication = 1; |
328 | if (options->permit_empty_passwd == -1) | 346 | if (options->permit_empty_passwd == -1) |
329 | options->permit_empty_passwd = 0; | 347 | options->permit_empty_passwd = 0; |
330 | if (options->permit_user_env == -1) | 348 | if (options->permit_user_env == -1) { |
331 | options->permit_user_env = 0; | 349 | options->permit_user_env = 0; |
350 | options->permit_user_env_whitelist = NULL; | ||
351 | } | ||
332 | if (options->compression == -1) | 352 | if (options->compression == -1) |
333 | options->compression = COMP_DELAYED; | 353 | options->compression = COMP_DELAYED; |
334 | if (options->rekey_limit == -1) | 354 | if (options->rekey_limit == -1) |
@@ -372,9 +392,9 @@ fill_default_server_options(ServerOptions *options) | |||
372 | if (options->permit_tun == -1) | 392 | if (options->permit_tun == -1) |
373 | options->permit_tun = SSH_TUNMODE_NO; | 393 | options->permit_tun = SSH_TUNMODE_NO; |
374 | if (options->ip_qos_interactive == -1) | 394 | if (options->ip_qos_interactive == -1) |
375 | options->ip_qos_interactive = IPTOS_LOWDELAY; | 395 | options->ip_qos_interactive = IPTOS_DSCP_AF21; |
376 | if (options->ip_qos_bulk == -1) | 396 | if (options->ip_qos_bulk == -1) |
377 | options->ip_qos_bulk = IPTOS_THROUGHPUT; | 397 | options->ip_qos_bulk = IPTOS_DSCP_CS1; |
378 | if (options->version_addendum == NULL) | 398 | if (options->version_addendum == NULL) |
379 | options->version_addendum = xstrdup(""); | 399 | options->version_addendum = xstrdup(""); |
380 | if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) | 400 | if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) |
@@ -461,8 +481,8 @@ typedef enum { | |||
461 | sHostKeyAlgorithms, | 481 | sHostKeyAlgorithms, |
462 | sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, | 482 | sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, |
463 | sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, | 483 | sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, |
464 | sAcceptEnv, sPermitTunnel, | 484 | sAcceptEnv, sSetEnv, sPermitTunnel, |
465 | sMatch, sPermitOpen, sForceCommand, sChrootDirectory, | 485 | sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, |
466 | sUsePrivilegeSeparation, sAllowAgentForwarding, | 486 | sUsePrivilegeSeparation, sAllowAgentForwarding, |
467 | sHostCertificate, | 487 | sHostCertificate, |
468 | sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, | 488 | sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
@@ -544,7 +564,7 @@ static struct { | |||
544 | { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, | 564 | { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, |
545 | { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, | 565 | { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, |
546 | { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, | 566 | { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, |
547 | { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ | 567 | { "skeyauthentication", sDeprecated, SSHCFG_GLOBAL }, |
548 | { "checkmail", sDeprecated, SSHCFG_GLOBAL }, | 568 | { "checkmail", sDeprecated, SSHCFG_GLOBAL }, |
549 | { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, | 569 | { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, |
550 | { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, | 570 | { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, |
@@ -592,11 +612,13 @@ static struct { | |||
592 | { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL }, | 612 | { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL }, |
593 | { "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL}, | 613 | { "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL}, |
594 | { "acceptenv", sAcceptEnv, SSHCFG_ALL }, | 614 | { "acceptenv", sAcceptEnv, SSHCFG_ALL }, |
615 | { "setenv", sSetEnv, SSHCFG_ALL }, | ||
595 | { "permittunnel", sPermitTunnel, SSHCFG_ALL }, | 616 | { "permittunnel", sPermitTunnel, SSHCFG_ALL }, |
596 | { "permittty", sPermitTTY, SSHCFG_ALL }, | 617 | { "permittty", sPermitTTY, SSHCFG_ALL }, |
597 | { "permituserrc", sPermitUserRC, SSHCFG_ALL }, | 618 | { "permituserrc", sPermitUserRC, SSHCFG_ALL }, |
598 | { "match", sMatch, SSHCFG_ALL }, | 619 | { "match", sMatch, SSHCFG_ALL }, |
599 | { "permitopen", sPermitOpen, SSHCFG_ALL }, | 620 | { "permitopen", sPermitOpen, SSHCFG_ALL }, |
621 | { "permitlisten", sPermitListen, SSHCFG_ALL }, | ||
600 | { "forcecommand", sForceCommand, SSHCFG_ALL }, | 622 | { "forcecommand", sForceCommand, SSHCFG_ALL }, |
601 | { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, | 623 | { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, |
602 | { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, | 624 | { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, |
@@ -632,6 +654,20 @@ static struct { | |||
632 | { -1, NULL } | 654 | { -1, NULL } |
633 | }; | 655 | }; |
634 | 656 | ||
657 | /* Returns an opcode name from its number */ | ||
658 | |||
659 | static const char * | ||
660 | lookup_opcode_name(ServerOpCodes code) | ||
661 | { | ||
662 | u_int i; | ||
663 | |||
664 | for (i = 0; keywords[i].name != NULL; i++) | ||
665 | if (keywords[i].opcode == code) | ||
666 | return(keywords[i].name); | ||
667 | return "UNKNOWN"; | ||
668 | } | ||
669 | |||
670 | |||
635 | /* | 671 | /* |
636 | * Returns the number of the token pointed to by cp or sBadOption. | 672 | * Returns the number of the token pointed to by cp or sBadOption. |
637 | */ | 673 | */ |
@@ -814,43 +850,59 @@ process_queued_listen_addrs(ServerOptions *options) | |||
814 | } | 850 | } |
815 | 851 | ||
816 | /* | 852 | /* |
817 | * Inform channels layer of permitopen options from configuration. | 853 | * Inform channels layer of permitopen options for a single forwarding |
854 | * direction (local/remote). | ||
818 | */ | 855 | */ |
819 | void | 856 | static void |
820 | process_permitopen(struct ssh *ssh, ServerOptions *options) | 857 | process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode, |
858 | char **opens, u_int num_opens) | ||
821 | { | 859 | { |
822 | u_int i; | 860 | u_int i; |
823 | int port; | 861 | int port; |
824 | char *host, *arg, *oarg; | 862 | char *host, *arg, *oarg; |
863 | int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE; | ||
864 | const char *what = lookup_opcode_name(opcode); | ||
825 | 865 | ||
826 | channel_clear_adm_permitted_opens(ssh); | 866 | channel_clear_permission(ssh, FORWARD_ADM, where); |
827 | if (options->num_permitted_opens == 0) | 867 | if (num_opens == 0) |
828 | return; /* permit any */ | 868 | return; /* permit any */ |
829 | 869 | ||
830 | /* handle keywords: "any" / "none" */ | 870 | /* handle keywords: "any" / "none" */ |
831 | if (options->num_permitted_opens == 1 && | 871 | if (num_opens == 1 && strcmp(opens[0], "any") == 0) |
832 | strcmp(options->permitted_opens[0], "any") == 0) | ||
833 | return; | 872 | return; |
834 | if (options->num_permitted_opens == 1 && | 873 | if (num_opens == 1 && strcmp(opens[0], "none") == 0) { |
835 | strcmp(options->permitted_opens[0], "none") == 0) { | 874 | channel_disable_admin(ssh, where); |
836 | channel_disable_adm_local_opens(ssh); | ||
837 | return; | 875 | return; |
838 | } | 876 | } |
839 | /* Otherwise treat it as a list of permitted host:port */ | 877 | /* Otherwise treat it as a list of permitted host:port */ |
840 | for (i = 0; i < options->num_permitted_opens; i++) { | 878 | for (i = 0; i < num_opens; i++) { |
841 | oarg = arg = xstrdup(options->permitted_opens[i]); | 879 | oarg = arg = xstrdup(opens[i]); |
842 | host = hpdelim(&arg); | 880 | host = hpdelim(&arg); |
843 | if (host == NULL) | 881 | if (host == NULL) |
844 | fatal("%s: missing host in PermitOpen", __func__); | 882 | fatal("%s: missing host in %s", __func__, what); |
845 | host = cleanhostname(host); | 883 | host = cleanhostname(host); |
846 | if (arg == NULL || ((port = permitopen_port(arg)) < 0)) | 884 | if (arg == NULL || ((port = permitopen_port(arg)) < 0)) |
847 | fatal("%s: bad port number in PermitOpen", __func__); | 885 | fatal("%s: bad port number in %s", __func__, what); |
848 | /* Send it to channels layer */ | 886 | /* Send it to channels layer */ |
849 | channel_add_adm_permitted_opens(ssh, host, port); | 887 | channel_add_permission(ssh, FORWARD_ADM, |
888 | where, host, port); | ||
850 | free(oarg); | 889 | free(oarg); |
851 | } | 890 | } |
852 | } | 891 | } |
853 | 892 | ||
893 | /* | ||
894 | * Inform channels layer of permitopen options from configuration. | ||
895 | */ | ||
896 | void | ||
897 | process_permitopen(struct ssh *ssh, ServerOptions *options) | ||
898 | { | ||
899 | process_permitopen_list(ssh, sPermitOpen, | ||
900 | options->permitted_opens, options->num_permitted_opens); | ||
901 | process_permitopen_list(ssh, sPermitListen, | ||
902 | options->permitted_listens, | ||
903 | options->num_permitted_listens); | ||
904 | } | ||
905 | |||
854 | struct connection_info * | 906 | struct connection_info * |
855 | get_connection_info(int populate, int use_dns) | 907 | get_connection_info(int populate, int use_dns) |
856 | { | 908 | { |
@@ -1144,12 +1196,12 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1144 | const char *filename, int linenum, int *activep, | 1196 | const char *filename, int linenum, int *activep, |
1145 | struct connection_info *connectinfo) | 1197 | struct connection_info *connectinfo) |
1146 | { | 1198 | { |
1147 | char *cp, **charptr, *arg, *arg2, *p; | 1199 | char *cp, ***chararrayptr, **charptr, *arg, *arg2, *p; |
1148 | int cmdline = 0, *intptr, value, value2, n, port; | 1200 | int cmdline = 0, *intptr, value, value2, n, port; |
1149 | SyslogFacility *log_facility_ptr; | 1201 | SyslogFacility *log_facility_ptr; |
1150 | LogLevel *log_level_ptr; | 1202 | LogLevel *log_level_ptr; |
1151 | ServerOpCodes opcode; | 1203 | ServerOpCodes opcode; |
1152 | u_int i, flags = 0; | 1204 | u_int i, *uintptr, uvalue, flags = 0; |
1153 | size_t len; | 1205 | size_t len; |
1154 | long long val64; | 1206 | long long val64; |
1155 | const struct multistate *multistate_ptr; | 1207 | const struct multistate *multistate_ptr; |
@@ -1480,7 +1532,29 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1480 | 1532 | ||
1481 | case sPermitUserEnvironment: | 1533 | case sPermitUserEnvironment: |
1482 | intptr = &options->permit_user_env; | 1534 | intptr = &options->permit_user_env; |
1483 | goto parse_flag; | 1535 | charptr = &options->permit_user_env_whitelist; |
1536 | arg = strdelim(&cp); | ||
1537 | if (!arg || *arg == '\0') | ||
1538 | fatal("%s line %d: missing argument.", | ||
1539 | filename, linenum); | ||
1540 | value = 0; | ||
1541 | p = NULL; | ||
1542 | if (strcmp(arg, "yes") == 0) | ||
1543 | value = 1; | ||
1544 | else if (strcmp(arg, "no") == 0) | ||
1545 | value = 0; | ||
1546 | else { | ||
1547 | /* Pattern-list specified */ | ||
1548 | value = 1; | ||
1549 | p = xstrdup(arg); | ||
1550 | } | ||
1551 | if (*activep && *intptr == -1) { | ||
1552 | *intptr = value; | ||
1553 | *charptr = p; | ||
1554 | p = NULL; | ||
1555 | } | ||
1556 | free(p); | ||
1557 | break; | ||
1484 | 1558 | ||
1485 | case sCompression: | 1559 | case sCompression: |
1486 | intptr = &options->compression; | 1560 | intptr = &options->compression; |
@@ -1769,6 +1843,19 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1769 | } | 1843 | } |
1770 | break; | 1844 | break; |
1771 | 1845 | ||
1846 | case sSetEnv: | ||
1847 | uvalue = options->num_setenv; | ||
1848 | while ((arg = strdelimw(&cp)) && *arg != '\0') { | ||
1849 | if (strchr(arg, '=') == NULL) | ||
1850 | fatal("%s line %d: Invalid environment.", | ||
1851 | filename, linenum); | ||
1852 | if (!*activep || uvalue != 0) | ||
1853 | continue; | ||
1854 | array_append(filename, linenum, "SetEnv", | ||
1855 | &options->setenv, &options->num_setenv, arg); | ||
1856 | } | ||
1857 | break; | ||
1858 | |||
1772 | case sPermitTunnel: | 1859 | case sPermitTunnel: |
1773 | intptr = &options->permit_tun; | 1860 | intptr = &options->permit_tun; |
1774 | arg = strdelim(&cp); | 1861 | arg = strdelim(&cp); |
@@ -1799,36 +1886,57 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1799 | *activep = value; | 1886 | *activep = value; |
1800 | break; | 1887 | break; |
1801 | 1888 | ||
1889 | case sPermitListen: | ||
1802 | case sPermitOpen: | 1890 | case sPermitOpen: |
1891 | if (opcode == sPermitListen) { | ||
1892 | uintptr = &options->num_permitted_listens; | ||
1893 | chararrayptr = &options->permitted_listens; | ||
1894 | } else { | ||
1895 | uintptr = &options->num_permitted_opens; | ||
1896 | chararrayptr = &options->permitted_opens; | ||
1897 | } | ||
1803 | arg = strdelim(&cp); | 1898 | arg = strdelim(&cp); |
1804 | if (!arg || *arg == '\0') | 1899 | if (!arg || *arg == '\0') |
1805 | fatal("%s line %d: missing PermitOpen specification", | 1900 | fatal("%s line %d: missing %s specification", |
1806 | filename, linenum); | 1901 | filename, linenum, lookup_opcode_name(opcode)); |
1807 | value = options->num_permitted_opens; /* modified later */ | 1902 | uvalue = *uintptr; /* modified later */ |
1808 | if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { | 1903 | if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { |
1809 | if (*activep && value == 0) { | 1904 | if (*activep && uvalue == 0) { |
1810 | options->num_permitted_opens = 1; | 1905 | *uintptr = 1; |
1811 | options->permitted_opens = xcalloc(1, | 1906 | *chararrayptr = xcalloc(1, |
1812 | sizeof(*options->permitted_opens)); | 1907 | sizeof(**chararrayptr)); |
1813 | options->permitted_opens[0] = xstrdup(arg); | 1908 | (*chararrayptr)[0] = xstrdup(arg); |
1814 | } | 1909 | } |
1815 | break; | 1910 | break; |
1816 | } | 1911 | } |
1817 | for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { | 1912 | for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { |
1818 | arg2 = xstrdup(arg); | 1913 | if (opcode == sPermitListen && |
1819 | p = hpdelim(&arg); | 1914 | strchr(arg, ':') == NULL) { |
1820 | if (p == NULL) | 1915 | /* |
1821 | fatal("%s line %d: missing host in PermitOpen", | 1916 | * Allow bare port number for PermitListen |
1822 | filename, linenum); | 1917 | * to indicate a wildcard listen host. |
1823 | p = cleanhostname(p); | 1918 | */ |
1824 | if (arg == NULL || ((port = permitopen_port(arg)) < 0)) | 1919 | xasprintf(&arg2, "*:%s", arg); |
1825 | fatal("%s line %d: bad port number in " | 1920 | } else { |
1826 | "PermitOpen", filename, linenum); | 1921 | arg2 = xstrdup(arg); |
1827 | if (*activep && value == 0) { | 1922 | p = hpdelim(&arg); |
1923 | if (p == NULL) { | ||
1924 | fatal("%s line %d: missing host in %s", | ||
1925 | filename, linenum, | ||
1926 | lookup_opcode_name(opcode)); | ||
1927 | } | ||
1928 | p = cleanhostname(p); | ||
1929 | } | ||
1930 | if (arg == NULL || | ||
1931 | ((port = permitopen_port(arg)) < 0)) { | ||
1932 | fatal("%s line %d: bad port number in %s", | ||
1933 | filename, linenum, | ||
1934 | lookup_opcode_name(opcode)); | ||
1935 | } | ||
1936 | if (*activep && uvalue == 0) { | ||
1828 | array_append(filename, linenum, | 1937 | array_append(filename, linenum, |
1829 | "PermitOpen", | 1938 | lookup_opcode_name(opcode), |
1830 | &options->permitted_opens, | 1939 | chararrayptr, uintptr, arg2); |
1831 | &options->num_permitted_opens, arg2); | ||
1832 | } | 1940 | } |
1833 | free(arg2); | 1941 | free(arg2); |
1834 | } | 1942 | } |
@@ -1951,7 +2059,7 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1951 | case sAuthenticationMethods: | 2059 | case sAuthenticationMethods: |
1952 | if (options->num_auth_methods == 0) { | 2060 | if (options->num_auth_methods == 0) { |
1953 | value = 0; /* seen "any" pseudo-method */ | 2061 | value = 0; /* seen "any" pseudo-method */ |
1954 | value2 = 0; /* sucessfully parsed any method */ | 2062 | value2 = 0; /* successfully parsed any method */ |
1955 | while ((arg = strdelim(&cp)) && *arg != '\0') { | 2063 | while ((arg = strdelim(&cp)) && *arg != '\0') { |
1956 | if (strcmp(arg, "any") == 0) { | 2064 | if (strcmp(arg, "any") == 0) { |
1957 | if (options->num_auth_methods > 0) { | 2065 | if (options->num_auth_methods > 0) { |
@@ -2056,22 +2164,21 @@ process_server_config_line(ServerOptions *options, char *line, | |||
2056 | /* Reads the server configuration file. */ | 2164 | /* Reads the server configuration file. */ |
2057 | 2165 | ||
2058 | void | 2166 | void |
2059 | load_server_config(const char *filename, Buffer *conf) | 2167 | load_server_config(const char *filename, struct sshbuf *conf) |
2060 | { | 2168 | { |
2061 | char line[4096], *cp; | 2169 | char *line = NULL, *cp; |
2170 | size_t linesize = 0; | ||
2062 | FILE *f; | 2171 | FILE *f; |
2063 | int lineno = 0; | 2172 | int r, lineno = 0; |
2064 | 2173 | ||
2065 | debug2("%s: filename %s", __func__, filename); | 2174 | debug2("%s: filename %s", __func__, filename); |
2066 | if ((f = fopen(filename, "r")) == NULL) { | 2175 | if ((f = fopen(filename, "r")) == NULL) { |
2067 | perror(filename); | 2176 | perror(filename); |
2068 | exit(1); | 2177 | exit(1); |
2069 | } | 2178 | } |
2070 | buffer_clear(conf); | 2179 | sshbuf_reset(conf); |
2071 | while (fgets(line, sizeof(line), f)) { | 2180 | while (getline(&line, &linesize, f) != -1) { |
2072 | lineno++; | 2181 | lineno++; |
2073 | if (strlen(line) == sizeof(line) - 1) | ||
2074 | fatal("%s line %d too long", filename, lineno); | ||
2075 | /* | 2182 | /* |
2076 | * Trim out comments and strip whitespace | 2183 | * Trim out comments and strip whitespace |
2077 | * NB - preserve newlines, they are needed to reproduce | 2184 | * NB - preserve newlines, they are needed to reproduce |
@@ -2080,12 +2187,14 @@ load_server_config(const char *filename, Buffer *conf) | |||
2080 | if ((cp = strchr(line, '#')) != NULL) | 2187 | if ((cp = strchr(line, '#')) != NULL) |
2081 | memcpy(cp, "\n", 2); | 2188 | memcpy(cp, "\n", 2); |
2082 | cp = line + strspn(line, " \t\r"); | 2189 | cp = line + strspn(line, " \t\r"); |
2083 | 2190 | if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0) | |
2084 | buffer_append(conf, cp, strlen(cp)); | 2191 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
2085 | } | 2192 | } |
2086 | buffer_append(conf, "\0", 1); | 2193 | free(line); |
2194 | if ((r = sshbuf_put_u8(conf, 0)) != 0) | ||
2195 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
2087 | fclose(f); | 2196 | fclose(f); |
2088 | debug2("%s: done config len = %d", __func__, buffer_len(conf)); | 2197 | debug2("%s: done config len = %zu", __func__, sshbuf_len(conf)); |
2089 | } | 2198 | } |
2090 | 2199 | ||
2091 | void | 2200 | void |
@@ -2095,7 +2204,7 @@ parse_server_match_config(ServerOptions *options, | |||
2095 | ServerOptions mo; | 2204 | ServerOptions mo; |
2096 | 2205 | ||
2097 | initialize_server_options(&mo); | 2206 | initialize_server_options(&mo); |
2098 | parse_server_config(&mo, "reprocess config", &cfg, connectinfo); | 2207 | parse_server_config(&mo, "reprocess config", cfg, connectinfo); |
2099 | copy_set_server_options(options, &mo, 0); | 2208 | copy_set_server_options(options, &mo, 0); |
2100 | } | 2209 | } |
2101 | 2210 | ||
@@ -2135,7 +2244,7 @@ int parse_server_match_testspec(struct connection_info *ci, char *spec) | |||
2135 | * | 2244 | * |
2136 | * If the preauth flag is set, we do not bother copying the string or | 2245 | * If the preauth flag is set, we do not bother copying the string or |
2137 | * array values that are not used pre-authentication, because any that we | 2246 | * array values that are not used pre-authentication, because any that we |
2138 | * do use must be explictly sent in mm_getpwnamallow(). | 2247 | * do use must be explicitly sent in mm_getpwnamallow(). |
2139 | */ | 2248 | */ |
2140 | void | 2249 | void |
2141 | copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | 2250 | copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) |
@@ -2239,13 +2348,13 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | |||
2239 | #undef M_CP_STRARRAYOPT | 2348 | #undef M_CP_STRARRAYOPT |
2240 | 2349 | ||
2241 | void | 2350 | void |
2242 | parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, | 2351 | parse_server_config(ServerOptions *options, const char *filename, |
2243 | struct connection_info *connectinfo) | 2352 | struct sshbuf *conf, struct connection_info *connectinfo) |
2244 | { | 2353 | { |
2245 | int active, linenum, bad_options = 0; | 2354 | int active, linenum, bad_options = 0; |
2246 | char *cp, *obuf, *cbuf; | 2355 | char *cp, *obuf, *cbuf; |
2247 | 2356 | ||
2248 | debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); | 2357 | debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf)); |
2249 | 2358 | ||
2250 | if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) | 2359 | if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) |
2251 | fatal("%s: sshbuf_dup_string failed", __func__); | 2360 | fatal("%s: sshbuf_dup_string failed", __func__); |
@@ -2307,17 +2416,6 @@ fmt_intarg(ServerOpCodes code, int val) | |||
2307 | } | 2416 | } |
2308 | } | 2417 | } |
2309 | 2418 | ||
2310 | static const char * | ||
2311 | lookup_opcode_name(ServerOpCodes code) | ||
2312 | { | ||
2313 | u_int i; | ||
2314 | |||
2315 | for (i = 0; keywords[i].name != NULL; i++) | ||
2316 | if (keywords[i].opcode == code) | ||
2317 | return(keywords[i].name); | ||
2318 | return "UNKNOWN"; | ||
2319 | } | ||
2320 | |||
2321 | static void | 2419 | static void |
2322 | dump_cfg_int(ServerOpCodes code, int val) | 2420 | dump_cfg_int(ServerOpCodes code, int val) |
2323 | { | 2421 | { |
@@ -2471,7 +2569,6 @@ dump_config(ServerOptions *o) | |||
2471 | dump_cfg_fmtint(sStrictModes, o->strict_modes); | 2569 | dump_cfg_fmtint(sStrictModes, o->strict_modes); |
2472 | dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); | 2570 | dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); |
2473 | dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); | 2571 | dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); |
2474 | dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); | ||
2475 | dump_cfg_fmtint(sCompression, o->compression); | 2572 | dump_cfg_fmtint(sCompression, o->compression); |
2476 | dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); | 2573 | dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); |
2477 | dump_cfg_fmtint(sUseDNS, o->use_dns); | 2574 | dump_cfg_fmtint(sUseDNS, o->use_dns); |
@@ -2528,6 +2625,7 @@ dump_config(ServerOptions *o) | |||
2528 | dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); | 2625 | dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); |
2529 | dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); | 2626 | dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); |
2530 | dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); | 2627 | dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); |
2628 | dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv); | ||
2531 | dump_cfg_strarray_oneline(sAuthenticationMethods, | 2629 | dump_cfg_strarray_oneline(sAuthenticationMethods, |
2532 | o->num_auth_methods, o->auth_methods); | 2630 | o->num_auth_methods, o->auth_methods); |
2533 | 2631 | ||
@@ -2562,4 +2660,20 @@ dump_config(ServerOptions *o) | |||
2562 | printf(" %s", o->permitted_opens[i]); | 2660 | printf(" %s", o->permitted_opens[i]); |
2563 | } | 2661 | } |
2564 | printf("\n"); | 2662 | printf("\n"); |
2663 | printf("permitlisten"); | ||
2664 | if (o->num_permitted_listens == 0) | ||
2665 | printf(" any"); | ||
2666 | else { | ||
2667 | for (i = 0; i < o->num_permitted_listens; i++) | ||
2668 | printf(" %s", o->permitted_listens[i]); | ||
2669 | } | ||
2670 | printf("\n"); | ||
2671 | |||
2672 | if (o->permit_user_env_whitelist == NULL) { | ||
2673 | dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); | ||
2674 | } else { | ||
2675 | printf("permituserenvironment %s\n", | ||
2676 | o->permit_user_env_whitelist); | ||
2677 | } | ||
2678 | |||
2565 | } | 2679 | } |