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