]> andersk Git - openssh.git/blob - servconf.c
- stevesk@cvs.openbsd.org 2001/03/25 13:16:11
[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.72 2001/03/25 13:16:10 stevesk Exp $");
14
15 #ifdef KRB4
16 #include <krb.h>
17 #endif
18 #ifdef AFS
19 #include <kafs.h>
20 #endif
21
22 #include "ssh.h"
23 #include "log.h"
24 #include "servconf.h"
25 #include "xmalloc.h"
26 #include "compat.h"
27 #include "pathnames.h"
28 #include "tildexpand.h"
29 #include "misc.h"
30 #include "cipher.h"
31 #include "kex.h"
32 #include "mac.h"
33
34 /* add listen address */
35 void add_listen_addr(ServerOptions *options, char *addr);
36
37 /* AF_UNSPEC or AF_INET or AF_INET6 */
38 extern int IPv4or6;
39
40 /* Initializes the server options to their default values. */
41
42 void
43 initialize_server_options(ServerOptions *options)
44 {
45         memset(options, 0, sizeof(*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->check_mail = -1;
60         options->x11_forwarding = -1;
61         options->x11_display_offset = -1;
62         options->xauth_location = NULL;
63         options->strict_modes = -1;
64         options->keepalives = -1;
65         options->log_facility = (SyslogFacility) - 1;
66         options->log_level = (LogLevel) - 1;
67         options->rhosts_authentication = -1;
68         options->rhosts_rsa_authentication = -1;
69         options->rsa_authentication = -1;
70         options->pubkey_authentication = -1;
71 #ifdef KRB4
72         options->kerberos_authentication = -1;
73         options->kerberos_or_local_passwd = -1;
74         options->kerberos_ticket_cleanup = -1;
75 #endif
76 #ifdef AFS
77         options->kerberos_tgt_passing = -1;
78         options->afs_token_passing = -1;
79 #endif
80         options->password_authentication = -1;
81         options->kbd_interactive_authentication = -1;
82         options->challenge_reponse_authentication = -1;
83         options->permit_empty_passwd = -1;
84         options->use_login = -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->reverse_mapping_check = -1;
100 }
101
102 void
103 fill_default_server_options(ServerOptions *options)
104 {
105         if (options->protocol == SSH_PROTO_UNKNOWN)
106                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
107         if (options->num_host_key_files == 0) {
108                 /* fill default hostkeys for protocols */
109                 if (options->protocol & SSH_PROTO_1)
110                         options->host_key_files[options->num_host_key_files++] = _PATH_HOST_KEY_FILE;
111                 if (options->protocol & SSH_PROTO_2)
112                         options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE;
113         }
114         if (options->num_ports == 0)
115                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
116         if (options->listen_addrs == NULL)
117                 add_listen_addr(options, NULL);
118         if (options->pid_file == NULL)
119                 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
120         if (options->server_key_bits == -1)
121                 options->server_key_bits = 768;
122         if (options->login_grace_time == -1)
123                 options->login_grace_time = 600;
124         if (options->key_regeneration_time == -1)
125                 options->key_regeneration_time = 3600;
126         if (options->permit_root_login == PERMIT_NOT_SET)
127                 options->permit_root_login = PERMIT_YES;
128         if (options->ignore_rhosts == -1)
129                 options->ignore_rhosts = 1;
130         if (options->ignore_user_known_hosts == -1)
131                 options->ignore_user_known_hosts = 0;
132         if (options->check_mail == -1)
133                 options->check_mail = 0;
134         if (options->print_motd == -1)
135                 options->print_motd = 1;
136         if (options->print_lastlog == -1)
137                 options->print_lastlog = 1;
138         if (options->x11_forwarding == -1)
139                 options->x11_forwarding = 0;
140         if (options->x11_display_offset == -1)
141                 options->x11_display_offset = 10;
142 #ifdef XAUTH_PATH
143         if (options->xauth_location == NULL)
144                 options->xauth_location = XAUTH_PATH;
145 #endif /* XAUTH_PATH */
146         if (options->strict_modes == -1)
147                 options->strict_modes = 1;
148         if (options->keepalives == -1)
149                 options->keepalives = 1;
150         if (options->log_facility == (SyslogFacility) (-1))
151                 options->log_facility = SYSLOG_FACILITY_AUTH;
152         if (options->log_level == (LogLevel) (-1))
153                 options->log_level = SYSLOG_LEVEL_INFO;
154         if (options->rhosts_authentication == -1)
155                 options->rhosts_authentication = 0;
156         if (options->rhosts_rsa_authentication == -1)
157                 options->rhosts_rsa_authentication = 0;
158         if (options->rsa_authentication == -1)
159                 options->rsa_authentication = 1;
160         if (options->pubkey_authentication == -1)
161                 options->pubkey_authentication = 1;
162 #ifdef KRB4
163         if (options->kerberos_authentication == -1)
164                 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
165         if (options->kerberos_or_local_passwd == -1)
166                 options->kerberos_or_local_passwd = 1;
167         if (options->kerberos_ticket_cleanup == -1)
168                 options->kerberos_ticket_cleanup = 1;
169 #endif /* KRB4 */
170 #ifdef AFS
171         if (options->kerberos_tgt_passing == -1)
172                 options->kerberos_tgt_passing = 0;
173         if (options->afs_token_passing == -1)
174                 options->afs_token_passing = k_hasafs();
175 #endif /* AFS */
176         if (options->password_authentication == -1)
177                 options->password_authentication = 1;
178         if (options->kbd_interactive_authentication == -1)
179                 options->kbd_interactive_authentication = 0;
180         if (options->challenge_reponse_authentication == -1)
181                 options->challenge_reponse_authentication = 1;
182         if (options->permit_empty_passwd == -1)
183                 options->permit_empty_passwd = 0;
184         if (options->use_login == -1)
185                 options->use_login = 0;
186         if (options->allow_tcp_forwarding == -1)
187                 options->allow_tcp_forwarding = 1;
188         if (options->gateway_ports == -1)
189                 options->gateway_ports = 0;
190         if (options->max_startups == -1)
191                 options->max_startups = 10;
192         if (options->max_startups_rate == -1)
193                 options->max_startups_rate = 100;               /* 100% */
194         if (options->max_startups_begin == -1)
195                 options->max_startups_begin = options->max_startups;
196         if (options->reverse_mapping_check == -1)
197                 options->reverse_mapping_check = 0;
198 }
199
200 /* Keyword tokens. */
201 typedef enum {
202         sBadOption,             /* == unknown option */
203         sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
204         sPermitRootLogin, sLogFacility, sLogLevel,
205         sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
206 #ifdef KRB4
207         sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
208 #endif
209 #ifdef AFS
210         sKerberosTgtPassing, sAFSTokenPassing,
211 #endif
212         sChallengeResponseAuthentication,
213         sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
214         sPrintMotd, sPrintLastLog, sIgnoreRhosts,
215         sX11Forwarding, sX11DisplayOffset,
216         sStrictModes, sEmptyPasswd, sKeepAlives, sCheckMail,
217         sUseLogin, sAllowTcpForwarding,
218         sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
219         sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
220         sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
221         sBanner, sReverseMappingCheck
222 } ServerOpCodes;
223
224 /* Textual representation of the tokens. */
225 static struct {
226         const char *name;
227         ServerOpCodes opcode;
228 } keywords[] = {
229         { "port", sPort },
230         { "hostkey", sHostKeyFile },
231         { "hostdsakey", sHostKeyFile },                                 /* alias */
232         { "pidfile", sPidFile },
233         { "serverkeybits", sServerKeyBits },
234         { "logingracetime", sLoginGraceTime },
235         { "keyregenerationinterval", sKeyRegenerationTime },
236         { "permitrootlogin", sPermitRootLogin },
237         { "syslogfacility", sLogFacility },
238         { "loglevel", sLogLevel },
239         { "rhostsauthentication", sRhostsAuthentication },
240         { "rhostsrsaauthentication", sRhostsRSAAuthentication },
241         { "rsaauthentication", sRSAAuthentication },
242         { "pubkeyauthentication", sPubkeyAuthentication },
243         { "dsaauthentication", sPubkeyAuthentication },                 /* alias */
244 #ifdef KRB4
245         { "kerberosauthentication", sKerberosAuthentication },
246         { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
247         { "kerberosticketcleanup", sKerberosTicketCleanup },
248 #endif
249 #ifdef AFS
250         { "kerberostgtpassing", sKerberosTgtPassing },
251         { "afstokenpassing", sAFSTokenPassing },
252 #endif
253         { "passwordauthentication", sPasswordAuthentication },
254         { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
255         { "challengeresponseauthentication", sChallengeResponseAuthentication },
256         { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
257         { "checkmail", sCheckMail },
258         { "listenaddress", sListenAddress },
259         { "printmotd", sPrintMotd },
260         { "printlastlog", sPrintLastLog },
261         { "ignorerhosts", sIgnoreRhosts },
262         { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
263         { "x11forwarding", sX11Forwarding },
264         { "x11displayoffset", sX11DisplayOffset },
265         { "xauthlocation", sXAuthLocation },
266         { "strictmodes", sStrictModes },
267         { "permitemptypasswords", sEmptyPasswd },
268         { "uselogin", sUseLogin },
269         { "keepalive", sKeepAlives },
270         { "allowtcpforwarding", sAllowTcpForwarding },
271         { "allowusers", sAllowUsers },
272         { "denyusers", sDenyUsers },
273         { "allowgroups", sAllowGroups },
274         { "denygroups", sDenyGroups },
275         { "ciphers", sCiphers },
276         { "macs", sMacs },
277         { "protocol", sProtocol },
278         { "gatewayports", sGatewayPorts },
279         { "subsystem", sSubsystem },
280         { "maxstartups", sMaxStartups },
281         { "banner", sBanner },
282         { "reversemappingcheck", sReverseMappingCheck },
283         { NULL, 0 }
284 };
285
286 /*
287  * Returns the number of the token pointed to by cp of length len. Never
288  * returns if the token is not known.
289  */
290
291 static ServerOpCodes
292 parse_token(const char *cp, const char *filename,
293             int linenum)
294 {
295         u_int i;
296
297         for (i = 0; keywords[i].name; i++)
298                 if (strcasecmp(cp, keywords[i].name) == 0)
299                         return keywords[i].opcode;
300
301         fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
302                 filename, linenum, cp);
303         return sBadOption;
304 }
305
306 /*
307  * add listen address
308  */
309 void
310 add_listen_addr(ServerOptions *options, char *addr)
311 {
312         struct addrinfo hints, *ai, *aitop;
313         char strport[NI_MAXSERV];
314         int gaierr;
315         int i;
316
317         if (options->num_ports == 0)
318                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
319         for (i = 0; i < options->num_ports; i++) {
320                 memset(&hints, 0, sizeof(hints));
321                 hints.ai_family = IPv4or6;
322                 hints.ai_socktype = SOCK_STREAM;
323                 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
324                 snprintf(strport, sizeof strport, "%d", options->ports[i]);
325                 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
326                         fatal("bad addr or host: %s (%s)",
327                             addr ? addr : "<NULL>",
328                             gai_strerror(gaierr));
329                 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
330                         ;
331                 ai->ai_next = options->listen_addrs;
332                 options->listen_addrs = aitop;
333         }
334 }
335
336 /* Reads the server configuration file. */
337
338 void
339 read_server_config(ServerOptions *options, const char *filename)
340 {
341         FILE *f;
342         char line[1024];
343         char *cp, **charptr, *arg;
344         int linenum, *intptr, value;
345         int bad_options = 0;
346         ServerOpCodes opcode;
347         int i;
348
349         f = fopen(filename, "r");
350         if (!f) {
351                 perror(filename);
352                 exit(1);
353         }
354         linenum = 0;
355         while (fgets(line, sizeof(line), f)) {
356                 linenum++;
357                 cp = line;
358                 arg = strdelim(&cp);
359                 /* Ignore leading whitespace */
360                 if (*arg == '\0')
361                         arg = strdelim(&cp);
362                 if (!arg || !*arg || *arg == '#')
363                         continue;
364                 intptr = NULL;
365                 charptr = NULL;
366                 opcode = parse_token(arg, filename, linenum);
367                 switch (opcode) {
368                 case sBadOption:
369                         bad_options++;
370                         continue;
371                 case sPort:
372                         /* ignore ports from configfile if cmdline specifies ports */
373                         if (options->ports_from_cmdline)
374                                 continue;
375                         if (options->listen_addrs != NULL)
376                                 fatal("%s line %d: ports must be specified before "
377                                     "ListenAdress.\n", filename, linenum);
378                         if (options->num_ports >= MAX_PORTS)
379                                 fatal("%s line %d: too many ports.",
380                                     filename, linenum);
381                         arg = strdelim(&cp);
382                         if (!arg || *arg == '\0')
383                                 fatal("%s line %d: missing port number.",
384                                     filename, linenum);
385                         options->ports[options->num_ports++] = atoi(arg);
386                         break;
387
388                 case sServerKeyBits:
389                         intptr = &options->server_key_bits;
390 parse_int:
391                         arg = strdelim(&cp);
392                         if (!arg || *arg == '\0') {
393                                 fprintf(stderr, "%s line %d: missing integer value.\n",
394                                         filename, linenum);
395                                 exit(1);
396                         }
397                         value = atoi(arg);
398                         if (*intptr == -1)
399                                 *intptr = value;
400                         break;
401
402                 case sLoginGraceTime:
403                         intptr = &options->login_grace_time;
404                         goto parse_int;
405
406                 case sKeyRegenerationTime:
407                         intptr = &options->key_regeneration_time;
408                         goto parse_int;
409
410                 case sListenAddress:
411                         arg = strdelim(&cp);
412                         if (!arg || *arg == '\0')
413                                 fatal("%s line %d: missing inet addr.",
414                                     filename, linenum);
415                         add_listen_addr(options, arg);
416                         break;
417
418                 case sHostKeyFile:
419                         intptr = &options->num_host_key_files;
420                         if (*intptr >= MAX_HOSTKEYS) {
421                                 fprintf(stderr,
422                                     "%s line %d: too many host keys specified (max %d).\n",
423                                     filename, linenum, MAX_HOSTKEYS);
424                                 exit(1);
425                         }
426                         charptr = &options->host_key_files[*intptr];
427 parse_filename:
428                         arg = strdelim(&cp);
429                         if (!arg || *arg == '\0') {
430                                 fprintf(stderr, "%s line %d: missing file name.\n",
431                                     filename, linenum);
432                                 exit(1);
433                         }
434                         if (*charptr == NULL) {
435                                 *charptr = tilde_expand_filename(arg, getuid());
436                                 /* increase optional counter */
437                                 if (intptr != NULL)
438                                         *intptr = *intptr + 1;
439                         }
440                         break;
441
442                 case sPidFile:
443                         charptr = &options->pid_file;
444                         goto parse_filename;
445
446                 case sPermitRootLogin:
447                         intptr = &options->permit_root_login;
448                         arg = strdelim(&cp);
449                         if (!arg || *arg == '\0') {
450                                 fprintf(stderr, "%s line %d: missing yes/"
451                                     "without-password/forced-commands-only/no "
452                                     "argument.\n", filename, linenum);
453                                 exit(1);
454                         }
455                         if (strcmp(arg, "without-password") == 0)
456                                 value = PERMIT_NO_PASSWD;
457                         else if (strcmp(arg, "forced-commands-only") == 0)
458                                 value = PERMIT_FORCED_ONLY;
459                         else if (strcmp(arg, "yes") == 0)
460                                 value = PERMIT_YES;
461                         else if (strcmp(arg, "no") == 0)
462                                 value = PERMIT_NO;
463                         else {
464                                 fprintf(stderr, "%s line %d: Bad yes/"
465                                     "without-password/forced-commands-only/no "
466                                     "argument: %s\n", filename, linenum, arg);
467                                 exit(1);
468                         }
469                         if (*intptr == -1)
470                                 *intptr = value;
471                         break;
472
473                 case sIgnoreRhosts:
474                         intptr = &options->ignore_rhosts;
475 parse_flag:
476                         arg = strdelim(&cp);
477                         if (!arg || *arg == '\0') {
478                                 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
479                                         filename, linenum);
480                                 exit(1);
481                         }
482                         if (strcmp(arg, "yes") == 0)
483                                 value = 1;
484                         else if (strcmp(arg, "no") == 0)
485                                 value = 0;
486                         else {
487                                 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
488                                         filename, linenum, arg);
489                                 exit(1);
490                         }
491                         if (*intptr == -1)
492                                 *intptr = value;
493                         break;
494
495                 case sIgnoreUserKnownHosts:
496                         intptr = &options->ignore_user_known_hosts;
497                         goto parse_flag;
498
499                 case sRhostsAuthentication:
500                         intptr = &options->rhosts_authentication;
501                         goto parse_flag;
502
503                 case sRhostsRSAAuthentication:
504                         intptr = &options->rhosts_rsa_authentication;
505                         goto parse_flag;
506
507                 case sRSAAuthentication:
508                         intptr = &options->rsa_authentication;
509                         goto parse_flag;
510
511                 case sPubkeyAuthentication:
512                         intptr = &options->pubkey_authentication;
513                         goto parse_flag;
514
515 #ifdef KRB4
516                 case sKerberosAuthentication:
517                         intptr = &options->kerberos_authentication;
518                         goto parse_flag;
519
520                 case sKerberosOrLocalPasswd:
521                         intptr = &options->kerberos_or_local_passwd;
522                         goto parse_flag;
523
524                 case sKerberosTicketCleanup:
525                         intptr = &options->kerberos_ticket_cleanup;
526                         goto parse_flag;
527 #endif
528
529 #ifdef AFS
530                 case sKerberosTgtPassing:
531                         intptr = &options->kerberos_tgt_passing;
532                         goto parse_flag;
533
534                 case sAFSTokenPassing:
535                         intptr = &options->afs_token_passing;
536                         goto parse_flag;
537 #endif
538
539                 case sPasswordAuthentication:
540                         intptr = &options->password_authentication;
541                         goto parse_flag;
542
543                 case sKbdInteractiveAuthentication:
544                         intptr = &options->kbd_interactive_authentication;
545                         goto parse_flag;
546
547                 case sCheckMail:
548                         intptr = &options->check_mail;
549                         goto parse_flag;
550
551                 case sChallengeResponseAuthentication:
552                         intptr = &options->challenge_reponse_authentication;
553                         goto parse_flag;
554
555                 case sPrintMotd:
556                         intptr = &options->print_motd;
557                         goto parse_flag;
558
559                 case sPrintLastLog:
560                         intptr = &options->print_lastlog;
561                         goto parse_flag;
562
563                 case sX11Forwarding:
564                         intptr = &options->x11_forwarding;
565                         goto parse_flag;
566
567                 case sX11DisplayOffset:
568                         intptr = &options->x11_display_offset;
569                         goto parse_int;
570
571                 case sXAuthLocation:
572                         charptr = &options->xauth_location;
573                         goto parse_filename;
574
575                 case sStrictModes:
576                         intptr = &options->strict_modes;
577                         goto parse_flag;
578
579                 case sKeepAlives:
580                         intptr = &options->keepalives;
581                         goto parse_flag;
582
583                 case sEmptyPasswd:
584                         intptr = &options->permit_empty_passwd;
585                         goto parse_flag;
586
587                 case sUseLogin:
588                         intptr = &options->use_login;
589                         goto parse_flag;
590
591                 case sGatewayPorts:
592                         intptr = &options->gateway_ports;
593                         goto parse_flag;
594
595                 case sReverseMappingCheck:
596                         intptr = &options->reverse_mapping_check;
597                         goto parse_flag;
598
599                 case sLogFacility:
600                         intptr = (int *) &options->log_facility;
601                         arg = strdelim(&cp);
602                         value = log_facility_number(arg);
603                         if (value == (SyslogFacility) - 1)
604                                 fatal("%.200s line %d: unsupported log facility '%s'",
605                                     filename, linenum, arg ? arg : "<NONE>");
606                         if (*intptr == -1)
607                                 *intptr = (SyslogFacility) value;
608                         break;
609
610                 case sLogLevel:
611                         intptr = (int *) &options->log_level;
612                         arg = strdelim(&cp);
613                         value = log_level_number(arg);
614                         if (value == (LogLevel) - 1)
615                                 fatal("%.200s line %d: unsupported log level '%s'",
616                                     filename, linenum, arg ? arg : "<NONE>");
617                         if (*intptr == -1)
618                                 *intptr = (LogLevel) value;
619                         break;
620
621                 case sAllowTcpForwarding:
622                         intptr = &options->allow_tcp_forwarding;
623                         goto parse_flag;
624
625                 case sAllowUsers:
626                         while ((arg = strdelim(&cp)) && *arg != '\0') {
627                                 if (options->num_allow_users >= MAX_ALLOW_USERS)
628                                         fatal("%s line %d: too many allow users.",
629                                             filename, linenum);
630                                 options->allow_users[options->num_allow_users++] = xstrdup(arg);
631                         }
632                         break;
633
634                 case sDenyUsers:
635                         while ((arg = strdelim(&cp)) && *arg != '\0') {
636                                 if (options->num_deny_users >= MAX_DENY_USERS)
637                                         fatal( "%s line %d: too many deny users.",
638                                             filename, linenum);
639                                 options->deny_users[options->num_deny_users++] = xstrdup(arg);
640                         }
641                         break;
642
643                 case sAllowGroups:
644                         while ((arg = strdelim(&cp)) && *arg != '\0') {
645                                 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
646                                         fatal("%s line %d: too many allow groups.",
647                                             filename, linenum);
648                                 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
649                         }
650                         break;
651
652                 case sDenyGroups:
653                         while ((arg = strdelim(&cp)) && *arg != '\0') {
654                                 if (options->num_deny_groups >= MAX_DENY_GROUPS)
655                                         fatal("%s line %d: too many deny groups.",
656                                             filename, linenum);
657                                 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
658                         }
659                         break;
660
661                 case sCiphers:
662                         arg = strdelim(&cp);
663                         if (!arg || *arg == '\0')
664                                 fatal("%s line %d: Missing argument.", filename, linenum);
665                         if (!ciphers_valid(arg))
666                                 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
667                                     filename, linenum, arg ? arg : "<NONE>");
668                         if (options->ciphers == NULL)
669                                 options->ciphers = xstrdup(arg);
670                         break;
671
672                 case sMacs:
673                         arg = strdelim(&cp);
674                         if (!arg || *arg == '\0')
675                                 fatal("%s line %d: Missing argument.", filename, linenum);
676                         if (!mac_valid(arg))
677                                 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
678                                     filename, linenum, arg ? arg : "<NONE>");
679                         if (options->macs == NULL)
680                                 options->macs = xstrdup(arg);
681                         break;
682
683                 case sProtocol:
684                         intptr = &options->protocol;
685                         arg = strdelim(&cp);
686                         if (!arg || *arg == '\0')
687                                 fatal("%s line %d: Missing argument.", filename, linenum);
688                         value = proto_spec(arg);
689                         if (value == SSH_PROTO_UNKNOWN)
690                                 fatal("%s line %d: Bad protocol spec '%s'.",
691                                       filename, linenum, arg ? arg : "<NONE>");
692                         if (*intptr == SSH_PROTO_UNKNOWN)
693                                 *intptr = value;
694                         break;
695
696                 case sSubsystem:
697                         if(options->num_subsystems >= MAX_SUBSYSTEMS) {
698                                 fatal("%s line %d: too many subsystems defined.",
699                                       filename, linenum);
700                         }
701                         arg = strdelim(&cp);
702                         if (!arg || *arg == '\0')
703                                 fatal("%s line %d: Missing subsystem name.",
704                                       filename, linenum);
705                         for (i = 0; i < options->num_subsystems; i++)
706                                 if(strcmp(arg, options->subsystem_name[i]) == 0)
707                                         fatal("%s line %d: Subsystem '%s' already defined.",
708                                               filename, linenum, arg);
709                         options->subsystem_name[options->num_subsystems] = xstrdup(arg);
710                         arg = strdelim(&cp);
711                         if (!arg || *arg == '\0')
712                                 fatal("%s line %d: Missing subsystem command.",
713                                       filename, linenum);
714                         options->subsystem_command[options->num_subsystems] = xstrdup(arg);
715                         options->num_subsystems++;
716                         break;
717
718                 case sMaxStartups:
719                         arg = strdelim(&cp);
720                         if (!arg || *arg == '\0')
721                                 fatal("%s line %d: Missing MaxStartups spec.",
722                                       filename, linenum);
723                         if (sscanf(arg, "%d:%d:%d",
724                             &options->max_startups_begin,
725                             &options->max_startups_rate,
726                             &options->max_startups) == 3) {
727                                 if (options->max_startups_begin >
728                                     options->max_startups ||
729                                     options->max_startups_rate > 100 ||
730                                     options->max_startups_rate < 1)
731                                 fatal("%s line %d: Illegal MaxStartups spec.",
732                                       filename, linenum);
733                                 break;
734                         }
735                         intptr = &options->max_startups;
736                         goto parse_int;
737
738                 case sBanner:
739                         charptr = &options->banner;
740                         goto parse_filename;
741
742                 default:
743                         fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
744                                 filename, linenum, arg, opcode);
745                         exit(1);
746                 }
747                 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
748                         fprintf(stderr,
749                                 "%s line %d: garbage at end of line; \"%.200s\".\n",
750                                 filename, linenum, arg);
751                         exit(1);
752                 }
753         }
754         fclose(f);
755         if (bad_options > 0) {
756                 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
757                         filename, bad_options);
758                 exit(1);
759         }
760 }
This page took 0.105556 seconds and 5 git commands to generate.