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->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;
81 fill_default_server_options(ServerOptions *options)
83 if (options->num_ports == 0)
84 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
85 if (options->listen_addrs == NULL)
86 add_listen_addr(options, NULL);
87 if (options->host_key_file == NULL)
88 options->host_key_file = HOST_KEY_FILE;
89 if (options->host_dsa_key_file == NULL)
90 options->host_dsa_key_file = HOST_DSA_KEY_FILE;
91 if (options->pid_file == NULL)
92 options->pid_file = SSH_DAEMON_PID_FILE;
93 if (options->server_key_bits == -1)
94 options->server_key_bits = 768;
95 if (options->login_grace_time == -1)
96 options->login_grace_time = 600;
97 if (options->key_regeneration_time == -1)
98 options->key_regeneration_time = 3600;
99 if (options->permit_root_login == -1)
100 options->permit_root_login = 1; /* yes */
101 if (options->ignore_rhosts == -1)
102 options->ignore_rhosts = 1;
103 if (options->ignore_user_known_hosts == -1)
104 options->ignore_user_known_hosts = 0;
105 if (options->check_mail == -1)
106 options->check_mail = 0;
107 if (options->print_motd == -1)
108 options->print_motd = 1;
109 if (options->x11_forwarding == -1)
110 options->x11_forwarding = 0;
111 if (options->x11_display_offset == -1)
112 options->x11_display_offset = 10;
114 if (options->xauth_location == NULL)
115 options->xauth_location = XAUTH_PATH;
116 #endif /* XAUTH_PATH */
117 if (options->strict_modes == -1)
118 options->strict_modes = 1;
119 if (options->keepalives == -1)
120 options->keepalives = 1;
121 if (options->log_facility == (SyslogFacility) (-1))
122 options->log_facility = SYSLOG_FACILITY_AUTH;
123 if (options->log_level == (LogLevel) (-1))
124 options->log_level = SYSLOG_LEVEL_INFO;
125 if (options->rhosts_authentication == -1)
126 options->rhosts_authentication = 0;
127 if (options->rhosts_rsa_authentication == -1)
128 options->rhosts_rsa_authentication = 0;
129 if (options->rsa_authentication == -1)
130 options->rsa_authentication = 1;
131 if (options->dsa_authentication == -1)
132 options->dsa_authentication = 1;
134 if (options->kerberos_authentication == -1)
135 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
136 if (options->kerberos_or_local_passwd == -1)
137 options->kerberos_or_local_passwd = 1;
138 if (options->kerberos_ticket_cleanup == -1)
139 options->kerberos_ticket_cleanup = 1;
142 if (options->kerberos_tgt_passing == -1)
143 options->kerberos_tgt_passing = 0;
144 if (options->afs_token_passing == -1)
145 options->afs_token_passing = k_hasafs();
147 if (options->password_authentication == -1)
148 options->password_authentication = 1;
150 if (options->skey_authentication == -1)
151 options->skey_authentication = 1;
153 if (options->permit_empty_passwd == -1)
154 options->permit_empty_passwd = 0;
155 if (options->use_login == -1)
156 options->use_login = 0;
157 if (options->protocol == SSH_PROTO_UNKNOWN)
158 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
159 if (options->gateway_ports == -1)
160 options->gateway_ports = 0;
163 #define WHITESPACE " \t\r\n"
165 /* Keyword tokens. */
167 sBadOption, /* == unknown option */
168 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
169 sPermitRootLogin, sLogFacility, sLogLevel,
170 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
172 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
175 sKerberosTgtPassing, sAFSTokenPassing,
180 sPasswordAuthentication, sListenAddress,
181 sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
182 sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
183 sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
184 sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
185 sGatewayPorts, sDSAAuthentication, sXAuthLocation
188 /* Textual representation of the tokens. */
191 ServerOpCodes opcode;
194 { "hostkey", sHostKeyFile },
195 { "hostdsakey", sHostDSAKeyFile },
196 { "pidfile", sPidFile },
197 { "serverkeybits", sServerKeyBits },
198 { "logingracetime", sLoginGraceTime },
199 { "keyregenerationinterval", sKeyRegenerationTime },
200 { "permitrootlogin", sPermitRootLogin },
201 { "syslogfacility", sLogFacility },
202 { "loglevel", sLogLevel },
203 { "rhostsauthentication", sRhostsAuthentication },
204 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
205 { "rsaauthentication", sRSAAuthentication },
206 { "dsaauthentication", sDSAAuthentication },
208 { "kerberosauthentication", sKerberosAuthentication },
209 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
210 { "kerberosticketcleanup", sKerberosTicketCleanup },
213 { "kerberostgtpassing", sKerberosTgtPassing },
214 { "afstokenpassing", sAFSTokenPassing },
216 { "passwordauthentication", sPasswordAuthentication },
218 { "skeyauthentication", sSkeyAuthentication },
220 { "checkmail", sCheckMail },
221 { "listenaddress", sListenAddress },
222 { "printmotd", sPrintMotd },
223 { "ignorerhosts", sIgnoreRhosts },
224 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
225 { "x11forwarding", sX11Forwarding },
226 { "x11displayoffset", sX11DisplayOffset },
227 { "xauthlocation", sXAuthLocation },
228 { "strictmodes", sStrictModes },
229 { "permitemptypasswords", sEmptyPasswd },
230 { "uselogin", sUseLogin },
231 { "randomseed", sRandomSeedFile },
232 { "keepalive", sKeepAlives },
233 { "allowusers", sAllowUsers },
234 { "denyusers", sDenyUsers },
235 { "allowgroups", sAllowGroups },
236 { "denygroups", sDenyGroups },
237 { "ciphers", sCiphers },
238 { "protocol", sProtocol },
239 { "gatewayports", sGatewayPorts },
244 * Returns the number of the token pointed to by cp of length len. Never
245 * returns if the token is not known.
249 parse_token(const char *cp, const char *filename,
254 for (i = 0; keywords[i].name; i++)
255 if (strcasecmp(cp, keywords[i].name) == 0)
256 return keywords[i].opcode;
258 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
259 filename, linenum, cp);
267 add_listen_addr(ServerOptions *options, char *addr)
270 struct addrinfo hints, *ai, *aitop;
271 char strport[NI_MAXSERV];
275 if (options->num_ports == 0)
276 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
277 for (i = 0; i < options->num_ports; i++) {
278 memset(&hints, 0, sizeof(hints));
279 hints.ai_family = IPv4or6;
280 hints.ai_socktype = SOCK_STREAM;
281 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
282 snprintf(strport, sizeof strport, "%d", options->ports[i]);
283 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
284 fatal("bad addr or host: %s (%s)\n",
285 addr ? addr : "<NULL>",
286 gai_strerror(gaierr));
287 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
289 ai->ai_next = options->listen_addrs;
290 options->listen_addrs = aitop;
294 /* Reads the server configuration file. */
297 read_server_config(ServerOptions *options, const char *filename)
302 int linenum, *intptr, value;
304 ServerOpCodes opcode;
306 f = fopen(filename, "r");
312 while (fgets(line, sizeof(line), f)) {
314 cp = line + strspn(line, WHITESPACE);
315 if (!*cp || *cp == '#')
317 cp = strtok(cp, WHITESPACE);
318 opcode = parse_token(cp, filename, linenum);
324 /* ignore ports from configfile if cmdline specifies ports */
325 if (options->ports_from_cmdline)
327 if (options->listen_addrs != NULL)
328 fatal("%s line %d: ports must be specified before "
329 "ListenAdress.\n", filename, linenum);
330 if (options->num_ports >= MAX_PORTS)
331 fatal("%s line %d: too many ports.\n",
333 cp = strtok(NULL, WHITESPACE);
335 fatal("%s line %d: missing port number.\n",
337 options->ports[options->num_ports++] = atoi(cp);
341 intptr = &options->server_key_bits;
343 cp = strtok(NULL, WHITESPACE);
345 fprintf(stderr, "%s line %d: missing integer value.\n",
354 case sLoginGraceTime:
355 intptr = &options->login_grace_time;
358 case sKeyRegenerationTime:
359 intptr = &options->key_regeneration_time;
363 cp = strtok(NULL, WHITESPACE);
365 fatal("%s line %d: missing inet addr.\n",
367 add_listen_addr(options, cp);
371 case sHostDSAKeyFile:
372 charptr = (opcode == sHostKeyFile ) ?
373 &options->host_key_file : &options->host_dsa_key_file;
375 cp = strtok(NULL, WHITESPACE);
377 fprintf(stderr, "%s line %d: missing file name.\n",
381 if (*charptr == NULL)
382 *charptr = tilde_expand_filename(cp, getuid());
386 charptr = &options->pid_file;
389 case sRandomSeedFile:
390 fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
392 cp = strtok(NULL, WHITESPACE);
395 case sPermitRootLogin:
396 intptr = &options->permit_root_login;
397 cp = strtok(NULL, WHITESPACE);
399 fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
403 if (strcmp(cp, "without-password") == 0)
405 else if (strcmp(cp, "yes") == 0)
407 else if (strcmp(cp, "no") == 0)
410 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
411 filename, linenum, cp);
419 intptr = &options->ignore_rhosts;
421 cp = strtok(NULL, WHITESPACE);
423 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
427 if (strcmp(cp, "yes") == 0)
429 else if (strcmp(cp, "no") == 0)
432 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
433 filename, linenum, cp);
440 case sIgnoreUserKnownHosts:
441 intptr = &options->ignore_user_known_hosts;
444 case sRhostsAuthentication:
445 intptr = &options->rhosts_authentication;
448 case sRhostsRSAAuthentication:
449 intptr = &options->rhosts_rsa_authentication;
452 case sRSAAuthentication:
453 intptr = &options->rsa_authentication;
456 case sDSAAuthentication:
457 intptr = &options->dsa_authentication;
461 case sKerberosAuthentication:
462 intptr = &options->kerberos_authentication;
465 case sKerberosOrLocalPasswd:
466 intptr = &options->kerberos_or_local_passwd;
469 case sKerberosTicketCleanup:
470 intptr = &options->kerberos_ticket_cleanup;
475 case sKerberosTgtPassing:
476 intptr = &options->kerberos_tgt_passing;
479 case sAFSTokenPassing:
480 intptr = &options->afs_token_passing;
484 case sPasswordAuthentication:
485 intptr = &options->password_authentication;
489 intptr = &options->check_mail;
493 case sSkeyAuthentication:
494 intptr = &options->skey_authentication;
499 intptr = &options->print_motd;
503 intptr = &options->x11_forwarding;
506 case sX11DisplayOffset:
507 intptr = &options->x11_display_offset;
511 charptr = &options->xauth_location;
515 intptr = &options->strict_modes;
519 intptr = &options->keepalives;
523 intptr = &options->permit_empty_passwd;
527 intptr = &options->use_login;
531 intptr = &options->gateway_ports;
535 intptr = (int *) &options->log_facility;
536 cp = strtok(NULL, WHITESPACE);
537 value = log_facility_number(cp);
538 if (value == (SyslogFacility) - 1)
539 fatal("%.200s line %d: unsupported log facility '%s'\n",
540 filename, linenum, cp ? cp : "<NONE>");
542 *intptr = (SyslogFacility) value;
546 intptr = (int *) &options->log_level;
547 cp = strtok(NULL, WHITESPACE);
548 value = log_level_number(cp);
549 if (value == (LogLevel) - 1)
550 fatal("%.200s line %d: unsupported log level '%s'\n",
551 filename, linenum, cp ? cp : "<NONE>");
553 *intptr = (LogLevel) value;
557 while ((cp = strtok(NULL, WHITESPACE))) {
558 if (options->num_allow_users >= MAX_ALLOW_USERS)
559 fatal("%s line %d: too many allow users.\n",
561 options->allow_users[options->num_allow_users++] = xstrdup(cp);
566 while ((cp = strtok(NULL, WHITESPACE))) {
567 if (options->num_deny_users >= MAX_DENY_USERS)
568 fatal( "%s line %d: too many deny users.\n",
570 options->deny_users[options->num_deny_users++] = xstrdup(cp);
575 while ((cp = strtok(NULL, WHITESPACE))) {
576 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
577 fatal("%s line %d: too many allow groups.\n",
579 options->allow_groups[options->num_allow_groups++] = xstrdup(cp);
584 while ((cp = strtok(NULL, WHITESPACE))) {
585 if (options->num_deny_groups >= MAX_DENY_GROUPS)
586 fatal("%s line %d: too many deny groups.\n",
588 options->deny_groups[options->num_deny_groups++] = xstrdup(cp);
593 cp = strtok(NULL, WHITESPACE);
595 fatal("%s line %d: Missing argument.", filename, linenum);
596 if (!ciphers_valid(cp))
597 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
598 filename, linenum, cp ? cp : "<NONE>");
599 if (options->ciphers == NULL)
600 options->ciphers = xstrdup(cp);
604 intptr = &options->protocol;
605 cp = strtok(NULL, WHITESPACE);
607 fatal("%s line %d: Missing argument.", filename, linenum);
608 value = proto_spec(cp);
609 if (value == SSH_PROTO_UNKNOWN)
610 fatal("%s line %d: Bad protocol spec '%s'.",
611 filename, linenum, cp ? cp : "<NONE>");
612 if (*intptr == SSH_PROTO_UNKNOWN)
617 fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
618 filename, linenum, cp, opcode);
621 if (strtok(NULL, WHITESPACE) != NULL) {
622 fprintf(stderr, "%s line %d: garbage at end of line.\n",
628 if (bad_options > 0) {
629 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
630 filename, bad_options);