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