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