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