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