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.59 2001/01/19 12:45:26 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->num_host_key_files = 0;
33 options->pid_file = NULL;
34 options->server_key_bits = -1;
35 options->login_grace_time = -1;
36 options->key_regeneration_time = -1;
37 options->permit_root_login = -1;
38 options->ignore_rhosts = -1;
39 options->ignore_user_known_hosts = -1;
40 options->print_motd = -1;
41 options->check_mail = -1;
42 options->x11_forwarding = -1;
43 options->x11_display_offset = -1;
44 options->xauth_location = NULL;
45 options->strict_modes = -1;
46 options->keepalives = -1;
47 options->log_facility = (SyslogFacility) - 1;
48 options->log_level = (LogLevel) - 1;
49 options->rhosts_authentication = -1;
50 options->rhosts_rsa_authentication = -1;
51 options->rsa_authentication = -1;
52 options->pubkey_authentication = -1;
54 options->kerberos_authentication = -1;
55 options->kerberos_or_local_passwd = -1;
56 options->kerberos_ticket_cleanup = -1;
59 options->kerberos_tgt_passing = -1;
60 options->afs_token_passing = -1;
62 options->password_authentication = -1;
63 options->kbd_interactive_authentication = -1;
64 options->skey_authentication = -1;
65 options->permit_empty_passwd = -1;
66 options->use_login = -1;
67 options->allow_tcp_forwarding = -1;
68 options->num_allow_users = 0;
69 options->num_deny_users = 0;
70 options->num_allow_groups = 0;
71 options->num_deny_groups = 0;
72 options->ciphers = NULL;
73 options->protocol = SSH_PROTO_UNKNOWN;
74 options->gateway_ports = -1;
75 options->num_subsystems = 0;
76 options->max_startups_begin = -1;
77 options->max_startups_rate = -1;
78 options->max_startups = -1;
79 options->banner = NULL;
83 fill_default_server_options(ServerOptions *options)
85 if (options->protocol == SSH_PROTO_UNKNOWN)
86 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
87 if (options->num_host_key_files == 0) {
88 /* fill default hostkeys for protocols */
89 if (options->protocol & SSH_PROTO_1)
90 options->host_key_files[options->num_host_key_files++] = HOST_KEY_FILE;
91 if (options->protocol & SSH_PROTO_2)
92 options->host_key_files[options->num_host_key_files++] = HOST_DSA_KEY_FILE;
94 if (options->num_ports == 0)
95 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
96 if (options->listen_addrs == NULL)
97 add_listen_addr(options, NULL);
98 if (options->pid_file == NULL)
99 options->pid_file = SSH_DAEMON_PID_FILE;
100 if (options->server_key_bits == -1)
101 options->server_key_bits = 768;
102 if (options->login_grace_time == -1)
103 options->login_grace_time = 600;
104 if (options->key_regeneration_time == -1)
105 options->key_regeneration_time = 3600;
106 if (options->permit_root_login == -1)
107 options->permit_root_login = 1; /* yes */
108 if (options->ignore_rhosts == -1)
109 options->ignore_rhosts = 1;
110 if (options->ignore_user_known_hosts == -1)
111 options->ignore_user_known_hosts = 0;
112 if (options->check_mail == -1)
113 options->check_mail = 0;
114 if (options->print_motd == -1)
115 options->print_motd = 1;
116 if (options->x11_forwarding == -1)
117 options->x11_forwarding = 0;
118 if (options->x11_display_offset == -1)
119 options->x11_display_offset = 10;
121 if (options->xauth_location == NULL)
122 options->xauth_location = XAUTH_PATH;
123 #endif /* XAUTH_PATH */
124 if (options->strict_modes == -1)
125 options->strict_modes = 1;
126 if (options->keepalives == -1)
127 options->keepalives = 1;
128 if (options->log_facility == (SyslogFacility) (-1))
129 options->log_facility = SYSLOG_FACILITY_AUTH;
130 if (options->log_level == (LogLevel) (-1))
131 options->log_level = SYSLOG_LEVEL_INFO;
132 if (options->rhosts_authentication == -1)
133 options->rhosts_authentication = 0;
134 if (options->rhosts_rsa_authentication == -1)
135 options->rhosts_rsa_authentication = 0;
136 if (options->rsa_authentication == -1)
137 options->rsa_authentication = 1;
138 if (options->pubkey_authentication == -1)
139 options->pubkey_authentication = 1;
141 if (options->kerberos_authentication == -1)
142 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
143 if (options->kerberos_or_local_passwd == -1)
144 options->kerberos_or_local_passwd = 1;
145 if (options->kerberos_ticket_cleanup == -1)
146 options->kerberos_ticket_cleanup = 1;
149 if (options->kerberos_tgt_passing == -1)
150 options->kerberos_tgt_passing = 0;
151 if (options->afs_token_passing == -1)
152 options->afs_token_passing = k_hasafs();
154 if (options->password_authentication == -1)
155 options->password_authentication = 1;
156 if (options->kbd_interactive_authentication == -1)
157 options->kbd_interactive_authentication = 0;
158 if (options->skey_authentication == -1)
159 options->skey_authentication = 1;
160 if (options->permit_empty_passwd == -1)
161 options->permit_empty_passwd = 0;
162 if (options->use_login == -1)
163 options->use_login = 0;
164 if (options->allow_tcp_forwarding == -1)
165 options->allow_tcp_forwarding = 1;
166 if (options->gateway_ports == -1)
167 options->gateway_ports = 0;
168 if (options->max_startups == -1)
169 options->max_startups = 10;
170 if (options->max_startups_rate == -1)
171 options->max_startups_rate = 100; /* 100% */
172 if (options->max_startups_begin == -1)
173 options->max_startups_begin = options->max_startups;
176 /* Keyword tokens. */
178 sBadOption, /* == unknown option */
179 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
180 sPermitRootLogin, sLogFacility, sLogLevel,
181 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
183 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
186 sKerberosTgtPassing, sAFSTokenPassing,
189 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
190 sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
191 sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
192 sUseLogin, sAllowTcpForwarding,
193 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
194 sIgnoreUserKnownHosts, sCiphers, sProtocol, sPidFile,
195 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
199 /* Textual representation of the tokens. */
202 ServerOpCodes opcode;
205 { "hostkey", sHostKeyFile },
206 { "hostdsakey", sHostKeyFile }, /* alias */
207 { "pidfile", sPidFile },
208 { "serverkeybits", sServerKeyBits },
209 { "logingracetime", sLoginGraceTime },
210 { "keyregenerationinterval", sKeyRegenerationTime },
211 { "permitrootlogin", sPermitRootLogin },
212 { "syslogfacility", sLogFacility },
213 { "loglevel", sLogLevel },
214 { "rhostsauthentication", sRhostsAuthentication },
215 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
216 { "rsaauthentication", sRSAAuthentication },
217 { "pubkeyauthentication", sPubkeyAuthentication },
218 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
220 { "kerberosauthentication", sKerberosAuthentication },
221 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
222 { "kerberosticketcleanup", sKerberosTicketCleanup },
225 { "kerberostgtpassing", sKerberosTgtPassing },
226 { "afstokenpassing", sAFSTokenPassing },
228 { "passwordauthentication", sPasswordAuthentication },
229 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
230 { "skeyauthentication", sSkeyAuthentication },
231 { "checkmail", sCheckMail },
232 { "listenaddress", sListenAddress },
233 { "printmotd", sPrintMotd },
234 { "ignorerhosts", sIgnoreRhosts },
235 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
236 { "x11forwarding", sX11Forwarding },
237 { "x11displayoffset", sX11DisplayOffset },
238 { "xauthlocation", sXAuthLocation },
239 { "strictmodes", sStrictModes },
240 { "permitemptypasswords", sEmptyPasswd },
241 { "uselogin", sUseLogin },
242 { "randomseed", sRandomSeedFile },
243 { "keepalive", sKeepAlives },
244 { "allowtcpforwarding", sAllowTcpForwarding },
245 { "allowusers", sAllowUsers },
246 { "denyusers", sDenyUsers },
247 { "allowgroups", sAllowGroups },
248 { "denygroups", sDenyGroups },
249 { "ciphers", sCiphers },
250 { "protocol", sProtocol },
251 { "gatewayports", sGatewayPorts },
252 { "subsystem", sSubsystem },
253 { "maxstartups", sMaxStartups },
254 { "banner", sBanner },
259 * Returns the number of the token pointed to by cp of length len. Never
260 * returns if the token is not known.
264 parse_token(const char *cp, const char *filename,
269 for (i = 0; keywords[i].name; i++)
270 if (strcasecmp(cp, keywords[i].name) == 0)
271 return keywords[i].opcode;
273 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
274 filename, linenum, cp);
282 add_listen_addr(ServerOptions *options, char *addr)
285 struct addrinfo hints, *ai, *aitop;
286 char strport[NI_MAXSERV];
290 if (options->num_ports == 0)
291 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
292 for (i = 0; i < options->num_ports; i++) {
293 memset(&hints, 0, sizeof(hints));
294 hints.ai_family = IPv4or6;
295 hints.ai_socktype = SOCK_STREAM;
296 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
297 snprintf(strport, sizeof strport, "%d", options->ports[i]);
298 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
299 fatal("bad addr or host: %s (%s)\n",
300 addr ? addr : "<NULL>",
301 gai_strerror(gaierr));
302 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
304 ai->ai_next = options->listen_addrs;
305 options->listen_addrs = aitop;
309 /* Reads the server configuration file. */
312 read_server_config(ServerOptions *options, const char *filename)
316 char *cp, **charptr, *arg;
317 int linenum, *intptr, value;
319 ServerOpCodes opcode;
322 f = fopen(filename, "r");
328 while (fgets(line, sizeof(line), f)) {
332 /* Ignore leading whitespace */
335 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 intptr = &options->num_host_key_files;
393 if (*intptr >= MAX_HOSTKEYS) {
394 fprintf(stderr, "%s line %d: to many host keys specified (max %d).\n",
395 filename, linenum, MAX_HOSTKEYS);
398 charptr = &options->host_key_files[*intptr];
401 if (!arg || *arg == '\0') {
402 fprintf(stderr, "%s line %d: missing file name.\n",
406 if (*charptr == NULL) {
407 *charptr = tilde_expand_filename(arg, getuid());
408 /* increase optional counter */
410 *intptr = *intptr + 1;
415 charptr = &options->pid_file;
418 case sRandomSeedFile:
419 fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
424 case sPermitRootLogin:
425 intptr = &options->permit_root_login;
427 if (!arg || *arg == '\0') {
428 fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
432 if (strcmp(arg, "without-password") == 0)
434 else if (strcmp(arg, "yes") == 0)
436 else if (strcmp(arg, "no") == 0)
439 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
440 filename, linenum, arg);
448 intptr = &options->ignore_rhosts;
451 if (!arg || *arg == '\0') {
452 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
456 if (strcmp(arg, "yes") == 0)
458 else if (strcmp(arg, "no") == 0)
461 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
462 filename, linenum, arg);
469 case sIgnoreUserKnownHosts:
470 intptr = &options->ignore_user_known_hosts;
473 case sRhostsAuthentication:
474 intptr = &options->rhosts_authentication;
477 case sRhostsRSAAuthentication:
478 intptr = &options->rhosts_rsa_authentication;
481 case sRSAAuthentication:
482 intptr = &options->rsa_authentication;
485 case sPubkeyAuthentication:
486 intptr = &options->pubkey_authentication;
490 case sKerberosAuthentication:
491 intptr = &options->kerberos_authentication;
494 case sKerberosOrLocalPasswd:
495 intptr = &options->kerberos_or_local_passwd;
498 case sKerberosTicketCleanup:
499 intptr = &options->kerberos_ticket_cleanup;
504 case sKerberosTgtPassing:
505 intptr = &options->kerberos_tgt_passing;
508 case sAFSTokenPassing:
509 intptr = &options->afs_token_passing;
513 case sPasswordAuthentication:
514 intptr = &options->password_authentication;
517 case sKbdInteractiveAuthentication:
518 intptr = &options->kbd_interactive_authentication;
522 intptr = &options->check_mail;
525 case sSkeyAuthentication:
526 intptr = &options->skey_authentication;
530 intptr = &options->print_motd;
534 intptr = &options->x11_forwarding;
537 case sX11DisplayOffset:
538 intptr = &options->x11_display_offset;
542 charptr = &options->xauth_location;
546 intptr = &options->strict_modes;
550 intptr = &options->keepalives;
554 intptr = &options->permit_empty_passwd;
558 intptr = &options->use_login;
562 intptr = &options->gateway_ports;
566 intptr = (int *) &options->log_facility;
568 value = log_facility_number(arg);
569 if (value == (SyslogFacility) - 1)
570 fatal("%.200s line %d: unsupported log facility '%s'\n",
571 filename, linenum, arg ? arg : "<NONE>");
573 *intptr = (SyslogFacility) value;
577 intptr = (int *) &options->log_level;
579 value = log_level_number(arg);
580 if (value == (LogLevel) - 1)
581 fatal("%.200s line %d: unsupported log level '%s'\n",
582 filename, linenum, arg ? arg : "<NONE>");
584 *intptr = (LogLevel) value;
587 case sAllowTcpForwarding:
588 intptr = &options->allow_tcp_forwarding;
592 while ((arg = strdelim(&cp)) && *arg != '\0') {
593 if (options->num_allow_users >= MAX_ALLOW_USERS)
594 fatal("%s line %d: too many allow users.\n",
596 options->allow_users[options->num_allow_users++] = xstrdup(arg);
601 while ((arg = strdelim(&cp)) && *arg != '\0') {
602 if (options->num_deny_users >= MAX_DENY_USERS)
603 fatal( "%s line %d: too many deny users.\n",
605 options->deny_users[options->num_deny_users++] = xstrdup(arg);
610 while ((arg = strdelim(&cp)) && *arg != '\0') {
611 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
612 fatal("%s line %d: too many allow groups.\n",
614 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
619 while ((arg = strdelim(&cp)) && *arg != '\0') {
620 if (options->num_deny_groups >= MAX_DENY_GROUPS)
621 fatal("%s line %d: too many deny groups.\n",
623 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
629 if (!arg || *arg == '\0')
630 fatal("%s line %d: Missing argument.", filename, linenum);
631 if (!ciphers_valid(arg))
632 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
633 filename, linenum, arg ? arg : "<NONE>");
634 if (options->ciphers == NULL)
635 options->ciphers = xstrdup(arg);
639 intptr = &options->protocol;
641 if (!arg || *arg == '\0')
642 fatal("%s line %d: Missing argument.", filename, linenum);
643 value = proto_spec(arg);
644 if (value == SSH_PROTO_UNKNOWN)
645 fatal("%s line %d: Bad protocol spec '%s'.",
646 filename, linenum, arg ? arg : "<NONE>");
647 if (*intptr == SSH_PROTO_UNKNOWN)
652 if(options->num_subsystems >= MAX_SUBSYSTEMS) {
653 fatal("%s line %d: too many subsystems defined.",
657 if (!arg || *arg == '\0')
658 fatal("%s line %d: Missing subsystem name.",
660 for (i = 0; i < options->num_subsystems; i++)
661 if(strcmp(arg, options->subsystem_name[i]) == 0)
662 fatal("%s line %d: Subsystem '%s' already defined.",
663 filename, linenum, arg);
664 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
666 if (!arg || *arg == '\0')
667 fatal("%s line %d: Missing subsystem command.",
669 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
670 options->num_subsystems++;
675 if (!arg || *arg == '\0')
676 fatal("%s line %d: Missing MaxStartups spec.",
678 if (sscanf(arg, "%d:%d:%d",
679 &options->max_startups_begin,
680 &options->max_startups_rate,
681 &options->max_startups) == 3) {
682 if (options->max_startups_begin >
683 options->max_startups ||
684 options->max_startups_rate > 100 ||
685 options->max_startups_rate < 1)
686 fatal("%s line %d: Illegal MaxStartups spec.",
690 intptr = &options->max_startups;
694 charptr = &options->banner;
698 fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
699 filename, linenum, arg, opcode);
702 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
704 "%s line %d: garbage at end of line; \"%.200s\".\n",
705 filename, linenum, arg);
710 if (bad_options > 0) {
711 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
712 filename, bad_options);