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