drm: Add atomic_cmpxchg()
[dragonfly.git] / crypto / openssh / servconf.c
blob1f6abb690b1b6c807a3848d7680f31b2b7550df4
2 /* $OpenBSD: servconf.c,v 1.251 2014/07/15 15:54:14 millert Exp $ */
3 /*
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
7 * As far as I am concerned, the code I have written for this software
8 * can be used freely for any purpose. Any derived versions of this
9 * software must be clearly marked as such, and if the derived work is
10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell".
14 #include "includes.h"
16 #include <sys/types.h>
17 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <netinet/in_systm.h>
21 #include <netinet/ip.h>
23 #include <ctype.h>
24 #include <netdb.h>
25 #include <pwd.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <signal.h>
30 #include <unistd.h>
31 #include <stdarg.h>
32 #include <errno.h>
33 #ifdef HAVE_UTIL_H
34 #include <util.h>
35 #endif
37 #include "openbsd-compat/sys-queue.h"
38 #include "xmalloc.h"
39 #include "ssh.h"
40 #include "log.h"
41 #include "buffer.h"
42 #include "misc.h"
43 #include "servconf.h"
44 #include "compat.h"
45 #include "pathnames.h"
46 #include "cipher.h"
47 #include "key.h"
48 #include "kex.h"
49 #include "mac.h"
50 #include "match.h"
51 #include "channels.h"
52 #include "groupaccess.h"
53 #include "canohost.h"
54 #include "packet.h"
55 #include "hostfile.h"
56 #include "auth.h"
57 #include "version.h"
59 static void add_listen_addr(ServerOptions *, char *, int);
60 static void add_one_listen_addr(ServerOptions *, char *, int);
62 /* Use of privilege separation or not */
63 extern int use_privsep;
64 extern Buffer cfg;
66 /* Initializes the server options to their default values. */
68 void
69 initialize_server_options(ServerOptions *options)
71 memset(options, 0, sizeof(*options));
73 /* Portable-specific options */
74 options->use_pam = -1;
76 /* Standard Options */
77 options->num_ports = 0;
78 options->ports_from_cmdline = 0;
79 options->listen_addrs = NULL;
80 options->address_family = -1;
81 options->num_host_key_files = 0;
82 options->num_host_cert_files = 0;
83 options->host_key_agent = NULL;
84 options->pid_file = NULL;
85 options->server_key_bits = -1;
86 options->login_grace_time = -1;
87 options->key_regeneration_time = -1;
88 options->permit_root_login = PERMIT_NOT_SET;
89 options->ignore_rhosts = -1;
90 options->ignore_user_known_hosts = -1;
91 options->print_motd = -1;
92 options->print_lastlog = -1;
93 options->x11_forwarding = -1;
94 options->x11_display_offset = -1;
95 options->x11_use_localhost = -1;
96 options->permit_tty = -1;
97 options->permit_user_rc = -1;
98 options->xauth_location = NULL;
99 options->strict_modes = -1;
100 options->tcp_keep_alive = -1;
101 options->log_facility = SYSLOG_FACILITY_NOT_SET;
102 options->log_level = SYSLOG_LEVEL_NOT_SET;
103 options->rhosts_rsa_authentication = -1;
104 options->hostbased_authentication = -1;
105 options->hostbased_uses_name_from_packet_only = -1;
106 options->rsa_authentication = -1;
107 options->pubkey_authentication = -1;
108 options->kerberos_authentication = -1;
109 options->kerberos_or_local_passwd = -1;
110 options->kerberos_ticket_cleanup = -1;
111 options->kerberos_get_afs_token = -1;
112 options->gss_authentication=-1;
113 options->gss_cleanup_creds = -1;
114 options->password_authentication = -1;
115 options->kbd_interactive_authentication = -1;
116 options->challenge_response_authentication = -1;
117 options->permit_blacklisted_keys = -1;
118 options->permit_empty_passwd = -1;
119 options->permit_user_env = -1;
120 options->use_login = -1;
121 options->compression = -1;
122 options->rekey_limit = -1;
123 options->rekey_interval = -1;
124 options->allow_tcp_forwarding = -1;
125 options->allow_streamlocal_forwarding = -1;
126 options->allow_agent_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->kex_algorithms = NULL;
134 options->protocol = SSH_PROTO_UNKNOWN;
135 options->fwd_opts.gateway_ports = -1;
136 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
137 options->fwd_opts.streamlocal_bind_unlink = -1;
138 options->num_subsystems = 0;
139 options->max_startups_begin = -1;
140 options->max_startups_rate = -1;
141 options->max_startups = -1;
142 options->max_authtries = -1;
143 options->max_sessions = -1;
144 options->banner = NULL;
145 options->use_dns = -1;
146 options->client_alive_interval = -1;
147 options->client_alive_count_max = -1;
148 options->num_authkeys_files = 0;
149 options->num_accept_env = 0;
150 options->permit_tun = -1;
151 options->num_permitted_opens = -1;
152 options->adm_forced_command = NULL;
153 options->chroot_directory = NULL;
154 options->authorized_keys_command = NULL;
155 options->authorized_keys_command_user = NULL;
156 options->revoked_keys_file = NULL;
157 options->trusted_user_ca_keys = NULL;
158 options->authorized_principals_file = NULL;
159 options->none_enabled = -1;
160 options->tcp_rcv_buf_poll = -1;
161 options->hpn_disabled = -1;
162 options->hpn_buffer_size = -1;
163 options->ip_qos_interactive = -1;
164 options->ip_qos_bulk = -1;
165 options->version_addendum = NULL;
168 void
169 fill_default_server_options(ServerOptions *options)
171 /* needed for hpn socket tests */
172 int sock;
173 int socksize;
174 int socksizelen = sizeof(int);
176 /* Portable-specific options */
177 if (options->use_pam == -1)
178 options->use_pam = 0;
180 /* Standard Options */
181 if (options->protocol == SSH_PROTO_UNKNOWN)
182 options->protocol = SSH_PROTO_2;
183 if (options->num_host_key_files == 0) {
184 /* fill default hostkeys for protocols */
185 if (options->protocol & SSH_PROTO_1)
186 options->host_key_files[options->num_host_key_files++] =
187 _PATH_HOST_KEY_FILE;
188 if (options->protocol & SSH_PROTO_2) {
189 options->host_key_files[options->num_host_key_files++] =
190 _PATH_HOST_RSA_KEY_FILE;
191 options->host_key_files[options->num_host_key_files++] =
192 _PATH_HOST_DSA_KEY_FILE;
193 #ifdef OPENSSL_HAS_ECC
194 options->host_key_files[options->num_host_key_files++] =
195 _PATH_HOST_ECDSA_KEY_FILE;
196 #endif
197 options->host_key_files[options->num_host_key_files++] =
198 _PATH_HOST_ED25519_KEY_FILE;
201 /* No certificates by default */
202 if (options->num_ports == 0)
203 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
204 if (options->listen_addrs == NULL)
205 add_listen_addr(options, NULL, 0);
206 if (options->pid_file == NULL)
207 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
208 if (options->server_key_bits == -1)
209 options->server_key_bits = 1024;
210 if (options->login_grace_time == -1)
211 options->login_grace_time = 120;
212 if (options->key_regeneration_time == -1)
213 options->key_regeneration_time = 3600;
214 if (options->permit_root_login == PERMIT_NOT_SET)
215 options->permit_root_login = PERMIT_NO;
216 if (options->ignore_rhosts == -1)
217 options->ignore_rhosts = 1;
218 if (options->ignore_user_known_hosts == -1)
219 options->ignore_user_known_hosts = 0;
220 if (options->print_motd == -1)
221 options->print_motd = 1;
222 if (options->print_lastlog == -1)
223 options->print_lastlog = 1;
224 if (options->x11_forwarding == -1)
225 options->x11_forwarding = 1;
226 if (options->x11_display_offset == -1)
227 options->x11_display_offset = 10;
228 if (options->x11_use_localhost == -1)
229 options->x11_use_localhost = 1;
230 if (options->xauth_location == NULL)
231 options->xauth_location = _PATH_XAUTH;
232 if (options->permit_tty == -1)
233 options->permit_tty = 1;
234 if (options->permit_user_rc == -1)
235 options->permit_user_rc = 1;
236 if (options->strict_modes == -1)
237 options->strict_modes = 1;
238 if (options->tcp_keep_alive == -1)
239 options->tcp_keep_alive = 1;
240 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
241 options->log_facility = SYSLOG_FACILITY_AUTH;
242 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
243 options->log_level = SYSLOG_LEVEL_INFO;
244 if (options->rhosts_rsa_authentication == -1)
245 options->rhosts_rsa_authentication = 0;
246 if (options->hostbased_authentication == -1)
247 options->hostbased_authentication = 0;
248 if (options->hostbased_uses_name_from_packet_only == -1)
249 options->hostbased_uses_name_from_packet_only = 0;
250 if (options->rsa_authentication == -1)
251 options->rsa_authentication = 1;
252 if (options->pubkey_authentication == -1)
253 options->pubkey_authentication = 1;
254 if (options->kerberos_authentication == -1)
255 options->kerberos_authentication = 0;
256 if (options->kerberos_or_local_passwd == -1)
257 options->kerberos_or_local_passwd = 1;
258 if (options->kerberos_ticket_cleanup == -1)
259 options->kerberos_ticket_cleanup = 1;
260 if (options->kerberos_get_afs_token == -1)
261 options->kerberos_get_afs_token = 0;
262 if (options->gss_authentication == -1)
263 options->gss_authentication = 0;
264 if (options->gss_cleanup_creds == -1)
265 options->gss_cleanup_creds = 1;
266 if (options->password_authentication == -1)
267 options->password_authentication = 1;
268 if (options->kbd_interactive_authentication == -1)
269 options->kbd_interactive_authentication = 0;
270 if (options->challenge_response_authentication == -1)
271 options->challenge_response_authentication = 1;
272 if (options->permit_blacklisted_keys == -1)
273 options->permit_blacklisted_keys = 0;
274 if (options->permit_empty_passwd == -1)
275 options->permit_empty_passwd = 0;
276 if (options->permit_user_env == -1)
277 options->permit_user_env = 0;
278 if (options->use_login == -1)
279 options->use_login = 0;
280 if (options->compression == -1)
281 options->compression = COMP_DELAYED;
282 if (options->rekey_limit == -1)
283 options->rekey_limit = 0;
284 if (options->rekey_interval == -1)
285 options->rekey_interval = 0;
286 if (options->allow_tcp_forwarding == -1)
287 options->allow_tcp_forwarding = FORWARD_ALLOW;
288 if (options->allow_streamlocal_forwarding == -1)
289 options->allow_streamlocal_forwarding = FORWARD_ALLOW;
290 if (options->allow_agent_forwarding == -1)
291 options->allow_agent_forwarding = 1;
292 if (options->fwd_opts.gateway_ports == -1)
293 options->fwd_opts.gateway_ports = 0;
294 if (options->max_startups == -1)
295 options->max_startups = 100;
296 if (options->max_startups_rate == -1)
297 options->max_startups_rate = 30; /* 30% */
298 if (options->max_startups_begin == -1)
299 options->max_startups_begin = 10;
300 if (options->max_authtries == -1)
301 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
302 if (options->max_sessions == -1)
303 options->max_sessions = DEFAULT_SESSIONS_MAX;
304 if (options->use_dns == -1)
305 options->use_dns = 1;
306 if (options->client_alive_interval == -1)
307 options->client_alive_interval = 0;
308 if (options->client_alive_count_max == -1)
309 options->client_alive_count_max = 3;
310 if (options->num_authkeys_files == 0) {
311 options->authorized_keys_files[options->num_authkeys_files++] =
312 xstrdup(_PATH_SSH_USER_PERMITTED_KEYS);
313 options->authorized_keys_files[options->num_authkeys_files++] =
314 xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2);
316 if (options->permit_tun == -1)
317 options->permit_tun = SSH_TUNMODE_NO;
318 if (options->none_enabled == -1)
319 options->none_enabled = 0;
320 if (options->hpn_disabled == -1)
321 options->hpn_disabled = 0;
323 if (options->hpn_buffer_size == -1) {
324 /* option not explicitly set. Now we have to figure out */
325 /* what value to use */
326 if (options->hpn_disabled == 1) {
327 options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
328 } else {
329 /* get the current RCV size and set it to that */
330 /*create a socket but don't connect it */
331 /* we use that the get the rcv socket size */
332 sock = socket(AF_INET, SOCK_STREAM, 0);
333 getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
334 &socksize, &socksizelen);
335 close(sock);
336 options->hpn_buffer_size = socksize;
337 debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
340 } else {
341 /* we have to do this incase the user sets both values in a contradictory */
342 /* manner. hpn_disabled overrrides hpn_buffer_size*/
343 if (options->hpn_disabled <= 0) {
344 if (options->hpn_buffer_size == 0)
345 options->hpn_buffer_size = 1;
346 /* limit the maximum buffer to 64MB */
347 if (options->hpn_buffer_size > 64*1024) {
348 options->hpn_buffer_size = 64*1024*1024;
349 } else {
350 options->hpn_buffer_size *= 1024;
352 } else
353 options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
356 if (options->ip_qos_interactive == -1)
357 options->ip_qos_interactive = IPTOS_LOWDELAY;
358 if (options->ip_qos_bulk == -1)
359 options->ip_qos_bulk = IPTOS_THROUGHPUT;
360 if (options->version_addendum == NULL)
361 options->version_addendum = xstrdup(SSH_VERSION_DRAGONFLY);
362 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
363 options->fwd_opts.streamlocal_bind_mask = 0177;
364 if (options->fwd_opts.streamlocal_bind_unlink == -1)
365 options->fwd_opts.streamlocal_bind_unlink = 0;
366 /* Turn privilege separation on by default */
367 if (use_privsep == -1)
368 use_privsep = PRIVSEP_NOSANDBOX;
370 #ifndef HAVE_MMAP
371 if (use_privsep && options->compression == 1) {
372 error("This platform does not support both privilege "
373 "separation and compression");
374 error("Compression disabled");
375 options->compression = 0;
377 #endif
381 /* Keyword tokens. */
382 typedef enum {
383 sBadOption, /* == unknown option */
384 /* Portable-specific options */
385 sUsePAM,
386 /* Standard Options */
387 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
388 sPermitRootLogin, sLogFacility, sLogLevel,
389 sRhostsRSAAuthentication, sRSAAuthentication,
390 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
391 sKerberosGetAFSToken,
392 sKerberosTgtPassing, sChallengeResponseAuthentication,
393 sPasswordAuthentication, sKbdInteractiveAuthentication,
394 sListenAddress, sAddressFamily,
395 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
396 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
397 sPermitTTY, sStrictModes, sPermitBlacklistedKeys, sEmptyPasswd, sTCPKeepAlive,
398 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
399 sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
400 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
401 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
402 sMaxStartups, sMaxAuthTries, sMaxSessions,
403 sBanner, sUseDNS, sHostbasedAuthentication,
404 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
405 sClientAliveCountMax, sAuthorizedKeysFile,
406 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
407 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
408 sUsePrivilegeSeparation, sAllowAgentForwarding,
409 sHostCertificate,
410 sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
411 sKexAlgorithms, sIPQoS, sVersionAddendum,
412 sNoneEnabled, sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize,
413 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
414 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
415 sStreamLocalBindMask, sStreamLocalBindUnlink,
416 sAllowStreamLocalForwarding,
417 sDeprecated, sUnsupported
418 } ServerOpCodes;
420 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
421 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
422 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
424 /* Textual representation of the tokens. */
425 static struct {
426 const char *name;
427 ServerOpCodes opcode;
428 u_int flags;
429 } keywords[] = {
430 /* Portable-specific options */
431 #ifdef USE_PAM
432 { "usepam", sUsePAM, SSHCFG_GLOBAL },
433 #else
434 { "usepam", sUnsupported, SSHCFG_GLOBAL },
435 #endif
436 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
437 /* Standard Options */
438 { "port", sPort, SSHCFG_GLOBAL },
439 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
440 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
441 { "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
442 { "pidfile", sPidFile, SSHCFG_GLOBAL },
443 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
444 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
445 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
446 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
447 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
448 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
449 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
450 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
451 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
452 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
453 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
454 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
455 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
456 #ifdef KRB5
457 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
458 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
459 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
460 #ifdef USE_AFS
461 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
462 #else
463 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
464 #endif
465 #else
466 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
467 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
468 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
469 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
470 #endif
471 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
472 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
473 #ifdef GSSAPI
474 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
475 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
476 #else
477 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
478 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
479 #endif
480 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
481 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
482 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
483 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
484 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
485 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
486 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
487 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
488 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
489 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
490 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
491 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
492 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
493 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
494 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
495 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
496 { "permitblacklistedkeys", sPermitBlacklistedKeys, SSHCFG_GLOBAL },
497 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
498 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
499 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
500 { "compression", sCompression, SSHCFG_GLOBAL },
501 { "rekeylimit", sRekeyLimit, SSHCFG_ALL },
502 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
503 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
504 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
505 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
506 { "allowusers", sAllowUsers, SSHCFG_ALL },
507 { "denyusers", sDenyUsers, SSHCFG_ALL },
508 { "allowgroups", sAllowGroups, SSHCFG_ALL },
509 { "denygroups", sDenyGroups, SSHCFG_ALL },
510 { "ciphers", sCiphers, SSHCFG_GLOBAL },
511 { "macs", sMacs, SSHCFG_GLOBAL },
512 { "protocol", sProtocol, SSHCFG_GLOBAL },
513 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
514 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
515 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
516 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
517 { "maxsessions", sMaxSessions, SSHCFG_ALL },
518 { "banner", sBanner, SSHCFG_ALL },
519 { "usedns", sUseDNS, SSHCFG_GLOBAL },
520 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
521 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
522 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
523 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
524 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
525 { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
526 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
527 { "acceptenv", sAcceptEnv, SSHCFG_ALL },
528 { "permittunnel", sPermitTunnel, SSHCFG_ALL },
529 { "permittty", sPermitTTY, SSHCFG_ALL },
530 { "permituserrc", sPermitUserRC, SSHCFG_ALL },
531 { "match", sMatch, SSHCFG_ALL },
532 { "permitopen", sPermitOpen, SSHCFG_ALL },
533 { "forcecommand", sForceCommand, SSHCFG_ALL },
534 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
535 { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
536 { "revokedkeys", sRevokedKeys, SSHCFG_ALL },
537 { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
538 { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
539 { "noneenabled", sNoneEnabled, SSHCFG_ALL },
540 { "hpndisabled", sHPNDisabled, SSHCFG_ALL },
541 { "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL },
542 { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL },
543 { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
544 { "ipqos", sIPQoS, SSHCFG_ALL },
545 { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
546 { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
547 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
548 { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
549 { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
550 { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
551 { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
552 { NULL, sBadOption, 0 }
555 static struct {
556 int val;
557 char *text;
558 } tunmode_desc[] = {
559 { SSH_TUNMODE_NO, "no" },
560 { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
561 { SSH_TUNMODE_ETHERNET, "ethernet" },
562 { SSH_TUNMODE_YES, "yes" },
563 { -1, NULL }
567 * Returns the number of the token pointed to by cp or sBadOption.
570 static ServerOpCodes
571 parse_token(const char *cp, const char *filename,
572 int linenum, u_int *flags)
574 u_int i;
576 for (i = 0; keywords[i].name; i++)
577 if (strcasecmp(cp, keywords[i].name) == 0) {
578 debug ("Config token is %s", keywords[i].name);
579 *flags = keywords[i].flags;
580 return keywords[i].opcode;
583 error("%s: line %d: Bad configuration option: %s",
584 filename, linenum, cp);
585 return sBadOption;
588 char *
589 derelativise_path(const char *path)
591 char *expanded, *ret, cwd[MAXPATHLEN];
593 expanded = tilde_expand_filename(path, getuid());
594 if (*expanded == '/')
595 return expanded;
596 if (getcwd(cwd, sizeof(cwd)) == NULL)
597 fatal("%s: getcwd: %s", __func__, strerror(errno));
598 xasprintf(&ret, "%s/%s", cwd, expanded);
599 free(expanded);
600 return ret;
603 static void
604 add_listen_addr(ServerOptions *options, char *addr, int port)
606 u_int i;
608 if (options->num_ports == 0)
609 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
610 if (options->address_family == -1)
611 options->address_family = AF_UNSPEC;
612 if (port == 0)
613 for (i = 0; i < options->num_ports; i++)
614 add_one_listen_addr(options, addr, options->ports[i]);
615 else
616 add_one_listen_addr(options, addr, port);
619 static void
620 add_one_listen_addr(ServerOptions *options, char *addr, int port)
622 struct addrinfo hints, *ai, *aitop;
623 char strport[NI_MAXSERV];
624 int gaierr;
626 memset(&hints, 0, sizeof(hints));
627 hints.ai_family = options->address_family;
628 hints.ai_socktype = SOCK_STREAM;
629 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
630 snprintf(strport, sizeof strport, "%d", port);
631 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
632 fatal("bad addr or host: %s (%s)",
633 addr ? addr : "<NULL>",
634 ssh_gai_strerror(gaierr));
635 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
637 ai->ai_next = options->listen_addrs;
638 options->listen_addrs = aitop;
641 struct connection_info *
642 get_connection_info(int populate, int use_dns)
644 static struct connection_info ci;
646 if (!populate)
647 return &ci;
648 ci.host = get_canonical_hostname(use_dns);
649 ci.address = get_remote_ipaddr();
650 ci.laddress = get_local_ipaddr(packet_get_connection_in());
651 ci.lport = get_local_port();
652 return &ci;
656 * The strategy for the Match blocks is that the config file is parsed twice.
658 * The first time is at startup. activep is initialized to 1 and the
659 * directives in the global context are processed and acted on. Hitting a
660 * Match directive unsets activep and the directives inside the block are
661 * checked for syntax only.
663 * The second time is after a connection has been established but before
664 * authentication. activep is initialized to 2 and global config directives
665 * are ignored since they have already been processed. If the criteria in a
666 * Match block is met, activep is set and the subsequent directives
667 * processed and actioned until EOF or another Match block unsets it. Any
668 * options set are copied into the main server config.
670 * Potential additions/improvements:
671 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
673 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
674 * Match Address 192.168.0.*
675 * Tag trusted
676 * Match Group wheel
677 * Tag trusted
678 * Match Tag trusted
679 * AllowTcpForwarding yes
680 * GatewayPorts clientspecified
681 * [...]
683 * - Add a PermittedChannelRequests directive
684 * Match Group shell
685 * PermittedChannelRequests session,forwarded-tcpip
688 static int
689 match_cfg_line_group(const char *grps, int line, const char *user)
691 int result = 0;
692 struct passwd *pw;
694 if (user == NULL)
695 goto out;
697 if ((pw = getpwnam(user)) == NULL) {
698 debug("Can't match group at line %d because user %.100s does "
699 "not exist", line, user);
700 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
701 debug("Can't Match group because user %.100s not in any group "
702 "at line %d", user, line);
703 } else if (ga_match_pattern_list(grps) != 1) {
704 debug("user %.100s does not match group list %.100s at line %d",
705 user, grps, line);
706 } else {
707 debug("user %.100s matched group list %.100s at line %d", user,
708 grps, line);
709 result = 1;
711 out:
712 ga_free();
713 return result;
717 * All of the attributes on a single Match line are ANDed together, so we need
718 * to check every attribute and set the result to zero if any attribute does
719 * not match.
721 static int
722 match_cfg_line(char **condition, int line, struct connection_info *ci)
724 int result = 1, attributes = 0, port;
725 char *arg, *attrib, *cp = *condition;
726 size_t len;
728 if (ci == NULL)
729 debug3("checking syntax for 'Match %s'", cp);
730 else
731 debug3("checking match for '%s' user %s host %s addr %s "
732 "laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
733 ci->host ? ci->host : "(null)",
734 ci->address ? ci->address : "(null)",
735 ci->laddress ? ci->laddress : "(null)", ci->lport);
737 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
738 attributes++;
739 if (strcasecmp(attrib, "all") == 0) {
740 if (attributes != 1 ||
741 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
742 error("'all' cannot be combined with other "
743 "Match attributes");
744 return -1;
746 *condition = cp;
747 return 1;
749 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
750 error("Missing Match criteria for %s", attrib);
751 return -1;
753 len = strlen(arg);
754 if (strcasecmp(attrib, "user") == 0) {
755 if (ci == NULL || ci->user == NULL) {
756 result = 0;
757 continue;
759 if (match_pattern_list(ci->user, arg, len, 0) != 1)
760 result = 0;
761 else
762 debug("user %.100s matched 'User %.100s' at "
763 "line %d", ci->user, arg, line);
764 } else if (strcasecmp(attrib, "group") == 0) {
765 if (ci == NULL || ci->user == NULL) {
766 result = 0;
767 continue;
769 switch (match_cfg_line_group(arg, line, ci->user)) {
770 case -1:
771 return -1;
772 case 0:
773 result = 0;
775 } else if (strcasecmp(attrib, "host") == 0) {
776 if (ci == NULL || ci->host == NULL) {
777 result = 0;
778 continue;
780 if (match_hostname(ci->host, arg, len) != 1)
781 result = 0;
782 else
783 debug("connection from %.100s matched 'Host "
784 "%.100s' at line %d", ci->host, arg, line);
785 } else if (strcasecmp(attrib, "address") == 0) {
786 if (ci == NULL || ci->address == NULL) {
787 result = 0;
788 continue;
790 switch (addr_match_list(ci->address, arg)) {
791 case 1:
792 debug("connection from %.100s matched 'Address "
793 "%.100s' at line %d", ci->address, arg, line);
794 break;
795 case 0:
796 case -1:
797 result = 0;
798 break;
799 case -2:
800 return -1;
802 } else if (strcasecmp(attrib, "localaddress") == 0){
803 if (ci == NULL || ci->laddress == NULL) {
804 result = 0;
805 continue;
807 switch (addr_match_list(ci->laddress, arg)) {
808 case 1:
809 debug("connection from %.100s matched "
810 "'LocalAddress %.100s' at line %d",
811 ci->laddress, arg, line);
812 break;
813 case 0:
814 case -1:
815 result = 0;
816 break;
817 case -2:
818 return -1;
820 } else if (strcasecmp(attrib, "localport") == 0) {
821 if ((port = a2port(arg)) == -1) {
822 error("Invalid LocalPort '%s' on Match line",
823 arg);
824 return -1;
826 if (ci == NULL || ci->lport == 0) {
827 result = 0;
828 continue;
830 /* TODO support port lists */
831 if (port == ci->lport)
832 debug("connection from %.100s matched "
833 "'LocalPort %d' at line %d",
834 ci->laddress, port, line);
835 else
836 result = 0;
837 } else {
838 error("Unsupported Match attribute %s", attrib);
839 return -1;
842 if (attributes == 0) {
843 error("One or more attributes required for Match");
844 return -1;
846 if (ci != NULL)
847 debug3("match %sfound", result ? "" : "not ");
848 *condition = cp;
849 return result;
852 #define WHITESPACE " \t\r\n"
854 /* Multistate option parsing */
855 struct multistate {
856 char *key;
857 int value;
859 static const struct multistate multistate_addressfamily[] = {
860 { "inet", AF_INET },
861 { "inet6", AF_INET6 },
862 { "any", AF_UNSPEC },
863 { NULL, -1 }
865 static const struct multistate multistate_permitrootlogin[] = {
866 { "without-password", PERMIT_NO_PASSWD },
867 { "forced-commands-only", PERMIT_FORCED_ONLY },
868 { "yes", PERMIT_YES },
869 { "no", PERMIT_NO },
870 { NULL, -1 }
872 static const struct multistate multistate_compression[] = {
873 { "delayed", COMP_DELAYED },
874 { "yes", COMP_ZLIB },
875 { "no", COMP_NONE },
876 { NULL, -1 }
878 static const struct multistate multistate_gatewayports[] = {
879 { "clientspecified", 2 },
880 { "yes", 1 },
881 { "no", 0 },
882 { NULL, -1 }
884 static const struct multistate multistate_privsep[] = {
885 { "yes", PRIVSEP_NOSANDBOX },
886 { "sandbox", PRIVSEP_ON },
887 { "nosandbox", PRIVSEP_NOSANDBOX },
888 { "no", PRIVSEP_OFF },
889 { NULL, -1 }
891 static const struct multistate multistate_tcpfwd[] = {
892 { "yes", FORWARD_ALLOW },
893 { "all", FORWARD_ALLOW },
894 { "no", FORWARD_DENY },
895 { "remote", FORWARD_REMOTE },
896 { "local", FORWARD_LOCAL },
897 { NULL, -1 }
901 process_server_config_line(ServerOptions *options, char *line,
902 const char *filename, int linenum, int *activep,
903 struct connection_info *connectinfo)
905 char *cp, **charptr, *arg, *p;
906 int cmdline = 0, *intptr, value, value2, n, port;
907 SyslogFacility *log_facility_ptr;
908 LogLevel *log_level_ptr;
909 ServerOpCodes opcode;
910 u_int i, flags = 0;
911 size_t len;
912 long long val64;
913 const struct multistate *multistate_ptr;
915 cp = line;
916 if ((arg = strdelim(&cp)) == NULL)
917 return 0;
918 /* Ignore leading whitespace */
919 if (*arg == '\0')
920 arg = strdelim(&cp);
921 if (!arg || !*arg || *arg == '#')
922 return 0;
923 intptr = NULL;
924 charptr = NULL;
925 opcode = parse_token(arg, filename, linenum, &flags);
927 if (activep == NULL) { /* We are processing a command line directive */
928 cmdline = 1;
929 activep = &cmdline;
931 if (*activep && opcode != sMatch)
932 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
933 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
934 if (connectinfo == NULL) {
935 fatal("%s line %d: Directive '%s' is not allowed "
936 "within a Match block", filename, linenum, arg);
937 } else { /* this is a directive we have already processed */
938 while (arg)
939 arg = strdelim(&cp);
940 return 0;
944 switch (opcode) {
945 /* Portable-specific options */
946 case sUsePAM:
947 intptr = &options->use_pam;
948 goto parse_flag;
950 /* Standard Options */
951 case sBadOption:
952 return -1;
953 case sPort:
954 /* ignore ports from configfile if cmdline specifies ports */
955 if (options->ports_from_cmdline)
956 return 0;
957 if (options->listen_addrs != NULL)
958 fatal("%s line %d: ports must be specified before "
959 "ListenAddress.", filename, linenum);
960 if (options->num_ports >= MAX_PORTS)
961 fatal("%s line %d: too many ports.",
962 filename, linenum);
963 arg = strdelim(&cp);
964 if (!arg || *arg == '\0')
965 fatal("%s line %d: missing port number.",
966 filename, linenum);
967 options->ports[options->num_ports++] = a2port(arg);
968 if (options->ports[options->num_ports-1] <= 0)
969 fatal("%s line %d: Badly formatted port number.",
970 filename, linenum);
971 break;
973 case sServerKeyBits:
974 intptr = &options->server_key_bits;
975 parse_int:
976 arg = strdelim(&cp);
977 if (!arg || *arg == '\0')
978 fatal("%s line %d: missing integer value.",
979 filename, linenum);
980 value = atoi(arg);
981 if (*activep && *intptr == -1)
982 *intptr = value;
983 break;
985 case sLoginGraceTime:
986 intptr = &options->login_grace_time;
987 parse_time:
988 arg = strdelim(&cp);
989 if (!arg || *arg == '\0')
990 fatal("%s line %d: missing time value.",
991 filename, linenum);
992 if ((value = convtime(arg)) == -1)
993 fatal("%s line %d: invalid time value.",
994 filename, linenum);
995 if (*intptr == -1)
996 *intptr = value;
997 break;
999 case sKeyRegenerationTime:
1000 intptr = &options->key_regeneration_time;
1001 goto parse_time;
1003 case sListenAddress:
1004 arg = strdelim(&cp);
1005 if (arg == NULL || *arg == '\0')
1006 fatal("%s line %d: missing address",
1007 filename, linenum);
1008 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
1009 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1010 && strchr(p+1, ':') != NULL) {
1011 add_listen_addr(options, arg, 0);
1012 break;
1014 p = hpdelim(&arg);
1015 if (p == NULL)
1016 fatal("%s line %d: bad address:port usage",
1017 filename, linenum);
1018 p = cleanhostname(p);
1019 if (arg == NULL)
1020 port = 0;
1021 else if ((port = a2port(arg)) <= 0)
1022 fatal("%s line %d: bad port number", filename, linenum);
1024 add_listen_addr(options, p, port);
1026 break;
1028 case sAddressFamily:
1029 intptr = &options->address_family;
1030 multistate_ptr = multistate_addressfamily;
1031 if (options->listen_addrs != NULL)
1032 fatal("%s line %d: address family must be specified "
1033 "before ListenAddress.", filename, linenum);
1034 parse_multistate:
1035 arg = strdelim(&cp);
1036 if (!arg || *arg == '\0')
1037 fatal("%s line %d: missing argument.",
1038 filename, linenum);
1039 value = -1;
1040 for (i = 0; multistate_ptr[i].key != NULL; i++) {
1041 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1042 value = multistate_ptr[i].value;
1043 break;
1046 if (value == -1)
1047 fatal("%s line %d: unsupported option \"%s\".",
1048 filename, linenum, arg);
1049 if (*activep && *intptr == -1)
1050 *intptr = value;
1051 break;
1053 case sHostKeyFile:
1054 intptr = &options->num_host_key_files;
1055 if (*intptr >= MAX_HOSTKEYS)
1056 fatal("%s line %d: too many host keys specified (max %d).",
1057 filename, linenum, MAX_HOSTKEYS);
1058 charptr = &options->host_key_files[*intptr];
1059 parse_filename:
1060 arg = strdelim(&cp);
1061 if (!arg || *arg == '\0')
1062 fatal("%s line %d: missing file name.",
1063 filename, linenum);
1064 if (*activep && *charptr == NULL) {
1065 *charptr = derelativise_path(arg);
1066 /* increase optional counter */
1067 if (intptr != NULL)
1068 *intptr = *intptr + 1;
1070 break;
1072 case sHostKeyAgent:
1073 charptr = &options->host_key_agent;
1074 arg = strdelim(&cp);
1075 if (!arg || *arg == '\0')
1076 fatal("%s line %d: missing socket name.",
1077 filename, linenum);
1078 if (*activep && *charptr == NULL)
1079 *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
1080 xstrdup(arg) : derelativise_path(arg);
1081 break;
1083 case sHostCertificate:
1084 intptr = &options->num_host_cert_files;
1085 if (*intptr >= MAX_HOSTKEYS)
1086 fatal("%s line %d: too many host certificates "
1087 "specified (max %d).", filename, linenum,
1088 MAX_HOSTCERTS);
1089 charptr = &options->host_cert_files[*intptr];
1090 goto parse_filename;
1091 break;
1093 case sPidFile:
1094 charptr = &options->pid_file;
1095 goto parse_filename;
1097 case sPermitRootLogin:
1098 intptr = &options->permit_root_login;
1099 multistate_ptr = multistate_permitrootlogin;
1100 goto parse_multistate;
1102 case sIgnoreRhosts:
1103 intptr = &options->ignore_rhosts;
1104 parse_flag:
1105 arg = strdelim(&cp);
1106 if (!arg || *arg == '\0')
1107 fatal("%s line %d: missing yes/no argument.",
1108 filename, linenum);
1109 value = 0; /* silence compiler */
1110 if (strcmp(arg, "yes") == 0)
1111 value = 1;
1112 else if (strcmp(arg, "no") == 0)
1113 value = 0;
1114 else
1115 fatal("%s line %d: Bad yes/no argument: %s",
1116 filename, linenum, arg);
1117 if (*activep && *intptr == -1)
1118 *intptr = value;
1119 break;
1121 case sNoneEnabled:
1122 intptr = &options->none_enabled;
1123 goto parse_flag;
1125 case sTcpRcvBufPoll:
1126 intptr = &options->tcp_rcv_buf_poll;
1127 goto parse_flag;
1129 case sHPNDisabled:
1130 intptr = &options->hpn_disabled;
1131 goto parse_flag;
1133 case sHPNBufferSize:
1134 intptr = &options->hpn_buffer_size;
1135 goto parse_int;
1137 case sIgnoreUserKnownHosts:
1138 intptr = &options->ignore_user_known_hosts;
1139 goto parse_flag;
1141 case sRhostsRSAAuthentication:
1142 intptr = &options->rhosts_rsa_authentication;
1143 goto parse_flag;
1145 case sHostbasedAuthentication:
1146 intptr = &options->hostbased_authentication;
1147 goto parse_flag;
1149 case sHostbasedUsesNameFromPacketOnly:
1150 intptr = &options->hostbased_uses_name_from_packet_only;
1151 goto parse_flag;
1153 case sRSAAuthentication:
1154 intptr = &options->rsa_authentication;
1155 goto parse_flag;
1157 case sPubkeyAuthentication:
1158 intptr = &options->pubkey_authentication;
1159 goto parse_flag;
1161 case sKerberosAuthentication:
1162 intptr = &options->kerberos_authentication;
1163 goto parse_flag;
1165 case sKerberosOrLocalPasswd:
1166 intptr = &options->kerberos_or_local_passwd;
1167 goto parse_flag;
1169 case sKerberosTicketCleanup:
1170 intptr = &options->kerberos_ticket_cleanup;
1171 goto parse_flag;
1173 case sKerberosGetAFSToken:
1174 intptr = &options->kerberos_get_afs_token;
1175 goto parse_flag;
1177 case sGssAuthentication:
1178 intptr = &options->gss_authentication;
1179 goto parse_flag;
1181 case sGssCleanupCreds:
1182 intptr = &options->gss_cleanup_creds;
1183 goto parse_flag;
1185 case sPasswordAuthentication:
1186 intptr = &options->password_authentication;
1187 goto parse_flag;
1189 case sKbdInteractiveAuthentication:
1190 intptr = &options->kbd_interactive_authentication;
1191 goto parse_flag;
1193 case sChallengeResponseAuthentication:
1194 intptr = &options->challenge_response_authentication;
1195 goto parse_flag;
1197 case sPrintMotd:
1198 intptr = &options->print_motd;
1199 goto parse_flag;
1201 case sPrintLastLog:
1202 intptr = &options->print_lastlog;
1203 goto parse_flag;
1205 case sX11Forwarding:
1206 intptr = &options->x11_forwarding;
1207 goto parse_flag;
1209 case sX11DisplayOffset:
1210 intptr = &options->x11_display_offset;
1211 goto parse_int;
1213 case sX11UseLocalhost:
1214 intptr = &options->x11_use_localhost;
1215 goto parse_flag;
1217 case sXAuthLocation:
1218 charptr = &options->xauth_location;
1219 goto parse_filename;
1221 case sPermitTTY:
1222 intptr = &options->permit_tty;
1223 goto parse_flag;
1225 case sPermitUserRC:
1226 intptr = &options->permit_user_rc;
1227 goto parse_flag;
1229 case sStrictModes:
1230 intptr = &options->strict_modes;
1231 goto parse_flag;
1233 case sTCPKeepAlive:
1234 intptr = &options->tcp_keep_alive;
1235 goto parse_flag;
1237 case sPermitBlacklistedKeys:
1238 intptr = &options->permit_blacklisted_keys;
1239 goto parse_flag;
1241 case sEmptyPasswd:
1242 intptr = &options->permit_empty_passwd;
1243 goto parse_flag;
1245 case sPermitUserEnvironment:
1246 intptr = &options->permit_user_env;
1247 goto parse_flag;
1249 case sUseLogin:
1250 intptr = &options->use_login;
1251 goto parse_flag;
1253 case sCompression:
1254 intptr = &options->compression;
1255 multistate_ptr = multistate_compression;
1256 goto parse_multistate;
1258 case sRekeyLimit:
1259 arg = strdelim(&cp);
1260 if (!arg || *arg == '\0')
1261 fatal("%.200s line %d: Missing argument.", filename,
1262 linenum);
1263 if (strcmp(arg, "default") == 0) {
1264 val64 = 0;
1265 } else {
1266 if (scan_scaled(arg, &val64) == -1)
1267 fatal("%.200s line %d: Bad number '%s': %s",
1268 filename, linenum, arg, strerror(errno));
1269 /* check for too-large or too-small limits */
1270 if (val64 > UINT_MAX)
1271 fatal("%.200s line %d: RekeyLimit too large",
1272 filename, linenum);
1273 if (val64 != 0 && val64 < 16)
1274 fatal("%.200s line %d: RekeyLimit too small",
1275 filename, linenum);
1277 if (*activep && options->rekey_limit == -1)
1278 options->rekey_limit = (u_int32_t)val64;
1279 if (cp != NULL) { /* optional rekey interval present */
1280 if (strcmp(cp, "none") == 0) {
1281 (void)strdelim(&cp); /* discard */
1282 break;
1284 intptr = &options->rekey_interval;
1285 goto parse_time;
1287 break;
1289 case sGatewayPorts:
1290 intptr = &options->fwd_opts.gateway_ports;
1291 multistate_ptr = multistate_gatewayports;
1292 goto parse_multistate;
1294 case sUseDNS:
1295 intptr = &options->use_dns;
1296 goto parse_flag;
1298 case sLogFacility:
1299 log_facility_ptr = &options->log_facility;
1300 arg = strdelim(&cp);
1301 value = log_facility_number(arg);
1302 if (value == SYSLOG_FACILITY_NOT_SET)
1303 fatal("%.200s line %d: unsupported log facility '%s'",
1304 filename, linenum, arg ? arg : "<NONE>");
1305 if (*log_facility_ptr == -1)
1306 *log_facility_ptr = (SyslogFacility) value;
1307 break;
1309 case sLogLevel:
1310 log_level_ptr = &options->log_level;
1311 arg = strdelim(&cp);
1312 value = log_level_number(arg);
1313 if (value == SYSLOG_LEVEL_NOT_SET)
1314 fatal("%.200s line %d: unsupported log level '%s'",
1315 filename, linenum, arg ? arg : "<NONE>");
1316 if (*log_level_ptr == -1)
1317 *log_level_ptr = (LogLevel) value;
1318 break;
1320 case sAllowTcpForwarding:
1321 intptr = &options->allow_tcp_forwarding;
1322 multistate_ptr = multistate_tcpfwd;
1323 goto parse_multistate;
1325 case sAllowStreamLocalForwarding:
1326 intptr = &options->allow_streamlocal_forwarding;
1327 multistate_ptr = multistate_tcpfwd;
1328 goto parse_multistate;
1330 case sAllowAgentForwarding:
1331 intptr = &options->allow_agent_forwarding;
1332 goto parse_flag;
1334 case sUsePrivilegeSeparation:
1335 intptr = &use_privsep;
1336 multistate_ptr = multistate_privsep;
1337 goto parse_multistate;
1339 case sAllowUsers:
1340 while ((arg = strdelim(&cp)) && *arg != '\0') {
1341 if (options->num_allow_users >= MAX_ALLOW_USERS)
1342 fatal("%s line %d: too many allow users.",
1343 filename, linenum);
1344 if (!*activep)
1345 continue;
1346 options->allow_users[options->num_allow_users++] =
1347 xstrdup(arg);
1349 break;
1351 case sDenyUsers:
1352 while ((arg = strdelim(&cp)) && *arg != '\0') {
1353 if (options->num_deny_users >= MAX_DENY_USERS)
1354 fatal("%s line %d: too many deny users.",
1355 filename, linenum);
1356 if (!*activep)
1357 continue;
1358 options->deny_users[options->num_deny_users++] =
1359 xstrdup(arg);
1361 break;
1363 case sAllowGroups:
1364 while ((arg = strdelim(&cp)) && *arg != '\0') {
1365 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1366 fatal("%s line %d: too many allow groups.",
1367 filename, linenum);
1368 if (!*activep)
1369 continue;
1370 options->allow_groups[options->num_allow_groups++] =
1371 xstrdup(arg);
1373 break;
1375 case sDenyGroups:
1376 while ((arg = strdelim(&cp)) && *arg != '\0') {
1377 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1378 fatal("%s line %d: too many deny groups.",
1379 filename, linenum);
1380 if (!*activep)
1381 continue;
1382 options->deny_groups[options->num_deny_groups++] =
1383 xstrdup(arg);
1385 break;
1387 case sCiphers:
1388 arg = strdelim(&cp);
1389 if (!arg || *arg == '\0')
1390 fatal("%s line %d: Missing argument.", filename, linenum);
1391 if (!ciphers_valid(arg))
1392 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1393 filename, linenum, arg ? arg : "<NONE>");
1394 if (options->ciphers == NULL)
1395 options->ciphers = xstrdup(arg);
1396 break;
1398 case sMacs:
1399 arg = strdelim(&cp);
1400 if (!arg || *arg == '\0')
1401 fatal("%s line %d: Missing argument.", filename, linenum);
1402 if (!mac_valid(arg))
1403 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1404 filename, linenum, arg ? arg : "<NONE>");
1405 if (options->macs == NULL)
1406 options->macs = xstrdup(arg);
1407 break;
1409 case sKexAlgorithms:
1410 arg = strdelim(&cp);
1411 if (!arg || *arg == '\0')
1412 fatal("%s line %d: Missing argument.",
1413 filename, linenum);
1414 if (!kex_names_valid(arg))
1415 fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1416 filename, linenum, arg ? arg : "<NONE>");
1417 if (options->kex_algorithms == NULL)
1418 options->kex_algorithms = xstrdup(arg);
1419 break;
1421 case sProtocol:
1422 intptr = &options->protocol;
1423 arg = strdelim(&cp);
1424 if (!arg || *arg == '\0')
1425 fatal("%s line %d: Missing argument.", filename, linenum);
1426 value = proto_spec(arg);
1427 if (value == SSH_PROTO_UNKNOWN)
1428 fatal("%s line %d: Bad protocol spec '%s'.",
1429 filename, linenum, arg ? arg : "<NONE>");
1430 if (*intptr == SSH_PROTO_UNKNOWN)
1431 *intptr = value;
1432 break;
1434 case sSubsystem:
1435 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1436 fatal("%s line %d: too many subsystems defined.",
1437 filename, linenum);
1439 arg = strdelim(&cp);
1440 if (!arg || *arg == '\0')
1441 fatal("%s line %d: Missing subsystem name.",
1442 filename, linenum);
1443 if (!*activep) {
1444 arg = strdelim(&cp);
1445 break;
1447 for (i = 0; i < options->num_subsystems; i++)
1448 if (strcmp(arg, options->subsystem_name[i]) == 0)
1449 fatal("%s line %d: Subsystem '%s' already defined.",
1450 filename, linenum, arg);
1451 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1452 arg = strdelim(&cp);
1453 if (!arg || *arg == '\0')
1454 fatal("%s line %d: Missing subsystem command.",
1455 filename, linenum);
1456 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1458 /* Collect arguments (separate to executable) */
1459 p = xstrdup(arg);
1460 len = strlen(p) + 1;
1461 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1462 len += 1 + strlen(arg);
1463 p = xrealloc(p, 1, len);
1464 strlcat(p, " ", len);
1465 strlcat(p, arg, len);
1467 options->subsystem_args[options->num_subsystems] = p;
1468 options->num_subsystems++;
1469 break;
1471 case sMaxStartups:
1472 arg = strdelim(&cp);
1473 if (!arg || *arg == '\0')
1474 fatal("%s line %d: Missing MaxStartups spec.",
1475 filename, linenum);
1476 if ((n = sscanf(arg, "%d:%d:%d",
1477 &options->max_startups_begin,
1478 &options->max_startups_rate,
1479 &options->max_startups)) == 3) {
1480 if (options->max_startups_begin >
1481 options->max_startups ||
1482 options->max_startups_rate > 100 ||
1483 options->max_startups_rate < 1)
1484 fatal("%s line %d: Illegal MaxStartups spec.",
1485 filename, linenum);
1486 } else if (n != 1)
1487 fatal("%s line %d: Illegal MaxStartups spec.",
1488 filename, linenum);
1489 else
1490 options->max_startups = options->max_startups_begin;
1491 break;
1493 case sMaxAuthTries:
1494 intptr = &options->max_authtries;
1495 goto parse_int;
1497 case sMaxSessions:
1498 intptr = &options->max_sessions;
1499 goto parse_int;
1501 case sBanner:
1502 charptr = &options->banner;
1503 goto parse_filename;
1506 * These options can contain %X options expanded at
1507 * connect time, so that you can specify paths like:
1509 * AuthorizedKeysFile /etc/ssh_keys/%u
1511 case sAuthorizedKeysFile:
1512 if (*activep && options->num_authkeys_files == 0) {
1513 while ((arg = strdelim(&cp)) && *arg != '\0') {
1514 if (options->num_authkeys_files >=
1515 MAX_AUTHKEYS_FILES)
1516 fatal("%s line %d: "
1517 "too many authorized keys files.",
1518 filename, linenum);
1519 options->authorized_keys_files[
1520 options->num_authkeys_files++] =
1521 tilde_expand_filename(arg, getuid());
1524 return 0;
1526 case sAuthorizedPrincipalsFile:
1527 charptr = &options->authorized_principals_file;
1528 arg = strdelim(&cp);
1529 if (!arg || *arg == '\0')
1530 fatal("%s line %d: missing file name.",
1531 filename, linenum);
1532 if (*activep && *charptr == NULL) {
1533 *charptr = tilde_expand_filename(arg, getuid());
1534 /* increase optional counter */
1535 if (intptr != NULL)
1536 *intptr = *intptr + 1;
1538 break;
1540 case sClientAliveInterval:
1541 intptr = &options->client_alive_interval;
1542 goto parse_time;
1544 case sClientAliveCountMax:
1545 intptr = &options->client_alive_count_max;
1546 goto parse_int;
1548 case sAcceptEnv:
1549 while ((arg = strdelim(&cp)) && *arg != '\0') {
1550 if (strchr(arg, '=') != NULL)
1551 fatal("%s line %d: Invalid environment name.",
1552 filename, linenum);
1553 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1554 fatal("%s line %d: too many allow env.",
1555 filename, linenum);
1556 if (!*activep)
1557 continue;
1558 options->accept_env[options->num_accept_env++] =
1559 xstrdup(arg);
1561 break;
1563 case sPermitTunnel:
1564 intptr = &options->permit_tun;
1565 arg = strdelim(&cp);
1566 if (!arg || *arg == '\0')
1567 fatal("%s line %d: Missing yes/point-to-point/"
1568 "ethernet/no argument.", filename, linenum);
1569 value = -1;
1570 for (i = 0; tunmode_desc[i].val != -1; i++)
1571 if (strcmp(tunmode_desc[i].text, arg) == 0) {
1572 value = tunmode_desc[i].val;
1573 break;
1575 if (value == -1)
1576 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1577 "no argument: %s", filename, linenum, arg);
1578 if (*intptr == -1)
1579 *intptr = value;
1580 break;
1582 case sMatch:
1583 if (cmdline)
1584 fatal("Match directive not supported as a command-line "
1585 "option");
1586 value = match_cfg_line(&cp, linenum, connectinfo);
1587 if (value < 0)
1588 fatal("%s line %d: Bad Match condition", filename,
1589 linenum);
1590 *activep = value;
1591 break;
1593 case sPermitOpen:
1594 arg = strdelim(&cp);
1595 if (!arg || *arg == '\0')
1596 fatal("%s line %d: missing PermitOpen specification",
1597 filename, linenum);
1598 n = options->num_permitted_opens; /* modified later */
1599 if (strcmp(arg, "any") == 0) {
1600 if (*activep && n == -1) {
1601 channel_clear_adm_permitted_opens();
1602 options->num_permitted_opens = 0;
1604 break;
1606 if (strcmp(arg, "none") == 0) {
1607 if (*activep && n == -1) {
1608 options->num_permitted_opens = 1;
1609 channel_disable_adm_local_opens();
1611 break;
1613 if (*activep && n == -1)
1614 channel_clear_adm_permitted_opens();
1615 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1616 p = hpdelim(&arg);
1617 if (p == NULL)
1618 fatal("%s line %d: missing host in PermitOpen",
1619 filename, linenum);
1620 p = cleanhostname(p);
1621 if (arg == NULL || ((port = permitopen_port(arg)) < 0))
1622 fatal("%s line %d: bad port number in "
1623 "PermitOpen", filename, linenum);
1624 if (*activep && n == -1)
1625 options->num_permitted_opens =
1626 channel_add_adm_permitted_opens(p, port);
1628 break;
1630 case sForceCommand:
1631 if (cp == NULL)
1632 fatal("%.200s line %d: Missing argument.", filename,
1633 linenum);
1634 len = strspn(cp, WHITESPACE);
1635 if (*activep && options->adm_forced_command == NULL)
1636 options->adm_forced_command = xstrdup(cp + len);
1637 return 0;
1639 case sChrootDirectory:
1640 charptr = &options->chroot_directory;
1642 arg = strdelim(&cp);
1643 if (!arg || *arg == '\0')
1644 fatal("%s line %d: missing file name.",
1645 filename, linenum);
1646 if (*activep && *charptr == NULL)
1647 *charptr = xstrdup(arg);
1648 break;
1650 case sTrustedUserCAKeys:
1651 charptr = &options->trusted_user_ca_keys;
1652 goto parse_filename;
1654 case sRevokedKeys:
1655 charptr = &options->revoked_keys_file;
1656 goto parse_filename;
1658 case sIPQoS:
1659 arg = strdelim(&cp);
1660 if ((value = parse_ipqos(arg)) == -1)
1661 fatal("%s line %d: Bad IPQoS value: %s",
1662 filename, linenum, arg);
1663 arg = strdelim(&cp);
1664 if (arg == NULL)
1665 value2 = value;
1666 else if ((value2 = parse_ipqos(arg)) == -1)
1667 fatal("%s line %d: Bad IPQoS value: %s",
1668 filename, linenum, arg);
1669 if (*activep) {
1670 options->ip_qos_interactive = value;
1671 options->ip_qos_bulk = value2;
1673 break;
1675 case sVersionAddendum:
1676 if (cp == NULL)
1677 fatal("%.200s line %d: Missing argument.", filename,
1678 linenum);
1679 len = strspn(cp, WHITESPACE);
1680 if (*activep && options->version_addendum == NULL) {
1681 if (strcasecmp(cp + len, "none") == 0)
1682 options->version_addendum = xstrdup("");
1683 else if (strchr(cp + len, '\r') != NULL)
1684 fatal("%.200s line %d: Invalid argument",
1685 filename, linenum);
1686 else
1687 options->version_addendum = xstrdup(cp + len);
1689 return 0;
1691 case sAuthorizedKeysCommand:
1692 len = strspn(cp, WHITESPACE);
1693 if (*activep && options->authorized_keys_command == NULL) {
1694 if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
1695 fatal("%.200s line %d: AuthorizedKeysCommand "
1696 "must be an absolute path",
1697 filename, linenum);
1698 options->authorized_keys_command = xstrdup(cp + len);
1700 return 0;
1702 case sAuthorizedKeysCommandUser:
1703 charptr = &options->authorized_keys_command_user;
1705 arg = strdelim(&cp);
1706 if (*activep && *charptr == NULL)
1707 *charptr = xstrdup(arg);
1708 break;
1710 case sAuthenticationMethods:
1711 if (*activep && options->num_auth_methods == 0) {
1712 while ((arg = strdelim(&cp)) && *arg != '\0') {
1713 if (options->num_auth_methods >=
1714 MAX_AUTH_METHODS)
1715 fatal("%s line %d: "
1716 "too many authentication methods.",
1717 filename, linenum);
1718 if (auth2_methods_valid(arg, 0) != 0)
1719 fatal("%s line %d: invalid "
1720 "authentication method list.",
1721 filename, linenum);
1722 options->auth_methods[
1723 options->num_auth_methods++] = xstrdup(arg);
1726 return 0;
1728 case sStreamLocalBindMask:
1729 arg = strdelim(&cp);
1730 if (!arg || *arg == '\0')
1731 fatal("%s line %d: missing StreamLocalBindMask argument.",
1732 filename, linenum);
1733 /* Parse mode in octal format */
1734 value = strtol(arg, &p, 8);
1735 if (arg == p || value < 0 || value > 0777)
1736 fatal("%s line %d: Bad mask.", filename, linenum);
1737 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1738 break;
1740 case sStreamLocalBindUnlink:
1741 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1742 goto parse_flag;
1744 case sDeprecated:
1745 logit("%s line %d: Deprecated option %s",
1746 filename, linenum, arg);
1747 while (arg)
1748 arg = strdelim(&cp);
1749 break;
1751 case sUnsupported:
1752 logit("%s line %d: Unsupported option %s",
1753 filename, linenum, arg);
1754 while (arg)
1755 arg = strdelim(&cp);
1756 break;
1758 default:
1759 fatal("%s line %d: Missing handler for opcode %s (%d)",
1760 filename, linenum, arg, opcode);
1762 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1763 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1764 filename, linenum, arg);
1765 return 0;
1768 /* Reads the server configuration file. */
1770 void
1771 load_server_config(const char *filename, Buffer *conf)
1773 char line[4096], *cp;
1774 FILE *f;
1775 int lineno = 0;
1777 debug2("%s: filename %s", __func__, filename);
1778 if ((f = fopen(filename, "r")) == NULL) {
1779 perror(filename);
1780 exit(1);
1782 buffer_clear(conf);
1783 while (fgets(line, sizeof(line), f)) {
1784 lineno++;
1785 if (strlen(line) == sizeof(line) - 1)
1786 fatal("%s line %d too long", filename, lineno);
1788 * Trim out comments and strip whitespace
1789 * NB - preserve newlines, they are needed to reproduce
1790 * line numbers later for error messages
1792 if ((cp = strchr(line, '#')) != NULL)
1793 memcpy(cp, "\n", 2);
1794 cp = line + strspn(line, " \t\r");
1796 buffer_append(conf, cp, strlen(cp));
1798 buffer_append(conf, "\0", 1);
1799 fclose(f);
1800 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1803 void
1804 parse_server_match_config(ServerOptions *options,
1805 struct connection_info *connectinfo)
1807 ServerOptions mo;
1809 initialize_server_options(&mo);
1810 parse_server_config(&mo, "reprocess config", &cfg, connectinfo);
1811 copy_set_server_options(options, &mo, 0);
1814 int parse_server_match_testspec(struct connection_info *ci, char *spec)
1816 char *p;
1818 while ((p = strsep(&spec, ",")) && *p != '\0') {
1819 if (strncmp(p, "addr=", 5) == 0) {
1820 ci->address = xstrdup(p + 5);
1821 } else if (strncmp(p, "host=", 5) == 0) {
1822 ci->host = xstrdup(p + 5);
1823 } else if (strncmp(p, "user=", 5) == 0) {
1824 ci->user = xstrdup(p + 5);
1825 } else if (strncmp(p, "laddr=", 6) == 0) {
1826 ci->laddress = xstrdup(p + 6);
1827 } else if (strncmp(p, "lport=", 6) == 0) {
1828 ci->lport = a2port(p + 6);
1829 if (ci->lport == -1) {
1830 fprintf(stderr, "Invalid port '%s' in test mode"
1831 " specification %s\n", p+6, p);
1832 return -1;
1834 } else {
1835 fprintf(stderr, "Invalid test mode specification %s\n",
1837 return -1;
1840 return 0;
1844 * returns 1 for a complete spec, 0 for partial spec and -1 for an
1845 * empty spec.
1847 int server_match_spec_complete(struct connection_info *ci)
1849 if (ci->user && ci->host && ci->address)
1850 return 1; /* complete */
1851 if (!ci->user && !ci->host && !ci->address)
1852 return -1; /* empty */
1853 return 0; /* partial */
1857 * Copy any supported values that are set.
1859 * If the preauth flag is set, we do not bother copying the string or
1860 * array values that are not used pre-authentication, because any that we
1861 * do use must be explictly sent in mm_getpwnamallow().
1863 void
1864 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1866 #define M_CP_INTOPT(n) do {\
1867 if (src->n != -1) \
1868 dst->n = src->n; \
1869 } while (0)
1871 M_CP_INTOPT(password_authentication);
1872 M_CP_INTOPT(gss_authentication);
1873 M_CP_INTOPT(rsa_authentication);
1874 M_CP_INTOPT(pubkey_authentication);
1875 M_CP_INTOPT(kerberos_authentication);
1876 M_CP_INTOPT(hostbased_authentication);
1877 M_CP_INTOPT(hostbased_uses_name_from_packet_only);
1878 M_CP_INTOPT(kbd_interactive_authentication);
1879 M_CP_INTOPT(permit_root_login);
1880 M_CP_INTOPT(permit_empty_passwd);
1882 M_CP_INTOPT(allow_tcp_forwarding);
1883 M_CP_INTOPT(allow_streamlocal_forwarding);
1884 M_CP_INTOPT(allow_agent_forwarding);
1885 M_CP_INTOPT(permit_tun);
1886 M_CP_INTOPT(fwd_opts.gateway_ports);
1887 M_CP_INTOPT(x11_display_offset);
1888 M_CP_INTOPT(x11_forwarding);
1889 M_CP_INTOPT(x11_use_localhost);
1890 M_CP_INTOPT(permit_tty);
1891 M_CP_INTOPT(permit_user_rc);
1892 M_CP_INTOPT(max_sessions);
1893 M_CP_INTOPT(max_authtries);
1894 M_CP_INTOPT(ip_qos_interactive);
1895 M_CP_INTOPT(ip_qos_bulk);
1896 M_CP_INTOPT(rekey_limit);
1897 M_CP_INTOPT(rekey_interval);
1899 /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
1900 #define M_CP_STROPT(n) do {\
1901 if (src->n != NULL && dst->n != src->n) { \
1902 free(dst->n); \
1903 dst->n = src->n; \
1905 } while(0)
1906 #define M_CP_STRARRAYOPT(n, num_n) do {\
1907 if (src->num_n != 0) { \
1908 for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \
1909 dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \
1911 } while(0)
1913 /* See comment in servconf.h */
1914 COPY_MATCH_STRING_OPTS();
1917 * The only things that should be below this point are string options
1918 * which are only used after authentication.
1920 if (preauth)
1921 return;
1923 M_CP_STROPT(adm_forced_command);
1924 M_CP_STROPT(chroot_directory);
1927 #undef M_CP_INTOPT
1928 #undef M_CP_STROPT
1929 #undef M_CP_STRARRAYOPT
1931 void
1932 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1933 struct connection_info *connectinfo)
1935 int active, linenum, bad_options = 0;
1936 char *cp, *obuf, *cbuf;
1938 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1940 obuf = cbuf = xstrdup(buffer_ptr(conf));
1941 active = connectinfo ? 0 : 1;
1942 linenum = 1;
1943 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1944 if (process_server_config_line(options, cp, filename,
1945 linenum++, &active, connectinfo) != 0)
1946 bad_options++;
1948 free(obuf);
1949 if (bad_options > 0)
1950 fatal("%s: terminating, %d bad configuration options",
1951 filename, bad_options);
1954 static const char *
1955 fmt_multistate_int(int val, const struct multistate *m)
1957 u_int i;
1959 for (i = 0; m[i].key != NULL; i++) {
1960 if (m[i].value == val)
1961 return m[i].key;
1963 return "UNKNOWN";
1966 static const char *
1967 fmt_intarg(ServerOpCodes code, int val)
1969 if (val == -1)
1970 return "unset";
1971 switch (code) {
1972 case sAddressFamily:
1973 return fmt_multistate_int(val, multistate_addressfamily);
1974 case sPermitRootLogin:
1975 return fmt_multistate_int(val, multistate_permitrootlogin);
1976 case sGatewayPorts:
1977 return fmt_multistate_int(val, multistate_gatewayports);
1978 case sCompression:
1979 return fmt_multistate_int(val, multistate_compression);
1980 case sUsePrivilegeSeparation:
1981 return fmt_multistate_int(val, multistate_privsep);
1982 case sAllowTcpForwarding:
1983 return fmt_multistate_int(val, multistate_tcpfwd);
1984 case sAllowStreamLocalForwarding:
1985 return fmt_multistate_int(val, multistate_tcpfwd);
1986 case sProtocol:
1987 switch (val) {
1988 case SSH_PROTO_1:
1989 return "1";
1990 case SSH_PROTO_2:
1991 return "2";
1992 case (SSH_PROTO_1|SSH_PROTO_2):
1993 return "2,1";
1994 default:
1995 return "UNKNOWN";
1997 default:
1998 switch (val) {
1999 case 0:
2000 return "no";
2001 case 1:
2002 return "yes";
2003 default:
2004 return "UNKNOWN";
2009 static const char *
2010 lookup_opcode_name(ServerOpCodes code)
2012 u_int i;
2014 for (i = 0; keywords[i].name != NULL; i++)
2015 if (keywords[i].opcode == code)
2016 return(keywords[i].name);
2017 return "UNKNOWN";
2020 static void
2021 dump_cfg_int(ServerOpCodes code, int val)
2023 printf("%s %d\n", lookup_opcode_name(code), val);
2026 static void
2027 dump_cfg_fmtint(ServerOpCodes code, int val)
2029 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2032 static void
2033 dump_cfg_string(ServerOpCodes code, const char *val)
2035 if (val == NULL)
2036 return;
2037 printf("%s %s\n", lookup_opcode_name(code), val);
2040 static void
2041 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
2043 u_int i;
2045 for (i = 0; i < count; i++)
2046 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2049 static void
2050 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2052 u_int i;
2054 printf("%s", lookup_opcode_name(code));
2055 for (i = 0; i < count; i++)
2056 printf(" %s", vals[i]);
2057 printf("\n");
2060 void
2061 dump_config(ServerOptions *o)
2063 u_int i;
2064 int ret;
2065 struct addrinfo *ai;
2066 char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
2068 /* these are usually at the top of the config */
2069 for (i = 0; i < o->num_ports; i++)
2070 printf("port %d\n", o->ports[i]);
2071 dump_cfg_fmtint(sProtocol, o->protocol);
2072 dump_cfg_fmtint(sAddressFamily, o->address_family);
2074 /* ListenAddress must be after Port */
2075 for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
2076 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2077 sizeof(addr), port, sizeof(port),
2078 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2079 error("getnameinfo failed: %.100s",
2080 (ret != EAI_SYSTEM) ? gai_strerror(ret) :
2081 strerror(errno));
2082 } else {
2083 if (ai->ai_family == AF_INET6)
2084 printf("listenaddress [%s]:%s\n", addr, port);
2085 else
2086 printf("listenaddress %s:%s\n", addr, port);
2090 /* integer arguments */
2091 #ifdef USE_PAM
2092 dump_cfg_int(sUsePAM, o->use_pam);
2093 #endif
2094 dump_cfg_int(sServerKeyBits, o->server_key_bits);
2095 dump_cfg_int(sLoginGraceTime, o->login_grace_time);
2096 dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
2097 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
2098 dump_cfg_int(sMaxAuthTries, o->max_authtries);
2099 dump_cfg_int(sMaxSessions, o->max_sessions);
2100 dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
2101 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
2103 /* formatted integer arguments */
2104 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
2105 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
2106 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
2107 dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2108 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
2109 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
2110 o->hostbased_uses_name_from_packet_only);
2111 dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
2112 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
2113 #ifdef KRB5
2114 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
2115 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
2116 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
2117 # ifdef USE_AFS
2118 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
2119 # endif
2120 #endif
2121 #ifdef GSSAPI
2122 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
2123 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
2124 #endif
2125 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
2126 dump_cfg_fmtint(sKbdInteractiveAuthentication,
2127 o->kbd_interactive_authentication);
2128 dump_cfg_fmtint(sChallengeResponseAuthentication,
2129 o->challenge_response_authentication);
2130 dump_cfg_fmtint(sPrintMotd, o->print_motd);
2131 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
2132 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
2133 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
2134 dump_cfg_fmtint(sPermitTTY, o->permit_tty);
2135 dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
2136 dump_cfg_fmtint(sStrictModes, o->strict_modes);
2137 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
2138 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
2139 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
2140 dump_cfg_fmtint(sUseLogin, o->use_login);
2141 dump_cfg_fmtint(sCompression, o->compression);
2142 dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
2143 dump_cfg_fmtint(sUseDNS, o->use_dns);
2144 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
2145 dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2146 dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
2148 /* string arguments */
2149 dump_cfg_string(sPidFile, o->pid_file);
2150 dump_cfg_string(sXAuthLocation, o->xauth_location);
2151 dump_cfg_string(sCiphers, o->ciphers ? o->ciphers :
2152 cipher_alg_list(',', 0));
2153 dump_cfg_string(sMacs, o->macs ? o->macs : mac_alg_list(','));
2154 dump_cfg_string(sBanner, o->banner);
2155 dump_cfg_string(sForceCommand, o->adm_forced_command);
2156 dump_cfg_string(sChrootDirectory, o->chroot_directory);
2157 dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
2158 dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
2159 dump_cfg_string(sAuthorizedPrincipalsFile,
2160 o->authorized_principals_file);
2161 dump_cfg_string(sVersionAddendum, o->version_addendum);
2162 dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
2163 dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
2164 dump_cfg_string(sHostKeyAgent, o->host_key_agent);
2165 dump_cfg_string(sKexAlgorithms, o->kex_algorithms ? o->kex_algorithms :
2166 kex_alg_list(','));
2168 /* string arguments requiring a lookup */
2169 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
2170 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
2172 /* string array arguments */
2173 dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
2174 o->authorized_keys_files);
2175 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
2176 o->host_key_files);
2177 dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files,
2178 o->host_cert_files);
2179 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
2180 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
2181 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
2182 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
2183 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
2184 dump_cfg_strarray_oneline(sAuthenticationMethods,
2185 o->num_auth_methods, o->auth_methods);
2187 /* other arguments */
2188 for (i = 0; i < o->num_subsystems; i++)
2189 printf("subsystem %s %s\n", o->subsystem_name[i],
2190 o->subsystem_args[i]);
2192 printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
2193 o->max_startups_rate, o->max_startups);
2195 for (i = 0; tunmode_desc[i].val != -1; i++)
2196 if (tunmode_desc[i].val == o->permit_tun) {
2197 s = tunmode_desc[i].text;
2198 break;
2200 dump_cfg_string(sPermitTunnel, s);
2202 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2203 printf("%s\n", iptos2str(o->ip_qos_bulk));
2205 printf("rekeylimit %lld %d\n", (long long)o->rekey_limit,
2206 o->rekey_interval);
2208 channel_print_adm_permitted_opens();