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