]> andersk Git - openssh.git/blame - servconf.c
- dtucker@cvs.openbsd.org 2009/11/10 04:30:45
[openssh.git] / servconf.c
CommitLineData
fe7dba42 1/* $OpenBSD: servconf.c,v 1.197 2009/10/28 16:38:18 reyk Exp $ */
8efc0c15 2/*
5260325f 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
6ae2364d 5 *
bcbf86ec 6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be
10 * called by a name other than "ssh" or "Secure Shell".
5260325f 11 */
8efc0c15 12
13#include "includes.h"
8efc0c15 14
5b04a8bf 15#include <sys/types.h>
16#include <sys/socket.h>
17
28cb0a43 18#include <netdb.h>
fa47fe3c 19#include <pwd.h>
cf851879 20#include <stdio.h>
ffa517a8 21#include <stdlib.h>
00146caa 22#include <string.h>
31652869 23#include <signal.h>
5188ba17 24#include <unistd.h>
31652869 25#include <stdarg.h>
1760c982 26#include <errno.h>
c8dfff33 27
3593bdc0 28#include "openbsd-compat/sys-queue.h"
31652869 29#include "xmalloc.h"
8efc0c15 30#include "ssh.h"
42f11eb2 31#include "log.h"
31652869 32#include "buffer.h"
8efc0c15 33#include "servconf.h"
a8be9f80 34#include "compat.h"
42f11eb2 35#include "pathnames.h"
42f11eb2 36#include "misc.h"
37#include "cipher.h"
31652869 38#include "key.h"
b2552997 39#include "kex.h"
40#include "mac.h"
d231781a 41#include "match.h"
2fefbadf 42#include "channels.h"
fa47fe3c 43#include "groupaccess.h"
42f11eb2 44
5134115d 45static void add_listen_addr(ServerOptions *, char *, int);
46static void add_one_listen_addr(ServerOptions *, char *, int);
48e671d5 47
1853d1ef 48/* Use of privilege separation or not */
49extern int use_privsep;
d231781a 50extern Buffer cfg;
42f11eb2 51
8efc0c15 52/* Initializes the server options to their default values. */
53
6ae2364d 54void
5260325f 55initialize_server_options(ServerOptions *options)
8efc0c15 56{
5260325f 57 memset(options, 0, sizeof(*options));
e15895cd 58
59 /* Portable-specific options */
7fceb20d 60 options->use_pam = -1;
e15895cd 61
62 /* Standard Options */
48e671d5 63 options->num_ports = 0;
64 options->ports_from_cmdline = 0;
65 options->listen_addrs = NULL;
31b41ceb 66 options->address_family = -1;
fa08c86b 67 options->num_host_key_files = 0;
0fbe8c74 68 options->pid_file = NULL;
5260325f 69 options->server_key_bits = -1;
70 options->login_grace_time = -1;
71 options->key_regeneration_time = -1;
15853e93 72 options->permit_root_login = PERMIT_NOT_SET;
5260325f 73 options->ignore_rhosts = -1;
74 options->ignore_user_known_hosts = -1;
75 options->print_motd = -1;
4f4648f9 76 options->print_lastlog = -1;
5260325f 77 options->x11_forwarding = -1;
78 options->x11_display_offset = -1;
e6e573bd 79 options->x11_use_localhost = -1;
fa649821 80 options->xauth_location = NULL;
5260325f 81 options->strict_modes = -1;
fd573618 82 options->tcp_keep_alive = -1;
5eaf8578 83 options->log_facility = SYSLOG_FACILITY_NOT_SET;
84 options->log_level = SYSLOG_LEVEL_NOT_SET;
5260325f 85 options->rhosts_rsa_authentication = -1;
8002af61 86 options->hostbased_authentication = -1;
87 options->hostbased_uses_name_from_packet_only = -1;
5260325f 88 options->rsa_authentication = -1;
fa08c86b 89 options->pubkey_authentication = -1;
5260325f 90 options->kerberos_authentication = -1;
91 options->kerberos_or_local_passwd = -1;
92 options->kerberos_ticket_cleanup = -1;
a1e30b47 93 options->kerberos_get_afs_token = -1;
7364bd04 94 options->gss_authentication=-1;
95 options->gss_cleanup_creds = -1;
5260325f 96 options->password_authentication = -1;
94ec8c6b 97 options->kbd_interactive_authentication = -1;
5ba55ada 98 options->challenge_response_authentication = -1;
5260325f 99 options->permit_empty_passwd = -1;
f00bab84 100 options->permit_user_env = -1;
5260325f 101 options->use_login = -1;
636f76ca 102 options->compression = -1;
33de75a3 103 options->allow_tcp_forwarding = -1;
43c3f85c 104 options->allow_agent_forwarding = -1;
5260325f 105 options->num_allow_users = 0;
106 options->num_deny_users = 0;
107 options->num_allow_groups = 0;
108 options->num_deny_groups = 0;
a8be9f80 109 options->ciphers = NULL;
b2552997 110 options->macs = NULL;
a8be9f80 111 options->protocol = SSH_PROTO_UNKNOWN;
1d1ffb87 112 options->gateway_ports = -1;
38c295d6 113 options->num_subsystems = 0;
c345cf9d 114 options->max_startups_begin = -1;
115 options->max_startups_rate = -1;
089fbbd2 116 options->max_startups = -1;
af4bd935 117 options->max_authtries = -1;
c6dca55e 118 options->max_sessions = -1;
eea39c02 119 options->banner = NULL;
c5a7d788 120 options->use_dns = -1;
3ffc6336 121 options->client_alive_interval = -1;
122 options->client_alive_count_max = -1;
c8445989 123 options->authorized_keys_file = NULL;
124 options->authorized_keys_file2 = NULL;
61a2c1da 125 options->num_accept_env = 0;
d20f3c9e 126 options->permit_tun = -1;
ea46e550 127 options->num_permitted_opens = -1;
e7259e8d 128 options->adm_forced_command = NULL;
db49deeb 129 options->chroot_directory = NULL;
5adf6b9a 130 options->zero_knowledge_password_authentication = -1;
fe7dba42 131 options->rdomain = -1;
8efc0c15 132}
133
6ae2364d 134void
5260325f 135fill_default_server_options(ServerOptions *options)
8efc0c15 136{
e15895cd 137 /* Portable-specific options */
7fceb20d 138 if (options->use_pam == -1)
0a23d79f 139 options->use_pam = 0;
e15895cd 140
141 /* Standard Options */
fa08c86b 142 if (options->protocol == SSH_PROTO_UNKNOWN)
21af5fc4 143 options->protocol = SSH_PROTO_2;
fa08c86b 144 if (options->num_host_key_files == 0) {
145 /* fill default hostkeys for protocols */
146 if (options->protocol & SSH_PROTO_1)
0f84fe37 147 options->host_key_files[options->num_host_key_files++] =
148 _PATH_HOST_KEY_FILE;
149 if (options->protocol & SSH_PROTO_2) {
150 options->host_key_files[options->num_host_key_files++] =
151 _PATH_HOST_RSA_KEY_FILE;
152 options->host_key_files[options->num_host_key_files++] =
153 _PATH_HOST_DSA_KEY_FILE;
154 }
fa08c86b 155 }
48e671d5 156 if (options->num_ports == 0)
157 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
158 if (options->listen_addrs == NULL)
2d2a2c65 159 add_listen_addr(options, NULL, 0);
0fbe8c74 160 if (options->pid_file == NULL)
42f11eb2 161 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
5260325f 162 if (options->server_key_bits == -1)
39ceddb7 163 options->server_key_bits = 1024;
5260325f 164 if (options->login_grace_time == -1)
3445ca02 165 options->login_grace_time = 120;
5260325f 166 if (options->key_regeneration_time == -1)
167 options->key_regeneration_time = 3600;
15853e93 168 if (options->permit_root_login == PERMIT_NOT_SET)
169 options->permit_root_login = PERMIT_YES;
5260325f 170 if (options->ignore_rhosts == -1)
c8d54615 171 options->ignore_rhosts = 1;
5260325f 172 if (options->ignore_user_known_hosts == -1)
173 options->ignore_user_known_hosts = 0;
5260325f 174 if (options->print_motd == -1)
175 options->print_motd = 1;
4f4648f9 176 if (options->print_lastlog == -1)
177 options->print_lastlog = 1;
5260325f 178 if (options->x11_forwarding == -1)
c8d54615 179 options->x11_forwarding = 0;
5260325f 180 if (options->x11_display_offset == -1)
c8d54615 181 options->x11_display_offset = 10;
e6e573bd 182 if (options->x11_use_localhost == -1)
183 options->x11_use_localhost = 1;
fa649821 184 if (options->xauth_location == NULL)
fd9ede94 185 options->xauth_location = _PATH_XAUTH;
5260325f 186 if (options->strict_modes == -1)
187 options->strict_modes = 1;
fd573618 188 if (options->tcp_keep_alive == -1)
189 options->tcp_keep_alive = 1;
5eaf8578 190 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
5260325f 191 options->log_facility = SYSLOG_FACILITY_AUTH;
5eaf8578 192 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
59c97189 193 options->log_level = SYSLOG_LEVEL_INFO;
5260325f 194 if (options->rhosts_rsa_authentication == -1)
c8d54615 195 options->rhosts_rsa_authentication = 0;
8002af61 196 if (options->hostbased_authentication == -1)
197 options->hostbased_authentication = 0;
198 if (options->hostbased_uses_name_from_packet_only == -1)
199 options->hostbased_uses_name_from_packet_only = 0;
5260325f 200 if (options->rsa_authentication == -1)
201 options->rsa_authentication = 1;
fa08c86b 202 if (options->pubkey_authentication == -1)
203 options->pubkey_authentication = 1;
5260325f 204 if (options->kerberos_authentication == -1)
eadc806d 205 options->kerberos_authentication = 0;
5260325f 206 if (options->kerberos_or_local_passwd == -1)
207 options->kerberos_or_local_passwd = 1;
208 if (options->kerberos_ticket_cleanup == -1)
209 options->kerberos_ticket_cleanup = 1;
a1e30b47 210 if (options->kerberos_get_afs_token == -1)
211 options->kerberos_get_afs_token = 0;
7364bd04 212 if (options->gss_authentication == -1)
213 options->gss_authentication = 0;
214 if (options->gss_cleanup_creds == -1)
215 options->gss_cleanup_creds = 1;
5260325f 216 if (options->password_authentication == -1)
217 options->password_authentication = 1;
94ec8c6b 218 if (options->kbd_interactive_authentication == -1)
219 options->kbd_interactive_authentication = 0;
5ba55ada 220 if (options->challenge_response_authentication == -1)
221 options->challenge_response_authentication = 1;
5260325f 222 if (options->permit_empty_passwd == -1)
c8d54615 223 options->permit_empty_passwd = 0;
f00bab84 224 if (options->permit_user_env == -1)
225 options->permit_user_env = 0;
5260325f 226 if (options->use_login == -1)
227 options->use_login = 0;
636f76ca 228 if (options->compression == -1)
07200973 229 options->compression = COMP_DELAYED;
33de75a3 230 if (options->allow_tcp_forwarding == -1)
231 options->allow_tcp_forwarding = 1;
43c3f85c 232 if (options->allow_agent_forwarding == -1)
233 options->allow_agent_forwarding = 1;
1d1ffb87 234 if (options->gateway_ports == -1)
235 options->gateway_ports = 0;
089fbbd2 236 if (options->max_startups == -1)
237 options->max_startups = 10;
c345cf9d 238 if (options->max_startups_rate == -1)
239 options->max_startups_rate = 100; /* 100% */
240 if (options->max_startups_begin == -1)
241 options->max_startups_begin = options->max_startups;
af4bd935 242 if (options->max_authtries == -1)
243 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
c6dca55e 244 if (options->max_sessions == -1)
245 options->max_sessions = DEFAULT_SESSIONS_MAX;
c5a7d788 246 if (options->use_dns == -1)
247 options->use_dns = 1;
3ffc6336 248 if (options->client_alive_interval == -1)
184eed6a 249 options->client_alive_interval = 0;
3ffc6336 250 if (options->client_alive_count_max == -1)
251 options->client_alive_count_max = 3;
5df83e07 252 if (options->authorized_keys_file2 == NULL) {
253 /* authorized_keys_file2 falls back to authorized_keys_file */
254 if (options->authorized_keys_file != NULL)
255 options->authorized_keys_file2 = options->authorized_keys_file;
256 else
257 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
258 }
259 if (options->authorized_keys_file == NULL)
260 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
d20f3c9e 261 if (options->permit_tun == -1)
a4f24bf8 262 options->permit_tun = SSH_TUNMODE_NO;
5adf6b9a 263 if (options->zero_knowledge_password_authentication == -1)
264 options->zero_knowledge_password_authentication = 0;
1853d1ef 265
2ee1b704 266 /* Turn privilege separation on by default */
1853d1ef 267 if (use_privsep == -1)
2ee1b704 268 use_privsep = 1;
e299a298 269
4165b82e 270#ifndef HAVE_MMAP
e299a298 271 if (use_privsep && options->compression == 1) {
272 error("This platform does not support both privilege "
273 "separation and compression");
274 error("Compression disabled");
275 options->compression = 0;
276 }
277#endif
278
8efc0c15 279}
280
8efc0c15 281/* Keyword tokens. */
5260325f 282typedef enum {
283 sBadOption, /* == unknown option */
e15895cd 284 /* Portable-specific options */
7fceb20d 285 sUsePAM,
e15895cd 286 /* Standard Options */
5260325f 287 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
288 sPermitRootLogin, sLogFacility, sLogLevel,
0598d99d 289 sRhostsRSAAuthentication, sRSAAuthentication,
5260325f 290 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
a1e30b47 291 sKerberosGetAFSToken,
1c590258 292 sKerberosTgtPassing, sChallengeResponseAuthentication,
31b41ceb 293 sPasswordAuthentication, sKbdInteractiveAuthentication,
294 sListenAddress, sAddressFamily,
4f4648f9 295 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
e6e573bd 296 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
fd573618 297 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
f00bab84 298 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
33de75a3 299 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
b2552997 300 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
af4bd935 301 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
c6dca55e 302 sMaxStartups, sMaxAuthTries, sMaxSessions,
c5a7d788 303 sBanner, sUseDNS, sHostbasedAuthentication,
184eed6a 304 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
c8445989 305 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
d20f3c9e 306 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
db49deeb 307 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
fe7dba42 308 sUsePrivilegeSeparation, sAllowAgentForwarding, sRDomain,
5adf6b9a 309 sZeroKnowledgePasswordAuthentication,
a2144546 310 sDeprecated, sUnsupported
8efc0c15 311} ServerOpCodes;
312
d231781a 313#define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
314#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
315#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
316
8efc0c15 317/* Textual representation of the tokens. */
5260325f 318static struct {
319 const char *name;
320 ServerOpCodes opcode;
d231781a 321 u_int flags;
5260325f 322} keywords[] = {
e15895cd 323 /* Portable-specific options */
b06b11ad 324#ifdef USE_PAM
d231781a 325 { "usepam", sUsePAM, SSHCFG_GLOBAL },
b06b11ad 326#else
d231781a 327 { "usepam", sUnsupported, SSHCFG_GLOBAL },
b06b11ad 328#endif
d231781a 329 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
e15895cd 330 /* Standard Options */
d231781a 331 { "port", sPort, SSHCFG_GLOBAL },
332 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
333 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
334 { "pidfile", sPidFile, SSHCFG_GLOBAL },
335 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
336 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
337 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
2ef741a3 338 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
d231781a 339 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
340 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
341 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
03bcbf84 342 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
343 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
d231781a 344 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
03bcbf84 345 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
346 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
c8dc0909 347 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
1c590258 348#ifdef KRB5
03bcbf84 349 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
d231781a 350 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
351 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
bcfcc5f9 352#ifdef USE_AFS
d231781a 353 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
309af4e5 354#else
d231781a 355 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
309af4e5 356#endif
a2144546 357#else
03bcbf84 358 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
d231781a 359 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
360 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
361 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
a2144546 362#endif
d231781a 363 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
364 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
7364bd04 365#ifdef GSSAPI
03bcbf84 366 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
d231781a 367 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
7364bd04 368#else
03bcbf84 369 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
d231781a 370 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
7364bd04 371#endif
03bcbf84 372 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
373 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
121c4a34 374 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
d231781a 375 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
5adf6b9a 376#ifdef JPAKE
377 { "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
378#else
379 { "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
380#endif
d231781a 381 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
382 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
383 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
384 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
385 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
386 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
387 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
691712e0 388 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
389 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
390 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
d231781a 391 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
392 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
e68868a1 393 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
d231781a 394 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
395 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
396 { "compression", sCompression, SSHCFG_GLOBAL },
397 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
398 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
399 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
43c3f85c 400 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
d231781a 401 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
402 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
403 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
404 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
405 { "ciphers", sCiphers, SSHCFG_GLOBAL },
406 { "macs", sMacs, SSHCFG_GLOBAL },
407 { "protocol", sProtocol, SSHCFG_GLOBAL },
408 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
409 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
410 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
8086aeb2 411 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
c6dca55e 412 { "maxsessions", sMaxSessions, SSHCFG_ALL },
03bcbf84 413 { "banner", sBanner, SSHCFG_ALL },
d231781a 414 { "usedns", sUseDNS, SSHCFG_GLOBAL },
415 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
416 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
417 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
418 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
419 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
420 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
c8dc0909 421 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
d231781a 422 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
423 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
c8dc0909 424 { "match", sMatch, SSHCFG_ALL },
2fefbadf 425 { "permitopen", sPermitOpen, SSHCFG_ALL },
e7259e8d 426 { "forcecommand", sForceCommand, SSHCFG_ALL },
fe7dba42 427 { "rdomain", sRDomain, SSHCFG_GLOBAL },
db49deeb 428 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
d231781a 429 { NULL, sBadOption, 0 }
8efc0c15 430};
431
1760c982 432static struct {
433 int val;
434 char *text;
435} tunmode_desc[] = {
436 { SSH_TUNMODE_NO, "no" },
437 { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
438 { SSH_TUNMODE_ETHERNET, "ethernet" },
439 { SSH_TUNMODE_YES, "yes" },
440 { -1, NULL }
441};
442
aa3378df 443/*
6be9a5e8 444 * Returns the number of the token pointed to by cp or sBadOption.
aa3378df 445 */
8efc0c15 446
6ae2364d 447static ServerOpCodes
5260325f 448parse_token(const char *cp, const char *filename,
d231781a 449 int linenum, u_int *flags)
8efc0c15 450{
1e3b8b07 451 u_int i;
8efc0c15 452
5260325f 453 for (i = 0; keywords[i].name; i++)
d231781a 454 if (strcasecmp(cp, keywords[i].name) == 0) {
455 *flags = keywords[i].flags;
5260325f 456 return keywords[i].opcode;
d231781a 457 }
8efc0c15 458
b7c70970 459 error("%s: line %d: Bad configuration option: %s",
460 filename, linenum, cp);
5260325f 461 return sBadOption;
8efc0c15 462}
463
396c147e 464static void
5134115d 465add_listen_addr(ServerOptions *options, char *addr, int port)
48e671d5 466{
2ceb8101 467 u_int i;
48e671d5 468
469 if (options->num_ports == 0)
470 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
31b41ceb 471 if (options->address_family == -1)
472 options->address_family = AF_UNSPEC;
2d2a2c65 473 if (port == 0)
d11c1288 474 for (i = 0; i < options->num_ports; i++)
475 add_one_listen_addr(options, addr, options->ports[i]);
476 else
2d2a2c65 477 add_one_listen_addr(options, addr, port);
d11c1288 478}
479
396c147e 480static void
5134115d 481add_one_listen_addr(ServerOptions *options, char *addr, int port)
d11c1288 482{
483 struct addrinfo hints, *ai, *aitop;
484 char strport[NI_MAXSERV];
485 int gaierr;
486
487 memset(&hints, 0, sizeof(hints));
31b41ceb 488 hints.ai_family = options->address_family;
d11c1288 489 hints.ai_socktype = SOCK_STREAM;
490 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
5134115d 491 snprintf(strport, sizeof strport, "%d", port);
d11c1288 492 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
493 fatal("bad addr or host: %s (%s)",
494 addr ? addr : "<NULL>",
bb4626fe 495 ssh_gai_strerror(gaierr));
d11c1288 496 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
497 ;
498 ai->ai_next = options->listen_addrs;
499 options->listen_addrs = aitop;
48e671d5 500}
501
d231781a 502/*
503 * The strategy for the Match blocks is that the config file is parsed twice.
504 *
505 * The first time is at startup. activep is initialized to 1 and the
506 * directives in the global context are processed and acted on. Hitting a
507 * Match directive unsets activep and the directives inside the block are
508 * checked for syntax only.
509 *
510 * The second time is after a connection has been established but before
511 * authentication. activep is initialized to 2 and global config directives
512 * are ignored since they have already been processed. If the criteria in a
513 * Match block is met, activep is set and the subsequent directives
514 * processed and actioned until EOF or another Match block unsets it. Any
515 * options set are copied into the main server config.
516 *
517 * Potential additions/improvements:
518 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
519 *
520 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
521 * Match Address 192.168.0.*
522 * Tag trusted
523 * Match Group wheel
524 * Tag trusted
525 * Match Tag trusted
526 * AllowTcpForwarding yes
527 * GatewayPorts clientspecified
528 * [...]
529 *
530 * - Add a PermittedChannelRequests directive
531 * Match Group shell
532 * PermittedChannelRequests session,forwarded-tcpip
533 */
534
fa47fe3c 535static int
536match_cfg_line_group(const char *grps, int line, const char *user)
537{
538 int result = 0;
fa47fe3c 539 struct passwd *pw;
540
fa47fe3c 541 if (user == NULL)
542 goto out;
543
544 if ((pw = getpwnam(user)) == NULL) {
545 debug("Can't match group at line %d because user %.100s does "
546 "not exist", line, user);
547 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
548 debug("Can't Match group because user %.100s not in any group "
549 "at line %d", user, line);
cece208b 550 } else if (ga_match_pattern_list(grps) != 1) {
551 debug("user %.100s does not match group list %.100s at line %d",
552 user, grps, line);
fa47fe3c 553 } else {
cece208b 554 debug("user %.100s matched group list %.100s at line %d", user,
555 grps, line);
fa47fe3c 556 result = 1;
557 }
558out:
559 ga_free();
fa47fe3c 560 return result;
561}
562
d231781a 563static int
564match_cfg_line(char **condition, int line, const char *user, const char *host,
565 const char *address)
566{
567 int result = 1;
568 char *arg, *attrib, *cp = *condition;
569 size_t len;
570
571 if (user == NULL)
572 debug3("checking syntax for 'Match %s'", cp);
573 else
574 debug3("checking match for '%s' user %s host %s addr %s", cp,
575 user ? user : "(null)", host ? host : "(null)",
576 address ? address : "(null)");
577
578 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
579 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
580 error("Missing Match criteria for %s", attrib);
581 return -1;
582 }
583 len = strlen(arg);
584 if (strcasecmp(attrib, "user") == 0) {
585 if (!user) {
586 result = 0;
587 continue;
588 }
589 if (match_pattern_list(user, arg, len, 0) != 1)
590 result = 0;
591 else
592 debug("user %.100s matched 'User %.100s' at "
593 "line %d", user, arg, line);
fa47fe3c 594 } else if (strcasecmp(attrib, "group") == 0) {
595 switch (match_cfg_line_group(arg, line, user)) {
596 case -1:
597 return -1;
598 case 0:
599 result = 0;
600 }
d231781a 601 } else if (strcasecmp(attrib, "host") == 0) {
602 if (!host) {
603 result = 0;
604 continue;
605 }
606 if (match_hostname(host, arg, len) != 1)
607 result = 0;
608 else
609 debug("connection from %.100s matched 'Host "
610 "%.100s' at line %d", host, arg, line);
611 } else if (strcasecmp(attrib, "address") == 0) {
15b5fa9b 612 switch (addr_match_list(address, arg)) {
613 case 1:
d231781a 614 debug("connection from %.100s matched 'Address "
615 "%.100s' at line %d", address, arg, line);
15b5fa9b 616 break;
617 case 0:
b3b048d6 618 case -1:
15b5fa9b 619 result = 0;
620 break;
b3b048d6 621 case -2:
15b5fa9b 622 return -1;
623 }
d231781a 624 } else {
625 error("Unsupported Match attribute %s", attrib);
626 return -1;
627 }
628 }
629 if (user != NULL)
630 debug3("match %sfound", result ? "" : "not ");
631 *condition = cp;
632 return result;
633}
634
e7259e8d 635#define WHITESPACE " \t\r\n"
636
2717fa0f 637int
638process_server_config_line(ServerOptions *options, char *line,
d231781a 639 const char *filename, int linenum, int *activep, const char *user,
640 const char *host, const char *address)
8efc0c15 641{
d11c1288 642 char *cp, **charptr, *arg, *p;
d231781a 643 int cmdline = 0, *intptr, value, n;
2a72bc03 644 SyslogFacility *log_facility_ptr;
645 LogLevel *log_level_ptr;
5260325f 646 ServerOpCodes opcode;
5134115d 647 int port;
d231781a 648 u_int i, flags = 0;
d66ce1a1 649 size_t len;
5260325f 650
2717fa0f 651 cp = line;
0f8cd5a6 652 if ((arg = strdelim(&cp)) == NULL)
88299971 653 return 0;
2717fa0f 654 /* Ignore leading whitespace */
655 if (*arg == '\0')
704b1659 656 arg = strdelim(&cp);
2717fa0f 657 if (!arg || !*arg || *arg == '#')
658 return 0;
659 intptr = NULL;
660 charptr = NULL;
d231781a 661 opcode = parse_token(arg, filename, linenum, &flags);
662
663 if (activep == NULL) { /* We are processing a command line directive */
664 cmdline = 1;
665 activep = &cmdline;
666 }
667 if (*activep && opcode != sMatch)
668 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
669 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
670 if (user == NULL) {
671 fatal("%s line %d: Directive '%s' is not allowed "
672 "within a Match block", filename, linenum, arg);
673 } else { /* this is a directive we have already processed */
674 while (arg)
675 arg = strdelim(&cp);
676 return 0;
677 }
678 }
679
2717fa0f 680 switch (opcode) {
681 /* Portable-specific options */
7fceb20d 682 case sUsePAM:
683 intptr = &options->use_pam;
2717fa0f 684 goto parse_flag;
48e671d5 685
2717fa0f 686 /* Standard Options */
687 case sBadOption:
688 return -1;
689 case sPort:
690 /* ignore ports from configfile if cmdline specifies ports */
691 if (options->ports_from_cmdline)
692 return 0;
693 if (options->listen_addrs != NULL)
694 fatal("%s line %d: ports must be specified before "
3a454b6a 695 "ListenAddress.", filename, linenum);
2717fa0f 696 if (options->num_ports >= MAX_PORTS)
697 fatal("%s line %d: too many ports.",
698 filename, linenum);
699 arg = strdelim(&cp);
700 if (!arg || *arg == '\0')
701 fatal("%s line %d: missing port number.",
702 filename, linenum);
703 options->ports[options->num_ports++] = a2port(arg);
5134115d 704 if (options->ports[options->num_ports-1] <= 0)
2717fa0f 705 fatal("%s line %d: Badly formatted port number.",
706 filename, linenum);
707 break;
708
709 case sServerKeyBits:
710 intptr = &options->server_key_bits;
c6dca55e 711 parse_int:
2717fa0f 712 arg = strdelim(&cp);
713 if (!arg || *arg == '\0')
714 fatal("%s line %d: missing integer value.",
715 filename, linenum);
716 value = atoi(arg);
d231781a 717 if (*activep && *intptr == -1)
2717fa0f 718 *intptr = value;
719 break;
720
721 case sLoginGraceTime:
722 intptr = &options->login_grace_time;
c6dca55e 723 parse_time:
2717fa0f 724 arg = strdelim(&cp);
725 if (!arg || *arg == '\0')
726 fatal("%s line %d: missing time value.",
727 filename, linenum);
728 if ((value = convtime(arg)) == -1)
729 fatal("%s line %d: invalid time value.",
730 filename, linenum);
731 if (*intptr == -1)
732 *intptr = value;
733 break;
734
735 case sKeyRegenerationTime:
736 intptr = &options->key_regeneration_time;
737 goto parse_time;
738
739 case sListenAddress:
740 arg = strdelim(&cp);
3867aa0a 741 if (arg == NULL || *arg == '\0')
742 fatal("%s line %d: missing address",
2717fa0f 743 filename, linenum);
91135a0e 744 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
745 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
746 && strchr(p+1, ':') != NULL) {
747 add_listen_addr(options, arg, 0);
748 break;
749 }
3867aa0a 750 p = hpdelim(&arg);
751 if (p == NULL)
752 fatal("%s line %d: bad address:port usage",
2717fa0f 753 filename, linenum);
3867aa0a 754 p = cleanhostname(p);
755 if (arg == NULL)
756 port = 0;
5134115d 757 else if ((port = a2port(arg)) <= 0)
3867aa0a 758 fatal("%s line %d: bad port number", filename, linenum);
759
760 add_listen_addr(options, p, port);
761
2717fa0f 762 break;
763
31b41ceb 764 case sAddressFamily:
765 arg = strdelim(&cp);
38634ff6 766 if (!arg || *arg == '\0')
767 fatal("%s line %d: missing address family.",
768 filename, linenum);
31b41ceb 769 intptr = &options->address_family;
770 if (options->listen_addrs != NULL)
771 fatal("%s line %d: address family must be specified before "
772 "ListenAddress.", filename, linenum);
773 if (strcasecmp(arg, "inet") == 0)
774 value = AF_INET;
775 else if (strcasecmp(arg, "inet6") == 0)
776 value = AF_INET6;
777 else if (strcasecmp(arg, "any") == 0)
778 value = AF_UNSPEC;
779 else
780 fatal("%s line %d: unsupported address family \"%s\".",
781 filename, linenum, arg);
782 if (*intptr == -1)
783 *intptr = value;
784 break;
785
2717fa0f 786 case sHostKeyFile:
787 intptr = &options->num_host_key_files;
788 if (*intptr >= MAX_HOSTKEYS)
789 fatal("%s line %d: too many host keys specified (max %d).",
790 filename, linenum, MAX_HOSTKEYS);
791 charptr = &options->host_key_files[*intptr];
c6dca55e 792 parse_filename:
2717fa0f 793 arg = strdelim(&cp);
794 if (!arg || *arg == '\0')
795 fatal("%s line %d: missing file name.",
796 filename, linenum);
d231781a 797 if (*activep && *charptr == NULL) {
2717fa0f 798 *charptr = tilde_expand_filename(arg, getuid());
799 /* increase optional counter */
800 if (intptr != NULL)
801 *intptr = *intptr + 1;
802 }
803 break;
0fbe8c74 804
2717fa0f 805 case sPidFile:
806 charptr = &options->pid_file;
807 goto parse_filename;
5260325f 808
2717fa0f 809 case sPermitRootLogin:
810 intptr = &options->permit_root_login;
811 arg = strdelim(&cp);
812 if (!arg || *arg == '\0')
813 fatal("%s line %d: missing yes/"
814 "without-password/forced-commands-only/no "
815 "argument.", filename, linenum);
816 value = 0; /* silence compiler */
817 if (strcmp(arg, "without-password") == 0)
818 value = PERMIT_NO_PASSWD;
819 else if (strcmp(arg, "forced-commands-only") == 0)
820 value = PERMIT_FORCED_ONLY;
821 else if (strcmp(arg, "yes") == 0)
822 value = PERMIT_YES;
823 else if (strcmp(arg, "no") == 0)
824 value = PERMIT_NO;
825 else
826 fatal("%s line %d: Bad yes/"
827 "without-password/forced-commands-only/no "
828 "argument: %s", filename, linenum, arg);
2ef741a3 829 if (*activep && *intptr == -1)
2717fa0f 830 *intptr = value;
831 break;
832
833 case sIgnoreRhosts:
834 intptr = &options->ignore_rhosts;
c6dca55e 835 parse_flag:
2717fa0f 836 arg = strdelim(&cp);
837 if (!arg || *arg == '\0')
838 fatal("%s line %d: missing yes/no argument.",
839 filename, linenum);
840 value = 0; /* silence compiler */
841 if (strcmp(arg, "yes") == 0)
842 value = 1;
843 else if (strcmp(arg, "no") == 0)
844 value = 0;
845 else
846 fatal("%s line %d: Bad yes/no argument: %s",
847 filename, linenum, arg);
d231781a 848 if (*activep && *intptr == -1)
2717fa0f 849 *intptr = value;
850 break;
851
852 case sIgnoreUserKnownHosts:
853 intptr = &options->ignore_user_known_hosts;
854 goto parse_flag;
855
2717fa0f 856 case sRhostsRSAAuthentication:
857 intptr = &options->rhosts_rsa_authentication;
858 goto parse_flag;
859
860 case sHostbasedAuthentication:
861 intptr = &options->hostbased_authentication;
862 goto parse_flag;
863
864 case sHostbasedUsesNameFromPacketOnly:
865 intptr = &options->hostbased_uses_name_from_packet_only;
866 goto parse_flag;
867
868 case sRSAAuthentication:
869 intptr = &options->rsa_authentication;
870 goto parse_flag;
871
872 case sPubkeyAuthentication:
873 intptr = &options->pubkey_authentication;
874 goto parse_flag;
d0ec7f42 875
2717fa0f 876 case sKerberosAuthentication:
877 intptr = &options->kerberos_authentication;
878 goto parse_flag;
5260325f 879
2717fa0f 880 case sKerberosOrLocalPasswd:
881 intptr = &options->kerberos_or_local_passwd;
882 goto parse_flag;
5260325f 883
2717fa0f 884 case sKerberosTicketCleanup:
885 intptr = &options->kerberos_ticket_cleanup;
886 goto parse_flag;
d0ec7f42 887
a1e30b47 888 case sKerberosGetAFSToken:
889 intptr = &options->kerberos_get_afs_token;
890 goto parse_flag;
891
7364bd04 892 case sGssAuthentication:
893 intptr = &options->gss_authentication;
894 goto parse_flag;
895
896 case sGssCleanupCreds:
897 intptr = &options->gss_cleanup_creds;
898 goto parse_flag;
899
2717fa0f 900 case sPasswordAuthentication:
901 intptr = &options->password_authentication;
902 goto parse_flag;
5260325f 903
5adf6b9a 904 case sZeroKnowledgePasswordAuthentication:
905 intptr = &options->zero_knowledge_password_authentication;
906 goto parse_flag;
907
2717fa0f 908 case sKbdInteractiveAuthentication:
909 intptr = &options->kbd_interactive_authentication;
910 goto parse_flag;
8002af61 911
2717fa0f 912 case sChallengeResponseAuthentication:
913 intptr = &options->challenge_response_authentication;
914 goto parse_flag;
8002af61 915
2717fa0f 916 case sPrintMotd:
917 intptr = &options->print_motd;
918 goto parse_flag;
5260325f 919
2717fa0f 920 case sPrintLastLog:
921 intptr = &options->print_lastlog;
922 goto parse_flag;
5260325f 923
2717fa0f 924 case sX11Forwarding:
925 intptr = &options->x11_forwarding;
926 goto parse_flag;
5260325f 927
2717fa0f 928 case sX11DisplayOffset:
929 intptr = &options->x11_display_offset;
930 goto parse_int;
8efc0c15 931
e6e573bd 932 case sX11UseLocalhost:
933 intptr = &options->x11_use_localhost;
934 goto parse_flag;
935
2717fa0f 936 case sXAuthLocation:
937 charptr = &options->xauth_location;
938 goto parse_filename;
5260325f 939
2717fa0f 940 case sStrictModes:
941 intptr = &options->strict_modes;
942 goto parse_flag;
5260325f 943
fd573618 944 case sTCPKeepAlive:
945 intptr = &options->tcp_keep_alive;
2717fa0f 946 goto parse_flag;
33de75a3 947
2717fa0f 948 case sEmptyPasswd:
949 intptr = &options->permit_empty_passwd;
950 goto parse_flag;
5260325f 951
f00bab84 952 case sPermitUserEnvironment:
953 intptr = &options->permit_user_env;
954 goto parse_flag;
955
2717fa0f 956 case sUseLogin:
957 intptr = &options->use_login;
958 goto parse_flag;
5260325f 959
636f76ca 960 case sCompression:
961 intptr = &options->compression;
07200973 962 arg = strdelim(&cp);
963 if (!arg || *arg == '\0')
964 fatal("%s line %d: missing yes/no/delayed "
965 "argument.", filename, linenum);
966 value = 0; /* silence compiler */
967 if (strcmp(arg, "delayed") == 0)
968 value = COMP_DELAYED;
969 else if (strcmp(arg, "yes") == 0)
970 value = COMP_ZLIB;
971 else if (strcmp(arg, "no") == 0)
972 value = COMP_NONE;
973 else
974 fatal("%s line %d: Bad yes/no/delayed "
975 "argument: %s", filename, linenum, arg);
976 if (*intptr == -1)
977 *intptr = value;
978 break;
636f76ca 979
2717fa0f 980 case sGatewayPorts:
981 intptr = &options->gateway_ports;
3867aa0a 982 arg = strdelim(&cp);
983 if (!arg || *arg == '\0')
984 fatal("%s line %d: missing yes/no/clientspecified "
985 "argument.", filename, linenum);
986 value = 0; /* silence compiler */
987 if (strcmp(arg, "clientspecified") == 0)
988 value = 2;
989 else if (strcmp(arg, "yes") == 0)
990 value = 1;
991 else if (strcmp(arg, "no") == 0)
992 value = 0;
993 else
994 fatal("%s line %d: Bad yes/no/clientspecified "
995 "argument: %s", filename, linenum, arg);
f3e3d6ce 996 if (*activep && *intptr == -1)
3867aa0a 997 *intptr = value;
998 break;
5260325f 999
c5a7d788 1000 case sUseDNS:
1001 intptr = &options->use_dns;
2717fa0f 1002 goto parse_flag;
5260325f 1003
2717fa0f 1004 case sLogFacility:
2a72bc03 1005 log_facility_ptr = &options->log_facility;
2717fa0f 1006 arg = strdelim(&cp);
1007 value = log_facility_number(arg);
5eaf8578 1008 if (value == SYSLOG_FACILITY_NOT_SET)
2717fa0f 1009 fatal("%.200s line %d: unsupported log facility '%s'",
1010 filename, linenum, arg ? arg : "<NONE>");
2a72bc03 1011 if (*log_facility_ptr == -1)
1012 *log_facility_ptr = (SyslogFacility) value;
2717fa0f 1013 break;
1014
1015 case sLogLevel:
2a72bc03 1016 log_level_ptr = &options->log_level;
2717fa0f 1017 arg = strdelim(&cp);
1018 value = log_level_number(arg);
5eaf8578 1019 if (value == SYSLOG_LEVEL_NOT_SET)
2717fa0f 1020 fatal("%.200s line %d: unsupported log level '%s'",
1021 filename, linenum, arg ? arg : "<NONE>");
2a72bc03 1022 if (*log_level_ptr == -1)
1023 *log_level_ptr = (LogLevel) value;
2717fa0f 1024 break;
1025
1026 case sAllowTcpForwarding:
1027 intptr = &options->allow_tcp_forwarding;
1028 goto parse_flag;
1029
43c3f85c 1030 case sAllowAgentForwarding:
1031 intptr = &options->allow_agent_forwarding;
1032 goto parse_flag;
1033
1853d1ef 1034 case sUsePrivilegeSeparation:
1035 intptr = &use_privsep;
1036 goto parse_flag;
1037
2717fa0f 1038 case sAllowUsers:
1039 while ((arg = strdelim(&cp)) && *arg != '\0') {
1040 if (options->num_allow_users >= MAX_ALLOW_USERS)
1041 fatal("%s line %d: too many allow users.",
1042 filename, linenum);
7528d467 1043 options->allow_users[options->num_allow_users++] =
1044 xstrdup(arg);
2717fa0f 1045 }
1046 break;
a8be9f80 1047
2717fa0f 1048 case sDenyUsers:
1049 while ((arg = strdelim(&cp)) && *arg != '\0') {
1050 if (options->num_deny_users >= MAX_DENY_USERS)
d4f40d92 1051 fatal("%s line %d: too many deny users.",
2717fa0f 1052 filename, linenum);
7528d467 1053 options->deny_users[options->num_deny_users++] =
1054 xstrdup(arg);
2717fa0f 1055 }
1056 break;
b2552997 1057
2717fa0f 1058 case sAllowGroups:
1059 while ((arg = strdelim(&cp)) && *arg != '\0') {
1060 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1061 fatal("%s line %d: too many allow groups.",
1062 filename, linenum);
7528d467 1063 options->allow_groups[options->num_allow_groups++] =
1064 xstrdup(arg);
2717fa0f 1065 }
1066 break;
a8be9f80 1067
2717fa0f 1068 case sDenyGroups:
1069 while ((arg = strdelim(&cp)) && *arg != '\0') {
1070 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1071 fatal("%s line %d: too many deny groups.",
1072 filename, linenum);
1073 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1074 }
1075 break;
38c295d6 1076
2717fa0f 1077 case sCiphers:
1078 arg = strdelim(&cp);
1079 if (!arg || *arg == '\0')
1080 fatal("%s line %d: Missing argument.", filename, linenum);
1081 if (!ciphers_valid(arg))
1082 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1083 filename, linenum, arg ? arg : "<NONE>");
1084 if (options->ciphers == NULL)
1085 options->ciphers = xstrdup(arg);
1086 break;
1087
1088 case sMacs:
1089 arg = strdelim(&cp);
1090 if (!arg || *arg == '\0')
1091 fatal("%s line %d: Missing argument.", filename, linenum);
1092 if (!mac_valid(arg))
1093 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1094 filename, linenum, arg ? arg : "<NONE>");
1095 if (options->macs == NULL)
1096 options->macs = xstrdup(arg);
1097 break;
1098
1099 case sProtocol:
1100 intptr = &options->protocol;
1101 arg = strdelim(&cp);
1102 if (!arg || *arg == '\0')
1103 fatal("%s line %d: Missing argument.", filename, linenum);
1104 value = proto_spec(arg);
1105 if (value == SSH_PROTO_UNKNOWN)
1106 fatal("%s line %d: Bad protocol spec '%s'.",
184eed6a 1107 filename, linenum, arg ? arg : "<NONE>");
2717fa0f 1108 if (*intptr == SSH_PROTO_UNKNOWN)
1109 *intptr = value;
1110 break;
1111
1112 case sSubsystem:
1113 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1114 fatal("%s line %d: too many subsystems defined.",
184eed6a 1115 filename, linenum);
2717fa0f 1116 }
1117 arg = strdelim(&cp);
1118 if (!arg || *arg == '\0')
1119 fatal("%s line %d: Missing subsystem name.",
184eed6a 1120 filename, linenum);
d231781a 1121 if (!*activep) {
1122 arg = strdelim(&cp);
1123 break;
1124 }
2717fa0f 1125 for (i = 0; i < options->num_subsystems; i++)
1126 if (strcmp(arg, options->subsystem_name[i]) == 0)
1127 fatal("%s line %d: Subsystem '%s' already defined.",
184eed6a 1128 filename, linenum, arg);
2717fa0f 1129 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1130 arg = strdelim(&cp);
1131 if (!arg || *arg == '\0')
1132 fatal("%s line %d: Missing subsystem command.",
184eed6a 1133 filename, linenum);
2717fa0f 1134 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
d66ce1a1 1135
1136 /* Collect arguments (separate to executable) */
1137 p = xstrdup(arg);
1138 len = strlen(p) + 1;
1139 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1140 len += 1 + strlen(arg);
1141 p = xrealloc(p, 1, len);
1142 strlcat(p, " ", len);
1143 strlcat(p, arg, len);
1144 }
1145 options->subsystem_args[options->num_subsystems] = p;
2717fa0f 1146 options->num_subsystems++;
1147 break;
1148
1149 case sMaxStartups:
1150 arg = strdelim(&cp);
1151 if (!arg || *arg == '\0')
1152 fatal("%s line %d: Missing MaxStartups spec.",
184eed6a 1153 filename, linenum);
2717fa0f 1154 if ((n = sscanf(arg, "%d:%d:%d",
1155 &options->max_startups_begin,
1156 &options->max_startups_rate,
1157 &options->max_startups)) == 3) {
1158 if (options->max_startups_begin >
1159 options->max_startups ||
1160 options->max_startups_rate > 100 ||
1161 options->max_startups_rate < 1)
c345cf9d 1162 fatal("%s line %d: Illegal MaxStartups spec.",
97de229c 1163 filename, linenum);
2717fa0f 1164 } else if (n != 1)
1165 fatal("%s line %d: Illegal MaxStartups spec.",
1166 filename, linenum);
1167 else
1168 options->max_startups = options->max_startups_begin;
1169 break;
1170
af4bd935 1171 case sMaxAuthTries:
1172 intptr = &options->max_authtries;
1173 goto parse_int;
1174
c6dca55e 1175 case sMaxSessions:
1176 intptr = &options->max_sessions;
1177 goto parse_int;
1178
2717fa0f 1179 case sBanner:
1180 charptr = &options->banner;
1181 goto parse_filename;
db49deeb 1182
2717fa0f 1183 /*
1184 * These options can contain %X options expanded at
1185 * connect time, so that you can specify paths like:
1186 *
1187 * AuthorizedKeysFile /etc/ssh_keys/%u
1188 */
1189 case sAuthorizedKeysFile:
1190 case sAuthorizedKeysFile2:
d4f40d92 1191 charptr = (opcode == sAuthorizedKeysFile) ?
2717fa0f 1192 &options->authorized_keys_file :
1193 &options->authorized_keys_file2;
1194 goto parse_filename;
1195
1196 case sClientAliveInterval:
1197 intptr = &options->client_alive_interval;
1198 goto parse_time;
1199
1200 case sClientAliveCountMax:
1201 intptr = &options->client_alive_count_max;
1202 goto parse_int;
1203
61a2c1da 1204 case sAcceptEnv:
1205 while ((arg = strdelim(&cp)) && *arg != '\0') {
1206 if (strchr(arg, '=') != NULL)
1207 fatal("%s line %d: Invalid environment name.",
1208 filename, linenum);
1209 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1210 fatal("%s line %d: too many allow env.",
1211 filename, linenum);
d231781a 1212 if (!*activep)
1213 break;
61a2c1da 1214 options->accept_env[options->num_accept_env++] =
1215 xstrdup(arg);
1216 }
1217 break;
1218
d20f3c9e 1219 case sPermitTunnel:
1220 intptr = &options->permit_tun;
a4f24bf8 1221 arg = strdelim(&cp);
1222 if (!arg || *arg == '\0')
1223 fatal("%s line %d: Missing yes/point-to-point/"
1224 "ethernet/no argument.", filename, linenum);
1760c982 1225 value = -1;
1226 for (i = 0; tunmode_desc[i].val != -1; i++)
1227 if (strcmp(tunmode_desc[i].text, arg) == 0) {
1228 value = tunmode_desc[i].val;
1229 break;
1230 }
1231 if (value == -1)
a4f24bf8 1232 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1233 "no argument: %s", filename, linenum, arg);
1234 if (*intptr == -1)
1235 *intptr = value;
1236 break;
d20f3c9e 1237
d231781a 1238 case sMatch:
1239 if (cmdline)
1240 fatal("Match directive not supported as a command-line "
1241 "option");
1242 value = match_cfg_line(&cp, linenum, user, host, address);
1243 if (value < 0)
1244 fatal("%s line %d: Bad Match condition", filename,
1245 linenum);
1246 *activep = value;
1247 break;
1248
2fefbadf 1249 case sPermitOpen:
1250 arg = strdelim(&cp);
1251 if (!arg || *arg == '\0')
1252 fatal("%s line %d: missing PermitOpen specification",
1253 filename, linenum);
38757197 1254 n = options->num_permitted_opens; /* modified later */
2fefbadf 1255 if (strcmp(arg, "any") == 0) {
38757197 1256 if (*activep && n == -1) {
2fefbadf 1257 channel_clear_adm_permitted_opens();
ea46e550 1258 options->num_permitted_opens = 0;
1259 }
2fefbadf 1260 break;
1261 }
75b6d52c 1262 if (*activep && n == -1)
1263 channel_clear_adm_permitted_opens();
ea46e550 1264 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1265 p = hpdelim(&arg);
1266 if (p == NULL)
1267 fatal("%s line %d: missing host in PermitOpen",
1268 filename, linenum);
1269 p = cleanhostname(p);
5134115d 1270 if (arg == NULL || (port = a2port(arg)) <= 0)
ea46e550 1271 fatal("%s line %d: bad port number in "
1272 "PermitOpen", filename, linenum);
75b6d52c 1273 if (*activep && n == -1)
ea46e550 1274 options->num_permitted_opens =
1275 channel_add_adm_permitted_opens(p, port);
ea46e550 1276 }
2fefbadf 1277 break;
1278
e7259e8d 1279 case sForceCommand:
1280 if (cp == NULL)
1281 fatal("%.200s line %d: Missing argument.", filename,
1282 linenum);
1283 len = strspn(cp, WHITESPACE);
1284 if (*activep && options->adm_forced_command == NULL)
1285 options->adm_forced_command = xstrdup(cp + len);
1286 return 0;
1287
db49deeb 1288 case sChrootDirectory:
1289 charptr = &options->chroot_directory;
c5bf32e6 1290
1291 arg = strdelim(&cp);
1292 if (!arg || *arg == '\0')
1293 fatal("%s line %d: missing file name.",
1294 filename, linenum);
1295 if (*activep && *charptr == NULL)
1296 *charptr = xstrdup(arg);
1297 break;
db49deeb 1298
fe7dba42 1299 case sRDomain:
1300 intptr = &options->rdomain;
1301 goto parse_int;
1302
2717fa0f 1303 case sDeprecated:
bbe88b6d 1304 logit("%s line %d: Deprecated option %s",
2717fa0f 1305 filename, linenum, arg);
1306 while (arg)
1307 arg = strdelim(&cp);
1308 break;
1309
a2144546 1310 case sUnsupported:
1311 logit("%s line %d: Unsupported option %s",
1312 filename, linenum, arg);
1313 while (arg)
1314 arg = strdelim(&cp);
1315 break;
1316
2717fa0f 1317 default:
1318 fatal("%s line %d: Missing handler for opcode %s (%d)",
1319 filename, linenum, arg, opcode);
1320 }
1321 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1322 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1323 filename, linenum, arg);
1324 return 0;
1325}
089fbbd2 1326
2717fa0f 1327/* Reads the server configuration file. */
5c53a31e 1328
2717fa0f 1329void
b9a549d7 1330load_server_config(const char *filename, Buffer *conf)
2717fa0f 1331{
b9a549d7 1332 char line[1024], *cp;
7528d467 1333 FILE *f;
2717fa0f 1334
b9a549d7 1335 debug2("%s: filename %s", __func__, filename);
1336 if ((f = fopen(filename, "r")) == NULL) {
2717fa0f 1337 perror(filename);
1338 exit(1);
1339 }
b9a549d7 1340 buffer_clear(conf);
2717fa0f 1341 while (fgets(line, sizeof(line), f)) {
b9a549d7 1342 /*
1343 * Trim out comments and strip whitespace
f2107e97 1344 * NB - preserve newlines, they are needed to reproduce
b9a549d7 1345 * line numbers later for error messages
1346 */
1347 if ((cp = strchr(line, '#')) != NULL)
1348 memcpy(cp, "\n", 2);
1349 cp = line + strspn(line, " \t\r");
1350
1351 buffer_append(conf, cp, strlen(cp));
8efc0c15 1352 }
b9a549d7 1353 buffer_append(conf, "\0", 1);
5260325f 1354 fclose(f);
b9a549d7 1355 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1356}
1357
1358void
d231781a 1359parse_server_match_config(ServerOptions *options, const char *user,
1360 const char *host, const char *address)
1361{
1362 ServerOptions mo;
1363
1364 initialize_server_options(&mo);
1365 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
03bcbf84 1366 copy_set_server_options(options, &mo, 0);
d231781a 1367}
1368
03bcbf84 1369/* Helper macros */
1370#define M_CP_INTOPT(n) do {\
1371 if (src->n != -1) \
1372 dst->n = src->n; \
1373} while (0)
1374#define M_CP_STROPT(n) do {\
1375 if (src->n != NULL) { \
1376 if (dst->n != NULL) \
1377 xfree(dst->n); \
1378 dst->n = src->n; \
1379 } \
1380} while(0)
1381
1382/*
1383 * Copy any supported values that are set.
1384 *
3e576dfe 1385 * If the preauth flag is set, we do not bother copying the string or
03bcbf84 1386 * array values that are not used pre-authentication, because any that we
1387 * do use must be explictly sent in mm_getpwnamallow().
1388 */
d231781a 1389void
03bcbf84 1390copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
d231781a 1391{
03bcbf84 1392 M_CP_INTOPT(password_authentication);
1393 M_CP_INTOPT(gss_authentication);
1394 M_CP_INTOPT(rsa_authentication);
1395 M_CP_INTOPT(pubkey_authentication);
1396 M_CP_INTOPT(kerberos_authentication);
1397 M_CP_INTOPT(hostbased_authentication);
1398 M_CP_INTOPT(kbd_interactive_authentication);
5adf6b9a 1399 M_CP_INTOPT(zero_knowledge_password_authentication);
2ef741a3 1400 M_CP_INTOPT(permit_root_login);
e68868a1 1401 M_CP_INTOPT(permit_empty_passwd);
03bcbf84 1402
1403 M_CP_INTOPT(allow_tcp_forwarding);
43c3f85c 1404 M_CP_INTOPT(allow_agent_forwarding);
03bcbf84 1405 M_CP_INTOPT(gateway_ports);
1406 M_CP_INTOPT(x11_display_offset);
1407 M_CP_INTOPT(x11_forwarding);
1408 M_CP_INTOPT(x11_use_localhost);
c6dca55e 1409 M_CP_INTOPT(max_sessions);
8086aeb2 1410 M_CP_INTOPT(max_authtries);
03bcbf84 1411
1412 M_CP_STROPT(banner);
1413 if (preauth)
1414 return;
1415 M_CP_STROPT(adm_forced_command);
db49deeb 1416 M_CP_STROPT(chroot_directory);
d231781a 1417}
1418
03bcbf84 1419#undef M_CP_INTOPT
1420#undef M_CP_STROPT
1421
d231781a 1422void
1423parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1424 const char *user, const char *host, const char *address)
b9a549d7 1425{
d231781a 1426 int active, linenum, bad_options = 0;
16acb158 1427 char *cp, *obuf, *cbuf;
b9a549d7 1428
1429 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1430
16acb158 1431 obuf = cbuf = xstrdup(buffer_ptr(conf));
d231781a 1432 active = user ? 0 : 1;
861cc543 1433 linenum = 1;
f8cc7664 1434 while ((cp = strsep(&cbuf, "\n")) != NULL) {
b9a549d7 1435 if (process_server_config_line(options, cp, filename,
d231781a 1436 linenum++, &active, user, host, address) != 0)
b9a549d7 1437 bad_options++;
1438 }
16acb158 1439 xfree(obuf);
b7c70970 1440 if (bad_options > 0)
1441 fatal("%s: terminating, %d bad configuration options",
1442 filename, bad_options);
8efc0c15 1443}
1760c982 1444
1445static const char *
1446fmt_intarg(ServerOpCodes code, int val)
1447{
1448 if (code == sAddressFamily) {
1449 switch (val) {
1450 case AF_INET:
1451 return "inet";
1452 case AF_INET6:
1453 return "inet6";
1454 case AF_UNSPEC:
1455 return "any";
1456 default:
1457 return "UNKNOWN";
1458 }
1459 }
1460 if (code == sPermitRootLogin) {
1461 switch (val) {
1462 case PERMIT_NO_PASSWD:
0bd3332c 1463 return "without-password";
1760c982 1464 case PERMIT_FORCED_ONLY:
1465 return "forced-commands-only";
1466 case PERMIT_YES:
1467 return "yes";
1468 }
1469 }
1470 if (code == sProtocol) {
1471 switch (val) {
1472 case SSH_PROTO_1:
1473 return "1";
1474 case SSH_PROTO_2:
1475 return "2";
1476 case (SSH_PROTO_1|SSH_PROTO_2):
1477 return "2,1";
1478 default:
1479 return "UNKNOWN";
1480 }
1481 }
1482 if (code == sGatewayPorts && val == 2)
1483 return "clientspecified";
1484 if (code == sCompression && val == COMP_DELAYED)
1485 return "delayed";
1486 switch (val) {
1487 case -1:
1488 return "unset";
1489 case 0:
1490 return "no";
1491 case 1:
1492 return "yes";
1493 }
1494 return "UNKNOWN";
1495}
1496
1497static const char *
1498lookup_opcode_name(ServerOpCodes code)
1499{
1500 u_int i;
1501
1502 for (i = 0; keywords[i].name != NULL; i++)
1503 if (keywords[i].opcode == code)
1504 return(keywords[i].name);
1505 return "UNKNOWN";
1506}
1507
1508static void
1509dump_cfg_int(ServerOpCodes code, int val)
1510{
1511 printf("%s %d\n", lookup_opcode_name(code), val);
1512}
1513
1514static void
1515dump_cfg_fmtint(ServerOpCodes code, int val)
1516{
1517 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1518}
1519
1520static void
1521dump_cfg_string(ServerOpCodes code, const char *val)
1522{
1523 if (val == NULL)
1524 return;
1525 printf("%s %s\n", lookup_opcode_name(code), val);
1526}
1527
1528static void
1529dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
1530{
1531 u_int i;
1532
1533 for (i = 0; i < count; i++)
1534 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
1535}
1536
1537void
1538dump_config(ServerOptions *o)
1539{
1540 u_int i;
1541 int ret;
1542 struct addrinfo *ai;
1543 char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
1544
1545 /* these are usually at the top of the config */
1546 for (i = 0; i < o->num_ports; i++)
1547 printf("port %d\n", o->ports[i]);
1548 dump_cfg_fmtint(sProtocol, o->protocol);
1549 dump_cfg_fmtint(sAddressFamily, o->address_family);
1550
1551 /* ListenAddress must be after Port */
1552 for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
1553 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
1554 sizeof(addr), port, sizeof(port),
1555 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1556 error("getnameinfo failed: %.100s",
1557 (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1558 strerror(errno));
1559 } else {
1560 if (ai->ai_family == AF_INET6)
1561 printf("listenaddress [%s]:%s\n", addr, port);
1562 else
1563 printf("listenaddress %s:%s\n", addr, port);
1564 }
1565 }
1566
1567 /* integer arguments */
cee47c9f 1568#ifdef USE_PAM
1569 dump_cfg_int(sUsePAM, o->use_pam);
1570#endif
1760c982 1571 dump_cfg_int(sServerKeyBits, o->server_key_bits);
1572 dump_cfg_int(sLoginGraceTime, o->login_grace_time);
1573 dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
1574 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
1575 dump_cfg_int(sMaxAuthTries, o->max_authtries);
39aa8698 1576 dump_cfg_int(sMaxSessions, o->max_sessions);
1760c982 1577 dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
1578 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
fe7dba42 1579 dump_cfg_int(sRDomain, o->rdomain);
1760c982 1580
1581 /* formatted integer arguments */
1582 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
1583 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
1584 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
1585 dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
1586 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
1587 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
1588 o->hostbased_uses_name_from_packet_only);
1589 dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
1590 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
e888d981 1591#ifdef KRB5
1760c982 1592 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
1593 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
1594 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
e888d981 1595# ifdef USE_AFS
1760c982 1596 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
e888d981 1597# endif
1598#endif
1599#ifdef GSSAPI
1760c982 1600 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
1601 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
5adf6b9a 1602#endif
1603#ifdef JPAKE
1604 dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
1605 o->zero_knowledge_password_authentication);
e888d981 1606#endif
1760c982 1607 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
1608 dump_cfg_fmtint(sKbdInteractiveAuthentication,
1609 o->kbd_interactive_authentication);
1610 dump_cfg_fmtint(sChallengeResponseAuthentication,
1611 o->challenge_response_authentication);
1612 dump_cfg_fmtint(sPrintMotd, o->print_motd);
1613 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
1614 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
1615 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
1616 dump_cfg_fmtint(sStrictModes, o->strict_modes);
1617 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
1618 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
1619 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
1620 dump_cfg_fmtint(sUseLogin, o->use_login);
1621 dump_cfg_fmtint(sCompression, o->compression);
1622 dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
1623 dump_cfg_fmtint(sUseDNS, o->use_dns);
1624 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
1625 dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
1626
1627 /* string arguments */
1628 dump_cfg_string(sPidFile, o->pid_file);
1629 dump_cfg_string(sXAuthLocation, o->xauth_location);
1630 dump_cfg_string(sCiphers, o->ciphers);
1631 dump_cfg_string(sMacs, o->macs);
1632 dump_cfg_string(sBanner, o->banner);
1633 dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
1634 dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
1635 dump_cfg_string(sForceCommand, o->adm_forced_command);
1636
1637 /* string arguments requiring a lookup */
1638 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1639 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
1640
1641 /* string array arguments */
1642 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
1643 o->host_key_files);
1644 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
1645 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
1646 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
1647 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
1648 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
1649
1650 /* other arguments */
1651 for (i = 0; i < o->num_subsystems; i++)
1652 printf("subsystem %s %s\n", o->subsystem_name[i],
1653 o->subsystem_args[i]);
1654
1655 printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
1656 o->max_startups_rate, o->max_startups);
1657
1658 for (i = 0; tunmode_desc[i].val != -1; i++)
1659 if (tunmode_desc[i].val == o->permit_tun) {
1660 s = tunmode_desc[i].text;
1661 break;
1662 }
1663 dump_cfg_string(sPermitTunnel, s);
1664
1760c982 1665 channel_print_adm_permitted_opens();
1760c982 1666}
This page took 3.387404 seconds and 5 git commands to generate.