Merge from vendor branch NTPD:
[dragonfly.git] / crypto / openssh-3.9p1 / 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.137 2004/08/13 11:09:24 dtucker 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 "misc.h"
22 #include "cipher.h"
23 #include "kex.h"
24 #include "mac.h"
25
26 static void add_listen_addr(ServerOptions *, char *, u_short);
27 static void add_one_listen_addr(ServerOptions *, char *, u_short);
28
29 /* AF_UNSPEC or AF_INET or AF_INET6 */
30 extern int IPv4or6;
31 /* Use of privilege separation or not */
32 extern int use_privsep;
33
34 /* Initializes the server options to their default values. */
35
36 void
37 initialize_server_options(ServerOptions *options)
38 {
39         memset(options, 0, sizeof(*options));
40
41         /* Portable-specific options */
42         options->use_pam = -1;
43
44         /* Standard Options */
45         options->num_ports = 0;
46         options->ports_from_cmdline = 0;
47         options->listen_addrs = NULL;
48         options->num_host_key_files = 0;
49         options->pid_file = NULL;
50         options->server_key_bits = -1;
51         options->login_grace_time = -1;
52         options->key_regeneration_time = -1;
53         options->permit_root_login = PERMIT_NOT_SET;
54         options->ignore_rhosts = -1;
55         options->ignore_user_known_hosts = -1;
56         options->print_motd = -1;
57         options->print_lastlog = -1;
58         options->x11_forwarding = -1;
59         options->x11_display_offset = -1;
60         options->x11_use_localhost = -1;
61         options->xauth_location = NULL;
62         options->strict_modes = -1;
63         options->tcp_keep_alive = -1;
64         options->log_facility = SYSLOG_FACILITY_NOT_SET;
65         options->log_level = SYSLOG_LEVEL_NOT_SET;
66         options->rhosts_rsa_authentication = -1;
67         options->hostbased_authentication = -1;
68         options->hostbased_uses_name_from_packet_only = -1;
69         options->rsa_authentication = -1;
70         options->pubkey_authentication = -1;
71         options->kerberos_authentication = -1;
72         options->kerberos_or_local_passwd = -1;
73         options->kerberos_ticket_cleanup = -1;
74         options->kerberos_get_afs_token = -1;
75         options->gss_authentication=-1;
76         options->gss_cleanup_creds = -1;
77         options->password_authentication = -1;
78         options->kbd_interactive_authentication = -1;
79         options->challenge_response_authentication = -1;
80         options->permit_empty_passwd = -1;
81         options->permit_user_env = -1;
82         options->use_login = -1;
83         options->compression = -1;
84         options->allow_tcp_forwarding = -1;
85         options->num_allow_users = 0;
86         options->num_deny_users = 0;
87         options->num_allow_groups = 0;
88         options->num_deny_groups = 0;
89         options->ciphers = NULL;
90         options->macs = NULL;
91         options->protocol = SSH_PROTO_UNKNOWN;
92         options->gateway_ports = -1;
93         options->num_subsystems = 0;
94         options->max_startups_begin = -1;
95         options->max_startups_rate = -1;
96         options->max_startups = -1;
97         options->max_authtries = -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         options->num_accept_env = 0;
105
106         /* Needs to be accessable in many places */
107         use_privsep = -1;
108 }
109
110 void
111 fill_default_server_options(ServerOptions *options)
112 {
113         /* Portable-specific options */
114         if (options->use_pam == -1)
115                 options->use_pam = 0;
116
117         /* Standard Options */
118         if (options->protocol == SSH_PROTO_UNKNOWN)
119                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
120         if (options->num_host_key_files == 0) {
121                 /* fill default hostkeys for protocols */
122                 if (options->protocol & SSH_PROTO_1)
123                         options->host_key_files[options->num_host_key_files++] =
124                             _PATH_HOST_KEY_FILE;
125                 if (options->protocol & SSH_PROTO_2) {
126                         options->host_key_files[options->num_host_key_files++] =
127                             _PATH_HOST_RSA_KEY_FILE;
128                         options->host_key_files[options->num_host_key_files++] =
129                             _PATH_HOST_DSA_KEY_FILE;
130                 }
131         }
132         if (options->num_ports == 0)
133                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
134         if (options->listen_addrs == NULL)
135                 add_listen_addr(options, NULL, 0);
136         if (options->pid_file == NULL)
137                 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
138         if (options->server_key_bits == -1)
139                 options->server_key_bits = 768;
140         if (options->login_grace_time == -1)
141                 options->login_grace_time = 120;
142         if (options->key_regeneration_time == -1)
143                 options->key_regeneration_time = 3600;
144         if (options->permit_root_login == PERMIT_NOT_SET)
145                 options->permit_root_login = PERMIT_YES;
146         if (options->ignore_rhosts == -1)
147                 options->ignore_rhosts = 1;
148         if (options->ignore_user_known_hosts == -1)
149                 options->ignore_user_known_hosts = 0;
150         if (options->print_motd == -1)
151                 options->print_motd = 1;
152         if (options->print_lastlog == -1)
153                 options->print_lastlog = 1;
154         if (options->x11_forwarding == -1)
155                 options->x11_forwarding = 0;
156         if (options->x11_display_offset == -1)
157                 options->x11_display_offset = 10;
158         if (options->x11_use_localhost == -1)
159                 options->x11_use_localhost = 1;
160         if (options->xauth_location == NULL)
161                 options->xauth_location = _PATH_XAUTH;
162         if (options->strict_modes == -1)
163                 options->strict_modes = 1;
164         if (options->tcp_keep_alive == -1)
165                 options->tcp_keep_alive = 1;
166         if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
167                 options->log_facility = SYSLOG_FACILITY_AUTH;
168         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
169                 options->log_level = SYSLOG_LEVEL_INFO;
170         if (options->rhosts_rsa_authentication == -1)
171                 options->rhosts_rsa_authentication = 0;
172         if (options->hostbased_authentication == -1)
173                 options->hostbased_authentication = 0;
174         if (options->hostbased_uses_name_from_packet_only == -1)
175                 options->hostbased_uses_name_from_packet_only = 0;
176         if (options->rsa_authentication == -1)
177                 options->rsa_authentication = 1;
178         if (options->pubkey_authentication == -1)
179                 options->pubkey_authentication = 1;
180         if (options->kerberos_authentication == -1)
181                 options->kerberos_authentication = 0;
182         if (options->kerberos_or_local_passwd == -1)
183                 options->kerberos_or_local_passwd = 1;
184         if (options->kerberos_ticket_cleanup == -1)
185                 options->kerberos_ticket_cleanup = 1;
186         if (options->kerberos_get_afs_token == -1)
187                 options->kerberos_get_afs_token = 0;
188         if (options->gss_authentication == -1)
189                 options->gss_authentication = 0;
190         if (options->gss_cleanup_creds == -1)
191                 options->gss_cleanup_creds = 1;
192         if (options->password_authentication == -1)
193                 options->password_authentication = 1;
194         if (options->kbd_interactive_authentication == -1)
195                 options->kbd_interactive_authentication = 0;
196         if (options->challenge_response_authentication == -1)
197                 options->challenge_response_authentication = 1;
198         if (options->permit_empty_passwd == -1)
199                 options->permit_empty_passwd = 0;
200         if (options->permit_user_env == -1)
201                 options->permit_user_env = 0;
202         if (options->use_login == -1)
203                 options->use_login = 0;
204         if (options->compression == -1)
205                 options->compression = 1;
206         if (options->allow_tcp_forwarding == -1)
207                 options->allow_tcp_forwarding = 1;
208         if (options->gateway_ports == -1)
209                 options->gateway_ports = 0;
210         if (options->max_startups == -1)
211                 options->max_startups = 10;
212         if (options->max_startups_rate == -1)
213                 options->max_startups_rate = 100;               /* 100% */
214         if (options->max_startups_begin == -1)
215                 options->max_startups_begin = options->max_startups;
216         if (options->max_authtries == -1)
217                 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
218         if (options->use_dns == -1)
219                 options->use_dns = 1;
220         if (options->client_alive_interval == -1)
221                 options->client_alive_interval = 0;
222         if (options->client_alive_count_max == -1)
223                 options->client_alive_count_max = 3;
224         if (options->authorized_keys_file2 == NULL) {
225                 /* authorized_keys_file2 falls back to authorized_keys_file */
226                 if (options->authorized_keys_file != NULL)
227                         options->authorized_keys_file2 = options->authorized_keys_file;
228                 else
229                         options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
230         }
231         if (options->authorized_keys_file == NULL)
232                 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
233
234         /* Turn privilege separation on by default */
235         if (use_privsep == -1)
236                 use_privsep = 1;
237
238 #ifndef HAVE_MMAP
239         if (use_privsep && options->compression == 1) {
240                 error("This platform does not support both privilege "
241                     "separation and compression");
242                 error("Compression disabled");
243                 options->compression = 0;
244         }
245 #endif
246
247 }
248
249 /* Keyword tokens. */
250 typedef enum {
251         sBadOption,             /* == unknown option */
252         /* Portable-specific options */
253         sUsePAM,
254         /* Standard Options */
255         sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
256         sPermitRootLogin, sLogFacility, sLogLevel,
257         sRhostsRSAAuthentication, sRSAAuthentication,
258         sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
259         sKerberosGetAFSToken,
260         sKerberosTgtPassing, sChallengeResponseAuthentication,
261         sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
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;
277
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         { "printmotd", sPrintMotd },
339         { "printlastlog", sPrintLastLog },
340         { "ignorerhosts", sIgnoreRhosts },
341         { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
342         { "x11forwarding", sX11Forwarding },
343         { "x11displayoffset", sX11DisplayOffset },
344         { "x11uselocalhost", sX11UseLocalhost },
345         { "xauthlocation", sXAuthLocation },
346         { "strictmodes", sStrictModes },
347         { "permitemptypasswords", sEmptyPasswd },
348         { "permituserenvironment", sPermitUserEnvironment },
349         { "uselogin", sUseLogin },
350         { "compression", sCompression },
351         { "tcpkeepalive", sTCPKeepAlive },
352         { "keepalive", sTCPKeepAlive },                         /* obsolete alias */
353         { "allowtcpforwarding", sAllowTcpForwarding },
354         { "allowusers", sAllowUsers },
355         { "denyusers", sDenyUsers },
356         { "allowgroups", sAllowGroups },
357         { "denygroups", sDenyGroups },
358         { "ciphers", sCiphers },
359         { "macs", sMacs },
360         { "protocol", sProtocol },
361         { "gatewayports", sGatewayPorts },
362         { "subsystem", sSubsystem },
363         { "maxstartups", sMaxStartups },
364         { "maxauthtries", sMaxAuthTries },
365         { "banner", sBanner },
366         { "usedns", sUseDNS },
367         { "verifyreversemapping", sDeprecated },
368         { "reversemappingcheck", sDeprecated },
369         { "clientaliveinterval", sClientAliveInterval },
370         { "clientalivecountmax", sClientAliveCountMax },
371         { "authorizedkeysfile", sAuthorizedKeysFile },
372         { "authorizedkeysfile2", sAuthorizedKeysFile2 },
373         { "useprivilegeseparation", sUsePrivilegeSeparation},
374         { "acceptenv", sAcceptEnv },
375         { NULL, sBadOption }
376 };
377
378 /*
379  * Returns the number of the token pointed to by cp or sBadOption.
380  */
381
382 static ServerOpCodes
383 parse_token(const char *cp, const char *filename,
384             int linenum)
385 {
386         u_int i;
387
388         for (i = 0; keywords[i].name; i++)
389                 if (strcasecmp(cp, keywords[i].name) == 0)
390                         return keywords[i].opcode;
391
392         error("%s: line %d: Bad configuration option: %s",
393             filename, linenum, cp);
394         return sBadOption;
395 }
396
397 static void
398 add_listen_addr(ServerOptions *options, char *addr, u_short port)
399 {
400         int i;
401
402         if (options->num_ports == 0)
403                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
404         if (port == 0)
405                 for (i = 0; i < options->num_ports; i++)
406                         add_one_listen_addr(options, addr, options->ports[i]);
407         else
408                 add_one_listen_addr(options, addr, port);
409 }
410
411 static void
412 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
413 {
414         struct addrinfo hints, *ai, *aitop;
415         char strport[NI_MAXSERV];
416         int gaierr;
417
418         memset(&hints, 0, sizeof(hints));
419         hints.ai_family = IPv4or6;
420         hints.ai_socktype = SOCK_STREAM;
421         hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
422         snprintf(strport, sizeof strport, "%u", port);
423         if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
424                 fatal("bad addr or host: %s (%s)",
425                     addr ? addr : "<NULL>",
426                     gai_strerror(gaierr));
427         for (ai = aitop; ai->ai_next; ai = ai->ai_next)
428                 ;
429         ai->ai_next = options->listen_addrs;
430         options->listen_addrs = aitop;
431 }
432
433 int
434 process_server_config_line(ServerOptions *options, char *line,
435     const char *filename, int linenum)
436 {
437         char *cp, **charptr, *arg, *p;
438         int *intptr, value, i, n;
439         ServerOpCodes opcode;
440
441         cp = line;
442         arg = strdelim(&cp);
443         /* Ignore leading whitespace */
444         if (*arg == '\0')
445                 arg = strdelim(&cp);
446         if (!arg || !*arg || *arg == '#')
447                 return 0;
448         intptr = NULL;
449         charptr = NULL;
450         opcode = parse_token(arg, filename, linenum);
451         switch (opcode) {
452         /* Portable-specific options */
453         case sUsePAM:
454                 intptr = &options->use_pam;
455                 goto parse_flag;
456
457         /* Standard Options */
458         case sBadOption:
459                 return -1;
460         case sPort:
461                 /* ignore ports from configfile if cmdline specifies ports */
462                 if (options->ports_from_cmdline)
463                         return 0;
464                 if (options->listen_addrs != NULL)
465                         fatal("%s line %d: ports must be specified before "
466                             "ListenAddress.", filename, linenum);
467                 if (options->num_ports >= MAX_PORTS)
468                         fatal("%s line %d: too many ports.",
469                             filename, linenum);
470                 arg = strdelim(&cp);
471                 if (!arg || *arg == '\0')
472                         fatal("%s line %d: missing port number.",
473                             filename, linenum);
474                 options->ports[options->num_ports++] = a2port(arg);
475                 if (options->ports[options->num_ports-1] == 0)
476                         fatal("%s line %d: Badly formatted port number.",
477                             filename, linenum);
478                 break;
479
480         case sServerKeyBits:
481                 intptr = &options->server_key_bits;
482 parse_int:
483                 arg = strdelim(&cp);
484                 if (!arg || *arg == '\0')
485                         fatal("%s line %d: missing integer value.",
486                             filename, linenum);
487                 value = atoi(arg);
488                 if (*intptr == -1)
489                         *intptr = value;
490                 break;
491
492         case sLoginGraceTime:
493                 intptr = &options->login_grace_time;
494 parse_time:
495                 arg = strdelim(&cp);
496                 if (!arg || *arg == '\0')
497                         fatal("%s line %d: missing time value.",
498                             filename, linenum);
499                 if ((value = convtime(arg)) == -1)
500                         fatal("%s line %d: invalid time value.",
501                             filename, linenum);
502                 if (*intptr == -1)
503                         *intptr = value;
504                 break;
505
506         case sKeyRegenerationTime:
507                 intptr = &options->key_regeneration_time;
508                 goto parse_time;
509
510         case sListenAddress:
511                 arg = strdelim(&cp);
512                 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
513                         fatal("%s line %d: missing inet addr.",
514                             filename, linenum);
515                 if (*arg == '[') {
516                         if ((p = strchr(arg, ']')) == NULL)
517                                 fatal("%s line %d: bad ipv6 inet addr usage.",
518                                     filename, linenum);
519                         arg++;
520                         memmove(p, p+1, strlen(p+1)+1);
521                 } else if (((p = strchr(arg, ':')) == NULL) ||
522                             (strchr(p+1, ':') != NULL)) {
523                         add_listen_addr(options, arg, 0);
524                         break;
525                 }
526                 if (*p == ':') {
527                         u_short port;
528
529                         p++;
530                         if (*p == '\0')
531                                 fatal("%s line %d: bad inet addr:port usage.",
532                                     filename, linenum);
533                         else {
534                                 *(p-1) = '\0';
535                                 if ((port = a2port(p)) == 0)
536                                         fatal("%s line %d: bad port number.",
537                                             filename, linenum);
538                                 add_listen_addr(options, arg, port);
539                         }
540                 } else if (*p == '\0')
541                         add_listen_addr(options, arg, 0);
542                 else
543                         fatal("%s line %d: bad inet addr usage.",
544                             filename, linenum);
545                 break;
546
547         case sHostKeyFile:
548                 intptr = &options->num_host_key_files;
549                 if (*intptr >= MAX_HOSTKEYS)
550                         fatal("%s line %d: too many host keys specified (max %d).",
551                             filename, linenum, MAX_HOSTKEYS);
552                 charptr = &options->host_key_files[*intptr];
553 parse_filename:
554                 arg = strdelim(&cp);
555                 if (!arg || *arg == '\0')
556                         fatal("%s line %d: missing file name.",
557                             filename, linenum);
558                 if (*charptr == NULL) {
559                         *charptr = tilde_expand_filename(arg, getuid());
560                         /* increase optional counter */
561                         if (intptr != NULL)
562                                 *intptr = *intptr + 1;
563                 }
564                 break;
565
566         case sPidFile:
567                 charptr = &options->pid_file;
568                 goto parse_filename;
569
570         case sPermitRootLogin:
571                 intptr = &options->permit_root_login;
572                 arg = strdelim(&cp);
573                 if (!arg || *arg == '\0')
574                         fatal("%s line %d: missing yes/"
575                             "without-password/forced-commands-only/no "
576                             "argument.", filename, linenum);
577                 value = 0;      /* silence compiler */
578                 if (strcmp(arg, "without-password") == 0)
579                         value = PERMIT_NO_PASSWD;
580                 else if (strcmp(arg, "forced-commands-only") == 0)
581                         value = PERMIT_FORCED_ONLY;
582                 else if (strcmp(arg, "yes") == 0)
583                         value = PERMIT_YES;
584                 else if (strcmp(arg, "no") == 0)
585                         value = PERMIT_NO;
586                 else
587                         fatal("%s line %d: Bad yes/"
588                             "without-password/forced-commands-only/no "
589                             "argument: %s", filename, linenum, arg);
590                 if (*intptr == -1)
591                         *intptr = value;
592                 break;
593
594         case sIgnoreRhosts:
595                 intptr = &options->ignore_rhosts;
596 parse_flag:
597                 arg = strdelim(&cp);
598                 if (!arg || *arg == '\0')
599                         fatal("%s line %d: missing yes/no argument.",
600                             filename, linenum);
601                 value = 0;      /* silence compiler */
602                 if (strcmp(arg, "yes") == 0)
603                         value = 1;
604                 else if (strcmp(arg, "no") == 0)
605                         value = 0;
606                 else
607                         fatal("%s line %d: Bad yes/no argument: %s",
608                                 filename, linenum, arg);
609                 if (*intptr == -1)
610                         *intptr = value;
611                 break;
612
613         case sIgnoreUserKnownHosts:
614                 intptr = &options->ignore_user_known_hosts;
615                 goto parse_flag;
616
617         case sRhostsRSAAuthentication:
618                 intptr = &options->rhosts_rsa_authentication;
619                 goto parse_flag;
620
621         case sHostbasedAuthentication:
622                 intptr = &options->hostbased_authentication;
623                 goto parse_flag;
624
625         case sHostbasedUsesNameFromPacketOnly:
626                 intptr = &options->hostbased_uses_name_from_packet_only;
627                 goto parse_flag;
628
629         case sRSAAuthentication:
630                 intptr = &options->rsa_authentication;
631                 goto parse_flag;
632
633         case sPubkeyAuthentication:
634                 intptr = &options->pubkey_authentication;
635                 goto parse_flag;
636
637         case sKerberosAuthentication:
638                 intptr = &options->kerberos_authentication;
639                 goto parse_flag;
640
641         case sKerberosOrLocalPasswd:
642                 intptr = &options->kerberos_or_local_passwd;
643                 goto parse_flag;
644
645         case sKerberosTicketCleanup:
646                 intptr = &options->kerberos_ticket_cleanup;
647                 goto parse_flag;
648
649         case sKerberosGetAFSToken:
650                 intptr = &options->kerberos_get_afs_token;
651                 goto parse_flag;
652
653         case sGssAuthentication:
654                 intptr = &options->gss_authentication;
655                 goto parse_flag;
656
657         case sGssCleanupCreds:
658                 intptr = &options->gss_cleanup_creds;
659                 goto parse_flag;
660
661         case sPasswordAuthentication:
662                 intptr = &options->password_authentication;
663                 goto parse_flag;
664
665         case sKbdInteractiveAuthentication:
666                 intptr = &options->kbd_interactive_authentication;
667                 goto parse_flag;
668
669         case sChallengeResponseAuthentication:
670                 intptr = &options->challenge_response_authentication;
671                 goto parse_flag;
672
673         case sPrintMotd:
674                 intptr = &options->print_motd;
675                 goto parse_flag;
676
677         case sPrintLastLog:
678                 intptr = &options->print_lastlog;
679                 goto parse_flag;
680
681         case sX11Forwarding:
682                 intptr = &options->x11_forwarding;
683                 goto parse_flag;
684
685         case sX11DisplayOffset:
686                 intptr = &options->x11_display_offset;
687                 goto parse_int;
688
689         case sX11UseLocalhost:
690                 intptr = &options->x11_use_localhost;
691                 goto parse_flag;
692
693         case sXAuthLocation:
694                 charptr = &options->xauth_location;
695                 goto parse_filename;
696
697         case sStrictModes:
698                 intptr = &options->strict_modes;
699                 goto parse_flag;
700
701         case sTCPKeepAlive:
702                 intptr = &options->tcp_keep_alive;
703                 goto parse_flag;
704
705         case sEmptyPasswd:
706                 intptr = &options->permit_empty_passwd;
707                 goto parse_flag;
708
709         case sPermitUserEnvironment:
710                 intptr = &options->permit_user_env;
711                 goto parse_flag;
712
713         case sUseLogin:
714                 intptr = &options->use_login;
715                 goto parse_flag;
716
717         case sCompression:
718                 intptr = &options->compression;
719                 goto parse_flag;
720
721         case sGatewayPorts:
722                 intptr = &options->gateway_ports;
723                 goto parse_flag;
724
725         case sUseDNS:
726                 intptr = &options->use_dns;
727                 goto parse_flag;
728
729         case sLogFacility:
730                 intptr = (int *) &options->log_facility;
731                 arg = strdelim(&cp);
732                 value = log_facility_number(arg);
733                 if (value == SYSLOG_FACILITY_NOT_SET)
734                         fatal("%.200s line %d: unsupported log facility '%s'",
735                             filename, linenum, arg ? arg : "<NONE>");
736                 if (*intptr == -1)
737                         *intptr = (SyslogFacility) value;
738                 break;
739
740         case sLogLevel:
741                 intptr = (int *) &options->log_level;
742                 arg = strdelim(&cp);
743                 value = log_level_number(arg);
744                 if (value == SYSLOG_LEVEL_NOT_SET)
745                         fatal("%.200s line %d: unsupported log level '%s'",
746                             filename, linenum, arg ? arg : "<NONE>");
747                 if (*intptr == -1)
748                         *intptr = (LogLevel) value;
749                 break;
750
751         case sAllowTcpForwarding:
752                 intptr = &options->allow_tcp_forwarding;
753                 goto parse_flag;
754
755         case sUsePrivilegeSeparation:
756                 intptr = &use_privsep;
757                 goto parse_flag;
758
759         case sAllowUsers:
760                 while ((arg = strdelim(&cp)) && *arg != '\0') {
761                         if (options->num_allow_users >= MAX_ALLOW_USERS)
762                                 fatal("%s line %d: too many allow users.",
763                                     filename, linenum);
764                         options->allow_users[options->num_allow_users++] =
765                             xstrdup(arg);
766                 }
767                 break;
768
769         case sDenyUsers:
770                 while ((arg = strdelim(&cp)) && *arg != '\0') {
771                         if (options->num_deny_users >= MAX_DENY_USERS)
772                                 fatal( "%s line %d: too many deny users.",
773                                     filename, linenum);
774                         options->deny_users[options->num_deny_users++] =
775                             xstrdup(arg);
776                 }
777                 break;
778
779         case sAllowGroups:
780                 while ((arg = strdelim(&cp)) && *arg != '\0') {
781                         if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
782                                 fatal("%s line %d: too many allow groups.",
783                                     filename, linenum);
784                         options->allow_groups[options->num_allow_groups++] =
785                             xstrdup(arg);
786                 }
787                 break;
788
789         case sDenyGroups:
790                 while ((arg = strdelim(&cp)) && *arg != '\0') {
791                         if (options->num_deny_groups >= MAX_DENY_GROUPS)
792                                 fatal("%s line %d: too many deny groups.",
793                                     filename, linenum);
794                         options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
795                 }
796                 break;
797
798         case sCiphers:
799                 arg = strdelim(&cp);
800                 if (!arg || *arg == '\0')
801                         fatal("%s line %d: Missing argument.", filename, linenum);
802                 if (!ciphers_valid(arg))
803                         fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
804                             filename, linenum, arg ? arg : "<NONE>");
805                 if (options->ciphers == NULL)
806                         options->ciphers = xstrdup(arg);
807                 break;
808
809         case sMacs:
810                 arg = strdelim(&cp);
811                 if (!arg || *arg == '\0')
812                         fatal("%s line %d: Missing argument.", filename, linenum);
813                 if (!mac_valid(arg))
814                         fatal("%s line %d: Bad SSH2 mac spec '%s'.",
815                             filename, linenum, arg ? arg : "<NONE>");
816                 if (options->macs == NULL)
817                         options->macs = xstrdup(arg);
818                 break;
819
820         case sProtocol:
821                 intptr = &options->protocol;
822                 arg = strdelim(&cp);
823                 if (!arg || *arg == '\0')
824                         fatal("%s line %d: Missing argument.", filename, linenum);
825                 value = proto_spec(arg);
826                 if (value == SSH_PROTO_UNKNOWN)
827                         fatal("%s line %d: Bad protocol spec '%s'.",
828                             filename, linenum, arg ? arg : "<NONE>");
829                 if (*intptr == SSH_PROTO_UNKNOWN)
830                         *intptr = value;
831                 break;
832
833         case sSubsystem:
834                 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
835                         fatal("%s line %d: too many subsystems defined.",
836                             filename, linenum);
837                 }
838                 arg = strdelim(&cp);
839                 if (!arg || *arg == '\0')
840                         fatal("%s line %d: Missing subsystem name.",
841                             filename, linenum);
842                 for (i = 0; i < options->num_subsystems; i++)
843                         if (strcmp(arg, options->subsystem_name[i]) == 0)
844                                 fatal("%s line %d: Subsystem '%s' already defined.",
845                                     filename, linenum, arg);
846                 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
847                 arg = strdelim(&cp);
848                 if (!arg || *arg == '\0')
849                         fatal("%s line %d: Missing subsystem command.",
850                             filename, linenum);
851                 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
852                 options->num_subsystems++;
853                 break;
854
855         case sMaxStartups:
856                 arg = strdelim(&cp);
857                 if (!arg || *arg == '\0')
858                         fatal("%s line %d: Missing MaxStartups spec.",
859                             filename, linenum);
860                 if ((n = sscanf(arg, "%d:%d:%d",
861                     &options->max_startups_begin,
862                     &options->max_startups_rate,
863                     &options->max_startups)) == 3) {
864                         if (options->max_startups_begin >
865                             options->max_startups ||
866                             options->max_startups_rate > 100 ||
867                             options->max_startups_rate < 1)
868                                 fatal("%s line %d: Illegal MaxStartups spec.",
869                                     filename, linenum);
870                 } else if (n != 1)
871                         fatal("%s line %d: Illegal MaxStartups spec.",
872                             filename, linenum);
873                 else
874                         options->max_startups = options->max_startups_begin;
875                 break;
876
877         case sMaxAuthTries:
878                 intptr = &options->max_authtries;
879                 goto parse_int;
880
881         case sBanner:
882                 charptr = &options->banner;
883                 goto parse_filename;
884         /*
885          * These options can contain %X options expanded at
886          * connect time, so that you can specify paths like:
887          *
888          * AuthorizedKeysFile   /etc/ssh_keys/%u
889          */
890         case sAuthorizedKeysFile:
891         case sAuthorizedKeysFile2:
892                 charptr = (opcode == sAuthorizedKeysFile ) ?
893                     &options->authorized_keys_file :
894                     &options->authorized_keys_file2;
895                 goto parse_filename;
896
897         case sClientAliveInterval:
898                 intptr = &options->client_alive_interval;
899                 goto parse_time;
900
901         case sClientAliveCountMax:
902                 intptr = &options->client_alive_count_max;
903                 goto parse_int;
904
905         case sAcceptEnv:
906                 while ((arg = strdelim(&cp)) && *arg != '\0') {
907                         if (strchr(arg, '=') != NULL)
908                                 fatal("%s line %d: Invalid environment name.",
909                                     filename, linenum);
910                         if (options->num_accept_env >= MAX_ACCEPT_ENV)
911                                 fatal("%s line %d: too many allow env.",
912                                     filename, linenum);
913                         options->accept_env[options->num_accept_env++] =
914                             xstrdup(arg);
915                 }
916                 break;
917
918         case sDeprecated:
919                 logit("%s line %d: Deprecated option %s",
920                     filename, linenum, arg);
921                 while (arg)
922                     arg = strdelim(&cp);
923                 break;
924
925         case sUnsupported:
926                 logit("%s line %d: Unsupported option %s",
927                     filename, linenum, arg);
928                 while (arg)
929                     arg = strdelim(&cp);
930                 break;
931
932         default:
933                 fatal("%s line %d: Missing handler for opcode %s (%d)",
934                     filename, linenum, arg, opcode);
935         }
936         if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
937                 fatal("%s line %d: garbage at end of line; \"%.200s\".",
938                     filename, linenum, arg);
939         return 0;
940 }
941
942 /* Reads the server configuration file. */
943
944 void
945 load_server_config(const char *filename, Buffer *conf)
946 {
947         char line[1024], *cp;
948         FILE *f;
949
950         debug2("%s: filename %s", __func__, filename);
951         if ((f = fopen(filename, "r")) == NULL) {
952                 perror(filename);
953                 exit(1);
954         }
955         buffer_clear(conf);
956         while (fgets(line, sizeof(line), f)) {
957                 /*
958                  * Trim out comments and strip whitespace
959                  * NB - preserve newlines, they are needed to reproduce
960                  * line numbers later for error messages
961                  */
962                 if ((cp = strchr(line, '#')) != NULL)
963                         memcpy(cp, "\n", 2);
964                 cp = line + strspn(line, " \t\r");
965
966                 buffer_append(conf, cp, strlen(cp));
967         }
968         buffer_append(conf, "\0", 1);
969         fclose(f);
970         debug2("%s: done config len = %d", __func__, buffer_len(conf));
971 }
972
973 void
974 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
975 {
976         int linenum, bad_options = 0;
977         char *cp, *obuf, *cbuf;
978
979         debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
980
981         obuf = cbuf = xstrdup(buffer_ptr(conf));
982         linenum = 1;
983         while((cp = strsep(&cbuf, "\n")) != NULL) {
984                 if (process_server_config_line(options, cp, filename,
985                     linenum++) != 0)
986                         bad_options++;
987         }
988         xfree(obuf);
989         if (bad_options > 0)
990                 fatal("%s: terminating, %d bad configuration options",
991                     filename, bad_options);
992 }