Import OpenSSH-5.1p1.
[dragonfly.git] / crypto / openssh-3.8.1p1 / servconf.c
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"
13 RCSID("$OpenBSD: servconf.c,v 1.130 2003/12/23 16:12:10 jakob Exp $");
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"
21 #include "tildexpand.h"
22 #include "misc.h"
23 #include "cipher.h"
24 #include "kex.h"
25 #include "mac.h"
26
27 static void add_listen_addr(ServerOptions *, char *, u_short);
28 static void add_one_listen_addr(ServerOptions *, char *, u_short);
29
30 /* AF_UNSPEC or AF_INET or AF_INET6 */
31 extern int IPv4or6;
32 /* Use of privilege separation or not */
33 extern int use_privsep;
34
35 /* Initializes the server options to their default values. */
36
37 void
38 initialize_server_options(ServerOptions *options)
39 {
40         memset(options, 0, sizeof(*options));
41
42         /* Portable-specific options */
43         options->use_pam = -1;
44
45         /* Standard Options */
46         options->num_ports = 0;
47         options->ports_from_cmdline = 0;
48         options->listen_addrs = NULL;
49         options->num_host_key_files = 0;
50         options->pid_file = NULL;
51         options->server_key_bits = -1;
52         options->login_grace_time = -1;
53         options->key_regeneration_time = -1;
54         options->permit_root_login = PERMIT_NOT_SET;
55         options->ignore_rhosts = -1;
56         options->ignore_user_known_hosts = -1;
57         options->print_motd = -1;
58         options->print_lastlog = -1;
59         options->x11_forwarding = -1;
60         options->x11_display_offset = -1;
61         options->x11_use_localhost = -1;
62         options->xauth_location = NULL;
63         options->strict_modes = -1;
64         options->tcp_keep_alive = -1;
65         options->log_facility = SYSLOG_FACILITY_NOT_SET;
66         options->log_level = SYSLOG_LEVEL_NOT_SET;
67         options->rhosts_rsa_authentication = -1;
68         options->hostbased_authentication = -1;
69         options->hostbased_uses_name_from_packet_only = -1;
70         options->rsa_authentication = -1;
71         options->pubkey_authentication = -1;
72         options->kerberos_authentication = -1;
73         options->kerberos_or_local_passwd = -1;
74         options->kerberos_ticket_cleanup = -1;
75         options->kerberos_get_afs_token = -1;
76         options->gss_authentication=-1;
77         options->gss_cleanup_creds = -1;
78         options->password_authentication = -1;
79         options->kbd_interactive_authentication = -1;
80         options->challenge_response_authentication = -1;
81         options->permit_empty_passwd = -1;
82         options->permit_user_env = -1;
83         options->use_login = -1;
84         options->compression = -1;
85         options->allow_tcp_forwarding = -1;
86         options->num_allow_users = 0;
87         options->num_deny_users = 0;
88         options->num_allow_groups = 0;
89         options->num_deny_groups = 0;
90         options->ciphers = NULL;
91         options->macs = NULL;
92         options->protocol = SSH_PROTO_UNKNOWN;
93         options->gateway_ports = -1;
94         options->num_subsystems = 0;
95         options->max_startups_begin = -1;
96         options->max_startups_rate = -1;
97         options->max_startups = -1;
98         options->banner = NULL;
99         options->use_dns = -1;
100         options->client_alive_interval = -1;
101         options->client_alive_count_max = -1;
102         options->authorized_keys_file = NULL;
103         options->authorized_keys_file2 = NULL;
104
105         /* Needs to be accessable in many places */
106         use_privsep = -1;
107 }
108
109 void
110 fill_default_server_options(ServerOptions *options)
111 {
112         /* Portable-specific options */
113         if (options->use_pam == -1)
114                 options->use_pam = 0;
115
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;
129                 }
130         }
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->use_dns == -1)
216                 options->use_dns = 1;
217         if (options->client_alive_interval == -1)
218                 options->client_alive_interval = 0;
219         if (options->client_alive_count_max == -1)
220                 options->client_alive_count_max = 3;
221         if (options->authorized_keys_file2 == NULL) {
222                 /* authorized_keys_file2 falls back to authorized_keys_file */
223                 if (options->authorized_keys_file != NULL)
224                         options->authorized_keys_file2 = options->authorized_keys_file;
225                 else
226                         options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
227         }
228         if (options->authorized_keys_file == NULL)
229                 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
230
231         /* Turn privilege separation on by default */
232         if (use_privsep == -1)
233                 use_privsep = 1;
234
235 #ifndef HAVE_MMAP
236         if (use_privsep && options->compression == 1) {
237                 error("This platform does not support both privilege "
238                     "separation and compression");
239                 error("Compression disabled");
240                 options->compression = 0;
241         }
242 #endif
243
244 }
245
246 /* Keyword tokens. */
247 typedef enum {
248         sBadOption,             /* == unknown option */
249         /* Portable-specific options */
250         sUsePAM,
251         /* Standard Options */
252         sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
253         sPermitRootLogin, sLogFacility, sLogLevel,
254         sRhostsRSAAuthentication, sRSAAuthentication,
255         sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
256         sKerberosGetAFSToken,
257         sKerberosTgtPassing, sChallengeResponseAuthentication,
258         sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
259         sPrintMotd, sPrintLastLog, sIgnoreRhosts,
260         sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
261         sStrictModes, sEmptyPasswd, sTCPKeepAlive,
262         sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
263         sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
264         sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
265         sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
266         sBanner, sUseDNS, sHostbasedAuthentication,
267         sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
268         sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
269         sGssAuthentication, sGssCleanupCreds,
270         sUsePrivilegeSeparation,
271         sDeprecated, sUnsupported
272 } ServerOpCodes;
273
274 /* Textual representation of the tokens. */
275 static struct {
276         const char *name;
277         ServerOpCodes opcode;
278 } keywords[] = {
279         /* Portable-specific options */
280 #ifdef USE_PAM
281         { "usepam", sUsePAM },
282 #else
283         { "usepam", sUnsupported },
284 #endif
285         { "pamauthenticationviakbdint", sDeprecated },
286         /* Standard Options */
287         { "port", sPort },
288         { "hostkey", sHostKeyFile },
289         { "hostdsakey", sHostKeyFile },                                 /* alias */
290         { "pidfile", sPidFile },
291         { "serverkeybits", sServerKeyBits },
292         { "logingracetime", sLoginGraceTime },
293         { "keyregenerationinterval", sKeyRegenerationTime },
294         { "permitrootlogin", sPermitRootLogin },
295         { "syslogfacility", sLogFacility },
296         { "loglevel", sLogLevel },
297         { "rhostsauthentication", sDeprecated },
298         { "rhostsrsaauthentication", sRhostsRSAAuthentication },
299         { "hostbasedauthentication", sHostbasedAuthentication },
300         { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
301         { "rsaauthentication", sRSAAuthentication },
302         { "pubkeyauthentication", sPubkeyAuthentication },
303         { "dsaauthentication", sPubkeyAuthentication },                 /* alias */
304 #ifdef KRB5
305         { "kerberosauthentication", sKerberosAuthentication },
306         { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
307         { "kerberosticketcleanup", sKerberosTicketCleanup },
308 #ifdef USE_AFS
309         { "kerberosgetafstoken", sKerberosGetAFSToken },
310 #else
311         { "kerberosgetafstoken", sUnsupported },
312 #endif
313 #else
314         { "kerberosauthentication", sUnsupported },
315         { "kerberosorlocalpasswd", sUnsupported },
316         { "kerberosticketcleanup", sUnsupported },
317         { "kerberosgetafstoken", sUnsupported },
318 #endif
319         { "kerberostgtpassing", sUnsupported },
320         { "afstokenpassing", sUnsupported },
321 #ifdef GSSAPI
322         { "gssapiauthentication", sGssAuthentication },
323         { "gssapicleanupcredentials", sGssCleanupCreds },
324 #else
325         { "gssapiauthentication", sUnsupported },
326         { "gssapicleanupcredentials", sUnsupported },
327 #endif
328         { "passwordauthentication", sPasswordAuthentication },
329         { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
330         { "challengeresponseauthentication", sChallengeResponseAuthentication },
331         { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
332         { "checkmail", sDeprecated },
333         { "listenaddress", sListenAddress },
334         { "printmotd", sPrintMotd },
335         { "printlastlog", sPrintLastLog },
336         { "ignorerhosts", sIgnoreRhosts },
337         { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
338         { "x11forwarding", sX11Forwarding },
339         { "x11displayoffset", sX11DisplayOffset },
340         { "x11uselocalhost", sX11UseLocalhost },
341         { "xauthlocation", sXAuthLocation },
342         { "strictmodes", sStrictModes },
343         { "permitemptypasswords", sEmptyPasswd },
344         { "permituserenvironment", sPermitUserEnvironment },
345         { "uselogin", sUseLogin },
346         { "compression", sCompression },
347         { "tcpkeepalive", sTCPKeepAlive },
348         { "keepalive", sTCPKeepAlive },                         /* obsolete alias */
349         { "allowtcpforwarding", sAllowTcpForwarding },
350         { "allowusers", sAllowUsers },
351         { "denyusers", sDenyUsers },
352         { "allowgroups", sAllowGroups },
353         { "denygroups", sDenyGroups },
354         { "ciphers", sCiphers },
355         { "macs", sMacs },
356         { "protocol", sProtocol },
357         { "gatewayports", sGatewayPorts },
358         { "subsystem", sSubsystem },
359         { "maxstartups", sMaxStartups },
360         { "banner", sBanner },
361         { "usedns", sUseDNS },
362         { "verifyreversemapping", sDeprecated },
363         { "reversemappingcheck", sDeprecated },
364         { "clientaliveinterval", sClientAliveInterval },
365         { "clientalivecountmax", sClientAliveCountMax },
366         { "authorizedkeysfile", sAuthorizedKeysFile },
367         { "authorizedkeysfile2", sAuthorizedKeysFile2 },
368         { "useprivilegeseparation", sUsePrivilegeSeparation},
369         { NULL, sBadOption }
370 };
371
372 /*
373  * Returns the number of the token pointed to by cp or sBadOption.
374  */
375
376 static ServerOpCodes
377 parse_token(const char *cp, const char *filename,
378             int linenum)
379 {
380         u_int i;
381
382         for (i = 0; keywords[i].name; i++)
383                 if (strcasecmp(cp, keywords[i].name) == 0)
384                         return keywords[i].opcode;
385
386         error("%s: line %d: Bad configuration option: %s",
387             filename, linenum, cp);
388         return sBadOption;
389 }
390
391 static void
392 add_listen_addr(ServerOptions *options, char *addr, u_short port)
393 {
394         int i;
395
396         if (options->num_ports == 0)
397                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
398         if (port == 0)
399                 for (i = 0; i < options->num_ports; i++)
400                         add_one_listen_addr(options, addr, options->ports[i]);
401         else
402                 add_one_listen_addr(options, addr, port);
403 }
404
405 static void
406 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
407 {
408         struct addrinfo hints, *ai, *aitop;
409         char strport[NI_MAXSERV];
410         int gaierr;
411
412         memset(&hints, 0, sizeof(hints));
413         hints.ai_family = IPv4or6;
414         hints.ai_socktype = SOCK_STREAM;
415         hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
416         snprintf(strport, sizeof strport, "%u", port);
417         if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
418                 fatal("bad addr or host: %s (%s)",
419                     addr ? addr : "<NULL>",
420                     gai_strerror(gaierr));
421         for (ai = aitop; ai->ai_next; ai = ai->ai_next)
422                 ;
423         ai->ai_next = options->listen_addrs;
424         options->listen_addrs = aitop;
425 }
426
427 int
428 process_server_config_line(ServerOptions *options, char *line,
429     const char *filename, int linenum)
430 {
431         char *cp, **charptr, *arg, *p;
432         int *intptr, value, i, n;
433         ServerOpCodes opcode;
434
435         cp = line;
436         arg = strdelim(&cp);
437         /* Ignore leading whitespace */
438         if (*arg == '\0')
439                 arg = strdelim(&cp);
440         if (!arg || !*arg || *arg == '#')
441                 return 0;
442         intptr = NULL;
443         charptr = NULL;
444         opcode = parse_token(arg, filename, linenum);
445         switch (opcode) {
446         /* Portable-specific options */
447         case sUsePAM:
448                 intptr = &options->use_pam;
449                 goto parse_flag;
450
451         /* Standard Options */
452         case sBadOption:
453                 return -1;
454         case sPort:
455                 /* ignore ports from configfile if cmdline specifies ports */
456                 if (options->ports_from_cmdline)
457                         return 0;
458                 if (options->listen_addrs != NULL)
459                         fatal("%s line %d: ports must be specified before "
460                             "ListenAddress.", filename, linenum);
461                 if (options->num_ports >= MAX_PORTS)
462                         fatal("%s line %d: too many ports.",
463                             filename, linenum);
464                 arg = strdelim(&cp);
465                 if (!arg || *arg == '\0')
466                         fatal("%s line %d: missing port number.",
467                             filename, linenum);
468                 options->ports[options->num_ports++] = a2port(arg);
469                 if (options->ports[options->num_ports-1] == 0)
470                         fatal("%s line %d: Badly formatted port number.",
471                             filename, linenum);
472                 break;
473
474         case sServerKeyBits:
475                 intptr = &options->server_key_bits;
476 parse_int:
477                 arg = strdelim(&cp);
478                 if (!arg || *arg == '\0')
479                         fatal("%s line %d: missing integer value.",
480                             filename, linenum);
481                 value = atoi(arg);
482                 if (*intptr == -1)
483                         *intptr = value;
484                 break;
485
486         case sLoginGraceTime:
487                 intptr = &options->login_grace_time;
488 parse_time:
489                 arg = strdelim(&cp);
490                 if (!arg || *arg == '\0')
491                         fatal("%s line %d: missing time value.",
492                             filename, linenum);
493                 if ((value = convtime(arg)) == -1)
494                         fatal("%s line %d: invalid time value.",
495                             filename, linenum);
496                 if (*intptr == -1)
497                         *intptr = value;
498                 break;
499
500         case sKeyRegenerationTime:
501                 intptr = &options->key_regeneration_time;
502                 goto parse_time;
503
504         case sListenAddress:
505                 arg = strdelim(&cp);
506                 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
507                         fatal("%s line %d: missing inet addr.",
508                             filename, linenum);
509                 if (*arg == '[') {
510                         if ((p = strchr(arg, ']')) == NULL)
511                                 fatal("%s line %d: bad ipv6 inet addr usage.",
512                                     filename, linenum);
513                         arg++;
514                         memmove(p, p+1, strlen(p+1)+1);
515                 } else if (((p = strchr(arg, ':')) == NULL) ||
516                             (strchr(p+1, ':') != NULL)) {
517                         add_listen_addr(options, arg, 0);
518                         break;
519                 }
520                 if (*p == ':') {
521                         u_short port;
522
523                         p++;
524                         if (*p == '\0')
525                                 fatal("%s line %d: bad inet addr:port usage.",
526                                     filename, linenum);
527                         else {
528                                 *(p-1) = '\0';
529                                 if ((port = a2port(p)) == 0)
530                                         fatal("%s line %d: bad port number.",
531                                             filename, linenum);
532                                 add_listen_addr(options, arg, port);
533                         }
534                 } else if (*p == '\0')
535                         add_listen_addr(options, arg, 0);
536                 else
537                         fatal("%s line %d: bad inet addr usage.",
538                             filename, linenum);
539                 break;
540
541         case sHostKeyFile:
542                 intptr = &options->num_host_key_files;
543                 if (*intptr >= MAX_HOSTKEYS)
544                         fatal("%s line %d: too many host keys specified (max %d).",
545                             filename, linenum, MAX_HOSTKEYS);
546                 charptr = &options->host_key_files[*intptr];
547 parse_filename:
548                 arg = strdelim(&cp);
549                 if (!arg || *arg == '\0')
550                         fatal("%s line %d: missing file name.",
551                             filename, linenum);
552                 if (*charptr == NULL) {
553                         *charptr = tilde_expand_filename(arg, getuid());
554                         /* increase optional counter */
555                         if (intptr != NULL)
556                                 *intptr = *intptr + 1;
557                 }
558                 break;
559
560         case sPidFile:
561                 charptr = &options->pid_file;
562                 goto parse_filename;
563
564         case sPermitRootLogin:
565                 intptr = &options->permit_root_login;
566                 arg = strdelim(&cp);
567                 if (!arg || *arg == '\0')
568                         fatal("%s line %d: missing yes/"
569                             "without-password/forced-commands-only/no "
570                             "argument.", filename, linenum);
571                 value = 0;      /* silence compiler */
572                 if (strcmp(arg, "without-password") == 0)
573                         value = PERMIT_NO_PASSWD;
574                 else if (strcmp(arg, "forced-commands-only") == 0)
575                         value = PERMIT_FORCED_ONLY;
576                 else if (strcmp(arg, "yes") == 0)
577                         value = PERMIT_YES;
578                 else if (strcmp(arg, "no") == 0)
579                         value = PERMIT_NO;
580                 else
581                         fatal("%s line %d: Bad yes/"
582                             "without-password/forced-commands-only/no "
583                             "argument: %s", filename, linenum, arg);
584                 if (*intptr == -1)
585                         *intptr = value;
586                 break;
587
588         case sIgnoreRhosts:
589                 intptr = &options->ignore_rhosts;
590 parse_flag:
591                 arg = strdelim(&cp);
592                 if (!arg || *arg == '\0')
593                         fatal("%s line %d: missing yes/no argument.",
594                             filename, linenum);
595                 value = 0;      /* silence compiler */
596                 if (strcmp(arg, "yes") == 0)
597                         value = 1;
598                 else if (strcmp(arg, "no") == 0)
599                         value = 0;
600                 else
601                         fatal("%s line %d: Bad yes/no argument: %s",
602                                 filename, linenum, arg);
603                 if (*intptr == -1)
604                         *intptr = value;
605                 break;
606
607         case sIgnoreUserKnownHosts:
608                 intptr = &options->ignore_user_known_hosts;
609                 goto parse_flag;
610
611         case sRhostsRSAAuthentication:
612                 intptr = &options->rhosts_rsa_authentication;
613                 goto parse_flag;
614
615         case sHostbasedAuthentication:
616                 intptr = &options->hostbased_authentication;
617                 goto parse_flag;
618
619         case sHostbasedUsesNameFromPacketOnly:
620                 intptr = &options->hostbased_uses_name_from_packet_only;
621                 goto parse_flag;
622
623         case sRSAAuthentication:
624                 intptr = &options->rsa_authentication;
625                 goto parse_flag;
626
627         case sPubkeyAuthentication:
628                 intptr = &options->pubkey_authentication;
629                 goto parse_flag;
630
631         case sKerberosAuthentication:
632                 intptr = &options->kerberos_authentication;
633                 goto parse_flag;
634
635         case sKerberosOrLocalPasswd:
636                 intptr = &options->kerberos_or_local_passwd;
637                 goto parse_flag;
638
639         case sKerberosTicketCleanup:
640                 intptr = &options->kerberos_ticket_cleanup;
641                 goto parse_flag;
642
643         case sKerberosGetAFSToken:
644                 intptr = &options->kerberos_get_afs_token;
645                 goto parse_flag;
646
647         case sGssAuthentication:
648                 intptr = &options->gss_authentication;
649                 goto parse_flag;
650
651         case sGssCleanupCreds:
652                 intptr = &options->gss_cleanup_creds;
653                 goto parse_flag;
654
655         case sPasswordAuthentication:
656                 intptr = &options->password_authentication;
657                 goto parse_flag;
658
659         case sKbdInteractiveAuthentication:
660                 intptr = &options->kbd_interactive_authentication;
661                 goto parse_flag;
662
663         case sChallengeResponseAuthentication:
664                 intptr = &options->challenge_response_authentication;
665                 goto parse_flag;
666
667         case sPrintMotd:
668                 intptr = &options->print_motd;
669                 goto parse_flag;
670
671         case sPrintLastLog:
672                 intptr = &options->print_lastlog;
673                 goto parse_flag;
674
675         case sX11Forwarding:
676                 intptr = &options->x11_forwarding;
677                 goto parse_flag;
678
679         case sX11DisplayOffset:
680                 intptr = &options->x11_display_offset;
681                 goto parse_int;
682
683         case sX11UseLocalhost:
684                 intptr = &options->x11_use_localhost;
685                 goto parse_flag;
686
687         case sXAuthLocation:
688                 charptr = &options->xauth_location;
689                 goto parse_filename;
690
691         case sStrictModes:
692                 intptr = &options->strict_modes;
693                 goto parse_flag;
694
695         case sTCPKeepAlive:
696                 intptr = &options->tcp_keep_alive;
697                 goto parse_flag;
698
699         case sEmptyPasswd:
700                 intptr = &options->permit_empty_passwd;
701                 goto parse_flag;
702
703         case sPermitUserEnvironment:
704                 intptr = &options->permit_user_env;
705                 goto parse_flag;
706
707         case sUseLogin:
708                 intptr = &options->use_login;
709                 goto parse_flag;
710
711         case sCompression:
712                 intptr = &options->compression;
713                 goto parse_flag;
714
715         case sGatewayPorts:
716                 intptr = &options->gateway_ports;
717                 goto parse_flag;
718
719         case sUseDNS:
720                 intptr = &options->use_dns;
721                 goto parse_flag;
722
723         case sLogFacility:
724                 intptr = (int *) &options->log_facility;
725                 arg = strdelim(&cp);
726                 value = log_facility_number(arg);
727                 if (value == SYSLOG_FACILITY_NOT_SET)
728                         fatal("%.200s line %d: unsupported log facility '%s'",
729                             filename, linenum, arg ? arg : "<NONE>");
730                 if (*intptr == -1)
731                         *intptr = (SyslogFacility) value;
732                 break;
733
734         case sLogLevel:
735                 intptr = (int *) &options->log_level;
736                 arg = strdelim(&cp);
737                 value = log_level_number(arg);
738                 if (value == SYSLOG_LEVEL_NOT_SET)
739                         fatal("%.200s line %d: unsupported log level '%s'",
740                             filename, linenum, arg ? arg : "<NONE>");
741                 if (*intptr == -1)
742                         *intptr = (LogLevel) value;
743                 break;
744
745         case sAllowTcpForwarding:
746                 intptr = &options->allow_tcp_forwarding;
747                 goto parse_flag;
748
749         case sUsePrivilegeSeparation:
750                 intptr = &use_privsep;
751                 goto parse_flag;
752
753         case sAllowUsers:
754                 while ((arg = strdelim(&cp)) && *arg != '\0') {
755                         if (options->num_allow_users >= MAX_ALLOW_USERS)
756                                 fatal("%s line %d: too many allow users.",
757                                     filename, linenum);
758                         options->allow_users[options->num_allow_users++] =
759                             xstrdup(arg);
760                 }
761                 break;
762
763         case sDenyUsers:
764                 while ((arg = strdelim(&cp)) && *arg != '\0') {
765                         if (options->num_deny_users >= MAX_DENY_USERS)
766                                 fatal( "%s line %d: too many deny users.",
767                                     filename, linenum);
768                         options->deny_users[options->num_deny_users++] =
769                             xstrdup(arg);
770                 }
771                 break;
772
773         case sAllowGroups:
774                 while ((arg = strdelim(&cp)) && *arg != '\0') {
775                         if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
776                                 fatal("%s line %d: too many allow groups.",
777                                     filename, linenum);
778                         options->allow_groups[options->num_allow_groups++] =
779                             xstrdup(arg);
780                 }
781                 break;
782
783         case sDenyGroups:
784                 while ((arg = strdelim(&cp)) && *arg != '\0') {
785                         if (options->num_deny_groups >= MAX_DENY_GROUPS)
786                                 fatal("%s line %d: too many deny groups.",
787                                     filename, linenum);
788                         options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
789                 }
790                 break;
791
792         case sCiphers:
793                 arg = strdelim(&cp);
794                 if (!arg || *arg == '\0')
795                         fatal("%s line %d: Missing argument.", filename, linenum);
796                 if (!ciphers_valid(arg))
797                         fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
798                             filename, linenum, arg ? arg : "<NONE>");
799                 if (options->ciphers == NULL)
800                         options->ciphers = xstrdup(arg);
801                 break;
802
803         case sMacs:
804                 arg = strdelim(&cp);
805                 if (!arg || *arg == '\0')
806                         fatal("%s line %d: Missing argument.", filename, linenum);
807                 if (!mac_valid(arg))
808                         fatal("%s line %d: Bad SSH2 mac spec '%s'.",
809                             filename, linenum, arg ? arg : "<NONE>");
810                 if (options->macs == NULL)
811                         options->macs = xstrdup(arg);
812                 break;
813
814         case sProtocol:
815                 intptr = &options->protocol;
816                 arg = strdelim(&cp);
817                 if (!arg || *arg == '\0')
818                         fatal("%s line %d: Missing argument.", filename, linenum);
819                 value = proto_spec(arg);
820                 if (value == SSH_PROTO_UNKNOWN)
821                         fatal("%s line %d: Bad protocol spec '%s'.",
822                             filename, linenum, arg ? arg : "<NONE>");
823                 if (*intptr == SSH_PROTO_UNKNOWN)
824                         *intptr = value;
825                 break;
826
827         case sSubsystem:
828                 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
829                         fatal("%s line %d: too many subsystems defined.",
830                             filename, linenum);
831                 }
832                 arg = strdelim(&cp);
833                 if (!arg || *arg == '\0')
834                         fatal("%s line %d: Missing subsystem name.",
835                             filename, linenum);
836                 for (i = 0; i < options->num_subsystems; i++)
837                         if (strcmp(arg, options->subsystem_name[i]) == 0)
838                                 fatal("%s line %d: Subsystem '%s' already defined.",
839                                     filename, linenum, arg);
840                 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
841                 arg = strdelim(&cp);
842                 if (!arg || *arg == '\0')
843                         fatal("%s line %d: Missing subsystem command.",
844                             filename, linenum);
845                 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
846                 options->num_subsystems++;
847                 break;
848
849         case sMaxStartups:
850                 arg = strdelim(&cp);
851                 if (!arg || *arg == '\0')
852                         fatal("%s line %d: Missing MaxStartups spec.",
853                             filename, linenum);
854                 if ((n = sscanf(arg, "%d:%d:%d",
855                     &options->max_startups_begin,
856                     &options->max_startups_rate,
857                     &options->max_startups)) == 3) {
858                         if (options->max_startups_begin >
859                             options->max_startups ||
860                             options->max_startups_rate > 100 ||
861                             options->max_startups_rate < 1)
862                                 fatal("%s line %d: Illegal MaxStartups spec.",
863                                     filename, linenum);
864                 } else if (n != 1)
865                         fatal("%s line %d: Illegal MaxStartups spec.",
866                             filename, linenum);
867                 else
868                         options->max_startups = options->max_startups_begin;
869                 break;
870
871         case sBanner:
872                 charptr = &options->banner;
873                 goto parse_filename;
874         /*
875          * These options can contain %X options expanded at
876          * connect time, so that you can specify paths like:
877          *
878          * AuthorizedKeysFile   /etc/ssh_keys/%u
879          */
880         case sAuthorizedKeysFile:
881         case sAuthorizedKeysFile2:
882                 charptr = (opcode == sAuthorizedKeysFile ) ?
883                     &options->authorized_keys_file :
884                     &options->authorized_keys_file2;
885                 goto parse_filename;
886
887         case sClientAliveInterval:
888                 intptr = &options->client_alive_interval;
889                 goto parse_time;
890
891         case sClientAliveCountMax:
892                 intptr = &options->client_alive_count_max;
893                 goto parse_int;
894
895         case sDeprecated:
896                 logit("%s line %d: Deprecated option %s",
897                     filename, linenum, arg);
898                 while (arg)
899                     arg = strdelim(&cp);
900                 break;
901
902         case sUnsupported:
903                 logit("%s line %d: Unsupported option %s",
904                     filename, linenum, arg);
905                 while (arg)
906                     arg = strdelim(&cp);
907                 break;
908
909         default:
910                 fatal("%s line %d: Missing handler for opcode %s (%d)",
911                     filename, linenum, arg, opcode);
912         }
913         if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
914                 fatal("%s line %d: garbage at end of line; \"%.200s\".",
915                     filename, linenum, arg);
916         return 0;
917 }
918
919 /* Reads the server configuration file. */
920
921 void
922 read_server_config(ServerOptions *options, const char *filename)
923 {
924         int linenum, bad_options = 0;
925         char line[1024];
926         FILE *f;
927
928         debug2("read_server_config: filename %s", filename);
929         f = fopen(filename, "r");
930         if (!f) {
931                 perror(filename);
932                 exit(1);
933         }
934         linenum = 0;
935         while (fgets(line, sizeof(line), f)) {
936                 /* Update line number counter. */
937                 linenum++;
938                 if (process_server_config_line(options, line, filename, linenum) != 0)
939                         bad_options++;
940         }
941         fclose(f);
942         if (bad_options > 0)
943                 fatal("%s: terminating, %d bad configuration options",
944                     filename, bad_options);
945 }