2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * As far as I am concerned, the code I have written for this software
6 * can be used freely for any purpose. Any derived versions of this
7 * software must be clearly marked as such, and if the derived work is
8 * incompatible with the protocol description in the RFC file, it must be
9 * called by a name other than "ssh" or "Secure Shell".
13 RCSID("$OpenBSD: servconf.c,v 1.53 2000/10/14 12:12:09 markus Exp $");
20 /* add listen address */
21 void add_listen_addr(ServerOptions *options, char *addr);
23 /* Initializes the server options to their default values. */
26 initialize_server_options(ServerOptions *options)
28 memset(options, 0, sizeof(*options));
29 options->num_ports = 0;
30 options->ports_from_cmdline = 0;
31 options->listen_addrs = NULL;
32 options->host_key_file = NULL;
33 options->host_dsa_key_file = NULL;
34 options->pid_file = NULL;
35 options->server_key_bits = -1;
36 options->login_grace_time = -1;
37 options->key_regeneration_time = -1;
38 options->permit_root_login = -1;
39 options->ignore_rhosts = -1;
40 options->ignore_user_known_hosts = -1;
41 options->print_motd = -1;
42 options->check_mail = -1;
43 options->x11_forwarding = -1;
44 options->x11_display_offset = -1;
45 options->xauth_location = NULL;
46 options->strict_modes = -1;
47 options->keepalives = -1;
48 options->log_facility = (SyslogFacility) - 1;
49 options->log_level = (LogLevel) - 1;
50 options->rhosts_authentication = -1;
51 options->rhosts_rsa_authentication = -1;
52 options->rsa_authentication = -1;
53 options->dsa_authentication = -1;
55 options->kerberos_authentication = -1;
56 options->kerberos_or_local_passwd = -1;
57 options->kerberos_ticket_cleanup = -1;
60 options->kerberos_tgt_passing = -1;
61 options->afs_token_passing = -1;
63 options->password_authentication = -1;
64 options->kbd_interactive_authentication = -1;
66 options->skey_authentication = -1;
68 options->permit_empty_passwd = -1;
69 options->use_login = -1;
70 options->allow_tcp_forwarding = -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_begin = -1;
80 options->max_startups_rate = -1;
81 options->max_startups = -1;
85 fill_default_server_options(ServerOptions *options)
87 if (options->num_ports == 0)
88 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
89 if (options->listen_addrs == NULL)
90 add_listen_addr(options, NULL);
91 if (options->host_key_file == NULL)
92 options->host_key_file = HOST_KEY_FILE;
93 if (options->host_dsa_key_file == NULL)
94 options->host_dsa_key_file = HOST_DSA_KEY_FILE;
95 if (options->pid_file == NULL)
96 options->pid_file = SSH_DAEMON_PID_FILE;
97 if (options->server_key_bits == -1)
98 options->server_key_bits = 768;
99 if (options->login_grace_time == -1)
100 options->login_grace_time = 600;
101 if (options->key_regeneration_time == -1)
102 options->key_regeneration_time = 3600;
103 if (options->permit_root_login == -1)
104 options->permit_root_login = 1; /* yes */
105 if (options->ignore_rhosts == -1)
106 options->ignore_rhosts = 1;
107 if (options->ignore_user_known_hosts == -1)
108 options->ignore_user_known_hosts = 0;
109 if (options->check_mail == -1)
110 options->check_mail = 0;
111 if (options->print_motd == -1)
112 options->print_motd = 1;
113 if (options->x11_forwarding == -1)
114 options->x11_forwarding = 0;
115 if (options->x11_display_offset == -1)
116 options->x11_display_offset = 10;
118 if (options->xauth_location == NULL)
119 options->xauth_location = XAUTH_PATH;
120 #endif /* XAUTH_PATH */
121 if (options->strict_modes == -1)
122 options->strict_modes = 1;
123 if (options->keepalives == -1)
124 options->keepalives = 1;
125 if (options->log_facility == (SyslogFacility) (-1))
126 options->log_facility = SYSLOG_FACILITY_AUTH;
127 if (options->log_level == (LogLevel) (-1))
128 options->log_level = SYSLOG_LEVEL_INFO;
129 if (options->rhosts_authentication == -1)
130 options->rhosts_authentication = 0;
131 if (options->rhosts_rsa_authentication == -1)
132 options->rhosts_rsa_authentication = 0;
133 if (options->rsa_authentication == -1)
134 options->rsa_authentication = 1;
135 if (options->dsa_authentication == -1)
136 options->dsa_authentication = 1;
138 if (options->kerberos_authentication == -1)
139 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
140 if (options->kerberos_or_local_passwd == -1)
141 options->kerberos_or_local_passwd = 1;
142 if (options->kerberos_ticket_cleanup == -1)
143 options->kerberos_ticket_cleanup = 1;
146 if (options->kerberos_tgt_passing == -1)
147 options->kerberos_tgt_passing = 0;
148 if (options->afs_token_passing == -1)
149 options->afs_token_passing = k_hasafs();
151 if (options->password_authentication == -1)
152 options->password_authentication = 1;
153 if (options->kbd_interactive_authentication == -1)
154 options->kbd_interactive_authentication = 0;
156 if (options->skey_authentication == -1)
157 options->skey_authentication = 1;
159 if (options->permit_empty_passwd == -1)
160 options->permit_empty_passwd = 0;
161 if (options->use_login == -1)
162 options->use_login = 0;
163 if (options->allow_tcp_forwarding == -1)
164 options->allow_tcp_forwarding = 1;
165 if (options->protocol == SSH_PROTO_UNKNOWN)
166 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
167 if (options->gateway_ports == -1)
168 options->gateway_ports = 0;
169 if (options->max_startups == -1)
170 options->max_startups = 10;
171 if (options->max_startups_rate == -1)
172 options->max_startups_rate = 100; /* 100% */
173 if (options->max_startups_begin == -1)
174 options->max_startups_begin = options->max_startups;
177 /* Keyword tokens. */
179 sBadOption, /* == unknown option */
180 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
181 sPermitRootLogin, sLogFacility, sLogLevel,
182 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
184 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
187 sKerberosTgtPassing, sAFSTokenPassing,
192 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
193 sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
194 sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
195 sUseLogin, sAllowTcpForwarding,
196 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
197 sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
198 sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups
201 /* Textual representation of the tokens. */
204 ServerOpCodes opcode;
207 { "hostkey", sHostKeyFile },
208 { "hostdsakey", sHostDSAKeyFile },
209 { "pidfile", sPidFile },
210 { "serverkeybits", sServerKeyBits },
211 { "logingracetime", sLoginGraceTime },
212 { "keyregenerationinterval", sKeyRegenerationTime },
213 { "permitrootlogin", sPermitRootLogin },
214 { "syslogfacility", sLogFacility },
215 { "loglevel", sLogLevel },
216 { "rhostsauthentication", sRhostsAuthentication },
217 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
218 { "rsaauthentication", sRSAAuthentication },
219 { "dsaauthentication", sDSAAuthentication },
221 { "kerberosauthentication", sKerberosAuthentication },
222 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
223 { "kerberosticketcleanup", sKerberosTicketCleanup },
226 { "kerberostgtpassing", sKerberosTgtPassing },
227 { "afstokenpassing", sAFSTokenPassing },
229 { "passwordauthentication", sPasswordAuthentication },
230 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
232 { "skeyauthentication", sSkeyAuthentication },
234 { "checkmail", sCheckMail },
235 { "listenaddress", sListenAddress },
236 { "printmotd", sPrintMotd },
237 { "ignorerhosts", sIgnoreRhosts },
238 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
239 { "x11forwarding", sX11Forwarding },
240 { "x11displayoffset", sX11DisplayOffset },
241 { "xauthlocation", sXAuthLocation },
242 { "strictmodes", sStrictModes },
243 { "permitemptypasswords", sEmptyPasswd },
244 { "uselogin", sUseLogin },
245 { "randomseed", sRandomSeedFile },
246 { "keepalive", sKeepAlives },
247 { "allowtcpforwarding", sAllowTcpForwarding },
248 { "allowusers", sAllowUsers },
249 { "denyusers", sDenyUsers },
250 { "allowgroups", sAllowGroups },
251 { "denygroups", sDenyGroups },
252 { "ciphers", sCiphers },
253 { "protocol", sProtocol },
254 { "gatewayports", sGatewayPorts },
255 { "subsystem", sSubsystem },
256 { "maxstartups", sMaxStartups },
261 * Returns the number of the token pointed to by cp of length len. Never
262 * returns if the token is not known.
266 parse_token(const char *cp, const char *filename,
271 for (i = 0; keywords[i].name; i++)
272 if (strcasecmp(cp, keywords[i].name) == 0)
273 return keywords[i].opcode;
275 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
276 filename, linenum, cp);
284 add_listen_addr(ServerOptions *options, char *addr)
287 struct addrinfo hints, *ai, *aitop;
288 char strport[NI_MAXSERV];
292 if (options->num_ports == 0)
293 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
294 for (i = 0; i < options->num_ports; i++) {
295 memset(&hints, 0, sizeof(hints));
296 hints.ai_family = IPv4or6;
297 hints.ai_socktype = SOCK_STREAM;
298 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
299 snprintf(strport, sizeof strport, "%d", options->ports[i]);
300 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
301 fatal("bad addr or host: %s (%s)\n",
302 addr ? addr : "<NULL>",
303 gai_strerror(gaierr));
304 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
306 ai->ai_next = options->listen_addrs;
307 options->listen_addrs = aitop;
311 /* Reads the server configuration file. */
314 read_server_config(ServerOptions *options, const char *filename)
318 char *cp, **charptr, *arg;
319 int linenum, *intptr, value;
321 ServerOpCodes opcode;
324 f = fopen(filename, "r");
330 while (fgets(line, sizeof(line), f)) {
334 /* Ignore leading whitespace */
337 if (!*arg || *arg == '#')
339 opcode = parse_token(arg, filename, linenum);
345 /* ignore ports from configfile if cmdline specifies ports */
346 if (options->ports_from_cmdline)
348 if (options->listen_addrs != NULL)
349 fatal("%s line %d: ports must be specified before "
350 "ListenAdress.\n", filename, linenum);
351 if (options->num_ports >= MAX_PORTS)
352 fatal("%s line %d: too many ports.\n",
355 if (!arg || *arg == '\0')
356 fatal("%s line %d: missing port number.\n",
358 options->ports[options->num_ports++] = atoi(arg);
362 intptr = &options->server_key_bits;
365 if (!arg || *arg == '\0') {
366 fprintf(stderr, "%s line %d: missing integer value.\n",
375 case sLoginGraceTime:
376 intptr = &options->login_grace_time;
379 case sKeyRegenerationTime:
380 intptr = &options->key_regeneration_time;
385 if (!arg || *arg == '\0')
386 fatal("%s line %d: missing inet addr.\n",
388 add_listen_addr(options, arg);
392 case sHostDSAKeyFile:
393 charptr = (opcode == sHostKeyFile ) ?
394 &options->host_key_file : &options->host_dsa_key_file;
397 if (!arg || *arg == '\0') {
398 fprintf(stderr, "%s line %d: missing file name.\n",
402 if (*charptr == NULL)
403 *charptr = tilde_expand_filename(arg, getuid());
407 charptr = &options->pid_file;
410 case sRandomSeedFile:
411 fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
416 case sPermitRootLogin:
417 intptr = &options->permit_root_login;
419 if (!arg || *arg == '\0') {
420 fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
424 if (strcmp(arg, "without-password") == 0)
426 else if (strcmp(arg, "yes") == 0)
428 else if (strcmp(arg, "no") == 0)
431 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
432 filename, linenum, arg);
440 intptr = &options->ignore_rhosts;
443 if (!arg || *arg == '\0') {
444 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
448 if (strcmp(arg, "yes") == 0)
450 else if (strcmp(arg, "no") == 0)
453 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
454 filename, linenum, arg);
461 case sIgnoreUserKnownHosts:
462 intptr = &options->ignore_user_known_hosts;
465 case sRhostsAuthentication:
466 intptr = &options->rhosts_authentication;
469 case sRhostsRSAAuthentication:
470 intptr = &options->rhosts_rsa_authentication;
473 case sRSAAuthentication:
474 intptr = &options->rsa_authentication;
477 case sDSAAuthentication:
478 intptr = &options->dsa_authentication;
482 case sKerberosAuthentication:
483 intptr = &options->kerberos_authentication;
486 case sKerberosOrLocalPasswd:
487 intptr = &options->kerberos_or_local_passwd;
490 case sKerberosTicketCleanup:
491 intptr = &options->kerberos_ticket_cleanup;
496 case sKerberosTgtPassing:
497 intptr = &options->kerberos_tgt_passing;
500 case sAFSTokenPassing:
501 intptr = &options->afs_token_passing;
505 case sPasswordAuthentication:
506 intptr = &options->password_authentication;
509 case sKbdInteractiveAuthentication:
510 intptr = &options->kbd_interactive_authentication;
514 intptr = &options->check_mail;
518 case sSkeyAuthentication:
519 intptr = &options->skey_authentication;
524 intptr = &options->print_motd;
528 intptr = &options->x11_forwarding;
531 case sX11DisplayOffset:
532 intptr = &options->x11_display_offset;
536 charptr = &options->xauth_location;
540 intptr = &options->strict_modes;
544 intptr = &options->keepalives;
548 intptr = &options->permit_empty_passwd;
552 intptr = &options->use_login;
556 intptr = &options->gateway_ports;
560 intptr = (int *) &options->log_facility;
562 value = log_facility_number(arg);
563 if (value == (SyslogFacility) - 1)
564 fatal("%.200s line %d: unsupported log facility '%s'\n",
565 filename, linenum, arg ? arg : "<NONE>");
567 *intptr = (SyslogFacility) value;
571 intptr = (int *) &options->log_level;
573 value = log_level_number(arg);
574 if (value == (LogLevel) - 1)
575 fatal("%.200s line %d: unsupported log level '%s'\n",
576 filename, linenum, arg ? arg : "<NONE>");
578 *intptr = (LogLevel) value;
581 case sAllowTcpForwarding:
582 intptr = &options->allow_tcp_forwarding;
586 while ((arg = strdelim(&cp)) && *arg != '\0') {
587 if (options->num_allow_users >= MAX_ALLOW_USERS)
588 fatal("%s line %d: too many allow users.\n",
590 options->allow_users[options->num_allow_users++] = xstrdup(arg);
595 while ((arg = strdelim(&cp)) && *arg != '\0') {
596 if (options->num_deny_users >= MAX_DENY_USERS)
597 fatal( "%s line %d: too many deny users.\n",
599 options->deny_users[options->num_deny_users++] = xstrdup(arg);
604 while ((arg = strdelim(&cp)) && *arg != '\0') {
605 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
606 fatal("%s line %d: too many allow groups.\n",
608 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
613 while ((arg = strdelim(&cp)) && *arg != '\0') {
614 if (options->num_deny_groups >= MAX_DENY_GROUPS)
615 fatal("%s line %d: too many deny groups.\n",
617 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
623 if (!arg || *arg == '\0')
624 fatal("%s line %d: Missing argument.", filename, linenum);
625 if (!ciphers_valid(arg))
626 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
627 filename, linenum, arg ? arg : "<NONE>");
628 if (options->ciphers == NULL)
629 options->ciphers = xstrdup(arg);
633 intptr = &options->protocol;
635 if (!arg || *arg == '\0')
636 fatal("%s line %d: Missing argument.", filename, linenum);
637 value = proto_spec(arg);
638 if (value == SSH_PROTO_UNKNOWN)
639 fatal("%s line %d: Bad protocol spec '%s'.",
640 filename, linenum, arg ? arg : "<NONE>");
641 if (*intptr == SSH_PROTO_UNKNOWN)
646 if(options->num_subsystems >= MAX_SUBSYSTEMS) {
647 fatal("%s line %d: too many subsystems defined.",
651 if (!arg || *arg == '\0')
652 fatal("%s line %d: Missing subsystem name.",
654 for (i = 0; i < options->num_subsystems; i++)
655 if(strcmp(arg, options->subsystem_name[i]) == 0)
656 fatal("%s line %d: Subsystem '%s' already defined.",
657 filename, linenum, arg);
658 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
660 if (!arg || *arg == '\0')
661 fatal("%s line %d: Missing subsystem command.",
663 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
664 options->num_subsystems++;
669 if (!arg || *arg == '\0')
670 fatal("%s line %d: Missing MaxStartups spec.",
672 if (sscanf(arg, "%d:%d:%d",
673 &options->max_startups_begin,
674 &options->max_startups_rate,
675 &options->max_startups) == 3) {
676 if (options->max_startups_begin >
677 options->max_startups ||
678 options->max_startups_rate > 100 ||
679 options->max_startups_rate < 1)
680 fatal("%s line %d: Illegal MaxStartups spec.",
684 intptr = &options->max_startups;
688 fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
689 filename, linenum, arg, opcode);
692 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
694 "%s line %d: garbage at end of line; \"%.200s\".\n",
695 filename, linenum, arg);
700 if (bad_options > 0) {
701 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
702 filename, bad_options);