diff options
Diffstat (limited to 'servconf.c')
-rw-r--r-- | servconf.c | 138 |
1 files changed, 90 insertions, 48 deletions
diff --git a/servconf.c b/servconf.c index 5ca84515f..b75faf3f8 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | /* $OpenBSD: servconf.c,v 1.328 2018/04/10 00:10:49 djm Exp $ */ | 2 | /* $OpenBSD: servconf.c,v 1.329 2018/06/06 18:22:41 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 |
@@ -160,6 +160,7 @@ initialize_server_options(ServerOptions *options) | |||
160 | options->num_accept_env = 0; | 160 | options->num_accept_env = 0; |
161 | options->permit_tun = -1; | 161 | options->permit_tun = -1; |
162 | options->permitted_opens = NULL; | 162 | options->permitted_opens = NULL; |
163 | options->permitted_remote_opens = NULL; | ||
163 | options->adm_forced_command = NULL; | 164 | options->adm_forced_command = NULL; |
164 | options->chroot_directory = NULL; | 165 | options->chroot_directory = NULL; |
165 | options->authorized_keys_command = NULL; | 166 | options->authorized_keys_command = NULL; |
@@ -462,7 +463,7 @@ typedef enum { | |||
462 | sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, | 463 | sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, |
463 | sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, | 464 | sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, |
464 | sAcceptEnv, sPermitTunnel, | 465 | sAcceptEnv, sPermitTunnel, |
465 | sMatch, sPermitOpen, sForceCommand, sChrootDirectory, | 466 | sMatch, sPermitOpen, sPermitRemoteOpen, sForceCommand, sChrootDirectory, |
466 | sUsePrivilegeSeparation, sAllowAgentForwarding, | 467 | sUsePrivilegeSeparation, sAllowAgentForwarding, |
467 | sHostCertificate, | 468 | sHostCertificate, |
468 | sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, | 469 | sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
@@ -597,6 +598,7 @@ static struct { | |||
597 | { "permituserrc", sPermitUserRC, SSHCFG_ALL }, | 598 | { "permituserrc", sPermitUserRC, SSHCFG_ALL }, |
598 | { "match", sMatch, SSHCFG_ALL }, | 599 | { "match", sMatch, SSHCFG_ALL }, |
599 | { "permitopen", sPermitOpen, SSHCFG_ALL }, | 600 | { "permitopen", sPermitOpen, SSHCFG_ALL }, |
601 | { "permitremoteopen", sPermitRemoteOpen, SSHCFG_ALL }, | ||
600 | { "forcecommand", sForceCommand, SSHCFG_ALL }, | 602 | { "forcecommand", sForceCommand, SSHCFG_ALL }, |
601 | { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, | 603 | { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, |
602 | { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, | 604 | { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, |
@@ -632,6 +634,20 @@ static struct { | |||
632 | { -1, NULL } | 634 | { -1, NULL } |
633 | }; | 635 | }; |
634 | 636 | ||
637 | /* Returns an opcode name from its number */ | ||
638 | |||
639 | static const char * | ||
640 | lookup_opcode_name(ServerOpCodes code) | ||
641 | { | ||
642 | u_int i; | ||
643 | |||
644 | for (i = 0; keywords[i].name != NULL; i++) | ||
645 | if (keywords[i].opcode == code) | ||
646 | return(keywords[i].name); | ||
647 | return "UNKNOWN"; | ||
648 | } | ||
649 | |||
650 | |||
635 | /* | 651 | /* |
636 | * Returns the number of the token pointed to by cp or sBadOption. | 652 | * Returns the number of the token pointed to by cp or sBadOption. |
637 | */ | 653 | */ |
@@ -814,43 +830,59 @@ process_queued_listen_addrs(ServerOptions *options) | |||
814 | } | 830 | } |
815 | 831 | ||
816 | /* | 832 | /* |
817 | * Inform channels layer of permitopen options from configuration. | 833 | * Inform channels layer of permitopen options for a single forwarding |
834 | * direction (local/remote). | ||
818 | */ | 835 | */ |
819 | void | 836 | static void |
820 | process_permitopen(struct ssh *ssh, ServerOptions *options) | 837 | process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode, |
838 | char **opens, u_int num_opens) | ||
821 | { | 839 | { |
822 | u_int i; | 840 | u_int i; |
823 | int port; | 841 | int port; |
824 | char *host, *arg, *oarg; | 842 | char *host, *arg, *oarg; |
843 | int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE; | ||
844 | const char *what = lookup_opcode_name(opcode); | ||
825 | 845 | ||
826 | channel_clear_adm_permitted_opens(ssh); | 846 | channel_clear_permission(ssh, FORWARD_ADM, where); |
827 | if (options->num_permitted_opens == 0) | 847 | if (num_opens == 0) |
828 | return; /* permit any */ | 848 | return; /* permit any */ |
829 | 849 | ||
830 | /* handle keywords: "any" / "none" */ | 850 | /* handle keywords: "any" / "none" */ |
831 | if (options->num_permitted_opens == 1 && | 851 | if (num_opens == 1 && strcmp(opens[0], "any") == 0) |
832 | strcmp(options->permitted_opens[0], "any") == 0) | ||
833 | return; | 852 | return; |
834 | if (options->num_permitted_opens == 1 && | 853 | if (num_opens == 1 && strcmp(opens[0], "none") == 0) { |
835 | strcmp(options->permitted_opens[0], "none") == 0) { | 854 | channel_disable_admin(ssh, where); |
836 | channel_disable_adm_local_opens(ssh); | ||
837 | return; | 855 | return; |
838 | } | 856 | } |
839 | /* Otherwise treat it as a list of permitted host:port */ | 857 | /* Otherwise treat it as a list of permitted host:port */ |
840 | for (i = 0; i < options->num_permitted_opens; i++) { | 858 | for (i = 0; i < num_opens; i++) { |
841 | oarg = arg = xstrdup(options->permitted_opens[i]); | 859 | oarg = arg = xstrdup(opens[i]); |
842 | host = hpdelim(&arg); | 860 | host = hpdelim(&arg); |
843 | if (host == NULL) | 861 | if (host == NULL) |
844 | fatal("%s: missing host in PermitOpen", __func__); | 862 | fatal("%s: missing host in %s", __func__, what); |
845 | host = cleanhostname(host); | 863 | host = cleanhostname(host); |
846 | if (arg == NULL || ((port = permitopen_port(arg)) < 0)) | 864 | if (arg == NULL || ((port = permitopen_port(arg)) < 0)) |
847 | fatal("%s: bad port number in PermitOpen", __func__); | 865 | fatal("%s: bad port number in %s", __func__, what); |
848 | /* Send it to channels layer */ | 866 | /* Send it to channels layer */ |
849 | channel_add_adm_permitted_opens(ssh, host, port); | 867 | channel_add_permission(ssh, FORWARD_ADM, |
868 | where, host, port); | ||
850 | free(oarg); | 869 | free(oarg); |
851 | } | 870 | } |
852 | } | 871 | } |
853 | 872 | ||
873 | /* | ||
874 | * Inform channels layer of permitopen options from configuration. | ||
875 | */ | ||
876 | void | ||
877 | process_permitopen(struct ssh *ssh, ServerOptions *options) | ||
878 | { | ||
879 | process_permitopen_list(ssh, sPermitOpen, | ||
880 | options->permitted_opens, options->num_permitted_opens); | ||
881 | process_permitopen_list(ssh, sPermitRemoteOpen, | ||
882 | options->permitted_remote_opens, | ||
883 | options->num_permitted_remote_opens); | ||
884 | } | ||
885 | |||
854 | struct connection_info * | 886 | struct connection_info * |
855 | get_connection_info(int populate, int use_dns) | 887 | get_connection_info(int populate, int use_dns) |
856 | { | 888 | { |
@@ -1144,12 +1176,12 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1144 | const char *filename, int linenum, int *activep, | 1176 | const char *filename, int linenum, int *activep, |
1145 | struct connection_info *connectinfo) | 1177 | struct connection_info *connectinfo) |
1146 | { | 1178 | { |
1147 | char *cp, **charptr, *arg, *arg2, *p; | 1179 | char *cp, ***chararrayptr, **charptr, *arg, *arg2, *p; |
1148 | int cmdline = 0, *intptr, value, value2, n, port; | 1180 | int cmdline = 0, *intptr, value, value2, n, port; |
1149 | SyslogFacility *log_facility_ptr; | 1181 | SyslogFacility *log_facility_ptr; |
1150 | LogLevel *log_level_ptr; | 1182 | LogLevel *log_level_ptr; |
1151 | ServerOpCodes opcode; | 1183 | ServerOpCodes opcode; |
1152 | u_int i, flags = 0; | 1184 | u_int i, *uintptr, uvalue, flags = 0; |
1153 | size_t len; | 1185 | size_t len; |
1154 | long long val64; | 1186 | long long val64; |
1155 | const struct multistate *multistate_ptr; | 1187 | const struct multistate *multistate_ptr; |
@@ -1799,36 +1831,49 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1799 | *activep = value; | 1831 | *activep = value; |
1800 | break; | 1832 | break; |
1801 | 1833 | ||
1834 | case sPermitRemoteOpen: | ||
1802 | case sPermitOpen: | 1835 | case sPermitOpen: |
1836 | if (opcode == sPermitRemoteOpen) { | ||
1837 | uintptr = &options->num_permitted_remote_opens; | ||
1838 | chararrayptr = &options->permitted_remote_opens; | ||
1839 | } else { | ||
1840 | uintptr = &options->num_permitted_opens; | ||
1841 | chararrayptr = &options->permitted_opens; | ||
1842 | } | ||
1803 | arg = strdelim(&cp); | 1843 | arg = strdelim(&cp); |
1804 | if (!arg || *arg == '\0') | 1844 | if (!arg || *arg == '\0') |
1805 | fatal("%s line %d: missing PermitOpen specification", | 1845 | fatal("%s line %d: missing %s specification", |
1806 | filename, linenum); | 1846 | filename, linenum, lookup_opcode_name(opcode)); |
1807 | value = options->num_permitted_opens; /* modified later */ | 1847 | uvalue = *uintptr; /* modified later */ |
1808 | if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { | 1848 | if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { |
1809 | if (*activep && value == 0) { | 1849 | if (*activep && uvalue == 0) { |
1810 | options->num_permitted_opens = 1; | 1850 | *uintptr = 1; |
1811 | options->permitted_opens = xcalloc(1, | 1851 | *chararrayptr = xcalloc(1, |
1812 | sizeof(*options->permitted_opens)); | 1852 | sizeof(**chararrayptr)); |
1813 | options->permitted_opens[0] = xstrdup(arg); | 1853 | (*chararrayptr)[0] = xstrdup(arg); |
1814 | } | 1854 | } |
1815 | break; | 1855 | break; |
1816 | } | 1856 | } |
1817 | for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { | 1857 | for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { |
1818 | arg2 = xstrdup(arg); | 1858 | arg2 = xstrdup(arg); |
1819 | p = hpdelim(&arg); | 1859 | p = hpdelim(&arg); |
1820 | if (p == NULL) | 1860 | /* XXX support bare port number for PermitRemoteOpen */ |
1821 | fatal("%s line %d: missing host in PermitOpen", | 1861 | if (p == NULL) { |
1822 | filename, linenum); | 1862 | fatal("%s line %d: missing host in %s", |
1863 | filename, linenum, | ||
1864 | lookup_opcode_name(opcode)); | ||
1865 | } | ||
1823 | p = cleanhostname(p); | 1866 | p = cleanhostname(p); |
1824 | if (arg == NULL || ((port = permitopen_port(arg)) < 0)) | 1867 | if (arg == NULL || |
1825 | fatal("%s line %d: bad port number in " | 1868 | ((port = permitopen_port(arg)) < 0)) { |
1826 | "PermitOpen", filename, linenum); | 1869 | fatal("%s line %d: bad port number in %s", |
1827 | if (*activep && value == 0) { | 1870 | filename, linenum, |
1871 | lookup_opcode_name(opcode)); | ||
1872 | } | ||
1873 | if (*activep && uvalue == 0) { | ||
1828 | array_append(filename, linenum, | 1874 | array_append(filename, linenum, |
1829 | "PermitOpen", | 1875 | lookup_opcode_name(opcode), |
1830 | &options->permitted_opens, | 1876 | chararrayptr, uintptr, arg2); |
1831 | &options->num_permitted_opens, arg2); | ||
1832 | } | 1877 | } |
1833 | free(arg2); | 1878 | free(arg2); |
1834 | } | 1879 | } |
@@ -2307,17 +2352,6 @@ fmt_intarg(ServerOpCodes code, int val) | |||
2307 | } | 2352 | } |
2308 | } | 2353 | } |
2309 | 2354 | ||
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 | 2355 | static void |
2322 | dump_cfg_int(ServerOpCodes code, int val) | 2356 | dump_cfg_int(ServerOpCodes code, int val) |
2323 | { | 2357 | { |
@@ -2562,4 +2596,12 @@ dump_config(ServerOptions *o) | |||
2562 | printf(" %s", o->permitted_opens[i]); | 2596 | printf(" %s", o->permitted_opens[i]); |
2563 | } | 2597 | } |
2564 | printf("\n"); | 2598 | printf("\n"); |
2599 | printf("permitremoteopen"); | ||
2600 | if (o->num_permitted_remote_opens == 0) | ||
2601 | printf(" any"); | ||
2602 | else { | ||
2603 | for (i = 0; i < o->num_permitted_remote_opens; i++) | ||
2604 | printf(" %s", o->permitted_remote_opens[i]); | ||
2605 | } | ||
2606 | printf("\n"); | ||
2565 | } | 2607 | } |