5 * Author: Tatu Ylonen <ylo@cs.hut.fi>
7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
10 * Created: Mon Aug 21 15:48:58 1995 ylo
15 RCSID("$OpenBSD: servconf.c,v 1.47 2000/07/10 16:30:25 ho Exp $");
22 /* add listen address */
23 void add_listen_addr(ServerOptions *options, char *addr);
25 /* Initializes the server options to their default values. */
28 initialize_server_options(ServerOptions *options)
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;
57 options->kerberos_authentication = -1;
58 options->kerberos_or_local_passwd = -1;
59 options->kerberos_ticket_cleanup = -1;
62 options->kerberos_tgt_passing = -1;
63 options->afs_token_passing = -1;
65 options->password_authentication = -1;
67 options->skey_authentication = -1;
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;
83 fill_default_server_options(ServerOptions *options)
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;
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;
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;
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();
149 if (options->password_authentication == -1)
150 options->password_authentication = 1;
152 if (options->skey_authentication == -1)
153 options->skey_authentication = 1;
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;
167 #define WHITESPACE " \t\r\n="
169 /* Keyword tokens. */
171 sBadOption, /* == unknown option */
172 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
173 sPermitRootLogin, sLogFacility, sLogLevel,
174 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
176 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
179 sKerberosTgtPassing, sAFSTokenPassing,
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
192 /* Textual representation of the tokens. */
195 ServerOpCodes opcode;
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 },
212 { "kerberosauthentication", sKerberosAuthentication },
213 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
214 { "kerberosticketcleanup", sKerberosTicketCleanup },
217 { "kerberostgtpassing", sKerberosTgtPassing },
218 { "afstokenpassing", sAFSTokenPassing },
220 { "passwordauthentication", sPasswordAuthentication },
222 { "skeyauthentication", sSkeyAuthentication },
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 },
250 * Returns the number of the token pointed to by cp of length len. Never
251 * returns if the token is not known.
255 parse_token(const char *cp, const char *filename,
260 for (i = 0; keywords[i].name; i++)
261 if (strcasecmp(cp, keywords[i].name) == 0)
262 return keywords[i].opcode;
264 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
265 filename, linenum, cp);
273 add_listen_addr(ServerOptions *options, char *addr)
276 struct addrinfo hints, *ai, *aitop;
277 char strport[NI_MAXSERV];
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)
295 ai->ai_next = options->listen_addrs;
296 options->listen_addrs = aitop;
300 /* Reads the server configuration file. */
303 read_server_config(ServerOptions *options, const char *filename)
307 char *cp, **charptr, *arg;
308 int linenum, *intptr, value;
310 ServerOpCodes opcode;
313 f = fopen(filename, "r");
319 while (fgets(line, sizeof(line), f)) {
321 cp = line + strspn(line, WHITESPACE);
322 if (!*cp || *cp == '#')
324 arg = strsep(&cp, WHITESPACE);
325 opcode = parse_token(arg, filename, linenum);
331 /* ignore ports from configfile if cmdline specifies ports */
332 if (options->ports_from_cmdline)
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",
340 arg = strsep(&cp, WHITESPACE);
341 if (!arg || *arg == '\0')
342 fatal("%s line %d: missing port number.\n",
344 options->ports[options->num_ports++] = atoi(arg);
348 intptr = &options->server_key_bits;
350 arg = strsep(&cp, WHITESPACE);
351 if (!arg || *arg == '\0') {
352 fprintf(stderr, "%s line %d: missing integer value.\n",
361 case sLoginGraceTime:
362 intptr = &options->login_grace_time;
365 case sKeyRegenerationTime:
366 intptr = &options->key_regeneration_time;
370 arg = strsep(&cp, WHITESPACE);
371 if (!arg || *arg == '\0')
372 fatal("%s line %d: missing inet addr.\n",
374 add_listen_addr(options, arg);
378 case sHostDSAKeyFile:
379 charptr = (opcode == sHostKeyFile ) ?
380 &options->host_key_file : &options->host_dsa_key_file;
382 arg = strsep(&cp, WHITESPACE);
383 if (!arg || *arg == '\0') {
384 fprintf(stderr, "%s line %d: missing file name.\n",
388 if (*charptr == NULL)
389 *charptr = tilde_expand_filename(arg, getuid());
393 charptr = &options->pid_file;
396 case sRandomSeedFile:
397 fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
399 arg = strsep(&cp, WHITESPACE);
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",
410 if (strcmp(arg, "without-password") == 0)
412 else if (strcmp(arg, "yes") == 0)
414 else if (strcmp(arg, "no") == 0)
417 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
418 filename, linenum, arg);
426 intptr = &options->ignore_rhosts;
428 arg = strsep(&cp, WHITESPACE);
429 if (!arg || *arg == '\0') {
430 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
434 if (strcmp(arg, "yes") == 0)
436 else if (strcmp(arg, "no") == 0)
439 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
440 filename, linenum, arg);
447 case sIgnoreUserKnownHosts:
448 intptr = &options->ignore_user_known_hosts;
451 case sRhostsAuthentication:
452 intptr = &options->rhosts_authentication;
455 case sRhostsRSAAuthentication:
456 intptr = &options->rhosts_rsa_authentication;
459 case sRSAAuthentication:
460 intptr = &options->rsa_authentication;
463 case sDSAAuthentication:
464 intptr = &options->dsa_authentication;
468 case sKerberosAuthentication:
469 intptr = &options->kerberos_authentication;
472 case sKerberosOrLocalPasswd:
473 intptr = &options->kerberos_or_local_passwd;
476 case sKerberosTicketCleanup:
477 intptr = &options->kerberos_ticket_cleanup;
482 case sKerberosTgtPassing:
483 intptr = &options->kerberos_tgt_passing;
486 case sAFSTokenPassing:
487 intptr = &options->afs_token_passing;
491 case sPasswordAuthentication:
492 intptr = &options->password_authentication;
496 intptr = &options->check_mail;
500 case sSkeyAuthentication:
501 intptr = &options->skey_authentication;
506 intptr = &options->print_motd;
510 intptr = &options->x11_forwarding;
513 case sX11DisplayOffset:
514 intptr = &options->x11_display_offset;
518 charptr = &options->xauth_location;
522 intptr = &options->strict_modes;
526 intptr = &options->keepalives;
530 intptr = &options->permit_empty_passwd;
534 intptr = &options->use_login;
538 intptr = &options->gateway_ports;
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>");
549 *intptr = (SyslogFacility) value;
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>");
560 *intptr = (LogLevel) value;
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",
568 options->allow_users[options->num_allow_users++] = xstrdup(arg);
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",
577 options->deny_users[options->num_deny_users++] = xstrdup(arg);
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",
586 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
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",
595 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
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);
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)
624 if(options->num_subsystems >= MAX_SUBSYSTEMS) {
625 fatal("%s line %d: too many subsystems defined.",
628 arg = strsep(&cp, WHITESPACE);
629 if (!arg || *arg == '\0')
630 fatal("%s line %d: Missing subsystem name.",
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.",
641 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
642 options->num_subsystems++;
646 intptr = &options->max_startups;
650 fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
651 filename, linenum, arg, opcode);
654 if ((arg = strsep(&cp, WHITESPACE)) != NULL && *arg != '\0') {
656 "%s line %d: garbage at end of line; \"%.200s\".\n",
657 filename, linenum, arg);
662 if (bad_options > 0) {
663 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
664 filename, bad_options);