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