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