]> andersk Git - openssh.git/blame - servconf.c
- stevesk@cvs.openbsd.org 2006/07/20 15:26:15
[openssh.git] / servconf.c
CommitLineData
e7259e8d 1/* $OpenBSD: servconf.c,v 1.158 2006/07/19 13:07:10 dtucker 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
c8dfff33 18#if defined(HAVE_NETDB_H)
19# include <netdb.h>
20#endif
5188ba17 21#include <unistd.h>
c8dfff33 22
8efc0c15 23#include "ssh.h"
42f11eb2 24#include "log.h"
8efc0c15 25#include "servconf.h"
26#include "xmalloc.h"
a8be9f80 27#include "compat.h"
42f11eb2 28#include "pathnames.h"
42f11eb2 29#include "misc.h"
30#include "cipher.h"
b2552997 31#include "kex.h"
32#include "mac.h"
d231781a 33#include "match.h"
2fefbadf 34#include "channels.h"
42f11eb2 35
396c147e 36static void add_listen_addr(ServerOptions *, char *, u_short);
37static void add_one_listen_addr(ServerOptions *, char *, u_short);
48e671d5 38
1853d1ef 39/* Use of privilege separation or not */
40extern int use_privsep;
d231781a 41extern Buffer cfg;
42f11eb2 42
8efc0c15 43/* Initializes the server options to their default values. */
44
6ae2364d 45void
5260325f 46initialize_server_options(ServerOptions *options)
8efc0c15 47{
5260325f 48 memset(options, 0, sizeof(*options));
e15895cd 49
50 /* Portable-specific options */
7fceb20d 51 options->use_pam = -1;
e15895cd 52
53 /* Standard Options */
48e671d5 54 options->num_ports = 0;
55 options->ports_from_cmdline = 0;
56 options->listen_addrs = NULL;
31b41ceb 57 options->address_family = -1;
fa08c86b 58 options->num_host_key_files = 0;
0fbe8c74 59 options->pid_file = NULL;
5260325f 60 options->server_key_bits = -1;
61 options->login_grace_time = -1;
62 options->key_regeneration_time = -1;
15853e93 63 options->permit_root_login = PERMIT_NOT_SET;
5260325f 64 options->ignore_rhosts = -1;
65 options->ignore_user_known_hosts = -1;
66 options->print_motd = -1;
4f4648f9 67 options->print_lastlog = -1;
5260325f 68 options->x11_forwarding = -1;
69 options->x11_display_offset = -1;
e6e573bd 70 options->x11_use_localhost = -1;
fa649821 71 options->xauth_location = NULL;
5260325f 72 options->strict_modes = -1;
fd573618 73 options->tcp_keep_alive = -1;
5eaf8578 74 options->log_facility = SYSLOG_FACILITY_NOT_SET;
75 options->log_level = SYSLOG_LEVEL_NOT_SET;
5260325f 76 options->rhosts_rsa_authentication = -1;
8002af61 77 options->hostbased_authentication = -1;
78 options->hostbased_uses_name_from_packet_only = -1;
5260325f 79 options->rsa_authentication = -1;
fa08c86b 80 options->pubkey_authentication = -1;
5260325f 81 options->kerberos_authentication = -1;
82 options->kerberos_or_local_passwd = -1;
83 options->kerberos_ticket_cleanup = -1;
a1e30b47 84 options->kerberos_get_afs_token = -1;
7364bd04 85 options->gss_authentication=-1;
86 options->gss_cleanup_creds = -1;
5260325f 87 options->password_authentication = -1;
94ec8c6b 88 options->kbd_interactive_authentication = -1;
5ba55ada 89 options->challenge_response_authentication = -1;
5260325f 90 options->permit_empty_passwd = -1;
f00bab84 91 options->permit_user_env = -1;
5260325f 92 options->use_login = -1;
636f76ca 93 options->compression = -1;
33de75a3 94 options->allow_tcp_forwarding = -1;
5260325f 95 options->num_allow_users = 0;
96 options->num_deny_users = 0;
97 options->num_allow_groups = 0;
98 options->num_deny_groups = 0;
a8be9f80 99 options->ciphers = NULL;
b2552997 100 options->macs = NULL;
a8be9f80 101 options->protocol = SSH_PROTO_UNKNOWN;
1d1ffb87 102 options->gateway_ports = -1;
38c295d6 103 options->num_subsystems = 0;
c345cf9d 104 options->max_startups_begin = -1;
105 options->max_startups_rate = -1;
089fbbd2 106 options->max_startups = -1;
af4bd935 107 options->max_authtries = -1;
eea39c02 108 options->banner = NULL;
c5a7d788 109 options->use_dns = -1;
3ffc6336 110 options->client_alive_interval = -1;
111 options->client_alive_count_max = -1;
c8445989 112 options->authorized_keys_file = NULL;
113 options->authorized_keys_file2 = NULL;
61a2c1da 114 options->num_accept_env = 0;
d20f3c9e 115 options->permit_tun = -1;
e7259e8d 116 options->adm_forced_command = NULL;
8efc0c15 117}
118
6ae2364d 119void
5260325f 120fill_default_server_options(ServerOptions *options)
8efc0c15 121{
e15895cd 122 /* Portable-specific options */
7fceb20d 123 if (options->use_pam == -1)
0a23d79f 124 options->use_pam = 0;
e15895cd 125
126 /* Standard Options */
fa08c86b 127 if (options->protocol == SSH_PROTO_UNKNOWN)
128 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
129 if (options->num_host_key_files == 0) {
130 /* fill default hostkeys for protocols */
131 if (options->protocol & SSH_PROTO_1)
0f84fe37 132 options->host_key_files[options->num_host_key_files++] =
133 _PATH_HOST_KEY_FILE;
134 if (options->protocol & SSH_PROTO_2) {
135 options->host_key_files[options->num_host_key_files++] =
136 _PATH_HOST_RSA_KEY_FILE;
137 options->host_key_files[options->num_host_key_files++] =
138 _PATH_HOST_DSA_KEY_FILE;
139 }
fa08c86b 140 }
48e671d5 141 if (options->num_ports == 0)
142 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
143 if (options->listen_addrs == NULL)
2d2a2c65 144 add_listen_addr(options, NULL, 0);
0fbe8c74 145 if (options->pid_file == NULL)
42f11eb2 146 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
5260325f 147 if (options->server_key_bits == -1)
148 options->server_key_bits = 768;
149 if (options->login_grace_time == -1)
3445ca02 150 options->login_grace_time = 120;
5260325f 151 if (options->key_regeneration_time == -1)
152 options->key_regeneration_time = 3600;
15853e93 153 if (options->permit_root_login == PERMIT_NOT_SET)
154 options->permit_root_login = PERMIT_YES;
5260325f 155 if (options->ignore_rhosts == -1)
c8d54615 156 options->ignore_rhosts = 1;
5260325f 157 if (options->ignore_user_known_hosts == -1)
158 options->ignore_user_known_hosts = 0;
5260325f 159 if (options->print_motd == -1)
160 options->print_motd = 1;
4f4648f9 161 if (options->print_lastlog == -1)
162 options->print_lastlog = 1;
5260325f 163 if (options->x11_forwarding == -1)
c8d54615 164 options->x11_forwarding = 0;
5260325f 165 if (options->x11_display_offset == -1)
c8d54615 166 options->x11_display_offset = 10;
e6e573bd 167 if (options->x11_use_localhost == -1)
168 options->x11_use_localhost = 1;
fa649821 169 if (options->xauth_location == NULL)
fd9ede94 170 options->xauth_location = _PATH_XAUTH;
5260325f 171 if (options->strict_modes == -1)
172 options->strict_modes = 1;
fd573618 173 if (options->tcp_keep_alive == -1)
174 options->tcp_keep_alive = 1;
5eaf8578 175 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
5260325f 176 options->log_facility = SYSLOG_FACILITY_AUTH;
5eaf8578 177 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
59c97189 178 options->log_level = SYSLOG_LEVEL_INFO;
5260325f 179 if (options->rhosts_rsa_authentication == -1)
c8d54615 180 options->rhosts_rsa_authentication = 0;
8002af61 181 if (options->hostbased_authentication == -1)
182 options->hostbased_authentication = 0;
183 if (options->hostbased_uses_name_from_packet_only == -1)
184 options->hostbased_uses_name_from_packet_only = 0;
5260325f 185 if (options->rsa_authentication == -1)
186 options->rsa_authentication = 1;
fa08c86b 187 if (options->pubkey_authentication == -1)
188 options->pubkey_authentication = 1;
5260325f 189 if (options->kerberos_authentication == -1)
eadc806d 190 options->kerberos_authentication = 0;
5260325f 191 if (options->kerberos_or_local_passwd == -1)
192 options->kerberos_or_local_passwd = 1;
193 if (options->kerberos_ticket_cleanup == -1)
194 options->kerberos_ticket_cleanup = 1;
a1e30b47 195 if (options->kerberos_get_afs_token == -1)
196 options->kerberos_get_afs_token = 0;
7364bd04 197 if (options->gss_authentication == -1)
198 options->gss_authentication = 0;
199 if (options->gss_cleanup_creds == -1)
200 options->gss_cleanup_creds = 1;
5260325f 201 if (options->password_authentication == -1)
202 options->password_authentication = 1;
94ec8c6b 203 if (options->kbd_interactive_authentication == -1)
204 options->kbd_interactive_authentication = 0;
5ba55ada 205 if (options->challenge_response_authentication == -1)
206 options->challenge_response_authentication = 1;
5260325f 207 if (options->permit_empty_passwd == -1)
c8d54615 208 options->permit_empty_passwd = 0;
f00bab84 209 if (options->permit_user_env == -1)
210 options->permit_user_env = 0;
5260325f 211 if (options->use_login == -1)
212 options->use_login = 0;
636f76ca 213 if (options->compression == -1)
07200973 214 options->compression = COMP_DELAYED;
33de75a3 215 if (options->allow_tcp_forwarding == -1)
216 options->allow_tcp_forwarding = 1;
1d1ffb87 217 if (options->gateway_ports == -1)
218 options->gateway_ports = 0;
089fbbd2 219 if (options->max_startups == -1)
220 options->max_startups = 10;
c345cf9d 221 if (options->max_startups_rate == -1)
222 options->max_startups_rate = 100; /* 100% */
223 if (options->max_startups_begin == -1)
224 options->max_startups_begin = options->max_startups;
af4bd935 225 if (options->max_authtries == -1)
226 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
c5a7d788 227 if (options->use_dns == -1)
228 options->use_dns = 1;
3ffc6336 229 if (options->client_alive_interval == -1)
184eed6a 230 options->client_alive_interval = 0;
3ffc6336 231 if (options->client_alive_count_max == -1)
232 options->client_alive_count_max = 3;
5df83e07 233 if (options->authorized_keys_file2 == NULL) {
234 /* authorized_keys_file2 falls back to authorized_keys_file */
235 if (options->authorized_keys_file != NULL)
236 options->authorized_keys_file2 = options->authorized_keys_file;
237 else
238 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
239 }
240 if (options->authorized_keys_file == NULL)
241 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
d20f3c9e 242 if (options->permit_tun == -1)
a4f24bf8 243 options->permit_tun = SSH_TUNMODE_NO;
1853d1ef 244
2ee1b704 245 /* Turn privilege separation on by default */
1853d1ef 246 if (use_privsep == -1)
2ee1b704 247 use_privsep = 1;
e299a298 248
4165b82e 249#ifndef HAVE_MMAP
e299a298 250 if (use_privsep && options->compression == 1) {
251 error("This platform does not support both privilege "
252 "separation and compression");
253 error("Compression disabled");
254 options->compression = 0;
255 }
256#endif
257
8efc0c15 258}
259
8efc0c15 260/* Keyword tokens. */
5260325f 261typedef enum {
262 sBadOption, /* == unknown option */
e15895cd 263 /* Portable-specific options */
7fceb20d 264 sUsePAM,
e15895cd 265 /* Standard Options */
5260325f 266 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
267 sPermitRootLogin, sLogFacility, sLogLevel,
0598d99d 268 sRhostsRSAAuthentication, sRSAAuthentication,
5260325f 269 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
a1e30b47 270 sKerberosGetAFSToken,
1c590258 271 sKerberosTgtPassing, sChallengeResponseAuthentication,
31b41ceb 272 sPasswordAuthentication, sKbdInteractiveAuthentication,
273 sListenAddress, sAddressFamily,
4f4648f9 274 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
e6e573bd 275 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
fd573618 276 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
f00bab84 277 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
33de75a3 278 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
b2552997 279 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
af4bd935 280 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
281 sMaxStartups, sMaxAuthTries,
c5a7d788 282 sBanner, sUseDNS, sHostbasedAuthentication,
184eed6a 283 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
c8445989 284 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
d20f3c9e 285 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
e7259e8d 286 sMatch, sPermitOpen, sForceCommand,
2ea6de2b 287 sUsePrivilegeSeparation,
a2144546 288 sDeprecated, sUnsupported
8efc0c15 289} ServerOpCodes;
290
d231781a 291#define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
292#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
293#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
294
8efc0c15 295/* Textual representation of the tokens. */
5260325f 296static struct {
297 const char *name;
298 ServerOpCodes opcode;
d231781a 299 u_int flags;
5260325f 300} keywords[] = {
e15895cd 301 /* Portable-specific options */
b06b11ad 302#ifdef USE_PAM
d231781a 303 { "usepam", sUsePAM, SSHCFG_GLOBAL },
b06b11ad 304#else
d231781a 305 { "usepam", sUnsupported, SSHCFG_GLOBAL },
b06b11ad 306#endif
d231781a 307 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
e15895cd 308 /* Standard Options */
d231781a 309 { "port", sPort, SSHCFG_GLOBAL },
310 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
311 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
312 { "pidfile", sPidFile, SSHCFG_GLOBAL },
313 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
314 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
315 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
316 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
317 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
318 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
319 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
320 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
321 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
322 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
323 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
324 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
325 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
1c590258 326#ifdef KRB5
d231781a 327 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
328 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
329 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
bcfcc5f9 330#ifdef USE_AFS
d231781a 331 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
309af4e5 332#else
d231781a 333 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
309af4e5 334#endif
a2144546 335#else
d231781a 336 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
337 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
338 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
339 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
a2144546 340#endif
d231781a 341 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
342 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
7364bd04 343#ifdef GSSAPI
d231781a 344 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
345 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
7364bd04 346#else
d231781a 347 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
348 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
7364bd04 349#endif
d231781a 350 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
351 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
352 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
353 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
354 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
355 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
356 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
357 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
358 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
359 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
360 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
691712e0 361 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
362 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
363 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
d231781a 364 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
365 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
366 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
367 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
368 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
369 { "compression", sCompression, SSHCFG_GLOBAL },
370 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
371 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
372 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
373 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
374 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
375 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
376 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
377 { "ciphers", sCiphers, SSHCFG_GLOBAL },
378 { "macs", sMacs, SSHCFG_GLOBAL },
379 { "protocol", sProtocol, SSHCFG_GLOBAL },
380 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
381 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
382 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
383 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
384 { "banner", sBanner, SSHCFG_GLOBAL },
385 { "usedns", sUseDNS, SSHCFG_GLOBAL },
386 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
387 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
388 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
389 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
390 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
391 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
392 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
393 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
394 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
2fefbadf 395 { "match", sMatch, SSHCFG_ALL },
396 { "permitopen", sPermitOpen, SSHCFG_ALL },
e7259e8d 397 { "forcecommand", sForceCommand, SSHCFG_ALL },
d231781a 398 { NULL, sBadOption, 0 }
8efc0c15 399};
400
aa3378df 401/*
6be9a5e8 402 * Returns the number of the token pointed to by cp or sBadOption.
aa3378df 403 */
8efc0c15 404
6ae2364d 405static ServerOpCodes
5260325f 406parse_token(const char *cp, const char *filename,
d231781a 407 int linenum, u_int *flags)
8efc0c15 408{
1e3b8b07 409 u_int i;
8efc0c15 410
5260325f 411 for (i = 0; keywords[i].name; i++)
d231781a 412 if (strcasecmp(cp, keywords[i].name) == 0) {
413 *flags = keywords[i].flags;
5260325f 414 return keywords[i].opcode;
d231781a 415 }
8efc0c15 416
b7c70970 417 error("%s: line %d: Bad configuration option: %s",
418 filename, linenum, cp);
5260325f 419 return sBadOption;
8efc0c15 420}
421
396c147e 422static void
2d2a2c65 423add_listen_addr(ServerOptions *options, char *addr, u_short port)
48e671d5 424{
2ceb8101 425 u_int i;
48e671d5 426
427 if (options->num_ports == 0)
428 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
31b41ceb 429 if (options->address_family == -1)
430 options->address_family = AF_UNSPEC;
2d2a2c65 431 if (port == 0)
d11c1288 432 for (i = 0; i < options->num_ports; i++)
433 add_one_listen_addr(options, addr, options->ports[i]);
434 else
2d2a2c65 435 add_one_listen_addr(options, addr, port);
d11c1288 436}
437
396c147e 438static void
d11c1288 439add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
440{
441 struct addrinfo hints, *ai, *aitop;
442 char strport[NI_MAXSERV];
443 int gaierr;
444
445 memset(&hints, 0, sizeof(hints));
31b41ceb 446 hints.ai_family = options->address_family;
d11c1288 447 hints.ai_socktype = SOCK_STREAM;
448 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
7528d467 449 snprintf(strport, sizeof strport, "%u", port);
d11c1288 450 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
451 fatal("bad addr or host: %s (%s)",
452 addr ? addr : "<NULL>",
453 gai_strerror(gaierr));
454 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
455 ;
456 ai->ai_next = options->listen_addrs;
457 options->listen_addrs = aitop;
48e671d5 458}
459
d231781a 460/*
461 * The strategy for the Match blocks is that the config file is parsed twice.
462 *
463 * The first time is at startup. activep is initialized to 1 and the
464 * directives in the global context are processed and acted on. Hitting a
465 * Match directive unsets activep and the directives inside the block are
466 * checked for syntax only.
467 *
468 * The second time is after a connection has been established but before
469 * authentication. activep is initialized to 2 and global config directives
470 * are ignored since they have already been processed. If the criteria in a
471 * Match block is met, activep is set and the subsequent directives
472 * processed and actioned until EOF or another Match block unsets it. Any
473 * options set are copied into the main server config.
474 *
475 * Potential additions/improvements:
476 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
477 *
478 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
479 * Match Address 192.168.0.*
480 * Tag trusted
481 * Match Group wheel
482 * Tag trusted
483 * Match Tag trusted
484 * AllowTcpForwarding yes
485 * GatewayPorts clientspecified
486 * [...]
487 *
488 * - Add a PermittedChannelRequests directive
489 * Match Group shell
490 * PermittedChannelRequests session,forwarded-tcpip
491 */
492
493static int
494match_cfg_line(char **condition, int line, const char *user, const char *host,
495 const char *address)
496{
497 int result = 1;
498 char *arg, *attrib, *cp = *condition;
499 size_t len;
500
501 if (user == NULL)
502 debug3("checking syntax for 'Match %s'", cp);
503 else
504 debug3("checking match for '%s' user %s host %s addr %s", cp,
505 user ? user : "(null)", host ? host : "(null)",
506 address ? address : "(null)");
507
508 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
509 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
510 error("Missing Match criteria for %s", attrib);
511 return -1;
512 }
513 len = strlen(arg);
514 if (strcasecmp(attrib, "user") == 0) {
515 if (!user) {
516 result = 0;
517 continue;
518 }
519 if (match_pattern_list(user, arg, len, 0) != 1)
520 result = 0;
521 else
522 debug("user %.100s matched 'User %.100s' at "
523 "line %d", user, arg, line);
524 } else if (strcasecmp(attrib, "host") == 0) {
525 if (!host) {
526 result = 0;
527 continue;
528 }
529 if (match_hostname(host, arg, len) != 1)
530 result = 0;
531 else
532 debug("connection from %.100s matched 'Host "
533 "%.100s' at line %d", host, arg, line);
534 } else if (strcasecmp(attrib, "address") == 0) {
535 debug("address '%s' arg '%s'", address, arg);
536 if (!address) {
537 result = 0;
538 continue;
539 }
540 if (match_hostname(address, arg, len) != 1)
541 result = 0;
542 else
543 debug("connection from %.100s matched 'Address "
544 "%.100s' at line %d", address, arg, line);
545 } else {
546 error("Unsupported Match attribute %s", attrib);
547 return -1;
548 }
549 }
550 if (user != NULL)
551 debug3("match %sfound", result ? "" : "not ");
552 *condition = cp;
553 return result;
554}
555
e7259e8d 556#define WHITESPACE " \t\r\n"
557
2717fa0f 558int
559process_server_config_line(ServerOptions *options, char *line,
d231781a 560 const char *filename, int linenum, int *activep, const char *user,
561 const char *host, const char *address)
8efc0c15 562{
d11c1288 563 char *cp, **charptr, *arg, *p;
d231781a 564 int cmdline = 0, *intptr, value, n;
5260325f 565 ServerOpCodes opcode;
3867aa0a 566 u_short port;
d231781a 567 u_int i, flags = 0;
d66ce1a1 568 size_t len;
5260325f 569
2717fa0f 570 cp = line;
0f8cd5a6 571 if ((arg = strdelim(&cp)) == NULL)
88299971 572 return 0;
2717fa0f 573 /* Ignore leading whitespace */
574 if (*arg == '\0')
704b1659 575 arg = strdelim(&cp);
2717fa0f 576 if (!arg || !*arg || *arg == '#')
577 return 0;
578 intptr = NULL;
579 charptr = NULL;
d231781a 580 opcode = parse_token(arg, filename, linenum, &flags);
581
582 if (activep == NULL) { /* We are processing a command line directive */
583 cmdline = 1;
584 activep = &cmdline;
585 }
586 if (*activep && opcode != sMatch)
587 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
588 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
589 if (user == NULL) {
590 fatal("%s line %d: Directive '%s' is not allowed "
591 "within a Match block", filename, linenum, arg);
592 } else { /* this is a directive we have already processed */
593 while (arg)
594 arg = strdelim(&cp);
595 return 0;
596 }
597 }
598
2717fa0f 599 switch (opcode) {
600 /* Portable-specific options */
7fceb20d 601 case sUsePAM:
602 intptr = &options->use_pam;
2717fa0f 603 goto parse_flag;
48e671d5 604
2717fa0f 605 /* Standard Options */
606 case sBadOption:
607 return -1;
608 case sPort:
609 /* ignore ports from configfile if cmdline specifies ports */
610 if (options->ports_from_cmdline)
611 return 0;
612 if (options->listen_addrs != NULL)
613 fatal("%s line %d: ports must be specified before "
3a454b6a 614 "ListenAddress.", filename, linenum);
2717fa0f 615 if (options->num_ports >= MAX_PORTS)
616 fatal("%s line %d: too many ports.",
617 filename, linenum);
618 arg = strdelim(&cp);
619 if (!arg || *arg == '\0')
620 fatal("%s line %d: missing port number.",
621 filename, linenum);
622 options->ports[options->num_ports++] = a2port(arg);
623 if (options->ports[options->num_ports-1] == 0)
624 fatal("%s line %d: Badly formatted port number.",
625 filename, linenum);
626 break;
627
628 case sServerKeyBits:
629 intptr = &options->server_key_bits;
5260325f 630parse_int:
2717fa0f 631 arg = strdelim(&cp);
632 if (!arg || *arg == '\0')
633 fatal("%s line %d: missing integer value.",
634 filename, linenum);
635 value = atoi(arg);
d231781a 636 if (*activep && *intptr == -1)
2717fa0f 637 *intptr = value;
638 break;
639
640 case sLoginGraceTime:
641 intptr = &options->login_grace_time;
e2b1fb42 642parse_time:
2717fa0f 643 arg = strdelim(&cp);
644 if (!arg || *arg == '\0')
645 fatal("%s line %d: missing time value.",
646 filename, linenum);
647 if ((value = convtime(arg)) == -1)
648 fatal("%s line %d: invalid time value.",
649 filename, linenum);
650 if (*intptr == -1)
651 *intptr = value;
652 break;
653
654 case sKeyRegenerationTime:
655 intptr = &options->key_regeneration_time;
656 goto parse_time;
657
658 case sListenAddress:
659 arg = strdelim(&cp);
3867aa0a 660 if (arg == NULL || *arg == '\0')
661 fatal("%s line %d: missing address",
2717fa0f 662 filename, linenum);
91135a0e 663 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
664 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
665 && strchr(p+1, ':') != NULL) {
666 add_listen_addr(options, arg, 0);
667 break;
668 }
3867aa0a 669 p = hpdelim(&arg);
670 if (p == NULL)
671 fatal("%s line %d: bad address:port usage",
2717fa0f 672 filename, linenum);
3867aa0a 673 p = cleanhostname(p);
674 if (arg == NULL)
675 port = 0;
676 else if ((port = a2port(arg)) == 0)
677 fatal("%s line %d: bad port number", filename, linenum);
678
679 add_listen_addr(options, p, port);
680
2717fa0f 681 break;
682
31b41ceb 683 case sAddressFamily:
684 arg = strdelim(&cp);
38634ff6 685 if (!arg || *arg == '\0')
686 fatal("%s line %d: missing address family.",
687 filename, linenum);
31b41ceb 688 intptr = &options->address_family;
689 if (options->listen_addrs != NULL)
690 fatal("%s line %d: address family must be specified before "
691 "ListenAddress.", filename, linenum);
692 if (strcasecmp(arg, "inet") == 0)
693 value = AF_INET;
694 else if (strcasecmp(arg, "inet6") == 0)
695 value = AF_INET6;
696 else if (strcasecmp(arg, "any") == 0)
697 value = AF_UNSPEC;
698 else
699 fatal("%s line %d: unsupported address family \"%s\".",
700 filename, linenum, arg);
701 if (*intptr == -1)
702 *intptr = value;
703 break;
704
2717fa0f 705 case sHostKeyFile:
706 intptr = &options->num_host_key_files;
707 if (*intptr >= MAX_HOSTKEYS)
708 fatal("%s line %d: too many host keys specified (max %d).",
709 filename, linenum, MAX_HOSTKEYS);
710 charptr = &options->host_key_files[*intptr];
fa649821 711parse_filename:
2717fa0f 712 arg = strdelim(&cp);
713 if (!arg || *arg == '\0')
714 fatal("%s line %d: missing file name.",
715 filename, linenum);
d231781a 716 if (*activep && *charptr == NULL) {
2717fa0f 717 *charptr = tilde_expand_filename(arg, getuid());
718 /* increase optional counter */
719 if (intptr != NULL)
720 *intptr = *intptr + 1;
721 }
722 break;
0fbe8c74 723
2717fa0f 724 case sPidFile:
725 charptr = &options->pid_file;
726 goto parse_filename;
5260325f 727
2717fa0f 728 case sPermitRootLogin:
729 intptr = &options->permit_root_login;
730 arg = strdelim(&cp);
731 if (!arg || *arg == '\0')
732 fatal("%s line %d: missing yes/"
733 "without-password/forced-commands-only/no "
734 "argument.", filename, linenum);
735 value = 0; /* silence compiler */
736 if (strcmp(arg, "without-password") == 0)
737 value = PERMIT_NO_PASSWD;
738 else if (strcmp(arg, "forced-commands-only") == 0)
739 value = PERMIT_FORCED_ONLY;
740 else if (strcmp(arg, "yes") == 0)
741 value = PERMIT_YES;
742 else if (strcmp(arg, "no") == 0)
743 value = PERMIT_NO;
744 else
745 fatal("%s line %d: Bad yes/"
746 "without-password/forced-commands-only/no "
747 "argument: %s", filename, linenum, arg);
748 if (*intptr == -1)
749 *intptr = value;
750 break;
751
752 case sIgnoreRhosts:
753 intptr = &options->ignore_rhosts;
5260325f 754parse_flag:
2717fa0f 755 arg = strdelim(&cp);
756 if (!arg || *arg == '\0')
757 fatal("%s line %d: missing yes/no argument.",
758 filename, linenum);
759 value = 0; /* silence compiler */
760 if (strcmp(arg, "yes") == 0)
761 value = 1;
762 else if (strcmp(arg, "no") == 0)
763 value = 0;
764 else
765 fatal("%s line %d: Bad yes/no argument: %s",
766 filename, linenum, arg);
d231781a 767 if (*activep && *intptr == -1)
2717fa0f 768 *intptr = value;
769 break;
770
771 case sIgnoreUserKnownHosts:
772 intptr = &options->ignore_user_known_hosts;
773 goto parse_flag;
774
2717fa0f 775 case sRhostsRSAAuthentication:
776 intptr = &options->rhosts_rsa_authentication;
777 goto parse_flag;
778
779 case sHostbasedAuthentication:
780 intptr = &options->hostbased_authentication;
781 goto parse_flag;
782
783 case sHostbasedUsesNameFromPacketOnly:
784 intptr = &options->hostbased_uses_name_from_packet_only;
785 goto parse_flag;
786
787 case sRSAAuthentication:
788 intptr = &options->rsa_authentication;
789 goto parse_flag;
790
791 case sPubkeyAuthentication:
792 intptr = &options->pubkey_authentication;
793 goto parse_flag;
d0ec7f42 794
2717fa0f 795 case sKerberosAuthentication:
796 intptr = &options->kerberos_authentication;
797 goto parse_flag;
5260325f 798
2717fa0f 799 case sKerberosOrLocalPasswd:
800 intptr = &options->kerberos_or_local_passwd;
801 goto parse_flag;
5260325f 802
2717fa0f 803 case sKerberosTicketCleanup:
804 intptr = &options->kerberos_ticket_cleanup;
805 goto parse_flag;
d0ec7f42 806
a1e30b47 807 case sKerberosGetAFSToken:
808 intptr = &options->kerberos_get_afs_token;
809 goto parse_flag;
810
7364bd04 811 case sGssAuthentication:
812 intptr = &options->gss_authentication;
813 goto parse_flag;
814
815 case sGssCleanupCreds:
816 intptr = &options->gss_cleanup_creds;
817 goto parse_flag;
818
2717fa0f 819 case sPasswordAuthentication:
820 intptr = &options->password_authentication;
821 goto parse_flag;
5260325f 822
2717fa0f 823 case sKbdInteractiveAuthentication:
824 intptr = &options->kbd_interactive_authentication;
825 goto parse_flag;
8002af61 826
2717fa0f 827 case sChallengeResponseAuthentication:
828 intptr = &options->challenge_response_authentication;
829 goto parse_flag;
8002af61 830
2717fa0f 831 case sPrintMotd:
832 intptr = &options->print_motd;
833 goto parse_flag;
5260325f 834
2717fa0f 835 case sPrintLastLog:
836 intptr = &options->print_lastlog;
837 goto parse_flag;
5260325f 838
2717fa0f 839 case sX11Forwarding:
840 intptr = &options->x11_forwarding;
841 goto parse_flag;
5260325f 842
2717fa0f 843 case sX11DisplayOffset:
844 intptr = &options->x11_display_offset;
845 goto parse_int;
8efc0c15 846
e6e573bd 847 case sX11UseLocalhost:
848 intptr = &options->x11_use_localhost;
849 goto parse_flag;
850
2717fa0f 851 case sXAuthLocation:
852 charptr = &options->xauth_location;
853 goto parse_filename;
5260325f 854
2717fa0f 855 case sStrictModes:
856 intptr = &options->strict_modes;
857 goto parse_flag;
5260325f 858
fd573618 859 case sTCPKeepAlive:
860 intptr = &options->tcp_keep_alive;
2717fa0f 861 goto parse_flag;
33de75a3 862
2717fa0f 863 case sEmptyPasswd:
864 intptr = &options->permit_empty_passwd;
865 goto parse_flag;
5260325f 866
f00bab84 867 case sPermitUserEnvironment:
868 intptr = &options->permit_user_env;
869 goto parse_flag;
870
2717fa0f 871 case sUseLogin:
872 intptr = &options->use_login;
873 goto parse_flag;
5260325f 874
636f76ca 875 case sCompression:
876 intptr = &options->compression;
07200973 877 arg = strdelim(&cp);
878 if (!arg || *arg == '\0')
879 fatal("%s line %d: missing yes/no/delayed "
880 "argument.", filename, linenum);
881 value = 0; /* silence compiler */
882 if (strcmp(arg, "delayed") == 0)
883 value = COMP_DELAYED;
884 else if (strcmp(arg, "yes") == 0)
885 value = COMP_ZLIB;
886 else if (strcmp(arg, "no") == 0)
887 value = COMP_NONE;
888 else
889 fatal("%s line %d: Bad yes/no/delayed "
890 "argument: %s", filename, linenum, arg);
891 if (*intptr == -1)
892 *intptr = value;
893 break;
636f76ca 894
2717fa0f 895 case sGatewayPorts:
896 intptr = &options->gateway_ports;
3867aa0a 897 arg = strdelim(&cp);
898 if (!arg || *arg == '\0')
899 fatal("%s line %d: missing yes/no/clientspecified "
900 "argument.", filename, linenum);
901 value = 0; /* silence compiler */
902 if (strcmp(arg, "clientspecified") == 0)
903 value = 2;
904 else if (strcmp(arg, "yes") == 0)
905 value = 1;
906 else if (strcmp(arg, "no") == 0)
907 value = 0;
908 else
909 fatal("%s line %d: Bad yes/no/clientspecified "
910 "argument: %s", filename, linenum, arg);
911 if (*intptr == -1)
912 *intptr = value;
913 break;
5260325f 914
c5a7d788 915 case sUseDNS:
916 intptr = &options->use_dns;
2717fa0f 917 goto parse_flag;
5260325f 918
2717fa0f 919 case sLogFacility:
920 intptr = (int *) &options->log_facility;
921 arg = strdelim(&cp);
922 value = log_facility_number(arg);
5eaf8578 923 if (value == SYSLOG_FACILITY_NOT_SET)
2717fa0f 924 fatal("%.200s line %d: unsupported log facility '%s'",
925 filename, linenum, arg ? arg : "<NONE>");
926 if (*intptr == -1)
927 *intptr = (SyslogFacility) value;
928 break;
929
930 case sLogLevel:
931 intptr = (int *) &options->log_level;
932 arg = strdelim(&cp);
933 value = log_level_number(arg);
5eaf8578 934 if (value == SYSLOG_LEVEL_NOT_SET)
2717fa0f 935 fatal("%.200s line %d: unsupported log level '%s'",
936 filename, linenum, arg ? arg : "<NONE>");
937 if (*intptr == -1)
938 *intptr = (LogLevel) value;
939 break;
940
941 case sAllowTcpForwarding:
942 intptr = &options->allow_tcp_forwarding;
943 goto parse_flag;
944
1853d1ef 945 case sUsePrivilegeSeparation:
946 intptr = &use_privsep;
947 goto parse_flag;
948
2717fa0f 949 case sAllowUsers:
950 while ((arg = strdelim(&cp)) && *arg != '\0') {
951 if (options->num_allow_users >= MAX_ALLOW_USERS)
952 fatal("%s line %d: too many allow users.",
953 filename, linenum);
7528d467 954 options->allow_users[options->num_allow_users++] =
955 xstrdup(arg);
2717fa0f 956 }
957 break;
a8be9f80 958
2717fa0f 959 case sDenyUsers:
960 while ((arg = strdelim(&cp)) && *arg != '\0') {
961 if (options->num_deny_users >= MAX_DENY_USERS)
962 fatal( "%s line %d: too many deny users.",
963 filename, linenum);
7528d467 964 options->deny_users[options->num_deny_users++] =
965 xstrdup(arg);
2717fa0f 966 }
967 break;
b2552997 968
2717fa0f 969 case sAllowGroups:
970 while ((arg = strdelim(&cp)) && *arg != '\0') {
971 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
972 fatal("%s line %d: too many allow groups.",
973 filename, linenum);
7528d467 974 options->allow_groups[options->num_allow_groups++] =
975 xstrdup(arg);
2717fa0f 976 }
977 break;
a8be9f80 978
2717fa0f 979 case sDenyGroups:
980 while ((arg = strdelim(&cp)) && *arg != '\0') {
981 if (options->num_deny_groups >= MAX_DENY_GROUPS)
982 fatal("%s line %d: too many deny groups.",
983 filename, linenum);
984 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
985 }
986 break;
38c295d6 987
2717fa0f 988 case sCiphers:
989 arg = strdelim(&cp);
990 if (!arg || *arg == '\0')
991 fatal("%s line %d: Missing argument.", filename, linenum);
992 if (!ciphers_valid(arg))
993 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
994 filename, linenum, arg ? arg : "<NONE>");
995 if (options->ciphers == NULL)
996 options->ciphers = xstrdup(arg);
997 break;
998
999 case sMacs:
1000 arg = strdelim(&cp);
1001 if (!arg || *arg == '\0')
1002 fatal("%s line %d: Missing argument.", filename, linenum);
1003 if (!mac_valid(arg))
1004 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1005 filename, linenum, arg ? arg : "<NONE>");
1006 if (options->macs == NULL)
1007 options->macs = xstrdup(arg);
1008 break;
1009
1010 case sProtocol:
1011 intptr = &options->protocol;
1012 arg = strdelim(&cp);
1013 if (!arg || *arg == '\0')
1014 fatal("%s line %d: Missing argument.", filename, linenum);
1015 value = proto_spec(arg);
1016 if (value == SSH_PROTO_UNKNOWN)
1017 fatal("%s line %d: Bad protocol spec '%s'.",
184eed6a 1018 filename, linenum, arg ? arg : "<NONE>");
2717fa0f 1019 if (*intptr == SSH_PROTO_UNKNOWN)
1020 *intptr = value;
1021 break;
1022
1023 case sSubsystem:
1024 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1025 fatal("%s line %d: too many subsystems defined.",
184eed6a 1026 filename, linenum);
2717fa0f 1027 }
1028 arg = strdelim(&cp);
1029 if (!arg || *arg == '\0')
1030 fatal("%s line %d: Missing subsystem name.",
184eed6a 1031 filename, linenum);
d231781a 1032 if (!*activep) {
1033 arg = strdelim(&cp);
1034 break;
1035 }
2717fa0f 1036 for (i = 0; i < options->num_subsystems; i++)
1037 if (strcmp(arg, options->subsystem_name[i]) == 0)
1038 fatal("%s line %d: Subsystem '%s' already defined.",
184eed6a 1039 filename, linenum, arg);
2717fa0f 1040 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1041 arg = strdelim(&cp);
1042 if (!arg || *arg == '\0')
1043 fatal("%s line %d: Missing subsystem command.",
184eed6a 1044 filename, linenum);
2717fa0f 1045 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
d66ce1a1 1046
1047 /* Collect arguments (separate to executable) */
1048 p = xstrdup(arg);
1049 len = strlen(p) + 1;
1050 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1051 len += 1 + strlen(arg);
1052 p = xrealloc(p, 1, len);
1053 strlcat(p, " ", len);
1054 strlcat(p, arg, len);
1055 }
1056 options->subsystem_args[options->num_subsystems] = p;
2717fa0f 1057 options->num_subsystems++;
1058 break;
1059
1060 case sMaxStartups:
1061 arg = strdelim(&cp);
1062 if (!arg || *arg == '\0')
1063 fatal("%s line %d: Missing MaxStartups spec.",
184eed6a 1064 filename, linenum);
2717fa0f 1065 if ((n = sscanf(arg, "%d:%d:%d",
1066 &options->max_startups_begin,
1067 &options->max_startups_rate,
1068 &options->max_startups)) == 3) {
1069 if (options->max_startups_begin >
1070 options->max_startups ||
1071 options->max_startups_rate > 100 ||
1072 options->max_startups_rate < 1)
c345cf9d 1073 fatal("%s line %d: Illegal MaxStartups spec.",
97de229c 1074 filename, linenum);
2717fa0f 1075 } else if (n != 1)
1076 fatal("%s line %d: Illegal MaxStartups spec.",
1077 filename, linenum);
1078 else
1079 options->max_startups = options->max_startups_begin;
1080 break;
1081
af4bd935 1082 case sMaxAuthTries:
1083 intptr = &options->max_authtries;
1084 goto parse_int;
1085
2717fa0f 1086 case sBanner:
1087 charptr = &options->banner;
1088 goto parse_filename;
1089 /*
1090 * These options can contain %X options expanded at
1091 * connect time, so that you can specify paths like:
1092 *
1093 * AuthorizedKeysFile /etc/ssh_keys/%u
1094 */
1095 case sAuthorizedKeysFile:
1096 case sAuthorizedKeysFile2:
1097 charptr = (opcode == sAuthorizedKeysFile ) ?
1098 &options->authorized_keys_file :
1099 &options->authorized_keys_file2;
1100 goto parse_filename;
1101
1102 case sClientAliveInterval:
1103 intptr = &options->client_alive_interval;
1104 goto parse_time;
1105
1106 case sClientAliveCountMax:
1107 intptr = &options->client_alive_count_max;
1108 goto parse_int;
1109
61a2c1da 1110 case sAcceptEnv:
1111 while ((arg = strdelim(&cp)) && *arg != '\0') {
1112 if (strchr(arg, '=') != NULL)
1113 fatal("%s line %d: Invalid environment name.",
1114 filename, linenum);
1115 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1116 fatal("%s line %d: too many allow env.",
1117 filename, linenum);
d231781a 1118 if (!*activep)
1119 break;
61a2c1da 1120 options->accept_env[options->num_accept_env++] =
1121 xstrdup(arg);
1122 }
1123 break;
1124
d20f3c9e 1125 case sPermitTunnel:
1126 intptr = &options->permit_tun;
a4f24bf8 1127 arg = strdelim(&cp);
1128 if (!arg || *arg == '\0')
1129 fatal("%s line %d: Missing yes/point-to-point/"
1130 "ethernet/no argument.", filename, linenum);
1131 value = 0; /* silence compiler */
1132 if (strcasecmp(arg, "ethernet") == 0)
1133 value = SSH_TUNMODE_ETHERNET;
1134 else if (strcasecmp(arg, "point-to-point") == 0)
1135 value = SSH_TUNMODE_POINTOPOINT;
1136 else if (strcasecmp(arg, "yes") == 0)
1137 value = SSH_TUNMODE_YES;
1138 else if (strcasecmp(arg, "no") == 0)
1139 value = SSH_TUNMODE_NO;
1140 else
1141 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1142 "no argument: %s", filename, linenum, arg);
1143 if (*intptr == -1)
1144 *intptr = value;
1145 break;
d20f3c9e 1146
d231781a 1147 case sMatch:
1148 if (cmdline)
1149 fatal("Match directive not supported as a command-line "
1150 "option");
1151 value = match_cfg_line(&cp, linenum, user, host, address);
1152 if (value < 0)
1153 fatal("%s line %d: Bad Match condition", filename,
1154 linenum);
1155 *activep = value;
1156 break;
1157
2fefbadf 1158 case sPermitOpen:
1159 arg = strdelim(&cp);
1160 if (!arg || *arg == '\0')
1161 fatal("%s line %d: missing PermitOpen specification",
1162 filename, linenum);
1163 if (strcmp(arg, "any") == 0) {
1164 if (*activep)
1165 channel_clear_adm_permitted_opens();
1166 break;
1167 }
1168 p = hpdelim(&arg);
1169 if (p == NULL)
1170 fatal("%s line %d: missing host in PermitOpen",
1171 filename, linenum);
1172 p = cleanhostname(p);
1173 if (arg == NULL || (port = a2port(arg)) == 0)
1174 fatal("%s line %d: bad port number in PermitOpen",
1175 filename, linenum);
1176 if (*activep)
1177 channel_add_adm_permitted_opens(p, port);
1178 break;
1179
e7259e8d 1180 case sForceCommand:
1181 if (cp == NULL)
1182 fatal("%.200s line %d: Missing argument.", filename,
1183 linenum);
1184 len = strspn(cp, WHITESPACE);
1185 if (*activep && options->adm_forced_command == NULL)
1186 options->adm_forced_command = xstrdup(cp + len);
1187 return 0;
1188
2717fa0f 1189 case sDeprecated:
bbe88b6d 1190 logit("%s line %d: Deprecated option %s",
2717fa0f 1191 filename, linenum, arg);
1192 while (arg)
1193 arg = strdelim(&cp);
1194 break;
1195
a2144546 1196 case sUnsupported:
1197 logit("%s line %d: Unsupported option %s",
1198 filename, linenum, arg);
1199 while (arg)
1200 arg = strdelim(&cp);
1201 break;
1202
2717fa0f 1203 default:
1204 fatal("%s line %d: Missing handler for opcode %s (%d)",
1205 filename, linenum, arg, opcode);
1206 }
1207 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1208 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1209 filename, linenum, arg);
1210 return 0;
1211}
089fbbd2 1212
2717fa0f 1213/* Reads the server configuration file. */
5c53a31e 1214
2717fa0f 1215void
b9a549d7 1216load_server_config(const char *filename, Buffer *conf)
2717fa0f 1217{
b9a549d7 1218 char line[1024], *cp;
7528d467 1219 FILE *f;
2717fa0f 1220
b9a549d7 1221 debug2("%s: filename %s", __func__, filename);
1222 if ((f = fopen(filename, "r")) == NULL) {
2717fa0f 1223 perror(filename);
1224 exit(1);
1225 }
b9a549d7 1226 buffer_clear(conf);
2717fa0f 1227 while (fgets(line, sizeof(line), f)) {
b9a549d7 1228 /*
1229 * Trim out comments and strip whitespace
f2107e97 1230 * NB - preserve newlines, they are needed to reproduce
b9a549d7 1231 * line numbers later for error messages
1232 */
1233 if ((cp = strchr(line, '#')) != NULL)
1234 memcpy(cp, "\n", 2);
1235 cp = line + strspn(line, " \t\r");
1236
1237 buffer_append(conf, cp, strlen(cp));
8efc0c15 1238 }
b9a549d7 1239 buffer_append(conf, "\0", 1);
5260325f 1240 fclose(f);
b9a549d7 1241 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1242}
1243
1244void
d231781a 1245parse_server_match_config(ServerOptions *options, const char *user,
1246 const char *host, const char *address)
1247{
1248 ServerOptions mo;
1249
1250 initialize_server_options(&mo);
1251 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1252 copy_set_server_options(options, &mo);
1253}
1254
1255/* Copy any (supported) values that are set */
1256void
1257copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1258{
1259 if (src->allow_tcp_forwarding != -1)
1260 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1261 if (src->gateway_ports != -1)
1262 dst->gateway_ports = src->gateway_ports;
e7259e8d 1263 if (src->adm_forced_command != NULL) {
1264 if (dst->adm_forced_command != NULL)
1265 xfree(dst->adm_forced_command);
1266 dst->adm_forced_command = src->adm_forced_command;
1267 }
691712e0 1268 if (src->x11_display_offset != -1)
1269 dst->x11_display_offset = src->x11_display_offset;
1270 if (src->x11_forwarding != -1)
1271 dst->x11_forwarding = src->x11_forwarding;
1272 if (src->x11_use_localhost != -1)
1273 dst->x11_use_localhost = src->x11_use_localhost;
d231781a 1274}
1275
1276void
1277parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1278 const char *user, const char *host, const char *address)
b9a549d7 1279{
d231781a 1280 int active, linenum, bad_options = 0;
16acb158 1281 char *cp, *obuf, *cbuf;
b9a549d7 1282
1283 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1284
16acb158 1285 obuf = cbuf = xstrdup(buffer_ptr(conf));
d231781a 1286 active = user ? 0 : 1;
861cc543 1287 linenum = 1;
f8cc7664 1288 while ((cp = strsep(&cbuf, "\n")) != NULL) {
b9a549d7 1289 if (process_server_config_line(options, cp, filename,
d231781a 1290 linenum++, &active, user, host, address) != 0)
b9a549d7 1291 bad_options++;
1292 }
16acb158 1293 xfree(obuf);
b7c70970 1294 if (bad_options > 0)
1295 fatal("%s: terminating, %d bad configuration options",
1296 filename, bad_options);
8efc0c15 1297}
This page took 0.48321 seconds and 5 git commands to generate.