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