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