1769 dladm show-link truncates OVER field
[unleashed.git] / usr / src / cmd / ssh / sshd / servconf.c
blob516466bbc113a10d47afd05d7fcf159bc6d8b4da
1 /*
2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3 * All rights reserved
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".
12 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
13 * Copyright 2013 Joyent, Inc. All rights reserved.
16 #include "includes.h"
17 RCSID("$OpenBSD: servconf.c,v 1.115 2002/09/04 18:52:42 stevesk Exp $");
19 #ifdef HAVE_DEFOPEN
20 #include <deflt.h>
21 #endif /* HAVE_DEFOPEN */
23 #if defined(KRB4)
24 #include <krb.h>
25 #endif
26 #if defined(KRB5)
27 #ifdef HEIMDAL
28 #include <krb.h>
29 #else
30 /* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V
31 * keytab */
32 #define KEYFILE "/etc/krb5.keytab"
33 #endif
34 #endif
35 #ifdef AFS
36 #include <kafs.h>
37 #endif
39 #include "ssh.h"
40 #include "log.h"
41 #include "buffer.h"
42 #include "servconf.h"
43 #include "xmalloc.h"
44 #include "compat.h"
45 #include "pathnames.h"
46 #include "tildexpand.h"
47 #include "misc.h"
48 #include "cipher.h"
49 #include "kex.h"
50 #include "mac.h"
51 #include "auth.h"
52 #include "match.h"
53 #include "groupaccess.h"
55 static void add_listen_addr(ServerOptions *, char *, u_short);
56 static void add_one_listen_addr(ServerOptions *, char *, u_short);
58 extern Buffer cfg;
60 /* AF_UNSPEC or AF_INET or AF_INET6 */
61 extern int IPv4or6;
64 * Initializes the server options to their initial (unset) values. Some of those
65 * that stay unset after the command line options and configuration files are
66 * read are set to their default values in fill_default_server_options().
68 void
69 initialize_server_options(ServerOptions *options)
71 (void) memset(options, 0, sizeof(*options));
73 /* Standard Options */
74 options->num_ports = 0;
75 options->ports_from_cmdline = 0;
76 options->listen_addrs = NULL;
77 options->num_host_key_files = 0;
78 options->pid_file = NULL;
79 options->server_key_bits = -1;
80 options->login_grace_time = -1;
81 options->key_regeneration_time = -1;
82 options->permit_root_login = PERMIT_NOT_SET;
83 options->ignore_rhosts = -1;
84 options->ignore_user_known_hosts = -1;
85 options->print_motd = -1;
86 options->print_lastlog = -1;
87 options->x11_forwarding = -1;
88 options->x11_display_offset = -1;
89 options->x11_use_localhost = -1;
90 options->xauth_location = NULL;
91 options->strict_modes = -1;
92 options->keepalives = -1;
93 options->log_facility = SYSLOG_FACILITY_NOT_SET;
94 options->log_level = SYSLOG_LEVEL_NOT_SET;
95 options->rhosts_authentication = -1;
96 options->rhosts_rsa_authentication = -1;
97 options->hostbased_authentication = -1;
98 options->hostbased_uses_name_from_packet_only = -1;
99 options->rsa_authentication = -1;
100 options->pubkey_authentication = -1;
101 #ifdef GSSAPI
102 options->gss_authentication = -1;
103 options->gss_keyex = -1;
104 options->gss_store_creds = -1;
105 options->gss_use_session_ccache = -1;
106 options->gss_cleanup_creds = -1;
107 #endif
108 #if defined(KRB4) || defined(KRB5)
109 options->kerberos_authentication = -1;
110 options->kerberos_or_local_passwd = -1;
111 options->kerberos_ticket_cleanup = -1;
112 #endif
113 #if defined(AFS) || defined(KRB5)
114 options->kerberos_tgt_passing = -1;
115 #endif
116 #ifdef AFS
117 options->afs_token_passing = -1;
118 #endif
119 options->password_authentication = -1;
120 options->kbd_interactive_authentication = -1;
121 options->challenge_response_authentication = -1;
122 options->pam_authentication_via_kbd_int = -1;
123 options->permit_empty_passwd = -1;
124 options->permit_user_env = -1;
125 options->compression = -1;
126 options->allow_tcp_forwarding = -1;
127 options->num_allow_users = 0;
128 options->num_deny_users = 0;
129 options->num_allow_groups = 0;
130 options->num_deny_groups = 0;
131 options->ciphers = NULL;
132 options->macs = NULL;
133 options->protocol = SSH_PROTO_UNKNOWN;
134 options->gateway_ports = -1;
135 options->num_subsystems = 0;
136 options->max_startups_begin = -1;
137 options->max_startups_rate = -1;
138 options->max_startups = -1;
139 options->banner = NULL;
140 options->verify_reverse_mapping = -1;
141 options->client_alive_interval = -1;
142 options->client_alive_count_max = -1;
143 options->authorized_keys_file = NULL;
144 options->authorized_keys_file2 = NULL;
146 options->max_auth_tries = -1;
147 options->max_auth_tries_log = -1;
149 options->max_init_auth_tries = -1;
150 options->max_init_auth_tries_log = -1;
152 options->lookup_client_hostnames = -1;
153 options->use_openssl_engine = -1;
154 options->chroot_directory = NULL;
155 options->pre_userauth_hook = NULL;
156 options->pam_service_name = NULL;
157 options->pam_service_prefix = NULL;
160 #ifdef HAVE_DEFOPEN
162 * Reads /etc/default/login and defaults several ServerOptions:
164 * PermitRootLogin
165 * PermitEmptyPasswords
166 * LoginGraceTime
168 * CONSOLE=* -> PermitRootLogin=without-password
169 * #CONSOLE=* -> PermitRootLogin=yes
171 * PASSREQ=YES -> PermitEmptyPasswords=no
172 * PASSREQ=NO -> PermitEmptyPasswords=yes
173 * #PASSREQ=* -> PermitEmptyPasswords=no
175 * TIMEOUT=<secs> -> LoginGraceTime=<secs>
176 * #TIMEOUT=<secs> -> LoginGraceTime=300
178 static
179 void
180 deflt_fill_default_server_options(ServerOptions *options)
182 int flags;
183 char *ptr;
185 if (defopen(_PATH_DEFAULT_LOGIN))
186 return;
188 /* Ignore case */
189 flags = defcntl(DC_GETFLAGS, 0);
190 TURNOFF(flags, DC_CASE);
191 (void) defcntl(DC_SETFLAGS, flags);
193 if (options->permit_root_login == PERMIT_NOT_SET &&
194 (ptr = defread("CONSOLE=")) != NULL)
195 options->permit_root_login = PERMIT_NO_PASSWD;
197 if (options->permit_empty_passwd == -1 &&
198 (ptr = defread("PASSREQ=")) != NULL) {
199 if (strcasecmp("YES", ptr) == 0)
200 options->permit_empty_passwd = 0;
201 else if (strcasecmp("NO", ptr) == 0)
202 options->permit_empty_passwd = 1;
205 if (options->max_init_auth_tries == -1 &&
206 (ptr = defread("RETRIES=")) != NULL) {
207 options->max_init_auth_tries = atoi(ptr);
210 if (options->max_init_auth_tries_log == -1 &&
211 (ptr = defread("SYSLOG_FAILED_LOGINS=")) != NULL) {
212 options->max_init_auth_tries_log = atoi(ptr);
215 if (options->login_grace_time == -1) {
216 if ((ptr = defread("TIMEOUT=")) != NULL)
217 options->login_grace_time = (unsigned)atoi(ptr);
218 else
219 options->login_grace_time = 300;
222 (void) defopen((char *)NULL);
224 #endif /* HAVE_DEFOPEN */
226 void
227 fill_default_server_options(ServerOptions *options)
230 #ifdef HAVE_DEFOPEN
231 deflt_fill_default_server_options(options);
232 #endif /* HAVE_DEFOPEN */
234 /* Standard Options */
235 if (options->protocol == SSH_PROTO_UNKNOWN)
236 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
237 if (options->num_host_key_files == 0) {
238 /* fill default hostkeys for protocols */
239 if (options->protocol & SSH_PROTO_1)
240 options->host_key_files[options->num_host_key_files++] =
241 _PATH_HOST_KEY_FILE;
242 #ifndef GSSAPI
243 /* With GSS keyex we can run v2 w/ no host keys */
244 if (options->protocol & SSH_PROTO_2) {
245 options->host_key_files[options->num_host_key_files++] =
246 _PATH_HOST_RSA_KEY_FILE;
247 options->host_key_files[options->num_host_key_files++] =
248 _PATH_HOST_DSA_KEY_FILE;
250 #endif /* GSSAPI */
252 if (options->num_ports == 0)
253 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
254 if (options->listen_addrs == NULL)
255 add_listen_addr(options, NULL, 0);
256 if (options->pid_file == NULL)
257 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
258 if (options->server_key_bits == -1)
259 options->server_key_bits = 768;
260 if (options->login_grace_time == -1)
261 options->login_grace_time = 120;
262 if (options->key_regeneration_time == -1)
263 options->key_regeneration_time = 3600;
264 if (options->permit_root_login == PERMIT_NOT_SET)
265 options->permit_root_login = PERMIT_YES;
266 if (options->ignore_rhosts == -1)
267 options->ignore_rhosts = 1;
268 if (options->ignore_user_known_hosts == -1)
269 options->ignore_user_known_hosts = 0;
270 if (options->print_motd == -1)
271 options->print_motd = 1;
272 if (options->print_lastlog == -1)
273 options->print_lastlog = 1;
274 if (options->x11_forwarding == -1)
275 options->x11_forwarding = 1;
276 if (options->x11_display_offset == -1)
277 options->x11_display_offset = 10;
278 if (options->x11_use_localhost == -1)
279 options->x11_use_localhost = 1;
280 if (options->xauth_location == NULL)
281 options->xauth_location = _PATH_XAUTH;
282 if (options->strict_modes == -1)
283 options->strict_modes = 1;
284 if (options->keepalives == -1)
285 options->keepalives = 1;
286 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
287 options->log_facility = SYSLOG_FACILITY_AUTH;
288 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
289 options->log_level = SYSLOG_LEVEL_INFO;
290 if (options->rhosts_authentication == -1)
291 options->rhosts_authentication = 0;
292 if (options->rhosts_rsa_authentication == -1)
293 options->rhosts_rsa_authentication = 0;
294 if (options->hostbased_authentication == -1)
295 options->hostbased_authentication = 0;
296 if (options->hostbased_uses_name_from_packet_only == -1)
297 options->hostbased_uses_name_from_packet_only = 0;
298 if (options->rsa_authentication == -1)
299 options->rsa_authentication = 1;
300 if (options->pubkey_authentication == -1)
301 options->pubkey_authentication = 1;
302 #ifdef GSSAPI
303 if (options->gss_authentication == -1)
304 options->gss_authentication = 1;
305 if (options->gss_keyex == -1)
306 options->gss_keyex = 1;
307 if (options->gss_store_creds == -1)
308 options->gss_store_creds = 1;
309 if (options->gss_use_session_ccache == -1)
310 options->gss_use_session_ccache = 1;
311 if (options->gss_cleanup_creds == -1)
312 options->gss_cleanup_creds = 1;
313 #endif
314 #if defined(KRB4) || defined(KRB5)
315 if (options->kerberos_authentication == -1)
316 options->kerberos_authentication = 0;
317 if (options->kerberos_or_local_passwd == -1)
318 options->kerberos_or_local_passwd = 1;
319 if (options->kerberos_ticket_cleanup == -1)
320 options->kerberos_ticket_cleanup = 1;
321 #endif
322 #if defined(AFS) || defined(KRB5)
323 if (options->kerberos_tgt_passing == -1)
324 options->kerberos_tgt_passing = 0;
325 #endif
326 #ifdef AFS
327 if (options->afs_token_passing == -1)
328 options->afs_token_passing = 0;
329 #endif
330 if (options->password_authentication == -1)
331 options->password_authentication = 1;
333 * options->pam_authentication_via_kbd_int has intentionally no default
334 * value since we do not need it.
336 if (options->kbd_interactive_authentication == -1)
337 options->kbd_interactive_authentication = 1;
338 if (options->challenge_response_authentication == -1)
339 options->challenge_response_authentication = 1;
340 if (options->permit_empty_passwd == -1)
341 options->permit_empty_passwd = 0;
342 if (options->permit_user_env == -1)
343 options->permit_user_env = 0;
344 if (options->compression == -1)
345 options->compression = 1;
346 if (options->allow_tcp_forwarding == -1)
347 options->allow_tcp_forwarding = 1;
348 if (options->gateway_ports == -1)
349 options->gateway_ports = 0;
350 if (options->max_startups == -1)
351 options->max_startups = 10;
352 if (options->max_startups_rate == -1)
353 options->max_startups_rate = 100; /* 100% */
354 if (options->max_startups_begin == -1)
355 options->max_startups_begin = options->max_startups;
356 if (options->verify_reverse_mapping == -1)
357 options->verify_reverse_mapping = 0;
358 if (options->client_alive_interval == -1)
359 options->client_alive_interval = 0;
360 if (options->client_alive_count_max == -1)
361 options->client_alive_count_max = 3;
362 if (options->authorized_keys_file2 == NULL) {
363 /* authorized_keys_file2 falls back to authorized_keys_file */
364 if (options->authorized_keys_file != NULL)
365 options->authorized_keys_file2 = options->authorized_keys_file;
366 else
367 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
369 if (options->authorized_keys_file == NULL)
370 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
372 if (options->max_auth_tries == -1)
373 options->max_auth_tries = AUTH_FAIL_MAX;
374 if (options->max_auth_tries_log == -1)
375 options->max_auth_tries_log = options->max_auth_tries / 2;
377 if (options->max_init_auth_tries == -1)
378 options->max_init_auth_tries = AUTH_FAIL_MAX;
379 if (options->max_init_auth_tries_log == -1)
380 options->max_init_auth_tries_log = options->max_init_auth_tries / 2;
382 if (options->lookup_client_hostnames == -1)
383 options->lookup_client_hostnames = 1;
384 if (options->use_openssl_engine == -1)
385 options->use_openssl_engine = 1;
386 if (options->pam_service_prefix == NULL)
387 options->pam_service_prefix = _SSH_PAM_SERVICE_PREFIX;
388 if (options->pam_service_name == NULL)
389 options->pam_service_name = NULL;
392 /* Keyword tokens. */
393 typedef enum {
394 sBadOption, /* == unknown option */
395 /* Portable-specific options */
396 sPAMAuthenticationViaKbdInt,
397 /* Standard Options */
398 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
399 sPermitRootLogin, sLogFacility, sLogLevel,
400 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
401 #ifdef GSSAPI
402 sGssAuthentication, sGssKeyEx, sGssStoreDelegCreds,
403 sGssUseSessionCredCache, sGssCleanupCreds,
404 #endif /* GSSAPI */
405 #if defined(KRB4) || defined(KRB5)
406 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
407 #endif
408 #if defined(AFS) || defined(KRB5)
409 sKerberosTgtPassing,
410 #endif
411 #ifdef AFS
412 sAFSTokenPassing,
413 #endif
414 sChallengeResponseAuthentication,
415 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
416 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
417 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
418 sStrictModes, sEmptyPasswd, sKeepAlives,
419 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
420 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
421 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
422 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
423 sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
424 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
425 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
426 sMaxAuthTries, sMaxAuthTriesLog, sUsePrivilegeSeparation,
427 sLookupClientHostnames, sUseOpenSSLEngine, sChrootDirectory,
428 sPreUserauthHook, sMatch, sPAMServicePrefix, sPAMServiceName,
429 sDeprecated
430 } ServerOpCodes;
432 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
433 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
434 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
436 /* Textual representation of the tokens. */
437 static struct {
438 const char *name;
439 ServerOpCodes opcode;
440 u_int flags;
441 } keywords[] = {
442 /* Portable-specific options */
443 { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt, SSHCFG_GLOBAL },
444 /* Standard Options */
445 { "port", sPort, SSHCFG_GLOBAL },
446 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
447 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
448 { "pidfile", sPidFile, SSHCFG_GLOBAL },
449 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
450 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
451 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
452 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
453 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
454 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
455 { "rhostsauthentication", sRhostsAuthentication, SSHCFG_GLOBAL },
456 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
457 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
458 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
459 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
460 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
461 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
462 #ifdef GSSAPI
463 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
464 { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
465 { "gssapistoredelegatedcredentials", sGssStoreDelegCreds, SSHCFG_GLOBAL },
466 { "gssauthentication", sGssAuthentication, SSHCFG_GLOBAL }, /* alias */
467 { "gsskeyex", sGssKeyEx, SSHCFG_GLOBAL }, /* alias */
468 { "gssstoredelegcreds", sGssStoreDelegCreds, SSHCFG_GLOBAL }, /* alias */
469 #ifndef SUNW_GSSAPI
470 { "gssusesessionccache", sGssUseSessionCredCache, SSHCFG_GLOBAL },
471 { "gssusesessioncredcache", sGssUseSessionCredCache, SSHCFG_GLOBAL },
472 { "gsscleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL },
473 #endif /* SUNW_GSSAPI */
474 #endif
475 #if defined(KRB4) || defined(KRB5)
476 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
477 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
478 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
479 #endif
480 #if defined(AFS) || defined(KRB5)
481 { "kerberostgtpassing", sKerberosTgtPassing, SSHCFG_GLOBAL },
482 #endif
483 #ifdef AFS
484 { "afstokenpassing", sAFSTokenPassing, SSHCFG_GLOBAL },
485 #endif
486 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
487 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
488 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
489 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
490 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
491 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
492 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
493 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
494 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
495 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
496 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
497 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
498 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
499 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
500 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
501 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
502 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
503 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
504 { "compression", sCompression, SSHCFG_GLOBAL },
505 { "tcpkeepalive", sKeepAlives, SSHCFG_GLOBAL },
506 { "keepalive", sKeepAlives, SSHCFG_GLOBAL }, /* obsolete */
507 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
508 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
509 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
510 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
511 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
512 { "ciphers", sCiphers, SSHCFG_GLOBAL },
513 { "macs", sMacs, SSHCFG_GLOBAL},
514 { "protocol", sProtocol,SSHCFG_GLOBAL },
515 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
516 { "subsystem", sSubsystem, SSHCFG_GLOBAL},
517 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
518 { "banner", sBanner, SSHCFG_ALL },
519 { "verifyreversemapping", sVerifyReverseMapping, SSHCFG_GLOBAL },
520 { "reversemappingcheck", sVerifyReverseMapping,SSHCFG_GLOBAL },
521 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
522 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
523 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
524 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
525 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
526 { "maxauthtrieslog", sMaxAuthTriesLog, SSHCFG_GLOBAL },
527 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
528 { "lookupclienthostnames", sLookupClientHostnames, SSHCFG_GLOBAL },
529 { "useopensslengine", sUseOpenSSLEngine, SSHCFG_GLOBAL },
530 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
531 { "preuserauthhook", sPreUserauthHook, SSHCFG_ALL},
532 { "match", sMatch, SSHCFG_ALL },
533 { "pamserviceprefix", sPAMServicePrefix, SSHCFG_GLOBAL },
534 { "pamservicename", sPAMServiceName, SSHCFG_GLOBAL },
536 { NULL, sBadOption, 0 }
540 * Returns the number of the token pointed to by cp or sBadOption.
543 static ServerOpCodes
544 parse_token(const char *cp, const char *filename,
545 int linenum, u_int *flags)
547 u_int i;
549 for (i = 0; keywords[i].name; i++)
550 if (strcasecmp(cp, keywords[i].name) == 0) {
551 *flags = keywords[i].flags;
552 return keywords[i].opcode;
555 error("%s: line %d: Bad configuration option: %s",
556 filename, linenum, cp);
557 return sBadOption;
560 static void
561 add_listen_addr(ServerOptions *options, char *addr, u_short port)
563 int i;
565 if (options->num_ports == 0)
566 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
567 if (port == 0)
568 for (i = 0; i < options->num_ports; i++)
569 add_one_listen_addr(options, addr, options->ports[i]);
570 else
571 add_one_listen_addr(options, addr, port);
574 static void
575 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
577 struct addrinfo hints, *ai, *aitop;
578 char strport[NI_MAXSERV];
579 int gaierr;
581 (void) memset(&hints, 0, sizeof(hints));
582 hints.ai_family = IPv4or6;
583 hints.ai_socktype = SOCK_STREAM;
584 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
585 (void) snprintf(strport, sizeof strport, "%u", port);
586 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
587 fatal("bad addr or host: %s (%s)",
588 addr ? addr : "<NULL>",
589 gai_strerror(gaierr));
590 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
592 ai->ai_next = options->listen_addrs;
593 options->listen_addrs = aitop;
597 * The strategy for the Match blocks is that the config file is parsed twice.
599 * The first time is at startup. activep is initialized to 1 and the
600 * directives in the global context are processed and acted on. Hitting a
601 * Match directive unsets activep and the directives inside the block are
602 * checked for syntax only.
604 * The second time is after a connection has been established but before
605 * authentication. activep is initialized to 2 and global config directives
606 * are ignored since they have already been processed. If the criteria in a
607 * Match block is met, activep is set and the subsequent directives
608 * processed and actioned until EOF or another Match block unsets it. Any
609 * options set are copied into the main server config.
611 * Potential additions/improvements:
612 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
614 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
615 * Match Address 192.168.0.*
616 * Tag trusted
617 * Match Group wheel
618 * Tag trusted
619 * Match Tag trusted
620 * AllowTcpForwarding yes
621 * GatewayPorts clientspecified
622 * [...]
624 * - Add a PermittedChannelRequests directive
625 * Match Group shell
626 * PermittedChannelRequests session,forwarded-tcpip
629 static int
630 match_cfg_line_group(const char *grps, int line, const char *user)
632 int result = 0;
633 struct passwd *pw;
635 if (user == NULL)
636 goto out;
638 if ((pw = getpwnam(user)) == NULL) {
639 debug("Can't match group at line %d because user %.100s does "
640 "not exist", line, user);
641 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
642 debug("Can't Match group because user %.100s not in any group "
643 "at line %d", user, line);
644 } else if (ga_match_pattern_list(grps) != 1) {
645 debug("user %.100s does not match group list %.100s at line %d",
646 user, grps, line);
647 } else {
648 debug("user %.100s matched group list %.100s at line %d", user,
649 grps, line);
650 result = 1;
652 out:
653 ga_free();
654 return result;
657 static int
658 match_cfg_line(char **condition, int line, const char *user, const char *host,
659 const char *address)
661 int result = 1;
662 char *arg, *attrib, *cp = *condition;
663 size_t len;
665 if (user == NULL)
666 debug3("checking syntax for 'Match %s'", cp);
667 else
668 debug3("checking match for '%s' user %s host %s addr %s", cp,
669 user ? user : "(null)", host ? host : "(null)",
670 address ? address : "(null)");
672 while ((attrib = strdelim(&cp)) != NULL && *attrib != '\0') {
673 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
674 error("Missing Match criteria for %s", attrib);
675 return -1;
677 len = strlen(arg);
678 if (strcasecmp(attrib, "user") == 0) {
679 if (!user) {
680 result = 0;
681 continue;
683 if (match_pattern_list(user, arg, len, 0) != 1)
684 result = 0;
685 else
686 debug("user %.100s matched 'User %.100s' at "
687 "line %d", user, arg, line);
688 } else if (strcasecmp(attrib, "group") == 0) {
689 switch (match_cfg_line_group(arg, line, user)) {
690 case -1:
691 return -1;
692 case 0:
693 result = 0;
695 } else if (strcasecmp(attrib, "host") == 0) {
696 if (!host) {
697 result = 0;
698 continue;
700 if (match_hostname(host, arg, len) != 1)
701 result = 0;
702 else
703 debug("connection from %.100s matched 'Host "
704 "%.100s' at line %d", host, arg, line);
705 } else if (strcasecmp(attrib, "address") == 0) {
706 switch (addr_match_list(address, arg)) {
707 case 1:
708 debug("connection from %.100s matched 'Address "
709 "%.100s' at line %d", address, arg, line);
710 break;
711 case 0:
712 case -1:
713 result = 0;
714 break;
715 case -2:
716 return -1;
718 } else {
719 error("Unsupported Match attribute %s", attrib);
720 return -1;
723 if (user != NULL)
724 debug3("match %sfound", result ? "" : "not ");
725 *condition = cp;
726 return result;
729 #define WHITESPACE " \t\r\n"
732 process_server_config_line(ServerOptions *options, char *line,
733 const char *filename, int linenum, int *activep, const char *user,
734 const char *host, const char *address)
736 char *cp, **charptr, *arg, *p;
737 int cmdline = 0, *intptr, value, n;
738 ServerOpCodes opcode;
739 u_int i, flags = 0;
740 size_t len;
742 cp = line;
743 arg = strdelim(&cp);
744 /* Ignore leading whitespace */
745 if (*arg == '\0')
746 arg = strdelim(&cp);
747 if (!arg || !*arg || *arg == '#')
748 return 0;
749 intptr = NULL;
750 charptr = NULL;
751 opcode = parse_token(arg, filename, linenum, &flags);
753 if (activep == NULL) { /* We are processing a command line directive */
754 cmdline = 1;
755 activep = &cmdline;
757 if (*activep && opcode != sMatch)
758 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
759 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
760 if (user == NULL) {
761 fatal("%s line %d: Directive '%s' is not allowed "
762 "within a Match block", filename, linenum, arg);
763 } else { /* this is a directive we have already processed */
764 while (arg)
765 arg = strdelim(&cp);
766 return 0;
770 switch (opcode) {
771 /* Portable-specific options */
772 case sPAMAuthenticationViaKbdInt:
773 log("%s line %d: PAMAuthenticationViaKbdInt has been "
774 "deprecated. You should use KbdInteractiveAuthentication "
775 "instead (which defaults to \"yes\").", filename, linenum);
776 intptr = &options->pam_authentication_via_kbd_int;
777 goto parse_flag;
779 /* Standard Options */
780 case sBadOption:
781 return -1;
782 case sPort:
783 /* ignore ports from configfile if cmdline specifies ports */
784 if (options->ports_from_cmdline)
785 return 0;
786 if (options->listen_addrs != NULL)
787 fatal("%s line %d: ports must be specified before "
788 "ListenAddress.", filename, linenum);
789 if (options->num_ports >= MAX_PORTS)
790 fatal("%s line %d: too many ports.",
791 filename, linenum);
792 arg = strdelim(&cp);
793 if (!arg || *arg == '\0')
794 fatal("%s line %d: missing port number.",
795 filename, linenum);
796 options->ports[options->num_ports++] = a2port(arg);
797 if (options->ports[options->num_ports-1] == 0)
798 fatal("%s line %d: Badly formatted port number.",
799 filename, linenum);
800 break;
802 case sServerKeyBits:
803 intptr = &options->server_key_bits;
804 parse_int:
805 arg = strdelim(&cp);
806 if (!arg || *arg == '\0')
807 fatal("%s line %d: missing integer value.",
808 filename, linenum);
809 value = atoi(arg);
810 if (*activep && *intptr == -1)
811 *intptr = value;
812 break;
814 case sLoginGraceTime:
815 intptr = &options->login_grace_time;
816 parse_time:
817 arg = strdelim(&cp);
818 if (!arg || *arg == '\0')
819 fatal("%s line %d: missing time value.",
820 filename, linenum);
821 if ((value = convtime(arg)) == -1)
822 fatal("%s line %d: invalid time value.",
823 filename, linenum);
824 if (*intptr == -1)
825 *intptr = value;
826 break;
828 case sKeyRegenerationTime:
829 intptr = &options->key_regeneration_time;
830 goto parse_time;
832 case sListenAddress:
833 arg = strdelim(&cp);
834 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
835 fatal("%s line %d: missing inet addr.",
836 filename, linenum);
837 if (*arg == '[') {
838 if ((p = strchr(arg, ']')) == NULL)
839 fatal("%s line %d: bad ipv6 inet addr usage.",
840 filename, linenum);
841 arg++;
842 (void) memmove(p, p+1, strlen(p+1)+1);
843 } else if (((p = strchr(arg, ':')) == NULL) ||
844 (strchr(p+1, ':') != NULL)) {
845 add_listen_addr(options, arg, 0);
846 break;
848 if (*p == ':') {
849 u_short port;
851 p++;
852 if (*p == '\0')
853 fatal("%s line %d: bad inet addr:port usage.",
854 filename, linenum);
855 else {
856 *(p-1) = '\0';
857 if ((port = a2port(p)) == 0)
858 fatal("%s line %d: bad port number.",
859 filename, linenum);
860 add_listen_addr(options, arg, port);
862 } else if (*p == '\0')
863 add_listen_addr(options, arg, 0);
864 else
865 fatal("%s line %d: bad inet addr usage.",
866 filename, linenum);
867 break;
869 case sHostKeyFile:
870 intptr = &options->num_host_key_files;
871 if (*intptr >= MAX_HOSTKEYS)
872 fatal("%s line %d: too many host keys specified (max %d).",
873 filename, linenum, MAX_HOSTKEYS);
874 charptr = &options->host_key_files[*intptr];
875 parse_filename:
876 arg = strdelim(&cp);
877 if (!arg || *arg == '\0')
878 fatal("%s line %d: missing file name.",
879 filename, linenum);
880 if (*activep && *charptr == NULL) {
881 *charptr = tilde_expand_filename(arg, getuid());
882 /* increase optional counter */
883 if (intptr != NULL)
884 *intptr = *intptr + 1;
886 break;
888 case sPidFile:
889 charptr = &options->pid_file;
890 goto parse_filename;
892 case sPermitRootLogin:
893 intptr = &options->permit_root_login;
894 arg = strdelim(&cp);
895 if (!arg || *arg == '\0')
896 fatal("%s line %d: missing yes/"
897 "without-password/forced-commands-only/no "
898 "argument.", filename, linenum);
899 value = 0; /* silence compiler */
900 if (strcmp(arg, "without-password") == 0)
901 value = PERMIT_NO_PASSWD;
902 else if (strcmp(arg, "forced-commands-only") == 0)
903 value = PERMIT_FORCED_ONLY;
904 else if (strcmp(arg, "yes") == 0)
905 value = PERMIT_YES;
906 else if (strcmp(arg, "no") == 0)
907 value = PERMIT_NO;
908 else
909 fatal("%s line %d: Bad yes/"
910 "without-password/forced-commands-only/no "
911 "argument: %s", filename, linenum, arg);
912 if (*activep && *intptr == -1)
913 *intptr = value;
914 break;
916 case sIgnoreRhosts:
917 intptr = &options->ignore_rhosts;
918 parse_flag:
919 arg = strdelim(&cp);
920 if (!arg || *arg == '\0')
921 fatal("%s line %d: missing yes/no argument.",
922 filename, linenum);
923 value = 0; /* silence compiler */
924 if (strcmp(arg, "yes") == 0)
925 value = 1;
926 else if (strcmp(arg, "no") == 0)
927 value = 0;
928 else
929 fatal("%s line %d: Bad yes/no argument: %s",
930 filename, linenum, arg);
931 if (*activep && *intptr == -1)
932 *intptr = value;
933 break;
935 case sIgnoreUserKnownHosts:
936 intptr = &options->ignore_user_known_hosts;
937 goto parse_flag;
939 case sRhostsAuthentication:
940 intptr = &options->rhosts_authentication;
941 goto parse_flag;
943 case sRhostsRSAAuthentication:
944 intptr = &options->rhosts_rsa_authentication;
945 goto parse_flag;
947 case sHostbasedAuthentication:
948 intptr = &options->hostbased_authentication;
949 goto parse_flag;
951 case sHostbasedUsesNameFromPacketOnly:
952 intptr = &options->hostbased_uses_name_from_packet_only;
953 goto parse_flag;
955 case sRSAAuthentication:
956 intptr = &options->rsa_authentication;
957 goto parse_flag;
959 case sPubkeyAuthentication:
960 intptr = &options->pubkey_authentication;
961 goto parse_flag;
962 #ifdef GSSAPI
963 case sGssAuthentication:
964 intptr = &options->gss_authentication;
965 goto parse_flag;
966 case sGssKeyEx:
967 intptr = &options->gss_keyex;
968 goto parse_flag;
969 case sGssStoreDelegCreds:
970 intptr = &options->gss_keyex;
971 goto parse_flag;
972 #ifndef SUNW_GSSAPI
973 case sGssUseSessionCredCache:
974 intptr = &options->gss_use_session_ccache;
975 goto parse_flag;
976 case sGssCleanupCreds:
977 intptr = &options->gss_cleanup_creds;
978 goto parse_flag;
979 #endif /* SUNW_GSSAPI */
980 #endif /* GSSAPI */
981 #if defined(KRB4) || defined(KRB5)
982 case sKerberosAuthentication:
983 intptr = &options->kerberos_authentication;
984 goto parse_flag;
986 case sKerberosOrLocalPasswd:
987 intptr = &options->kerberos_or_local_passwd;
988 goto parse_flag;
990 case sKerberosTicketCleanup:
991 intptr = &options->kerberos_ticket_cleanup;
992 goto parse_flag;
993 #endif
994 #if defined(AFS) || defined(KRB5)
995 case sKerberosTgtPassing:
996 intptr = &options->kerberos_tgt_passing;
997 goto parse_flag;
998 #endif
999 #ifdef AFS
1000 case sAFSTokenPassing:
1001 intptr = &options->afs_token_passing;
1002 goto parse_flag;
1003 #endif
1005 case sPasswordAuthentication:
1006 intptr = &options->password_authentication;
1007 goto parse_flag;
1009 case sKbdInteractiveAuthentication:
1010 intptr = &options->kbd_interactive_authentication;
1011 goto parse_flag;
1013 case sChallengeResponseAuthentication:
1014 intptr = &options->challenge_response_authentication;
1015 goto parse_flag;
1017 case sPrintMotd:
1018 intptr = &options->print_motd;
1019 goto parse_flag;
1021 case sPrintLastLog:
1022 intptr = &options->print_lastlog;
1023 goto parse_flag;
1025 case sX11Forwarding:
1026 intptr = &options->x11_forwarding;
1027 goto parse_flag;
1029 case sX11DisplayOffset:
1030 intptr = &options->x11_display_offset;
1031 goto parse_int;
1033 case sX11UseLocalhost:
1034 intptr = &options->x11_use_localhost;
1035 goto parse_flag;
1037 case sXAuthLocation:
1038 charptr = &options->xauth_location;
1039 goto parse_filename;
1041 case sStrictModes:
1042 intptr = &options->strict_modes;
1043 goto parse_flag;
1045 case sKeepAlives:
1046 intptr = &options->keepalives;
1047 goto parse_flag;
1049 case sEmptyPasswd:
1050 intptr = &options->permit_empty_passwd;
1051 goto parse_flag;
1053 case sPermitUserEnvironment:
1054 intptr = &options->permit_user_env;
1055 goto parse_flag;
1057 case sUseLogin:
1058 log("%s line %d: ignoring UseLogin option value."
1059 " This option is always off.", filename, linenum);
1060 while (arg)
1061 arg = strdelim(&cp);
1062 break;
1064 case sCompression:
1065 intptr = &options->compression;
1066 goto parse_flag;
1068 case sGatewayPorts:
1069 intptr = &options->gateway_ports;
1070 arg = strdelim(&cp);
1071 if (!arg || *arg == '\0')
1072 fatal("%s line %d: missing yes/no/clientspecified "
1073 "argument.", filename, linenum);
1074 value = 0; /* silence compiler */
1075 if (strcmp(arg, "clientspecified") == 0)
1076 value = 2;
1077 else if (strcmp(arg, "yes") == 0)
1078 value = 1;
1079 else if (strcmp(arg, "no") == 0)
1080 value = 0;
1081 else
1082 fatal("%s line %d: Bad yes/no/clientspecified "
1083 "argument: %s", filename, linenum, arg);
1084 if (*activep && *intptr == -1)
1085 *intptr = value;
1086 break;
1088 case sVerifyReverseMapping:
1089 intptr = &options->verify_reverse_mapping;
1090 goto parse_flag;
1092 case sLogFacility:
1093 intptr = (int *) &options->log_facility;
1094 arg = strdelim(&cp);
1095 value = log_facility_number(arg);
1096 if (value == SYSLOG_FACILITY_NOT_SET)
1097 fatal("%.200s line %d: unsupported log facility '%s'",
1098 filename, linenum, arg ? arg : "<NONE>");
1099 if (*intptr == -1)
1100 *intptr = (SyslogFacility) value;
1101 break;
1103 case sLogLevel:
1104 intptr = (int *) &options->log_level;
1105 arg = strdelim(&cp);
1106 value = log_level_number(arg);
1107 if (value == SYSLOG_LEVEL_NOT_SET)
1108 fatal("%.200s line %d: unsupported log level '%s'",
1109 filename, linenum, arg ? arg : "<NONE>");
1110 if (*intptr == -1)
1111 *intptr = (LogLevel) value;
1112 break;
1114 case sAllowTcpForwarding:
1115 intptr = &options->allow_tcp_forwarding;
1116 goto parse_flag;
1118 case sUsePrivilegeSeparation:
1119 log("%s line %d: ignoring UsePrivilegeSeparation option value."
1120 " This option is always on.", filename, linenum);
1121 while (arg)
1122 arg = strdelim(&cp);
1123 break;
1125 case sAllowUsers:
1126 while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1127 if (options->num_allow_users >= MAX_ALLOW_USERS)
1128 fatal("%s line %d: too many allow users.",
1129 filename, linenum);
1130 options->allow_users[options->num_allow_users++] =
1131 xstrdup(arg);
1133 break;
1135 case sDenyUsers:
1136 while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1137 if (options->num_deny_users >= MAX_DENY_USERS)
1138 fatal( "%s line %d: too many deny users.",
1139 filename, linenum);
1140 options->deny_users[options->num_deny_users++] =
1141 xstrdup(arg);
1143 break;
1145 case sAllowGroups:
1146 while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1147 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1148 fatal("%s line %d: too many allow groups.",
1149 filename, linenum);
1150 options->allow_groups[options->num_allow_groups++] =
1151 xstrdup(arg);
1153 break;
1155 case sDenyGroups:
1156 while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1157 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1158 fatal("%s line %d: too many deny groups.",
1159 filename, linenum);
1160 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1162 break;
1164 case sCiphers:
1165 arg = strdelim(&cp);
1166 if (!arg || *arg == '\0')
1167 fatal("%s line %d: Missing argument.", filename, linenum);
1168 if (!ciphers_valid(arg))
1169 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1170 filename, linenum, arg ? arg : "<NONE>");
1171 if (options->ciphers == NULL)
1172 options->ciphers = xstrdup(arg);
1173 break;
1175 case sMacs:
1176 arg = strdelim(&cp);
1177 if (!arg || *arg == '\0')
1178 fatal("%s line %d: Missing argument.", filename, linenum);
1179 if (!mac_valid(arg))
1180 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1181 filename, linenum, arg ? arg : "<NONE>");
1182 if (options->macs == NULL)
1183 options->macs = xstrdup(arg);
1184 break;
1186 case sProtocol:
1187 intptr = &options->protocol;
1188 arg = strdelim(&cp);
1189 if (!arg || *arg == '\0')
1190 fatal("%s line %d: Missing argument.", filename, linenum);
1191 value = proto_spec(arg);
1192 if (value == SSH_PROTO_UNKNOWN)
1193 fatal("%s line %d: Bad protocol spec '%s'.",
1194 filename, linenum, arg ? arg : "<NONE>");
1195 if (*intptr == SSH_PROTO_UNKNOWN)
1196 *intptr = value;
1197 break;
1199 case sSubsystem:
1200 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1201 fatal("%s line %d: too many subsystems defined.",
1202 filename, linenum);
1204 arg = strdelim(&cp);
1205 if (!arg || *arg == '\0')
1206 fatal("%s line %d: Missing subsystem name.",
1207 filename, linenum);
1208 if (!*activep) {
1209 arg = strdelim(&cp);
1210 break;
1212 for (i = 0; i < options->num_subsystems; i++)
1213 if (strcmp(arg, options->subsystem_name[i]) == 0)
1214 fatal("%s line %d: Subsystem '%s' already defined.",
1215 filename, linenum, arg);
1216 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1217 arg = strdelim(&cp);
1218 if (!arg || *arg == '\0')
1219 fatal("%s line %d: Missing subsystem command.",
1220 filename, linenum);
1221 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1224 * Collect arguments (separate to executable), including the
1225 * name of the executable, in a way that is easier to parse
1226 * later.
1228 p = xstrdup(arg);
1229 len = strlen(p) + 1;
1230 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1231 len += 1 + strlen(arg);
1232 p = xrealloc(p, len);
1233 strlcat(p, " ", len);
1234 strlcat(p, arg, len);
1236 options->subsystem_args[options->num_subsystems] = p;
1237 options->num_subsystems++;
1238 break;
1240 case sMaxStartups:
1241 arg = strdelim(&cp);
1242 if (!arg || *arg == '\0')
1243 fatal("%s line %d: Missing MaxStartups spec.",
1244 filename, linenum);
1245 if ((n = sscanf(arg, "%d:%d:%d",
1246 &options->max_startups_begin,
1247 &options->max_startups_rate,
1248 &options->max_startups)) == 3) {
1249 if (options->max_startups_begin >
1250 options->max_startups ||
1251 options->max_startups_rate > 100 ||
1252 options->max_startups_rate < 1)
1253 fatal("%s line %d: Illegal MaxStartups spec.",
1254 filename, linenum);
1255 } else if (n != 1)
1256 fatal("%s line %d: Illegal MaxStartups spec.",
1257 filename, linenum);
1258 else
1259 options->max_startups = options->max_startups_begin;
1260 break;
1262 case sBanner:
1263 charptr = &options->banner;
1264 goto parse_filename;
1266 * These options can contain %X options expanded at
1267 * connect time, so that you can specify paths like:
1269 * AuthorizedKeysFile /etc/ssh_keys/%u
1271 case sAuthorizedKeysFile:
1272 case sAuthorizedKeysFile2:
1273 charptr = (opcode == sAuthorizedKeysFile) ?
1274 &options->authorized_keys_file :
1275 &options->authorized_keys_file2;
1276 goto parse_filename;
1278 case sClientAliveInterval:
1279 intptr = &options->client_alive_interval;
1280 goto parse_time;
1282 case sClientAliveCountMax:
1283 intptr = &options->client_alive_count_max;
1284 goto parse_int;
1286 case sMaxAuthTries:
1287 intptr = &options->max_auth_tries;
1288 goto parse_int;
1290 case sMaxAuthTriesLog:
1291 intptr = &options->max_auth_tries_log;
1292 goto parse_int;
1294 case sLookupClientHostnames:
1295 intptr = &options->lookup_client_hostnames;
1296 goto parse_flag;
1298 case sUseOpenSSLEngine:
1299 intptr = &options->use_openssl_engine;
1300 goto parse_flag;
1302 case sChrootDirectory:
1303 charptr = &options->chroot_directory;
1305 arg = strdelim(&cp);
1306 if (arg == NULL || *arg == '\0')
1307 fatal("%s line %d: missing directory name for "
1308 "ChrootDirectory.", filename, linenum);
1309 if (*activep && *charptr == NULL)
1310 *charptr = xstrdup(arg);
1311 break;
1313 case sPreUserauthHook:
1314 charptr = &options->pre_userauth_hook;
1315 goto parse_filename;
1317 case sMatch:
1318 if (cmdline)
1319 fatal("Match directive not supported as a command-line "
1320 "option");
1321 value = match_cfg_line(&cp, linenum, user, host, address);
1322 if (value < 0)
1323 fatal("%s line %d: Bad Match condition", filename,
1324 linenum);
1325 *activep = value;
1326 break;
1328 case sDeprecated:
1329 log("%s line %d: Deprecated option %s",
1330 filename, linenum, arg);
1331 while (arg)
1332 arg = strdelim(&cp);
1333 break;
1335 case sPAMServicePrefix:
1336 arg = strdelim(&cp);
1337 if (!arg || *arg == '\0')
1338 fatal("%s line %d: Missing argument.",
1339 filename, linenum);
1340 if (options->pam_service_name != NULL)
1341 fatal("%s line %d: PAMServiceName and PAMServicePrefix "
1342 "are mutually exclusive.", filename, linenum);
1343 if (options->pam_service_prefix == NULL)
1344 options->pam_service_prefix = xstrdup(arg);
1345 break;
1347 case sPAMServiceName:
1348 arg = strdelim(&cp);
1349 if (!arg || *arg == '\0')
1350 fatal("%s line %d: Missing argument.",
1351 filename, linenum);
1352 if (options->pam_service_prefix != NULL)
1353 fatal("%s line %d: PAMServiceName and PAMServicePrefix "
1354 "are mutually exclusive.", filename, linenum);
1355 if (options->pam_service_name == NULL)
1356 options->pam_service_name = xstrdup(arg);
1357 break;
1359 default:
1360 fatal("%s line %d: Missing handler for opcode %s (%d)",
1361 filename, linenum, arg, opcode);
1363 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1364 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1365 filename, linenum, arg);
1366 return 0;
1370 /* Reads the server configuration file. */
1372 void
1373 load_server_config(const char *filename, Buffer *conf)
1375 char line[1024], *cp;
1376 FILE *f;
1378 debug2("%s: filename %s", __func__, filename);
1379 if ((f = fopen(filename, "r")) == NULL) {
1380 perror(filename);
1381 exit(1);
1383 buffer_clear(conf);
1384 while (fgets(line, sizeof(line), f)) {
1386 * Trim out comments and strip whitespace
1387 * NB - preserve newlines, they are needed to reproduce
1388 * line numbers later for error messages
1390 if ((cp = strchr(line, '#')) != NULL)
1391 memcpy(cp, "\n", 2);
1392 cp = line + strspn(line, " \t\r");
1394 buffer_append(conf, cp, strlen(cp));
1396 buffer_append(conf, "\0", 1);
1397 fclose(f);
1398 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1401 void
1402 parse_server_match_config(ServerOptions *options, const char *user,
1403 const char *host, const char *address)
1405 ServerOptions mo;
1407 initialize_server_options(&mo);
1408 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1409 copy_set_server_options(options, &mo, 0);
1414 /* Helper macros */
1415 #define M_CP_INTOPT(n) do {\
1416 if (src->n != -1) \
1417 dst->n = src->n; \
1418 } while (0)
1419 #define M_CP_STROPT(n) do {\
1420 if (src->n != NULL) { \
1421 if (dst->n != NULL) \
1422 xfree(dst->n); \
1423 dst->n = src->n; \
1425 } while(0)
1428 * Copy any supported values that are set.
1430 * If the preauth flag is set, we do not bother copying the the string or
1431 * array values that are not used pre-authentication, because any that we
1432 * do use must be explictly sent in mm_getpwnamallow().
1434 void
1435 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1437 M_CP_INTOPT(password_authentication);
1438 M_CP_INTOPT(gss_authentication);
1439 M_CP_INTOPT(rsa_authentication);
1440 M_CP_INTOPT(pubkey_authentication);
1441 M_CP_INTOPT(hostbased_authentication);
1442 M_CP_INTOPT(kbd_interactive_authentication);
1443 M_CP_INTOPT(permit_root_login);
1444 M_CP_INTOPT(permit_empty_passwd);
1445 M_CP_INTOPT(allow_tcp_forwarding);
1446 M_CP_INTOPT(gateway_ports);
1447 M_CP_INTOPT(x11_display_offset);
1448 M_CP_INTOPT(x11_forwarding);
1449 M_CP_INTOPT(x11_use_localhost);
1450 M_CP_INTOPT(max_auth_tries);
1451 M_CP_STROPT(banner);
1453 if (preauth)
1454 return;
1455 M_CP_STROPT(chroot_directory);
1458 #undef M_CP_INTOPT
1459 #undef M_CP_STROPT
1461 void
1462 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1463 const char *user, const char *host, const char *address)
1465 int active, linenum, bad_options = 0;
1466 char *cp, *obuf, *cbuf;
1468 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1470 obuf = cbuf = xstrdup(buffer_ptr(conf));
1471 active = user ? 0 : 1;
1472 linenum = 1;
1473 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1474 if (process_server_config_line(options, cp, filename,
1475 linenum++, &active, user, host, address) != 0)
1476 bad_options++;
1478 xfree(obuf);
1479 if (bad_options > 0)
1480 fatal("%s: terminating, %d bad configuration options",
1481 filename, bad_options);
1486 * Note that "none" is a special path having the same affect on sshd
1487 * configuration as not specifying ChrootDirectory at all.
1490 chroot_requested(char *chroot_directory)
1492 return (chroot_directory != NULL &&
1493 strcasecmp(chroot_directory, "none") != 0);