servconf.c revision 94464
196462Sru/*
296462Sru * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
396462Sru *                    All rights reserved
496462Sru *
596462Sru * As far as I am concerned, the code I have written for this software
696462Sru * can be used freely for any purpose.  Any derived versions of this
7156813Sru * software must be clearly marked as such, and if the derived work is
8155264Sru * incompatible with the protocol description in the RFC file, it must be
996462Sru * called by a name other than "ssh" or "Secure Shell".
1096462Sru */
1196668Sru
1296462Sru#include "includes.h"
1396668SruRCSID("$OpenBSD: servconf.c,v 1.101 2002/02/04 12:15:25 markus Exp $");
1496462SruRCSID("$FreeBSD: head/crypto/openssh/servconf.c 94464 2002-04-11 22:04:40Z des $");
1596462Sru
1696462Sru#if defined(KRB4)
1796668Sru#include <krb.h>
1896462Sru#endif
1996668Sru#if defined(KRB5)
2096462Sru#include <krb5.h>
2196462Sru#endif
2296462Sru#ifdef AFS
2396462Sru#include <kafs.h>
2496462Sru#endif
2596462Sru
2696462Sru#include "ssh.h"
2796462Sru#include "log.h"
2896462Sru#include "servconf.h"
2996462Sru#include "xmalloc.h"
3096462Sru#include "compat.h"
3196462Sru#include "pathnames.h"
3296462Sru#include "tildexpand.h"
3396462Sru#include "misc.h"
3496462Sru#include "cipher.h"
3596462Sru#include "kex.h"
3696462Sru#include "mac.h"
3796462Sru
3896462Srustatic void add_listen_addr(ServerOptions *, char *, u_short);
3996462Srustatic void add_one_listen_addr(ServerOptions *, char *, u_short);
4096462Sru
4196462Sru/* AF_UNSPEC or AF_INET or AF_INET6 */
4296668Sruextern int IPv4or6;
4396462Sru
4496462Sru/* Initializes the server options to their default values. */
4596462Sru
4696462Sruvoid
4796462Sruinitialize_server_options(ServerOptions *options)
4896462Sru{
4996462Sru	memset(options, 0, sizeof(*options));
5096462Sru	options->num_ports = 0;
5196462Sru	options->ports_from_cmdline = 0;
5296462Sru	options->listen_addrs = NULL;
5396668Sru	options->num_host_key_files = 0;
5496462Sru	options->pid_file = NULL;
5596462Sru	options->server_key_bits = -1;
5696462Sru	options->login_grace_time = -1;
5796462Sru	options->key_regeneration_time = -1;
5896462Sru	options->permit_root_login = PERMIT_NOT_SET;
5996462Sru	options->ignore_rhosts = -1;
6096462Sru	options->ignore_user_known_hosts = -1;
6196462Sru	options->print_motd = -1;
6296462Sru	options->print_lastlog = -1;
6396462Sru	options->x11_forwarding = -1;
64144893Sharti	options->x11_display_offset = -1;
6596462Sru	options->x11_use_localhost = -1;
6696462Sru	options->xauth_location = NULL;
6796462Sru	options->strict_modes = -1;
6896668Sru	options->keepalives = -1;
6996462Sru	options->log_facility = SYSLOG_FACILITY_NOT_SET;
7096462Sru	options->log_level = SYSLOG_LEVEL_NOT_SET;
7196462Sru	options->rhosts_authentication = -1;
7296462Sru	options->rhosts_rsa_authentication = -1;
7396462Sru	options->hostbased_authentication = -1;
7496462Sru	options->hostbased_uses_name_from_packet_only = -1;
7596462Sru	options->rsa_authentication = -1;
76245752Sbrooks	options->pubkey_authentication = -1;
7796462Sru#if defined(KRB4) || defined(KRB5)
7896462Sru	options->kerberos_authentication = -1;
79144893Sharti	options->kerberos_or_local_passwd = -1;
8096668Sru	options->kerberos_ticket_cleanup = -1;
8196668Sru#endif
8299343Sru#if defined(AFS) || defined(KRB5)
83155264Sru	options->kerberos_tgt_passing = -1;
84156813Sru#endif
85#ifdef AFS
86	options->afs_token_passing = -1;
87#endif
88	options->password_authentication = -1;
89	options->kbd_interactive_authentication = -1;
90	options->challenge_response_authentication = -1;
91	options->permit_empty_passwd = -1;
92	options->use_login = -1;
93	options->allow_tcp_forwarding = -1;
94	options->num_allow_users = 0;
95	options->num_deny_users = 0;
96	options->num_allow_groups = 0;
97	options->num_deny_groups = 0;
98	options->ciphers = NULL;
99	options->macs = NULL;
100	options->protocol = SSH_PROTO_UNKNOWN;
101	options->gateway_ports = -1;
102	options->connections_period = 0;
103	options->num_subsystems = 0;
104	options->max_startups_begin = -1;
105	options->max_startups_rate = -1;
106	options->max_startups = -1;
107	options->banner = NULL;
108	options->verify_reverse_mapping = -1;
109	options->client_alive_interval = -1;
110	options->client_alive_count_max = -1;
111	options->authorized_keys_file = NULL;
112	options->authorized_keys_file2 = NULL;
113}
114
115void
116fill_default_server_options(ServerOptions *options)
117{
118	if (options->protocol == SSH_PROTO_UNKNOWN)
119		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
120	if (options->num_host_key_files == 0) {
121		/* fill default hostkeys for protocols */
122		if (options->protocol & SSH_PROTO_1)
123			options->host_key_files[options->num_host_key_files++] =
124			    _PATH_HOST_KEY_FILE;
125		if (options->protocol & SSH_PROTO_2) {
126			options->host_key_files[options->num_host_key_files++] =
127			    _PATH_HOST_RSA_KEY_FILE;
128			options->host_key_files[options->num_host_key_files++] =
129			    _PATH_HOST_DSA_KEY_FILE;
130		}
131	}
132	if (options->num_ports == 0)
133		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
134	if (options->listen_addrs == NULL)
135		add_listen_addr(options, NULL, 0);
136	if (options->pid_file == NULL)
137		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
138	if (options->server_key_bits == -1)
139		options->server_key_bits = 768;
140	if (options->login_grace_time == -1)
141		options->login_grace_time = 120;
142	if (options->key_regeneration_time == -1)
143		options->key_regeneration_time = 3600;
144	if (options->permit_root_login == PERMIT_NOT_SET)
145		options->permit_root_login = PERMIT_NO;
146	if (options->ignore_rhosts == -1)
147		options->ignore_rhosts = 1;
148	if (options->ignore_user_known_hosts == -1)
149		options->ignore_user_known_hosts = 0;
150	if (options->check_mail == -1)
151		options->check_mail = 1;
152	if (options->print_motd == -1)
153		options->print_motd = 1;
154	if (options->print_lastlog == -1)
155		options->print_lastlog = 1;
156	if (options->x11_forwarding == -1)
157		options->x11_forwarding = 1;
158	if (options->x11_display_offset == -1)
159		options->x11_display_offset = 10;
160	if (options->x11_use_localhost == -1)
161		options->x11_use_localhost = 1;
162	if (options->xauth_location == NULL)
163		options->xauth_location = _PATH_XAUTH;
164	if (options->strict_modes == -1)
165		options->strict_modes = 1;
166	if (options->keepalives == -1)
167		options->keepalives = 1;
168	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
169		options->log_facility = SYSLOG_FACILITY_AUTH;
170	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
171		options->log_level = SYSLOG_LEVEL_INFO;
172	if (options->rhosts_authentication == -1)
173		options->rhosts_authentication = 0;
174	if (options->rhosts_rsa_authentication == -1)
175		options->rhosts_rsa_authentication = 0;
176	if (options->hostbased_authentication == -1)
177		options->hostbased_authentication = 0;
178	if (options->hostbased_uses_name_from_packet_only == -1)
179		options->hostbased_uses_name_from_packet_only = 0;
180	if (options->rsa_authentication == -1)
181		options->rsa_authentication = 1;
182	if (options->pubkey_authentication == -1)
183		options->pubkey_authentication = 1;
184#if defined(KRB4) && defined(KRB5)
185	if (options->kerberos_authentication == -1)
186		options->kerberos_authentication =
187		    (access(KEYFILE, R_OK) == 0 ||
188		    (access(krb5_defkeyname, R_OK) == 0));
189#elif defined(KRB4)
190	if (options->kerberos_authentication == -1)
191		options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
192#elif defined(KRB5)
193	if (options->kerberos_authentication == -1)
194		options->kerberos_authentication =
195		    (access(krb5_defkeyname, R_OK) == 0);
196#endif
197#if defined(KRB4) || defined(KRB5)
198	if (options->kerberos_or_local_passwd == -1)
199		options->kerberos_or_local_passwd = 1;
200	if (options->kerberos_ticket_cleanup == -1)
201		options->kerberos_ticket_cleanup = 1;
202#endif
203#if defined(AFS) || defined(KRB5)
204	if (options->kerberos_tgt_passing == -1)
205		options->kerberos_tgt_passing = 0;
206#endif
207#ifdef AFS
208	if (options->afs_token_passing == -1)
209		options->afs_token_passing = k_hasafs();
210#endif
211	if (options->password_authentication == -1)
212		options->password_authentication = 1;
213	if (options->kbd_interactive_authentication == -1)
214		options->kbd_interactive_authentication = 0;
215	if (options->challenge_response_authentication == -1)
216		options->challenge_response_authentication = 1;
217	if (options->permit_empty_passwd == -1)
218		options->permit_empty_passwd = 0;
219	if (options->use_login == -1)
220		options->use_login = 0;
221	if (options->allow_tcp_forwarding == -1)
222		options->allow_tcp_forwarding = 1;
223	if (options->gateway_ports == -1)
224		options->gateway_ports = 0;
225	if (options->max_startups == -1)
226		options->max_startups = 10;
227	if (options->max_startups_rate == -1)
228		options->max_startups_rate = 100;		/* 100% */
229	if (options->max_startups_begin == -1)
230		options->max_startups_begin = options->max_startups;
231	if (options->verify_reverse_mapping == -1)
232		options->verify_reverse_mapping = 0;
233	if (options->client_alive_interval == -1)
234		options->client_alive_interval = 0;
235	if (options->client_alive_count_max == -1)
236		options->client_alive_count_max = 3;
237	if (options->authorized_keys_file2 == NULL) {
238		/* authorized_keys_file2 falls back to authorized_keys_file */
239		if (options->authorized_keys_file != NULL)
240			options->authorized_keys_file2 = options->authorized_keys_file;
241		else
242			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
243	}
244	if (options->authorized_keys_file == NULL)
245		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
246}
247
248/* Keyword tokens. */
249typedef enum {
250	sBadOption,		/* == unknown option */
251	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
252	sPermitRootLogin, sLogFacility, sLogLevel,
253	sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
254#if defined(KRB4) || defined(KRB5)
255	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
256#endif
257#if defined(AFS) || defined(KRB5)
258	sKerberosTgtPassing,
259#endif
260#ifdef AFS
261	sAFSTokenPassing,
262#endif
263	sChallengeResponseAuthentication,
264	sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
265	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
266	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
267	sStrictModes, sEmptyPasswd, sKeepAlives,
268	sUseLogin, sAllowTcpForwarding,
269	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
270	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
271	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
272	sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
273	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
274	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
275	sCheckMail, sVersionAddendum,
276	sDeprecated
277} ServerOpCodes;
278
279/* Textual representation of the tokens. */
280static struct {
281	const char *name;
282	ServerOpCodes opcode;
283} keywords[] = {
284	{ "port", sPort },
285	{ "hostkey", sHostKeyFile },
286	{ "hostdsakey", sHostKeyFile },					/* alias */
287	{ "pidfile", sPidFile },
288	{ "serverkeybits", sServerKeyBits },
289	{ "logingracetime", sLoginGraceTime },
290	{ "keyregenerationinterval", sKeyRegenerationTime },
291	{ "permitrootlogin", sPermitRootLogin },
292	{ "syslogfacility", sLogFacility },
293	{ "loglevel", sLogLevel },
294	{ "rhostsauthentication", sRhostsAuthentication },
295	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
296	{ "hostbasedauthentication", sHostbasedAuthentication },
297	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
298	{ "rsaauthentication", sRSAAuthentication },
299	{ "pubkeyauthentication", sPubkeyAuthentication },
300	{ "dsaauthentication", sPubkeyAuthentication },			/* alias */
301#if defined(KRB4) || defined(KRB5)
302	{ "kerberosauthentication", sKerberosAuthentication },
303	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
304	{ "kerberosticketcleanup", sKerberosTicketCleanup },
305#endif
306#if defined(AFS) || defined(KRB5)
307	{ "kerberostgtpassing", sKerberosTgtPassing },
308#endif
309#ifdef AFS
310	{ "afstokenpassing", sAFSTokenPassing },
311#endif
312	{ "passwordauthentication", sPasswordAuthentication },
313	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
314	{ "challengeresponseauthentication", sChallengeResponseAuthentication },
315	{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
316	{ "listenaddress", sListenAddress },
317	{ "printmotd", sPrintMotd },
318	{ "printlastlog", sPrintLastLog },
319	{ "ignorerhosts", sIgnoreRhosts },
320	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
321	{ "x11forwarding", sX11Forwarding },
322	{ "x11displayoffset", sX11DisplayOffset },
323	{ "x11uselocalhost", sX11UseLocalhost },
324	{ "xauthlocation", sXAuthLocation },
325	{ "strictmodes", sStrictModes },
326	{ "permitemptypasswords", sEmptyPasswd },
327	{ "uselogin", sUseLogin },
328	{ "keepalive", sKeepAlives },
329	{ "allowtcpforwarding", sAllowTcpForwarding },
330	{ "allowusers", sAllowUsers },
331	{ "denyusers", sDenyUsers },
332	{ "allowgroups", sAllowGroups },
333	{ "denygroups", sDenyGroups },
334	{ "ciphers", sCiphers },
335	{ "macs", sMacs },
336	{ "protocol", sProtocol },
337	{ "gatewayports", sGatewayPorts },
338	{ "subsystem", sSubsystem },
339	{ "maxstartups", sMaxStartups },
340	{ "banner", sBanner },
341	{ "verifyreversemapping", sVerifyReverseMapping },
342	{ "reversemappingcheck", sVerifyReverseMapping },
343	{ "clientaliveinterval", sClientAliveInterval },
344	{ "clientalivecountmax", sClientAliveCountMax },
345	{ "authorizedkeysfile", sAuthorizedKeysFile },
346	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
347	{ "checkmail", sCheckMail },
348	{ "versionaddendum", sVersionAddendum },
349	{ NULL, sBadOption }
350};
351
352/*
353 * Returns the number of the token pointed to by cp or sBadOption.
354 */
355
356static ServerOpCodes
357parse_token(const char *cp, const char *filename,
358	    int linenum)
359{
360	u_int i;
361
362	for (i = 0; keywords[i].name; i++)
363		if (strcasecmp(cp, keywords[i].name) == 0)
364			return keywords[i].opcode;
365
366	error("%s: line %d: Bad configuration option: %s",
367	    filename, linenum, cp);
368	return sBadOption;
369}
370
371static void
372add_listen_addr(ServerOptions *options, char *addr, u_short port)
373{
374	int i;
375
376	if (options->num_ports == 0)
377		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
378	if (port == 0)
379		for (i = 0; i < options->num_ports; i++)
380			add_one_listen_addr(options, addr, options->ports[i]);
381	else
382		add_one_listen_addr(options, addr, port);
383}
384
385static void
386add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
387{
388	struct addrinfo hints, *ai, *aitop;
389	char strport[NI_MAXSERV];
390	int gaierr;
391
392	memset(&hints, 0, sizeof(hints));
393	hints.ai_family = IPv4or6;
394	hints.ai_socktype = SOCK_STREAM;
395	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
396	snprintf(strport, sizeof strport, "%d", port);
397	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
398		fatal("bad addr or host: %s (%s)",
399		    addr ? addr : "<NULL>",
400		    gai_strerror(gaierr));
401	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
402		;
403	ai->ai_next = options->listen_addrs;
404	options->listen_addrs = aitop;
405}
406
407int
408process_server_config_line(ServerOptions *options, char *line,
409    const char *filename, int linenum)
410{
411	char *cp, **charptr, *arg, *p;
412	int *intptr, value;
413	ServerOpCodes opcode;
414	int i, n;
415
416	cp = line;
417	arg = strdelim(&cp);
418	/* Ignore leading whitespace */
419	if (*arg == '\0')
420		arg = strdelim(&cp);
421	if (!arg || !*arg || *arg == '#')
422		return 0;
423	intptr = NULL;
424	charptr = NULL;
425	opcode = parse_token(arg, filename, linenum);
426	switch (opcode) {
427	case sBadOption:
428		return -1;
429	case sPort:
430		/* ignore ports from configfile if cmdline specifies ports */
431		if (options->ports_from_cmdline)
432			return 0;
433		if (options->listen_addrs != NULL)
434			fatal("%s line %d: ports must be specified before "
435			    "ListenAddress.", filename, linenum);
436		if (options->num_ports >= MAX_PORTS)
437			fatal("%s line %d: too many ports.",
438			    filename, linenum);
439		arg = strdelim(&cp);
440		if (!arg || *arg == '\0')
441			fatal("%s line %d: missing port number.",
442			    filename, linenum);
443		options->ports[options->num_ports++] = a2port(arg);
444		if (options->ports[options->num_ports-1] == 0)
445			fatal("%s line %d: Badly formatted port number.",
446			    filename, linenum);
447		break;
448
449	case sServerKeyBits:
450		intptr = &options->server_key_bits;
451parse_int:
452		arg = strdelim(&cp);
453		if (!arg || *arg == '\0')
454			fatal("%s line %d: missing integer value.",
455			    filename, linenum);
456		value = atoi(arg);
457		if (*intptr == -1)
458			*intptr = value;
459		break;
460
461	case sLoginGraceTime:
462		intptr = &options->login_grace_time;
463parse_time:
464		arg = strdelim(&cp);
465		if (!arg || *arg == '\0')
466			fatal("%s line %d: missing time value.",
467			    filename, linenum);
468		if ((value = convtime(arg)) == -1)
469			fatal("%s line %d: invalid time value.",
470			    filename, linenum);
471		if (*intptr == -1)
472			*intptr = value;
473		break;
474
475	case sKeyRegenerationTime:
476		intptr = &options->key_regeneration_time;
477		goto parse_time;
478
479	case sListenAddress:
480		arg = strdelim(&cp);
481		if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
482			fatal("%s line %d: missing inet addr.",
483			    filename, linenum);
484		if (*arg == '[') {
485			if ((p = strchr(arg, ']')) == NULL)
486				fatal("%s line %d: bad ipv6 inet addr usage.",
487				    filename, linenum);
488			arg++;
489			memmove(p, p+1, strlen(p+1)+1);
490		} else if (((p = strchr(arg, ':')) == NULL) ||
491			    (strchr(p+1, ':') != NULL)) {
492			add_listen_addr(options, arg, 0);
493			break;
494		}
495		if (*p == ':') {
496			u_short port;
497
498			p++;
499			if (*p == '\0')
500				fatal("%s line %d: bad inet addr:port usage.",
501				    filename, linenum);
502			else {
503				*(p-1) = '\0';
504				if ((port = a2port(p)) == 0)
505					fatal("%s line %d: bad port number.",
506					    filename, linenum);
507				add_listen_addr(options, arg, port);
508			}
509		} else if (*p == '\0')
510			add_listen_addr(options, arg, 0);
511		else
512			fatal("%s line %d: bad inet addr usage.",
513			    filename, linenum);
514		break;
515
516	case sHostKeyFile:
517		intptr = &options->num_host_key_files;
518		if (*intptr >= MAX_HOSTKEYS)
519			fatal("%s line %d: too many host keys specified (max %d).",
520			    filename, linenum, MAX_HOSTKEYS);
521		charptr = &options->host_key_files[*intptr];
522parse_filename:
523		arg = strdelim(&cp);
524		if (!arg || *arg == '\0')
525			fatal("%s line %d: missing file name.",
526			    filename, linenum);
527		if (*charptr == NULL) {
528			*charptr = tilde_expand_filename(arg, getuid());
529			/* increase optional counter */
530			if (intptr != NULL)
531				*intptr = *intptr + 1;
532		}
533		break;
534
535	case sPidFile:
536		charptr = &options->pid_file;
537		goto parse_filename;
538
539	case sPermitRootLogin:
540		intptr = &options->permit_root_login;
541		arg = strdelim(&cp);
542		if (!arg || *arg == '\0')
543			fatal("%s line %d: missing yes/"
544			    "without-password/forced-commands-only/no "
545			    "argument.", filename, linenum);
546		value = 0;	/* silence compiler */
547		if (strcmp(arg, "without-password") == 0)
548			value = PERMIT_NO_PASSWD;
549		else if (strcmp(arg, "forced-commands-only") == 0)
550			value = PERMIT_FORCED_ONLY;
551		else if (strcmp(arg, "yes") == 0)
552			value = PERMIT_YES;
553		else if (strcmp(arg, "no") == 0)
554			value = PERMIT_NO;
555		else
556			fatal("%s line %d: Bad yes/"
557			    "without-password/forced-commands-only/no "
558			    "argument: %s", filename, linenum, arg);
559		if (*intptr == -1)
560			*intptr = value;
561		break;
562
563	case sIgnoreRhosts:
564		intptr = &options->ignore_rhosts;
565parse_flag:
566		arg = strdelim(&cp);
567		if (!arg || *arg == '\0')
568			fatal("%s line %d: missing yes/no argument.",
569			    filename, linenum);
570		value = 0;	/* silence compiler */
571		if (strcmp(arg, "yes") == 0)
572			value = 1;
573		else if (strcmp(arg, "no") == 0)
574			value = 0;
575		else
576			fatal("%s line %d: Bad yes/no argument: %s",
577				filename, linenum, arg);
578		if (*intptr == -1)
579			*intptr = value;
580		break;
581
582	case sIgnoreUserKnownHosts:
583		intptr = &options->ignore_user_known_hosts;
584		goto parse_flag;
585
586	case sRhostsAuthentication:
587		intptr = &options->rhosts_authentication;
588		goto parse_flag;
589
590	case sRhostsRSAAuthentication:
591		intptr = &options->rhosts_rsa_authentication;
592		goto parse_flag;
593
594	case sHostbasedAuthentication:
595		intptr = &options->hostbased_authentication;
596		goto parse_flag;
597
598	case sHostbasedUsesNameFromPacketOnly:
599		intptr = &options->hostbased_uses_name_from_packet_only;
600		goto parse_flag;
601
602	case sRSAAuthentication:
603		intptr = &options->rsa_authentication;
604		goto parse_flag;
605
606	case sPubkeyAuthentication:
607		intptr = &options->pubkey_authentication;
608		goto parse_flag;
609#if defined(KRB4) || defined(KRB5)
610	case sKerberosAuthentication:
611		intptr = &options->kerberos_authentication;
612		goto parse_flag;
613
614	case sKerberosOrLocalPasswd:
615		intptr = &options->kerberos_or_local_passwd;
616		goto parse_flag;
617
618	case sKerberosTicketCleanup:
619		intptr = &options->kerberos_ticket_cleanup;
620		goto parse_flag;
621#endif
622#if defined(AFS) || defined(KRB5)
623	case sKerberosTgtPassing:
624		intptr = &options->kerberos_tgt_passing;
625		goto parse_flag;
626#endif
627#ifdef AFS
628	case sAFSTokenPassing:
629		intptr = &options->afs_token_passing;
630		goto parse_flag;
631#endif
632
633	case sPasswordAuthentication:
634		intptr = &options->password_authentication;
635		goto parse_flag;
636
637	case sKbdInteractiveAuthentication:
638		intptr = &options->kbd_interactive_authentication;
639		goto parse_flag;
640
641	case sChallengeResponseAuthentication:
642		intptr = &options->challenge_response_authentication;
643		goto parse_flag;
644
645	case sPrintMotd:
646		intptr = &options->print_motd;
647		goto parse_flag;
648
649	case sPrintLastLog:
650		intptr = &options->print_lastlog;
651		goto parse_flag;
652
653	case sX11Forwarding:
654		intptr = &options->x11_forwarding;
655		goto parse_flag;
656
657	case sX11DisplayOffset:
658		intptr = &options->x11_display_offset;
659		goto parse_int;
660
661	case sX11UseLocalhost:
662		intptr = &options->x11_use_localhost;
663		goto parse_flag;
664
665	case sXAuthLocation:
666		charptr = &options->xauth_location;
667		goto parse_filename;
668
669	case sStrictModes:
670		intptr = &options->strict_modes;
671		goto parse_flag;
672
673	case sKeepAlives:
674		intptr = &options->keepalives;
675		goto parse_flag;
676
677	case sEmptyPasswd:
678		intptr = &options->permit_empty_passwd;
679		goto parse_flag;
680
681	case sUseLogin:
682		intptr = &options->use_login;
683		goto parse_flag;
684
685	case sGatewayPorts:
686		intptr = &options->gateway_ports;
687		goto parse_flag;
688
689	case sVerifyReverseMapping:
690		intptr = &options->verify_reverse_mapping;
691		goto parse_flag;
692
693	case sLogFacility:
694		intptr = (int *) &options->log_facility;
695		arg = strdelim(&cp);
696		value = log_facility_number(arg);
697		if (value == SYSLOG_FACILITY_NOT_SET)
698			fatal("%.200s line %d: unsupported log facility '%s'",
699			    filename, linenum, arg ? arg : "<NONE>");
700		if (*intptr == -1)
701			*intptr = (SyslogFacility) value;
702		break;
703
704	case sLogLevel:
705		intptr = (int *) &options->log_level;
706		arg = strdelim(&cp);
707		value = log_level_number(arg);
708		if (value == SYSLOG_LEVEL_NOT_SET)
709			fatal("%.200s line %d: unsupported log level '%s'",
710			    filename, linenum, arg ? arg : "<NONE>");
711		if (*intptr == -1)
712			*intptr = (LogLevel) value;
713		break;
714
715	case sAllowTcpForwarding:
716		intptr = &options->allow_tcp_forwarding;
717		goto parse_flag;
718
719	case sAllowUsers:
720		while ((arg = strdelim(&cp)) && *arg != '\0') {
721			if (options->num_allow_users >= MAX_ALLOW_USERS)
722				fatal("%s line %d: too many allow users.",
723				    filename, linenum);
724			options->allow_users[options->num_allow_users++] = xstrdup(arg);
725		}
726		break;
727
728	case sDenyUsers:
729		while ((arg = strdelim(&cp)) && *arg != '\0') {
730			if (options->num_deny_users >= MAX_DENY_USERS)
731				fatal( "%s line %d: too many deny users.",
732				    filename, linenum);
733			options->deny_users[options->num_deny_users++] = xstrdup(arg);
734		}
735		break;
736
737	case sAllowGroups:
738		while ((arg = strdelim(&cp)) && *arg != '\0') {
739			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
740				fatal("%s line %d: too many allow groups.",
741				    filename, linenum);
742			options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
743		}
744		break;
745
746	case sDenyGroups:
747		while ((arg = strdelim(&cp)) && *arg != '\0') {
748			if (options->num_deny_groups >= MAX_DENY_GROUPS)
749				fatal("%s line %d: too many deny groups.",
750				    filename, linenum);
751			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
752		}
753		break;
754
755	case sCiphers:
756		arg = strdelim(&cp);
757		if (!arg || *arg == '\0')
758			fatal("%s line %d: Missing argument.", filename, linenum);
759		if (!ciphers_valid(arg))
760			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
761			    filename, linenum, arg ? arg : "<NONE>");
762		if (options->ciphers == NULL)
763			options->ciphers = xstrdup(arg);
764		break;
765
766	case sMacs:
767		arg = strdelim(&cp);
768		if (!arg || *arg == '\0')
769			fatal("%s line %d: Missing argument.", filename, linenum);
770		if (!mac_valid(arg))
771			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
772			    filename, linenum, arg ? arg : "<NONE>");
773		if (options->macs == NULL)
774			options->macs = xstrdup(arg);
775		break;
776
777	case sProtocol:
778		intptr = &options->protocol;
779		arg = strdelim(&cp);
780		if (!arg || *arg == '\0')
781			fatal("%s line %d: Missing argument.", filename, linenum);
782		value = proto_spec(arg);
783		if (value == SSH_PROTO_UNKNOWN)
784			fatal("%s line %d: Bad protocol spec '%s'.",
785			    filename, linenum, arg ? arg : "<NONE>");
786		if (*intptr == SSH_PROTO_UNKNOWN)
787			*intptr = value;
788		break;
789
790	case sSubsystem:
791		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
792			fatal("%s line %d: too many subsystems defined.",
793			    filename, linenum);
794		}
795		arg = strdelim(&cp);
796		if (!arg || *arg == '\0')
797			fatal("%s line %d: Missing subsystem name.",
798			    filename, linenum);
799		for (i = 0; i < options->num_subsystems; i++)
800			if (strcmp(arg, options->subsystem_name[i]) == 0)
801				fatal("%s line %d: Subsystem '%s' already defined.",
802				    filename, linenum, arg);
803		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
804		arg = strdelim(&cp);
805		if (!arg || *arg == '\0')
806			fatal("%s line %d: Missing subsystem command.",
807			    filename, linenum);
808		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
809		options->num_subsystems++;
810		break;
811
812	case sMaxStartups:
813		arg = strdelim(&cp);
814		if (!arg || *arg == '\0')
815			fatal("%s line %d: Missing MaxStartups spec.",
816			    filename, linenum);
817		if ((n = sscanf(arg, "%d:%d:%d",
818		    &options->max_startups_begin,
819		    &options->max_startups_rate,
820		    &options->max_startups)) == 3) {
821			if (options->max_startups_begin >
822			    options->max_startups ||
823			    options->max_startups_rate > 100 ||
824			    options->max_startups_rate < 1)
825				fatal("%s line %d: Illegal MaxStartups spec.",
826				    filename, linenum);
827		} else if (n != 1)
828			fatal("%s line %d: Illegal MaxStartups spec.",
829			    filename, linenum);
830		else
831			options->max_startups = options->max_startups_begin;
832		break;
833
834	case sBanner:
835		charptr = &options->banner;
836		goto parse_filename;
837	/*
838	 * These options can contain %X options expanded at
839	 * connect time, so that you can specify paths like:
840	 *
841	 * AuthorizedKeysFile	/etc/ssh_keys/%u
842	 */
843	case sAuthorizedKeysFile:
844	case sAuthorizedKeysFile2:
845		charptr = (opcode == sAuthorizedKeysFile ) ?
846		    &options->authorized_keys_file :
847		    &options->authorized_keys_file2;
848		goto parse_filename;
849
850	case sClientAliveInterval:
851		intptr = &options->client_alive_interval;
852		goto parse_time;
853
854	case sClientAliveCountMax:
855		intptr = &options->client_alive_count_max;
856		goto parse_int;
857
858	case sDeprecated:
859		log("%s line %d: Deprecated option %s",
860		    filename, linenum, arg);
861		while (arg)
862		    arg = strdelim(&cp);
863		break;
864
865	case sCheckMail:
866		intptr = &options->check_mail;
867		goto parse_flag;
868
869	case sVersionAddendum:
870		ssh_version_set_addendum(strtok(cp, "\n"));
871		do {
872			arg = strdelim(&cp);
873		} while (arg != NULL && *arg != '\0');
874		break;
875
876	default:
877		fatal("%s line %d: Missing handler for opcode %s (%d)",
878		    filename, linenum, arg, opcode);
879	}
880	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
881		fatal("%s line %d: garbage at end of line; \"%.200s\".",
882		    filename, linenum, arg);
883	return 0;
884}
885
886/* Reads the server configuration file. */
887
888void
889read_server_config(ServerOptions *options, const char *filename)
890{
891	FILE *f;
892	char line[1024];
893	int linenum;
894	int bad_options = 0;
895
896	f = fopen(filename, "r");
897	if (!f) {
898		perror(filename);
899		exit(1);
900	}
901	linenum = 0;
902	while (fgets(line, sizeof(line), f)) {
903		/* Update line number counter. */
904		linenum++;
905		if (process_server_config_line(options, line, filename, linenum) != 0)
906			bad_options++;
907	}
908	fclose(f);
909	if (bad_options > 0)
910		fatal("%s: terminating, %d bad configuration options",
911		    filename, bad_options);
912}
913