summaryrefslogtreecommitdiff
path: root/servconf.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2018-08-24 12:49:36 +0100
committerColin Watson <cjwatson@debian.org>2018-08-24 12:49:36 +0100
commite6547182a54f0f268ee36e7c99319eeddffbaff2 (patch)
tree417527229ad3f3764ba71ea383f478a168895087 /servconf.c
parented6ae9c1a014a08ff5db3d768f01f2e427eeb476 (diff)
parent71508e06fab14bc415a79a08f5535ad7bffa93d9 (diff)
Import openssh_7.8p1.orig.tar.gz
Diffstat (limited to 'servconf.c')
-rw-r--r--servconf.c288
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 */
73extern int use_privsep; 74extern int use_privsep;
74extern Buffer cfg; 75extern 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)
187static void 191static void
188assemble_algorithms(ServerOptions *o) 192assemble_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
201static void 219static 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
659static const char *
660lookup_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 */
819void 856static void
820process_permitopen(struct ssh *ssh, ServerOptions *options) 857process_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 */
896void
897process_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
854struct connection_info * 906struct connection_info *
855get_connection_info(int populate, int use_dns) 907get_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
2058void 2166void
2059load_server_config(const char *filename, Buffer *conf) 2167load_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
2091void 2200void
@@ -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 */
2140void 2249void
2141copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) 2250copy_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
2241void 2350void
2242parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, 2351parse_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
2310static const char *
2311lookup_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
2321static void 2419static void
2322dump_cfg_int(ServerOpCodes code, int val) 2420dump_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}