1 /* $OpenBSD: servconf.c,v 1.165 2006/08/14 12:40:25 dtucker Exp $ */
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
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".
15 #include <sys/types.h>
16 #include <sys/socket.h>
33 #include "pathnames.h"
41 #include "groupaccess.h"
43 static void add_listen_addr(ServerOptions *, char *, u_short);
44 static void add_one_listen_addr(ServerOptions *, char *, u_short);
46 /* Use of privilege separation or not */
47 extern int use_privsep;
50 /* Initializes the server options to their default values. */
53 initialize_server_options(ServerOptions *options)
55 memset(options, 0, sizeof(*options));
57 /* Portable-specific options */
58 options->use_pam = -1;
60 /* Standard Options */
61 options->num_ports = 0;
62 options->ports_from_cmdline = 0;
63 options->listen_addrs = NULL;
64 options->address_family = -1;
65 options->num_host_key_files = 0;
66 options->pid_file = NULL;
67 options->server_key_bits = -1;
68 options->login_grace_time = -1;
69 options->key_regeneration_time = -1;
70 options->permit_root_login = PERMIT_NOT_SET;
71 options->ignore_rhosts = -1;
72 options->ignore_user_known_hosts = -1;
73 options->print_motd = -1;
74 options->print_lastlog = -1;
75 options->x11_forwarding = -1;
76 options->x11_display_offset = -1;
77 options->x11_use_localhost = -1;
78 options->xauth_location = NULL;
79 options->strict_modes = -1;
80 options->tcp_keep_alive = -1;
81 options->log_facility = SYSLOG_FACILITY_NOT_SET;
82 options->log_level = SYSLOG_LEVEL_NOT_SET;
83 options->rhosts_rsa_authentication = -1;
84 options->hostbased_authentication = -1;
85 options->hostbased_uses_name_from_packet_only = -1;
86 options->rsa_authentication = -1;
87 options->pubkey_authentication = -1;
88 options->kerberos_authentication = -1;
89 options->kerberos_or_local_passwd = -1;
90 options->kerberos_ticket_cleanup = -1;
91 options->kerberos_get_afs_token = -1;
92 options->gss_authentication=-1;
93 options->gss_keyex = -1;
94 options->gss_cleanup_creds = -1;
95 options->gss_strict_acceptor = -1;
96 options->password_authentication = -1;
97 options->kbd_interactive_authentication = -1;
98 options->challenge_response_authentication = -1;
99 options->permit_empty_passwd = -1;
100 options->permit_user_env = -1;
101 options->use_login = -1;
102 options->compression = -1;
103 options->allow_tcp_forwarding = -1;
104 options->num_allow_users = 0;
105 options->num_deny_users = 0;
106 options->num_allow_groups = 0;
107 options->num_deny_groups = 0;
108 options->ciphers = NULL;
109 options->macs = NULL;
110 options->protocol = SSH_PROTO_UNKNOWN;
111 options->gateway_ports = -1;
112 options->num_subsystems = 0;
113 options->max_startups_begin = -1;
114 options->max_startups_rate = -1;
115 options->max_startups = -1;
116 options->max_authtries = -1;
117 options->banner = NULL;
118 options->use_dns = -1;
119 options->client_alive_interval = -1;
120 options->client_alive_count_max = -1;
121 options->authorized_keys_file = NULL;
122 options->authorized_keys_file2 = NULL;
123 options->num_accept_env = 0;
124 options->permit_tun = -1;
125 options->num_permitted_opens = -1;
126 options->adm_forced_command = NULL;
127 options->none_enabled = -1;
128 options->tcp_rcv_buf_poll = -1;
129 options->hpn_disabled = -1;
130 options->hpn_buffer_size = -1;
134 fill_default_server_options(ServerOptions *options)
137 /* Portable-specific options */
138 if (options->use_pam == -1)
139 options->use_pam = 0;
141 /* Standard Options */
142 if (options->protocol == SSH_PROTO_UNKNOWN)
143 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
144 if (options->num_host_key_files == 0) {
145 /* fill default hostkeys for protocols */
146 if (options->protocol & SSH_PROTO_1)
147 options->host_key_files[options->num_host_key_files++] =
149 if (options->protocol & SSH_PROTO_2) {
150 options->host_key_files[options->num_host_key_files++] =
151 _PATH_HOST_RSA_KEY_FILE;
152 options->host_key_files[options->num_host_key_files++] =
153 _PATH_HOST_DSA_KEY_FILE;
156 if (options->num_ports == 0)
157 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
158 if (options->listen_addrs == NULL)
159 add_listen_addr(options, NULL, 0);
160 if (options->pid_file == NULL)
161 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
162 if (options->server_key_bits == -1)
163 options->server_key_bits = 768;
164 if (options->login_grace_time == -1)
165 options->login_grace_time = 120;
166 if (options->key_regeneration_time == -1)
167 options->key_regeneration_time = 3600;
168 if (options->permit_root_login == PERMIT_NOT_SET)
169 options->permit_root_login = PERMIT_YES;
170 if (options->ignore_rhosts == -1)
171 options->ignore_rhosts = 1;
172 if (options->ignore_user_known_hosts == -1)
173 options->ignore_user_known_hosts = 0;
174 if (options->print_motd == -1)
175 options->print_motd = 1;
176 if (options->print_lastlog == -1)
177 options->print_lastlog = 1;
178 if (options->x11_forwarding == -1)
179 options->x11_forwarding = 0;
180 if (options->x11_display_offset == -1)
181 options->x11_display_offset = 10;
182 if (options->x11_use_localhost == -1)
183 options->x11_use_localhost = 1;
184 if (options->xauth_location == NULL)
185 options->xauth_location = _PATH_XAUTH;
186 if (options->strict_modes == -1)
187 options->strict_modes = 1;
188 if (options->tcp_keep_alive == -1)
189 options->tcp_keep_alive = 1;
190 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
191 options->log_facility = SYSLOG_FACILITY_AUTH;
192 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
193 options->log_level = SYSLOG_LEVEL_INFO;
194 if (options->rhosts_rsa_authentication == -1)
195 options->rhosts_rsa_authentication = 0;
196 if (options->hostbased_authentication == -1)
197 options->hostbased_authentication = 0;
198 if (options->hostbased_uses_name_from_packet_only == -1)
199 options->hostbased_uses_name_from_packet_only = 0;
200 if (options->rsa_authentication == -1)
201 options->rsa_authentication = 1;
202 if (options->pubkey_authentication == -1)
203 options->pubkey_authentication = 1;
204 if (options->kerberos_authentication == -1)
205 options->kerberos_authentication = 0;
206 if (options->kerberos_or_local_passwd == -1)
207 options->kerberos_or_local_passwd = 1;
208 if (options->kerberos_ticket_cleanup == -1)
209 options->kerberos_ticket_cleanup = 1;
210 if (options->kerberos_get_afs_token == -1)
211 options->kerberos_get_afs_token = 0;
212 if (options->gss_authentication == -1)
213 options->gss_authentication = 0;
214 if (options->gss_keyex == -1)
215 options->gss_keyex = 0;
216 if (options->gss_cleanup_creds == -1)
217 options->gss_cleanup_creds = 1;
218 if (options->gss_strict_acceptor == -1)
219 options->gss_strict_acceptor = 0;
220 if (options->password_authentication == -1)
221 options->password_authentication = 1;
222 if (options->kbd_interactive_authentication == -1)
223 options->kbd_interactive_authentication = 0;
224 if (options->challenge_response_authentication == -1)
225 options->challenge_response_authentication = 1;
226 if (options->permit_empty_passwd == -1)
227 options->permit_empty_passwd = 0;
228 if (options->permit_user_env == -1)
229 options->permit_user_env = 0;
230 if (options->use_login == -1)
231 options->use_login = 0;
232 if (options->compression == -1)
233 options->compression = COMP_DELAYED;
234 if (options->allow_tcp_forwarding == -1)
235 options->allow_tcp_forwarding = 1;
236 if (options->gateway_ports == -1)
237 options->gateway_ports = 0;
238 if (options->max_startups == -1)
239 options->max_startups = 10;
240 if (options->max_startups_rate == -1)
241 options->max_startups_rate = 100; /* 100% */
242 if (options->max_startups_begin == -1)
243 options->max_startups_begin = options->max_startups;
244 if (options->max_authtries == -1)
245 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
246 if (options->use_dns == -1)
247 options->use_dns = 1;
248 if (options->client_alive_interval == -1)
249 options->client_alive_interval = 0;
250 if (options->client_alive_count_max == -1)
251 options->client_alive_count_max = 3;
252 if (options->authorized_keys_file2 == NULL) {
253 /* authorized_keys_file2 falls back to authorized_keys_file */
254 if (options->authorized_keys_file != NULL)
255 options->authorized_keys_file2 = options->authorized_keys_file;
257 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
259 if (options->authorized_keys_file == NULL)
260 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
261 if (options->permit_tun == -1)
262 options->permit_tun = SSH_TUNMODE_NO;
264 if (options->hpn_disabled == -1)
265 options->hpn_disabled = 0;
267 if (options->hpn_buffer_size == -1)
268 options->hpn_buffer_size = 2*1024*1024;
270 if (options->hpn_buffer_size == 0)
271 options->hpn_buffer_size = 1;
272 /* limit the maximum buffer to 7MB */
273 if (options->hpn_buffer_size > 7168)
274 options->hpn_buffer_size = 7168;
275 options->hpn_buffer_size *=1024;
278 /* Turn privilege separation on by default */
279 if (use_privsep == -1)
285 if (use_privsep && options->compression == 1) {
286 error("This platform does not support both privilege "
287 "separation and compression");
288 error("Compression disabled");
289 options->compression = 0;
295 /* Keyword tokens. */
297 sBadOption, /* == unknown option */
298 /* Portable-specific options */
300 /* Standard Options */
301 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
302 sPermitRootLogin, sLogFacility, sLogLevel,
303 sRhostsRSAAuthentication, sRSAAuthentication,
304 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
305 sKerberosGetAFSToken,
306 sKerberosTgtPassing, sChallengeResponseAuthentication,
307 sPasswordAuthentication, sKbdInteractiveAuthentication,
308 sListenAddress, sAddressFamily,
309 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
310 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
311 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
312 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
313 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
314 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
315 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
316 sMaxStartups, sMaxAuthTries,
317 sBanner, sUseDNS, sHostbasedAuthentication,
318 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
319 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
320 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
322 sAcceptEnv, sPermitTunnel,
323 sMatch, sPermitOpen, sForceCommand,
324 sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll,
325 sHPNDisabled, sHPNBufferSize,
326 sDeprecated, sUnsupported
329 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
330 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
331 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
333 /* Textual representation of the tokens. */
336 ServerOpCodes opcode;
339 /* Portable-specific options */
341 { "usepam", sUsePAM, SSHCFG_GLOBAL },
343 { "usepam", sUnsupported, SSHCFG_GLOBAL },
345 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
346 /* Standard Options */
347 { "port", sPort, SSHCFG_GLOBAL },
348 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
349 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
350 { "pidfile", sPidFile, SSHCFG_GLOBAL },
351 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
352 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
353 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
354 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
355 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
356 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
357 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
358 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
359 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
360 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
361 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
362 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
363 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
365 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
366 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
367 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
369 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
371 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
374 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
375 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
376 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
377 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
379 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
380 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
382 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
383 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
384 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
385 { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
387 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
388 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
389 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
390 { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
392 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
393 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
394 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
395 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
396 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
397 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
398 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
399 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
400 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
401 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
402 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
403 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
404 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
405 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
406 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
407 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
408 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
409 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
410 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
411 { "compression", sCompression, SSHCFG_GLOBAL },
412 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
413 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
414 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
415 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
416 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
417 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
418 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
419 { "ciphers", sCiphers, SSHCFG_GLOBAL },
420 { "macs", sMacs, SSHCFG_GLOBAL },
421 { "protocol", sProtocol, SSHCFG_GLOBAL },
422 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
423 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
424 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
425 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
426 { "banner", sBanner, SSHCFG_GLOBAL },
427 { "usedns", sUseDNS, SSHCFG_GLOBAL },
428 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
429 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
430 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
431 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
432 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
433 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
434 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
435 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
436 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
437 { "match", sMatch, SSHCFG_ALL },
438 { "permitopen", sPermitOpen, SSHCFG_ALL },
439 { "forcecommand", sForceCommand, SSHCFG_ALL },
440 { "noneenabled", sNoneEnabled },
441 { "hpndisabled", sHPNDisabled },
442 { "hpnbuffersize", sHPNBufferSize },
443 { "tcprcvbufpoll", sTcpRcvBufPoll },
444 { NULL, sBadOption, 0 }
448 * Returns the number of the token pointed to by cp or sBadOption.
452 parse_token(const char *cp, const char *filename,
453 int linenum, u_int *flags)
457 for (i = 0; keywords[i].name; i++)
458 if (strcasecmp(cp, keywords[i].name) == 0) {
459 debug ("Config token is %s", keywords[i].name);
460 *flags = keywords[i].flags;
461 return keywords[i].opcode;
464 error("%s: line %d: Bad configuration option: %s",
465 filename, linenum, cp);
470 add_listen_addr(ServerOptions *options, char *addr, u_short port)
474 if (options->num_ports == 0)
475 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
476 if (options->address_family == -1)
477 options->address_family = AF_UNSPEC;
479 for (i = 0; i < options->num_ports; i++)
480 add_one_listen_addr(options, addr, options->ports[i]);
482 add_one_listen_addr(options, addr, port);
486 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
488 struct addrinfo hints, *ai, *aitop;
489 char strport[NI_MAXSERV];
492 memset(&hints, 0, sizeof(hints));
493 hints.ai_family = options->address_family;
494 hints.ai_socktype = SOCK_STREAM;
495 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
496 snprintf(strport, sizeof strport, "%u", port);
497 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
498 fatal("bad addr or host: %s (%s)",
499 addr ? addr : "<NULL>",
500 gai_strerror(gaierr));
501 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
503 ai->ai_next = options->listen_addrs;
504 options->listen_addrs = aitop;
508 * The strategy for the Match blocks is that the config file is parsed twice.
510 * The first time is at startup. activep is initialized to 1 and the
511 * directives in the global context are processed and acted on. Hitting a
512 * Match directive unsets activep and the directives inside the block are
513 * checked for syntax only.
515 * The second time is after a connection has been established but before
516 * authentication. activep is initialized to 2 and global config directives
517 * are ignored since they have already been processed. If the criteria in a
518 * Match block is met, activep is set and the subsequent directives
519 * processed and actioned until EOF or another Match block unsets it. Any
520 * options set are copied into the main server config.
522 * Potential additions/improvements:
523 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
525 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
526 * Match Address 192.168.0.*
531 * AllowTcpForwarding yes
532 * GatewayPorts clientspecified
535 * - Add a PermittedChannelRequests directive
537 * PermittedChannelRequests session,forwarded-tcpip
541 match_cfg_line_group(const char *grps, int line, const char *user)
545 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
549 * Even if we do not have a user yet, we still need to check for
552 arg = cp = xstrdup(grps);
553 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
554 if (ngrps >= MAX_MATCH_GROUPS) {
555 error("line %d: too many groups in Match Group", line);
559 grplist[ngrps++] = p;
565 if ((pw = getpwnam(user)) == NULL) {
566 debug("Can't match group at line %d because user %.100s does "
567 "not exist", line, user);
568 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
569 debug("Can't Match group because user %.100s not in any group "
570 "at line %d", user, line);
571 } else if (ga_match(grplist, ngrps) != 1) {
572 debug("user %.100s does not match group %.100s at line %d",
575 debug("user %.100s matched group %.100s at line %d", user,
586 match_cfg_line(char **condition, int line, const char *user, const char *host,
590 char *arg, *attrib, *cp = *condition;
594 debug3("checking syntax for 'Match %s'", cp);
596 debug3("checking match for '%s' user %s host %s addr %s", cp,
597 user ? user : "(null)", host ? host : "(null)",
598 address ? address : "(null)");
600 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
601 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
602 error("Missing Match criteria for %s", attrib);
606 if (strcasecmp(attrib, "user") == 0) {
611 if (match_pattern_list(user, arg, len, 0) != 1)
614 debug("user %.100s matched 'User %.100s' at "
615 "line %d", user, arg, line);
616 } else if (strcasecmp(attrib, "group") == 0) {
617 switch (match_cfg_line_group(arg, line, user)) {
623 } else if (strcasecmp(attrib, "host") == 0) {
628 if (match_hostname(host, arg, len) != 1)
631 debug("connection from %.100s matched 'Host "
632 "%.100s' at line %d", host, arg, line);
633 } else if (strcasecmp(attrib, "address") == 0) {
634 debug("address '%s' arg '%s'", address, arg);
639 if (match_hostname(address, arg, len) != 1)
642 debug("connection from %.100s matched 'Address "
643 "%.100s' at line %d", address, arg, line);
645 error("Unsupported Match attribute %s", attrib);
650 debug3("match %sfound", result ? "" : "not ");
655 #define WHITESPACE " \t\r\n"
658 process_server_config_line(ServerOptions *options, char *line,
659 const char *filename, int linenum, int *activep, const char *user,
660 const char *host, const char *address)
662 char *cp, **charptr, *arg, *p;
663 int cmdline = 0, *intptr, value, n;
664 ServerOpCodes opcode;
670 if ((arg = strdelim(&cp)) == NULL)
672 /* Ignore leading whitespace */
675 if (!arg || !*arg || *arg == '#')
679 opcode = parse_token(arg, filename, linenum, &flags);
681 if (activep == NULL) { /* We are processing a command line directive */
685 if (*activep && opcode != sMatch)
686 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
687 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
689 fatal("%s line %d: Directive '%s' is not allowed "
690 "within a Match block", filename, linenum, arg);
691 } else { /* this is a directive we have already processed */
699 /* Portable-specific options */
701 intptr = &options->use_pam;
704 /* Standard Options */
708 /* ignore ports from configfile if cmdline specifies ports */
709 if (options->ports_from_cmdline)
711 if (options->listen_addrs != NULL)
712 fatal("%s line %d: ports must be specified before "
713 "ListenAddress.", filename, linenum);
714 if (options->num_ports >= MAX_PORTS)
715 fatal("%s line %d: too many ports.",
718 if (!arg || *arg == '\0')
719 fatal("%s line %d: missing port number.",
721 options->ports[options->num_ports++] = a2port(arg);
722 if (options->ports[options->num_ports-1] == 0)
723 fatal("%s line %d: Badly formatted port number.",
728 intptr = &options->server_key_bits;
731 if (!arg || *arg == '\0')
732 fatal("%s line %d: missing integer value.",
735 if (*activep && *intptr == -1)
739 case sLoginGraceTime:
740 intptr = &options->login_grace_time;
743 if (!arg || *arg == '\0')
744 fatal("%s line %d: missing time value.",
746 if ((value = convtime(arg)) == -1)
747 fatal("%s line %d: invalid time value.",
753 case sKeyRegenerationTime:
754 intptr = &options->key_regeneration_time;
759 if (arg == NULL || *arg == '\0')
760 fatal("%s line %d: missing address",
762 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
763 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
764 && strchr(p+1, ':') != NULL) {
765 add_listen_addr(options, arg, 0);
770 fatal("%s line %d: bad address:port usage",
772 p = cleanhostname(p);
775 else if ((port = a2port(arg)) == 0)
776 fatal("%s line %d: bad port number", filename, linenum);
778 add_listen_addr(options, p, port);
784 if (!arg || *arg == '\0')
785 fatal("%s line %d: missing address family.",
787 intptr = &options->address_family;
788 if (options->listen_addrs != NULL)
789 fatal("%s line %d: address family must be specified before "
790 "ListenAddress.", filename, linenum);
791 if (strcasecmp(arg, "inet") == 0)
793 else if (strcasecmp(arg, "inet6") == 0)
795 else if (strcasecmp(arg, "any") == 0)
798 fatal("%s line %d: unsupported address family \"%s\".",
799 filename, linenum, arg);
805 intptr = &options->num_host_key_files;
806 if (*intptr >= MAX_HOSTKEYS)
807 fatal("%s line %d: too many host keys specified (max %d).",
808 filename, linenum, MAX_HOSTKEYS);
809 charptr = &options->host_key_files[*intptr];
812 if (!arg || *arg == '\0')
813 fatal("%s line %d: missing file name.",
815 if (*activep && *charptr == NULL) {
816 *charptr = tilde_expand_filename(arg, getuid());
817 /* increase optional counter */
819 *intptr = *intptr + 1;
824 charptr = &options->pid_file;
827 case sPermitRootLogin:
828 intptr = &options->permit_root_login;
830 if (!arg || *arg == '\0')
831 fatal("%s line %d: missing yes/"
832 "without-password/forced-commands-only/no "
833 "argument.", filename, linenum);
834 value = 0; /* silence compiler */
835 if (strcmp(arg, "without-password") == 0)
836 value = PERMIT_NO_PASSWD;
837 else if (strcmp(arg, "forced-commands-only") == 0)
838 value = PERMIT_FORCED_ONLY;
839 else if (strcmp(arg, "yes") == 0)
841 else if (strcmp(arg, "no") == 0)
844 fatal("%s line %d: Bad yes/"
845 "without-password/forced-commands-only/no "
846 "argument: %s", filename, linenum, arg);
852 intptr = &options->ignore_rhosts;
855 if (!arg || *arg == '\0')
856 fatal("%s line %d: missing yes/no argument.",
858 value = 0; /* silence compiler */
859 if (strcmp(arg, "yes") == 0)
861 else if (strcmp(arg, "no") == 0)
864 fatal("%s line %d: Bad yes/no argument: %s",
865 filename, linenum, arg);
866 if (*activep && *intptr == -1)
871 intptr = &options->none_enabled;
875 intptr = &options->tcp_rcv_buf_poll;
879 intptr = &options->hpn_disabled;
883 intptr = &options->hpn_buffer_size;
886 case sIgnoreUserKnownHosts:
887 intptr = &options->ignore_user_known_hosts;
890 case sRhostsRSAAuthentication:
891 intptr = &options->rhosts_rsa_authentication;
894 case sHostbasedAuthentication:
895 intptr = &options->hostbased_authentication;
898 case sHostbasedUsesNameFromPacketOnly:
899 intptr = &options->hostbased_uses_name_from_packet_only;
902 case sRSAAuthentication:
903 intptr = &options->rsa_authentication;
906 case sPubkeyAuthentication:
907 intptr = &options->pubkey_authentication;
910 case sKerberosAuthentication:
911 intptr = &options->kerberos_authentication;
914 case sKerberosOrLocalPasswd:
915 intptr = &options->kerberos_or_local_passwd;
918 case sKerberosTicketCleanup:
919 intptr = &options->kerberos_ticket_cleanup;
922 case sKerberosGetAFSToken:
923 intptr = &options->kerberos_get_afs_token;
926 case sGssAuthentication:
927 intptr = &options->gss_authentication;
931 intptr = &options->gss_keyex;
934 case sGssCleanupCreds:
935 intptr = &options->gss_cleanup_creds;
938 case sGssStrictAcceptor:
939 intptr = &options->gss_strict_acceptor;
942 case sPasswordAuthentication:
943 intptr = &options->password_authentication;
946 case sKbdInteractiveAuthentication:
947 intptr = &options->kbd_interactive_authentication;
950 case sChallengeResponseAuthentication:
951 intptr = &options->challenge_response_authentication;
955 intptr = &options->print_motd;
959 intptr = &options->print_lastlog;
963 intptr = &options->x11_forwarding;
966 case sX11DisplayOffset:
967 intptr = &options->x11_display_offset;
970 case sX11UseLocalhost:
971 intptr = &options->x11_use_localhost;
975 charptr = &options->xauth_location;
979 intptr = &options->strict_modes;
983 intptr = &options->tcp_keep_alive;
987 intptr = &options->permit_empty_passwd;
990 case sPermitUserEnvironment:
991 intptr = &options->permit_user_env;
995 intptr = &options->use_login;
999 intptr = &options->compression;
1000 arg = strdelim(&cp);
1001 if (!arg || *arg == '\0')
1002 fatal("%s line %d: missing yes/no/delayed "
1003 "argument.", filename, linenum);
1004 value = 0; /* silence compiler */
1005 if (strcmp(arg, "delayed") == 0)
1006 value = COMP_DELAYED;
1007 else if (strcmp(arg, "yes") == 0)
1009 else if (strcmp(arg, "no") == 0)
1012 fatal("%s line %d: Bad yes/no/delayed "
1013 "argument: %s", filename, linenum, arg);
1019 intptr = &options->gateway_ports;
1020 arg = strdelim(&cp);
1021 if (!arg || *arg == '\0')
1022 fatal("%s line %d: missing yes/no/clientspecified "
1023 "argument.", filename, linenum);
1024 value = 0; /* silence compiler */
1025 if (strcmp(arg, "clientspecified") == 0)
1027 else if (strcmp(arg, "yes") == 0)
1029 else if (strcmp(arg, "no") == 0)
1032 fatal("%s line %d: Bad yes/no/clientspecified "
1033 "argument: %s", filename, linenum, arg);
1039 intptr = &options->use_dns;
1043 intptr = (int *) &options->log_facility;
1044 arg = strdelim(&cp);
1045 value = log_facility_number(arg);
1046 if (value == SYSLOG_FACILITY_NOT_SET)
1047 fatal("%.200s line %d: unsupported log facility '%s'",
1048 filename, linenum, arg ? arg : "<NONE>");
1050 *intptr = (SyslogFacility) value;
1054 intptr = (int *) &options->log_level;
1055 arg = strdelim(&cp);
1056 value = log_level_number(arg);
1057 if (value == SYSLOG_LEVEL_NOT_SET)
1058 fatal("%.200s line %d: unsupported log level '%s'",
1059 filename, linenum, arg ? arg : "<NONE>");
1061 *intptr = (LogLevel) value;
1064 case sAllowTcpForwarding:
1065 intptr = &options->allow_tcp_forwarding;
1068 case sUsePrivilegeSeparation:
1069 intptr = &use_privsep;
1073 while ((arg = strdelim(&cp)) && *arg != '\0') {
1074 if (options->num_allow_users >= MAX_ALLOW_USERS)
1075 fatal("%s line %d: too many allow users.",
1077 options->allow_users[options->num_allow_users++] =
1083 while ((arg = strdelim(&cp)) && *arg != '\0') {
1084 if (options->num_deny_users >= MAX_DENY_USERS)
1085 fatal("%s line %d: too many deny users.",
1087 options->deny_users[options->num_deny_users++] =
1093 while ((arg = strdelim(&cp)) && *arg != '\0') {
1094 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1095 fatal("%s line %d: too many allow groups.",
1097 options->allow_groups[options->num_allow_groups++] =
1103 while ((arg = strdelim(&cp)) && *arg != '\0') {
1104 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1105 fatal("%s line %d: too many deny groups.",
1107 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1112 arg = strdelim(&cp);
1113 if (!arg || *arg == '\0')
1114 fatal("%s line %d: Missing argument.", filename, linenum);
1115 if (!ciphers_valid(arg))
1116 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1117 filename, linenum, arg ? arg : "<NONE>");
1118 if (options->ciphers == NULL)
1119 options->ciphers = xstrdup(arg);
1123 arg = strdelim(&cp);
1124 if (!arg || *arg == '\0')
1125 fatal("%s line %d: Missing argument.", filename, linenum);
1126 if (!mac_valid(arg))
1127 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1128 filename, linenum, arg ? arg : "<NONE>");
1129 if (options->macs == NULL)
1130 options->macs = xstrdup(arg);
1134 intptr = &options->protocol;
1135 arg = strdelim(&cp);
1136 if (!arg || *arg == '\0')
1137 fatal("%s line %d: Missing argument.", filename, linenum);
1138 value = proto_spec(arg);
1139 if (value == SSH_PROTO_UNKNOWN)
1140 fatal("%s line %d: Bad protocol spec '%s'.",
1141 filename, linenum, arg ? arg : "<NONE>");
1142 if (*intptr == SSH_PROTO_UNKNOWN)
1147 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1148 fatal("%s line %d: too many subsystems defined.",
1151 arg = strdelim(&cp);
1152 if (!arg || *arg == '\0')
1153 fatal("%s line %d: Missing subsystem name.",
1156 arg = strdelim(&cp);
1159 for (i = 0; i < options->num_subsystems; i++)
1160 if (strcmp(arg, options->subsystem_name[i]) == 0)
1161 fatal("%s line %d: Subsystem '%s' already defined.",
1162 filename, linenum, arg);
1163 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1164 arg = strdelim(&cp);
1165 if (!arg || *arg == '\0')
1166 fatal("%s line %d: Missing subsystem command.",
1168 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1170 /* Collect arguments (separate to executable) */
1172 len = strlen(p) + 1;
1173 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1174 len += 1 + strlen(arg);
1175 p = xrealloc(p, 1, len);
1176 strlcat(p, " ", len);
1177 strlcat(p, arg, len);
1179 options->subsystem_args[options->num_subsystems] = p;
1180 options->num_subsystems++;
1184 arg = strdelim(&cp);
1185 if (!arg || *arg == '\0')
1186 fatal("%s line %d: Missing MaxStartups spec.",
1188 if ((n = sscanf(arg, "%d:%d:%d",
1189 &options->max_startups_begin,
1190 &options->max_startups_rate,
1191 &options->max_startups)) == 3) {
1192 if (options->max_startups_begin >
1193 options->max_startups ||
1194 options->max_startups_rate > 100 ||
1195 options->max_startups_rate < 1)
1196 fatal("%s line %d: Illegal MaxStartups spec.",
1199 fatal("%s line %d: Illegal MaxStartups spec.",
1202 options->max_startups = options->max_startups_begin;
1206 intptr = &options->max_authtries;
1210 charptr = &options->banner;
1211 goto parse_filename;
1213 * These options can contain %X options expanded at
1214 * connect time, so that you can specify paths like:
1216 * AuthorizedKeysFile /etc/ssh_keys/%u
1218 case sAuthorizedKeysFile:
1219 case sAuthorizedKeysFile2:
1220 charptr = (opcode == sAuthorizedKeysFile) ?
1221 &options->authorized_keys_file :
1222 &options->authorized_keys_file2;
1223 goto parse_filename;
1225 case sClientAliveInterval:
1226 intptr = &options->client_alive_interval;
1229 case sClientAliveCountMax:
1230 intptr = &options->client_alive_count_max;
1234 while ((arg = strdelim(&cp)) && *arg != '\0') {
1235 if (strchr(arg, '=') != NULL)
1236 fatal("%s line %d: Invalid environment name.",
1238 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1239 fatal("%s line %d: too many allow env.",
1243 options->accept_env[options->num_accept_env++] =
1249 intptr = &options->permit_tun;
1250 arg = strdelim(&cp);
1251 if (!arg || *arg == '\0')
1252 fatal("%s line %d: Missing yes/point-to-point/"
1253 "ethernet/no argument.", filename, linenum);
1254 value = 0; /* silence compiler */
1255 if (strcasecmp(arg, "ethernet") == 0)
1256 value = SSH_TUNMODE_ETHERNET;
1257 else if (strcasecmp(arg, "point-to-point") == 0)
1258 value = SSH_TUNMODE_POINTOPOINT;
1259 else if (strcasecmp(arg, "yes") == 0)
1260 value = SSH_TUNMODE_YES;
1261 else if (strcasecmp(arg, "no") == 0)
1262 value = SSH_TUNMODE_NO;
1264 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1265 "no argument: %s", filename, linenum, arg);
1272 fatal("Match directive not supported as a command-line "
1274 value = match_cfg_line(&cp, linenum, user, host, address);
1276 fatal("%s line %d: Bad Match condition", filename,
1282 arg = strdelim(&cp);
1283 if (!arg || *arg == '\0')
1284 fatal("%s line %d: missing PermitOpen specification",
1286 if (strcmp(arg, "any") == 0) {
1288 channel_clear_adm_permitted_opens();
1289 options->num_permitted_opens = 0;
1293 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1296 fatal("%s line %d: missing host in PermitOpen",
1298 p = cleanhostname(p);
1299 if (arg == NULL || (port = a2port(arg)) == 0)
1300 fatal("%s line %d: bad port number in "
1301 "PermitOpen", filename, linenum);
1302 if (*activep && options->num_permitted_opens == -1) {
1303 channel_clear_adm_permitted_opens();
1304 options->num_permitted_opens =
1305 channel_add_adm_permitted_opens(p, port);
1312 fatal("%.200s line %d: Missing argument.", filename,
1314 len = strspn(cp, WHITESPACE);
1315 if (*activep && options->adm_forced_command == NULL)
1316 options->adm_forced_command = xstrdup(cp + len);
1320 logit("%s line %d: Deprecated option %s",
1321 filename, linenum, arg);
1323 arg = strdelim(&cp);
1327 logit("%s line %d: Unsupported option %s",
1328 filename, linenum, arg);
1330 arg = strdelim(&cp);
1334 fatal("%s line %d: Missing handler for opcode %s (%d)",
1335 filename, linenum, arg, opcode);
1337 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1338 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1339 filename, linenum, arg);
1343 /* Reads the server configuration file. */
1346 load_server_config(const char *filename, Buffer *conf)
1348 char line[1024], *cp;
1351 debug2("%s: filename %s", __func__, filename);
1352 if ((f = fopen(filename, "r")) == NULL) {
1357 while (fgets(line, sizeof(line), f)) {
1359 * Trim out comments and strip whitespace
1360 * NB - preserve newlines, they are needed to reproduce
1361 * line numbers later for error messages
1363 if ((cp = strchr(line, '#')) != NULL)
1364 memcpy(cp, "\n", 2);
1365 cp = line + strspn(line, " \t\r");
1367 buffer_append(conf, cp, strlen(cp));
1369 buffer_append(conf, "\0", 1);
1371 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1375 parse_server_match_config(ServerOptions *options, const char *user,
1376 const char *host, const char *address)
1380 initialize_server_options(&mo);
1381 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1382 copy_set_server_options(options, &mo);
1385 /* Copy any (supported) values that are set */
1387 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1389 if (src->allow_tcp_forwarding != -1)
1390 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1391 if (src->gateway_ports != -1)
1392 dst->gateway_ports = src->gateway_ports;
1393 if (src->adm_forced_command != NULL) {
1394 if (dst->adm_forced_command != NULL)
1395 xfree(dst->adm_forced_command);
1396 dst->adm_forced_command = src->adm_forced_command;
1398 if (src->x11_display_offset != -1)
1399 dst->x11_display_offset = src->x11_display_offset;
1400 if (src->x11_forwarding != -1)
1401 dst->x11_forwarding = src->x11_forwarding;
1402 if (src->x11_use_localhost != -1)
1403 dst->x11_use_localhost = src->x11_use_localhost;
1407 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1408 const char *user, const char *host, const char *address)
1410 int active, linenum, bad_options = 0;
1411 char *cp, *obuf, *cbuf;
1413 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1415 obuf = cbuf = xstrdup(buffer_ptr(conf));
1416 active = user ? 0 : 1;
1418 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1419 if (process_server_config_line(options, cp, filename,
1420 linenum++, &active, user, host, address) != 0)
1424 if (bad_options > 0)
1425 fatal("%s: terminating, %d bad configuration options",
1426 filename, bad_options);