]> andersk Git - gssapi-openssh.git/blame - openssh/servconf.c
Merge from OPENSSH_3_8_1P1_GSSAPI_20040713 to OPENSSH_3_9P1_GSSAPI_20040818.
[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"
1b56ff3d 13RCSID("$OpenBSD: servconf.c,v 1.137 2004/08/13 11:09:24 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
29/* AF_UNSPEC or AF_INET or AF_INET6 */
30extern int IPv4or6;
2980ea68 31/* Use of privilege separation or not */
32extern int use_privsep;
3c0ef626 33
34/* Initializes the server options to their default values. */
35
36void
37initialize_server_options(ServerOptions *options)
38{
39 memset(options, 0, sizeof(*options));
40
41 /* Portable-specific options */
70791e56 42 options->use_pam = -1;
3c0ef626 43
44 /* Standard Options */
45 options->num_ports = 0;
46 options->ports_from_cmdline = 0;
47 options->listen_addrs = NULL;
48 options->num_host_key_files = 0;
49 options->pid_file = NULL;
50 options->server_key_bits = -1;
51 options->login_grace_time = -1;
52 options->key_regeneration_time = -1;
53 options->permit_root_login = PERMIT_NOT_SET;
54 options->ignore_rhosts = -1;
55 options->ignore_user_known_hosts = -1;
56 options->print_motd = -1;
57 options->print_lastlog = -1;
58 options->x11_forwarding = -1;
59 options->x11_display_offset = -1;
e9a17296 60 options->x11_use_localhost = -1;
3c0ef626 61 options->xauth_location = NULL;
62 options->strict_modes = -1;
416fd2a8 63 options->tcp_keep_alive = -1;
e9a17296 64 options->log_facility = SYSLOG_FACILITY_NOT_SET;
65 options->log_level = SYSLOG_LEVEL_NOT_SET;
3c0ef626 66 options->rhosts_rsa_authentication = -1;
67 options->hostbased_authentication = -1;
68 options->hostbased_uses_name_from_packet_only = -1;
69 options->rsa_authentication = -1;
70 options->pubkey_authentication = -1;
3c0ef626 71 options->kerberos_authentication = -1;
72 options->kerberos_or_local_passwd = -1;
73 options->kerberos_ticket_cleanup = -1;
88928908 74#ifdef SESSION_HOOKS
75 options->session_hooks_allow = -1;
76 options->session_hooks_startup_cmd = NULL;
77 options->session_hooks_shutdown_cmd = NULL;
3c0ef626 78#endif
416fd2a8 79 options->kerberos_get_afs_token = -1;
70791e56 80 options->gss_authentication=-1;
81 options->gss_keyex=-1;
70791e56 82 options->gss_cleanup_creds = -1;
3c0ef626 83 options->password_authentication = -1;
84 options->kbd_interactive_authentication = -1;
85 options->challenge_response_authentication = -1;
86 options->permit_empty_passwd = -1;
e54b3d7c 87 options->permit_user_env = -1;
3c0ef626 88 options->use_login = -1;
ff2d7a98 89 options->compression = -1;
3c0ef626 90 options->allow_tcp_forwarding = -1;
91 options->num_allow_users = 0;
92 options->num_deny_users = 0;
93 options->num_allow_groups = 0;
94 options->num_deny_groups = 0;
95 options->ciphers = NULL;
96 options->macs = NULL;
97 options->protocol = SSH_PROTO_UNKNOWN;
98 options->gateway_ports = -1;
99 options->num_subsystems = 0;
100 options->max_startups_begin = -1;
101 options->max_startups_rate = -1;
102 options->max_startups = -1;
1b56ff3d 103 options->max_authtries = -1;
3c0ef626 104 options->banner = NULL;
70791e56 105 options->use_dns = -1;
3c0ef626 106 options->client_alive_interval = -1;
107 options->client_alive_count_max = -1;
108 options->authorized_keys_file = NULL;
109 options->authorized_keys_file2 = NULL;
1b56ff3d 110 options->num_accept_env = 0;
2980ea68 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 */
70791e56 120 if (options->use_pam == -1)
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)
e9a17296 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)
e54b3d7c 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;
e9a17296 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;
416fd2a8 170 if (options->tcp_keep_alive == -1)
171 options->tcp_keep_alive = 1;
e9a17296 172 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
3c0ef626 173 options->log_facility = SYSLOG_FACILITY_AUTH;
e9a17296 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;
70791e56 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;
416fd2a8 192 if (options->kerberos_get_afs_token == -1)
193 options->kerberos_get_afs_token = 0;
b9a54c29 194 if (options->gss_authentication == -1)
195 options->gss_authentication = 1;
196 if (options->gss_keyex == -1)
70791e56 197 options->gss_keyex = 1;
b9a54c29 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;
e54b3d7c 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;
ff2d7a98 212 if (options->compression == -1)
213 options->compression = 1;
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;
1b56ff3d 224 if (options->max_authtries == -1)
225 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
70791e56 226 if (options->use_dns == -1)
227 options->use_dns = 1;
3c0ef626 228 if (options->client_alive_interval == -1)
e9a17296 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;
2980ea68 241
ff2d7a98 242 /* Turn privilege separation on by default */
2980ea68 243 if (use_privsep == -1)
ff2d7a98 244 use_privsep = 1;
245
e54b3d7c 246#ifndef HAVE_MMAP
ff2d7a98 247 if (use_privsep && options->compression == 1) {
248 error("This platform does not support both privilege "
249 "separation and compression");
250 error("Compression disabled");
251 options->compression = 0;
252 }
253#endif
254
3c0ef626 255}
256
257/* Keyword tokens. */
258typedef enum {
259 sBadOption, /* == unknown option */
260 /* Portable-specific options */
70791e56 261 sUsePAM,
3c0ef626 262 /* Standard Options */
263 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
264 sPermitRootLogin, sLogFacility, sLogLevel,
70791e56 265 sRhostsRSAAuthentication, sRSAAuthentication,
3c0ef626 266 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
416fd2a8 267 sKerberosGetAFSToken,
70791e56 268 sKerberosTgtPassing, sChallengeResponseAuthentication,
88928908 269#ifdef SESSION_HOOKS
270 sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
3c0ef626 271#endif
3c0ef626 272 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
273 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
e9a17296 274 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
416fd2a8 275 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
e54b3d7c 276 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
3c0ef626 277 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
278 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
1b56ff3d 279 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
280 sMaxStartups, sMaxAuthTries,
70791e56 281 sBanner, sUseDNS, sHostbasedAuthentication,
e9a17296 282 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
3c0ef626 283 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
1b56ff3d 284 sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
285 sGssKeyEx,
2980ea68 286 sUsePrivilegeSeparation,
70791e56 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 */
70791e56 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 },
70791e56 313 { "rhostsauthentication", sDeprecated },
3c0ef626 314 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
315 { "hostbasedauthentication", sHostbasedAuthentication },
316 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
317 { "rsaauthentication", sRSAAuthentication },
318 { "pubkeyauthentication", sPubkeyAuthentication },
319 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
70791e56 320#ifdef KRB5
321 { "kerberosauthentication", sKerberosAuthentication },
322 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
323 { "kerberosticketcleanup", sKerberosTicketCleanup },
416fd2a8 324#ifdef USE_AFS
325 { "kerberosgetafstoken", sKerberosGetAFSToken },
326#else
327 { "kerberosgetafstoken", sUnsupported },
328#endif
70791e56 329#else
330 { "kerberosauthentication", sUnsupported },
331 { "kerberosorlocalpasswd", sUnsupported },
332 { "kerberosticketcleanup", sUnsupported },
416fd2a8 333 { "kerberosgetafstoken", sUnsupported },
70791e56 334#endif
335 { "kerberostgtpassing", sUnsupported },
336 { "afstokenpassing", sUnsupported },
b9a54c29 337#ifdef GSSAPI
338 { "gssapiauthentication", sGssAuthentication },
339 { "gssapikeyexchange", sGssKeyEx },
416fd2a8 340 { "gssapicleanupcredentials", sGssCleanupCreds },
70791e56 341#else
342 { "gssapiauthentication", sUnsupported },
343 { "gssapikeyexchange", sUnsupported },
416fd2a8 344 { "gssapicleanupcredentials", sUnsupported },
3c0ef626 345#endif
88928908 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 },
357 { "printmotd", sPrintMotd },
358 { "printlastlog", sPrintLastLog },
359 { "ignorerhosts", sIgnoreRhosts },
360 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
361 { "x11forwarding", sX11Forwarding },
362 { "x11displayoffset", sX11DisplayOffset },
e9a17296 363 { "x11uselocalhost", sX11UseLocalhost },
3c0ef626 364 { "xauthlocation", sXAuthLocation },
365 { "strictmodes", sStrictModes },
366 { "permitemptypasswords", sEmptyPasswd },
e54b3d7c 367 { "permituserenvironment", sPermitUserEnvironment },
3c0ef626 368 { "uselogin", sUseLogin },
ff2d7a98 369 { "compression", sCompression },
416fd2a8 370 { "tcpkeepalive", sTCPKeepAlive },
371 { "keepalive", sTCPKeepAlive }, /* obsolete alias */
3c0ef626 372 { "allowtcpforwarding", sAllowTcpForwarding },
373 { "allowusers", sAllowUsers },
374 { "denyusers", sDenyUsers },
375 { "allowgroups", sAllowGroups },
376 { "denygroups", sDenyGroups },
377 { "ciphers", sCiphers },
378 { "macs", sMacs },
379 { "protocol", sProtocol },
380 { "gatewayports", sGatewayPorts },
381 { "subsystem", sSubsystem },
382 { "maxstartups", sMaxStartups },
1b56ff3d 383 { "maxauthtries", sMaxAuthTries },
3c0ef626 384 { "banner", sBanner },
70791e56 385 { "usedns", sUseDNS },
386 { "verifyreversemapping", sDeprecated },
387 { "reversemappingcheck", sDeprecated },
3c0ef626 388 { "clientaliveinterval", sClientAliveInterval },
389 { "clientalivecountmax", sClientAliveCountMax },
390 { "authorizedkeysfile", sAuthorizedKeysFile },
391 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
2980ea68 392 { "useprivilegeseparation", sUsePrivilegeSeparation},
1b56ff3d 393 { "acceptenv", sAcceptEnv },
e9a17296 394 { NULL, sBadOption }
3c0ef626 395};
396
397/*
398 * Returns the number of the token pointed to by cp or sBadOption.
399 */
400
401static ServerOpCodes
402parse_token(const char *cp, const char *filename,
403 int linenum)
404{
405 u_int i;
406
407 for (i = 0; keywords[i].name; i++)
408 if (strcasecmp(cp, keywords[i].name) == 0)
409 return keywords[i].opcode;
410
411 error("%s: line %d: Bad configuration option: %s",
412 filename, linenum, cp);
413 return sBadOption;
414}
415
416static void
417add_listen_addr(ServerOptions *options, char *addr, u_short port)
418{
419 int i;
420
421 if (options->num_ports == 0)
422 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
423 if (port == 0)
424 for (i = 0; i < options->num_ports; i++)
425 add_one_listen_addr(options, addr, options->ports[i]);
426 else
427 add_one_listen_addr(options, addr, port);
428}
429
430static void
431add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
432{
433 struct addrinfo hints, *ai, *aitop;
434 char strport[NI_MAXSERV];
435 int gaierr;
436
437 memset(&hints, 0, sizeof(hints));
438 hints.ai_family = IPv4or6;
439 hints.ai_socktype = SOCK_STREAM;
440 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
ff2d7a98 441 snprintf(strport, sizeof strport, "%u", port);
3c0ef626 442 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
443 fatal("bad addr or host: %s (%s)",
444 addr ? addr : "<NULL>",
445 gai_strerror(gaierr));
446 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
447 ;
448 ai->ai_next = options->listen_addrs;
449 options->listen_addrs = aitop;
450}
451
e9a17296 452int
453process_server_config_line(ServerOptions *options, char *line,
454 const char *filename, int linenum)
3c0ef626 455{
3c0ef626 456 char *cp, **charptr, *arg, *p;
ff2d7a98 457 int *intptr, value, i, n;
3c0ef626 458 ServerOpCodes opcode;
3c0ef626 459
e9a17296 460 cp = line;
461 arg = strdelim(&cp);
462 /* Ignore leading whitespace */
463 if (*arg == '\0')
3c0ef626 464 arg = strdelim(&cp);
e9a17296 465 if (!arg || !*arg || *arg == '#')
466 return 0;
467 intptr = NULL;
468 charptr = NULL;
469 opcode = parse_token(arg, filename, linenum);
470 switch (opcode) {
471 /* Portable-specific options */
70791e56 472 case sUsePAM:
473 intptr = &options->use_pam;
e9a17296 474 goto parse_flag;
3c0ef626 475
e9a17296 476 /* Standard Options */
477 case sBadOption:
478 return -1;
479 case sPort:
480 /* ignore ports from configfile if cmdline specifies ports */
481 if (options->ports_from_cmdline)
482 return 0;
483 if (options->listen_addrs != NULL)
484 fatal("%s line %d: ports must be specified before "
485 "ListenAddress.", filename, linenum);
486 if (options->num_ports >= MAX_PORTS)
487 fatal("%s line %d: too many ports.",
488 filename, linenum);
489 arg = strdelim(&cp);
490 if (!arg || *arg == '\0')
491 fatal("%s line %d: missing port number.",
492 filename, linenum);
493 options->ports[options->num_ports++] = a2port(arg);
494 if (options->ports[options->num_ports-1] == 0)
495 fatal("%s line %d: Badly formatted port number.",
496 filename, linenum);
497 break;
498
499 case sServerKeyBits:
500 intptr = &options->server_key_bits;
3c0ef626 501parse_int:
e9a17296 502 arg = strdelim(&cp);
503 if (!arg || *arg == '\0')
504 fatal("%s line %d: missing integer value.",
505 filename, linenum);
506 value = atoi(arg);
507 if (*intptr == -1)
508 *intptr = value;
509 break;
510
511 case sLoginGraceTime:
512 intptr = &options->login_grace_time;
3c0ef626 513parse_time:
e9a17296 514 arg = strdelim(&cp);
515 if (!arg || *arg == '\0')
516 fatal("%s line %d: missing time value.",
517 filename, linenum);
518 if ((value = convtime(arg)) == -1)
519 fatal("%s line %d: invalid time value.",
520 filename, linenum);
521 if (*intptr == -1)
522 *intptr = value;
523 break;
524
525 case sKeyRegenerationTime:
526 intptr = &options->key_regeneration_time;
527 goto parse_time;
528
529 case sListenAddress:
530 arg = strdelim(&cp);
531 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
532 fatal("%s line %d: missing inet addr.",
533 filename, linenum);
534 if (*arg == '[') {
535 if ((p = strchr(arg, ']')) == NULL)
536 fatal("%s line %d: bad ipv6 inet addr usage.",
3c0ef626 537 filename, linenum);
e9a17296 538 arg++;
539 memmove(p, p+1, strlen(p+1)+1);
540 } else if (((p = strchr(arg, ':')) == NULL) ||
541 (strchr(p+1, ':') != NULL)) {
542 add_listen_addr(options, arg, 0);
3c0ef626 543 break;
e9a17296 544 }
545 if (*p == ':') {
546 u_short port;
3c0ef626 547
e9a17296 548 p++;
549 if (*p == '\0')
550 fatal("%s line %d: bad inet addr:port usage.",
3c0ef626 551 filename, linenum);
e9a17296 552 else {
553 *(p-1) = '\0';
554 if ((port = a2port(p)) == 0)
555 fatal("%s line %d: bad port number.",
3c0ef626 556 filename, linenum);
e9a17296 557 add_listen_addr(options, arg, port);
3c0ef626 558 }
e9a17296 559 } else if (*p == '\0')
560 add_listen_addr(options, arg, 0);
561 else
562 fatal("%s line %d: bad inet addr usage.",
563 filename, linenum);
564 break;
565
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];
3c0ef626 572parse_filename:
e9a17296 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;
3c0ef626 584
e9a17296 585 case sPidFile:
586 charptr = &options->pid_file;
587 goto parse_filename;
3c0ef626 588
e9a17296 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;
3c0ef626 615parse_flag:
e9a17296 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
e9a17296 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;
70791e56 655
e9a17296 656 case sKerberosAuthentication:
657 intptr = &options->kerberos_authentication;
658 goto parse_flag;
3c0ef626 659
e9a17296 660 case sKerberosOrLocalPasswd:
661 intptr = &options->kerberos_or_local_passwd;
662 goto parse_flag;
3c0ef626 663
e9a17296 664 case sKerberosTicketCleanup:
665 intptr = &options->kerberos_ticket_cleanup;
666 goto parse_flag;
70791e56 667
416fd2a8 668 case sKerberosGetAFSToken:
669 intptr = &options->kerberos_get_afs_token;
670 goto parse_flag;
671
70791e56 672 case sGssAuthentication:
673 intptr = &options->gss_authentication;
e9a17296 674 goto parse_flag;
70791e56 675
676 case sGssKeyEx:
677 intptr = &options->gss_keyex;
e9a17296 678 goto parse_flag;
70791e56 679
70791e56 680 case sGssCleanupCreds:
681 intptr = &options->gss_cleanup_creds;
682 goto parse_flag;
683
88928908 684#ifdef SESSION_HOOKS
685 case sAllowSessionHooks:
686 intptr = &options->session_hooks_allow;
687 goto parse_flag;
688 case sSessionHookStartupCmd:
689 case sSessionHookShutdownCmd:
690 arg = strdelim(&cp);
691 if (!arg || *arg == '\0')
692 fatal("%s line %d: empty session hook command",
693 filename, linenum);
694 if (opcode==sSessionHookStartupCmd)
695 options->session_hooks_startup_cmd = strdup(arg);
696 else
697 options->session_hooks_shutdown_cmd = strdup(arg);
698 break;
699#endif
70791e56 700
e9a17296 701 case sPasswordAuthentication:
702 intptr = &options->password_authentication;
703 goto parse_flag;
3c0ef626 704
e9a17296 705 case sKbdInteractiveAuthentication:
706 intptr = &options->kbd_interactive_authentication;
707 goto parse_flag;
3c0ef626 708
e9a17296 709 case sChallengeResponseAuthentication:
710 intptr = &options->challenge_response_authentication;
711 goto parse_flag;
3c0ef626 712
e9a17296 713 case sPrintMotd:
714 intptr = &options->print_motd;
715 goto parse_flag;
3c0ef626 716
e9a17296 717 case sPrintLastLog:
718 intptr = &options->print_lastlog;
719 goto parse_flag;
3c0ef626 720
e9a17296 721 case sX11Forwarding:
722 intptr = &options->x11_forwarding;
723 goto parse_flag;
3c0ef626 724
e9a17296 725 case sX11DisplayOffset:
726 intptr = &options->x11_display_offset;
727 goto parse_int;
3c0ef626 728
e9a17296 729 case sX11UseLocalhost:
730 intptr = &options->x11_use_localhost;
731 goto parse_flag;
3c0ef626 732
e9a17296 733 case sXAuthLocation:
734 charptr = &options->xauth_location;
735 goto parse_filename;
3c0ef626 736
e9a17296 737 case sStrictModes:
738 intptr = &options->strict_modes;
739 goto parse_flag;
3c0ef626 740
416fd2a8 741 case sTCPKeepAlive:
742 intptr = &options->tcp_keep_alive;
e9a17296 743 goto parse_flag;
3c0ef626 744
e9a17296 745 case sEmptyPasswd:
746 intptr = &options->permit_empty_passwd;
747 goto parse_flag;
3c0ef626 748
e54b3d7c 749 case sPermitUserEnvironment:
750 intptr = &options->permit_user_env;
751 goto parse_flag;
752
e9a17296 753 case sUseLogin:
754 intptr = &options->use_login;
755 goto parse_flag;
3c0ef626 756
ff2d7a98 757 case sCompression:
758 intptr = &options->compression;
759 goto parse_flag;
760
e9a17296 761 case sGatewayPorts:
762 intptr = &options->gateway_ports;
763 goto parse_flag;
3c0ef626 764
70791e56 765 case sUseDNS:
766 intptr = &options->use_dns;
e9a17296 767 goto parse_flag;
3c0ef626 768
e9a17296 769 case sLogFacility:
770 intptr = (int *) &options->log_facility;
771 arg = strdelim(&cp);
772 value = log_facility_number(arg);
773 if (value == SYSLOG_FACILITY_NOT_SET)
774 fatal("%.200s line %d: unsupported log facility '%s'",
775 filename, linenum, arg ? arg : "<NONE>");
776 if (*intptr == -1)
777 *intptr = (SyslogFacility) value;
778 break;
779
780 case sLogLevel:
781 intptr = (int *) &options->log_level;
782 arg = strdelim(&cp);
783 value = log_level_number(arg);
784 if (value == SYSLOG_LEVEL_NOT_SET)
785 fatal("%.200s line %d: unsupported log level '%s'",
786 filename, linenum, arg ? arg : "<NONE>");
787 if (*intptr == -1)
788 *intptr = (LogLevel) value;
789 break;
790
791 case sAllowTcpForwarding:
792 intptr = &options->allow_tcp_forwarding;
793 goto parse_flag;
794
2980ea68 795 case sUsePrivilegeSeparation:
796 intptr = &use_privsep;
797 goto parse_flag;
798
e9a17296 799 case sAllowUsers:
800 while ((arg = strdelim(&cp)) && *arg != '\0') {
801 if (options->num_allow_users >= MAX_ALLOW_USERS)
802 fatal("%s line %d: too many allow users.",
803 filename, linenum);
ff2d7a98 804 options->allow_users[options->num_allow_users++] =
805 xstrdup(arg);
e9a17296 806 }
807 break;
3c0ef626 808
e9a17296 809 case sDenyUsers:
810 while ((arg = strdelim(&cp)) && *arg != '\0') {
811 if (options->num_deny_users >= MAX_DENY_USERS)
812 fatal( "%s line %d: too many deny users.",
813 filename, linenum);
ff2d7a98 814 options->deny_users[options->num_deny_users++] =
815 xstrdup(arg);
e9a17296 816 }
817 break;
3c0ef626 818
e9a17296 819 case sAllowGroups:
820 while ((arg = strdelim(&cp)) && *arg != '\0') {
821 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
822 fatal("%s line %d: too many allow groups.",
823 filename, linenum);
ff2d7a98 824 options->allow_groups[options->num_allow_groups++] =
825 xstrdup(arg);
e9a17296 826 }
827 break;
3c0ef626 828
e9a17296 829 case sDenyGroups:
830 while ((arg = strdelim(&cp)) && *arg != '\0') {
831 if (options->num_deny_groups >= MAX_DENY_GROUPS)
832 fatal("%s line %d: too many deny groups.",
833 filename, linenum);
834 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
835 }
836 break;
837
838 case sCiphers:
839 arg = strdelim(&cp);
840 if (!arg || *arg == '\0')
841 fatal("%s line %d: Missing argument.", filename, linenum);
842 if (!ciphers_valid(arg))
843 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
844 filename, linenum, arg ? arg : "<NONE>");
845 if (options->ciphers == NULL)
846 options->ciphers = xstrdup(arg);
847 break;
848
849 case sMacs:
850 arg = strdelim(&cp);
851 if (!arg || *arg == '\0')
852 fatal("%s line %d: Missing argument.", filename, linenum);
853 if (!mac_valid(arg))
854 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
855 filename, linenum, arg ? arg : "<NONE>");
856 if (options->macs == NULL)
857 options->macs = xstrdup(arg);
858 break;
859
860 case sProtocol:
861 intptr = &options->protocol;
862 arg = strdelim(&cp);
863 if (!arg || *arg == '\0')
864 fatal("%s line %d: Missing argument.", filename, linenum);
865 value = proto_spec(arg);
866 if (value == SSH_PROTO_UNKNOWN)
867 fatal("%s line %d: Bad protocol spec '%s'.",
868 filename, linenum, arg ? arg : "<NONE>");
869 if (*intptr == SSH_PROTO_UNKNOWN)
870 *intptr = value;
871 break;
872
873 case sSubsystem:
874 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
875 fatal("%s line %d: too many subsystems defined.",
876 filename, linenum);
877 }
878 arg = strdelim(&cp);
879 if (!arg || *arg == '\0')
880 fatal("%s line %d: Missing subsystem name.",
881 filename, linenum);
882 for (i = 0; i < options->num_subsystems; i++)
883 if (strcmp(arg, options->subsystem_name[i]) == 0)
884 fatal("%s line %d: Subsystem '%s' already defined.",
885 filename, linenum, arg);
886 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
887 arg = strdelim(&cp);
888 if (!arg || *arg == '\0')
889 fatal("%s line %d: Missing subsystem command.",
890 filename, linenum);
891 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
892 options->num_subsystems++;
893 break;
894
895 case sMaxStartups:
896 arg = strdelim(&cp);
897 if (!arg || *arg == '\0')
898 fatal("%s line %d: Missing MaxStartups spec.",
899 filename, linenum);
900 if ((n = sscanf(arg, "%d:%d:%d",
901 &options->max_startups_begin,
902 &options->max_startups_rate,
903 &options->max_startups)) == 3) {
904 if (options->max_startups_begin >
905 options->max_startups ||
906 options->max_startups_rate > 100 ||
907 options->max_startups_rate < 1)
3c0ef626 908 fatal("%s line %d: Illegal MaxStartups spec.",
909 filename, linenum);
e9a17296 910 } else if (n != 1)
911 fatal("%s line %d: Illegal MaxStartups spec.",
912 filename, linenum);
913 else
914 options->max_startups = options->max_startups_begin;
915 break;
916
1b56ff3d 917 case sMaxAuthTries:
918 intptr = &options->max_authtries;
919 goto parse_int;
920
e9a17296 921 case sBanner:
922 charptr = &options->banner;
923 goto parse_filename;
924 /*
925 * These options can contain %X options expanded at
926 * connect time, so that you can specify paths like:
927 *
928 * AuthorizedKeysFile /etc/ssh_keys/%u
929 */
930 case sAuthorizedKeysFile:
931 case sAuthorizedKeysFile2:
932 charptr = (opcode == sAuthorizedKeysFile ) ?
933 &options->authorized_keys_file :
934 &options->authorized_keys_file2;
935 goto parse_filename;
936
937 case sClientAliveInterval:
938 intptr = &options->client_alive_interval;
939 goto parse_time;
940
941 case sClientAliveCountMax:
942 intptr = &options->client_alive_count_max;
943 goto parse_int;
944
1b56ff3d 945 case sAcceptEnv:
946 while ((arg = strdelim(&cp)) && *arg != '\0') {
947 if (strchr(arg, '=') != NULL)
948 fatal("%s line %d: Invalid environment name.",
949 filename, linenum);
950 if (options->num_accept_env >= MAX_ACCEPT_ENV)
951 fatal("%s line %d: too many allow env.",
952 filename, linenum);
953 options->accept_env[options->num_accept_env++] =
954 xstrdup(arg);
955 }
956 break;
957
e9a17296 958 case sDeprecated:
70791e56 959 logit("%s line %d: Deprecated option %s",
960 filename, linenum, arg);
961 while (arg)
962 arg = strdelim(&cp);
963 break;
964
965 case sUnsupported:
966 logit("%s line %d: Unsupported option %s",
e9a17296 967 filename, linenum, arg);
968 while (arg)
969 arg = strdelim(&cp);
970 break;
971
972 default:
973 fatal("%s line %d: Missing handler for opcode %s (%d)",
974 filename, linenum, arg, opcode);
975 }
976 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
977 fatal("%s line %d: garbage at end of line; \"%.200s\".",
978 filename, linenum, arg);
979 return 0;
980}
3c0ef626 981
e9a17296 982/* Reads the server configuration file. */
3c0ef626 983
e9a17296 984void
1b56ff3d 985load_server_config(const char *filename, Buffer *conf)
e9a17296 986{
1b56ff3d 987 char line[1024], *cp;
ff2d7a98 988 FILE *f;
e9a17296 989
1b56ff3d 990 debug2("%s: filename %s", __func__, filename);
991 if ((f = fopen(filename, "r")) == NULL) {
e9a17296 992 perror(filename);
993 exit(1);
994 }
1b56ff3d 995 buffer_clear(conf);
e9a17296 996 while (fgets(line, sizeof(line), f)) {
1b56ff3d 997 /*
998 * Trim out comments and strip whitespace
999 * NB - preserve newlines, they are needed to reproduce
1000 * line numbers later for error messages
1001 */
1002 if ((cp = strchr(line, '#')) != NULL)
1003 memcpy(cp, "\n", 2);
1004 cp = line + strspn(line, " \t\r");
1005
1006 buffer_append(conf, cp, strlen(cp));
3c0ef626 1007 }
1b56ff3d 1008 buffer_append(conf, "\0", 1);
3c0ef626 1009 fclose(f);
1b56ff3d 1010 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1011}
1012
1013void
1014parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1015{
1016 int linenum, bad_options = 0;
1017 char *cp, *obuf, *cbuf;
1018
1019 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1020
1021 obuf = cbuf = xstrdup(buffer_ptr(conf));
1022 linenum = 1;
1023 while((cp = strsep(&cbuf, "\n")) != NULL) {
1024 if (process_server_config_line(options, cp, filename,
1025 linenum++) != 0)
1026 bad_options++;
1027 }
1028 xfree(obuf);
3c0ef626 1029 if (bad_options > 0)
1030 fatal("%s: terminating, %d bad configuration options",
1031 filename, bad_options);
1032}
This page took 0.225361 seconds and 5 git commands to generate.