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