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