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