]> andersk Git - openssh.git/blob - servconf.c
- jakob@cvs.openbsd.org 2003/12/23 16:12:10
[openssh.git] / 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         { "kerberosgetafstoken", sKerberosGetAFSToken },
309 #else
310         { "kerberosauthentication", sUnsupported },
311         { "kerberosorlocalpasswd", sUnsupported },
312         { "kerberosticketcleanup", sUnsupported },
313         { "kerberosgetafstoken", sUnsupported },
314 #endif
315         { "kerberostgtpassing", sUnsupported },
316         { "afstokenpassing", sUnsupported },
317 #ifdef GSSAPI
318         { "gssapiauthentication", sGssAuthentication },
319         { "gssapicleanupcredentials", sGssCleanupCreds },
320 #else
321         { "gssapiauthentication", sUnsupported },
322         { "gssapicleanupcredentials", sUnsupported },
323 #endif
324         { "passwordauthentication", sPasswordAuthentication },
325         { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
326         { "challengeresponseauthentication", sChallengeResponseAuthentication },
327         { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
328         { "checkmail", sDeprecated },
329         { "listenaddress", sListenAddress },
330         { "printmotd", sPrintMotd },
331         { "printlastlog", sPrintLastLog },
332         { "ignorerhosts", sIgnoreRhosts },
333         { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
334         { "x11forwarding", sX11Forwarding },
335         { "x11displayoffset", sX11DisplayOffset },
336         { "x11uselocalhost", sX11UseLocalhost },
337         { "xauthlocation", sXAuthLocation },
338         { "strictmodes", sStrictModes },
339         { "permitemptypasswords", sEmptyPasswd },
340         { "permituserenvironment", sPermitUserEnvironment },
341         { "uselogin", sUseLogin },
342         { "compression", sCompression },
343         { "tcpkeepalive", sTCPKeepAlive },
344         { "keepalive", sTCPKeepAlive },                         /* obsolete alias */
345         { "allowtcpforwarding", sAllowTcpForwarding },
346         { "allowusers", sAllowUsers },
347         { "denyusers", sDenyUsers },
348         { "allowgroups", sAllowGroups },
349         { "denygroups", sDenyGroups },
350         { "ciphers", sCiphers },
351         { "macs", sMacs },
352         { "protocol", sProtocol },
353         { "gatewayports", sGatewayPorts },
354         { "subsystem", sSubsystem },
355         { "maxstartups", sMaxStartups },
356         { "banner", sBanner },
357         { "usedns", sUseDNS },
358         { "verifyreversemapping", sDeprecated },
359         { "reversemappingcheck", sDeprecated },
360         { "clientaliveinterval", sClientAliveInterval },
361         { "clientalivecountmax", sClientAliveCountMax },
362         { "authorizedkeysfile", sAuthorizedKeysFile },
363         { "authorizedkeysfile2", sAuthorizedKeysFile2 },
364         { "useprivilegeseparation", sUsePrivilegeSeparation},
365         { NULL, sBadOption }
366 };
367
368 /*
369  * Returns the number of the token pointed to by cp or sBadOption.
370  */
371
372 static ServerOpCodes
373 parse_token(const char *cp, const char *filename,
374             int linenum)
375 {
376         u_int i;
377
378         for (i = 0; keywords[i].name; i++)
379                 if (strcasecmp(cp, keywords[i].name) == 0)
380                         return keywords[i].opcode;
381
382         error("%s: line %d: Bad configuration option: %s",
383             filename, linenum, cp);
384         return sBadOption;
385 }
386
387 static void
388 add_listen_addr(ServerOptions *options, char *addr, u_short port)
389 {
390         int i;
391
392         if (options->num_ports == 0)
393                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
394         if (port == 0)
395                 for (i = 0; i < options->num_ports; i++)
396                         add_one_listen_addr(options, addr, options->ports[i]);
397         else
398                 add_one_listen_addr(options, addr, port);
399 }
400
401 static void
402 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
403 {
404         struct addrinfo hints, *ai, *aitop;
405         char strport[NI_MAXSERV];
406         int gaierr;
407
408         memset(&hints, 0, sizeof(hints));
409         hints.ai_family = IPv4or6;
410         hints.ai_socktype = SOCK_STREAM;
411         hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
412         snprintf(strport, sizeof strport, "%u", port);
413         if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
414                 fatal("bad addr or host: %s (%s)",
415                     addr ? addr : "<NULL>",
416                     gai_strerror(gaierr));
417         for (ai = aitop; ai->ai_next; ai = ai->ai_next)
418                 ;
419         ai->ai_next = options->listen_addrs;
420         options->listen_addrs = aitop;
421 }
422
423 int
424 process_server_config_line(ServerOptions *options, char *line,
425     const char *filename, int linenum)
426 {
427         char *cp, **charptr, *arg, *p;
428         int *intptr, value, i, n;
429         ServerOpCodes opcode;
430
431         cp = line;
432         arg = strdelim(&cp);
433         /* Ignore leading whitespace */
434         if (*arg == '\0')
435                 arg = strdelim(&cp);
436         if (!arg || !*arg || *arg == '#')
437                 return 0;
438         intptr = NULL;
439         charptr = NULL;
440         opcode = parse_token(arg, filename, linenum);
441         switch (opcode) {
442         /* Portable-specific options */
443         case sUsePAM:
444                 intptr = &options->use_pam;
445                 goto parse_flag;
446
447         /* Standard Options */
448         case sBadOption:
449                 return -1;
450         case sPort:
451                 /* ignore ports from configfile if cmdline specifies ports */
452                 if (options->ports_from_cmdline)
453                         return 0;
454                 if (options->listen_addrs != NULL)
455                         fatal("%s line %d: ports must be specified before "
456                             "ListenAddress.", filename, linenum);
457                 if (options->num_ports >= MAX_PORTS)
458                         fatal("%s line %d: too many ports.",
459                             filename, linenum);
460                 arg = strdelim(&cp);
461                 if (!arg || *arg == '\0')
462                         fatal("%s line %d: missing port number.",
463                             filename, linenum);
464                 options->ports[options->num_ports++] = a2port(arg);
465                 if (options->ports[options->num_ports-1] == 0)
466                         fatal("%s line %d: Badly formatted port number.",
467                             filename, linenum);
468                 break;
469
470         case sServerKeyBits:
471                 intptr = &options->server_key_bits;
472 parse_int:
473                 arg = strdelim(&cp);
474                 if (!arg || *arg == '\0')
475                         fatal("%s line %d: missing integer value.",
476                             filename, linenum);
477                 value = atoi(arg);
478                 if (*intptr == -1)
479                         *intptr = value;
480                 break;
481
482         case sLoginGraceTime:
483                 intptr = &options->login_grace_time;
484 parse_time:
485                 arg = strdelim(&cp);
486                 if (!arg || *arg == '\0')
487                         fatal("%s line %d: missing time value.",
488                             filename, linenum);
489                 if ((value = convtime(arg)) == -1)
490                         fatal("%s line %d: invalid time value.",
491                             filename, linenum);
492                 if (*intptr == -1)
493                         *intptr = value;
494                 break;
495
496         case sKeyRegenerationTime:
497                 intptr = &options->key_regeneration_time;
498                 goto parse_time;
499
500         case sListenAddress:
501                 arg = strdelim(&cp);
502                 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
503                         fatal("%s line %d: missing inet addr.",
504                             filename, linenum);
505                 if (*arg == '[') {
506                         if ((p = strchr(arg, ']')) == NULL)
507                                 fatal("%s line %d: bad ipv6 inet addr usage.",
508                                     filename, linenum);
509                         arg++;
510                         memmove(p, p+1, strlen(p+1)+1);
511                 } else if (((p = strchr(arg, ':')) == NULL) ||
512                             (strchr(p+1, ':') != NULL)) {
513                         add_listen_addr(options, arg, 0);
514                         break;
515                 }
516                 if (*p == ':') {
517                         u_short port;
518
519                         p++;
520                         if (*p == '\0')
521                                 fatal("%s line %d: bad inet addr:port usage.",
522                                     filename, linenum);
523                         else {
524                                 *(p-1) = '\0';
525                                 if ((port = a2port(p)) == 0)
526                                         fatal("%s line %d: bad port number.",
527                                             filename, linenum);
528                                 add_listen_addr(options, arg, port);
529                         }
530                 } else if (*p == '\0')
531                         add_listen_addr(options, arg, 0);
532                 else
533                         fatal("%s line %d: bad inet addr usage.",
534                             filename, linenum);
535                 break;
536
537         case sHostKeyFile:
538                 intptr = &options->num_host_key_files;
539                 if (*intptr >= MAX_HOSTKEYS)
540                         fatal("%s line %d: too many host keys specified (max %d).",
541                             filename, linenum, MAX_HOSTKEYS);
542                 charptr = &options->host_key_files[*intptr];
543 parse_filename:
544                 arg = strdelim(&cp);
545                 if (!arg || *arg == '\0')
546                         fatal("%s line %d: missing file name.",
547                             filename, linenum);
548                 if (*charptr == NULL) {
549                         *charptr = tilde_expand_filename(arg, getuid());
550                         /* increase optional counter */
551                         if (intptr != NULL)
552                                 *intptr = *intptr + 1;
553                 }
554                 break;
555
556         case sPidFile:
557                 charptr = &options->pid_file;
558                 goto parse_filename;
559
560         case sPermitRootLogin:
561                 intptr = &options->permit_root_login;
562                 arg = strdelim(&cp);
563                 if (!arg || *arg == '\0')
564                         fatal("%s line %d: missing yes/"
565                             "without-password/forced-commands-only/no "
566                             "argument.", filename, linenum);
567                 value = 0;      /* silence compiler */
568                 if (strcmp(arg, "without-password") == 0)
569                         value = PERMIT_NO_PASSWD;
570                 else if (strcmp(arg, "forced-commands-only") == 0)
571                         value = PERMIT_FORCED_ONLY;
572                 else if (strcmp(arg, "yes") == 0)
573                         value = PERMIT_YES;
574                 else if (strcmp(arg, "no") == 0)
575                         value = PERMIT_NO;
576                 else
577                         fatal("%s line %d: Bad yes/"
578                             "without-password/forced-commands-only/no "
579                             "argument: %s", filename, linenum, arg);
580                 if (*intptr == -1)
581                         *intptr = value;
582                 break;
583
584         case sIgnoreRhosts:
585                 intptr = &options->ignore_rhosts;
586 parse_flag:
587                 arg = strdelim(&cp);
588                 if (!arg || *arg == '\0')
589                         fatal("%s line %d: missing yes/no argument.",
590                             filename, linenum);
591                 value = 0;      /* silence compiler */
592                 if (strcmp(arg, "yes") == 0)
593                         value = 1;
594                 else if (strcmp(arg, "no") == 0)
595                         value = 0;
596                 else
597                         fatal("%s line %d: Bad yes/no argument: %s",
598                                 filename, linenum, arg);
599                 if (*intptr == -1)
600                         *intptr = value;
601                 break;
602
603         case sIgnoreUserKnownHosts:
604                 intptr = &options->ignore_user_known_hosts;
605                 goto parse_flag;
606
607         case sRhostsRSAAuthentication:
608                 intptr = &options->rhosts_rsa_authentication;
609                 goto parse_flag;
610
611         case sHostbasedAuthentication:
612                 intptr = &options->hostbased_authentication;
613                 goto parse_flag;
614
615         case sHostbasedUsesNameFromPacketOnly:
616                 intptr = &options->hostbased_uses_name_from_packet_only;
617                 goto parse_flag;
618
619         case sRSAAuthentication:
620                 intptr = &options->rsa_authentication;
621                 goto parse_flag;
622
623         case sPubkeyAuthentication:
624                 intptr = &options->pubkey_authentication;
625                 goto parse_flag;
626
627         case sKerberosAuthentication:
628                 intptr = &options->kerberos_authentication;
629                 goto parse_flag;
630
631         case sKerberosOrLocalPasswd:
632                 intptr = &options->kerberos_or_local_passwd;
633                 goto parse_flag;
634
635         case sKerberosTicketCleanup:
636                 intptr = &options->kerberos_ticket_cleanup;
637                 goto parse_flag;
638
639         case sKerberosGetAFSToken:
640                 intptr = &options->kerberos_get_afs_token;
641                 goto parse_flag;
642
643         case sGssAuthentication:
644                 intptr = &options->gss_authentication;
645                 goto parse_flag;
646
647         case sGssCleanupCreds:
648                 intptr = &options->gss_cleanup_creds;
649                 goto parse_flag;
650
651         case sPasswordAuthentication:
652                 intptr = &options->password_authentication;
653                 goto parse_flag;
654
655         case sKbdInteractiveAuthentication:
656                 intptr = &options->kbd_interactive_authentication;
657                 goto parse_flag;
658
659         case sChallengeResponseAuthentication:
660                 intptr = &options->challenge_response_authentication;
661                 goto parse_flag;
662
663         case sPrintMotd:
664                 intptr = &options->print_motd;
665                 goto parse_flag;
666
667         case sPrintLastLog:
668                 intptr = &options->print_lastlog;
669                 goto parse_flag;
670
671         case sX11Forwarding:
672                 intptr = &options->x11_forwarding;
673                 goto parse_flag;
674
675         case sX11DisplayOffset:
676                 intptr = &options->x11_display_offset;
677                 goto parse_int;
678
679         case sX11UseLocalhost:
680                 intptr = &options->x11_use_localhost;
681                 goto parse_flag;
682
683         case sXAuthLocation:
684                 charptr = &options->xauth_location;
685                 goto parse_filename;
686
687         case sStrictModes:
688                 intptr = &options->strict_modes;
689                 goto parse_flag;
690
691         case sTCPKeepAlive:
692                 intptr = &options->tcp_keep_alive;
693                 goto parse_flag;
694
695         case sEmptyPasswd:
696                 intptr = &options->permit_empty_passwd;
697                 goto parse_flag;
698
699         case sPermitUserEnvironment:
700                 intptr = &options->permit_user_env;
701                 goto parse_flag;
702
703         case sUseLogin:
704                 intptr = &options->use_login;
705                 goto parse_flag;
706
707         case sCompression:
708                 intptr = &options->compression;
709                 goto parse_flag;
710
711         case sGatewayPorts:
712                 intptr = &options->gateway_ports;
713                 goto parse_flag;
714
715         case sUseDNS:
716                 intptr = &options->use_dns;
717                 goto parse_flag;
718
719         case sLogFacility:
720                 intptr = (int *) &options->log_facility;
721                 arg = strdelim(&cp);
722                 value = log_facility_number(arg);
723                 if (value == SYSLOG_FACILITY_NOT_SET)
724                         fatal("%.200s line %d: unsupported log facility '%s'",
725                             filename, linenum, arg ? arg : "<NONE>");
726                 if (*intptr == -1)
727                         *intptr = (SyslogFacility) value;
728                 break;
729
730         case sLogLevel:
731                 intptr = (int *) &options->log_level;
732                 arg = strdelim(&cp);
733                 value = log_level_number(arg);
734                 if (value == SYSLOG_LEVEL_NOT_SET)
735                         fatal("%.200s line %d: unsupported log level '%s'",
736                             filename, linenum, arg ? arg : "<NONE>");
737                 if (*intptr == -1)
738                         *intptr = (LogLevel) value;
739                 break;
740
741         case sAllowTcpForwarding:
742                 intptr = &options->allow_tcp_forwarding;
743                 goto parse_flag;
744
745         case sUsePrivilegeSeparation:
746                 intptr = &use_privsep;
747                 goto parse_flag;
748
749         case sAllowUsers:
750                 while ((arg = strdelim(&cp)) && *arg != '\0') {
751                         if (options->num_allow_users >= MAX_ALLOW_USERS)
752                                 fatal("%s line %d: too many allow users.",
753                                     filename, linenum);
754                         options->allow_users[options->num_allow_users++] =
755                             xstrdup(arg);
756                 }
757                 break;
758
759         case sDenyUsers:
760                 while ((arg = strdelim(&cp)) && *arg != '\0') {
761                         if (options->num_deny_users >= MAX_DENY_USERS)
762                                 fatal( "%s line %d: too many deny users.",
763                                     filename, linenum);
764                         options->deny_users[options->num_deny_users++] =
765                             xstrdup(arg);
766                 }
767                 break;
768
769         case sAllowGroups:
770                 while ((arg = strdelim(&cp)) && *arg != '\0') {
771                         if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
772                                 fatal("%s line %d: too many allow groups.",
773                                     filename, linenum);
774                         options->allow_groups[options->num_allow_groups++] =
775                             xstrdup(arg);
776                 }
777                 break;
778
779         case sDenyGroups:
780                 while ((arg = strdelim(&cp)) && *arg != '\0') {
781                         if (options->num_deny_groups >= MAX_DENY_GROUPS)
782                                 fatal("%s line %d: too many deny groups.",
783                                     filename, linenum);
784                         options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
785                 }
786                 break;
787
788         case sCiphers:
789                 arg = strdelim(&cp);
790                 if (!arg || *arg == '\0')
791                         fatal("%s line %d: Missing argument.", filename, linenum);
792                 if (!ciphers_valid(arg))
793                         fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
794                             filename, linenum, arg ? arg : "<NONE>");
795                 if (options->ciphers == NULL)
796                         options->ciphers = xstrdup(arg);
797                 break;
798
799         case sMacs:
800                 arg = strdelim(&cp);
801                 if (!arg || *arg == '\0')
802                         fatal("%s line %d: Missing argument.", filename, linenum);
803                 if (!mac_valid(arg))
804                         fatal("%s line %d: Bad SSH2 mac spec '%s'.",
805                             filename, linenum, arg ? arg : "<NONE>");
806                 if (options->macs == NULL)
807                         options->macs = xstrdup(arg);
808                 break;
809
810         case sProtocol:
811                 intptr = &options->protocol;
812                 arg = strdelim(&cp);
813                 if (!arg || *arg == '\0')
814                         fatal("%s line %d: Missing argument.", filename, linenum);
815                 value = proto_spec(arg);
816                 if (value == SSH_PROTO_UNKNOWN)
817                         fatal("%s line %d: Bad protocol spec '%s'.",
818                             filename, linenum, arg ? arg : "<NONE>");
819                 if (*intptr == SSH_PROTO_UNKNOWN)
820                         *intptr = value;
821                 break;
822
823         case sSubsystem:
824                 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
825                         fatal("%s line %d: too many subsystems defined.",
826                             filename, linenum);
827                 }
828                 arg = strdelim(&cp);
829                 if (!arg || *arg == '\0')
830                         fatal("%s line %d: Missing subsystem name.",
831                             filename, linenum);
832                 for (i = 0; i < options->num_subsystems; i++)
833                         if (strcmp(arg, options->subsystem_name[i]) == 0)
834                                 fatal("%s line %d: Subsystem '%s' already defined.",
835                                     filename, linenum, arg);
836                 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
837                 arg = strdelim(&cp);
838                 if (!arg || *arg == '\0')
839                         fatal("%s line %d: Missing subsystem command.",
840                             filename, linenum);
841                 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
842                 options->num_subsystems++;
843                 break;
844
845         case sMaxStartups:
846                 arg = strdelim(&cp);
847                 if (!arg || *arg == '\0')
848                         fatal("%s line %d: Missing MaxStartups spec.",
849                             filename, linenum);
850                 if ((n = sscanf(arg, "%d:%d:%d",
851                     &options->max_startups_begin,
852                     &options->max_startups_rate,
853                     &options->max_startups)) == 3) {
854                         if (options->max_startups_begin >
855                             options->max_startups ||
856                             options->max_startups_rate > 100 ||
857                             options->max_startups_rate < 1)
858                                 fatal("%s line %d: Illegal MaxStartups spec.",
859                                     filename, linenum);
860                 } else if (n != 1)
861                         fatal("%s line %d: Illegal MaxStartups spec.",
862                             filename, linenum);
863                 else
864                         options->max_startups = options->max_startups_begin;
865                 break;
866
867         case sBanner:
868                 charptr = &options->banner;
869                 goto parse_filename;
870         /*
871          * These options can contain %X options expanded at
872          * connect time, so that you can specify paths like:
873          *
874          * AuthorizedKeysFile   /etc/ssh_keys/%u
875          */
876         case sAuthorizedKeysFile:
877         case sAuthorizedKeysFile2:
878                 charptr = (opcode == sAuthorizedKeysFile ) ?
879                     &options->authorized_keys_file :
880                     &options->authorized_keys_file2;
881                 goto parse_filename;
882
883         case sClientAliveInterval:
884                 intptr = &options->client_alive_interval;
885                 goto parse_time;
886
887         case sClientAliveCountMax:
888                 intptr = &options->client_alive_count_max;
889                 goto parse_int;
890
891         case sDeprecated:
892                 logit("%s line %d: Deprecated option %s",
893                     filename, linenum, arg);
894                 while (arg)
895                     arg = strdelim(&cp);
896                 break;
897
898         case sUnsupported:
899                 logit("%s line %d: Unsupported option %s",
900                     filename, linenum, arg);
901                 while (arg)
902                     arg = strdelim(&cp);
903                 break;
904
905         default:
906                 fatal("%s line %d: Missing handler for opcode %s (%d)",
907                     filename, linenum, arg, opcode);
908         }
909         if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
910                 fatal("%s line %d: garbage at end of line; \"%.200s\".",
911                     filename, linenum, arg);
912         return 0;
913 }
914
915 /* Reads the server configuration file. */
916
917 void
918 read_server_config(ServerOptions *options, const char *filename)
919 {
920         int linenum, bad_options = 0;
921         char line[1024];
922         FILE *f;
923
924         debug2("read_server_config: filename %s", filename);
925         f = fopen(filename, "r");
926         if (!f) {
927                 perror(filename);
928                 exit(1);
929         }
930         linenum = 0;
931         while (fgets(line, sizeof(line), f)) {
932                 /* Update line number counter. */
933                 linenum++;
934                 if (process_server_config_line(options, line, filename, linenum) != 0)
935                         bad_options++;
936         }
937         fclose(f);
938         if (bad_options > 0)
939                 fatal("%s: terminating, %d bad configuration options",
940                     filename, bad_options);
941 }
This page took 0.323873 seconds and 5 git commands to generate.