]> andersk Git - openssh.git/blame - servconf.c
- dtucker@cvs.openbsd.org 2006/07/18 08:22:23
[openssh.git] / servconf.c
CommitLineData
2fefbadf 1/* $OpenBSD: servconf.c,v 1.156 2006/07/17 12:06:00 dtucker Exp $ */
8efc0c15 2/*
5260325f 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
6ae2364d 5 *
bcbf86ec 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".
5260325f 11 */
8efc0c15 12
13#include "includes.h"
8efc0c15 14
5b04a8bf 15#include <sys/types.h>
16#include <sys/socket.h>
17
c8dfff33 18#if defined(HAVE_NETDB_H)
19# include <netdb.h>
20#endif
5188ba17 21#include <unistd.h>
c8dfff33 22
8efc0c15 23#include "ssh.h"
42f11eb2 24#include "log.h"
8efc0c15 25#include "servconf.h"
26#include "xmalloc.h"
a8be9f80 27#include "compat.h"
42f11eb2 28#include "pathnames.h"
42f11eb2 29#include "misc.h"
30#include "cipher.h"
b2552997 31#include "kex.h"
32#include "mac.h"
d231781a 33#include "match.h"
2fefbadf 34#include "channels.h"
42f11eb2 35
396c147e 36static void add_listen_addr(ServerOptions *, char *, u_short);
37static void add_one_listen_addr(ServerOptions *, char *, u_short);
48e671d5 38
1853d1ef 39/* Use of privilege separation or not */
40extern int use_privsep;
d231781a 41extern Buffer cfg;
42f11eb2 42
8efc0c15 43/* Initializes the server options to their default values. */
44
6ae2364d 45void
5260325f 46initialize_server_options(ServerOptions *options)
8efc0c15 47{
5260325f 48 memset(options, 0, sizeof(*options));
e15895cd 49
50 /* Portable-specific options */
7fceb20d 51 options->use_pam = -1;
e15895cd 52
53 /* Standard Options */
48e671d5 54 options->num_ports = 0;
55 options->ports_from_cmdline = 0;
56 options->listen_addrs = NULL;
31b41ceb 57 options->address_family = -1;
fa08c86b 58 options->num_host_key_files = 0;
0fbe8c74 59 options->pid_file = NULL;
5260325f 60 options->server_key_bits = -1;
61 options->login_grace_time = -1;
62 options->key_regeneration_time = -1;
15853e93 63 options->permit_root_login = PERMIT_NOT_SET;
5260325f 64 options->ignore_rhosts = -1;
65 options->ignore_user_known_hosts = -1;
66 options->print_motd = -1;
4f4648f9 67 options->print_lastlog = -1;
5260325f 68 options->x11_forwarding = -1;
69 options->x11_display_offset = -1;
e6e573bd 70 options->x11_use_localhost = -1;
fa649821 71 options->xauth_location = NULL;
5260325f 72 options->strict_modes = -1;
fd573618 73 options->tcp_keep_alive = -1;
5eaf8578 74 options->log_facility = SYSLOG_FACILITY_NOT_SET;
75 options->log_level = SYSLOG_LEVEL_NOT_SET;
5260325f 76 options->rhosts_rsa_authentication = -1;
8002af61 77 options->hostbased_authentication = -1;
78 options->hostbased_uses_name_from_packet_only = -1;
5260325f 79 options->rsa_authentication = -1;
fa08c86b 80 options->pubkey_authentication = -1;
5260325f 81 options->kerberos_authentication = -1;
82 options->kerberos_or_local_passwd = -1;
83 options->kerberos_ticket_cleanup = -1;
a1e30b47 84 options->kerberos_get_afs_token = -1;
7364bd04 85 options->gss_authentication=-1;
86 options->gss_cleanup_creds = -1;
5260325f 87 options->password_authentication = -1;
94ec8c6b 88 options->kbd_interactive_authentication = -1;
5ba55ada 89 options->challenge_response_authentication = -1;
5260325f 90 options->permit_empty_passwd = -1;
f00bab84 91 options->permit_user_env = -1;
5260325f 92 options->use_login = -1;
636f76ca 93 options->compression = -1;
33de75a3 94 options->allow_tcp_forwarding = -1;
5260325f 95 options->num_allow_users = 0;
96 options->num_deny_users = 0;
97 options->num_allow_groups = 0;
98 options->num_deny_groups = 0;
a8be9f80 99 options->ciphers = NULL;
b2552997 100 options->macs = NULL;
a8be9f80 101 options->protocol = SSH_PROTO_UNKNOWN;
1d1ffb87 102 options->gateway_ports = -1;
38c295d6 103 options->num_subsystems = 0;
c345cf9d 104 options->max_startups_begin = -1;
105 options->max_startups_rate = -1;
089fbbd2 106 options->max_startups = -1;
af4bd935 107 options->max_authtries = -1;
eea39c02 108 options->banner = NULL;
c5a7d788 109 options->use_dns = -1;
3ffc6336 110 options->client_alive_interval = -1;
111 options->client_alive_count_max = -1;
c8445989 112 options->authorized_keys_file = NULL;
113 options->authorized_keys_file2 = NULL;
61a2c1da 114 options->num_accept_env = 0;
d20f3c9e 115 options->permit_tun = -1;
8efc0c15 116}
117
6ae2364d 118void
5260325f 119fill_default_server_options(ServerOptions *options)
8efc0c15 120{
e15895cd 121 /* Portable-specific options */
7fceb20d 122 if (options->use_pam == -1)
0a23d79f 123 options->use_pam = 0;
e15895cd 124
125 /* Standard Options */
fa08c86b 126 if (options->protocol == SSH_PROTO_UNKNOWN)
127 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
128 if (options->num_host_key_files == 0) {
129 /* fill default hostkeys for protocols */
130 if (options->protocol & SSH_PROTO_1)
0f84fe37 131 options->host_key_files[options->num_host_key_files++] =
132 _PATH_HOST_KEY_FILE;
133 if (options->protocol & SSH_PROTO_2) {
134 options->host_key_files[options->num_host_key_files++] =
135 _PATH_HOST_RSA_KEY_FILE;
136 options->host_key_files[options->num_host_key_files++] =
137 _PATH_HOST_DSA_KEY_FILE;
138 }
fa08c86b 139 }
48e671d5 140 if (options->num_ports == 0)
141 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
142 if (options->listen_addrs == NULL)
2d2a2c65 143 add_listen_addr(options, NULL, 0);
0fbe8c74 144 if (options->pid_file == NULL)
42f11eb2 145 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
5260325f 146 if (options->server_key_bits == -1)
147 options->server_key_bits = 768;
148 if (options->login_grace_time == -1)
3445ca02 149 options->login_grace_time = 120;
5260325f 150 if (options->key_regeneration_time == -1)
151 options->key_regeneration_time = 3600;
15853e93 152 if (options->permit_root_login == PERMIT_NOT_SET)
153 options->permit_root_login = PERMIT_YES;
5260325f 154 if (options->ignore_rhosts == -1)
c8d54615 155 options->ignore_rhosts = 1;
5260325f 156 if (options->ignore_user_known_hosts == -1)
157 options->ignore_user_known_hosts = 0;
5260325f 158 if (options->print_motd == -1)
159 options->print_motd = 1;
4f4648f9 160 if (options->print_lastlog == -1)
161 options->print_lastlog = 1;
5260325f 162 if (options->x11_forwarding == -1)
c8d54615 163 options->x11_forwarding = 0;
5260325f 164 if (options->x11_display_offset == -1)
c8d54615 165 options->x11_display_offset = 10;
e6e573bd 166 if (options->x11_use_localhost == -1)
167 options->x11_use_localhost = 1;
fa649821 168 if (options->xauth_location == NULL)
fd9ede94 169 options->xauth_location = _PATH_XAUTH;
5260325f 170 if (options->strict_modes == -1)
171 options->strict_modes = 1;
fd573618 172 if (options->tcp_keep_alive == -1)
173 options->tcp_keep_alive = 1;
5eaf8578 174 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
5260325f 175 options->log_facility = SYSLOG_FACILITY_AUTH;
5eaf8578 176 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
59c97189 177 options->log_level = SYSLOG_LEVEL_INFO;
5260325f 178 if (options->rhosts_rsa_authentication == -1)
c8d54615 179 options->rhosts_rsa_authentication = 0;
8002af61 180 if (options->hostbased_authentication == -1)
181 options->hostbased_authentication = 0;
182 if (options->hostbased_uses_name_from_packet_only == -1)
183 options->hostbased_uses_name_from_packet_only = 0;
5260325f 184 if (options->rsa_authentication == -1)
185 options->rsa_authentication = 1;
fa08c86b 186 if (options->pubkey_authentication == -1)
187 options->pubkey_authentication = 1;
5260325f 188 if (options->kerberos_authentication == -1)
eadc806d 189 options->kerberos_authentication = 0;
5260325f 190 if (options->kerberos_or_local_passwd == -1)
191 options->kerberos_or_local_passwd = 1;
192 if (options->kerberos_ticket_cleanup == -1)
193 options->kerberos_ticket_cleanup = 1;
a1e30b47 194 if (options->kerberos_get_afs_token == -1)
195 options->kerberos_get_afs_token = 0;
7364bd04 196 if (options->gss_authentication == -1)
197 options->gss_authentication = 0;
198 if (options->gss_cleanup_creds == -1)
199 options->gss_cleanup_creds = 1;
5260325f 200 if (options->password_authentication == -1)
201 options->password_authentication = 1;
94ec8c6b 202 if (options->kbd_interactive_authentication == -1)
203 options->kbd_interactive_authentication = 0;
5ba55ada 204 if (options->challenge_response_authentication == -1)
205 options->challenge_response_authentication = 1;
5260325f 206 if (options->permit_empty_passwd == -1)
c8d54615 207 options->permit_empty_passwd = 0;
f00bab84 208 if (options->permit_user_env == -1)
209 options->permit_user_env = 0;
5260325f 210 if (options->use_login == -1)
211 options->use_login = 0;
636f76ca 212 if (options->compression == -1)
07200973 213 options->compression = COMP_DELAYED;
33de75a3 214 if (options->allow_tcp_forwarding == -1)
215 options->allow_tcp_forwarding = 1;
1d1ffb87 216 if (options->gateway_ports == -1)
217 options->gateway_ports = 0;
089fbbd2 218 if (options->max_startups == -1)
219 options->max_startups = 10;
c345cf9d 220 if (options->max_startups_rate == -1)
221 options->max_startups_rate = 100; /* 100% */
222 if (options->max_startups_begin == -1)
223 options->max_startups_begin = options->max_startups;
af4bd935 224 if (options->max_authtries == -1)
225 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
c5a7d788 226 if (options->use_dns == -1)
227 options->use_dns = 1;
3ffc6336 228 if (options->client_alive_interval == -1)
184eed6a 229 options->client_alive_interval = 0;
3ffc6336 230 if (options->client_alive_count_max == -1)
231 options->client_alive_count_max = 3;
5df83e07 232 if (options->authorized_keys_file2 == NULL) {
233 /* authorized_keys_file2 falls back to authorized_keys_file */
234 if (options->authorized_keys_file != NULL)
235 options->authorized_keys_file2 = options->authorized_keys_file;
236 else
237 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
238 }
239 if (options->authorized_keys_file == NULL)
240 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
d20f3c9e 241 if (options->permit_tun == -1)
a4f24bf8 242 options->permit_tun = SSH_TUNMODE_NO;
1853d1ef 243
2ee1b704 244 /* Turn privilege separation on by default */
1853d1ef 245 if (use_privsep == -1)
2ee1b704 246 use_privsep = 1;
e299a298 247
4165b82e 248#ifndef HAVE_MMAP
e299a298 249 if (use_privsep && options->compression == 1) {
250 error("This platform does not support both privilege "
251 "separation and compression");
252 error("Compression disabled");
253 options->compression = 0;
254 }
255#endif
256
8efc0c15 257}
258
8efc0c15 259/* Keyword tokens. */
5260325f 260typedef enum {
261 sBadOption, /* == unknown option */
e15895cd 262 /* Portable-specific options */
7fceb20d 263 sUsePAM,
e15895cd 264 /* Standard Options */
5260325f 265 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
266 sPermitRootLogin, sLogFacility, sLogLevel,
0598d99d 267 sRhostsRSAAuthentication, sRSAAuthentication,
5260325f 268 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
a1e30b47 269 sKerberosGetAFSToken,
1c590258 270 sKerberosTgtPassing, sChallengeResponseAuthentication,
31b41ceb 271 sPasswordAuthentication, sKbdInteractiveAuthentication,
272 sListenAddress, sAddressFamily,
4f4648f9 273 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
e6e573bd 274 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
fd573618 275 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
f00bab84 276 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
33de75a3 277 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
b2552997 278 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
af4bd935 279 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
280 sMaxStartups, sMaxAuthTries,
c5a7d788 281 sBanner, sUseDNS, sHostbasedAuthentication,
184eed6a 282 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
c8445989 283 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
d20f3c9e 284 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
2fefbadf 285 sMatch, sPermitOpen,
2ea6de2b 286 sUsePrivilegeSeparation,
a2144546 287 sDeprecated, sUnsupported
8efc0c15 288} ServerOpCodes;
289
d231781a 290#define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
291#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
292#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
293
8efc0c15 294/* Textual representation of the tokens. */
5260325f 295static struct {
296 const char *name;
297 ServerOpCodes opcode;
d231781a 298 u_int flags;
5260325f 299} keywords[] = {
e15895cd 300 /* Portable-specific options */
b06b11ad 301#ifdef USE_PAM
d231781a 302 { "usepam", sUsePAM, SSHCFG_GLOBAL },
b06b11ad 303#else
d231781a 304 { "usepam", sUnsupported, SSHCFG_GLOBAL },
b06b11ad 305#endif
d231781a 306 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
e15895cd 307 /* Standard Options */
d231781a 308 { "port", sPort, SSHCFG_GLOBAL },
309 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
310 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
311 { "pidfile", sPidFile, SSHCFG_GLOBAL },
312 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
313 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
314 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
315 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
316 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
317 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
318 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
319 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
320 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
321 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
322 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
323 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
324 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
1c590258 325#ifdef KRB5
d231781a 326 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
327 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
328 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
bcfcc5f9 329#ifdef USE_AFS
d231781a 330 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
309af4e5 331#else
d231781a 332 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
309af4e5 333#endif
a2144546 334#else
d231781a 335 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
336 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
337 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
338 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
a2144546 339#endif
d231781a 340 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
341 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
7364bd04 342#ifdef GSSAPI
d231781a 343 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
344 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
7364bd04 345#else
d231781a 346 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
347 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
7364bd04 348#endif
d231781a 349 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
350 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
351 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
352 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
353 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
354 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
355 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
356 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
357 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
358 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
359 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
360 { "x11forwarding", sX11Forwarding, SSHCFG_GLOBAL },
361 { "x11displayoffset", sX11DisplayOffset, SSHCFG_GLOBAL },
362 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_GLOBAL },
363 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
364 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
365 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
366 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
367 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
368 { "compression", sCompression, SSHCFG_GLOBAL },
369 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
370 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
371 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
372 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
373 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
374 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
375 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
376 { "ciphers", sCiphers, SSHCFG_GLOBAL },
377 { "macs", sMacs, SSHCFG_GLOBAL },
378 { "protocol", sProtocol, SSHCFG_GLOBAL },
379 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
380 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
381 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
382 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
383 { "banner", sBanner, SSHCFG_GLOBAL },
384 { "usedns", sUseDNS, SSHCFG_GLOBAL },
385 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
386 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
387 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
388 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
389 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
390 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
391 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
392 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
393 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
2fefbadf 394 { "match", sMatch, SSHCFG_ALL },
395 { "permitopen", sPermitOpen, SSHCFG_ALL },
d231781a 396 { NULL, sBadOption, 0 }
8efc0c15 397};
398
aa3378df 399/*
6be9a5e8 400 * Returns the number of the token pointed to by cp or sBadOption.
aa3378df 401 */
8efc0c15 402
6ae2364d 403static ServerOpCodes
5260325f 404parse_token(const char *cp, const char *filename,
d231781a 405 int linenum, u_int *flags)
8efc0c15 406{
1e3b8b07 407 u_int i;
8efc0c15 408
5260325f 409 for (i = 0; keywords[i].name; i++)
d231781a 410 if (strcasecmp(cp, keywords[i].name) == 0) {
411 *flags = keywords[i].flags;
5260325f 412 return keywords[i].opcode;
d231781a 413 }
8efc0c15 414
b7c70970 415 error("%s: line %d: Bad configuration option: %s",
416 filename, linenum, cp);
5260325f 417 return sBadOption;
8efc0c15 418}
419
396c147e 420static void
2d2a2c65 421add_listen_addr(ServerOptions *options, char *addr, u_short port)
48e671d5 422{
2ceb8101 423 u_int i;
48e671d5 424
425 if (options->num_ports == 0)
426 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
31b41ceb 427 if (options->address_family == -1)
428 options->address_family = AF_UNSPEC;
2d2a2c65 429 if (port == 0)
d11c1288 430 for (i = 0; i < options->num_ports; i++)
431 add_one_listen_addr(options, addr, options->ports[i]);
432 else
2d2a2c65 433 add_one_listen_addr(options, addr, port);
d11c1288 434}
435
396c147e 436static void
d11c1288 437add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
438{
439 struct addrinfo hints, *ai, *aitop;
440 char strport[NI_MAXSERV];
441 int gaierr;
442
443 memset(&hints, 0, sizeof(hints));
31b41ceb 444 hints.ai_family = options->address_family;
d11c1288 445 hints.ai_socktype = SOCK_STREAM;
446 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
7528d467 447 snprintf(strport, sizeof strport, "%u", port);
d11c1288 448 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
449 fatal("bad addr or host: %s (%s)",
450 addr ? addr : "<NULL>",
451 gai_strerror(gaierr));
452 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
453 ;
454 ai->ai_next = options->listen_addrs;
455 options->listen_addrs = aitop;
48e671d5 456}
457
d231781a 458/*
459 * The strategy for the Match blocks is that the config file is parsed twice.
460 *
461 * The first time is at startup. activep is initialized to 1 and the
462 * directives in the global context are processed and acted on. Hitting a
463 * Match directive unsets activep and the directives inside the block are
464 * checked for syntax only.
465 *
466 * The second time is after a connection has been established but before
467 * authentication. activep is initialized to 2 and global config directives
468 * are ignored since they have already been processed. If the criteria in a
469 * Match block is met, activep is set and the subsequent directives
470 * processed and actioned until EOF or another Match block unsets it. Any
471 * options set are copied into the main server config.
472 *
473 * Potential additions/improvements:
474 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
475 *
476 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
477 * Match Address 192.168.0.*
478 * Tag trusted
479 * Match Group wheel
480 * Tag trusted
481 * Match Tag trusted
482 * AllowTcpForwarding yes
483 * GatewayPorts clientspecified
484 * [...]
485 *
486 * - Add a PermittedChannelRequests directive
487 * Match Group shell
488 * PermittedChannelRequests session,forwarded-tcpip
489 */
490
491static int
492match_cfg_line(char **condition, int line, const char *user, const char *host,
493 const char *address)
494{
495 int result = 1;
496 char *arg, *attrib, *cp = *condition;
497 size_t len;
498
499 if (user == NULL)
500 debug3("checking syntax for 'Match %s'", cp);
501 else
502 debug3("checking match for '%s' user %s host %s addr %s", cp,
503 user ? user : "(null)", host ? host : "(null)",
504 address ? address : "(null)");
505
506 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
507 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
508 error("Missing Match criteria for %s", attrib);
509 return -1;
510 }
511 len = strlen(arg);
512 if (strcasecmp(attrib, "user") == 0) {
513 if (!user) {
514 result = 0;
515 continue;
516 }
517 if (match_pattern_list(user, arg, len, 0) != 1)
518 result = 0;
519 else
520 debug("user %.100s matched 'User %.100s' at "
521 "line %d", user, arg, line);
522 } else if (strcasecmp(attrib, "host") == 0) {
523 if (!host) {
524 result = 0;
525 continue;
526 }
527 if (match_hostname(host, arg, len) != 1)
528 result = 0;
529 else
530 debug("connection from %.100s matched 'Host "
531 "%.100s' at line %d", host, arg, line);
532 } else if (strcasecmp(attrib, "address") == 0) {
533 debug("address '%s' arg '%s'", address, arg);
534 if (!address) {
535 result = 0;
536 continue;
537 }
538 if (match_hostname(address, arg, len) != 1)
539 result = 0;
540 else
541 debug("connection from %.100s matched 'Address "
542 "%.100s' at line %d", address, arg, line);
543 } else {
544 error("Unsupported Match attribute %s", attrib);
545 return -1;
546 }
547 }
548 if (user != NULL)
549 debug3("match %sfound", result ? "" : "not ");
550 *condition = cp;
551 return result;
552}
553
2717fa0f 554int
555process_server_config_line(ServerOptions *options, char *line,
d231781a 556 const char *filename, int linenum, int *activep, const char *user,
557 const char *host, const char *address)
8efc0c15 558{
d11c1288 559 char *cp, **charptr, *arg, *p;
d231781a 560 int cmdline = 0, *intptr, value, n;
5260325f 561 ServerOpCodes opcode;
3867aa0a 562 u_short port;
d231781a 563 u_int i, flags = 0;
d66ce1a1 564 size_t len;
5260325f 565
2717fa0f 566 cp = line;
0f8cd5a6 567 if ((arg = strdelim(&cp)) == NULL)
88299971 568 return 0;
2717fa0f 569 /* Ignore leading whitespace */
570 if (*arg == '\0')
704b1659 571 arg = strdelim(&cp);
2717fa0f 572 if (!arg || !*arg || *arg == '#')
573 return 0;
574 intptr = NULL;
575 charptr = NULL;
d231781a 576 opcode = parse_token(arg, filename, linenum, &flags);
577
578 if (activep == NULL) { /* We are processing a command line directive */
579 cmdline = 1;
580 activep = &cmdline;
581 }
582 if (*activep && opcode != sMatch)
583 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
584 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
585 if (user == NULL) {
586 fatal("%s line %d: Directive '%s' is not allowed "
587 "within a Match block", filename, linenum, arg);
588 } else { /* this is a directive we have already processed */
589 while (arg)
590 arg = strdelim(&cp);
591 return 0;
592 }
593 }
594
2717fa0f 595 switch (opcode) {
596 /* Portable-specific options */
7fceb20d 597 case sUsePAM:
598 intptr = &options->use_pam;
2717fa0f 599 goto parse_flag;
48e671d5 600
2717fa0f 601 /* Standard Options */
602 case sBadOption:
603 return -1;
604 case sPort:
605 /* ignore ports from configfile if cmdline specifies ports */
606 if (options->ports_from_cmdline)
607 return 0;
608 if (options->listen_addrs != NULL)
609 fatal("%s line %d: ports must be specified before "
3a454b6a 610 "ListenAddress.", filename, linenum);
2717fa0f 611 if (options->num_ports >= MAX_PORTS)
612 fatal("%s line %d: too many ports.",
613 filename, linenum);
614 arg = strdelim(&cp);
615 if (!arg || *arg == '\0')
616 fatal("%s line %d: missing port number.",
617 filename, linenum);
618 options->ports[options->num_ports++] = a2port(arg);
619 if (options->ports[options->num_ports-1] == 0)
620 fatal("%s line %d: Badly formatted port number.",
621 filename, linenum);
622 break;
623
624 case sServerKeyBits:
625 intptr = &options->server_key_bits;
5260325f 626parse_int:
2717fa0f 627 arg = strdelim(&cp);
628 if (!arg || *arg == '\0')
629 fatal("%s line %d: missing integer value.",
630 filename, linenum);
631 value = atoi(arg);
d231781a 632 if (*activep && *intptr == -1)
2717fa0f 633 *intptr = value;
634 break;
635
636 case sLoginGraceTime:
637 intptr = &options->login_grace_time;
e2b1fb42 638parse_time:
2717fa0f 639 arg = strdelim(&cp);
640 if (!arg || *arg == '\0')
641 fatal("%s line %d: missing time value.",
642 filename, linenum);
643 if ((value = convtime(arg)) == -1)
644 fatal("%s line %d: invalid time value.",
645 filename, linenum);
646 if (*intptr == -1)
647 *intptr = value;
648 break;
649
650 case sKeyRegenerationTime:
651 intptr = &options->key_regeneration_time;
652 goto parse_time;
653
654 case sListenAddress:
655 arg = strdelim(&cp);
3867aa0a 656 if (arg == NULL || *arg == '\0')
657 fatal("%s line %d: missing address",
2717fa0f 658 filename, linenum);
91135a0e 659 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
660 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
661 && strchr(p+1, ':') != NULL) {
662 add_listen_addr(options, arg, 0);
663 break;
664 }
3867aa0a 665 p = hpdelim(&arg);
666 if (p == NULL)
667 fatal("%s line %d: bad address:port usage",
2717fa0f 668 filename, linenum);
3867aa0a 669 p = cleanhostname(p);
670 if (arg == NULL)
671 port = 0;
672 else if ((port = a2port(arg)) == 0)
673 fatal("%s line %d: bad port number", filename, linenum);
674
675 add_listen_addr(options, p, port);
676
2717fa0f 677 break;
678
31b41ceb 679 case sAddressFamily:
680 arg = strdelim(&cp);
38634ff6 681 if (!arg || *arg == '\0')
682 fatal("%s line %d: missing address family.",
683 filename, linenum);
31b41ceb 684 intptr = &options->address_family;
685 if (options->listen_addrs != NULL)
686 fatal("%s line %d: address family must be specified before "
687 "ListenAddress.", filename, linenum);
688 if (strcasecmp(arg, "inet") == 0)
689 value = AF_INET;
690 else if (strcasecmp(arg, "inet6") == 0)
691 value = AF_INET6;
692 else if (strcasecmp(arg, "any") == 0)
693 value = AF_UNSPEC;
694 else
695 fatal("%s line %d: unsupported address family \"%s\".",
696 filename, linenum, arg);
697 if (*intptr == -1)
698 *intptr = value;
699 break;
700
2717fa0f 701 case sHostKeyFile:
702 intptr = &options->num_host_key_files;
703 if (*intptr >= MAX_HOSTKEYS)
704 fatal("%s line %d: too many host keys specified (max %d).",
705 filename, linenum, MAX_HOSTKEYS);
706 charptr = &options->host_key_files[*intptr];
fa649821 707parse_filename:
2717fa0f 708 arg = strdelim(&cp);
709 if (!arg || *arg == '\0')
710 fatal("%s line %d: missing file name.",
711 filename, linenum);
d231781a 712 if (*activep && *charptr == NULL) {
2717fa0f 713 *charptr = tilde_expand_filename(arg, getuid());
714 /* increase optional counter */
715 if (intptr != NULL)
716 *intptr = *intptr + 1;
717 }
718 break;
0fbe8c74 719
2717fa0f 720 case sPidFile:
721 charptr = &options->pid_file;
722 goto parse_filename;
5260325f 723
2717fa0f 724 case sPermitRootLogin:
725 intptr = &options->permit_root_login;
726 arg = strdelim(&cp);
727 if (!arg || *arg == '\0')
728 fatal("%s line %d: missing yes/"
729 "without-password/forced-commands-only/no "
730 "argument.", filename, linenum);
731 value = 0; /* silence compiler */
732 if (strcmp(arg, "without-password") == 0)
733 value = PERMIT_NO_PASSWD;
734 else if (strcmp(arg, "forced-commands-only") == 0)
735 value = PERMIT_FORCED_ONLY;
736 else if (strcmp(arg, "yes") == 0)
737 value = PERMIT_YES;
738 else if (strcmp(arg, "no") == 0)
739 value = PERMIT_NO;
740 else
741 fatal("%s line %d: Bad yes/"
742 "without-password/forced-commands-only/no "
743 "argument: %s", filename, linenum, arg);
744 if (*intptr == -1)
745 *intptr = value;
746 break;
747
748 case sIgnoreRhosts:
749 intptr = &options->ignore_rhosts;
5260325f 750parse_flag:
2717fa0f 751 arg = strdelim(&cp);
752 if (!arg || *arg == '\0')
753 fatal("%s line %d: missing yes/no argument.",
754 filename, linenum);
755 value = 0; /* silence compiler */
756 if (strcmp(arg, "yes") == 0)
757 value = 1;
758 else if (strcmp(arg, "no") == 0)
759 value = 0;
760 else
761 fatal("%s line %d: Bad yes/no argument: %s",
762 filename, linenum, arg);
d231781a 763 if (*activep && *intptr == -1)
2717fa0f 764 *intptr = value;
765 break;
766
767 case sIgnoreUserKnownHosts:
768 intptr = &options->ignore_user_known_hosts;
769 goto parse_flag;
770
2717fa0f 771 case sRhostsRSAAuthentication:
772 intptr = &options->rhosts_rsa_authentication;
773 goto parse_flag;
774
775 case sHostbasedAuthentication:
776 intptr = &options->hostbased_authentication;
777 goto parse_flag;
778
779 case sHostbasedUsesNameFromPacketOnly:
780 intptr = &options->hostbased_uses_name_from_packet_only;
781 goto parse_flag;
782
783 case sRSAAuthentication:
784 intptr = &options->rsa_authentication;
785 goto parse_flag;
786
787 case sPubkeyAuthentication:
788 intptr = &options->pubkey_authentication;
789 goto parse_flag;
d0ec7f42 790
2717fa0f 791 case sKerberosAuthentication:
792 intptr = &options->kerberos_authentication;
793 goto parse_flag;
5260325f 794
2717fa0f 795 case sKerberosOrLocalPasswd:
796 intptr = &options->kerberos_or_local_passwd;
797 goto parse_flag;
5260325f 798
2717fa0f 799 case sKerberosTicketCleanup:
800 intptr = &options->kerberos_ticket_cleanup;
801 goto parse_flag;
d0ec7f42 802
a1e30b47 803 case sKerberosGetAFSToken:
804 intptr = &options->kerberos_get_afs_token;
805 goto parse_flag;
806
7364bd04 807 case sGssAuthentication:
808 intptr = &options->gss_authentication;
809 goto parse_flag;
810
811 case sGssCleanupCreds:
812 intptr = &options->gss_cleanup_creds;
813 goto parse_flag;
814
2717fa0f 815 case sPasswordAuthentication:
816 intptr = &options->password_authentication;
817 goto parse_flag;
5260325f 818
2717fa0f 819 case sKbdInteractiveAuthentication:
820 intptr = &options->kbd_interactive_authentication;
821 goto parse_flag;
8002af61 822
2717fa0f 823 case sChallengeResponseAuthentication:
824 intptr = &options->challenge_response_authentication;
825 goto parse_flag;
8002af61 826
2717fa0f 827 case sPrintMotd:
828 intptr = &options->print_motd;
829 goto parse_flag;
5260325f 830
2717fa0f 831 case sPrintLastLog:
832 intptr = &options->print_lastlog;
833 goto parse_flag;
5260325f 834
2717fa0f 835 case sX11Forwarding:
836 intptr = &options->x11_forwarding;
837 goto parse_flag;
5260325f 838
2717fa0f 839 case sX11DisplayOffset:
840 intptr = &options->x11_display_offset;
841 goto parse_int;
8efc0c15 842
e6e573bd 843 case sX11UseLocalhost:
844 intptr = &options->x11_use_localhost;
845 goto parse_flag;
846
2717fa0f 847 case sXAuthLocation:
848 charptr = &options->xauth_location;
849 goto parse_filename;
5260325f 850
2717fa0f 851 case sStrictModes:
852 intptr = &options->strict_modes;
853 goto parse_flag;
5260325f 854
fd573618 855 case sTCPKeepAlive:
856 intptr = &options->tcp_keep_alive;
2717fa0f 857 goto parse_flag;
33de75a3 858
2717fa0f 859 case sEmptyPasswd:
860 intptr = &options->permit_empty_passwd;
861 goto parse_flag;
5260325f 862
f00bab84 863 case sPermitUserEnvironment:
864 intptr = &options->permit_user_env;
865 goto parse_flag;
866
2717fa0f 867 case sUseLogin:
868 intptr = &options->use_login;
869 goto parse_flag;
5260325f 870
636f76ca 871 case sCompression:
872 intptr = &options->compression;
07200973 873 arg = strdelim(&cp);
874 if (!arg || *arg == '\0')
875 fatal("%s line %d: missing yes/no/delayed "
876 "argument.", filename, linenum);
877 value = 0; /* silence compiler */
878 if (strcmp(arg, "delayed") == 0)
879 value = COMP_DELAYED;
880 else if (strcmp(arg, "yes") == 0)
881 value = COMP_ZLIB;
882 else if (strcmp(arg, "no") == 0)
883 value = COMP_NONE;
884 else
885 fatal("%s line %d: Bad yes/no/delayed "
886 "argument: %s", filename, linenum, arg);
887 if (*intptr == -1)
888 *intptr = value;
889 break;
636f76ca 890
2717fa0f 891 case sGatewayPorts:
892 intptr = &options->gateway_ports;
3867aa0a 893 arg = strdelim(&cp);
894 if (!arg || *arg == '\0')
895 fatal("%s line %d: missing yes/no/clientspecified "
896 "argument.", filename, linenum);
897 value = 0; /* silence compiler */
898 if (strcmp(arg, "clientspecified") == 0)
899 value = 2;
900 else if (strcmp(arg, "yes") == 0)
901 value = 1;
902 else if (strcmp(arg, "no") == 0)
903 value = 0;
904 else
905 fatal("%s line %d: Bad yes/no/clientspecified "
906 "argument: %s", filename, linenum, arg);
907 if (*intptr == -1)
908 *intptr = value;
909 break;
5260325f 910
c5a7d788 911 case sUseDNS:
912 intptr = &options->use_dns;
2717fa0f 913 goto parse_flag;
5260325f 914
2717fa0f 915 case sLogFacility:
916 intptr = (int *) &options->log_facility;
917 arg = strdelim(&cp);
918 value = log_facility_number(arg);
5eaf8578 919 if (value == SYSLOG_FACILITY_NOT_SET)
2717fa0f 920 fatal("%.200s line %d: unsupported log facility '%s'",
921 filename, linenum, arg ? arg : "<NONE>");
922 if (*intptr == -1)
923 *intptr = (SyslogFacility) value;
924 break;
925
926 case sLogLevel:
927 intptr = (int *) &options->log_level;
928 arg = strdelim(&cp);
929 value = log_level_number(arg);
5eaf8578 930 if (value == SYSLOG_LEVEL_NOT_SET)
2717fa0f 931 fatal("%.200s line %d: unsupported log level '%s'",
932 filename, linenum, arg ? arg : "<NONE>");
933 if (*intptr == -1)
934 *intptr = (LogLevel) value;
935 break;
936
937 case sAllowTcpForwarding:
938 intptr = &options->allow_tcp_forwarding;
939 goto parse_flag;
940
1853d1ef 941 case sUsePrivilegeSeparation:
942 intptr = &use_privsep;
943 goto parse_flag;
944
2717fa0f 945 case sAllowUsers:
946 while ((arg = strdelim(&cp)) && *arg != '\0') {
947 if (options->num_allow_users >= MAX_ALLOW_USERS)
948 fatal("%s line %d: too many allow users.",
949 filename, linenum);
7528d467 950 options->allow_users[options->num_allow_users++] =
951 xstrdup(arg);
2717fa0f 952 }
953 break;
a8be9f80 954
2717fa0f 955 case sDenyUsers:
956 while ((arg = strdelim(&cp)) && *arg != '\0') {
957 if (options->num_deny_users >= MAX_DENY_USERS)
958 fatal( "%s line %d: too many deny users.",
959 filename, linenum);
7528d467 960 options->deny_users[options->num_deny_users++] =
961 xstrdup(arg);
2717fa0f 962 }
963 break;
b2552997 964
2717fa0f 965 case sAllowGroups:
966 while ((arg = strdelim(&cp)) && *arg != '\0') {
967 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
968 fatal("%s line %d: too many allow groups.",
969 filename, linenum);
7528d467 970 options->allow_groups[options->num_allow_groups++] =
971 xstrdup(arg);
2717fa0f 972 }
973 break;
a8be9f80 974
2717fa0f 975 case sDenyGroups:
976 while ((arg = strdelim(&cp)) && *arg != '\0') {
977 if (options->num_deny_groups >= MAX_DENY_GROUPS)
978 fatal("%s line %d: too many deny groups.",
979 filename, linenum);
980 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
981 }
982 break;
38c295d6 983
2717fa0f 984 case sCiphers:
985 arg = strdelim(&cp);
986 if (!arg || *arg == '\0')
987 fatal("%s line %d: Missing argument.", filename, linenum);
988 if (!ciphers_valid(arg))
989 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
990 filename, linenum, arg ? arg : "<NONE>");
991 if (options->ciphers == NULL)
992 options->ciphers = xstrdup(arg);
993 break;
994
995 case sMacs:
996 arg = strdelim(&cp);
997 if (!arg || *arg == '\0')
998 fatal("%s line %d: Missing argument.", filename, linenum);
999 if (!mac_valid(arg))
1000 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1001 filename, linenum, arg ? arg : "<NONE>");
1002 if (options->macs == NULL)
1003 options->macs = xstrdup(arg);
1004 break;
1005
1006 case sProtocol:
1007 intptr = &options->protocol;
1008 arg = strdelim(&cp);
1009 if (!arg || *arg == '\0')
1010 fatal("%s line %d: Missing argument.", filename, linenum);
1011 value = proto_spec(arg);
1012 if (value == SSH_PROTO_UNKNOWN)
1013 fatal("%s line %d: Bad protocol spec '%s'.",
184eed6a 1014 filename, linenum, arg ? arg : "<NONE>");
2717fa0f 1015 if (*intptr == SSH_PROTO_UNKNOWN)
1016 *intptr = value;
1017 break;
1018
1019 case sSubsystem:
1020 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1021 fatal("%s line %d: too many subsystems defined.",
184eed6a 1022 filename, linenum);
2717fa0f 1023 }
1024 arg = strdelim(&cp);
1025 if (!arg || *arg == '\0')
1026 fatal("%s line %d: Missing subsystem name.",
184eed6a 1027 filename, linenum);
d231781a 1028 if (!*activep) {
1029 arg = strdelim(&cp);
1030 break;
1031 }
2717fa0f 1032 for (i = 0; i < options->num_subsystems; i++)
1033 if (strcmp(arg, options->subsystem_name[i]) == 0)
1034 fatal("%s line %d: Subsystem '%s' already defined.",
184eed6a 1035 filename, linenum, arg);
2717fa0f 1036 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1037 arg = strdelim(&cp);
1038 if (!arg || *arg == '\0')
1039 fatal("%s line %d: Missing subsystem command.",
184eed6a 1040 filename, linenum);
2717fa0f 1041 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
d66ce1a1 1042
1043 /* Collect arguments (separate to executable) */
1044 p = xstrdup(arg);
1045 len = strlen(p) + 1;
1046 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1047 len += 1 + strlen(arg);
1048 p = xrealloc(p, 1, len);
1049 strlcat(p, " ", len);
1050 strlcat(p, arg, len);
1051 }
1052 options->subsystem_args[options->num_subsystems] = p;
2717fa0f 1053 options->num_subsystems++;
1054 break;
1055
1056 case sMaxStartups:
1057 arg = strdelim(&cp);
1058 if (!arg || *arg == '\0')
1059 fatal("%s line %d: Missing MaxStartups spec.",
184eed6a 1060 filename, linenum);
2717fa0f 1061 if ((n = sscanf(arg, "%d:%d:%d",
1062 &options->max_startups_begin,
1063 &options->max_startups_rate,
1064 &options->max_startups)) == 3) {
1065 if (options->max_startups_begin >
1066 options->max_startups ||
1067 options->max_startups_rate > 100 ||
1068 options->max_startups_rate < 1)
c345cf9d 1069 fatal("%s line %d: Illegal MaxStartups spec.",
97de229c 1070 filename, linenum);
2717fa0f 1071 } else if (n != 1)
1072 fatal("%s line %d: Illegal MaxStartups spec.",
1073 filename, linenum);
1074 else
1075 options->max_startups = options->max_startups_begin;
1076 break;
1077
af4bd935 1078 case sMaxAuthTries:
1079 intptr = &options->max_authtries;
1080 goto parse_int;
1081
2717fa0f 1082 case sBanner:
1083 charptr = &options->banner;
1084 goto parse_filename;
1085 /*
1086 * These options can contain %X options expanded at
1087 * connect time, so that you can specify paths like:
1088 *
1089 * AuthorizedKeysFile /etc/ssh_keys/%u
1090 */
1091 case sAuthorizedKeysFile:
1092 case sAuthorizedKeysFile2:
1093 charptr = (opcode == sAuthorizedKeysFile ) ?
1094 &options->authorized_keys_file :
1095 &options->authorized_keys_file2;
1096 goto parse_filename;
1097
1098 case sClientAliveInterval:
1099 intptr = &options->client_alive_interval;
1100 goto parse_time;
1101
1102 case sClientAliveCountMax:
1103 intptr = &options->client_alive_count_max;
1104 goto parse_int;
1105
61a2c1da 1106 case sAcceptEnv:
1107 while ((arg = strdelim(&cp)) && *arg != '\0') {
1108 if (strchr(arg, '=') != NULL)
1109 fatal("%s line %d: Invalid environment name.",
1110 filename, linenum);
1111 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1112 fatal("%s line %d: too many allow env.",
1113 filename, linenum);
d231781a 1114 if (!*activep)
1115 break;
61a2c1da 1116 options->accept_env[options->num_accept_env++] =
1117 xstrdup(arg);
1118 }
1119 break;
1120
d20f3c9e 1121 case sPermitTunnel:
1122 intptr = &options->permit_tun;
a4f24bf8 1123 arg = strdelim(&cp);
1124 if (!arg || *arg == '\0')
1125 fatal("%s line %d: Missing yes/point-to-point/"
1126 "ethernet/no argument.", filename, linenum);
1127 value = 0; /* silence compiler */
1128 if (strcasecmp(arg, "ethernet") == 0)
1129 value = SSH_TUNMODE_ETHERNET;
1130 else if (strcasecmp(arg, "point-to-point") == 0)
1131 value = SSH_TUNMODE_POINTOPOINT;
1132 else if (strcasecmp(arg, "yes") == 0)
1133 value = SSH_TUNMODE_YES;
1134 else if (strcasecmp(arg, "no") == 0)
1135 value = SSH_TUNMODE_NO;
1136 else
1137 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1138 "no argument: %s", filename, linenum, arg);
1139 if (*intptr == -1)
1140 *intptr = value;
1141 break;
d20f3c9e 1142
d231781a 1143 case sMatch:
1144 if (cmdline)
1145 fatal("Match directive not supported as a command-line "
1146 "option");
1147 value = match_cfg_line(&cp, linenum, user, host, address);
1148 if (value < 0)
1149 fatal("%s line %d: Bad Match condition", filename,
1150 linenum);
1151 *activep = value;
1152 break;
1153
2fefbadf 1154 case sPermitOpen:
1155 arg = strdelim(&cp);
1156 if (!arg || *arg == '\0')
1157 fatal("%s line %d: missing PermitOpen specification",
1158 filename, linenum);
1159 if (strcmp(arg, "any") == 0) {
1160 if (*activep)
1161 channel_clear_adm_permitted_opens();
1162 break;
1163 }
1164 p = hpdelim(&arg);
1165 if (p == NULL)
1166 fatal("%s line %d: missing host in PermitOpen",
1167 filename, linenum);
1168 p = cleanhostname(p);
1169 if (arg == NULL || (port = a2port(arg)) == 0)
1170 fatal("%s line %d: bad port number in PermitOpen",
1171 filename, linenum);
1172 if (*activep)
1173 channel_add_adm_permitted_opens(p, port);
1174 break;
1175
2717fa0f 1176 case sDeprecated:
bbe88b6d 1177 logit("%s line %d: Deprecated option %s",
2717fa0f 1178 filename, linenum, arg);
1179 while (arg)
1180 arg = strdelim(&cp);
1181 break;
1182
a2144546 1183 case sUnsupported:
1184 logit("%s line %d: Unsupported option %s",
1185 filename, linenum, arg);
1186 while (arg)
1187 arg = strdelim(&cp);
1188 break;
1189
2717fa0f 1190 default:
1191 fatal("%s line %d: Missing handler for opcode %s (%d)",
1192 filename, linenum, arg, opcode);
1193 }
1194 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1195 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1196 filename, linenum, arg);
1197 return 0;
1198}
089fbbd2 1199
2717fa0f 1200/* Reads the server configuration file. */
5c53a31e 1201
2717fa0f 1202void
b9a549d7 1203load_server_config(const char *filename, Buffer *conf)
2717fa0f 1204{
b9a549d7 1205 char line[1024], *cp;
7528d467 1206 FILE *f;
2717fa0f 1207
b9a549d7 1208 debug2("%s: filename %s", __func__, filename);
1209 if ((f = fopen(filename, "r")) == NULL) {
2717fa0f 1210 perror(filename);
1211 exit(1);
1212 }
b9a549d7 1213 buffer_clear(conf);
2717fa0f 1214 while (fgets(line, sizeof(line), f)) {
b9a549d7 1215 /*
1216 * Trim out comments and strip whitespace
f2107e97 1217 * NB - preserve newlines, they are needed to reproduce
b9a549d7 1218 * line numbers later for error messages
1219 */
1220 if ((cp = strchr(line, '#')) != NULL)
1221 memcpy(cp, "\n", 2);
1222 cp = line + strspn(line, " \t\r");
1223
1224 buffer_append(conf, cp, strlen(cp));
8efc0c15 1225 }
b9a549d7 1226 buffer_append(conf, "\0", 1);
5260325f 1227 fclose(f);
b9a549d7 1228 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1229}
1230
1231void
d231781a 1232parse_server_match_config(ServerOptions *options, const char *user,
1233 const char *host, const char *address)
1234{
1235 ServerOptions mo;
1236
1237 initialize_server_options(&mo);
1238 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1239 copy_set_server_options(options, &mo);
1240}
1241
1242/* Copy any (supported) values that are set */
1243void
1244copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1245{
1246 if (src->allow_tcp_forwarding != -1)
1247 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1248 if (src->gateway_ports != -1)
1249 dst->gateway_ports = src->gateway_ports;
1250}
1251
1252void
1253parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1254 const char *user, const char *host, const char *address)
b9a549d7 1255{
d231781a 1256 int active, linenum, bad_options = 0;
16acb158 1257 char *cp, *obuf, *cbuf;
b9a549d7 1258
1259 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1260
16acb158 1261 obuf = cbuf = xstrdup(buffer_ptr(conf));
d231781a 1262 active = user ? 0 : 1;
861cc543 1263 linenum = 1;
f8cc7664 1264 while ((cp = strsep(&cbuf, "\n")) != NULL) {
b9a549d7 1265 if (process_server_config_line(options, cp, filename,
d231781a 1266 linenum++, &active, user, host, address) != 0)
b9a549d7 1267 bad_options++;
1268 }
16acb158 1269 xfree(obuf);
b7c70970 1270 if (bad_options > 0)
1271 fatal("%s: terminating, %d bad configuration options",
1272 filename, bad_options);
8efc0c15 1273}
This page took 0.463599 seconds and 5 git commands to generate.