- (djm) OpenBSD CVS Sync
[openssh-git.git] / servconf.c
blobddb34f9b92fb3855d8e0c47115316499444216e8
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.141 2005/05/16 15:30:51 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 = 1;
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 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, i, n;
442 ServerOpCodes opcode;
443 u_short port;
445 cp = line;
446 arg = strdelim(&cp);
447 /* Ignore leading whitespace */
448 if (*arg == '\0')
449 arg = strdelim(&cp);
450 if (!arg || !*arg || *arg == '#')
451 return 0;
452 intptr = NULL;
453 charptr = NULL;
454 opcode = parse_token(arg, filename, linenum);
455 switch (opcode) {
456 /* Portable-specific options */
457 case sUsePAM:
458 intptr = &options->use_pam;
459 goto parse_flag;
461 /* Standard Options */
462 case sBadOption:
463 return -1;
464 case sPort:
465 /* ignore ports from configfile if cmdline specifies ports */
466 if (options->ports_from_cmdline)
467 return 0;
468 if (options->listen_addrs != NULL)
469 fatal("%s line %d: ports must be specified before "
470 "ListenAddress.", filename, linenum);
471 if (options->num_ports >= MAX_PORTS)
472 fatal("%s line %d: too many ports.",
473 filename, linenum);
474 arg = strdelim(&cp);
475 if (!arg || *arg == '\0')
476 fatal("%s line %d: missing port number.",
477 filename, linenum);
478 options->ports[options->num_ports++] = a2port(arg);
479 if (options->ports[options->num_ports-1] == 0)
480 fatal("%s line %d: Badly formatted port number.",
481 filename, linenum);
482 break;
484 case sServerKeyBits:
485 intptr = &options->server_key_bits;
486 parse_int:
487 arg = strdelim(&cp);
488 if (!arg || *arg == '\0')
489 fatal("%s line %d: missing integer value.",
490 filename, linenum);
491 value = atoi(arg);
492 if (*intptr == -1)
493 *intptr = value;
494 break;
496 case sLoginGraceTime:
497 intptr = &options->login_grace_time;
498 parse_time:
499 arg = strdelim(&cp);
500 if (!arg || *arg == '\0')
501 fatal("%s line %d: missing time value.",
502 filename, linenum);
503 if ((value = convtime(arg)) == -1)
504 fatal("%s line %d: invalid time value.",
505 filename, linenum);
506 if (*intptr == -1)
507 *intptr = value;
508 break;
510 case sKeyRegenerationTime:
511 intptr = &options->key_regeneration_time;
512 goto parse_time;
514 case sListenAddress:
515 arg = strdelim(&cp);
516 if (arg == NULL || *arg == '\0')
517 fatal("%s line %d: missing address",
518 filename, linenum);
519 p = hpdelim(&arg);
520 if (p == NULL)
521 fatal("%s line %d: bad address:port usage",
522 filename, linenum);
523 p = cleanhostname(p);
524 if (arg == NULL)
525 port = 0;
526 else if ((port = a2port(arg)) == 0)
527 fatal("%s line %d: bad port number", filename, linenum);
529 add_listen_addr(options, p, port);
531 break;
533 case sAddressFamily:
534 arg = strdelim(&cp);
535 if (!arg || *arg == '\0')
536 fatal("%s line %d: missing address family.",
537 filename, linenum);
538 intptr = &options->address_family;
539 if (options->listen_addrs != NULL)
540 fatal("%s line %d: address family must be specified before "
541 "ListenAddress.", filename, linenum);
542 if (strcasecmp(arg, "inet") == 0)
543 value = AF_INET;
544 else if (strcasecmp(arg, "inet6") == 0)
545 value = AF_INET6;
546 else if (strcasecmp(arg, "any") == 0)
547 value = AF_UNSPEC;
548 else
549 fatal("%s line %d: unsupported address family \"%s\".",
550 filename, linenum, arg);
551 if (*intptr == -1)
552 *intptr = value;
553 break;
555 case sHostKeyFile:
556 intptr = &options->num_host_key_files;
557 if (*intptr >= MAX_HOSTKEYS)
558 fatal("%s line %d: too many host keys specified (max %d).",
559 filename, linenum, MAX_HOSTKEYS);
560 charptr = &options->host_key_files[*intptr];
561 parse_filename:
562 arg = strdelim(&cp);
563 if (!arg || *arg == '\0')
564 fatal("%s line %d: missing file name.",
565 filename, linenum);
566 if (*charptr == NULL) {
567 *charptr = tilde_expand_filename(arg, getuid());
568 /* increase optional counter */
569 if (intptr != NULL)
570 *intptr = *intptr + 1;
572 break;
574 case sPidFile:
575 charptr = &options->pid_file;
576 goto parse_filename;
578 case sPermitRootLogin:
579 intptr = &options->permit_root_login;
580 arg = strdelim(&cp);
581 if (!arg || *arg == '\0')
582 fatal("%s line %d: missing yes/"
583 "without-password/forced-commands-only/no "
584 "argument.", filename, linenum);
585 value = 0; /* silence compiler */
586 if (strcmp(arg, "without-password") == 0)
587 value = PERMIT_NO_PASSWD;
588 else if (strcmp(arg, "forced-commands-only") == 0)
589 value = PERMIT_FORCED_ONLY;
590 else if (strcmp(arg, "yes") == 0)
591 value = PERMIT_YES;
592 else if (strcmp(arg, "no") == 0)
593 value = PERMIT_NO;
594 else
595 fatal("%s line %d: Bad yes/"
596 "without-password/forced-commands-only/no "
597 "argument: %s", filename, linenum, arg);
598 if (*intptr == -1)
599 *intptr = value;
600 break;
602 case sIgnoreRhosts:
603 intptr = &options->ignore_rhosts;
604 parse_flag:
605 arg = strdelim(&cp);
606 if (!arg || *arg == '\0')
607 fatal("%s line %d: missing yes/no argument.",
608 filename, linenum);
609 value = 0; /* silence compiler */
610 if (strcmp(arg, "yes") == 0)
611 value = 1;
612 else if (strcmp(arg, "no") == 0)
613 value = 0;
614 else
615 fatal("%s line %d: Bad yes/no argument: %s",
616 filename, linenum, arg);
617 if (*intptr == -1)
618 *intptr = value;
619 break;
621 case sIgnoreUserKnownHosts:
622 intptr = &options->ignore_user_known_hosts;
623 goto parse_flag;
625 case sRhostsRSAAuthentication:
626 intptr = &options->rhosts_rsa_authentication;
627 goto parse_flag;
629 case sHostbasedAuthentication:
630 intptr = &options->hostbased_authentication;
631 goto parse_flag;
633 case sHostbasedUsesNameFromPacketOnly:
634 intptr = &options->hostbased_uses_name_from_packet_only;
635 goto parse_flag;
637 case sRSAAuthentication:
638 intptr = &options->rsa_authentication;
639 goto parse_flag;
641 case sPubkeyAuthentication:
642 intptr = &options->pubkey_authentication;
643 goto parse_flag;
645 case sKerberosAuthentication:
646 intptr = &options->kerberos_authentication;
647 goto parse_flag;
649 case sKerberosOrLocalPasswd:
650 intptr = &options->kerberos_or_local_passwd;
651 goto parse_flag;
653 case sKerberosTicketCleanup:
654 intptr = &options->kerberos_ticket_cleanup;
655 goto parse_flag;
657 case sKerberosGetAFSToken:
658 intptr = &options->kerberos_get_afs_token;
659 goto parse_flag;
661 case sGssAuthentication:
662 intptr = &options->gss_authentication;
663 goto parse_flag;
665 case sGssCleanupCreds:
666 intptr = &options->gss_cleanup_creds;
667 goto parse_flag;
669 case sPasswordAuthentication:
670 intptr = &options->password_authentication;
671 goto parse_flag;
673 case sKbdInteractiveAuthentication:
674 intptr = &options->kbd_interactive_authentication;
675 goto parse_flag;
677 case sChallengeResponseAuthentication:
678 intptr = &options->challenge_response_authentication;
679 goto parse_flag;
681 case sPrintMotd:
682 intptr = &options->print_motd;
683 goto parse_flag;
685 case sPrintLastLog:
686 intptr = &options->print_lastlog;
687 goto parse_flag;
689 case sX11Forwarding:
690 intptr = &options->x11_forwarding;
691 goto parse_flag;
693 case sX11DisplayOffset:
694 intptr = &options->x11_display_offset;
695 goto parse_int;
697 case sX11UseLocalhost:
698 intptr = &options->x11_use_localhost;
699 goto parse_flag;
701 case sXAuthLocation:
702 charptr = &options->xauth_location;
703 goto parse_filename;
705 case sStrictModes:
706 intptr = &options->strict_modes;
707 goto parse_flag;
709 case sTCPKeepAlive:
710 intptr = &options->tcp_keep_alive;
711 goto parse_flag;
713 case sEmptyPasswd:
714 intptr = &options->permit_empty_passwd;
715 goto parse_flag;
717 case sPermitUserEnvironment:
718 intptr = &options->permit_user_env;
719 goto parse_flag;
721 case sUseLogin:
722 intptr = &options->use_login;
723 goto parse_flag;
725 case sCompression:
726 intptr = &options->compression;
727 goto parse_flag;
729 case sGatewayPorts:
730 intptr = &options->gateway_ports;
731 arg = strdelim(&cp);
732 if (!arg || *arg == '\0')
733 fatal("%s line %d: missing yes/no/clientspecified "
734 "argument.", filename, linenum);
735 value = 0; /* silence compiler */
736 if (strcmp(arg, "clientspecified") == 0)
737 value = 2;
738 else if (strcmp(arg, "yes") == 0)
739 value = 1;
740 else if (strcmp(arg, "no") == 0)
741 value = 0;
742 else
743 fatal("%s line %d: Bad yes/no/clientspecified "
744 "argument: %s", filename, linenum, arg);
745 if (*intptr == -1)
746 *intptr = value;
747 break;
749 case sUseDNS:
750 intptr = &options->use_dns;
751 goto parse_flag;
753 case sLogFacility:
754 intptr = (int *) &options->log_facility;
755 arg = strdelim(&cp);
756 value = log_facility_number(arg);
757 if (value == SYSLOG_FACILITY_NOT_SET)
758 fatal("%.200s line %d: unsupported log facility '%s'",
759 filename, linenum, arg ? arg : "<NONE>");
760 if (*intptr == -1)
761 *intptr = (SyslogFacility) value;
762 break;
764 case sLogLevel:
765 intptr = (int *) &options->log_level;
766 arg = strdelim(&cp);
767 value = log_level_number(arg);
768 if (value == SYSLOG_LEVEL_NOT_SET)
769 fatal("%.200s line %d: unsupported log level '%s'",
770 filename, linenum, arg ? arg : "<NONE>");
771 if (*intptr == -1)
772 *intptr = (LogLevel) value;
773 break;
775 case sAllowTcpForwarding:
776 intptr = &options->allow_tcp_forwarding;
777 goto parse_flag;
779 case sUsePrivilegeSeparation:
780 intptr = &use_privsep;
781 goto parse_flag;
783 case sAllowUsers:
784 while ((arg = strdelim(&cp)) && *arg != '\0') {
785 if (options->num_allow_users >= MAX_ALLOW_USERS)
786 fatal("%s line %d: too many allow users.",
787 filename, linenum);
788 options->allow_users[options->num_allow_users++] =
789 xstrdup(arg);
791 break;
793 case sDenyUsers:
794 while ((arg = strdelim(&cp)) && *arg != '\0') {
795 if (options->num_deny_users >= MAX_DENY_USERS)
796 fatal( "%s line %d: too many deny users.",
797 filename, linenum);
798 options->deny_users[options->num_deny_users++] =
799 xstrdup(arg);
801 break;
803 case sAllowGroups:
804 while ((arg = strdelim(&cp)) && *arg != '\0') {
805 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
806 fatal("%s line %d: too many allow groups.",
807 filename, linenum);
808 options->allow_groups[options->num_allow_groups++] =
809 xstrdup(arg);
811 break;
813 case sDenyGroups:
814 while ((arg = strdelim(&cp)) && *arg != '\0') {
815 if (options->num_deny_groups >= MAX_DENY_GROUPS)
816 fatal("%s line %d: too many deny groups.",
817 filename, linenum);
818 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
820 break;
822 case sCiphers:
823 arg = strdelim(&cp);
824 if (!arg || *arg == '\0')
825 fatal("%s line %d: Missing argument.", filename, linenum);
826 if (!ciphers_valid(arg))
827 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
828 filename, linenum, arg ? arg : "<NONE>");
829 if (options->ciphers == NULL)
830 options->ciphers = xstrdup(arg);
831 break;
833 case sMacs:
834 arg = strdelim(&cp);
835 if (!arg || *arg == '\0')
836 fatal("%s line %d: Missing argument.", filename, linenum);
837 if (!mac_valid(arg))
838 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
839 filename, linenum, arg ? arg : "<NONE>");
840 if (options->macs == NULL)
841 options->macs = xstrdup(arg);
842 break;
844 case sProtocol:
845 intptr = &options->protocol;
846 arg = strdelim(&cp);
847 if (!arg || *arg == '\0')
848 fatal("%s line %d: Missing argument.", filename, linenum);
849 value = proto_spec(arg);
850 if (value == SSH_PROTO_UNKNOWN)
851 fatal("%s line %d: Bad protocol spec '%s'.",
852 filename, linenum, arg ? arg : "<NONE>");
853 if (*intptr == SSH_PROTO_UNKNOWN)
854 *intptr = value;
855 break;
857 case sSubsystem:
858 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
859 fatal("%s line %d: too many subsystems defined.",
860 filename, linenum);
862 arg = strdelim(&cp);
863 if (!arg || *arg == '\0')
864 fatal("%s line %d: Missing subsystem name.",
865 filename, linenum);
866 for (i = 0; i < options->num_subsystems; i++)
867 if (strcmp(arg, options->subsystem_name[i]) == 0)
868 fatal("%s line %d: Subsystem '%s' already defined.",
869 filename, linenum, arg);
870 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
871 arg = strdelim(&cp);
872 if (!arg || *arg == '\0')
873 fatal("%s line %d: Missing subsystem command.",
874 filename, linenum);
875 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
876 options->num_subsystems++;
877 break;
879 case sMaxStartups:
880 arg = strdelim(&cp);
881 if (!arg || *arg == '\0')
882 fatal("%s line %d: Missing MaxStartups spec.",
883 filename, linenum);
884 if ((n = sscanf(arg, "%d:%d:%d",
885 &options->max_startups_begin,
886 &options->max_startups_rate,
887 &options->max_startups)) == 3) {
888 if (options->max_startups_begin >
889 options->max_startups ||
890 options->max_startups_rate > 100 ||
891 options->max_startups_rate < 1)
892 fatal("%s line %d: Illegal MaxStartups spec.",
893 filename, linenum);
894 } else if (n != 1)
895 fatal("%s line %d: Illegal MaxStartups spec.",
896 filename, linenum);
897 else
898 options->max_startups = options->max_startups_begin;
899 break;
901 case sMaxAuthTries:
902 intptr = &options->max_authtries;
903 goto parse_int;
905 case sBanner:
906 charptr = &options->banner;
907 goto parse_filename;
909 * These options can contain %X options expanded at
910 * connect time, so that you can specify paths like:
912 * AuthorizedKeysFile /etc/ssh_keys/%u
914 case sAuthorizedKeysFile:
915 case sAuthorizedKeysFile2:
916 charptr = (opcode == sAuthorizedKeysFile ) ?
917 &options->authorized_keys_file :
918 &options->authorized_keys_file2;
919 goto parse_filename;
921 case sClientAliveInterval:
922 intptr = &options->client_alive_interval;
923 goto parse_time;
925 case sClientAliveCountMax:
926 intptr = &options->client_alive_count_max;
927 goto parse_int;
929 case sAcceptEnv:
930 while ((arg = strdelim(&cp)) && *arg != '\0') {
931 if (strchr(arg, '=') != NULL)
932 fatal("%s line %d: Invalid environment name.",
933 filename, linenum);
934 if (options->num_accept_env >= MAX_ACCEPT_ENV)
935 fatal("%s line %d: too many allow env.",
936 filename, linenum);
937 options->accept_env[options->num_accept_env++] =
938 xstrdup(arg);
940 break;
942 case sDeprecated:
943 logit("%s line %d: Deprecated option %s",
944 filename, linenum, arg);
945 while (arg)
946 arg = strdelim(&cp);
947 break;
949 case sUnsupported:
950 logit("%s line %d: Unsupported option %s",
951 filename, linenum, arg);
952 while (arg)
953 arg = strdelim(&cp);
954 break;
956 default:
957 fatal("%s line %d: Missing handler for opcode %s (%d)",
958 filename, linenum, arg, opcode);
960 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
961 fatal("%s line %d: garbage at end of line; \"%.200s\".",
962 filename, linenum, arg);
963 return 0;
966 /* Reads the server configuration file. */
968 void
969 load_server_config(const char *filename, Buffer *conf)
971 char line[1024], *cp;
972 FILE *f;
974 debug2("%s: filename %s", __func__, filename);
975 if ((f = fopen(filename, "r")) == NULL) {
976 perror(filename);
977 exit(1);
979 buffer_clear(conf);
980 while (fgets(line, sizeof(line), f)) {
982 * Trim out comments and strip whitespace
983 * NB - preserve newlines, they are needed to reproduce
984 * line numbers later for error messages
986 if ((cp = strchr(line, '#')) != NULL)
987 memcpy(cp, "\n", 2);
988 cp = line + strspn(line, " \t\r");
990 buffer_append(conf, cp, strlen(cp));
992 buffer_append(conf, "\0", 1);
993 fclose(f);
994 debug2("%s: done config len = %d", __func__, buffer_len(conf));
997 void
998 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1000 int linenum, bad_options = 0;
1001 char *cp, *obuf, *cbuf;
1003 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1005 obuf = cbuf = xstrdup(buffer_ptr(conf));
1006 linenum = 1;
1007 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1008 if (process_server_config_line(options, cp, filename,
1009 linenum++) != 0)
1010 bad_options++;
1012 xfree(obuf);
1013 if (bad_options > 0)
1014 fatal("%s: terminating, %d bad configuration options",
1015 filename, bad_options);