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