]> andersk Git - openssh.git/blame - servconf.c
- djm@cvs.openbsd.org 2006/03/19 07:41:30
[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;
88299971 450 if ((arg = strdelim(&cp)) != NULL)
451 return 0;
2717fa0f 452 /* Ignore leading whitespace */
453 if (*arg == '\0')
704b1659 454 arg = strdelim(&cp);
2717fa0f 455 if (!arg || !*arg || *arg == '#')
456 return 0;
457 intptr = NULL;
458 charptr = NULL;
459 opcode = parse_token(arg, filename, linenum);
460 switch (opcode) {
461 /* Portable-specific options */
7fceb20d 462 case sUsePAM:
463 intptr = &options->use_pam;
2717fa0f 464 goto parse_flag;
48e671d5 465
2717fa0f 466 /* Standard Options */
467 case sBadOption:
468 return -1;
469 case sPort:
470 /* ignore ports from configfile if cmdline specifies ports */
471 if (options->ports_from_cmdline)
472 return 0;
473 if (options->listen_addrs != NULL)
474 fatal("%s line %d: ports must be specified before "
3a454b6a 475 "ListenAddress.", filename, linenum);
2717fa0f 476 if (options->num_ports >= MAX_PORTS)
477 fatal("%s line %d: too many ports.",
478 filename, linenum);
479 arg = strdelim(&cp);
480 if (!arg || *arg == '\0')
481 fatal("%s line %d: missing port number.",
482 filename, linenum);
483 options->ports[options->num_ports++] = a2port(arg);
484 if (options->ports[options->num_ports-1] == 0)
485 fatal("%s line %d: Badly formatted port number.",
486 filename, linenum);
487 break;
488
489 case sServerKeyBits:
490 intptr = &options->server_key_bits;
5260325f 491parse_int:
2717fa0f 492 arg = strdelim(&cp);
493 if (!arg || *arg == '\0')
494 fatal("%s line %d: missing integer value.",
495 filename, linenum);
496 value = atoi(arg);
497 if (*intptr == -1)
498 *intptr = value;
499 break;
500
501 case sLoginGraceTime:
502 intptr = &options->login_grace_time;
e2b1fb42 503parse_time:
2717fa0f 504 arg = strdelim(&cp);
505 if (!arg || *arg == '\0')
506 fatal("%s line %d: missing time value.",
507 filename, linenum);
508 if ((value = convtime(arg)) == -1)
509 fatal("%s line %d: invalid time value.",
510 filename, linenum);
511 if (*intptr == -1)
512 *intptr = value;
513 break;
514
515 case sKeyRegenerationTime:
516 intptr = &options->key_regeneration_time;
517 goto parse_time;
518
519 case sListenAddress:
520 arg = strdelim(&cp);
3867aa0a 521 if (arg == NULL || *arg == '\0')
522 fatal("%s line %d: missing address",
2717fa0f 523 filename, linenum);
91135a0e 524 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
525 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
526 && strchr(p+1, ':') != NULL) {
527 add_listen_addr(options, arg, 0);
528 break;
529 }
3867aa0a 530 p = hpdelim(&arg);
531 if (p == NULL)
532 fatal("%s line %d: bad address:port usage",
2717fa0f 533 filename, linenum);
3867aa0a 534 p = cleanhostname(p);
535 if (arg == NULL)
536 port = 0;
537 else if ((port = a2port(arg)) == 0)
538 fatal("%s line %d: bad port number", filename, linenum);
539
540 add_listen_addr(options, p, port);
541
2717fa0f 542 break;
543
31b41ceb 544 case sAddressFamily:
545 arg = strdelim(&cp);
38634ff6 546 if (!arg || *arg == '\0')
547 fatal("%s line %d: missing address family.",
548 filename, linenum);
31b41ceb 549 intptr = &options->address_family;
550 if (options->listen_addrs != NULL)
551 fatal("%s line %d: address family must be specified before "
552 "ListenAddress.", filename, linenum);
553 if (strcasecmp(arg, "inet") == 0)
554 value = AF_INET;
555 else if (strcasecmp(arg, "inet6") == 0)
556 value = AF_INET6;
557 else if (strcasecmp(arg, "any") == 0)
558 value = AF_UNSPEC;
559 else
560 fatal("%s line %d: unsupported address family \"%s\".",
561 filename, linenum, arg);
562 if (*intptr == -1)
563 *intptr = value;
564 break;
565
2717fa0f 566 case sHostKeyFile:
567 intptr = &options->num_host_key_files;
568 if (*intptr >= MAX_HOSTKEYS)
569 fatal("%s line %d: too many host keys specified (max %d).",
570 filename, linenum, MAX_HOSTKEYS);
571 charptr = &options->host_key_files[*intptr];
fa649821 572parse_filename:
2717fa0f 573 arg = strdelim(&cp);
574 if (!arg || *arg == '\0')
575 fatal("%s line %d: missing file name.",
576 filename, linenum);
577 if (*charptr == NULL) {
578 *charptr = tilde_expand_filename(arg, getuid());
579 /* increase optional counter */
580 if (intptr != NULL)
581 *intptr = *intptr + 1;
582 }
583 break;
0fbe8c74 584
2717fa0f 585 case sPidFile:
586 charptr = &options->pid_file;
587 goto parse_filename;
5260325f 588
2717fa0f 589 case sPermitRootLogin:
590 intptr = &options->permit_root_login;
591 arg = strdelim(&cp);
592 if (!arg || *arg == '\0')
593 fatal("%s line %d: missing yes/"
594 "without-password/forced-commands-only/no "
595 "argument.", filename, linenum);
596 value = 0; /* silence compiler */
597 if (strcmp(arg, "without-password") == 0)
598 value = PERMIT_NO_PASSWD;
599 else if (strcmp(arg, "forced-commands-only") == 0)
600 value = PERMIT_FORCED_ONLY;
601 else if (strcmp(arg, "yes") == 0)
602 value = PERMIT_YES;
603 else if (strcmp(arg, "no") == 0)
604 value = PERMIT_NO;
605 else
606 fatal("%s line %d: Bad yes/"
607 "without-password/forced-commands-only/no "
608 "argument: %s", filename, linenum, arg);
609 if (*intptr == -1)
610 *intptr = value;
611 break;
612
613 case sIgnoreRhosts:
614 intptr = &options->ignore_rhosts;
5260325f 615parse_flag:
2717fa0f 616 arg = strdelim(&cp);
617 if (!arg || *arg == '\0')
618 fatal("%s line %d: missing yes/no argument.",
619 filename, linenum);
620 value = 0; /* silence compiler */
621 if (strcmp(arg, "yes") == 0)
622 value = 1;
623 else if (strcmp(arg, "no") == 0)
624 value = 0;
625 else
626 fatal("%s line %d: Bad yes/no argument: %s",
627 filename, linenum, arg);
628 if (*intptr == -1)
629 *intptr = value;
630 break;
631
632 case sIgnoreUserKnownHosts:
633 intptr = &options->ignore_user_known_hosts;
634 goto parse_flag;
635
2717fa0f 636 case sRhostsRSAAuthentication:
637 intptr = &options->rhosts_rsa_authentication;
638 goto parse_flag;
639
640 case sHostbasedAuthentication:
641 intptr = &options->hostbased_authentication;
642 goto parse_flag;
643
644 case sHostbasedUsesNameFromPacketOnly:
645 intptr = &options->hostbased_uses_name_from_packet_only;
646 goto parse_flag;
647
648 case sRSAAuthentication:
649 intptr = &options->rsa_authentication;
650 goto parse_flag;
651
652 case sPubkeyAuthentication:
653 intptr = &options->pubkey_authentication;
654 goto parse_flag;
d0ec7f42 655
2717fa0f 656 case sKerberosAuthentication:
657 intptr = &options->kerberos_authentication;
658 goto parse_flag;
5260325f 659
2717fa0f 660 case sKerberosOrLocalPasswd:
661 intptr = &options->kerberos_or_local_passwd;
662 goto parse_flag;
5260325f 663
2717fa0f 664 case sKerberosTicketCleanup:
665 intptr = &options->kerberos_ticket_cleanup;
666 goto parse_flag;
d0ec7f42 667
a1e30b47 668 case sKerberosGetAFSToken:
669 intptr = &options->kerberos_get_afs_token;
670 goto parse_flag;
671
7364bd04 672 case sGssAuthentication:
673 intptr = &options->gss_authentication;
674 goto parse_flag;
675
676 case sGssCleanupCreds:
677 intptr = &options->gss_cleanup_creds;
678 goto parse_flag;
679
2717fa0f 680 case sPasswordAuthentication:
681 intptr = &options->password_authentication;
682 goto parse_flag;
5260325f 683
2717fa0f 684 case sKbdInteractiveAuthentication:
685 intptr = &options->kbd_interactive_authentication;
686 goto parse_flag;
8002af61 687
2717fa0f 688 case sChallengeResponseAuthentication:
689 intptr = &options->challenge_response_authentication;
690 goto parse_flag;
8002af61 691
2717fa0f 692 case sPrintMotd:
693 intptr = &options->print_motd;
694 goto parse_flag;
5260325f 695
2717fa0f 696 case sPrintLastLog:
697 intptr = &options->print_lastlog;
698 goto parse_flag;
5260325f 699
2717fa0f 700 case sX11Forwarding:
701 intptr = &options->x11_forwarding;
702 goto parse_flag;
5260325f 703
2717fa0f 704 case sX11DisplayOffset:
705 intptr = &options->x11_display_offset;
706 goto parse_int;
8efc0c15 707
e6e573bd 708 case sX11UseLocalhost:
709 intptr = &options->x11_use_localhost;
710 goto parse_flag;
711
2717fa0f 712 case sXAuthLocation:
713 charptr = &options->xauth_location;
714 goto parse_filename;
5260325f 715
2717fa0f 716 case sStrictModes:
717 intptr = &options->strict_modes;
718 goto parse_flag;
5260325f 719
fd573618 720 case sTCPKeepAlive:
721 intptr = &options->tcp_keep_alive;
2717fa0f 722 goto parse_flag;
33de75a3 723
2717fa0f 724 case sEmptyPasswd:
725 intptr = &options->permit_empty_passwd;
726 goto parse_flag;
5260325f 727
f00bab84 728 case sPermitUserEnvironment:
729 intptr = &options->permit_user_env;
730 goto parse_flag;
731
2717fa0f 732 case sUseLogin:
733 intptr = &options->use_login;
734 goto parse_flag;
5260325f 735
636f76ca 736 case sCompression:
737 intptr = &options->compression;
07200973 738 arg = strdelim(&cp);
739 if (!arg || *arg == '\0')
740 fatal("%s line %d: missing yes/no/delayed "
741 "argument.", filename, linenum);
742 value = 0; /* silence compiler */
743 if (strcmp(arg, "delayed") == 0)
744 value = COMP_DELAYED;
745 else if (strcmp(arg, "yes") == 0)
746 value = COMP_ZLIB;
747 else if (strcmp(arg, "no") == 0)
748 value = COMP_NONE;
749 else
750 fatal("%s line %d: Bad yes/no/delayed "
751 "argument: %s", filename, linenum, arg);
752 if (*intptr == -1)
753 *intptr = value;
754 break;
636f76ca 755
2717fa0f 756 case sGatewayPorts:
757 intptr = &options->gateway_ports;
3867aa0a 758 arg = strdelim(&cp);
759 if (!arg || *arg == '\0')
760 fatal("%s line %d: missing yes/no/clientspecified "
761 "argument.", filename, linenum);
762 value = 0; /* silence compiler */
763 if (strcmp(arg, "clientspecified") == 0)
764 value = 2;
765 else if (strcmp(arg, "yes") == 0)
766 value = 1;
767 else if (strcmp(arg, "no") == 0)
768 value = 0;
769 else
770 fatal("%s line %d: Bad yes/no/clientspecified "
771 "argument: %s", filename, linenum, arg);
772 if (*intptr == -1)
773 *intptr = value;
774 break;
5260325f 775
c5a7d788 776 case sUseDNS:
777 intptr = &options->use_dns;
2717fa0f 778 goto parse_flag;
5260325f 779
2717fa0f 780 case sLogFacility:
781 intptr = (int *) &options->log_facility;
782 arg = strdelim(&cp);
783 value = log_facility_number(arg);
5eaf8578 784 if (value == SYSLOG_FACILITY_NOT_SET)
2717fa0f 785 fatal("%.200s line %d: unsupported log facility '%s'",
786 filename, linenum, arg ? arg : "<NONE>");
787 if (*intptr == -1)
788 *intptr = (SyslogFacility) value;
789 break;
790
791 case sLogLevel:
792 intptr = (int *) &options->log_level;
793 arg = strdelim(&cp);
794 value = log_level_number(arg);
5eaf8578 795 if (value == SYSLOG_LEVEL_NOT_SET)
2717fa0f 796 fatal("%.200s line %d: unsupported log level '%s'",
797 filename, linenum, arg ? arg : "<NONE>");
798 if (*intptr == -1)
799 *intptr = (LogLevel) value;
800 break;
801
802 case sAllowTcpForwarding:
803 intptr = &options->allow_tcp_forwarding;
804 goto parse_flag;
805
1853d1ef 806 case sUsePrivilegeSeparation:
807 intptr = &use_privsep;
808 goto parse_flag;
809
2717fa0f 810 case sAllowUsers:
811 while ((arg = strdelim(&cp)) && *arg != '\0') {
812 if (options->num_allow_users >= MAX_ALLOW_USERS)
813 fatal("%s line %d: too many allow users.",
814 filename, linenum);
7528d467 815 options->allow_users[options->num_allow_users++] =
816 xstrdup(arg);
2717fa0f 817 }
818 break;
a8be9f80 819
2717fa0f 820 case sDenyUsers:
821 while ((arg = strdelim(&cp)) && *arg != '\0') {
822 if (options->num_deny_users >= MAX_DENY_USERS)
823 fatal( "%s line %d: too many deny users.",
824 filename, linenum);
7528d467 825 options->deny_users[options->num_deny_users++] =
826 xstrdup(arg);
2717fa0f 827 }
828 break;
b2552997 829
2717fa0f 830 case sAllowGroups:
831 while ((arg = strdelim(&cp)) && *arg != '\0') {
832 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
833 fatal("%s line %d: too many allow groups.",
834 filename, linenum);
7528d467 835 options->allow_groups[options->num_allow_groups++] =
836 xstrdup(arg);
2717fa0f 837 }
838 break;
a8be9f80 839
2717fa0f 840 case sDenyGroups:
841 while ((arg = strdelim(&cp)) && *arg != '\0') {
842 if (options->num_deny_groups >= MAX_DENY_GROUPS)
843 fatal("%s line %d: too many deny groups.",
844 filename, linenum);
845 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
846 }
847 break;
38c295d6 848
2717fa0f 849 case sCiphers:
850 arg = strdelim(&cp);
851 if (!arg || *arg == '\0')
852 fatal("%s line %d: Missing argument.", filename, linenum);
853 if (!ciphers_valid(arg))
854 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
855 filename, linenum, arg ? arg : "<NONE>");
856 if (options->ciphers == NULL)
857 options->ciphers = xstrdup(arg);
858 break;
859
860 case sMacs:
861 arg = strdelim(&cp);
862 if (!arg || *arg == '\0')
863 fatal("%s line %d: Missing argument.", filename, linenum);
864 if (!mac_valid(arg))
865 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
866 filename, linenum, arg ? arg : "<NONE>");
867 if (options->macs == NULL)
868 options->macs = xstrdup(arg);
869 break;
870
871 case sProtocol:
872 intptr = &options->protocol;
873 arg = strdelim(&cp);
874 if (!arg || *arg == '\0')
875 fatal("%s line %d: Missing argument.", filename, linenum);
876 value = proto_spec(arg);
877 if (value == SSH_PROTO_UNKNOWN)
878 fatal("%s line %d: Bad protocol spec '%s'.",
184eed6a 879 filename, linenum, arg ? arg : "<NONE>");
2717fa0f 880 if (*intptr == SSH_PROTO_UNKNOWN)
881 *intptr = value;
882 break;
883
884 case sSubsystem:
885 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
886 fatal("%s line %d: too many subsystems defined.",
184eed6a 887 filename, linenum);
2717fa0f 888 }
889 arg = strdelim(&cp);
890 if (!arg || *arg == '\0')
891 fatal("%s line %d: Missing subsystem name.",
184eed6a 892 filename, linenum);
2717fa0f 893 for (i = 0; i < options->num_subsystems; i++)
894 if (strcmp(arg, options->subsystem_name[i]) == 0)
895 fatal("%s line %d: Subsystem '%s' already defined.",
184eed6a 896 filename, linenum, arg);
2717fa0f 897 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
898 arg = strdelim(&cp);
899 if (!arg || *arg == '\0')
900 fatal("%s line %d: Missing subsystem command.",
184eed6a 901 filename, linenum);
2717fa0f 902 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
903 options->num_subsystems++;
904 break;
905
906 case sMaxStartups:
907 arg = strdelim(&cp);
908 if (!arg || *arg == '\0')
909 fatal("%s line %d: Missing MaxStartups spec.",
184eed6a 910 filename, linenum);
2717fa0f 911 if ((n = sscanf(arg, "%d:%d:%d",
912 &options->max_startups_begin,
913 &options->max_startups_rate,
914 &options->max_startups)) == 3) {
915 if (options->max_startups_begin >
916 options->max_startups ||
917 options->max_startups_rate > 100 ||
918 options->max_startups_rate < 1)
c345cf9d 919 fatal("%s line %d: Illegal MaxStartups spec.",
97de229c 920 filename, linenum);
2717fa0f 921 } else if (n != 1)
922 fatal("%s line %d: Illegal MaxStartups spec.",
923 filename, linenum);
924 else
925 options->max_startups = options->max_startups_begin;
926 break;
927
af4bd935 928 case sMaxAuthTries:
929 intptr = &options->max_authtries;
930 goto parse_int;
931
2717fa0f 932 case sBanner:
933 charptr = &options->banner;
934 goto parse_filename;
935 /*
936 * These options can contain %X options expanded at
937 * connect time, so that you can specify paths like:
938 *
939 * AuthorizedKeysFile /etc/ssh_keys/%u
940 */
941 case sAuthorizedKeysFile:
942 case sAuthorizedKeysFile2:
943 charptr = (opcode == sAuthorizedKeysFile ) ?
944 &options->authorized_keys_file :
945 &options->authorized_keys_file2;
946 goto parse_filename;
947
948 case sClientAliveInterval:
949 intptr = &options->client_alive_interval;
950 goto parse_time;
951
952 case sClientAliveCountMax:
953 intptr = &options->client_alive_count_max;
954 goto parse_int;
955
61a2c1da 956 case sAcceptEnv:
957 while ((arg = strdelim(&cp)) && *arg != '\0') {
958 if (strchr(arg, '=') != NULL)
959 fatal("%s line %d: Invalid environment name.",
960 filename, linenum);
961 if (options->num_accept_env >= MAX_ACCEPT_ENV)
962 fatal("%s line %d: too many allow env.",
963 filename, linenum);
964 options->accept_env[options->num_accept_env++] =
965 xstrdup(arg);
966 }
967 break;
968
d20f3c9e 969 case sPermitTunnel:
970 intptr = &options->permit_tun;
a4f24bf8 971 arg = strdelim(&cp);
972 if (!arg || *arg == '\0')
973 fatal("%s line %d: Missing yes/point-to-point/"
974 "ethernet/no argument.", filename, linenum);
975 value = 0; /* silence compiler */
976 if (strcasecmp(arg, "ethernet") == 0)
977 value = SSH_TUNMODE_ETHERNET;
978 else if (strcasecmp(arg, "point-to-point") == 0)
979 value = SSH_TUNMODE_POINTOPOINT;
980 else if (strcasecmp(arg, "yes") == 0)
981 value = SSH_TUNMODE_YES;
982 else if (strcasecmp(arg, "no") == 0)
983 value = SSH_TUNMODE_NO;
984 else
985 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
986 "no argument: %s", filename, linenum, arg);
987 if (*intptr == -1)
988 *intptr = value;
989 break;
d20f3c9e 990
2717fa0f 991 case sDeprecated:
bbe88b6d 992 logit("%s line %d: Deprecated option %s",
2717fa0f 993 filename, linenum, arg);
994 while (arg)
995 arg = strdelim(&cp);
996 break;
997
a2144546 998 case sUnsupported:
999 logit("%s line %d: Unsupported option %s",
1000 filename, linenum, arg);
1001 while (arg)
1002 arg = strdelim(&cp);
1003 break;
1004
2717fa0f 1005 default:
1006 fatal("%s line %d: Missing handler for opcode %s (%d)",
1007 filename, linenum, arg, opcode);
1008 }
1009 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1010 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1011 filename, linenum, arg);
1012 return 0;
1013}
089fbbd2 1014
2717fa0f 1015/* Reads the server configuration file. */
5c53a31e 1016
2717fa0f 1017void
b9a549d7 1018load_server_config(const char *filename, Buffer *conf)
2717fa0f 1019{
b9a549d7 1020 char line[1024], *cp;
7528d467 1021 FILE *f;
2717fa0f 1022
b9a549d7 1023 debug2("%s: filename %s", __func__, filename);
1024 if ((f = fopen(filename, "r")) == NULL) {
2717fa0f 1025 perror(filename);
1026 exit(1);
1027 }
b9a549d7 1028 buffer_clear(conf);
2717fa0f 1029 while (fgets(line, sizeof(line), f)) {
b9a549d7 1030 /*
1031 * Trim out comments and strip whitespace
f2107e97 1032 * NB - preserve newlines, they are needed to reproduce
b9a549d7 1033 * line numbers later for error messages
1034 */
1035 if ((cp = strchr(line, '#')) != NULL)
1036 memcpy(cp, "\n", 2);
1037 cp = line + strspn(line, " \t\r");
1038
1039 buffer_append(conf, cp, strlen(cp));
8efc0c15 1040 }
b9a549d7 1041 buffer_append(conf, "\0", 1);
5260325f 1042 fclose(f);
b9a549d7 1043 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1044}
1045
1046void
1047parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1048{
1049 int linenum, bad_options = 0;
16acb158 1050 char *cp, *obuf, *cbuf;
b9a549d7 1051
1052 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1053
16acb158 1054 obuf = cbuf = xstrdup(buffer_ptr(conf));
861cc543 1055 linenum = 1;
f8cc7664 1056 while ((cp = strsep(&cbuf, "\n")) != NULL) {
b9a549d7 1057 if (process_server_config_line(options, cp, filename,
1058 linenum++) != 0)
1059 bad_options++;
1060 }
16acb158 1061 xfree(obuf);
b7c70970 1062 if (bad_options > 0)
1063 fatal("%s: terminating, %d bad configuration options",
1064 filename, bad_options);
8efc0c15 1065}
This page took 2.231688 seconds and 5 git commands to generate.