]> andersk Git - openssh.git/blame - servconf.c
- jmc@cvs.openbsd.org 2005/12/08 15:06:29
[openssh.git] / servconf.c
CommitLineData
8efc0c15 1/*
5260325f 2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3 * All rights reserved
6ae2364d 4 *
bcbf86ec 5 * As far as I am concerned, the code I have written for this software
6 * can be used freely for any purpose. Any derived versions of this
7 * software must be clearly marked as such, and if the derived work is
8 * incompatible with the protocol description in the RFC file, it must be
9 * called by a name other than "ssh" or "Secure Shell".
5260325f 10 */
8efc0c15 11
12#include "includes.h"
d20f3c9e 13RCSID("$OpenBSD: servconf.c,v 1.145 2005/12/06 22:38:27 reyk Exp $");
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)
234 options->permit_tun = 0;
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;
5260325f 449
2717fa0f 450 cp = line;
451 arg = strdelim(&cp);
452 /* Ignore leading whitespace */
453 if (*arg == '\0')
704b1659 454 arg = strdelim(&cp);
2717fa0f 455 if (!arg || !*arg || *arg == '#')
456 return 0;
457 intptr = NULL;
458 charptr = NULL;
459 opcode = parse_token(arg, filename, linenum);
460 switch (opcode) {
461 /* Portable-specific options */
7fceb20d 462 case sUsePAM:
463 intptr = &options->use_pam;
2717fa0f 464 goto parse_flag;
48e671d5 465
2717fa0f 466 /* Standard Options */
467 case sBadOption:
468 return -1;
469 case sPort:
470 /* ignore ports from configfile if cmdline specifies ports */
471 if (options->ports_from_cmdline)
472 return 0;
473 if (options->listen_addrs != NULL)
474 fatal("%s line %d: ports must be specified before "
3a454b6a 475 "ListenAddress.", filename, linenum);
2717fa0f 476 if (options->num_ports >= MAX_PORTS)
477 fatal("%s line %d: too many ports.",
478 filename, linenum);
479 arg = strdelim(&cp);
480 if (!arg || *arg == '\0')
481 fatal("%s line %d: missing port number.",
482 filename, linenum);
483 options->ports[options->num_ports++] = a2port(arg);
484 if (options->ports[options->num_ports-1] == 0)
485 fatal("%s line %d: Badly formatted port number.",
486 filename, linenum);
487 break;
488
489 case sServerKeyBits:
490 intptr = &options->server_key_bits;
5260325f 491parse_int:
2717fa0f 492 arg = strdelim(&cp);
493 if (!arg || *arg == '\0')
494 fatal("%s line %d: missing integer value.",
495 filename, linenum);
496 value = atoi(arg);
497 if (*intptr == -1)
498 *intptr = value;
499 break;
500
501 case sLoginGraceTime:
502 intptr = &options->login_grace_time;
e2b1fb42 503parse_time:
2717fa0f 504 arg = strdelim(&cp);
505 if (!arg || *arg == '\0')
506 fatal("%s line %d: missing time value.",
507 filename, linenum);
508 if ((value = convtime(arg)) == -1)
509 fatal("%s line %d: invalid time value.",
510 filename, linenum);
511 if (*intptr == -1)
512 *intptr = value;
513 break;
514
515 case sKeyRegenerationTime:
516 intptr = &options->key_regeneration_time;
517 goto parse_time;
518
519 case sListenAddress:
520 arg = strdelim(&cp);
3867aa0a 521 if (arg == NULL || *arg == '\0')
522 fatal("%s line %d: missing address",
2717fa0f 523 filename, linenum);
91135a0e 524 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
525 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
526 && strchr(p+1, ':') != NULL) {
527 add_listen_addr(options, arg, 0);
528 break;
529 }
3867aa0a 530 p = hpdelim(&arg);
531 if (p == NULL)
532 fatal("%s line %d: bad address:port usage",
2717fa0f 533 filename, linenum);
3867aa0a 534 p = cleanhostname(p);
535 if (arg == NULL)
536 port = 0;
537 else if ((port = a2port(arg)) == 0)
538 fatal("%s line %d: bad port number", filename, linenum);
539
540 add_listen_addr(options, p, port);
541
2717fa0f 542 break;
543
31b41ceb 544 case sAddressFamily:
545 arg = strdelim(&cp);
38634ff6 546 if (!arg || *arg == '\0')
547 fatal("%s line %d: missing address family.",
548 filename, linenum);
31b41ceb 549 intptr = &options->address_family;
550 if (options->listen_addrs != NULL)
551 fatal("%s line %d: address family must be specified before "
552 "ListenAddress.", filename, linenum);
553 if (strcasecmp(arg, "inet") == 0)
554 value = AF_INET;
555 else if (strcasecmp(arg, "inet6") == 0)
556 value = AF_INET6;
557 else if (strcasecmp(arg, "any") == 0)
558 value = AF_UNSPEC;
559 else
560 fatal("%s line %d: unsupported address family \"%s\".",
561 filename, linenum, arg);
562 if (*intptr == -1)
563 *intptr = value;
564 break;
565
2717fa0f 566 case sHostKeyFile:
567 intptr = &options->num_host_key_files;
568 if (*intptr >= MAX_HOSTKEYS)
569 fatal("%s line %d: too many host keys specified (max %d).",
570 filename, linenum, MAX_HOSTKEYS);
571 charptr = &options->host_key_files[*intptr];
fa649821 572parse_filename:
2717fa0f 573 arg = strdelim(&cp);
574 if (!arg || *arg == '\0')
575 fatal("%s line %d: missing file name.",
576 filename, linenum);
577 if (*charptr == NULL) {
578 *charptr = tilde_expand_filename(arg, getuid());
579 /* increase optional counter */
580 if (intptr != NULL)
581 *intptr = *intptr + 1;
582 }
583 break;
0fbe8c74 584
2717fa0f 585 case sPidFile:
586 charptr = &options->pid_file;
587 goto parse_filename;
5260325f 588
2717fa0f 589 case sPermitRootLogin:
590 intptr = &options->permit_root_login;
591 arg = strdelim(&cp);
592 if (!arg || *arg == '\0')
593 fatal("%s line %d: missing yes/"
594 "without-password/forced-commands-only/no "
595 "argument.", filename, linenum);
596 value = 0; /* silence compiler */
597 if (strcmp(arg, "without-password") == 0)
598 value = PERMIT_NO_PASSWD;
599 else if (strcmp(arg, "forced-commands-only") == 0)
600 value = PERMIT_FORCED_ONLY;
601 else if (strcmp(arg, "yes") == 0)
602 value = PERMIT_YES;
603 else if (strcmp(arg, "no") == 0)
604 value = PERMIT_NO;
605 else
606 fatal("%s line %d: Bad yes/"
607 "without-password/forced-commands-only/no "
608 "argument: %s", filename, linenum, arg);
609 if (*intptr == -1)
610 *intptr = value;
611 break;
612
613 case sIgnoreRhosts:
614 intptr = &options->ignore_rhosts;
5260325f 615parse_flag:
2717fa0f 616 arg = strdelim(&cp);
617 if (!arg || *arg == '\0')
618 fatal("%s line %d: missing yes/no argument.",
619 filename, linenum);
620 value = 0; /* silence compiler */
621 if (strcmp(arg, "yes") == 0)
622 value = 1;
623 else if (strcmp(arg, "no") == 0)
624 value = 0;
625 else
626 fatal("%s line %d: Bad yes/no argument: %s",
627 filename, linenum, arg);
628 if (*intptr == -1)
629 *intptr = value;
630 break;
631
632 case sIgnoreUserKnownHosts:
633 intptr = &options->ignore_user_known_hosts;
634 goto parse_flag;
635
2717fa0f 636 case sRhostsRSAAuthentication:
637 intptr = &options->rhosts_rsa_authentication;
638 goto parse_flag;
639
640 case sHostbasedAuthentication:
641 intptr = &options->hostbased_authentication;
642 goto parse_flag;
643
644 case sHostbasedUsesNameFromPacketOnly:
645 intptr = &options->hostbased_uses_name_from_packet_only;
646 goto parse_flag;
647
648 case sRSAAuthentication:
649 intptr = &options->rsa_authentication;
650 goto parse_flag;
651
652 case sPubkeyAuthentication:
653 intptr = &options->pubkey_authentication;
654 goto parse_flag;
d0ec7f42 655
2717fa0f 656 case sKerberosAuthentication:
657 intptr = &options->kerberos_authentication;
658 goto parse_flag;
5260325f 659
2717fa0f 660 case sKerberosOrLocalPasswd:
661 intptr = &options->kerberos_or_local_passwd;
662 goto parse_flag;
5260325f 663
2717fa0f 664 case sKerberosTicketCleanup:
665 intptr = &options->kerberos_ticket_cleanup;
666 goto parse_flag;
d0ec7f42 667
a1e30b47 668 case sKerberosGetAFSToken:
669 intptr = &options->kerberos_get_afs_token;
670 goto parse_flag;
671
7364bd04 672 case sGssAuthentication:
673 intptr = &options->gss_authentication;
674 goto parse_flag;
675
676 case sGssCleanupCreds:
677 intptr = &options->gss_cleanup_creds;
678 goto parse_flag;
679
2717fa0f 680 case sPasswordAuthentication:
681 intptr = &options->password_authentication;
682 goto parse_flag;
5260325f 683
2717fa0f 684 case sKbdInteractiveAuthentication:
685 intptr = &options->kbd_interactive_authentication;
686 goto parse_flag;
8002af61 687
2717fa0f 688 case sChallengeResponseAuthentication:
689 intptr = &options->challenge_response_authentication;
690 goto parse_flag;
8002af61 691
2717fa0f 692 case sPrintMotd:
693 intptr = &options->print_motd;
694 goto parse_flag;
5260325f 695
2717fa0f 696 case sPrintLastLog:
697 intptr = &options->print_lastlog;
698 goto parse_flag;
5260325f 699
2717fa0f 700 case sX11Forwarding:
701 intptr = &options->x11_forwarding;
702 goto parse_flag;
5260325f 703
2717fa0f 704 case sX11DisplayOffset:
705 intptr = &options->x11_display_offset;
706 goto parse_int;
8efc0c15 707
e6e573bd 708 case sX11UseLocalhost:
709 intptr = &options->x11_use_localhost;
710 goto parse_flag;
711
2717fa0f 712 case sXAuthLocation:
713 charptr = &options->xauth_location;
714 goto parse_filename;
5260325f 715
2717fa0f 716 case sStrictModes:
717 intptr = &options->strict_modes;
718 goto parse_flag;
5260325f 719
fd573618 720 case sTCPKeepAlive:
721 intptr = &options->tcp_keep_alive;
2717fa0f 722 goto parse_flag;
33de75a3 723
2717fa0f 724 case sEmptyPasswd:
725 intptr = &options->permit_empty_passwd;
726 goto parse_flag;
5260325f 727
f00bab84 728 case sPermitUserEnvironment:
729 intptr = &options->permit_user_env;
730 goto parse_flag;
731
2717fa0f 732 case sUseLogin:
733 intptr = &options->use_login;
734 goto parse_flag;
5260325f 735
636f76ca 736 case sCompression:
737 intptr = &options->compression;
07200973 738 arg = strdelim(&cp);
739 if (!arg || *arg == '\0')
740 fatal("%s line %d: missing yes/no/delayed "
741 "argument.", filename, linenum);
742 value = 0; /* silence compiler */
743 if (strcmp(arg, "delayed") == 0)
744 value = COMP_DELAYED;
745 else if (strcmp(arg, "yes") == 0)
746 value = COMP_ZLIB;
747 else if (strcmp(arg, "no") == 0)
748 value = COMP_NONE;
749 else
750 fatal("%s line %d: Bad yes/no/delayed "
751 "argument: %s", filename, linenum, arg);
752 if (*intptr == -1)
753 *intptr = value;
754 break;
636f76ca 755
2717fa0f 756 case sGatewayPorts:
757 intptr = &options->gateway_ports;
3867aa0a 758 arg = strdelim(&cp);
759 if (!arg || *arg == '\0')
760 fatal("%s line %d: missing yes/no/clientspecified "
761 "argument.", filename, linenum);
762 value = 0; /* silence compiler */
763 if (strcmp(arg, "clientspecified") == 0)
764 value = 2;
765 else if (strcmp(arg, "yes") == 0)
766 value = 1;
767 else if (strcmp(arg, "no") == 0)
768 value = 0;
769 else
770 fatal("%s line %d: Bad yes/no/clientspecified "
771 "argument: %s", filename, linenum, arg);
772 if (*intptr == -1)
773 *intptr = value;
774 break;
5260325f 775
c5a7d788 776 case sUseDNS:
777 intptr = &options->use_dns;
2717fa0f 778 goto parse_flag;
5260325f 779
2717fa0f 780 case sLogFacility:
781 intptr = (int *) &options->log_facility;
782 arg = strdelim(&cp);
783 value = log_facility_number(arg);
5eaf8578 784 if (value == SYSLOG_FACILITY_NOT_SET)
2717fa0f 785 fatal("%.200s line %d: unsupported log facility '%s'",
786 filename, linenum, arg ? arg : "<NONE>");
787 if (*intptr == -1)
788 *intptr = (SyslogFacility) value;
789 break;
790
791 case sLogLevel:
792 intptr = (int *) &options->log_level;
793 arg = strdelim(&cp);
794 value = log_level_number(arg);
5eaf8578 795 if (value == SYSLOG_LEVEL_NOT_SET)
2717fa0f 796 fatal("%.200s line %d: unsupported log level '%s'",
797 filename, linenum, arg ? arg : "<NONE>");
798 if (*intptr == -1)
799 *intptr = (LogLevel) value;
800 break;
801
802 case sAllowTcpForwarding:
803 intptr = &options->allow_tcp_forwarding;
804 goto parse_flag;
805
1853d1ef 806 case sUsePrivilegeSeparation:
807 intptr = &use_privsep;
808 goto parse_flag;
809
2717fa0f 810 case sAllowUsers:
811 while ((arg = strdelim(&cp)) && *arg != '\0') {
812 if (options->num_allow_users >= MAX_ALLOW_USERS)
813 fatal("%s line %d: too many allow users.",
814 filename, linenum);
7528d467 815 options->allow_users[options->num_allow_users++] =
816 xstrdup(arg);
2717fa0f 817 }
818 break;
a8be9f80 819
2717fa0f 820 case sDenyUsers:
821 while ((arg = strdelim(&cp)) && *arg != '\0') {
822 if (options->num_deny_users >= MAX_DENY_USERS)
823 fatal( "%s line %d: too many deny users.",
824 filename, linenum);
7528d467 825 options->deny_users[options->num_deny_users++] =
826 xstrdup(arg);
2717fa0f 827 }
828 break;
b2552997 829
2717fa0f 830 case sAllowGroups:
831 while ((arg = strdelim(&cp)) && *arg != '\0') {
832 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
833 fatal("%s line %d: too many allow groups.",
834 filename, linenum);
7528d467 835 options->allow_groups[options->num_allow_groups++] =
836 xstrdup(arg);
2717fa0f 837 }
838 break;
a8be9f80 839
2717fa0f 840 case sDenyGroups:
841 while ((arg = strdelim(&cp)) && *arg != '\0') {
842 if (options->num_deny_groups >= MAX_DENY_GROUPS)
843 fatal("%s line %d: too many deny groups.",
844 filename, linenum);
845 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
846 }
847 break;
38c295d6 848
2717fa0f 849 case sCiphers:
850 arg = strdelim(&cp);
851 if (!arg || *arg == '\0')
852 fatal("%s line %d: Missing argument.", filename, linenum);
853 if (!ciphers_valid(arg))
854 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
855 filename, linenum, arg ? arg : "<NONE>");
856 if (options->ciphers == NULL)
857 options->ciphers = xstrdup(arg);
858 break;
859
860 case sMacs:
861 arg = strdelim(&cp);
862 if (!arg || *arg == '\0')
863 fatal("%s line %d: Missing argument.", filename, linenum);
864 if (!mac_valid(arg))
865 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
866 filename, linenum, arg ? arg : "<NONE>");
867 if (options->macs == NULL)
868 options->macs = xstrdup(arg);
869 break;
870
871 case sProtocol:
872 intptr = &options->protocol;
873 arg = strdelim(&cp);
874 if (!arg || *arg == '\0')
875 fatal("%s line %d: Missing argument.", filename, linenum);
876 value = proto_spec(arg);
877 if (value == SSH_PROTO_UNKNOWN)
878 fatal("%s line %d: Bad protocol spec '%s'.",
184eed6a 879 filename, linenum, arg ? arg : "<NONE>");
2717fa0f 880 if (*intptr == SSH_PROTO_UNKNOWN)
881 *intptr = value;
882 break;
883
884 case sSubsystem:
885 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
886 fatal("%s line %d: too many subsystems defined.",
184eed6a 887 filename, linenum);
2717fa0f 888 }
889 arg = strdelim(&cp);
890 if (!arg || *arg == '\0')
891 fatal("%s line %d: Missing subsystem name.",
184eed6a 892 filename, linenum);
2717fa0f 893 for (i = 0; i < options->num_subsystems; i++)
894 if (strcmp(arg, options->subsystem_name[i]) == 0)
895 fatal("%s line %d: Subsystem '%s' already defined.",
184eed6a 896 filename, linenum, arg);
2717fa0f 897 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
898 arg = strdelim(&cp);
899 if (!arg || *arg == '\0')
900 fatal("%s line %d: Missing subsystem command.",
184eed6a 901 filename, linenum);
2717fa0f 902 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
903 options->num_subsystems++;
904 break;
905
906 case sMaxStartups:
907 arg = strdelim(&cp);
908 if (!arg || *arg == '\0')
909 fatal("%s line %d: Missing MaxStartups spec.",
184eed6a 910 filename, linenum);
2717fa0f 911 if ((n = sscanf(arg, "%d:%d:%d",
912 &options->max_startups_begin,
913 &options->max_startups_rate,
914 &options->max_startups)) == 3) {
915 if (options->max_startups_begin >
916 options->max_startups ||
917 options->max_startups_rate > 100 ||
918 options->max_startups_rate < 1)
c345cf9d 919 fatal("%s line %d: Illegal MaxStartups spec.",
97de229c 920 filename, linenum);
2717fa0f 921 } else if (n != 1)
922 fatal("%s line %d: Illegal MaxStartups spec.",
923 filename, linenum);
924 else
925 options->max_startups = options->max_startups_begin;
926 break;
927
af4bd935 928 case sMaxAuthTries:
929 intptr = &options->max_authtries;
930 goto parse_int;
931
2717fa0f 932 case sBanner:
933 charptr = &options->banner;
934 goto parse_filename;
935 /*
936 * These options can contain %X options expanded at
937 * connect time, so that you can specify paths like:
938 *
939 * AuthorizedKeysFile /etc/ssh_keys/%u
940 */
941 case sAuthorizedKeysFile:
942 case sAuthorizedKeysFile2:
943 charptr = (opcode == sAuthorizedKeysFile ) ?
944 &options->authorized_keys_file :
945 &options->authorized_keys_file2;
946 goto parse_filename;
947
948 case sClientAliveInterval:
949 intptr = &options->client_alive_interval;
950 goto parse_time;
951
952 case sClientAliveCountMax:
953 intptr = &options->client_alive_count_max;
954 goto parse_int;
955
61a2c1da 956 case sAcceptEnv:
957 while ((arg = strdelim(&cp)) && *arg != '\0') {
958 if (strchr(arg, '=') != NULL)
959 fatal("%s line %d: Invalid environment name.",
960 filename, linenum);
961 if (options->num_accept_env >= MAX_ACCEPT_ENV)
962 fatal("%s line %d: too many allow env.",
963 filename, linenum);
964 options->accept_env[options->num_accept_env++] =
965 xstrdup(arg);
966 }
967 break;
968
d20f3c9e 969 case sPermitTunnel:
970 intptr = &options->permit_tun;
971 goto parse_flag;
972
2717fa0f 973 case sDeprecated:
bbe88b6d 974 logit("%s line %d: Deprecated option %s",
2717fa0f 975 filename, linenum, arg);
976 while (arg)
977 arg = strdelim(&cp);
978 break;
979
a2144546 980 case sUnsupported:
981 logit("%s line %d: Unsupported option %s",
982 filename, linenum, arg);
983 while (arg)
984 arg = strdelim(&cp);
985 break;
986
2717fa0f 987 default:
988 fatal("%s line %d: Missing handler for opcode %s (%d)",
989 filename, linenum, arg, opcode);
990 }
991 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
992 fatal("%s line %d: garbage at end of line; \"%.200s\".",
993 filename, linenum, arg);
994 return 0;
995}
089fbbd2 996
2717fa0f 997/* Reads the server configuration file. */
5c53a31e 998
2717fa0f 999void
b9a549d7 1000load_server_config(const char *filename, Buffer *conf)
2717fa0f 1001{
b9a549d7 1002 char line[1024], *cp;
7528d467 1003 FILE *f;
2717fa0f 1004
b9a549d7 1005 debug2("%s: filename %s", __func__, filename);
1006 if ((f = fopen(filename, "r")) == NULL) {
2717fa0f 1007 perror(filename);
1008 exit(1);
1009 }
b9a549d7 1010 buffer_clear(conf);
2717fa0f 1011 while (fgets(line, sizeof(line), f)) {
b9a549d7 1012 /*
1013 * Trim out comments and strip whitespace
f2107e97 1014 * NB - preserve newlines, they are needed to reproduce
b9a549d7 1015 * line numbers later for error messages
1016 */
1017 if ((cp = strchr(line, '#')) != NULL)
1018 memcpy(cp, "\n", 2);
1019 cp = line + strspn(line, " \t\r");
1020
1021 buffer_append(conf, cp, strlen(cp));
8efc0c15 1022 }
b9a549d7 1023 buffer_append(conf, "\0", 1);
5260325f 1024 fclose(f);
b9a549d7 1025 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1026}
1027
1028void
1029parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1030{
1031 int linenum, bad_options = 0;
16acb158 1032 char *cp, *obuf, *cbuf;
b9a549d7 1033
1034 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1035
16acb158 1036 obuf = cbuf = xstrdup(buffer_ptr(conf));
861cc543 1037 linenum = 1;
f8cc7664 1038 while ((cp = strsep(&cbuf, "\n")) != NULL) {
b9a549d7 1039 if (process_server_config_line(options, cp, filename,
1040 linenum++) != 0)
1041 bad_options++;
1042 }
16acb158 1043 xfree(obuf);
b7c70970 1044 if (bad_options > 0)
1045 fatal("%s: terminating, %d bad configuration options",
1046 filename, bad_options);
8efc0c15 1047}
This page took 0.49347 seconds and 5 git commands to generate.