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