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