blob: 916215061798eca94e85d94d81a509a165fee95e [file] [log] [blame]
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001/*
Damien Miller95def091999-11-25 00:26:21 +11002 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3 * All rights reserved
Damien Miller4af51302000-04-16 11:18:38 +10004 *
Damien Millere4340be2000-09-16 13:29:08 +11005 * 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".
Damien Miller95def091999-11-25 00:26:21 +110010 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100011
12#include "includes.h"
Damien Miller33804262001-02-04 23:20:18 +110013RCSID("$OpenBSD: servconf.c,v 1.64 2001/02/03 10:08:37 markus Exp $");
Ben Lindstrom226cfa02001-01-22 05:34:40 +000014
15#ifdef KRB4
16#include <krb.h>
17#endif
18#ifdef AFS
19#include <kafs.h>
20#endif
Damien Millerd4a8b7e1999-10-27 13:42:43 +100021
22#include "ssh.h"
Ben Lindstrom226cfa02001-01-22 05:34:40 +000023#include "log.h"
Damien Millerd4a8b7e1999-10-27 13:42:43 +100024#include "servconf.h"
25#include "xmalloc.h"
Damien Miller78928792000-04-12 20:17:38 +100026#include "compat.h"
Ben Lindstrom226cfa02001-01-22 05:34:40 +000027#include "pathnames.h"
28#include "tildexpand.h"
29#include "misc.h"
30#include "cipher.h"
31
Damien Miller34132e52000-01-14 15:45:46 +110032/* add listen address */
33void add_listen_addr(ServerOptions *options, char *addr);
34
Ben Lindstrom226cfa02001-01-22 05:34:40 +000035/* AF_UNSPEC or AF_INET or AF_INET6 */
36extern int IPv4or6;
37
Damien Millerd4a8b7e1999-10-27 13:42:43 +100038/* Initializes the server options to their default values. */
39
Damien Miller4af51302000-04-16 11:18:38 +100040void
Damien Miller95def091999-11-25 00:26:21 +110041initialize_server_options(ServerOptions *options)
Damien Millerd4a8b7e1999-10-27 13:42:43 +100042{
Damien Miller95def091999-11-25 00:26:21 +110043 memset(options, 0, sizeof(*options));
Damien Miller34132e52000-01-14 15:45:46 +110044 options->num_ports = 0;
45 options->ports_from_cmdline = 0;
46 options->listen_addrs = NULL;
Damien Miller0bc1bd82000-11-13 22:57:25 +110047 options->num_host_key_files = 0;
Damien Miller6f83b8e2000-05-02 09:23:45 +100048 options->pid_file = NULL;
Damien Miller95def091999-11-25 00:26:21 +110049 options->server_key_bits = -1;
50 options->login_grace_time = -1;
51 options->key_regeneration_time = -1;
52 options->permit_root_login = -1;
53 options->ignore_rhosts = -1;
54 options->ignore_user_known_hosts = -1;
55 options->print_motd = -1;
56 options->check_mail = -1;
57 options->x11_forwarding = -1;
58 options->x11_display_offset = -1;
Damien Millerd3a18572000-06-07 19:55:44 +100059 options->xauth_location = NULL;
Damien Miller95def091999-11-25 00:26:21 +110060 options->strict_modes = -1;
61 options->keepalives = -1;
62 options->log_facility = (SyslogFacility) - 1;
63 options->log_level = (LogLevel) - 1;
64 options->rhosts_authentication = -1;
65 options->rhosts_rsa_authentication = -1;
66 options->rsa_authentication = -1;
Damien Miller0bc1bd82000-11-13 22:57:25 +110067 options->pubkey_authentication = -1;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100068#ifdef KRB4
Damien Miller95def091999-11-25 00:26:21 +110069 options->kerberos_authentication = -1;
70 options->kerberos_or_local_passwd = -1;
71 options->kerberos_ticket_cleanup = -1;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100072#endif
73#ifdef AFS
Damien Miller95def091999-11-25 00:26:21 +110074 options->kerberos_tgt_passing = -1;
75 options->afs_token_passing = -1;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100076#endif
Damien Miller95def091999-11-25 00:26:21 +110077 options->password_authentication = -1;
Damien Miller874d77b2000-10-14 16:23:11 +110078 options->kbd_interactive_authentication = -1;
Ben Lindstrom95fb2dd2001-01-23 03:12:10 +000079 options->challenge_reponse_authentication = -1;
Damien Miller95def091999-11-25 00:26:21 +110080 options->permit_empty_passwd = -1;
81 options->use_login = -1;
Damien Miller50a41ed2000-10-16 12:14:42 +110082 options->allow_tcp_forwarding = -1;
Damien Miller95def091999-11-25 00:26:21 +110083 options->num_allow_users = 0;
84 options->num_deny_users = 0;
85 options->num_allow_groups = 0;
86 options->num_deny_groups = 0;
Damien Miller78928792000-04-12 20:17:38 +100087 options->ciphers = NULL;
88 options->protocol = SSH_PROTO_UNKNOWN;
Damien Millere247cc42000-05-07 12:03:14 +100089 options->gateway_ports = -1;
Damien Millerf6d9e222000-06-18 14:50:44 +100090 options->num_subsystems = 0;
Damien Miller942da032000-08-18 13:59:06 +100091 options->max_startups_begin = -1;
92 options->max_startups_rate = -1;
Damien Miller37023962000-07-11 17:31:38 +100093 options->max_startups = -1;
Ben Lindstrom48bd7c12001-01-09 00:35:42 +000094 options->banner = NULL;
Damien Miller33804262001-02-04 23:20:18 +110095 options->reverse_mapping_check = -1;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100096}
97
Damien Miller4af51302000-04-16 11:18:38 +100098void
Damien Miller95def091999-11-25 00:26:21 +110099fill_default_server_options(ServerOptions *options)
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000100{
Damien Miller0bc1bd82000-11-13 22:57:25 +1100101 if (options->protocol == SSH_PROTO_UNKNOWN)
102 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
103 if (options->num_host_key_files == 0) {
104 /* fill default hostkeys for protocols */
105 if (options->protocol & SSH_PROTO_1)
Ben Lindstrom226cfa02001-01-22 05:34:40 +0000106 options->host_key_files[options->num_host_key_files++] = _PATH_HOST_KEY_FILE;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100107 if (options->protocol & SSH_PROTO_2)
Ben Lindstrom226cfa02001-01-22 05:34:40 +0000108 options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100109 }
Damien Miller34132e52000-01-14 15:45:46 +1100110 if (options->num_ports == 0)
111 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
112 if (options->listen_addrs == NULL)
113 add_listen_addr(options, NULL);
Damien Miller6f83b8e2000-05-02 09:23:45 +1000114 if (options->pid_file == NULL)
Ben Lindstrom226cfa02001-01-22 05:34:40 +0000115 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
Damien Miller95def091999-11-25 00:26:21 +1100116 if (options->server_key_bits == -1)
117 options->server_key_bits = 768;
118 if (options->login_grace_time == -1)
119 options->login_grace_time = 600;
120 if (options->key_regeneration_time == -1)
121 options->key_regeneration_time = 3600;
122 if (options->permit_root_login == -1)
123 options->permit_root_login = 1; /* yes */
124 if (options->ignore_rhosts == -1)
Damien Miller98c7ad62000-03-09 21:27:49 +1100125 options->ignore_rhosts = 1;
Damien Miller95def091999-11-25 00:26:21 +1100126 if (options->ignore_user_known_hosts == -1)
127 options->ignore_user_known_hosts = 0;
128 if (options->check_mail == -1)
129 options->check_mail = 0;
130 if (options->print_motd == -1)
131 options->print_motd = 1;
132 if (options->x11_forwarding == -1)
Damien Miller98c7ad62000-03-09 21:27:49 +1100133 options->x11_forwarding = 0;
Damien Miller95def091999-11-25 00:26:21 +1100134 if (options->x11_display_offset == -1)
Damien Miller98c7ad62000-03-09 21:27:49 +1100135 options->x11_display_offset = 10;
Damien Millerd3a18572000-06-07 19:55:44 +1000136#ifdef XAUTH_PATH
137 if (options->xauth_location == NULL)
138 options->xauth_location = XAUTH_PATH;
139#endif /* XAUTH_PATH */
Damien Miller95def091999-11-25 00:26:21 +1100140 if (options->strict_modes == -1)
141 options->strict_modes = 1;
142 if (options->keepalives == -1)
143 options->keepalives = 1;
144 if (options->log_facility == (SyslogFacility) (-1))
145 options->log_facility = SYSLOG_FACILITY_AUTH;
146 if (options->log_level == (LogLevel) (-1))
Ben Lindstromdb65e8f2001-01-19 04:26:52 +0000147 options->log_level = SYSLOG_LEVEL_INFO;
Damien Miller95def091999-11-25 00:26:21 +1100148 if (options->rhosts_authentication == -1)
149 options->rhosts_authentication = 0;
150 if (options->rhosts_rsa_authentication == -1)
Damien Miller98c7ad62000-03-09 21:27:49 +1100151 options->rhosts_rsa_authentication = 0;
Damien Miller95def091999-11-25 00:26:21 +1100152 if (options->rsa_authentication == -1)
153 options->rsa_authentication = 1;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100154 if (options->pubkey_authentication == -1)
155 options->pubkey_authentication = 1;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000156#ifdef KRB4
Damien Miller95def091999-11-25 00:26:21 +1100157 if (options->kerberos_authentication == -1)
158 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
159 if (options->kerberos_or_local_passwd == -1)
160 options->kerberos_or_local_passwd = 1;
161 if (options->kerberos_ticket_cleanup == -1)
162 options->kerberos_ticket_cleanup = 1;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000163#endif /* KRB4 */
164#ifdef AFS
Damien Miller95def091999-11-25 00:26:21 +1100165 if (options->kerberos_tgt_passing == -1)
166 options->kerberos_tgt_passing = 0;
167 if (options->afs_token_passing == -1)
168 options->afs_token_passing = k_hasafs();
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000169#endif /* AFS */
Damien Miller95def091999-11-25 00:26:21 +1100170 if (options->password_authentication == -1)
171 options->password_authentication = 1;
Damien Miller874d77b2000-10-14 16:23:11 +1100172 if (options->kbd_interactive_authentication == -1)
173 options->kbd_interactive_authentication = 0;
Ben Lindstrom95fb2dd2001-01-23 03:12:10 +0000174 if (options->challenge_reponse_authentication == -1)
175 options->challenge_reponse_authentication = 1;
Damien Miller95def091999-11-25 00:26:21 +1100176 if (options->permit_empty_passwd == -1)
Damien Miller98c7ad62000-03-09 21:27:49 +1100177 options->permit_empty_passwd = 0;
Damien Miller95def091999-11-25 00:26:21 +1100178 if (options->use_login == -1)
179 options->use_login = 0;
Damien Miller50a41ed2000-10-16 12:14:42 +1100180 if (options->allow_tcp_forwarding == -1)
181 options->allow_tcp_forwarding = 1;
Damien Millere247cc42000-05-07 12:03:14 +1000182 if (options->gateway_ports == -1)
183 options->gateway_ports = 0;
Damien Miller37023962000-07-11 17:31:38 +1000184 if (options->max_startups == -1)
185 options->max_startups = 10;
Damien Miller942da032000-08-18 13:59:06 +1000186 if (options->max_startups_rate == -1)
187 options->max_startups_rate = 100; /* 100% */
188 if (options->max_startups_begin == -1)
189 options->max_startups_begin = options->max_startups;
Damien Miller33804262001-02-04 23:20:18 +1100190 if (options->reverse_mapping_check == -1)
191 options->reverse_mapping_check = 0;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000192}
193
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000194/* Keyword tokens. */
Damien Miller95def091999-11-25 00:26:21 +1100195typedef enum {
196 sBadOption, /* == unknown option */
197 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
198 sPermitRootLogin, sLogFacility, sLogLevel,
199 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000200#ifdef KRB4
Damien Miller95def091999-11-25 00:26:21 +1100201 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000202#endif
203#ifdef AFS
Damien Miller95def091999-11-25 00:26:21 +1100204 sKerberosTgtPassing, sAFSTokenPassing,
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000205#endif
Ben Lindstrom95fb2dd2001-01-23 03:12:10 +0000206 sChallengeResponseAuthentication,
Damien Miller874d77b2000-10-14 16:23:11 +1100207 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
Damien Miller95def091999-11-25 00:26:21 +1100208 sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
209 sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
Damien Miller50a41ed2000-10-16 12:14:42 +1100210 sUseLogin, sAllowTcpForwarding,
211 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
Damien Miller0bc1bd82000-11-13 22:57:25 +1100212 sIgnoreUserKnownHosts, sCiphers, sProtocol, sPidFile,
213 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
Damien Miller33804262001-02-04 23:20:18 +1100214 sBanner, sReverseMappingCheck
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000215} ServerOpCodes;
216
217/* Textual representation of the tokens. */
Damien Miller95def091999-11-25 00:26:21 +1100218static struct {
219 const char *name;
220 ServerOpCodes opcode;
221} keywords[] = {
222 { "port", sPort },
223 { "hostkey", sHostKeyFile },
Damien Miller0bc1bd82000-11-13 22:57:25 +1100224 { "hostdsakey", sHostKeyFile }, /* alias */
Kevin Stevesef4eea92001-02-05 12:42:17 +0000225 { "pidfile", sPidFile },
Damien Miller95def091999-11-25 00:26:21 +1100226 { "serverkeybits", sServerKeyBits },
227 { "logingracetime", sLoginGraceTime },
228 { "keyregenerationinterval", sKeyRegenerationTime },
229 { "permitrootlogin", sPermitRootLogin },
230 { "syslogfacility", sLogFacility },
231 { "loglevel", sLogLevel },
232 { "rhostsauthentication", sRhostsAuthentication },
233 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
234 { "rsaauthentication", sRSAAuthentication },
Damien Miller0bc1bd82000-11-13 22:57:25 +1100235 { "pubkeyauthentication", sPubkeyAuthentication },
236 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000237#ifdef KRB4
Damien Miller95def091999-11-25 00:26:21 +1100238 { "kerberosauthentication", sKerberosAuthentication },
239 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
240 { "kerberosticketcleanup", sKerberosTicketCleanup },
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000241#endif
242#ifdef AFS
Damien Miller95def091999-11-25 00:26:21 +1100243 { "kerberostgtpassing", sKerberosTgtPassing },
244 { "afstokenpassing", sAFSTokenPassing },
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000245#endif
Damien Miller95def091999-11-25 00:26:21 +1100246 { "passwordauthentication", sPasswordAuthentication },
Damien Miller874d77b2000-10-14 16:23:11 +1100247 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
Ben Lindstrom95fb2dd2001-01-23 03:12:10 +0000248 { "challengeresponseauthentication", sChallengeResponseAuthentication },
249 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
Damien Miller95def091999-11-25 00:26:21 +1100250 { "checkmail", sCheckMail },
251 { "listenaddress", sListenAddress },
252 { "printmotd", sPrintMotd },
253 { "ignorerhosts", sIgnoreRhosts },
254 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
255 { "x11forwarding", sX11Forwarding },
256 { "x11displayoffset", sX11DisplayOffset },
Damien Millerd3a18572000-06-07 19:55:44 +1000257 { "xauthlocation", sXAuthLocation },
Damien Miller95def091999-11-25 00:26:21 +1100258 { "strictmodes", sStrictModes },
259 { "permitemptypasswords", sEmptyPasswd },
260 { "uselogin", sUseLogin },
261 { "randomseed", sRandomSeedFile },
262 { "keepalive", sKeepAlives },
Damien Miller50a41ed2000-10-16 12:14:42 +1100263 { "allowtcpforwarding", sAllowTcpForwarding },
Damien Miller95def091999-11-25 00:26:21 +1100264 { "allowusers", sAllowUsers },
265 { "denyusers", sDenyUsers },
266 { "allowgroups", sAllowGroups },
267 { "denygroups", sDenyGroups },
Damien Miller78928792000-04-12 20:17:38 +1000268 { "ciphers", sCiphers },
269 { "protocol", sProtocol },
Damien Millere247cc42000-05-07 12:03:14 +1000270 { "gatewayports", sGatewayPorts },
Damien Millerf6d9e222000-06-18 14:50:44 +1000271 { "subsystem", sSubsystem },
Damien Miller37023962000-07-11 17:31:38 +1000272 { "maxstartups", sMaxStartups },
Ben Lindstrom48bd7c12001-01-09 00:35:42 +0000273 { "banner", sBanner },
Damien Miller33804262001-02-04 23:20:18 +1100274 { "reversemappingcheck", sReverseMappingCheck },
Damien Miller95def091999-11-25 00:26:21 +1100275 { NULL, 0 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000276};
277
Damien Miller5428f641999-11-25 11:54:57 +1100278/*
279 * Returns the number of the token pointed to by cp of length len. Never
280 * returns if the token is not known.
281 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000282
Damien Miller4af51302000-04-16 11:18:38 +1000283static ServerOpCodes
Damien Miller95def091999-11-25 00:26:21 +1100284parse_token(const char *cp, const char *filename,
285 int linenum)
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000286{
Ben Lindstrom46c16222000-12-22 01:43:59 +0000287 u_int i;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000288
Damien Miller95def091999-11-25 00:26:21 +1100289 for (i = 0; keywords[i].name; i++)
Damien Miller5428f641999-11-25 11:54:57 +1100290 if (strcasecmp(cp, keywords[i].name) == 0)
Damien Miller95def091999-11-25 00:26:21 +1100291 return keywords[i].opcode;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000292
Damien Miller95def091999-11-25 00:26:21 +1100293 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
294 filename, linenum, cp);
295 return sBadOption;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000296}
297
Damien Miller34132e52000-01-14 15:45:46 +1100298/*
299 * add listen address
300 */
Damien Miller4af51302000-04-16 11:18:38 +1000301void
Damien Miller34132e52000-01-14 15:45:46 +1100302add_listen_addr(ServerOptions *options, char *addr)
303{
Damien Miller34132e52000-01-14 15:45:46 +1100304 struct addrinfo hints, *ai, *aitop;
305 char strport[NI_MAXSERV];
306 int gaierr;
307 int i;
308
309 if (options->num_ports == 0)
310 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
311 for (i = 0; i < options->num_ports; i++) {
312 memset(&hints, 0, sizeof(hints));
313 hints.ai_family = IPv4or6;
314 hints.ai_socktype = SOCK_STREAM;
315 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
316 snprintf(strport, sizeof strport, "%d", options->ports[i]);
317 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
318 fatal("bad addr or host: %s (%s)\n",
319 addr ? addr : "<NULL>",
320 gai_strerror(gaierr));
321 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
322 ;
323 ai->ai_next = options->listen_addrs;
324 options->listen_addrs = aitop;
325 }
326}
327
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000328/* Reads the server configuration file. */
329
Damien Miller4af51302000-04-16 11:18:38 +1000330void
Damien Miller95def091999-11-25 00:26:21 +1100331read_server_config(ServerOptions *options, const char *filename)
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000332{
Damien Miller95def091999-11-25 00:26:21 +1100333 FILE *f;
334 char line[1024];
Damien Miller37023962000-07-11 17:31:38 +1000335 char *cp, **charptr, *arg;
Damien Miller95def091999-11-25 00:26:21 +1100336 int linenum, *intptr, value;
337 int bad_options = 0;
338 ServerOpCodes opcode;
Damien Millerf6d9e222000-06-18 14:50:44 +1000339 int i;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000340
Damien Miller95def091999-11-25 00:26:21 +1100341 f = fopen(filename, "r");
342 if (!f) {
343 perror(filename);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000344 exit(1);
Damien Miller95def091999-11-25 00:26:21 +1100345 }
346 linenum = 0;
347 while (fgets(line, sizeof(line), f)) {
348 linenum++;
Damien Millerbe484b52000-07-15 14:14:16 +1000349 cp = line;
350 arg = strdelim(&cp);
351 /* Ignore leading whitespace */
352 if (*arg == '\0')
353 arg = strdelim(&cp);
Ben Lindstrom226cfa02001-01-22 05:34:40 +0000354 if (!arg || !*arg || *arg == '#')
Damien Miller95def091999-11-25 00:26:21 +1100355 continue;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100356 intptr = NULL;
357 charptr = NULL;
Damien Miller37023962000-07-11 17:31:38 +1000358 opcode = parse_token(arg, filename, linenum);
Damien Miller95def091999-11-25 00:26:21 +1100359 switch (opcode) {
360 case sBadOption:
361 bad_options++;
362 continue;
363 case sPort:
Damien Miller34132e52000-01-14 15:45:46 +1100364 /* ignore ports from configfile if cmdline specifies ports */
365 if (options->ports_from_cmdline)
366 continue;
367 if (options->listen_addrs != NULL)
368 fatal("%s line %d: ports must be specified before "
369 "ListenAdress.\n", filename, linenum);
370 if (options->num_ports >= MAX_PORTS)
371 fatal("%s line %d: too many ports.\n",
Damien Miller4af51302000-04-16 11:18:38 +1000372 filename, linenum);
Damien Millerbe484b52000-07-15 14:14:16 +1000373 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000374 if (!arg || *arg == '\0')
Damien Miller34132e52000-01-14 15:45:46 +1100375 fatal("%s line %d: missing port number.\n",
376 filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000377 options->ports[options->num_ports++] = atoi(arg);
Damien Miller34132e52000-01-14 15:45:46 +1100378 break;
379
380 case sServerKeyBits:
381 intptr = &options->server_key_bits;
Damien Miller95def091999-11-25 00:26:21 +1100382parse_int:
Damien Millerbe484b52000-07-15 14:14:16 +1000383 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000384 if (!arg || *arg == '\0') {
Damien Miller95def091999-11-25 00:26:21 +1100385 fprintf(stderr, "%s line %d: missing integer value.\n",
386 filename, linenum);
387 exit(1);
388 }
Damien Miller37023962000-07-11 17:31:38 +1000389 value = atoi(arg);
Damien Miller95def091999-11-25 00:26:21 +1100390 if (*intptr == -1)
391 *intptr = value;
392 break;
Damien Miller32265091999-11-12 11:33:04 +1100393
Damien Miller95def091999-11-25 00:26:21 +1100394 case sLoginGraceTime:
395 intptr = &options->login_grace_time;
396 goto parse_int;
397
398 case sKeyRegenerationTime:
399 intptr = &options->key_regeneration_time;
400 goto parse_int;
401
402 case sListenAddress:
Damien Millerbe484b52000-07-15 14:14:16 +1000403 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000404 if (!arg || *arg == '\0')
Damien Miller34132e52000-01-14 15:45:46 +1100405 fatal("%s line %d: missing inet addr.\n",
406 filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000407 add_listen_addr(options, arg);
Damien Miller95def091999-11-25 00:26:21 +1100408 break;
409
410 case sHostKeyFile:
Damien Miller0bc1bd82000-11-13 22:57:25 +1100411 intptr = &options->num_host_key_files;
412 if (*intptr >= MAX_HOSTKEYS) {
413 fprintf(stderr, "%s line %d: to many host keys specified (max %d).\n",
414 filename, linenum, MAX_HOSTKEYS);
415 exit(1);
416 }
417 charptr = &options->host_key_files[*intptr];
Damien Millerd3a18572000-06-07 19:55:44 +1000418parse_filename:
Damien Millerbe484b52000-07-15 14:14:16 +1000419 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000420 if (!arg || *arg == '\0') {
Damien Miller95def091999-11-25 00:26:21 +1100421 fprintf(stderr, "%s line %d: missing file name.\n",
Damien Miller6f83b8e2000-05-02 09:23:45 +1000422 filename, linenum);
423 exit(1);
424 }
Damien Miller0bc1bd82000-11-13 22:57:25 +1100425 if (*charptr == NULL) {
Damien Miller37023962000-07-11 17:31:38 +1000426 *charptr = tilde_expand_filename(arg, getuid());
Damien Miller0bc1bd82000-11-13 22:57:25 +1100427 /* increase optional counter */
428 if (intptr != NULL)
429 *intptr = *intptr + 1;
430 }
Damien Miller6f83b8e2000-05-02 09:23:45 +1000431 break;
432
433 case sPidFile:
434 charptr = &options->pid_file;
Damien Millerd3a18572000-06-07 19:55:44 +1000435 goto parse_filename;
Damien Miller95def091999-11-25 00:26:21 +1100436
437 case sRandomSeedFile:
438 fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
439 filename, linenum);
Damien Millerbe484b52000-07-15 14:14:16 +1000440 arg = strdelim(&cp);
Damien Miller95def091999-11-25 00:26:21 +1100441 break;
442
443 case sPermitRootLogin:
444 intptr = &options->permit_root_login;
Damien Millerbe484b52000-07-15 14:14:16 +1000445 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000446 if (!arg || *arg == '\0') {
Damien Miller95def091999-11-25 00:26:21 +1100447 fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
448 filename, linenum);
449 exit(1);
450 }
Damien Miller37023962000-07-11 17:31:38 +1000451 if (strcmp(arg, "without-password") == 0)
Damien Miller95def091999-11-25 00:26:21 +1100452 value = 2;
Damien Miller37023962000-07-11 17:31:38 +1000453 else if (strcmp(arg, "yes") == 0)
Damien Miller95def091999-11-25 00:26:21 +1100454 value = 1;
Damien Miller37023962000-07-11 17:31:38 +1000455 else if (strcmp(arg, "no") == 0)
Damien Miller95def091999-11-25 00:26:21 +1100456 value = 0;
457 else {
458 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
Damien Miller37023962000-07-11 17:31:38 +1000459 filename, linenum, arg);
Damien Miller95def091999-11-25 00:26:21 +1100460 exit(1);
461 }
462 if (*intptr == -1)
463 *intptr = value;
464 break;
465
466 case sIgnoreRhosts:
467 intptr = &options->ignore_rhosts;
468parse_flag:
Damien Millerbe484b52000-07-15 14:14:16 +1000469 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000470 if (!arg || *arg == '\0') {
Damien Miller95def091999-11-25 00:26:21 +1100471 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
472 filename, linenum);
473 exit(1);
474 }
Damien Miller37023962000-07-11 17:31:38 +1000475 if (strcmp(arg, "yes") == 0)
Damien Miller95def091999-11-25 00:26:21 +1100476 value = 1;
Damien Miller37023962000-07-11 17:31:38 +1000477 else if (strcmp(arg, "no") == 0)
Damien Miller95def091999-11-25 00:26:21 +1100478 value = 0;
479 else {
480 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
Damien Miller37023962000-07-11 17:31:38 +1000481 filename, linenum, arg);
Damien Miller95def091999-11-25 00:26:21 +1100482 exit(1);
483 }
484 if (*intptr == -1)
485 *intptr = value;
486 break;
487
488 case sIgnoreUserKnownHosts:
489 intptr = &options->ignore_user_known_hosts;
Damien Miller98c7ad62000-03-09 21:27:49 +1100490 goto parse_flag;
Damien Miller95def091999-11-25 00:26:21 +1100491
492 case sRhostsAuthentication:
493 intptr = &options->rhosts_authentication;
494 goto parse_flag;
495
496 case sRhostsRSAAuthentication:
497 intptr = &options->rhosts_rsa_authentication;
498 goto parse_flag;
499
500 case sRSAAuthentication:
501 intptr = &options->rsa_authentication;
502 goto parse_flag;
503
Damien Miller0bc1bd82000-11-13 22:57:25 +1100504 case sPubkeyAuthentication:
505 intptr = &options->pubkey_authentication;
Damien Millere247cc42000-05-07 12:03:14 +1000506 goto parse_flag;
507
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000508#ifdef KRB4
Damien Miller95def091999-11-25 00:26:21 +1100509 case sKerberosAuthentication:
510 intptr = &options->kerberos_authentication;
511 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000512
Damien Miller95def091999-11-25 00:26:21 +1100513 case sKerberosOrLocalPasswd:
514 intptr = &options->kerberos_or_local_passwd;
515 goto parse_flag;
516
517 case sKerberosTicketCleanup:
518 intptr = &options->kerberos_ticket_cleanup;
519 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000520#endif
Damien Miller95def091999-11-25 00:26:21 +1100521
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000522#ifdef AFS
Damien Miller95def091999-11-25 00:26:21 +1100523 case sKerberosTgtPassing:
524 intptr = &options->kerberos_tgt_passing;
525 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000526
Damien Miller95def091999-11-25 00:26:21 +1100527 case sAFSTokenPassing:
528 intptr = &options->afs_token_passing;
529 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000530#endif
531
Damien Miller95def091999-11-25 00:26:21 +1100532 case sPasswordAuthentication:
533 intptr = &options->password_authentication;
534 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000535
Damien Miller874d77b2000-10-14 16:23:11 +1100536 case sKbdInteractiveAuthentication:
537 intptr = &options->kbd_interactive_authentication;
538 goto parse_flag;
539
Damien Miller95def091999-11-25 00:26:21 +1100540 case sCheckMail:
541 intptr = &options->check_mail;
542 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000543
Ben Lindstrom95fb2dd2001-01-23 03:12:10 +0000544 case sChallengeResponseAuthentication:
545 intptr = &options->challenge_reponse_authentication;
Damien Miller95def091999-11-25 00:26:21 +1100546 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000547
Damien Miller95def091999-11-25 00:26:21 +1100548 case sPrintMotd:
549 intptr = &options->print_motd;
550 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000551
Damien Miller95def091999-11-25 00:26:21 +1100552 case sX11Forwarding:
553 intptr = &options->x11_forwarding;
554 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000555
Damien Miller95def091999-11-25 00:26:21 +1100556 case sX11DisplayOffset:
557 intptr = &options->x11_display_offset;
558 goto parse_int;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000559
Damien Millerd3a18572000-06-07 19:55:44 +1000560 case sXAuthLocation:
561 charptr = &options->xauth_location;
562 goto parse_filename;
Kevin Stevesef4eea92001-02-05 12:42:17 +0000563
Damien Miller95def091999-11-25 00:26:21 +1100564 case sStrictModes:
565 intptr = &options->strict_modes;
566 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000567
Damien Miller95def091999-11-25 00:26:21 +1100568 case sKeepAlives:
569 intptr = &options->keepalives;
570 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000571
Damien Miller95def091999-11-25 00:26:21 +1100572 case sEmptyPasswd:
573 intptr = &options->permit_empty_passwd;
574 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000575
Damien Miller95def091999-11-25 00:26:21 +1100576 case sUseLogin:
577 intptr = &options->use_login;
578 goto parse_flag;
Damien Miller5ce662a1999-11-11 17:57:39 +1100579
Damien Millere247cc42000-05-07 12:03:14 +1000580 case sGatewayPorts:
581 intptr = &options->gateway_ports;
582 goto parse_flag;
583
Damien Miller33804262001-02-04 23:20:18 +1100584 case sReverseMappingCheck:
585 intptr = &options->reverse_mapping_check;
586 goto parse_flag;
587
Damien Miller95def091999-11-25 00:26:21 +1100588 case sLogFacility:
589 intptr = (int *) &options->log_facility;
Damien Millerbe484b52000-07-15 14:14:16 +1000590 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000591 value = log_facility_number(arg);
Damien Miller95def091999-11-25 00:26:21 +1100592 if (value == (SyslogFacility) - 1)
593 fatal("%.200s line %d: unsupported log facility '%s'\n",
Damien Miller37023962000-07-11 17:31:38 +1000594 filename, linenum, arg ? arg : "<NONE>");
Damien Miller95def091999-11-25 00:26:21 +1100595 if (*intptr == -1)
596 *intptr = (SyslogFacility) value;
597 break;
598
599 case sLogLevel:
600 intptr = (int *) &options->log_level;
Damien Millerbe484b52000-07-15 14:14:16 +1000601 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000602 value = log_level_number(arg);
Damien Miller95def091999-11-25 00:26:21 +1100603 if (value == (LogLevel) - 1)
604 fatal("%.200s line %d: unsupported log level '%s'\n",
Damien Miller37023962000-07-11 17:31:38 +1000605 filename, linenum, arg ? arg : "<NONE>");
Damien Miller95def091999-11-25 00:26:21 +1100606 if (*intptr == -1)
607 *intptr = (LogLevel) value;
608 break;
609
Damien Miller50a41ed2000-10-16 12:14:42 +1100610 case sAllowTcpForwarding:
611 intptr = &options->allow_tcp_forwarding;
612 goto parse_flag;
613
Damien Miller95def091999-11-25 00:26:21 +1100614 case sAllowUsers:
Damien Millerbe484b52000-07-15 14:14:16 +1000615 while ((arg = strdelim(&cp)) && *arg != '\0') {
Damien Miller78928792000-04-12 20:17:38 +1000616 if (options->num_allow_users >= MAX_ALLOW_USERS)
617 fatal("%s line %d: too many allow users.\n",
618 filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000619 options->allow_users[options->num_allow_users++] = xstrdup(arg);
Damien Miller95def091999-11-25 00:26:21 +1100620 }
621 break;
622
623 case sDenyUsers:
Damien Millerbe484b52000-07-15 14:14:16 +1000624 while ((arg = strdelim(&cp)) && *arg != '\0') {
Damien Miller78928792000-04-12 20:17:38 +1000625 if (options->num_deny_users >= MAX_DENY_USERS)
626 fatal( "%s line %d: too many deny users.\n",
627 filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000628 options->deny_users[options->num_deny_users++] = xstrdup(arg);
Damien Miller95def091999-11-25 00:26:21 +1100629 }
630 break;
631
632 case sAllowGroups:
Damien Millerbe484b52000-07-15 14:14:16 +1000633 while ((arg = strdelim(&cp)) && *arg != '\0') {
Damien Miller78928792000-04-12 20:17:38 +1000634 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
635 fatal("%s line %d: too many allow groups.\n",
636 filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000637 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
Damien Miller95def091999-11-25 00:26:21 +1100638 }
639 break;
640
641 case sDenyGroups:
Damien Millerbe484b52000-07-15 14:14:16 +1000642 while ((arg = strdelim(&cp)) && *arg != '\0') {
Damien Miller78928792000-04-12 20:17:38 +1000643 if (options->num_deny_groups >= MAX_DENY_GROUPS)
644 fatal("%s line %d: too many deny groups.\n",
645 filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000646 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
Damien Miller95def091999-11-25 00:26:21 +1100647 }
648 break;
649
Damien Miller78928792000-04-12 20:17:38 +1000650 case sCiphers:
Damien Millerbe484b52000-07-15 14:14:16 +1000651 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000652 if (!arg || *arg == '\0')
Damien Millerb1715dc2000-05-30 13:44:51 +1000653 fatal("%s line %d: Missing argument.", filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000654 if (!ciphers_valid(arg))
Damien Miller30c3d422000-05-09 11:02:59 +1000655 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
Damien Miller37023962000-07-11 17:31:38 +1000656 filename, linenum, arg ? arg : "<NONE>");
Damien Miller78928792000-04-12 20:17:38 +1000657 if (options->ciphers == NULL)
Damien Miller37023962000-07-11 17:31:38 +1000658 options->ciphers = xstrdup(arg);
Damien Miller78928792000-04-12 20:17:38 +1000659 break;
660
661 case sProtocol:
662 intptr = &options->protocol;
Damien Millerbe484b52000-07-15 14:14:16 +1000663 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000664 if (!arg || *arg == '\0')
Damien Millerb1715dc2000-05-30 13:44:51 +1000665 fatal("%s line %d: Missing argument.", filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000666 value = proto_spec(arg);
Damien Miller78928792000-04-12 20:17:38 +1000667 if (value == SSH_PROTO_UNKNOWN)
668 fatal("%s line %d: Bad protocol spec '%s'.",
Damien Miller37023962000-07-11 17:31:38 +1000669 filename, linenum, arg ? arg : "<NONE>");
Damien Miller78928792000-04-12 20:17:38 +1000670 if (*intptr == SSH_PROTO_UNKNOWN)
671 *intptr = value;
672 break;
673
Damien Millerf6d9e222000-06-18 14:50:44 +1000674 case sSubsystem:
675 if(options->num_subsystems >= MAX_SUBSYSTEMS) {
676 fatal("%s line %d: too many subsystems defined.",
677 filename, linenum);
678 }
Damien Millerbe484b52000-07-15 14:14:16 +1000679 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000680 if (!arg || *arg == '\0')
Damien Millerf6d9e222000-06-18 14:50:44 +1000681 fatal("%s line %d: Missing subsystem name.",
682 filename, linenum);
683 for (i = 0; i < options->num_subsystems; i++)
Damien Miller37023962000-07-11 17:31:38 +1000684 if(strcmp(arg, options->subsystem_name[i]) == 0)
Damien Millerf6d9e222000-06-18 14:50:44 +1000685 fatal("%s line %d: Subsystem '%s' already defined.",
Damien Miller37023962000-07-11 17:31:38 +1000686 filename, linenum, arg);
687 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
Damien Millerbe484b52000-07-15 14:14:16 +1000688 arg = strdelim(&cp);
Damien Miller37023962000-07-11 17:31:38 +1000689 if (!arg || *arg == '\0')
Damien Millerf6d9e222000-06-18 14:50:44 +1000690 fatal("%s line %d: Missing subsystem command.",
691 filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000692 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
Damien Millerf6d9e222000-06-18 14:50:44 +1000693 options->num_subsystems++;
694 break;
695
Damien Miller37023962000-07-11 17:31:38 +1000696 case sMaxStartups:
Damien Miller942da032000-08-18 13:59:06 +1000697 arg = strdelim(&cp);
698 if (!arg || *arg == '\0')
699 fatal("%s line %d: Missing MaxStartups spec.",
700 filename, linenum);
701 if (sscanf(arg, "%d:%d:%d",
702 &options->max_startups_begin,
703 &options->max_startups_rate,
704 &options->max_startups) == 3) {
705 if (options->max_startups_begin >
706 options->max_startups ||
707 options->max_startups_rate > 100 ||
708 options->max_startups_rate < 1)
709 fatal("%s line %d: Illegal MaxStartups spec.",
710 filename, linenum);
711 break;
712 }
Damien Miller37023962000-07-11 17:31:38 +1000713 intptr = &options->max_startups;
714 goto parse_int;
715
Ben Lindstrom48bd7c12001-01-09 00:35:42 +0000716 case sBanner:
717 charptr = &options->banner;
718 goto parse_filename;
Kevin Stevesef4eea92001-02-05 12:42:17 +0000719
Damien Miller95def091999-11-25 00:26:21 +1100720 default:
721 fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
Damien Miller37023962000-07-11 17:31:38 +1000722 filename, linenum, arg, opcode);
Damien Miller95def091999-11-25 00:26:21 +1100723 exit(1);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000724 }
Damien Millerbe484b52000-07-15 14:14:16 +1000725 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
Kevin Stevesef4eea92001-02-05 12:42:17 +0000726 fprintf(stderr,
Damien Miller37023962000-07-11 17:31:38 +1000727 "%s line %d: garbage at end of line; \"%.200s\".\n",
728 filename, linenum, arg);
Damien Miller95def091999-11-25 00:26:21 +1100729 exit(1);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000730 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000731 }
Damien Miller95def091999-11-25 00:26:21 +1100732 fclose(f);
733 if (bad_options > 0) {
734 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
735 filename, bad_options);
736 exit(1);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000737 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000738}