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