]> andersk Git - openssh.git/blame_incremental - servconf.c
- djm@cvs.openbsd.org 2010/01/04 02:25:15
[openssh.git] / servconf.c
... / ...
CommitLineData
1/* $OpenBSD: servconf.c,v 1.199 2009/12/29 16:38:41 stevesk 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 <sys/types.h>
16#include <sys/socket.h>
17
18#include <netdb.h>
19#include <pwd.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <signal.h>
24#include <unistd.h>
25#include <stdarg.h>
26#include <errno.h>
27
28#include "openbsd-compat/sys-queue.h"
29#include "xmalloc.h"
30#include "ssh.h"
31#include "log.h"
32#include "buffer.h"
33#include "servconf.h"
34#include "compat.h"
35#include "pathnames.h"
36#include "misc.h"
37#include "cipher.h"
38#include "key.h"
39#include "kex.h"
40#include "mac.h"
41#include "match.h"
42#include "channels.h"
43#include "groupaccess.h"
44
45static void add_listen_addr(ServerOptions *, char *, int);
46static void add_one_listen_addr(ServerOptions *, char *, int);
47
48/* Use of privilege separation or not */
49extern int use_privsep;
50extern Buffer cfg;
51
52/* Initializes the server options to their default values. */
53
54void
55initialize_server_options(ServerOptions *options)
56{
57 memset(options, 0, sizeof(*options));
58
59 /* Portable-specific options */
60 options->use_pam = -1;
61
62 /* Standard Options */
63 options->num_ports = 0;
64 options->ports_from_cmdline = 0;
65 options->listen_addrs = NULL;
66 options->address_family = -1;
67 options->num_host_key_files = 0;
68 options->pid_file = NULL;
69 options->server_key_bits = -1;
70 options->login_grace_time = -1;
71 options->key_regeneration_time = -1;
72 options->permit_root_login = PERMIT_NOT_SET;
73 options->ignore_rhosts = -1;
74 options->ignore_user_known_hosts = -1;
75 options->print_motd = -1;
76 options->print_lastlog = -1;
77 options->x11_forwarding = -1;
78 options->x11_display_offset = -1;
79 options->x11_use_localhost = -1;
80 options->xauth_location = NULL;
81 options->strict_modes = -1;
82 options->tcp_keep_alive = -1;
83 options->log_facility = SYSLOG_FACILITY_NOT_SET;
84 options->log_level = SYSLOG_LEVEL_NOT_SET;
85 options->rhosts_rsa_authentication = -1;
86 options->hostbased_authentication = -1;
87 options->hostbased_uses_name_from_packet_only = -1;
88 options->rsa_authentication = -1;
89 options->pubkey_authentication = -1;
90 options->kerberos_authentication = -1;
91 options->kerberos_or_local_passwd = -1;
92 options->kerberos_ticket_cleanup = -1;
93 options->kerberos_get_afs_token = -1;
94 options->gss_authentication=-1;
95 options->gss_cleanup_creds = -1;
96 options->password_authentication = -1;
97 options->kbd_interactive_authentication = -1;
98 options->challenge_response_authentication = -1;
99 options->permit_empty_passwd = -1;
100 options->permit_user_env = -1;
101 options->use_login = -1;
102 options->compression = -1;
103 options->allow_tcp_forwarding = -1;
104 options->allow_agent_forwarding = -1;
105 options->num_allow_users = 0;
106 options->num_deny_users = 0;
107 options->num_allow_groups = 0;
108 options->num_deny_groups = 0;
109 options->ciphers = NULL;
110 options->macs = NULL;
111 options->protocol = SSH_PROTO_UNKNOWN;
112 options->gateway_ports = -1;
113 options->num_subsystems = 0;
114 options->max_startups_begin = -1;
115 options->max_startups_rate = -1;
116 options->max_startups = -1;
117 options->max_authtries = -1;
118 options->max_sessions = -1;
119 options->banner = NULL;
120 options->use_dns = -1;
121 options->client_alive_interval = -1;
122 options->client_alive_count_max = -1;
123 options->authorized_keys_file = NULL;
124 options->authorized_keys_file2 = NULL;
125 options->num_accept_env = 0;
126 options->permit_tun = -1;
127 options->num_permitted_opens = -1;
128 options->adm_forced_command = NULL;
129 options->chroot_directory = NULL;
130 options->zero_knowledge_password_authentication = -1;
131 options->rdomain = -1;
132}
133
134void
135fill_default_server_options(ServerOptions *options)
136{
137 /* Portable-specific options */
138 if (options->use_pam == -1)
139 options->use_pam = 0;
140
141 /* Standard Options */
142 if (options->protocol == SSH_PROTO_UNKNOWN)
143 options->protocol = SSH_PROTO_2;
144 if (options->num_host_key_files == 0) {
145 /* fill default hostkeys for protocols */
146 if (options->protocol & SSH_PROTO_1)
147 options->host_key_files[options->num_host_key_files++] =
148 _PATH_HOST_KEY_FILE;
149 if (options->protocol & SSH_PROTO_2) {
150 options->host_key_files[options->num_host_key_files++] =
151 _PATH_HOST_RSA_KEY_FILE;
152 options->host_key_files[options->num_host_key_files++] =
153 _PATH_HOST_DSA_KEY_FILE;
154 }
155 }
156 if (options->num_ports == 0)
157 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
158 if (options->listen_addrs == NULL)
159 add_listen_addr(options, NULL, 0);
160 if (options->pid_file == NULL)
161 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
162 if (options->server_key_bits == -1)
163 options->server_key_bits = 1024;
164 if (options->login_grace_time == -1)
165 options->login_grace_time = 120;
166 if (options->key_regeneration_time == -1)
167 options->key_regeneration_time = 3600;
168 if (options->permit_root_login == PERMIT_NOT_SET)
169 options->permit_root_login = PERMIT_YES;
170 if (options->ignore_rhosts == -1)
171 options->ignore_rhosts = 1;
172 if (options->ignore_user_known_hosts == -1)
173 options->ignore_user_known_hosts = 0;
174 if (options->print_motd == -1)
175 options->print_motd = 1;
176 if (options->print_lastlog == -1)
177 options->print_lastlog = 1;
178 if (options->x11_forwarding == -1)
179 options->x11_forwarding = 0;
180 if (options->x11_display_offset == -1)
181 options->x11_display_offset = 10;
182 if (options->x11_use_localhost == -1)
183 options->x11_use_localhost = 1;
184 if (options->xauth_location == NULL)
185 options->xauth_location = _PATH_XAUTH;
186 if (options->strict_modes == -1)
187 options->strict_modes = 1;
188 if (options->tcp_keep_alive == -1)
189 options->tcp_keep_alive = 1;
190 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
191 options->log_facility = SYSLOG_FACILITY_AUTH;
192 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
193 options->log_level = SYSLOG_LEVEL_INFO;
194 if (options->rhosts_rsa_authentication == -1)
195 options->rhosts_rsa_authentication = 0;
196 if (options->hostbased_authentication == -1)
197 options->hostbased_authentication = 0;
198 if (options->hostbased_uses_name_from_packet_only == -1)
199 options->hostbased_uses_name_from_packet_only = 0;
200 if (options->rsa_authentication == -1)
201 options->rsa_authentication = 1;
202 if (options->pubkey_authentication == -1)
203 options->pubkey_authentication = 1;
204 if (options->kerberos_authentication == -1)
205 options->kerberos_authentication = 0;
206 if (options->kerberos_or_local_passwd == -1)
207 options->kerberos_or_local_passwd = 1;
208 if (options->kerberos_ticket_cleanup == -1)
209 options->kerberos_ticket_cleanup = 1;
210 if (options->kerberos_get_afs_token == -1)
211 options->kerberos_get_afs_token = 0;
212 if (options->gss_authentication == -1)
213 options->gss_authentication = 0;
214 if (options->gss_cleanup_creds == -1)
215 options->gss_cleanup_creds = 1;
216 if (options->password_authentication == -1)
217 options->password_authentication = 1;
218 if (options->kbd_interactive_authentication == -1)
219 options->kbd_interactive_authentication = 0;
220 if (options->challenge_response_authentication == -1)
221 options->challenge_response_authentication = 1;
222 if (options->permit_empty_passwd == -1)
223 options->permit_empty_passwd = 0;
224 if (options->permit_user_env == -1)
225 options->permit_user_env = 0;
226 if (options->use_login == -1)
227 options->use_login = 0;
228 if (options->compression == -1)
229 options->compression = COMP_DELAYED;
230 if (options->allow_tcp_forwarding == -1)
231 options->allow_tcp_forwarding = 1;
232 if (options->allow_agent_forwarding == -1)
233 options->allow_agent_forwarding = 1;
234 if (options->gateway_ports == -1)
235 options->gateway_ports = 0;
236 if (options->max_startups == -1)
237 options->max_startups = 10;
238 if (options->max_startups_rate == -1)
239 options->max_startups_rate = 100; /* 100% */
240 if (options->max_startups_begin == -1)
241 options->max_startups_begin = options->max_startups;
242 if (options->max_authtries == -1)
243 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
244 if (options->max_sessions == -1)
245 options->max_sessions = DEFAULT_SESSIONS_MAX;
246 if (options->use_dns == -1)
247 options->use_dns = 1;
248 if (options->client_alive_interval == -1)
249 options->client_alive_interval = 0;
250 if (options->client_alive_count_max == -1)
251 options->client_alive_count_max = 3;
252 if (options->authorized_keys_file2 == NULL) {
253 /* authorized_keys_file2 falls back to authorized_keys_file */
254 if (options->authorized_keys_file != NULL)
255 options->authorized_keys_file2 = options->authorized_keys_file;
256 else
257 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
258 }
259 if (options->authorized_keys_file == NULL)
260 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
261 if (options->permit_tun == -1)
262 options->permit_tun = SSH_TUNMODE_NO;
263 if (options->zero_knowledge_password_authentication == -1)
264 options->zero_knowledge_password_authentication = 0;
265
266 /* Turn privilege separation on by default */
267 if (use_privsep == -1)
268 use_privsep = 1;
269
270#ifndef HAVE_MMAP
271 if (use_privsep && options->compression == 1) {
272 error("This platform does not support both privilege "
273 "separation and compression");
274 error("Compression disabled");
275 options->compression = 0;
276 }
277#endif
278
279}
280
281/* Keyword tokens. */
282typedef enum {
283 sBadOption, /* == unknown option */
284 /* Portable-specific options */
285 sUsePAM,
286 /* Standard Options */
287 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
288 sPermitRootLogin, sLogFacility, sLogLevel,
289 sRhostsRSAAuthentication, sRSAAuthentication,
290 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
291 sKerberosGetAFSToken,
292 sKerberosTgtPassing, sChallengeResponseAuthentication,
293 sPasswordAuthentication, sKbdInteractiveAuthentication,
294 sListenAddress, sAddressFamily,
295 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
296 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
297 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
298 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
299 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
300 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
301 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
302 sMaxStartups, sMaxAuthTries, sMaxSessions,
303 sBanner, sUseDNS, sHostbasedAuthentication,
304 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
305 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
306 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
307 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
308 sUsePrivilegeSeparation, sAllowAgentForwarding, sRDomain,
309 sZeroKnowledgePasswordAuthentication,
310 sDeprecated, sUnsupported
311} ServerOpCodes;
312
313#define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
314#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
315#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
316
317/* Textual representation of the tokens. */
318static struct {
319 const char *name;
320 ServerOpCodes opcode;
321 u_int flags;
322} keywords[] = {
323 /* Portable-specific options */
324#ifdef USE_PAM
325 { "usepam", sUsePAM, SSHCFG_GLOBAL },
326#else
327 { "usepam", sUnsupported, SSHCFG_GLOBAL },
328#endif
329 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
330 /* Standard Options */
331 { "port", sPort, SSHCFG_GLOBAL },
332 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
333 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
334 { "pidfile", sPidFile, SSHCFG_GLOBAL },
335 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
336 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
337 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
338 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
339 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
340 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
341 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
342 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
343 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
344 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
345 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
346 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
347 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
348#ifdef KRB5
349 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
350 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
351 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
352#ifdef USE_AFS
353 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
354#else
355 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
356#endif
357#else
358 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
359 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
360 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
361 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
362#endif
363 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
364 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
365#ifdef GSSAPI
366 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
367 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
368#else
369 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
370 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
371#endif
372 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
373 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
374 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
375 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
376#ifdef JPAKE
377 { "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
378#else
379 { "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
380#endif
381 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
382 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
383 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
384 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
385 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
386 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
387 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
388 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
389 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
390 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
391 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
392 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
393 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
394 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
395 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
396 { "compression", sCompression, SSHCFG_GLOBAL },
397 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
398 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
399 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
400 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
401 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
402 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
403 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
404 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
405 { "ciphers", sCiphers, SSHCFG_GLOBAL },
406 { "macs", sMacs, SSHCFG_GLOBAL },
407 { "protocol", sProtocol, SSHCFG_GLOBAL },
408 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
409 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
410 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
411 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
412 { "maxsessions", sMaxSessions, SSHCFG_ALL },
413 { "banner", sBanner, SSHCFG_ALL },
414 { "usedns", sUseDNS, SSHCFG_GLOBAL },
415 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
416 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
417 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
418 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
419 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
420 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
421 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
422 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
423 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
424 { "match", sMatch, SSHCFG_ALL },
425 { "permitopen", sPermitOpen, SSHCFG_ALL },
426 { "forcecommand", sForceCommand, SSHCFG_ALL },
427 { "routingdomain", sRDomain, SSHCFG_GLOBAL },
428 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
429 { NULL, sBadOption, 0 }
430};
431
432static struct {
433 int val;
434 char *text;
435} tunmode_desc[] = {
436 { SSH_TUNMODE_NO, "no" },
437 { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
438 { SSH_TUNMODE_ETHERNET, "ethernet" },
439 { SSH_TUNMODE_YES, "yes" },
440 { -1, NULL }
441};
442
443/*
444 * Returns the number of the token pointed to by cp or sBadOption.
445 */
446
447static ServerOpCodes
448parse_token(const char *cp, const char *filename,
449 int linenum, u_int *flags)
450{
451 u_int i;
452
453 for (i = 0; keywords[i].name; i++)
454 if (strcasecmp(cp, keywords[i].name) == 0) {
455 *flags = keywords[i].flags;
456 return keywords[i].opcode;
457 }
458
459 error("%s: line %d: Bad configuration option: %s",
460 filename, linenum, cp);
461 return sBadOption;
462}
463
464static void
465add_listen_addr(ServerOptions *options, char *addr, int port)
466{
467 u_int i;
468
469 if (options->num_ports == 0)
470 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
471 if (options->address_family == -1)
472 options->address_family = AF_UNSPEC;
473 if (port == 0)
474 for (i = 0; i < options->num_ports; i++)
475 add_one_listen_addr(options, addr, options->ports[i]);
476 else
477 add_one_listen_addr(options, addr, port);
478}
479
480static void
481add_one_listen_addr(ServerOptions *options, char *addr, int port)
482{
483 struct addrinfo hints, *ai, *aitop;
484 char strport[NI_MAXSERV];
485 int gaierr;
486
487 memset(&hints, 0, sizeof(hints));
488 hints.ai_family = options->address_family;
489 hints.ai_socktype = SOCK_STREAM;
490 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
491 snprintf(strport, sizeof strport, "%d", port);
492 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
493 fatal("bad addr or host: %s (%s)",
494 addr ? addr : "<NULL>",
495 ssh_gai_strerror(gaierr));
496 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
497 ;
498 ai->ai_next = options->listen_addrs;
499 options->listen_addrs = aitop;
500}
501
502/*
503 * The strategy for the Match blocks is that the config file is parsed twice.
504 *
505 * The first time is at startup. activep is initialized to 1 and the
506 * directives in the global context are processed and acted on. Hitting a
507 * Match directive unsets activep and the directives inside the block are
508 * checked for syntax only.
509 *
510 * The second time is after a connection has been established but before
511 * authentication. activep is initialized to 2 and global config directives
512 * are ignored since they have already been processed. If the criteria in a
513 * Match block is met, activep is set and the subsequent directives
514 * processed and actioned until EOF or another Match block unsets it. Any
515 * options set are copied into the main server config.
516 *
517 * Potential additions/improvements:
518 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
519 *
520 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
521 * Match Address 192.168.0.*
522 * Tag trusted
523 * Match Group wheel
524 * Tag trusted
525 * Match Tag trusted
526 * AllowTcpForwarding yes
527 * GatewayPorts clientspecified
528 * [...]
529 *
530 * - Add a PermittedChannelRequests directive
531 * Match Group shell
532 * PermittedChannelRequests session,forwarded-tcpip
533 */
534
535static int
536match_cfg_line_group(const char *grps, int line, const char *user)
537{
538 int result = 0;
539 struct passwd *pw;
540
541 if (user == NULL)
542 goto out;
543
544 if ((pw = getpwnam(user)) == NULL) {
545 debug("Can't match group at line %d because user %.100s does "
546 "not exist", line, user);
547 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
548 debug("Can't Match group because user %.100s not in any group "
549 "at line %d", user, line);
550 } else if (ga_match_pattern_list(grps) != 1) {
551 debug("user %.100s does not match group list %.100s at line %d",
552 user, grps, line);
553 } else {
554 debug("user %.100s matched group list %.100s at line %d", user,
555 grps, line);
556 result = 1;
557 }
558out:
559 ga_free();
560 return result;
561}
562
563static int
564match_cfg_line(char **condition, int line, const char *user, const char *host,
565 const char *address)
566{
567 int result = 1;
568 char *arg, *attrib, *cp = *condition;
569 size_t len;
570
571 if (user == NULL)
572 debug3("checking syntax for 'Match %s'", cp);
573 else
574 debug3("checking match for '%s' user %s host %s addr %s", cp,
575 user ? user : "(null)", host ? host : "(null)",
576 address ? address : "(null)");
577
578 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
579 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
580 error("Missing Match criteria for %s", attrib);
581 return -1;
582 }
583 len = strlen(arg);
584 if (strcasecmp(attrib, "user") == 0) {
585 if (!user) {
586 result = 0;
587 continue;
588 }
589 if (match_pattern_list(user, arg, len, 0) != 1)
590 result = 0;
591 else
592 debug("user %.100s matched 'User %.100s' at "
593 "line %d", user, arg, line);
594 } else if (strcasecmp(attrib, "group") == 0) {
595 switch (match_cfg_line_group(arg, line, user)) {
596 case -1:
597 return -1;
598 case 0:
599 result = 0;
600 }
601 } else if (strcasecmp(attrib, "host") == 0) {
602 if (!host) {
603 result = 0;
604 continue;
605 }
606 if (match_hostname(host, arg, len) != 1)
607 result = 0;
608 else
609 debug("connection from %.100s matched 'Host "
610 "%.100s' at line %d", host, arg, line);
611 } else if (strcasecmp(attrib, "address") == 0) {
612 switch (addr_match_list(address, arg)) {
613 case 1:
614 debug("connection from %.100s matched 'Address "
615 "%.100s' at line %d", address, arg, line);
616 break;
617 case 0:
618 case -1:
619 result = 0;
620 break;
621 case -2:
622 return -1;
623 }
624 } else {
625 error("Unsupported Match attribute %s", attrib);
626 return -1;
627 }
628 }
629 if (user != NULL)
630 debug3("match %sfound", result ? "" : "not ");
631 *condition = cp;
632 return result;
633}
634
635#define WHITESPACE " \t\r\n"
636
637int
638process_server_config_line(ServerOptions *options, char *line,
639 const char *filename, int linenum, int *activep, const char *user,
640 const char *host, const char *address)
641{
642 char *cp, **charptr, *arg, *p;
643 int cmdline = 0, *intptr, value, n;
644 SyslogFacility *log_facility_ptr;
645 LogLevel *log_level_ptr;
646 ServerOpCodes opcode;
647 int port;
648 u_int i, flags = 0;
649 size_t len;
650
651 cp = line;
652 if ((arg = strdelim(&cp)) == NULL)
653 return 0;
654 /* Ignore leading whitespace */
655 if (*arg == '\0')
656 arg = strdelim(&cp);
657 if (!arg || !*arg || *arg == '#')
658 return 0;
659 intptr = NULL;
660 charptr = NULL;
661 opcode = parse_token(arg, filename, linenum, &flags);
662
663 if (activep == NULL) { /* We are processing a command line directive */
664 cmdline = 1;
665 activep = &cmdline;
666 }
667 if (*activep && opcode != sMatch)
668 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
669 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
670 if (user == NULL) {
671 fatal("%s line %d: Directive '%s' is not allowed "
672 "within a Match block", filename, linenum, arg);
673 } else { /* this is a directive we have already processed */
674 while (arg)
675 arg = strdelim(&cp);
676 return 0;
677 }
678 }
679
680 switch (opcode) {
681 /* Portable-specific options */
682 case sUsePAM:
683 intptr = &options->use_pam;
684 goto parse_flag;
685
686 /* Standard Options */
687 case sBadOption:
688 return -1;
689 case sPort:
690 /* ignore ports from configfile if cmdline specifies ports */
691 if (options->ports_from_cmdline)
692 return 0;
693 if (options->listen_addrs != NULL)
694 fatal("%s line %d: ports must be specified before "
695 "ListenAddress.", filename, linenum);
696 if (options->num_ports >= MAX_PORTS)
697 fatal("%s line %d: too many ports.",
698 filename, linenum);
699 arg = strdelim(&cp);
700 if (!arg || *arg == '\0')
701 fatal("%s line %d: missing port number.",
702 filename, linenum);
703 options->ports[options->num_ports++] = a2port(arg);
704 if (options->ports[options->num_ports-1] <= 0)
705 fatal("%s line %d: Badly formatted port number.",
706 filename, linenum);
707 break;
708
709 case sServerKeyBits:
710 intptr = &options->server_key_bits;
711 parse_int:
712 arg = strdelim(&cp);
713 if (!arg || *arg == '\0')
714 fatal("%s line %d: missing integer value.",
715 filename, linenum);
716 value = atoi(arg);
717 if (*activep && *intptr == -1)
718 *intptr = value;
719 break;
720
721 case sLoginGraceTime:
722 intptr = &options->login_grace_time;
723 parse_time:
724 arg = strdelim(&cp);
725 if (!arg || *arg == '\0')
726 fatal("%s line %d: missing time value.",
727 filename, linenum);
728 if ((value = convtime(arg)) == -1)
729 fatal("%s line %d: invalid time value.",
730 filename, linenum);
731 if (*intptr == -1)
732 *intptr = value;
733 break;
734
735 case sKeyRegenerationTime:
736 intptr = &options->key_regeneration_time;
737 goto parse_time;
738
739 case sListenAddress:
740 arg = strdelim(&cp);
741 if (arg == NULL || *arg == '\0')
742 fatal("%s line %d: missing address",
743 filename, linenum);
744 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
745 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
746 && strchr(p+1, ':') != NULL) {
747 add_listen_addr(options, arg, 0);
748 break;
749 }
750 p = hpdelim(&arg);
751 if (p == NULL)
752 fatal("%s line %d: bad address:port usage",
753 filename, linenum);
754 p = cleanhostname(p);
755 if (arg == NULL)
756 port = 0;
757 else if ((port = a2port(arg)) <= 0)
758 fatal("%s line %d: bad port number", filename, linenum);
759
760 add_listen_addr(options, p, port);
761
762 break;
763
764 case sAddressFamily:
765 arg = strdelim(&cp);
766 if (!arg || *arg == '\0')
767 fatal("%s line %d: missing address family.",
768 filename, linenum);
769 intptr = &options->address_family;
770 if (options->listen_addrs != NULL)
771 fatal("%s line %d: address family must be specified before "
772 "ListenAddress.", filename, linenum);
773 if (strcasecmp(arg, "inet") == 0)
774 value = AF_INET;
775 else if (strcasecmp(arg, "inet6") == 0)
776 value = AF_INET6;
777 else if (strcasecmp(arg, "any") == 0)
778 value = AF_UNSPEC;
779 else
780 fatal("%s line %d: unsupported address family \"%s\".",
781 filename, linenum, arg);
782 if (*intptr == -1)
783 *intptr = value;
784 break;
785
786 case sHostKeyFile:
787 intptr = &options->num_host_key_files;
788 if (*intptr >= MAX_HOSTKEYS)
789 fatal("%s line %d: too many host keys specified (max %d).",
790 filename, linenum, MAX_HOSTKEYS);
791 charptr = &options->host_key_files[*intptr];
792 parse_filename:
793 arg = strdelim(&cp);
794 if (!arg || *arg == '\0')
795 fatal("%s line %d: missing file name.",
796 filename, linenum);
797 if (*activep && *charptr == NULL) {
798 *charptr = tilde_expand_filename(arg, getuid());
799 /* increase optional counter */
800 if (intptr != NULL)
801 *intptr = *intptr + 1;
802 }
803 break;
804
805 case sPidFile:
806 charptr = &options->pid_file;
807 goto parse_filename;
808
809 case sPermitRootLogin:
810 intptr = &options->permit_root_login;
811 arg = strdelim(&cp);
812 if (!arg || *arg == '\0')
813 fatal("%s line %d: missing yes/"
814 "without-password/forced-commands-only/no "
815 "argument.", filename, linenum);
816 value = 0; /* silence compiler */
817 if (strcmp(arg, "without-password") == 0)
818 value = PERMIT_NO_PASSWD;
819 else if (strcmp(arg, "forced-commands-only") == 0)
820 value = PERMIT_FORCED_ONLY;
821 else if (strcmp(arg, "yes") == 0)
822 value = PERMIT_YES;
823 else if (strcmp(arg, "no") == 0)
824 value = PERMIT_NO;
825 else
826 fatal("%s line %d: Bad yes/"
827 "without-password/forced-commands-only/no "
828 "argument: %s", filename, linenum, arg);
829 if (*activep && *intptr == -1)
830 *intptr = value;
831 break;
832
833 case sIgnoreRhosts:
834 intptr = &options->ignore_rhosts;
835 parse_flag:
836 arg = strdelim(&cp);
837 if (!arg || *arg == '\0')
838 fatal("%s line %d: missing yes/no argument.",
839 filename, linenum);
840 value = 0; /* silence compiler */
841 if (strcmp(arg, "yes") == 0)
842 value = 1;
843 else if (strcmp(arg, "no") == 0)
844 value = 0;
845 else
846 fatal("%s line %d: Bad yes/no argument: %s",
847 filename, linenum, arg);
848 if (*activep && *intptr == -1)
849 *intptr = value;
850 break;
851
852 case sIgnoreUserKnownHosts:
853 intptr = &options->ignore_user_known_hosts;
854 goto parse_flag;
855
856 case sRhostsRSAAuthentication:
857 intptr = &options->rhosts_rsa_authentication;
858 goto parse_flag;
859
860 case sHostbasedAuthentication:
861 intptr = &options->hostbased_authentication;
862 goto parse_flag;
863
864 case sHostbasedUsesNameFromPacketOnly:
865 intptr = &options->hostbased_uses_name_from_packet_only;
866 goto parse_flag;
867
868 case sRSAAuthentication:
869 intptr = &options->rsa_authentication;
870 goto parse_flag;
871
872 case sPubkeyAuthentication:
873 intptr = &options->pubkey_authentication;
874 goto parse_flag;
875
876 case sKerberosAuthentication:
877 intptr = &options->kerberos_authentication;
878 goto parse_flag;
879
880 case sKerberosOrLocalPasswd:
881 intptr = &options->kerberos_or_local_passwd;
882 goto parse_flag;
883
884 case sKerberosTicketCleanup:
885 intptr = &options->kerberos_ticket_cleanup;
886 goto parse_flag;
887
888 case sKerberosGetAFSToken:
889 intptr = &options->kerberos_get_afs_token;
890 goto parse_flag;
891
892 case sGssAuthentication:
893 intptr = &options->gss_authentication;
894 goto parse_flag;
895
896 case sGssCleanupCreds:
897 intptr = &options->gss_cleanup_creds;
898 goto parse_flag;
899
900 case sPasswordAuthentication:
901 intptr = &options->password_authentication;
902 goto parse_flag;
903
904 case sZeroKnowledgePasswordAuthentication:
905 intptr = &options->zero_knowledge_password_authentication;
906 goto parse_flag;
907
908 case sKbdInteractiveAuthentication:
909 intptr = &options->kbd_interactive_authentication;
910 goto parse_flag;
911
912 case sChallengeResponseAuthentication:
913 intptr = &options->challenge_response_authentication;
914 goto parse_flag;
915
916 case sPrintMotd:
917 intptr = &options->print_motd;
918 goto parse_flag;
919
920 case sPrintLastLog:
921 intptr = &options->print_lastlog;
922 goto parse_flag;
923
924 case sX11Forwarding:
925 intptr = &options->x11_forwarding;
926 goto parse_flag;
927
928 case sX11DisplayOffset:
929 intptr = &options->x11_display_offset;
930 goto parse_int;
931
932 case sX11UseLocalhost:
933 intptr = &options->x11_use_localhost;
934 goto parse_flag;
935
936 case sXAuthLocation:
937 charptr = &options->xauth_location;
938 goto parse_filename;
939
940 case sStrictModes:
941 intptr = &options->strict_modes;
942 goto parse_flag;
943
944 case sTCPKeepAlive:
945 intptr = &options->tcp_keep_alive;
946 goto parse_flag;
947
948 case sEmptyPasswd:
949 intptr = &options->permit_empty_passwd;
950 goto parse_flag;
951
952 case sPermitUserEnvironment:
953 intptr = &options->permit_user_env;
954 goto parse_flag;
955
956 case sUseLogin:
957 intptr = &options->use_login;
958 goto parse_flag;
959
960 case sCompression:
961 intptr = &options->compression;
962 arg = strdelim(&cp);
963 if (!arg || *arg == '\0')
964 fatal("%s line %d: missing yes/no/delayed "
965 "argument.", filename, linenum);
966 value = 0; /* silence compiler */
967 if (strcmp(arg, "delayed") == 0)
968 value = COMP_DELAYED;
969 else if (strcmp(arg, "yes") == 0)
970 value = COMP_ZLIB;
971 else if (strcmp(arg, "no") == 0)
972 value = COMP_NONE;
973 else
974 fatal("%s line %d: Bad yes/no/delayed "
975 "argument: %s", filename, linenum, arg);
976 if (*intptr == -1)
977 *intptr = value;
978 break;
979
980 case sGatewayPorts:
981 intptr = &options->gateway_ports;
982 arg = strdelim(&cp);
983 if (!arg || *arg == '\0')
984 fatal("%s line %d: missing yes/no/clientspecified "
985 "argument.", filename, linenum);
986 value = 0; /* silence compiler */
987 if (strcmp(arg, "clientspecified") == 0)
988 value = 2;
989 else if (strcmp(arg, "yes") == 0)
990 value = 1;
991 else if (strcmp(arg, "no") == 0)
992 value = 0;
993 else
994 fatal("%s line %d: Bad yes/no/clientspecified "
995 "argument: %s", filename, linenum, arg);
996 if (*activep && *intptr == -1)
997 *intptr = value;
998 break;
999
1000 case sUseDNS:
1001 intptr = &options->use_dns;
1002 goto parse_flag;
1003
1004 case sLogFacility:
1005 log_facility_ptr = &options->log_facility;
1006 arg = strdelim(&cp);
1007 value = log_facility_number(arg);
1008 if (value == SYSLOG_FACILITY_NOT_SET)
1009 fatal("%.200s line %d: unsupported log facility '%s'",
1010 filename, linenum, arg ? arg : "<NONE>");
1011 if (*log_facility_ptr == -1)
1012 *log_facility_ptr = (SyslogFacility) value;
1013 break;
1014
1015 case sLogLevel:
1016 log_level_ptr = &options->log_level;
1017 arg = strdelim(&cp);
1018 value = log_level_number(arg);
1019 if (value == SYSLOG_LEVEL_NOT_SET)
1020 fatal("%.200s line %d: unsupported log level '%s'",
1021 filename, linenum, arg ? arg : "<NONE>");
1022 if (*log_level_ptr == -1)
1023 *log_level_ptr = (LogLevel) value;
1024 break;
1025
1026 case sAllowTcpForwarding:
1027 intptr = &options->allow_tcp_forwarding;
1028 goto parse_flag;
1029
1030 case sAllowAgentForwarding:
1031 intptr = &options->allow_agent_forwarding;
1032 goto parse_flag;
1033
1034 case sUsePrivilegeSeparation:
1035 intptr = &use_privsep;
1036 goto parse_flag;
1037
1038 case sAllowUsers:
1039 while ((arg = strdelim(&cp)) && *arg != '\0') {
1040 if (options->num_allow_users >= MAX_ALLOW_USERS)
1041 fatal("%s line %d: too many allow users.",
1042 filename, linenum);
1043 options->allow_users[options->num_allow_users++] =
1044 xstrdup(arg);
1045 }
1046 break;
1047
1048 case sDenyUsers:
1049 while ((arg = strdelim(&cp)) && *arg != '\0') {
1050 if (options->num_deny_users >= MAX_DENY_USERS)
1051 fatal("%s line %d: too many deny users.",
1052 filename, linenum);
1053 options->deny_users[options->num_deny_users++] =
1054 xstrdup(arg);
1055 }
1056 break;
1057
1058 case sAllowGroups:
1059 while ((arg = strdelim(&cp)) && *arg != '\0') {
1060 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1061 fatal("%s line %d: too many allow groups.",
1062 filename, linenum);
1063 options->allow_groups[options->num_allow_groups++] =
1064 xstrdup(arg);
1065 }
1066 break;
1067
1068 case sDenyGroups:
1069 while ((arg = strdelim(&cp)) && *arg != '\0') {
1070 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1071 fatal("%s line %d: too many deny groups.",
1072 filename, linenum);
1073 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1074 }
1075 break;
1076
1077 case sCiphers:
1078 arg = strdelim(&cp);
1079 if (!arg || *arg == '\0')
1080 fatal("%s line %d: Missing argument.", filename, linenum);
1081 if (!ciphers_valid(arg))
1082 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1083 filename, linenum, arg ? arg : "<NONE>");
1084 if (options->ciphers == NULL)
1085 options->ciphers = xstrdup(arg);
1086 break;
1087
1088 case sMacs:
1089 arg = strdelim(&cp);
1090 if (!arg || *arg == '\0')
1091 fatal("%s line %d: Missing argument.", filename, linenum);
1092 if (!mac_valid(arg))
1093 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1094 filename, linenum, arg ? arg : "<NONE>");
1095 if (options->macs == NULL)
1096 options->macs = xstrdup(arg);
1097 break;
1098
1099 case sProtocol:
1100 intptr = &options->protocol;
1101 arg = strdelim(&cp);
1102 if (!arg || *arg == '\0')
1103 fatal("%s line %d: Missing argument.", filename, linenum);
1104 value = proto_spec(arg);
1105 if (value == SSH_PROTO_UNKNOWN)
1106 fatal("%s line %d: Bad protocol spec '%s'.",
1107 filename, linenum, arg ? arg : "<NONE>");
1108 if (*intptr == SSH_PROTO_UNKNOWN)
1109 *intptr = value;
1110 break;
1111
1112 case sSubsystem:
1113 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1114 fatal("%s line %d: too many subsystems defined.",
1115 filename, linenum);
1116 }
1117 arg = strdelim(&cp);
1118 if (!arg || *arg == '\0')
1119 fatal("%s line %d: Missing subsystem name.",
1120 filename, linenum);
1121 if (!*activep) {
1122 arg = strdelim(&cp);
1123 break;
1124 }
1125 for (i = 0; i < options->num_subsystems; i++)
1126 if (strcmp(arg, options->subsystem_name[i]) == 0)
1127 fatal("%s line %d: Subsystem '%s' already defined.",
1128 filename, linenum, arg);
1129 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1130 arg = strdelim(&cp);
1131 if (!arg || *arg == '\0')
1132 fatal("%s line %d: Missing subsystem command.",
1133 filename, linenum);
1134 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1135
1136 /* Collect arguments (separate to executable) */
1137 p = xstrdup(arg);
1138 len = strlen(p) + 1;
1139 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1140 len += 1 + strlen(arg);
1141 p = xrealloc(p, 1, len);
1142 strlcat(p, " ", len);
1143 strlcat(p, arg, len);
1144 }
1145 options->subsystem_args[options->num_subsystems] = p;
1146 options->num_subsystems++;
1147 break;
1148
1149 case sMaxStartups:
1150 arg = strdelim(&cp);
1151 if (!arg || *arg == '\0')
1152 fatal("%s line %d: Missing MaxStartups spec.",
1153 filename, linenum);
1154 if ((n = sscanf(arg, "%d:%d:%d",
1155 &options->max_startups_begin,
1156 &options->max_startups_rate,
1157 &options->max_startups)) == 3) {
1158 if (options->max_startups_begin >
1159 options->max_startups ||
1160 options->max_startups_rate > 100 ||
1161 options->max_startups_rate < 1)
1162 fatal("%s line %d: Illegal MaxStartups spec.",
1163 filename, linenum);
1164 } else if (n != 1)
1165 fatal("%s line %d: Illegal MaxStartups spec.",
1166 filename, linenum);
1167 else
1168 options->max_startups = options->max_startups_begin;
1169 break;
1170
1171 case sMaxAuthTries:
1172 intptr = &options->max_authtries;
1173 goto parse_int;
1174
1175 case sMaxSessions:
1176 intptr = &options->max_sessions;
1177 goto parse_int;
1178
1179 case sBanner:
1180 charptr = &options->banner;
1181 goto parse_filename;
1182
1183 /*
1184 * These options can contain %X options expanded at
1185 * connect time, so that you can specify paths like:
1186 *
1187 * AuthorizedKeysFile /etc/ssh_keys/%u
1188 */
1189 case sAuthorizedKeysFile:
1190 case sAuthorizedKeysFile2:
1191 charptr = (opcode == sAuthorizedKeysFile) ?
1192 &options->authorized_keys_file :
1193 &options->authorized_keys_file2;
1194 goto parse_filename;
1195
1196 case sClientAliveInterval:
1197 intptr = &options->client_alive_interval;
1198 goto parse_time;
1199
1200 case sClientAliveCountMax:
1201 intptr = &options->client_alive_count_max;
1202 goto parse_int;
1203
1204 case sAcceptEnv:
1205 while ((arg = strdelim(&cp)) && *arg != '\0') {
1206 if (strchr(arg, '=') != NULL)
1207 fatal("%s line %d: Invalid environment name.",
1208 filename, linenum);
1209 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1210 fatal("%s line %d: too many allow env.",
1211 filename, linenum);
1212 if (!*activep)
1213 break;
1214 options->accept_env[options->num_accept_env++] =
1215 xstrdup(arg);
1216 }
1217 break;
1218
1219 case sPermitTunnel:
1220 intptr = &options->permit_tun;
1221 arg = strdelim(&cp);
1222 if (!arg || *arg == '\0')
1223 fatal("%s line %d: Missing yes/point-to-point/"
1224 "ethernet/no argument.", filename, linenum);
1225 value = -1;
1226 for (i = 0; tunmode_desc[i].val != -1; i++)
1227 if (strcmp(tunmode_desc[i].text, arg) == 0) {
1228 value = tunmode_desc[i].val;
1229 break;
1230 }
1231 if (value == -1)
1232 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1233 "no argument: %s", filename, linenum, arg);
1234 if (*intptr == -1)
1235 *intptr = value;
1236 break;
1237
1238 case sMatch:
1239 if (cmdline)
1240 fatal("Match directive not supported as a command-line "
1241 "option");
1242 value = match_cfg_line(&cp, linenum, user, host, address);
1243 if (value < 0)
1244 fatal("%s line %d: Bad Match condition", filename,
1245 linenum);
1246 *activep = value;
1247 break;
1248
1249 case sPermitOpen:
1250 arg = strdelim(&cp);
1251 if (!arg || *arg == '\0')
1252 fatal("%s line %d: missing PermitOpen specification",
1253 filename, linenum);
1254 n = options->num_permitted_opens; /* modified later */
1255 if (strcmp(arg, "any") == 0) {
1256 if (*activep && n == -1) {
1257 channel_clear_adm_permitted_opens();
1258 options->num_permitted_opens = 0;
1259 }
1260 break;
1261 }
1262 if (*activep && n == -1)
1263 channel_clear_adm_permitted_opens();
1264 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1265 p = hpdelim(&arg);
1266 if (p == NULL)
1267 fatal("%s line %d: missing host in PermitOpen",
1268 filename, linenum);
1269 p = cleanhostname(p);
1270 if (arg == NULL || (port = a2port(arg)) <= 0)
1271 fatal("%s line %d: bad port number in "
1272 "PermitOpen", filename, linenum);
1273 if (*activep && n == -1)
1274 options->num_permitted_opens =
1275 channel_add_adm_permitted_opens(p, port);
1276 }
1277 break;
1278
1279 case sForceCommand:
1280 if (cp == NULL)
1281 fatal("%.200s line %d: Missing argument.", filename,
1282 linenum);
1283 len = strspn(cp, WHITESPACE);
1284 if (*activep && options->adm_forced_command == NULL)
1285 options->adm_forced_command = xstrdup(cp + len);
1286 return 0;
1287
1288 case sChrootDirectory:
1289 charptr = &options->chroot_directory;
1290
1291 arg = strdelim(&cp);
1292 if (!arg || *arg == '\0')
1293 fatal("%s line %d: missing file name.",
1294 filename, linenum);
1295 if (*activep && *charptr == NULL)
1296 *charptr = xstrdup(arg);
1297 break;
1298
1299 case sRDomain:
1300 intptr = &options->rdomain;
1301 arg = strdelim(&cp);
1302 if (!arg || *arg == '\0')
1303 fatal("%s line %d: missing rdomain value.",
1304 filename, linenum);
1305 if ((value = a2rdomain(arg)) == -1)
1306 fatal("%s line %d: invalid rdomain value.",
1307 filename, linenum);
1308 if (*intptr == -1)
1309 *intptr = value;
1310 break;
1311
1312 case sDeprecated:
1313 logit("%s line %d: Deprecated option %s",
1314 filename, linenum, arg);
1315 while (arg)
1316 arg = strdelim(&cp);
1317 break;
1318
1319 case sUnsupported:
1320 logit("%s line %d: Unsupported option %s",
1321 filename, linenum, arg);
1322 while (arg)
1323 arg = strdelim(&cp);
1324 break;
1325
1326 default:
1327 fatal("%s line %d: Missing handler for opcode %s (%d)",
1328 filename, linenum, arg, opcode);
1329 }
1330 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1331 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1332 filename, linenum, arg);
1333 return 0;
1334}
1335
1336/* Reads the server configuration file. */
1337
1338void
1339load_server_config(const char *filename, Buffer *conf)
1340{
1341 char line[1024], *cp;
1342 FILE *f;
1343
1344 debug2("%s: filename %s", __func__, filename);
1345 if ((f = fopen(filename, "r")) == NULL) {
1346 perror(filename);
1347 exit(1);
1348 }
1349 buffer_clear(conf);
1350 while (fgets(line, sizeof(line), f)) {
1351 /*
1352 * Trim out comments and strip whitespace
1353 * NB - preserve newlines, they are needed to reproduce
1354 * line numbers later for error messages
1355 */
1356 if ((cp = strchr(line, '#')) != NULL)
1357 memcpy(cp, "\n", 2);
1358 cp = line + strspn(line, " \t\r");
1359
1360 buffer_append(conf, cp, strlen(cp));
1361 }
1362 buffer_append(conf, "\0", 1);
1363 fclose(f);
1364 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1365}
1366
1367void
1368parse_server_match_config(ServerOptions *options, const char *user,
1369 const char *host, const char *address)
1370{
1371 ServerOptions mo;
1372
1373 initialize_server_options(&mo);
1374 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1375 copy_set_server_options(options, &mo, 0);
1376}
1377
1378/* Helper macros */
1379#define M_CP_INTOPT(n) do {\
1380 if (src->n != -1) \
1381 dst->n = src->n; \
1382} while (0)
1383#define M_CP_STROPT(n) do {\
1384 if (src->n != NULL) { \
1385 if (dst->n != NULL) \
1386 xfree(dst->n); \
1387 dst->n = src->n; \
1388 } \
1389} while(0)
1390
1391/*
1392 * Copy any supported values that are set.
1393 *
1394 * If the preauth flag is set, we do not bother copying the string or
1395 * array values that are not used pre-authentication, because any that we
1396 * do use must be explictly sent in mm_getpwnamallow().
1397 */
1398void
1399copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1400{
1401 M_CP_INTOPT(password_authentication);
1402 M_CP_INTOPT(gss_authentication);
1403 M_CP_INTOPT(rsa_authentication);
1404 M_CP_INTOPT(pubkey_authentication);
1405 M_CP_INTOPT(kerberos_authentication);
1406 M_CP_INTOPT(hostbased_authentication);
1407 M_CP_INTOPT(kbd_interactive_authentication);
1408 M_CP_INTOPT(zero_knowledge_password_authentication);
1409 M_CP_INTOPT(permit_root_login);
1410 M_CP_INTOPT(permit_empty_passwd);
1411
1412 M_CP_INTOPT(allow_tcp_forwarding);
1413 M_CP_INTOPT(allow_agent_forwarding);
1414 M_CP_INTOPT(gateway_ports);
1415 M_CP_INTOPT(x11_display_offset);
1416 M_CP_INTOPT(x11_forwarding);
1417 M_CP_INTOPT(x11_use_localhost);
1418 M_CP_INTOPT(max_sessions);
1419 M_CP_INTOPT(max_authtries);
1420
1421 M_CP_STROPT(banner);
1422 if (preauth)
1423 return;
1424 M_CP_STROPT(adm_forced_command);
1425 M_CP_STROPT(chroot_directory);
1426}
1427
1428#undef M_CP_INTOPT
1429#undef M_CP_STROPT
1430
1431void
1432parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1433 const char *user, const char *host, const char *address)
1434{
1435 int active, linenum, bad_options = 0;
1436 char *cp, *obuf, *cbuf;
1437
1438 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1439
1440 obuf = cbuf = xstrdup(buffer_ptr(conf));
1441 active = user ? 0 : 1;
1442 linenum = 1;
1443 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1444 if (process_server_config_line(options, cp, filename,
1445 linenum++, &active, user, host, address) != 0)
1446 bad_options++;
1447 }
1448 xfree(obuf);
1449 if (bad_options > 0)
1450 fatal("%s: terminating, %d bad configuration options",
1451 filename, bad_options);
1452}
1453
1454static const char *
1455fmt_intarg(ServerOpCodes code, int val)
1456{
1457 if (code == sAddressFamily) {
1458 switch (val) {
1459 case AF_INET:
1460 return "inet";
1461 case AF_INET6:
1462 return "inet6";
1463 case AF_UNSPEC:
1464 return "any";
1465 default:
1466 return "UNKNOWN";
1467 }
1468 }
1469 if (code == sPermitRootLogin) {
1470 switch (val) {
1471 case PERMIT_NO_PASSWD:
1472 return "without-password";
1473 case PERMIT_FORCED_ONLY:
1474 return "forced-commands-only";
1475 case PERMIT_YES:
1476 return "yes";
1477 }
1478 }
1479 if (code == sProtocol) {
1480 switch (val) {
1481 case SSH_PROTO_1:
1482 return "1";
1483 case SSH_PROTO_2:
1484 return "2";
1485 case (SSH_PROTO_1|SSH_PROTO_2):
1486 return "2,1";
1487 default:
1488 return "UNKNOWN";
1489 }
1490 }
1491 if (code == sGatewayPorts && val == 2)
1492 return "clientspecified";
1493 if (code == sCompression && val == COMP_DELAYED)
1494 return "delayed";
1495 switch (val) {
1496 case -1:
1497 return "unset";
1498 case 0:
1499 return "no";
1500 case 1:
1501 return "yes";
1502 }
1503 return "UNKNOWN";
1504}
1505
1506static const char *
1507lookup_opcode_name(ServerOpCodes code)
1508{
1509 u_int i;
1510
1511 for (i = 0; keywords[i].name != NULL; i++)
1512 if (keywords[i].opcode == code)
1513 return(keywords[i].name);
1514 return "UNKNOWN";
1515}
1516
1517static void
1518dump_cfg_int(ServerOpCodes code, int val)
1519{
1520 printf("%s %d\n", lookup_opcode_name(code), val);
1521}
1522
1523static void
1524dump_cfg_fmtint(ServerOpCodes code, int val)
1525{
1526 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1527}
1528
1529static void
1530dump_cfg_string(ServerOpCodes code, const char *val)
1531{
1532 if (val == NULL)
1533 return;
1534 printf("%s %s\n", lookup_opcode_name(code), val);
1535}
1536
1537static void
1538dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
1539{
1540 u_int i;
1541
1542 for (i = 0; i < count; i++)
1543 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
1544}
1545
1546void
1547dump_config(ServerOptions *o)
1548{
1549 u_int i;
1550 int ret;
1551 struct addrinfo *ai;
1552 char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
1553
1554 /* these are usually at the top of the config */
1555 for (i = 0; i < o->num_ports; i++)
1556 printf("port %d\n", o->ports[i]);
1557 dump_cfg_fmtint(sProtocol, o->protocol);
1558 dump_cfg_fmtint(sAddressFamily, o->address_family);
1559
1560 /* ListenAddress must be after Port */
1561 for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
1562 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
1563 sizeof(addr), port, sizeof(port),
1564 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1565 error("getnameinfo failed: %.100s",
1566 (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1567 strerror(errno));
1568 } else {
1569 if (ai->ai_family == AF_INET6)
1570 printf("listenaddress [%s]:%s\n", addr, port);
1571 else
1572 printf("listenaddress %s:%s\n", addr, port);
1573 }
1574 }
1575
1576 /* integer arguments */
1577#ifdef USE_PAM
1578 dump_cfg_int(sUsePAM, o->use_pam);
1579#endif
1580 dump_cfg_int(sServerKeyBits, o->server_key_bits);
1581 dump_cfg_int(sLoginGraceTime, o->login_grace_time);
1582 dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
1583 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
1584 dump_cfg_int(sMaxAuthTries, o->max_authtries);
1585 dump_cfg_int(sMaxSessions, o->max_sessions);
1586 dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
1587 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
1588 dump_cfg_int(sRDomain, o->rdomain);
1589
1590 /* formatted integer arguments */
1591 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
1592 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
1593 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
1594 dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
1595 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
1596 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
1597 o->hostbased_uses_name_from_packet_only);
1598 dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
1599 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
1600#ifdef KRB5
1601 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
1602 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
1603 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
1604# ifdef USE_AFS
1605 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
1606# endif
1607#endif
1608#ifdef GSSAPI
1609 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
1610 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
1611#endif
1612#ifdef JPAKE
1613 dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
1614 o->zero_knowledge_password_authentication);
1615#endif
1616 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
1617 dump_cfg_fmtint(sKbdInteractiveAuthentication,
1618 o->kbd_interactive_authentication);
1619 dump_cfg_fmtint(sChallengeResponseAuthentication,
1620 o->challenge_response_authentication);
1621 dump_cfg_fmtint(sPrintMotd, o->print_motd);
1622 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
1623 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
1624 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
1625 dump_cfg_fmtint(sStrictModes, o->strict_modes);
1626 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
1627 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
1628 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
1629 dump_cfg_fmtint(sUseLogin, o->use_login);
1630 dump_cfg_fmtint(sCompression, o->compression);
1631 dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
1632 dump_cfg_fmtint(sUseDNS, o->use_dns);
1633 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
1634 dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
1635
1636 /* string arguments */
1637 dump_cfg_string(sPidFile, o->pid_file);
1638 dump_cfg_string(sXAuthLocation, o->xauth_location);
1639 dump_cfg_string(sCiphers, o->ciphers);
1640 dump_cfg_string(sMacs, o->macs);
1641 dump_cfg_string(sBanner, o->banner);
1642 dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
1643 dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
1644 dump_cfg_string(sForceCommand, o->adm_forced_command);
1645
1646 /* string arguments requiring a lookup */
1647 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1648 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
1649
1650 /* string array arguments */
1651 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
1652 o->host_key_files);
1653 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
1654 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
1655 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
1656 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
1657 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
1658
1659 /* other arguments */
1660 for (i = 0; i < o->num_subsystems; i++)
1661 printf("subsystem %s %s\n", o->subsystem_name[i],
1662 o->subsystem_args[i]);
1663
1664 printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
1665 o->max_startups_rate, o->max_startups);
1666
1667 for (i = 0; tunmode_desc[i].val != -1; i++)
1668 if (tunmode_desc[i].val == o->permit_tun) {
1669 s = tunmode_desc[i].text;
1670 break;
1671 }
1672 dump_cfg_string(sPermitTunnel, s);
1673
1674 channel_print_adm_permitted_opens();
1675}
This page took 0.063742 seconds and 5 git commands to generate.