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
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->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;
54 options->dsa_authentication = -1;
56 options->kerberos_authentication = -1;
57 options->kerberos_or_local_passwd = -1;
58 options->kerberos_ticket_cleanup = -1;
61 options->kerberos_tgt_passing = -1;
62 options->afs_token_passing = -1;
64 options->password_authentication = -1;
66 options->skey_authentication = -1;
68 options->permit_empty_passwd = -1;
69 options->use_login = -1;
70 options->num_allow_users = 0;
71 options->num_deny_users = 0;
72 options->num_allow_groups = 0;
73 options->num_deny_groups = 0;
74 options->ciphers = NULL;
75 options->protocol = SSH_PROTO_UNKNOWN;
76 options->gateway_ports = -1;
80 fill_default_server_options(ServerOptions *options)
82 if (options->num_ports == 0)
83 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
84 if (options->listen_addrs == NULL)
85 add_listen_addr(options, NULL);
86 if (options->host_key_file == NULL)
87 options->host_key_file = HOST_KEY_FILE;
88 if (options->host_dsa_key_file == NULL)
89 options->host_dsa_key_file = HOST_DSA_KEY_FILE;
90 if (options->pid_file == NULL)
91 options->pid_file = SSH_DAEMON_PID_FILE;
92 if (options->server_key_bits == -1)
93 options->server_key_bits = 768;
94 if (options->login_grace_time == -1)
95 options->login_grace_time = 600;
96 if (options->key_regeneration_time == -1)
97 options->key_regeneration_time = 3600;
98 if (options->permit_root_login == -1)
99 options->permit_root_login = 1; /* yes */
100 if (options->ignore_rhosts == -1)
101 options->ignore_rhosts = 1;
102 if (options->ignore_user_known_hosts == -1)
103 options->ignore_user_known_hosts = 0;
104 if (options->check_mail == -1)
105 options->check_mail = 0;
106 if (options->print_motd == -1)
107 options->print_motd = 1;
108 if (options->x11_forwarding == -1)
109 options->x11_forwarding = 0;
110 if (options->x11_display_offset == -1)
111 options->x11_display_offset = 10;
112 if (options->strict_modes == -1)
113 options->strict_modes = 1;
114 if (options->keepalives == -1)
115 options->keepalives = 1;
116 if (options->log_facility == (SyslogFacility) (-1))
117 options->log_facility = SYSLOG_FACILITY_AUTH;
118 if (options->log_level == (LogLevel) (-1))
119 options->log_level = SYSLOG_LEVEL_INFO;
120 if (options->rhosts_authentication == -1)
121 options->rhosts_authentication = 0;
122 if (options->rhosts_rsa_authentication == -1)
123 options->rhosts_rsa_authentication = 0;
124 if (options->rsa_authentication == -1)
125 options->rsa_authentication = 1;
126 if (options->dsa_authentication == -1)
127 options->dsa_authentication = 1;
129 if (options->kerberos_authentication == -1)
130 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
131 if (options->kerberos_or_local_passwd == -1)
132 options->kerberos_or_local_passwd = 1;
133 if (options->kerberos_ticket_cleanup == -1)
134 options->kerberos_ticket_cleanup = 1;
137 if (options->kerberos_tgt_passing == -1)
138 options->kerberos_tgt_passing = 0;
139 if (options->afs_token_passing == -1)
140 options->afs_token_passing = k_hasafs();
142 if (options->password_authentication == -1)
143 options->password_authentication = 1;
145 if (options->skey_authentication == -1)
146 options->skey_authentication = 1;
148 if (options->permit_empty_passwd == -1)
149 options->permit_empty_passwd = 0;
150 if (options->use_login == -1)
151 options->use_login = 0;
152 if (options->protocol == SSH_PROTO_UNKNOWN)
153 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
154 if (options->gateway_ports == -1)
155 options->gateway_ports = 0;
158 #define WHITESPACE " \t\r\n"
160 /* Keyword tokens. */
162 sBadOption, /* == unknown option */
163 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
164 sPermitRootLogin, sLogFacility, sLogLevel,
165 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
167 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
170 sKerberosTgtPassing, sAFSTokenPassing,
175 sPasswordAuthentication, sListenAddress,
176 sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
177 sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
178 sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
179 sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
180 sGatewayPorts, sDSAAuthentication
183 /* Textual representation of the tokens. */
186 ServerOpCodes opcode;
189 { "hostkey", sHostKeyFile },
190 { "hostdsakey", sHostDSAKeyFile },
191 { "pidfile", sPidFile },
192 { "serverkeybits", sServerKeyBits },
193 { "logingracetime", sLoginGraceTime },
194 { "keyregenerationinterval", sKeyRegenerationTime },
195 { "permitrootlogin", sPermitRootLogin },
196 { "syslogfacility", sLogFacility },
197 { "loglevel", sLogLevel },
198 { "rhostsauthentication", sRhostsAuthentication },
199 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
200 { "rsaauthentication", sRSAAuthentication },
201 { "dsaauthentication", sDSAAuthentication },
203 { "kerberosauthentication", sKerberosAuthentication },
204 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
205 { "kerberosticketcleanup", sKerberosTicketCleanup },
208 { "kerberostgtpassing", sKerberosTgtPassing },
209 { "afstokenpassing", sAFSTokenPassing },
211 { "passwordauthentication", sPasswordAuthentication },
213 { "skeyauthentication", sSkeyAuthentication },
215 { "checkmail", sCheckMail },
216 { "listenaddress", sListenAddress },
217 { "printmotd", sPrintMotd },
218 { "ignorerhosts", sIgnoreRhosts },
219 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
220 { "x11forwarding", sX11Forwarding },
221 { "x11displayoffset", sX11DisplayOffset },
222 { "strictmodes", sStrictModes },
223 { "permitemptypasswords", sEmptyPasswd },
224 { "uselogin", sUseLogin },
225 { "randomseed", sRandomSeedFile },
226 { "keepalive", sKeepAlives },
227 { "allowusers", sAllowUsers },
228 { "denyusers", sDenyUsers },
229 { "allowgroups", sAllowGroups },
230 { "denygroups", sDenyGroups },
231 { "ciphers", sCiphers },
232 { "protocol", sProtocol },
233 { "gatewayports", sGatewayPorts },
238 * Returns the number of the token pointed to by cp of length len. Never
239 * returns if the token is not known.
243 parse_token(const char *cp, const char *filename,
248 for (i = 0; keywords[i].name; i++)
249 if (strcasecmp(cp, keywords[i].name) == 0)
250 return keywords[i].opcode;
252 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
253 filename, linenum, cp);
261 add_listen_addr(ServerOptions *options, char *addr)
264 struct addrinfo hints, *ai, *aitop;
265 char strport[NI_MAXSERV];
269 if (options->num_ports == 0)
270 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
271 for (i = 0; i < options->num_ports; i++) {
272 memset(&hints, 0, sizeof(hints));
273 hints.ai_family = IPv4or6;
274 hints.ai_socktype = SOCK_STREAM;
275 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
276 snprintf(strport, sizeof strport, "%d", options->ports[i]);
277 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
278 fatal("bad addr or host: %s (%s)\n",
279 addr ? addr : "<NULL>",
280 gai_strerror(gaierr));
281 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
283 ai->ai_next = options->listen_addrs;
284 options->listen_addrs = aitop;
288 /* Reads the server configuration file. */
291 read_server_config(ServerOptions *options, const char *filename)
296 int linenum, *intptr, value;
298 ServerOpCodes opcode;
300 f = fopen(filename, "r");
306 while (fgets(line, sizeof(line), f)) {
308 cp = line + strspn(line, WHITESPACE);
309 if (!*cp || *cp == '#')
311 cp = strtok(cp, WHITESPACE);
312 opcode = parse_token(cp, filename, linenum);
318 /* ignore ports from configfile if cmdline specifies ports */
319 if (options->ports_from_cmdline)
321 if (options->listen_addrs != NULL)
322 fatal("%s line %d: ports must be specified before "
323 "ListenAdress.\n", filename, linenum);
324 if (options->num_ports >= MAX_PORTS)
325 fatal("%s line %d: too many ports.\n",
327 cp = strtok(NULL, WHITESPACE);
329 fatal("%s line %d: missing port number.\n",
331 options->ports[options->num_ports++] = atoi(cp);
335 intptr = &options->server_key_bits;
337 cp = strtok(NULL, WHITESPACE);
339 fprintf(stderr, "%s line %d: missing integer value.\n",
348 case sLoginGraceTime:
349 intptr = &options->login_grace_time;
352 case sKeyRegenerationTime:
353 intptr = &options->key_regeneration_time;
357 cp = strtok(NULL, WHITESPACE);
359 fatal("%s line %d: missing inet addr.\n",
361 add_listen_addr(options, cp);
365 case sHostDSAKeyFile:
366 charptr = (opcode == sHostKeyFile ) ?
367 &options->host_key_file : &options->host_dsa_key_file;
368 cp = strtok(NULL, WHITESPACE);
370 fprintf(stderr, "%s line %d: missing file name.\n",
374 if (*charptr == NULL)
375 *charptr = tilde_expand_filename(cp, getuid());
379 charptr = &options->pid_file;
380 cp = strtok(NULL, WHITESPACE);
382 fprintf(stderr, "%s line %d: missing file name.\n",
386 if (*charptr == NULL)
387 *charptr = tilde_expand_filename(cp, getuid());
390 case sRandomSeedFile:
391 fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
393 cp = strtok(NULL, WHITESPACE);
396 case sPermitRootLogin:
397 intptr = &options->permit_root_login;
398 cp = strtok(NULL, WHITESPACE);
400 fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
404 if (strcmp(cp, "without-password") == 0)
406 else if (strcmp(cp, "yes") == 0)
408 else if (strcmp(cp, "no") == 0)
411 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
412 filename, linenum, cp);
420 intptr = &options->ignore_rhosts;
422 cp = strtok(NULL, WHITESPACE);
424 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
428 if (strcmp(cp, "yes") == 0)
430 else if (strcmp(cp, "no") == 0)
433 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
434 filename, linenum, cp);
441 case sIgnoreUserKnownHosts:
442 intptr = &options->ignore_user_known_hosts;
445 case sRhostsAuthentication:
446 intptr = &options->rhosts_authentication;
449 case sRhostsRSAAuthentication:
450 intptr = &options->rhosts_rsa_authentication;
453 case sRSAAuthentication:
454 intptr = &options->rsa_authentication;
457 case sDSAAuthentication:
458 intptr = &options->dsa_authentication;
462 case sKerberosAuthentication:
463 intptr = &options->kerberos_authentication;
466 case sKerberosOrLocalPasswd:
467 intptr = &options->kerberos_or_local_passwd;
470 case sKerberosTicketCleanup:
471 intptr = &options->kerberos_ticket_cleanup;
476 case sKerberosTgtPassing:
477 intptr = &options->kerberos_tgt_passing;
480 case sAFSTokenPassing:
481 intptr = &options->afs_token_passing;
485 case sPasswordAuthentication:
486 intptr = &options->password_authentication;
490 intptr = &options->check_mail;
494 case sSkeyAuthentication:
495 intptr = &options->skey_authentication;
500 intptr = &options->print_motd;
504 intptr = &options->x11_forwarding;
507 case sX11DisplayOffset:
508 intptr = &options->x11_display_offset;
512 intptr = &options->strict_modes;
516 intptr = &options->keepalives;
520 intptr = &options->permit_empty_passwd;
524 intptr = &options->use_login;
528 intptr = &options->gateway_ports;
532 intptr = (int *) &options->log_facility;
533 cp = strtok(NULL, WHITESPACE);
534 value = log_facility_number(cp);
535 if (value == (SyslogFacility) - 1)
536 fatal("%.200s line %d: unsupported log facility '%s'\n",
537 filename, linenum, cp ? cp : "<NONE>");
539 *intptr = (SyslogFacility) value;
543 intptr = (int *) &options->log_level;
544 cp = strtok(NULL, WHITESPACE);
545 value = log_level_number(cp);
546 if (value == (LogLevel) - 1)
547 fatal("%.200s line %d: unsupported log level '%s'\n",
548 filename, linenum, cp ? cp : "<NONE>");
550 *intptr = (LogLevel) value;
554 while ((cp = strtok(NULL, WHITESPACE))) {
555 if (options->num_allow_users >= MAX_ALLOW_USERS)
556 fatal("%s line %d: too many allow users.\n",
558 options->allow_users[options->num_allow_users++] = xstrdup(cp);
563 while ((cp = strtok(NULL, WHITESPACE))) {
564 if (options->num_deny_users >= MAX_DENY_USERS)
565 fatal( "%s line %d: too many deny users.\n",
567 options->deny_users[options->num_deny_users++] = xstrdup(cp);
572 while ((cp = strtok(NULL, WHITESPACE))) {
573 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
574 fatal("%s line %d: too many allow groups.\n",
576 options->allow_groups[options->num_allow_groups++] = xstrdup(cp);
581 while ((cp = strtok(NULL, WHITESPACE))) {
582 if (options->num_deny_groups >= MAX_DENY_GROUPS)
583 fatal("%s line %d: too many deny groups.\n",
585 options->deny_groups[options->num_deny_groups++] = xstrdup(cp);
590 cp = strtok(NULL, WHITESPACE);
591 if (!ciphers_valid(cp))
592 fatal("%s line %d: Bad cipher spec '%s'.",
593 filename, linenum, cp ? cp : "<NONE>");
594 if (options->ciphers == NULL)
595 options->ciphers = xstrdup(cp);
599 intptr = &options->protocol;
600 cp = strtok(NULL, WHITESPACE);
601 value = proto_spec(cp);
602 if (value == SSH_PROTO_UNKNOWN)
603 fatal("%s line %d: Bad protocol spec '%s'.",
604 filename, linenum, cp ? cp : "<NONE>");
605 if (*intptr == SSH_PROTO_UNKNOWN)
610 fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
611 filename, linenum, cp, opcode);
614 if (strtok(NULL, WHITESPACE) != NULL) {
615 fprintf(stderr, "%s line %d: garbage at end of line.\n",
621 if (bad_options > 0) {
622 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
623 filename, bad_options);