]> andersk Git - openssh.git/blame - servconf.c
- stevesk@cvs.openbsd.org 2006/07/11 20:27:56
[openssh.git] / servconf.c
CommitLineData
5b04a8bf 1/* $OpenBSD: servconf.c,v 1.152 2006/07/08 21:47:12 stevesk Exp $ */
8efc0c15 2/*
5260325f 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
6ae2364d 5 *
bcbf86ec 6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be
10 * called by a name other than "ssh" or "Secure Shell".
5260325f 11 */
8efc0c15 12
13#include "includes.h"
8efc0c15 14
5b04a8bf 15#include <sys/types.h>
16#include <sys/socket.h>
17
8efc0c15 18#include "ssh.h"
42f11eb2 19#include "log.h"
8efc0c15 20#include "servconf.h"
21#include "xmalloc.h"
a8be9f80 22#include "compat.h"
42f11eb2 23#include "pathnames.h"
42f11eb2 24#include "misc.h"
25#include "cipher.h"
b2552997 26#include "kex.h"
27#include "mac.h"
42f11eb2 28
396c147e 29static void add_listen_addr(ServerOptions *, char *, u_short);
30static void add_one_listen_addr(ServerOptions *, char *, u_short);
48e671d5 31
1853d1ef 32/* Use of privilege separation or not */
33extern int use_privsep;
42f11eb2 34
8efc0c15 35/* Initializes the server options to their default values. */
36
6ae2364d 37void
5260325f 38initialize_server_options(ServerOptions *options)
8efc0c15 39{
5260325f 40 memset(options, 0, sizeof(*options));
e15895cd 41
42 /* Portable-specific options */
7fceb20d 43 options->use_pam = -1;
e15895cd 44
45 /* Standard Options */
48e671d5 46 options->num_ports = 0;
47 options->ports_from_cmdline = 0;
48 options->listen_addrs = NULL;
31b41ceb 49 options->address_family = -1;
fa08c86b 50 options->num_host_key_files = 0;
0fbe8c74 51 options->pid_file = NULL;
5260325f 52 options->server_key_bits = -1;
53 options->login_grace_time = -1;
54 options->key_regeneration_time = -1;
15853e93 55 options->permit_root_login = PERMIT_NOT_SET;
5260325f 56 options->ignore_rhosts = -1;
57 options->ignore_user_known_hosts = -1;
58 options->print_motd = -1;
4f4648f9 59 options->print_lastlog = -1;
5260325f 60 options->x11_forwarding = -1;
61 options->x11_display_offset = -1;
e6e573bd 62 options->x11_use_localhost = -1;
fa649821 63 options->xauth_location = NULL;
5260325f 64 options->strict_modes = -1;
fd573618 65 options->tcp_keep_alive = -1;
5eaf8578 66 options->log_facility = SYSLOG_FACILITY_NOT_SET;
67 options->log_level = SYSLOG_LEVEL_NOT_SET;
5260325f 68 options->rhosts_rsa_authentication = -1;
8002af61 69 options->hostbased_authentication = -1;
70 options->hostbased_uses_name_from_packet_only = -1;
5260325f 71 options->rsa_authentication = -1;
fa08c86b 72 options->pubkey_authentication = -1;
5260325f 73 options->kerberos_authentication = -1;
74 options->kerberos_or_local_passwd = -1;
75 options->kerberos_ticket_cleanup = -1;
a1e30b47 76 options->kerberos_get_afs_token = -1;
7364bd04 77 options->gss_authentication=-1;
78 options->gss_cleanup_creds = -1;
5260325f 79 options->password_authentication = -1;
94ec8c6b 80 options->kbd_interactive_authentication = -1;
5ba55ada 81 options->challenge_response_authentication = -1;
5260325f 82 options->permit_empty_passwd = -1;
f00bab84 83 options->permit_user_env = -1;
5260325f 84 options->use_login = -1;
636f76ca 85 options->compression = -1;
33de75a3 86 options->allow_tcp_forwarding = -1;
5260325f 87 options->num_allow_users = 0;
88 options->num_deny_users = 0;
89 options->num_allow_groups = 0;
90 options->num_deny_groups = 0;
a8be9f80 91 options->ciphers = NULL;
b2552997 92 options->macs = NULL;
a8be9f80 93 options->protocol = SSH_PROTO_UNKNOWN;
1d1ffb87 94 options->gateway_ports = -1;
38c295d6 95 options->num_subsystems = 0;
c345cf9d 96 options->max_startups_begin = -1;
97 options->max_startups_rate = -1;
089fbbd2 98 options->max_startups = -1;
af4bd935 99 options->max_authtries = -1;
eea39c02 100 options->banner = NULL;
c5a7d788 101 options->use_dns = -1;
3ffc6336 102 options->client_alive_interval = -1;
103 options->client_alive_count_max = -1;
c8445989 104 options->authorized_keys_file = NULL;
105 options->authorized_keys_file2 = NULL;
61a2c1da 106 options->num_accept_env = 0;
d20f3c9e 107 options->permit_tun = -1;
1853d1ef 108
1853d1ef 109 /* Needs to be accessable in many places */
110 use_privsep = -1;
8efc0c15 111}
112
6ae2364d 113void
5260325f 114fill_default_server_options(ServerOptions *options)
8efc0c15 115{
e15895cd 116 /* Portable-specific options */
7fceb20d 117 if (options->use_pam == -1)
0a23d79f 118 options->use_pam = 0;
e15895cd 119
120 /* Standard Options */
fa08c86b 121 if (options->protocol == SSH_PROTO_UNKNOWN)
122 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
123 if (options->num_host_key_files == 0) {
124 /* fill default hostkeys for protocols */
125 if (options->protocol & SSH_PROTO_1)
0f84fe37 126 options->host_key_files[options->num_host_key_files++] =
127 _PATH_HOST_KEY_FILE;
128 if (options->protocol & SSH_PROTO_2) {
129 options->host_key_files[options->num_host_key_files++] =
130 _PATH_HOST_RSA_KEY_FILE;
131 options->host_key_files[options->num_host_key_files++] =
132 _PATH_HOST_DSA_KEY_FILE;
133 }
fa08c86b 134 }
48e671d5 135 if (options->num_ports == 0)
136 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
137 if (options->listen_addrs == NULL)
2d2a2c65 138 add_listen_addr(options, NULL, 0);
0fbe8c74 139 if (options->pid_file == NULL)
42f11eb2 140 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
5260325f 141 if (options->server_key_bits == -1)
142 options->server_key_bits = 768;
143 if (options->login_grace_time == -1)
3445ca02 144 options->login_grace_time = 120;
5260325f 145 if (options->key_regeneration_time == -1)
146 options->key_regeneration_time = 3600;
15853e93 147 if (options->permit_root_login == PERMIT_NOT_SET)
148 options->permit_root_login = PERMIT_YES;
5260325f 149 if (options->ignore_rhosts == -1)
c8d54615 150 options->ignore_rhosts = 1;
5260325f 151 if (options->ignore_user_known_hosts == -1)
152 options->ignore_user_known_hosts = 0;
5260325f 153 if (options->print_motd == -1)
154 options->print_motd = 1;
4f4648f9 155 if (options->print_lastlog == -1)
156 options->print_lastlog = 1;
5260325f 157 if (options->x11_forwarding == -1)
c8d54615 158 options->x11_forwarding = 0;
5260325f 159 if (options->x11_display_offset == -1)
c8d54615 160 options->x11_display_offset = 10;
e6e573bd 161 if (options->x11_use_localhost == -1)
162 options->x11_use_localhost = 1;
fa649821 163 if (options->xauth_location == NULL)
fd9ede94 164 options->xauth_location = _PATH_XAUTH;
5260325f 165 if (options->strict_modes == -1)
166 options->strict_modes = 1;
fd573618 167 if (options->tcp_keep_alive == -1)
168 options->tcp_keep_alive = 1;
5eaf8578 169 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
5260325f 170 options->log_facility = SYSLOG_FACILITY_AUTH;
5eaf8578 171 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
59c97189 172 options->log_level = SYSLOG_LEVEL_INFO;
5260325f 173 if (options->rhosts_rsa_authentication == -1)
c8d54615 174 options->rhosts_rsa_authentication = 0;
8002af61 175 if (options->hostbased_authentication == -1)
176 options->hostbased_authentication = 0;
177 if (options->hostbased_uses_name_from_packet_only == -1)
178 options->hostbased_uses_name_from_packet_only = 0;
5260325f 179 if (options->rsa_authentication == -1)
180 options->rsa_authentication = 1;
fa08c86b 181 if (options->pubkey_authentication == -1)
182 options->pubkey_authentication = 1;
5260325f 183 if (options->kerberos_authentication == -1)
eadc806d 184 options->kerberos_authentication = 0;
5260325f 185 if (options->kerberos_or_local_passwd == -1)
186 options->kerberos_or_local_passwd = 1;
187 if (options->kerberos_ticket_cleanup == -1)
188 options->kerberos_ticket_cleanup = 1;
a1e30b47 189 if (options->kerberos_get_afs_token == -1)
190 options->kerberos_get_afs_token = 0;
7364bd04 191 if (options->gss_authentication == -1)
192 options->gss_authentication = 0;
193 if (options->gss_cleanup_creds == -1)
194 options->gss_cleanup_creds = 1;
5260325f 195 if (options->password_authentication == -1)
196 options->password_authentication = 1;
94ec8c6b 197 if (options->kbd_interactive_authentication == -1)
198 options->kbd_interactive_authentication = 0;
5ba55ada 199 if (options->challenge_response_authentication == -1)
200 options->challenge_response_authentication = 1;
5260325f 201 if (options->permit_empty_passwd == -1)
c8d54615 202 options->permit_empty_passwd = 0;
f00bab84 203 if (options->permit_user_env == -1)
204 options->permit_user_env = 0;
5260325f 205 if (options->use_login == -1)
206 options->use_login = 0;
636f76ca 207 if (options->compression == -1)
07200973 208 options->compression = COMP_DELAYED;
33de75a3 209 if (options->allow_tcp_forwarding == -1)
210 options->allow_tcp_forwarding = 1;
1d1ffb87 211 if (options->gateway_ports == -1)
212 options->gateway_ports = 0;
089fbbd2 213 if (options->max_startups == -1)
214 options->max_startups = 10;
c345cf9d 215 if (options->max_startups_rate == -1)
216 options->max_startups_rate = 100; /* 100% */
217 if (options->max_startups_begin == -1)
218 options->max_startups_begin = options->max_startups;
af4bd935 219 if (options->max_authtries == -1)
220 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
c5a7d788 221 if (options->use_dns == -1)
222 options->use_dns = 1;
3ffc6336 223 if (options->client_alive_interval == -1)
184eed6a 224 options->client_alive_interval = 0;
3ffc6336 225 if (options->client_alive_count_max == -1)
226 options->client_alive_count_max = 3;
5df83e07 227 if (options->authorized_keys_file2 == NULL) {
228 /* authorized_keys_file2 falls back to authorized_keys_file */
229 if (options->authorized_keys_file != NULL)
230 options->authorized_keys_file2 = options->authorized_keys_file;
231 else
232 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
233 }
234 if (options->authorized_keys_file == NULL)
235 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
d20f3c9e 236 if (options->permit_tun == -1)
a4f24bf8 237 options->permit_tun = SSH_TUNMODE_NO;
1853d1ef 238
2ee1b704 239 /* Turn privilege separation on by default */
1853d1ef 240 if (use_privsep == -1)
2ee1b704 241 use_privsep = 1;
e299a298 242
4165b82e 243#ifndef HAVE_MMAP
e299a298 244 if (use_privsep && options->compression == 1) {
245 error("This platform does not support both privilege "
246 "separation and compression");
247 error("Compression disabled");
248 options->compression = 0;
249 }
250#endif
251
8efc0c15 252}
253
8efc0c15 254/* Keyword tokens. */
5260325f 255typedef enum {
256 sBadOption, /* == unknown option */
e15895cd 257 /* Portable-specific options */
7fceb20d 258 sUsePAM,
e15895cd 259 /* Standard Options */
5260325f 260 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
261 sPermitRootLogin, sLogFacility, sLogLevel,
0598d99d 262 sRhostsRSAAuthentication, sRSAAuthentication,
5260325f 263 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
a1e30b47 264 sKerberosGetAFSToken,
1c590258 265 sKerberosTgtPassing, sChallengeResponseAuthentication,
31b41ceb 266 sPasswordAuthentication, sKbdInteractiveAuthentication,
267 sListenAddress, sAddressFamily,
4f4648f9 268 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
e6e573bd 269 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
fd573618 270 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
f00bab84 271 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
33de75a3 272 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
b2552997 273 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
af4bd935 274 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
275 sMaxStartups, sMaxAuthTries,
c5a7d788 276 sBanner, sUseDNS, sHostbasedAuthentication,
184eed6a 277 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
c8445989 278 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
d20f3c9e 279 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
2ea6de2b 280 sUsePrivilegeSeparation,
a2144546 281 sDeprecated, sUnsupported
8efc0c15 282} ServerOpCodes;
283
284/* Textual representation of the tokens. */
5260325f 285static struct {
286 const char *name;
287 ServerOpCodes opcode;
288} keywords[] = {
e15895cd 289 /* Portable-specific options */
b06b11ad 290#ifdef USE_PAM
fe46678b 291 { "usepam", sUsePAM },
b06b11ad 292#else
fe46678b 293 { "usepam", sUnsupported },
b06b11ad 294#endif
fe46678b 295 { "pamauthenticationviakbdint", sDeprecated },
e15895cd 296 /* Standard Options */
5260325f 297 { "port", sPort },
298 { "hostkey", sHostKeyFile },
fa08c86b 299 { "hostdsakey", sHostKeyFile }, /* alias */
2b87da3b 300 { "pidfile", sPidFile },
5260325f 301 { "serverkeybits", sServerKeyBits },
302 { "logingracetime", sLoginGraceTime },
303 { "keyregenerationinterval", sKeyRegenerationTime },
304 { "permitrootlogin", sPermitRootLogin },
305 { "syslogfacility", sLogFacility },
306 { "loglevel", sLogLevel },
0598d99d 307 { "rhostsauthentication", sDeprecated },
5260325f 308 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
8002af61 309 { "hostbasedauthentication", sHostbasedAuthentication },
310 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
5260325f 311 { "rsaauthentication", sRSAAuthentication },
fa08c86b 312 { "pubkeyauthentication", sPubkeyAuthentication },
313 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
1c590258 314#ifdef KRB5
5260325f 315 { "kerberosauthentication", sKerberosAuthentication },
316 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
317 { "kerberosticketcleanup", sKerberosTicketCleanup },
bcfcc5f9 318#ifdef USE_AFS
a1e30b47 319 { "kerberosgetafstoken", sKerberosGetAFSToken },
309af4e5 320#else
321 { "kerberosgetafstoken", sUnsupported },
322#endif
a2144546 323#else
324 { "kerberosauthentication", sUnsupported },
325 { "kerberosorlocalpasswd", sUnsupported },
326 { "kerberosticketcleanup", sUnsupported },
a1e30b47 327 { "kerberosgetafstoken", sUnsupported },
a2144546 328#endif
8f73f7bb 329 { "kerberostgtpassing", sUnsupported },
a2144546 330 { "afstokenpassing", sUnsupported },
7364bd04 331#ifdef GSSAPI
332 { "gssapiauthentication", sGssAuthentication },
e377c083 333 { "gssapicleanupcredentials", sGssCleanupCreds },
7364bd04 334#else
335 { "gssapiauthentication", sUnsupported },
e377c083 336 { "gssapicleanupcredentials", sUnsupported },
7364bd04 337#endif
5260325f 338 { "passwordauthentication", sPasswordAuthentication },
94ec8c6b 339 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
d464095c 340 { "challengeresponseauthentication", sChallengeResponseAuthentication },
341 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
5c53a31e 342 { "checkmail", sDeprecated },
5260325f 343 { "listenaddress", sListenAddress },
31b41ceb 344 { "addressfamily", sAddressFamily },
5260325f 345 { "printmotd", sPrintMotd },
4f4648f9 346 { "printlastlog", sPrintLastLog },
5260325f 347 { "ignorerhosts", sIgnoreRhosts },
348 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
349 { "x11forwarding", sX11Forwarding },
350 { "x11displayoffset", sX11DisplayOffset },
e6e573bd 351 { "x11uselocalhost", sX11UseLocalhost },
fa649821 352 { "xauthlocation", sXAuthLocation },
5260325f 353 { "strictmodes", sStrictModes },
354 { "permitemptypasswords", sEmptyPasswd },
f00bab84 355 { "permituserenvironment", sPermitUserEnvironment },
5260325f 356 { "uselogin", sUseLogin },
636f76ca 357 { "compression", sCompression },
fd573618 358 { "tcpkeepalive", sTCPKeepAlive },
359 { "keepalive", sTCPKeepAlive }, /* obsolete alias */
33de75a3 360 { "allowtcpforwarding", sAllowTcpForwarding },
5260325f 361 { "allowusers", sAllowUsers },
362 { "denyusers", sDenyUsers },
363 { "allowgroups", sAllowGroups },
364 { "denygroups", sDenyGroups },
a8be9f80 365 { "ciphers", sCiphers },
b2552997 366 { "macs", sMacs },
a8be9f80 367 { "protocol", sProtocol },
1d1ffb87 368 { "gatewayports", sGatewayPorts },
38c295d6 369 { "subsystem", sSubsystem },
089fbbd2 370 { "maxstartups", sMaxStartups },
af4bd935 371 { "maxauthtries", sMaxAuthTries },
eea39c02 372 { "banner", sBanner },
c5a7d788 373 { "usedns", sUseDNS },
374 { "verifyreversemapping", sDeprecated },
375 { "reversemappingcheck", sDeprecated },
3ffc6336 376 { "clientaliveinterval", sClientAliveInterval },
377 { "clientalivecountmax", sClientAliveCountMax },
c8445989 378 { "authorizedkeysfile", sAuthorizedKeysFile },
379 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
1853d1ef 380 { "useprivilegeseparation", sUsePrivilegeSeparation},
61a2c1da 381 { "acceptenv", sAcceptEnv },
d20f3c9e 382 { "permittunnel", sPermitTunnel },
17a3011c 383 { NULL, sBadOption }
8efc0c15 384};
385
aa3378df 386/*
6be9a5e8 387 * Returns the number of the token pointed to by cp or sBadOption.
aa3378df 388 */
8efc0c15 389
6ae2364d 390static ServerOpCodes
5260325f 391parse_token(const char *cp, const char *filename,
392 int linenum)
8efc0c15 393{
1e3b8b07 394 u_int i;
8efc0c15 395
5260325f 396 for (i = 0; keywords[i].name; i++)
aa3378df 397 if (strcasecmp(cp, keywords[i].name) == 0)
5260325f 398 return keywords[i].opcode;
8efc0c15 399
b7c70970 400 error("%s: line %d: Bad configuration option: %s",
401 filename, linenum, cp);
5260325f 402 return sBadOption;
8efc0c15 403}
404
396c147e 405static void
2d2a2c65 406add_listen_addr(ServerOptions *options, char *addr, u_short port)
48e671d5 407{
2ceb8101 408 u_int i;
48e671d5 409
410 if (options->num_ports == 0)
411 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
31b41ceb 412 if (options->address_family == -1)
413 options->address_family = AF_UNSPEC;
2d2a2c65 414 if (port == 0)
d11c1288 415 for (i = 0; i < options->num_ports; i++)
416 add_one_listen_addr(options, addr, options->ports[i]);
417 else
2d2a2c65 418 add_one_listen_addr(options, addr, port);
d11c1288 419}
420
396c147e 421static void
d11c1288 422add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
423{
424 struct addrinfo hints, *ai, *aitop;
425 char strport[NI_MAXSERV];
426 int gaierr;
427
428 memset(&hints, 0, sizeof(hints));
31b41ceb 429 hints.ai_family = options->address_family;
d11c1288 430 hints.ai_socktype = SOCK_STREAM;
431 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
7528d467 432 snprintf(strport, sizeof strport, "%u", port);
d11c1288 433 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
434 fatal("bad addr or host: %s (%s)",
435 addr ? addr : "<NULL>",
436 gai_strerror(gaierr));
437 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
438 ;
439 ai->ai_next = options->listen_addrs;
440 options->listen_addrs = aitop;
48e671d5 441}
442
2717fa0f 443int
444process_server_config_line(ServerOptions *options, char *line,
445 const char *filename, int linenum)
8efc0c15 446{
d11c1288 447 char *cp, **charptr, *arg, *p;
2ceb8101 448 int *intptr, value, n;
5260325f 449 ServerOpCodes opcode;
3867aa0a 450 u_short port;
2ceb8101 451 u_int i;
d66ce1a1 452 size_t len;
5260325f 453
2717fa0f 454 cp = line;
0f8cd5a6 455 if ((arg = strdelim(&cp)) == NULL)
88299971 456 return 0;
2717fa0f 457 /* Ignore leading whitespace */
458 if (*arg == '\0')
704b1659 459 arg = strdelim(&cp);
2717fa0f 460 if (!arg || !*arg || *arg == '#')
461 return 0;
462 intptr = NULL;
463 charptr = NULL;
464 opcode = parse_token(arg, filename, linenum);
465 switch (opcode) {
466 /* Portable-specific options */
7fceb20d 467 case sUsePAM:
468 intptr = &options->use_pam;
2717fa0f 469 goto parse_flag;
48e671d5 470
2717fa0f 471 /* Standard Options */
472 case sBadOption:
473 return -1;
474 case sPort:
475 /* ignore ports from configfile if cmdline specifies ports */
476 if (options->ports_from_cmdline)
477 return 0;
478 if (options->listen_addrs != NULL)
479 fatal("%s line %d: ports must be specified before "
3a454b6a 480 "ListenAddress.", filename, linenum);
2717fa0f 481 if (options->num_ports >= MAX_PORTS)
482 fatal("%s line %d: too many ports.",
483 filename, linenum);
484 arg = strdelim(&cp);
485 if (!arg || *arg == '\0')
486 fatal("%s line %d: missing port number.",
487 filename, linenum);
488 options->ports[options->num_ports++] = a2port(arg);
489 if (options->ports[options->num_ports-1] == 0)
490 fatal("%s line %d: Badly formatted port number.",
491 filename, linenum);
492 break;
493
494 case sServerKeyBits:
495 intptr = &options->server_key_bits;
5260325f 496parse_int:
2717fa0f 497 arg = strdelim(&cp);
498 if (!arg || *arg == '\0')
499 fatal("%s line %d: missing integer value.",
500 filename, linenum);
501 value = atoi(arg);
502 if (*intptr == -1)
503 *intptr = value;
504 break;
505
506 case sLoginGraceTime:
507 intptr = &options->login_grace_time;
e2b1fb42 508parse_time:
2717fa0f 509 arg = strdelim(&cp);
510 if (!arg || *arg == '\0')
511 fatal("%s line %d: missing time value.",
512 filename, linenum);
513 if ((value = convtime(arg)) == -1)
514 fatal("%s line %d: invalid time value.",
515 filename, linenum);
516 if (*intptr == -1)
517 *intptr = value;
518 break;
519
520 case sKeyRegenerationTime:
521 intptr = &options->key_regeneration_time;
522 goto parse_time;
523
524 case sListenAddress:
525 arg = strdelim(&cp);
3867aa0a 526 if (arg == NULL || *arg == '\0')
527 fatal("%s line %d: missing address",
2717fa0f 528 filename, linenum);
91135a0e 529 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
530 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
531 && strchr(p+1, ':') != NULL) {
532 add_listen_addr(options, arg, 0);
533 break;
534 }
3867aa0a 535 p = hpdelim(&arg);
536 if (p == NULL)
537 fatal("%s line %d: bad address:port usage",
2717fa0f 538 filename, linenum);
3867aa0a 539 p = cleanhostname(p);
540 if (arg == NULL)
541 port = 0;
542 else if ((port = a2port(arg)) == 0)
543 fatal("%s line %d: bad port number", filename, linenum);
544
545 add_listen_addr(options, p, port);
546
2717fa0f 547 break;
548
31b41ceb 549 case sAddressFamily:
550 arg = strdelim(&cp);
38634ff6 551 if (!arg || *arg == '\0')
552 fatal("%s line %d: missing address family.",
553 filename, linenum);
31b41ceb 554 intptr = &options->address_family;
555 if (options->listen_addrs != NULL)
556 fatal("%s line %d: address family must be specified before "
557 "ListenAddress.", filename, linenum);
558 if (strcasecmp(arg, "inet") == 0)
559 value = AF_INET;
560 else if (strcasecmp(arg, "inet6") == 0)
561 value = AF_INET6;
562 else if (strcasecmp(arg, "any") == 0)
563 value = AF_UNSPEC;
564 else
565 fatal("%s line %d: unsupported address family \"%s\".",
566 filename, linenum, arg);
567 if (*intptr == -1)
568 *intptr = value;
569 break;
570
2717fa0f 571 case sHostKeyFile:
572 intptr = &options->num_host_key_files;
573 if (*intptr >= MAX_HOSTKEYS)
574 fatal("%s line %d: too many host keys specified (max %d).",
575 filename, linenum, MAX_HOSTKEYS);
576 charptr = &options->host_key_files[*intptr];
fa649821 577parse_filename:
2717fa0f 578 arg = strdelim(&cp);
579 if (!arg || *arg == '\0')
580 fatal("%s line %d: missing file name.",
581 filename, linenum);
582 if (*charptr == NULL) {
583 *charptr = tilde_expand_filename(arg, getuid());
584 /* increase optional counter */
585 if (intptr != NULL)
586 *intptr = *intptr + 1;
587 }
588 break;
0fbe8c74 589
2717fa0f 590 case sPidFile:
591 charptr = &options->pid_file;
592 goto parse_filename;
5260325f 593
2717fa0f 594 case sPermitRootLogin:
595 intptr = &options->permit_root_login;
596 arg = strdelim(&cp);
597 if (!arg || *arg == '\0')
598 fatal("%s line %d: missing yes/"
599 "without-password/forced-commands-only/no "
600 "argument.", filename, linenum);
601 value = 0; /* silence compiler */
602 if (strcmp(arg, "without-password") == 0)
603 value = PERMIT_NO_PASSWD;
604 else if (strcmp(arg, "forced-commands-only") == 0)
605 value = PERMIT_FORCED_ONLY;
606 else if (strcmp(arg, "yes") == 0)
607 value = PERMIT_YES;
608 else if (strcmp(arg, "no") == 0)
609 value = PERMIT_NO;
610 else
611 fatal("%s line %d: Bad yes/"
612 "without-password/forced-commands-only/no "
613 "argument: %s", filename, linenum, arg);
614 if (*intptr == -1)
615 *intptr = value;
616 break;
617
618 case sIgnoreRhosts:
619 intptr = &options->ignore_rhosts;
5260325f 620parse_flag:
2717fa0f 621 arg = strdelim(&cp);
622 if (!arg || *arg == '\0')
623 fatal("%s line %d: missing yes/no argument.",
624 filename, linenum);
625 value = 0; /* silence compiler */
626 if (strcmp(arg, "yes") == 0)
627 value = 1;
628 else if (strcmp(arg, "no") == 0)
629 value = 0;
630 else
631 fatal("%s line %d: Bad yes/no argument: %s",
632 filename, linenum, arg);
633 if (*intptr == -1)
634 *intptr = value;
635 break;
636
637 case sIgnoreUserKnownHosts:
638 intptr = &options->ignore_user_known_hosts;
639 goto parse_flag;
640
2717fa0f 641 case sRhostsRSAAuthentication:
642 intptr = &options->rhosts_rsa_authentication;
643 goto parse_flag;
644
645 case sHostbasedAuthentication:
646 intptr = &options->hostbased_authentication;
647 goto parse_flag;
648
649 case sHostbasedUsesNameFromPacketOnly:
650 intptr = &options->hostbased_uses_name_from_packet_only;
651 goto parse_flag;
652
653 case sRSAAuthentication:
654 intptr = &options->rsa_authentication;
655 goto parse_flag;
656
657 case sPubkeyAuthentication:
658 intptr = &options->pubkey_authentication;
659 goto parse_flag;
d0ec7f42 660
2717fa0f 661 case sKerberosAuthentication:
662 intptr = &options->kerberos_authentication;
663 goto parse_flag;
5260325f 664
2717fa0f 665 case sKerberosOrLocalPasswd:
666 intptr = &options->kerberos_or_local_passwd;
667 goto parse_flag;
5260325f 668
2717fa0f 669 case sKerberosTicketCleanup:
670 intptr = &options->kerberos_ticket_cleanup;
671 goto parse_flag;
d0ec7f42 672
a1e30b47 673 case sKerberosGetAFSToken:
674 intptr = &options->kerberos_get_afs_token;
675 goto parse_flag;
676
7364bd04 677 case sGssAuthentication:
678 intptr = &options->gss_authentication;
679 goto parse_flag;
680
681 case sGssCleanupCreds:
682 intptr = &options->gss_cleanup_creds;
683 goto parse_flag;
684
2717fa0f 685 case sPasswordAuthentication:
686 intptr = &options->password_authentication;
687 goto parse_flag;
5260325f 688
2717fa0f 689 case sKbdInteractiveAuthentication:
690 intptr = &options->kbd_interactive_authentication;
691 goto parse_flag;
8002af61 692
2717fa0f 693 case sChallengeResponseAuthentication:
694 intptr = &options->challenge_response_authentication;
695 goto parse_flag;
8002af61 696
2717fa0f 697 case sPrintMotd:
698 intptr = &options->print_motd;
699 goto parse_flag;
5260325f 700
2717fa0f 701 case sPrintLastLog:
702 intptr = &options->print_lastlog;
703 goto parse_flag;
5260325f 704
2717fa0f 705 case sX11Forwarding:
706 intptr = &options->x11_forwarding;
707 goto parse_flag;
5260325f 708
2717fa0f 709 case sX11DisplayOffset:
710 intptr = &options->x11_display_offset;
711 goto parse_int;
8efc0c15 712
e6e573bd 713 case sX11UseLocalhost:
714 intptr = &options->x11_use_localhost;
715 goto parse_flag;
716
2717fa0f 717 case sXAuthLocation:
718 charptr = &options->xauth_location;
719 goto parse_filename;
5260325f 720
2717fa0f 721 case sStrictModes:
722 intptr = &options->strict_modes;
723 goto parse_flag;
5260325f 724
fd573618 725 case sTCPKeepAlive:
726 intptr = &options->tcp_keep_alive;
2717fa0f 727 goto parse_flag;
33de75a3 728
2717fa0f 729 case sEmptyPasswd:
730 intptr = &options->permit_empty_passwd;
731 goto parse_flag;
5260325f 732
f00bab84 733 case sPermitUserEnvironment:
734 intptr = &options->permit_user_env;
735 goto parse_flag;
736
2717fa0f 737 case sUseLogin:
738 intptr = &options->use_login;
739 goto parse_flag;
5260325f 740
636f76ca 741 case sCompression:
742 intptr = &options->compression;
07200973 743 arg = strdelim(&cp);
744 if (!arg || *arg == '\0')
745 fatal("%s line %d: missing yes/no/delayed "
746 "argument.", filename, linenum);
747 value = 0; /* silence compiler */
748 if (strcmp(arg, "delayed") == 0)
749 value = COMP_DELAYED;
750 else if (strcmp(arg, "yes") == 0)
751 value = COMP_ZLIB;
752 else if (strcmp(arg, "no") == 0)
753 value = COMP_NONE;
754 else
755 fatal("%s line %d: Bad yes/no/delayed "
756 "argument: %s", filename, linenum, arg);
757 if (*intptr == -1)
758 *intptr = value;
759 break;
636f76ca 760
2717fa0f 761 case sGatewayPorts:
762 intptr = &options->gateway_ports;
3867aa0a 763 arg = strdelim(&cp);
764 if (!arg || *arg == '\0')
765 fatal("%s line %d: missing yes/no/clientspecified "
766 "argument.", filename, linenum);
767 value = 0; /* silence compiler */
768 if (strcmp(arg, "clientspecified") == 0)
769 value = 2;
770 else if (strcmp(arg, "yes") == 0)
771 value = 1;
772 else if (strcmp(arg, "no") == 0)
773 value = 0;
774 else
775 fatal("%s line %d: Bad yes/no/clientspecified "
776 "argument: %s", filename, linenum, arg);
777 if (*intptr == -1)
778 *intptr = value;
779 break;
5260325f 780
c5a7d788 781 case sUseDNS:
782 intptr = &options->use_dns;
2717fa0f 783 goto parse_flag;
5260325f 784
2717fa0f 785 case sLogFacility:
786 intptr = (int *) &options->log_facility;
787 arg = strdelim(&cp);
788 value = log_facility_number(arg);
5eaf8578 789 if (value == SYSLOG_FACILITY_NOT_SET)
2717fa0f 790 fatal("%.200s line %d: unsupported log facility '%s'",
791 filename, linenum, arg ? arg : "<NONE>");
792 if (*intptr == -1)
793 *intptr = (SyslogFacility) value;
794 break;
795
796 case sLogLevel:
797 intptr = (int *) &options->log_level;
798 arg = strdelim(&cp);
799 value = log_level_number(arg);
5eaf8578 800 if (value == SYSLOG_LEVEL_NOT_SET)
2717fa0f 801 fatal("%.200s line %d: unsupported log level '%s'",
802 filename, linenum, arg ? arg : "<NONE>");
803 if (*intptr == -1)
804 *intptr = (LogLevel) value;
805 break;
806
807 case sAllowTcpForwarding:
808 intptr = &options->allow_tcp_forwarding;
809 goto parse_flag;
810
1853d1ef 811 case sUsePrivilegeSeparation:
812 intptr = &use_privsep;
813 goto parse_flag;
814
2717fa0f 815 case sAllowUsers:
816 while ((arg = strdelim(&cp)) && *arg != '\0') {
817 if (options->num_allow_users >= MAX_ALLOW_USERS)
818 fatal("%s line %d: too many allow users.",
819 filename, linenum);
7528d467 820 options->allow_users[options->num_allow_users++] =
821 xstrdup(arg);
2717fa0f 822 }
823 break;
a8be9f80 824
2717fa0f 825 case sDenyUsers:
826 while ((arg = strdelim(&cp)) && *arg != '\0') {
827 if (options->num_deny_users >= MAX_DENY_USERS)
828 fatal( "%s line %d: too many deny users.",
829 filename, linenum);
7528d467 830 options->deny_users[options->num_deny_users++] =
831 xstrdup(arg);
2717fa0f 832 }
833 break;
b2552997 834
2717fa0f 835 case sAllowGroups:
836 while ((arg = strdelim(&cp)) && *arg != '\0') {
837 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
838 fatal("%s line %d: too many allow groups.",
839 filename, linenum);
7528d467 840 options->allow_groups[options->num_allow_groups++] =
841 xstrdup(arg);
2717fa0f 842 }
843 break;
a8be9f80 844
2717fa0f 845 case sDenyGroups:
846 while ((arg = strdelim(&cp)) && *arg != '\0') {
847 if (options->num_deny_groups >= MAX_DENY_GROUPS)
848 fatal("%s line %d: too many deny groups.",
849 filename, linenum);
850 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
851 }
852 break;
38c295d6 853
2717fa0f 854 case sCiphers:
855 arg = strdelim(&cp);
856 if (!arg || *arg == '\0')
857 fatal("%s line %d: Missing argument.", filename, linenum);
858 if (!ciphers_valid(arg))
859 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
860 filename, linenum, arg ? arg : "<NONE>");
861 if (options->ciphers == NULL)
862 options->ciphers = xstrdup(arg);
863 break;
864
865 case sMacs:
866 arg = strdelim(&cp);
867 if (!arg || *arg == '\0')
868 fatal("%s line %d: Missing argument.", filename, linenum);
869 if (!mac_valid(arg))
870 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
871 filename, linenum, arg ? arg : "<NONE>");
872 if (options->macs == NULL)
873 options->macs = xstrdup(arg);
874 break;
875
876 case sProtocol:
877 intptr = &options->protocol;
878 arg = strdelim(&cp);
879 if (!arg || *arg == '\0')
880 fatal("%s line %d: Missing argument.", filename, linenum);
881 value = proto_spec(arg);
882 if (value == SSH_PROTO_UNKNOWN)
883 fatal("%s line %d: Bad protocol spec '%s'.",
184eed6a 884 filename, linenum, arg ? arg : "<NONE>");
2717fa0f 885 if (*intptr == SSH_PROTO_UNKNOWN)
886 *intptr = value;
887 break;
888
889 case sSubsystem:
890 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
891 fatal("%s line %d: too many subsystems defined.",
184eed6a 892 filename, linenum);
2717fa0f 893 }
894 arg = strdelim(&cp);
895 if (!arg || *arg == '\0')
896 fatal("%s line %d: Missing subsystem name.",
184eed6a 897 filename, linenum);
2717fa0f 898 for (i = 0; i < options->num_subsystems; i++)
899 if (strcmp(arg, options->subsystem_name[i]) == 0)
900 fatal("%s line %d: Subsystem '%s' already defined.",
184eed6a 901 filename, linenum, arg);
2717fa0f 902 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
903 arg = strdelim(&cp);
904 if (!arg || *arg == '\0')
905 fatal("%s line %d: Missing subsystem command.",
184eed6a 906 filename, linenum);
2717fa0f 907 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
d66ce1a1 908
909 /* Collect arguments (separate to executable) */
910 p = xstrdup(arg);
911 len = strlen(p) + 1;
912 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
913 len += 1 + strlen(arg);
914 p = xrealloc(p, 1, len);
915 strlcat(p, " ", len);
916 strlcat(p, arg, len);
917 }
918 options->subsystem_args[options->num_subsystems] = p;
2717fa0f 919 options->num_subsystems++;
920 break;
921
922 case sMaxStartups:
923 arg = strdelim(&cp);
924 if (!arg || *arg == '\0')
925 fatal("%s line %d: Missing MaxStartups spec.",
184eed6a 926 filename, linenum);
2717fa0f 927 if ((n = sscanf(arg, "%d:%d:%d",
928 &options->max_startups_begin,
929 &options->max_startups_rate,
930 &options->max_startups)) == 3) {
931 if (options->max_startups_begin >
932 options->max_startups ||
933 options->max_startups_rate > 100 ||
934 options->max_startups_rate < 1)
c345cf9d 935 fatal("%s line %d: Illegal MaxStartups spec.",
97de229c 936 filename, linenum);
2717fa0f 937 } else if (n != 1)
938 fatal("%s line %d: Illegal MaxStartups spec.",
939 filename, linenum);
940 else
941 options->max_startups = options->max_startups_begin;
942 break;
943
af4bd935 944 case sMaxAuthTries:
945 intptr = &options->max_authtries;
946 goto parse_int;
947
2717fa0f 948 case sBanner:
949 charptr = &options->banner;
950 goto parse_filename;
951 /*
952 * These options can contain %X options expanded at
953 * connect time, so that you can specify paths like:
954 *
955 * AuthorizedKeysFile /etc/ssh_keys/%u
956 */
957 case sAuthorizedKeysFile:
958 case sAuthorizedKeysFile2:
959 charptr = (opcode == sAuthorizedKeysFile ) ?
960 &options->authorized_keys_file :
961 &options->authorized_keys_file2;
962 goto parse_filename;
963
964 case sClientAliveInterval:
965 intptr = &options->client_alive_interval;
966 goto parse_time;
967
968 case sClientAliveCountMax:
969 intptr = &options->client_alive_count_max;
970 goto parse_int;
971
61a2c1da 972 case sAcceptEnv:
973 while ((arg = strdelim(&cp)) && *arg != '\0') {
974 if (strchr(arg, '=') != NULL)
975 fatal("%s line %d: Invalid environment name.",
976 filename, linenum);
977 if (options->num_accept_env >= MAX_ACCEPT_ENV)
978 fatal("%s line %d: too many allow env.",
979 filename, linenum);
980 options->accept_env[options->num_accept_env++] =
981 xstrdup(arg);
982 }
983 break;
984
d20f3c9e 985 case sPermitTunnel:
986 intptr = &options->permit_tun;
a4f24bf8 987 arg = strdelim(&cp);
988 if (!arg || *arg == '\0')
989 fatal("%s line %d: Missing yes/point-to-point/"
990 "ethernet/no argument.", filename, linenum);
991 value = 0; /* silence compiler */
992 if (strcasecmp(arg, "ethernet") == 0)
993 value = SSH_TUNMODE_ETHERNET;
994 else if (strcasecmp(arg, "point-to-point") == 0)
995 value = SSH_TUNMODE_POINTOPOINT;
996 else if (strcasecmp(arg, "yes") == 0)
997 value = SSH_TUNMODE_YES;
998 else if (strcasecmp(arg, "no") == 0)
999 value = SSH_TUNMODE_NO;
1000 else
1001 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1002 "no argument: %s", filename, linenum, arg);
1003 if (*intptr == -1)
1004 *intptr = value;
1005 break;
d20f3c9e 1006
2717fa0f 1007 case sDeprecated:
bbe88b6d 1008 logit("%s line %d: Deprecated option %s",
2717fa0f 1009 filename, linenum, arg);
1010 while (arg)
1011 arg = strdelim(&cp);
1012 break;
1013
a2144546 1014 case sUnsupported:
1015 logit("%s line %d: Unsupported option %s",
1016 filename, linenum, arg);
1017 while (arg)
1018 arg = strdelim(&cp);
1019 break;
1020
2717fa0f 1021 default:
1022 fatal("%s line %d: Missing handler for opcode %s (%d)",
1023 filename, linenum, arg, opcode);
1024 }
1025 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1026 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1027 filename, linenum, arg);
1028 return 0;
1029}
089fbbd2 1030
2717fa0f 1031/* Reads the server configuration file. */
5c53a31e 1032
2717fa0f 1033void
b9a549d7 1034load_server_config(const char *filename, Buffer *conf)
2717fa0f 1035{
b9a549d7 1036 char line[1024], *cp;
7528d467 1037 FILE *f;
2717fa0f 1038
b9a549d7 1039 debug2("%s: filename %s", __func__, filename);
1040 if ((f = fopen(filename, "r")) == NULL) {
2717fa0f 1041 perror(filename);
1042 exit(1);
1043 }
b9a549d7 1044 buffer_clear(conf);
2717fa0f 1045 while (fgets(line, sizeof(line), f)) {
b9a549d7 1046 /*
1047 * Trim out comments and strip whitespace
f2107e97 1048 * NB - preserve newlines, they are needed to reproduce
b9a549d7 1049 * line numbers later for error messages
1050 */
1051 if ((cp = strchr(line, '#')) != NULL)
1052 memcpy(cp, "\n", 2);
1053 cp = line + strspn(line, " \t\r");
1054
1055 buffer_append(conf, cp, strlen(cp));
8efc0c15 1056 }
b9a549d7 1057 buffer_append(conf, "\0", 1);
5260325f 1058 fclose(f);
b9a549d7 1059 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1060}
1061
1062void
1063parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1064{
1065 int linenum, bad_options = 0;
16acb158 1066 char *cp, *obuf, *cbuf;
b9a549d7 1067
1068 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1069
16acb158 1070 obuf = cbuf = xstrdup(buffer_ptr(conf));
861cc543 1071 linenum = 1;
f8cc7664 1072 while ((cp = strsep(&cbuf, "\n")) != NULL) {
b9a549d7 1073 if (process_server_config_line(options, cp, filename,
1074 linenum++) != 0)
1075 bad_options++;
1076 }
16acb158 1077 xfree(obuf);
b7c70970 1078 if (bad_options > 0)
1079 fatal("%s: terminating, %d bad configuration options",
1080 filename, bad_options);
8efc0c15 1081}
This page took 1.110467 seconds and 5 git commands to generate.