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