Print this page
3477 SunSSH config should accept TCPKeepAlive as synonym for KeepAlive
Reviewed by: Jerry Jelinek <jerry@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/ssh/sshd/servconf.c
+++ new/usr/src/cmd/ssh/sshd/servconf.c
1 1 /*
2 2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3 * All rights reserved
4 4 *
5 5 * As far as I am concerned, the code I have written for this software
6 6 * can be used freely for any purpose. Any derived versions of this
7 7 * software must be clearly marked as such, and if the derived work is
8 8 * incompatible with the protocol description in the RFC file, it must be
9 9 * called by a name other than "ssh" or "Secure Shell".
10 10 */
11 11 /*
12 12 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
13 + * Copyright 2013 Joyent, Inc. All rights reserved.
13 14 */
14 15
15 16 #include "includes.h"
16 17 RCSID("$OpenBSD: servconf.c,v 1.115 2002/09/04 18:52:42 stevesk Exp $");
17 18
18 19 #ifdef HAVE_DEFOPEN
19 20 #include <deflt.h>
20 21 #endif /* HAVE_DEFOPEN */
21 22
22 23 #if defined(KRB4)
23 24 #include <krb.h>
24 25 #endif
25 26 #if defined(KRB5)
26 27 #ifdef HEIMDAL
27 28 #include <krb.h>
28 29 #else
29 30 /* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V
30 31 * keytab */
31 32 #define KEYFILE "/etc/krb5.keytab"
32 33 #endif
33 34 #endif
34 35 #ifdef AFS
35 36 #include <kafs.h>
36 37 #endif
37 38
38 39 #include "ssh.h"
39 40 #include "log.h"
40 41 #include "buffer.h"
41 42 #include "servconf.h"
42 43 #include "xmalloc.h"
43 44 #include "compat.h"
44 45 #include "pathnames.h"
45 46 #include "tildexpand.h"
46 47 #include "misc.h"
47 48 #include "cipher.h"
48 49 #include "kex.h"
49 50 #include "mac.h"
50 51 #include "auth.h"
51 52 #include "match.h"
52 53 #include "groupaccess.h"
53 54
54 55 static void add_listen_addr(ServerOptions *, char *, u_short);
55 56 static void add_one_listen_addr(ServerOptions *, char *, u_short);
56 57
57 58 extern Buffer cfg;
58 59
59 60 /* AF_UNSPEC or AF_INET or AF_INET6 */
60 61 extern int IPv4or6;
61 62
62 63 /*
63 64 * Initializes the server options to their initial (unset) values. Some of those
64 65 * that stay unset after the command line options and configuration files are
65 66 * read are set to their default values in fill_default_server_options().
66 67 */
67 68 void
68 69 initialize_server_options(ServerOptions *options)
69 70 {
70 71 (void) memset(options, 0, sizeof(*options));
71 72
72 73 /* Standard Options */
73 74 options->num_ports = 0;
74 75 options->ports_from_cmdline = 0;
75 76 options->listen_addrs = NULL;
76 77 options->num_host_key_files = 0;
77 78 options->pid_file = NULL;
78 79 options->server_key_bits = -1;
79 80 options->login_grace_time = -1;
80 81 options->key_regeneration_time = -1;
81 82 options->permit_root_login = PERMIT_NOT_SET;
82 83 options->ignore_rhosts = -1;
83 84 options->ignore_user_known_hosts = -1;
84 85 options->print_motd = -1;
85 86 options->print_lastlog = -1;
86 87 options->x11_forwarding = -1;
87 88 options->x11_display_offset = -1;
88 89 options->x11_use_localhost = -1;
89 90 options->xauth_location = NULL;
90 91 options->strict_modes = -1;
91 92 options->keepalives = -1;
92 93 options->log_facility = SYSLOG_FACILITY_NOT_SET;
93 94 options->log_level = SYSLOG_LEVEL_NOT_SET;
94 95 options->rhosts_authentication = -1;
95 96 options->rhosts_rsa_authentication = -1;
96 97 options->hostbased_authentication = -1;
97 98 options->hostbased_uses_name_from_packet_only = -1;
98 99 options->rsa_authentication = -1;
99 100 options->pubkey_authentication = -1;
100 101 #ifdef GSSAPI
101 102 options->gss_authentication = -1;
102 103 options->gss_keyex = -1;
103 104 options->gss_store_creds = -1;
104 105 options->gss_use_session_ccache = -1;
105 106 options->gss_cleanup_creds = -1;
106 107 #endif
107 108 #if defined(KRB4) || defined(KRB5)
108 109 options->kerberos_authentication = -1;
109 110 options->kerberos_or_local_passwd = -1;
110 111 options->kerberos_ticket_cleanup = -1;
111 112 #endif
112 113 #if defined(AFS) || defined(KRB5)
113 114 options->kerberos_tgt_passing = -1;
114 115 #endif
115 116 #ifdef AFS
116 117 options->afs_token_passing = -1;
117 118 #endif
118 119 options->password_authentication = -1;
119 120 options->kbd_interactive_authentication = -1;
120 121 options->challenge_response_authentication = -1;
121 122 options->pam_authentication_via_kbd_int = -1;
122 123 options->permit_empty_passwd = -1;
123 124 options->permit_user_env = -1;
124 125 options->compression = -1;
125 126 options->allow_tcp_forwarding = -1;
126 127 options->num_allow_users = 0;
127 128 options->num_deny_users = 0;
128 129 options->num_allow_groups = 0;
129 130 options->num_deny_groups = 0;
130 131 options->ciphers = NULL;
131 132 options->macs = NULL;
132 133 options->protocol = SSH_PROTO_UNKNOWN;
133 134 options->gateway_ports = -1;
134 135 options->num_subsystems = 0;
135 136 options->max_startups_begin = -1;
136 137 options->max_startups_rate = -1;
137 138 options->max_startups = -1;
138 139 options->banner = NULL;
139 140 options->verify_reverse_mapping = -1;
140 141 options->client_alive_interval = -1;
141 142 options->client_alive_count_max = -1;
142 143 options->authorized_keys_file = NULL;
143 144 options->authorized_keys_file2 = NULL;
144 145
145 146 options->max_auth_tries = -1;
146 147 options->max_auth_tries_log = -1;
147 148
148 149 options->max_init_auth_tries = -1;
149 150 options->max_init_auth_tries_log = -1;
150 151
151 152 options->lookup_client_hostnames = -1;
152 153 options->use_openssl_engine = -1;
153 154 options->chroot_directory = NULL;
154 155 options->pre_userauth_hook = NULL;
155 156 options->pam_service_name = NULL;
156 157 options->pam_service_prefix = NULL;
157 158 }
158 159
159 160 #ifdef HAVE_DEFOPEN
160 161 /*
161 162 * Reads /etc/default/login and defaults several ServerOptions:
162 163 *
163 164 * PermitRootLogin
164 165 * PermitEmptyPasswords
165 166 * LoginGraceTime
166 167 *
167 168 * CONSOLE=* -> PermitRootLogin=without-password
168 169 * #CONSOLE=* -> PermitRootLogin=yes
169 170 *
170 171 * PASSREQ=YES -> PermitEmptyPasswords=no
171 172 * PASSREQ=NO -> PermitEmptyPasswords=yes
172 173 * #PASSREQ=* -> PermitEmptyPasswords=no
173 174 *
174 175 * TIMEOUT=<secs> -> LoginGraceTime=<secs>
175 176 * #TIMEOUT=<secs> -> LoginGraceTime=300
176 177 */
177 178 static
178 179 void
179 180 deflt_fill_default_server_options(ServerOptions *options)
180 181 {
181 182 int flags;
182 183 char *ptr;
183 184
184 185 if (defopen(_PATH_DEFAULT_LOGIN))
185 186 return;
186 187
187 188 /* Ignore case */
188 189 flags = defcntl(DC_GETFLAGS, 0);
189 190 TURNOFF(flags, DC_CASE);
190 191 (void) defcntl(DC_SETFLAGS, flags);
191 192
192 193 if (options->permit_root_login == PERMIT_NOT_SET &&
193 194 (ptr = defread("CONSOLE=")) != NULL)
194 195 options->permit_root_login = PERMIT_NO_PASSWD;
195 196
196 197 if (options->permit_empty_passwd == -1 &&
197 198 (ptr = defread("PASSREQ=")) != NULL) {
198 199 if (strcasecmp("YES", ptr) == 0)
199 200 options->permit_empty_passwd = 0;
200 201 else if (strcasecmp("NO", ptr) == 0)
201 202 options->permit_empty_passwd = 1;
202 203 }
203 204
204 205 if (options->max_init_auth_tries == -1 &&
205 206 (ptr = defread("RETRIES=")) != NULL) {
206 207 options->max_init_auth_tries = atoi(ptr);
207 208 }
208 209
209 210 if (options->max_init_auth_tries_log == -1 &&
210 211 (ptr = defread("SYSLOG_FAILED_LOGINS=")) != NULL) {
211 212 options->max_init_auth_tries_log = atoi(ptr);
212 213 }
213 214
214 215 if (options->login_grace_time == -1) {
215 216 if ((ptr = defread("TIMEOUT=")) != NULL)
216 217 options->login_grace_time = (unsigned)atoi(ptr);
217 218 else
218 219 options->login_grace_time = 300;
219 220 }
220 221
221 222 (void) defopen((char *)NULL);
222 223 }
223 224 #endif /* HAVE_DEFOPEN */
224 225
225 226 void
226 227 fill_default_server_options(ServerOptions *options)
227 228 {
228 229
229 230 #ifdef HAVE_DEFOPEN
230 231 deflt_fill_default_server_options(options);
231 232 #endif /* HAVE_DEFOPEN */
232 233
233 234 /* Standard Options */
234 235 if (options->protocol == SSH_PROTO_UNKNOWN)
235 236 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
236 237 if (options->num_host_key_files == 0) {
237 238 /* fill default hostkeys for protocols */
238 239 if (options->protocol & SSH_PROTO_1)
239 240 options->host_key_files[options->num_host_key_files++] =
240 241 _PATH_HOST_KEY_FILE;
241 242 #ifndef GSSAPI
242 243 /* With GSS keyex we can run v2 w/ no host keys */
243 244 if (options->protocol & SSH_PROTO_2) {
244 245 options->host_key_files[options->num_host_key_files++] =
245 246 _PATH_HOST_RSA_KEY_FILE;
246 247 options->host_key_files[options->num_host_key_files++] =
247 248 _PATH_HOST_DSA_KEY_FILE;
248 249 }
249 250 #endif /* GSSAPI */
250 251 }
251 252 if (options->num_ports == 0)
252 253 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
253 254 if (options->listen_addrs == NULL)
254 255 add_listen_addr(options, NULL, 0);
255 256 if (options->pid_file == NULL)
256 257 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
257 258 if (options->server_key_bits == -1)
258 259 options->server_key_bits = 768;
259 260 if (options->login_grace_time == -1)
260 261 options->login_grace_time = 120;
261 262 if (options->key_regeneration_time == -1)
262 263 options->key_regeneration_time = 3600;
263 264 if (options->permit_root_login == PERMIT_NOT_SET)
264 265 options->permit_root_login = PERMIT_YES;
265 266 if (options->ignore_rhosts == -1)
266 267 options->ignore_rhosts = 1;
267 268 if (options->ignore_user_known_hosts == -1)
268 269 options->ignore_user_known_hosts = 0;
269 270 if (options->print_motd == -1)
270 271 options->print_motd = 1;
271 272 if (options->print_lastlog == -1)
272 273 options->print_lastlog = 1;
273 274 if (options->x11_forwarding == -1)
274 275 options->x11_forwarding = 1;
275 276 if (options->x11_display_offset == -1)
276 277 options->x11_display_offset = 10;
277 278 if (options->x11_use_localhost == -1)
278 279 options->x11_use_localhost = 1;
279 280 if (options->xauth_location == NULL)
280 281 options->xauth_location = _PATH_XAUTH;
281 282 if (options->strict_modes == -1)
282 283 options->strict_modes = 1;
283 284 if (options->keepalives == -1)
284 285 options->keepalives = 1;
285 286 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
286 287 options->log_facility = SYSLOG_FACILITY_AUTH;
287 288 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
288 289 options->log_level = SYSLOG_LEVEL_INFO;
289 290 if (options->rhosts_authentication == -1)
290 291 options->rhosts_authentication = 0;
291 292 if (options->rhosts_rsa_authentication == -1)
292 293 options->rhosts_rsa_authentication = 0;
293 294 if (options->hostbased_authentication == -1)
294 295 options->hostbased_authentication = 0;
295 296 if (options->hostbased_uses_name_from_packet_only == -1)
296 297 options->hostbased_uses_name_from_packet_only = 0;
297 298 if (options->rsa_authentication == -1)
298 299 options->rsa_authentication = 1;
299 300 if (options->pubkey_authentication == -1)
300 301 options->pubkey_authentication = 1;
301 302 #ifdef GSSAPI
302 303 if (options->gss_authentication == -1)
303 304 options->gss_authentication = 1;
304 305 if (options->gss_keyex == -1)
305 306 options->gss_keyex = 1;
306 307 if (options->gss_store_creds == -1)
307 308 options->gss_store_creds = 1;
308 309 if (options->gss_use_session_ccache == -1)
309 310 options->gss_use_session_ccache = 1;
310 311 if (options->gss_cleanup_creds == -1)
311 312 options->gss_cleanup_creds = 1;
312 313 #endif
313 314 #if defined(KRB4) || defined(KRB5)
314 315 if (options->kerberos_authentication == -1)
315 316 options->kerberos_authentication = 0;
316 317 if (options->kerberos_or_local_passwd == -1)
317 318 options->kerberos_or_local_passwd = 1;
318 319 if (options->kerberos_ticket_cleanup == -1)
319 320 options->kerberos_ticket_cleanup = 1;
320 321 #endif
321 322 #if defined(AFS) || defined(KRB5)
322 323 if (options->kerberos_tgt_passing == -1)
323 324 options->kerberos_tgt_passing = 0;
324 325 #endif
325 326 #ifdef AFS
326 327 if (options->afs_token_passing == -1)
327 328 options->afs_token_passing = 0;
328 329 #endif
329 330 if (options->password_authentication == -1)
330 331 options->password_authentication = 1;
331 332 /*
332 333 * options->pam_authentication_via_kbd_int has intentionally no default
333 334 * value since we do not need it.
334 335 */
335 336 if (options->kbd_interactive_authentication == -1)
336 337 options->kbd_interactive_authentication = 1;
337 338 if (options->challenge_response_authentication == -1)
338 339 options->challenge_response_authentication = 1;
339 340 if (options->permit_empty_passwd == -1)
340 341 options->permit_empty_passwd = 0;
341 342 if (options->permit_user_env == -1)
342 343 options->permit_user_env = 0;
343 344 if (options->compression == -1)
344 345 options->compression = 1;
345 346 if (options->allow_tcp_forwarding == -1)
346 347 options->allow_tcp_forwarding = 1;
347 348 if (options->gateway_ports == -1)
348 349 options->gateway_ports = 0;
349 350 if (options->max_startups == -1)
350 351 options->max_startups = 10;
351 352 if (options->max_startups_rate == -1)
352 353 options->max_startups_rate = 100; /* 100% */
353 354 if (options->max_startups_begin == -1)
354 355 options->max_startups_begin = options->max_startups;
355 356 if (options->verify_reverse_mapping == -1)
356 357 options->verify_reverse_mapping = 0;
357 358 if (options->client_alive_interval == -1)
358 359 options->client_alive_interval = 0;
359 360 if (options->client_alive_count_max == -1)
360 361 options->client_alive_count_max = 3;
361 362 if (options->authorized_keys_file2 == NULL) {
362 363 /* authorized_keys_file2 falls back to authorized_keys_file */
363 364 if (options->authorized_keys_file != NULL)
364 365 options->authorized_keys_file2 = options->authorized_keys_file;
365 366 else
366 367 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
367 368 }
368 369 if (options->authorized_keys_file == NULL)
369 370 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
370 371
371 372 if (options->max_auth_tries == -1)
372 373 options->max_auth_tries = AUTH_FAIL_MAX;
373 374 if (options->max_auth_tries_log == -1)
374 375 options->max_auth_tries_log = options->max_auth_tries / 2;
375 376
376 377 if (options->max_init_auth_tries == -1)
377 378 options->max_init_auth_tries = AUTH_FAIL_MAX;
378 379 if (options->max_init_auth_tries_log == -1)
379 380 options->max_init_auth_tries_log = options->max_init_auth_tries / 2;
380 381
381 382 if (options->lookup_client_hostnames == -1)
382 383 options->lookup_client_hostnames = 1;
383 384 if (options->use_openssl_engine == -1)
384 385 options->use_openssl_engine = 1;
385 386 if (options->pam_service_prefix == NULL)
386 387 options->pam_service_prefix = _SSH_PAM_SERVICE_PREFIX;
387 388 if (options->pam_service_name == NULL)
388 389 options->pam_service_name = NULL;
389 390 }
390 391
391 392 /* Keyword tokens. */
392 393 typedef enum {
393 394 sBadOption, /* == unknown option */
394 395 /* Portable-specific options */
395 396 sPAMAuthenticationViaKbdInt,
396 397 /* Standard Options */
397 398 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
398 399 sPermitRootLogin, sLogFacility, sLogLevel,
399 400 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
400 401 #ifdef GSSAPI
401 402 sGssAuthentication, sGssKeyEx, sGssStoreDelegCreds,
402 403 sGssUseSessionCredCache, sGssCleanupCreds,
403 404 #endif /* GSSAPI */
404 405 #if defined(KRB4) || defined(KRB5)
405 406 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
406 407 #endif
407 408 #if defined(AFS) || defined(KRB5)
408 409 sKerberosTgtPassing,
409 410 #endif
410 411 #ifdef AFS
411 412 sAFSTokenPassing,
412 413 #endif
413 414 sChallengeResponseAuthentication,
414 415 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
415 416 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
416 417 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
417 418 sStrictModes, sEmptyPasswd, sKeepAlives,
418 419 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
419 420 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
420 421 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
421 422 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
422 423 sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
423 424 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
424 425 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
425 426 sMaxAuthTries, sMaxAuthTriesLog, sUsePrivilegeSeparation,
426 427 sLookupClientHostnames, sUseOpenSSLEngine, sChrootDirectory,
427 428 sPreUserauthHook, sMatch, sPAMServicePrefix, sPAMServiceName,
428 429 sDeprecated
429 430 } ServerOpCodes;
430 431
431 432 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
432 433 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
433 434 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
434 435
435 436 /* Textual representation of the tokens. */
436 437 static struct {
437 438 const char *name;
438 439 ServerOpCodes opcode;
439 440 u_int flags;
440 441 } keywords[] = {
441 442 /* Portable-specific options */
442 443 { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt, SSHCFG_GLOBAL },
443 444 /* Standard Options */
444 445 { "port", sPort, SSHCFG_GLOBAL },
445 446 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
446 447 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
447 448 { "pidfile", sPidFile, SSHCFG_GLOBAL },
448 449 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
449 450 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
450 451 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
451 452 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
452 453 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
453 454 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
454 455 { "rhostsauthentication", sRhostsAuthentication, SSHCFG_GLOBAL },
455 456 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
456 457 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
457 458 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
458 459 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
459 460 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
460 461 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
461 462 #ifdef GSSAPI
462 463 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
463 464 { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
464 465 { "gssapistoredelegatedcredentials", sGssStoreDelegCreds, SSHCFG_GLOBAL },
465 466 { "gssauthentication", sGssAuthentication, SSHCFG_GLOBAL }, /* alias */
466 467 { "gsskeyex", sGssKeyEx, SSHCFG_GLOBAL }, /* alias */
467 468 { "gssstoredelegcreds", sGssStoreDelegCreds, SSHCFG_GLOBAL }, /* alias */
468 469 #ifndef SUNW_GSSAPI
469 470 { "gssusesessionccache", sGssUseSessionCredCache, SSHCFG_GLOBAL },
470 471 { "gssusesessioncredcache", sGssUseSessionCredCache, SSHCFG_GLOBAL },
471 472 { "gsscleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL },
472 473 #endif /* SUNW_GSSAPI */
473 474 #endif
474 475 #if defined(KRB4) || defined(KRB5)
475 476 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
476 477 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
477 478 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
478 479 #endif
479 480 #if defined(AFS) || defined(KRB5)
480 481 { "kerberostgtpassing", sKerberosTgtPassing, SSHCFG_GLOBAL },
481 482 #endif
482 483 #ifdef AFS
483 484 { "afstokenpassing", sAFSTokenPassing, SSHCFG_GLOBAL },
484 485 #endif
485 486 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
486 487 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
487 488 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
488 489 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
489 490 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
490 491 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
491 492 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
492 493 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
493 494 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
↓ open down ↓ |
471 lines elided |
↑ open up ↑ |
494 495 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
495 496 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
496 497 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
497 498 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
498 499 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
499 500 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
500 501 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
501 502 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
502 503 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
503 504 { "compression", sCompression, SSHCFG_GLOBAL },
504 - { "keepalive", sKeepAlives, SSHCFG_GLOBAL },
505 + { "tcpkeepalive", sKeepAlives, SSHCFG_GLOBAL },
506 + { "keepalive", sKeepAlives, SSHCFG_GLOBAL }, /* obsolete */
505 507 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
506 508 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
507 509 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
508 510 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
509 511 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
510 512 { "ciphers", sCiphers, SSHCFG_GLOBAL },
511 513 { "macs", sMacs, SSHCFG_GLOBAL},
512 514 { "protocol", sProtocol,SSHCFG_GLOBAL },
513 515 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
514 516 { "subsystem", sSubsystem, SSHCFG_GLOBAL},
515 517 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
516 518 { "banner", sBanner, SSHCFG_ALL },
517 519 { "verifyreversemapping", sVerifyReverseMapping, SSHCFG_GLOBAL },
518 520 { "reversemappingcheck", sVerifyReverseMapping,SSHCFG_GLOBAL },
519 521 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
520 522 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
521 523 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
522 524 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
523 525 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
524 526 { "maxauthtrieslog", sMaxAuthTriesLog, SSHCFG_GLOBAL },
525 527 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
526 528 { "lookupclienthostnames", sLookupClientHostnames, SSHCFG_GLOBAL },
527 529 { "useopensslengine", sUseOpenSSLEngine, SSHCFG_GLOBAL },
528 530 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
529 531 { "preuserauthhook", sPreUserauthHook, SSHCFG_ALL},
530 532 { "match", sMatch, SSHCFG_ALL },
531 533 { "pamserviceprefix", sPAMServicePrefix, SSHCFG_GLOBAL },
532 534 { "pamservicename", sPAMServiceName, SSHCFG_GLOBAL },
533 535
534 536 { NULL, sBadOption, 0 }
535 537 };
536 538
537 539 /*
538 540 * Returns the number of the token pointed to by cp or sBadOption.
539 541 */
540 542
541 543 static ServerOpCodes
542 544 parse_token(const char *cp, const char *filename,
543 545 int linenum, u_int *flags)
544 546 {
545 547 u_int i;
546 548
547 549 for (i = 0; keywords[i].name; i++)
548 550 if (strcasecmp(cp, keywords[i].name) == 0) {
549 551 *flags = keywords[i].flags;
550 552 return keywords[i].opcode;
551 553 }
552 554
553 555 error("%s: line %d: Bad configuration option: %s",
554 556 filename, linenum, cp);
555 557 return sBadOption;
556 558 }
557 559
558 560 static void
559 561 add_listen_addr(ServerOptions *options, char *addr, u_short port)
560 562 {
561 563 int i;
562 564
563 565 if (options->num_ports == 0)
564 566 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
565 567 if (port == 0)
566 568 for (i = 0; i < options->num_ports; i++)
567 569 add_one_listen_addr(options, addr, options->ports[i]);
568 570 else
569 571 add_one_listen_addr(options, addr, port);
570 572 }
571 573
572 574 static void
573 575 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
574 576 {
575 577 struct addrinfo hints, *ai, *aitop;
576 578 char strport[NI_MAXSERV];
577 579 int gaierr;
578 580
579 581 (void) memset(&hints, 0, sizeof(hints));
580 582 hints.ai_family = IPv4or6;
581 583 hints.ai_socktype = SOCK_STREAM;
582 584 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
583 585 (void) snprintf(strport, sizeof strport, "%u", port);
584 586 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
585 587 fatal("bad addr or host: %s (%s)",
586 588 addr ? addr : "<NULL>",
587 589 gai_strerror(gaierr));
588 590 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
589 591 ;
590 592 ai->ai_next = options->listen_addrs;
591 593 options->listen_addrs = aitop;
592 594 }
593 595
594 596 /*
595 597 * The strategy for the Match blocks is that the config file is parsed twice.
596 598 *
597 599 * The first time is at startup. activep is initialized to 1 and the
598 600 * directives in the global context are processed and acted on. Hitting a
599 601 * Match directive unsets activep and the directives inside the block are
600 602 * checked for syntax only.
601 603 *
602 604 * The second time is after a connection has been established but before
603 605 * authentication. activep is initialized to 2 and global config directives
604 606 * are ignored since they have already been processed. If the criteria in a
605 607 * Match block is met, activep is set and the subsequent directives
606 608 * processed and actioned until EOF or another Match block unsets it. Any
607 609 * options set are copied into the main server config.
608 610 *
609 611 * Potential additions/improvements:
610 612 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
611 613 *
612 614 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
613 615 * Match Address 192.168.0.*
614 616 * Tag trusted
615 617 * Match Group wheel
616 618 * Tag trusted
617 619 * Match Tag trusted
618 620 * AllowTcpForwarding yes
619 621 * GatewayPorts clientspecified
620 622 * [...]
621 623 *
622 624 * - Add a PermittedChannelRequests directive
623 625 * Match Group shell
624 626 * PermittedChannelRequests session,forwarded-tcpip
625 627 */
626 628
627 629 static int
628 630 match_cfg_line_group(const char *grps, int line, const char *user)
629 631 {
630 632 int result = 0;
631 633 struct passwd *pw;
632 634
633 635 if (user == NULL)
634 636 goto out;
635 637
636 638 if ((pw = getpwnam(user)) == NULL) {
637 639 debug("Can't match group at line %d because user %.100s does "
638 640 "not exist", line, user);
639 641 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
640 642 debug("Can't Match group because user %.100s not in any group "
641 643 "at line %d", user, line);
642 644 } else if (ga_match_pattern_list(grps) != 1) {
643 645 debug("user %.100s does not match group list %.100s at line %d",
644 646 user, grps, line);
645 647 } else {
646 648 debug("user %.100s matched group list %.100s at line %d", user,
647 649 grps, line);
648 650 result = 1;
649 651 }
650 652 out:
651 653 ga_free();
652 654 return result;
653 655 }
654 656
655 657 static int
656 658 match_cfg_line(char **condition, int line, const char *user, const char *host,
657 659 const char *address)
658 660 {
659 661 int result = 1;
660 662 char *arg, *attrib, *cp = *condition;
661 663 size_t len;
662 664
663 665 if (user == NULL)
664 666 debug3("checking syntax for 'Match %s'", cp);
665 667 else
666 668 debug3("checking match for '%s' user %s host %s addr %s", cp,
667 669 user ? user : "(null)", host ? host : "(null)",
668 670 address ? address : "(null)");
669 671
670 672 while ((attrib = strdelim(&cp)) != NULL && *attrib != '\0') {
671 673 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
672 674 error("Missing Match criteria for %s", attrib);
673 675 return -1;
674 676 }
675 677 len = strlen(arg);
676 678 if (strcasecmp(attrib, "user") == 0) {
677 679 if (!user) {
678 680 result = 0;
679 681 continue;
680 682 }
681 683 if (match_pattern_list(user, arg, len, 0) != 1)
682 684 result = 0;
683 685 else
684 686 debug("user %.100s matched 'User %.100s' at "
685 687 "line %d", user, arg, line);
686 688 } else if (strcasecmp(attrib, "group") == 0) {
687 689 switch (match_cfg_line_group(arg, line, user)) {
688 690 case -1:
689 691 return -1;
690 692 case 0:
691 693 result = 0;
692 694 }
693 695 } else if (strcasecmp(attrib, "host") == 0) {
694 696 if (!host) {
695 697 result = 0;
696 698 continue;
697 699 }
698 700 if (match_hostname(host, arg, len) != 1)
699 701 result = 0;
700 702 else
701 703 debug("connection from %.100s matched 'Host "
702 704 "%.100s' at line %d", host, arg, line);
703 705 } else if (strcasecmp(attrib, "address") == 0) {
704 706 switch (addr_match_list(address, arg)) {
705 707 case 1:
706 708 debug("connection from %.100s matched 'Address "
707 709 "%.100s' at line %d", address, arg, line);
708 710 break;
709 711 case 0:
710 712 case -1:
711 713 result = 0;
712 714 break;
713 715 case -2:
714 716 return -1;
715 717 }
716 718 } else {
717 719 error("Unsupported Match attribute %s", attrib);
718 720 return -1;
719 721 }
720 722 }
721 723 if (user != NULL)
722 724 debug3("match %sfound", result ? "" : "not ");
723 725 *condition = cp;
724 726 return result;
725 727 }
726 728
727 729 #define WHITESPACE " \t\r\n"
728 730
729 731 int
730 732 process_server_config_line(ServerOptions *options, char *line,
731 733 const char *filename, int linenum, int *activep, const char *user,
732 734 const char *host, const char *address)
733 735 {
734 736 char *cp, **charptr, *arg, *p;
735 737 int cmdline = 0, *intptr, value, n;
736 738 ServerOpCodes opcode;
737 739 u_int i, flags = 0;
738 740 size_t len;
739 741
740 742 cp = line;
741 743 arg = strdelim(&cp);
742 744 /* Ignore leading whitespace */
743 745 if (*arg == '\0')
744 746 arg = strdelim(&cp);
745 747 if (!arg || !*arg || *arg == '#')
746 748 return 0;
747 749 intptr = NULL;
748 750 charptr = NULL;
749 751 opcode = parse_token(arg, filename, linenum, &flags);
750 752
751 753 if (activep == NULL) { /* We are processing a command line directive */
752 754 cmdline = 1;
753 755 activep = &cmdline;
754 756 }
755 757 if (*activep && opcode != sMatch)
756 758 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
757 759 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
758 760 if (user == NULL) {
759 761 fatal("%s line %d: Directive '%s' is not allowed "
760 762 "within a Match block", filename, linenum, arg);
761 763 } else { /* this is a directive we have already processed */
762 764 while (arg)
763 765 arg = strdelim(&cp);
764 766 return 0;
765 767 }
766 768 }
767 769
768 770 switch (opcode) {
769 771 /* Portable-specific options */
770 772 case sPAMAuthenticationViaKbdInt:
771 773 log("%s line %d: PAMAuthenticationViaKbdInt has been "
772 774 "deprecated. You should use KbdInteractiveAuthentication "
773 775 "instead (which defaults to \"yes\").", filename, linenum);
774 776 intptr = &options->pam_authentication_via_kbd_int;
775 777 goto parse_flag;
776 778
777 779 /* Standard Options */
778 780 case sBadOption:
779 781 return -1;
780 782 case sPort:
781 783 /* ignore ports from configfile if cmdline specifies ports */
782 784 if (options->ports_from_cmdline)
783 785 return 0;
784 786 if (options->listen_addrs != NULL)
785 787 fatal("%s line %d: ports must be specified before "
786 788 "ListenAddress.", filename, linenum);
787 789 if (options->num_ports >= MAX_PORTS)
788 790 fatal("%s line %d: too many ports.",
789 791 filename, linenum);
790 792 arg = strdelim(&cp);
791 793 if (!arg || *arg == '\0')
792 794 fatal("%s line %d: missing port number.",
793 795 filename, linenum);
794 796 options->ports[options->num_ports++] = a2port(arg);
795 797 if (options->ports[options->num_ports-1] == 0)
796 798 fatal("%s line %d: Badly formatted port number.",
797 799 filename, linenum);
798 800 break;
799 801
800 802 case sServerKeyBits:
801 803 intptr = &options->server_key_bits;
802 804 parse_int:
803 805 arg = strdelim(&cp);
804 806 if (!arg || *arg == '\0')
805 807 fatal("%s line %d: missing integer value.",
806 808 filename, linenum);
807 809 value = atoi(arg);
808 810 if (*activep && *intptr == -1)
809 811 *intptr = value;
810 812 break;
811 813
812 814 case sLoginGraceTime:
813 815 intptr = &options->login_grace_time;
814 816 parse_time:
815 817 arg = strdelim(&cp);
816 818 if (!arg || *arg == '\0')
817 819 fatal("%s line %d: missing time value.",
818 820 filename, linenum);
819 821 if ((value = convtime(arg)) == -1)
820 822 fatal("%s line %d: invalid time value.",
821 823 filename, linenum);
822 824 if (*intptr == -1)
823 825 *intptr = value;
824 826 break;
825 827
826 828 case sKeyRegenerationTime:
827 829 intptr = &options->key_regeneration_time;
828 830 goto parse_time;
829 831
830 832 case sListenAddress:
831 833 arg = strdelim(&cp);
832 834 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
833 835 fatal("%s line %d: missing inet addr.",
834 836 filename, linenum);
835 837 if (*arg == '[') {
836 838 if ((p = strchr(arg, ']')) == NULL)
837 839 fatal("%s line %d: bad ipv6 inet addr usage.",
838 840 filename, linenum);
839 841 arg++;
840 842 (void) memmove(p, p+1, strlen(p+1)+1);
841 843 } else if (((p = strchr(arg, ':')) == NULL) ||
842 844 (strchr(p+1, ':') != NULL)) {
843 845 add_listen_addr(options, arg, 0);
844 846 break;
845 847 }
846 848 if (*p == ':') {
847 849 u_short port;
848 850
849 851 p++;
850 852 if (*p == '\0')
851 853 fatal("%s line %d: bad inet addr:port usage.",
852 854 filename, linenum);
853 855 else {
854 856 *(p-1) = '\0';
855 857 if ((port = a2port(p)) == 0)
856 858 fatal("%s line %d: bad port number.",
857 859 filename, linenum);
858 860 add_listen_addr(options, arg, port);
859 861 }
860 862 } else if (*p == '\0')
861 863 add_listen_addr(options, arg, 0);
862 864 else
863 865 fatal("%s line %d: bad inet addr usage.",
864 866 filename, linenum);
865 867 break;
866 868
867 869 case sHostKeyFile:
868 870 intptr = &options->num_host_key_files;
869 871 if (*intptr >= MAX_HOSTKEYS)
870 872 fatal("%s line %d: too many host keys specified (max %d).",
871 873 filename, linenum, MAX_HOSTKEYS);
872 874 charptr = &options->host_key_files[*intptr];
873 875 parse_filename:
874 876 arg = strdelim(&cp);
875 877 if (!arg || *arg == '\0')
876 878 fatal("%s line %d: missing file name.",
877 879 filename, linenum);
878 880 if (*activep && *charptr == NULL) {
879 881 *charptr = tilde_expand_filename(arg, getuid());
880 882 /* increase optional counter */
881 883 if (intptr != NULL)
882 884 *intptr = *intptr + 1;
883 885 }
884 886 break;
885 887
886 888 case sPidFile:
887 889 charptr = &options->pid_file;
888 890 goto parse_filename;
889 891
890 892 case sPermitRootLogin:
891 893 intptr = &options->permit_root_login;
892 894 arg = strdelim(&cp);
893 895 if (!arg || *arg == '\0')
894 896 fatal("%s line %d: missing yes/"
895 897 "without-password/forced-commands-only/no "
896 898 "argument.", filename, linenum);
897 899 value = 0; /* silence compiler */
898 900 if (strcmp(arg, "without-password") == 0)
899 901 value = PERMIT_NO_PASSWD;
900 902 else if (strcmp(arg, "forced-commands-only") == 0)
901 903 value = PERMIT_FORCED_ONLY;
902 904 else if (strcmp(arg, "yes") == 0)
903 905 value = PERMIT_YES;
904 906 else if (strcmp(arg, "no") == 0)
905 907 value = PERMIT_NO;
906 908 else
907 909 fatal("%s line %d: Bad yes/"
908 910 "without-password/forced-commands-only/no "
909 911 "argument: %s", filename, linenum, arg);
910 912 if (*activep && *intptr == -1)
911 913 *intptr = value;
912 914 break;
913 915
914 916 case sIgnoreRhosts:
915 917 intptr = &options->ignore_rhosts;
916 918 parse_flag:
917 919 arg = strdelim(&cp);
918 920 if (!arg || *arg == '\0')
919 921 fatal("%s line %d: missing yes/no argument.",
920 922 filename, linenum);
921 923 value = 0; /* silence compiler */
922 924 if (strcmp(arg, "yes") == 0)
923 925 value = 1;
924 926 else if (strcmp(arg, "no") == 0)
925 927 value = 0;
926 928 else
927 929 fatal("%s line %d: Bad yes/no argument: %s",
928 930 filename, linenum, arg);
929 931 if (*activep && *intptr == -1)
930 932 *intptr = value;
931 933 break;
932 934
933 935 case sIgnoreUserKnownHosts:
934 936 intptr = &options->ignore_user_known_hosts;
935 937 goto parse_flag;
936 938
937 939 case sRhostsAuthentication:
938 940 intptr = &options->rhosts_authentication;
939 941 goto parse_flag;
940 942
941 943 case sRhostsRSAAuthentication:
942 944 intptr = &options->rhosts_rsa_authentication;
943 945 goto parse_flag;
944 946
945 947 case sHostbasedAuthentication:
946 948 intptr = &options->hostbased_authentication;
947 949 goto parse_flag;
948 950
949 951 case sHostbasedUsesNameFromPacketOnly:
950 952 intptr = &options->hostbased_uses_name_from_packet_only;
951 953 goto parse_flag;
952 954
953 955 case sRSAAuthentication:
954 956 intptr = &options->rsa_authentication;
955 957 goto parse_flag;
956 958
957 959 case sPubkeyAuthentication:
958 960 intptr = &options->pubkey_authentication;
959 961 goto parse_flag;
960 962 #ifdef GSSAPI
961 963 case sGssAuthentication:
962 964 intptr = &options->gss_authentication;
963 965 goto parse_flag;
964 966 case sGssKeyEx:
965 967 intptr = &options->gss_keyex;
966 968 goto parse_flag;
967 969 case sGssStoreDelegCreds:
968 970 intptr = &options->gss_keyex;
969 971 goto parse_flag;
970 972 #ifndef SUNW_GSSAPI
971 973 case sGssUseSessionCredCache:
972 974 intptr = &options->gss_use_session_ccache;
973 975 goto parse_flag;
974 976 case sGssCleanupCreds:
975 977 intptr = &options->gss_cleanup_creds;
976 978 goto parse_flag;
977 979 #endif /* SUNW_GSSAPI */
978 980 #endif /* GSSAPI */
979 981 #if defined(KRB4) || defined(KRB5)
980 982 case sKerberosAuthentication:
981 983 intptr = &options->kerberos_authentication;
982 984 goto parse_flag;
983 985
984 986 case sKerberosOrLocalPasswd:
985 987 intptr = &options->kerberos_or_local_passwd;
986 988 goto parse_flag;
987 989
988 990 case sKerberosTicketCleanup:
989 991 intptr = &options->kerberos_ticket_cleanup;
990 992 goto parse_flag;
991 993 #endif
992 994 #if defined(AFS) || defined(KRB5)
993 995 case sKerberosTgtPassing:
994 996 intptr = &options->kerberos_tgt_passing;
995 997 goto parse_flag;
996 998 #endif
997 999 #ifdef AFS
998 1000 case sAFSTokenPassing:
999 1001 intptr = &options->afs_token_passing;
1000 1002 goto parse_flag;
1001 1003 #endif
1002 1004
1003 1005 case sPasswordAuthentication:
1004 1006 intptr = &options->password_authentication;
1005 1007 goto parse_flag;
1006 1008
1007 1009 case sKbdInteractiveAuthentication:
1008 1010 intptr = &options->kbd_interactive_authentication;
1009 1011 goto parse_flag;
1010 1012
1011 1013 case sChallengeResponseAuthentication:
1012 1014 intptr = &options->challenge_response_authentication;
1013 1015 goto parse_flag;
1014 1016
1015 1017 case sPrintMotd:
1016 1018 intptr = &options->print_motd;
1017 1019 goto parse_flag;
1018 1020
1019 1021 case sPrintLastLog:
1020 1022 intptr = &options->print_lastlog;
1021 1023 goto parse_flag;
1022 1024
1023 1025 case sX11Forwarding:
1024 1026 intptr = &options->x11_forwarding;
1025 1027 goto parse_flag;
1026 1028
1027 1029 case sX11DisplayOffset:
1028 1030 intptr = &options->x11_display_offset;
1029 1031 goto parse_int;
1030 1032
1031 1033 case sX11UseLocalhost:
1032 1034 intptr = &options->x11_use_localhost;
1033 1035 goto parse_flag;
1034 1036
1035 1037 case sXAuthLocation:
1036 1038 charptr = &options->xauth_location;
1037 1039 goto parse_filename;
1038 1040
1039 1041 case sStrictModes:
1040 1042 intptr = &options->strict_modes;
1041 1043 goto parse_flag;
1042 1044
1043 1045 case sKeepAlives:
1044 1046 intptr = &options->keepalives;
1045 1047 goto parse_flag;
1046 1048
1047 1049 case sEmptyPasswd:
1048 1050 intptr = &options->permit_empty_passwd;
1049 1051 goto parse_flag;
1050 1052
1051 1053 case sPermitUserEnvironment:
1052 1054 intptr = &options->permit_user_env;
1053 1055 goto parse_flag;
1054 1056
1055 1057 case sUseLogin:
1056 1058 log("%s line %d: ignoring UseLogin option value."
1057 1059 " This option is always off.", filename, linenum);
1058 1060 while (arg)
1059 1061 arg = strdelim(&cp);
1060 1062 break;
1061 1063
1062 1064 case sCompression:
1063 1065 intptr = &options->compression;
1064 1066 goto parse_flag;
1065 1067
1066 1068 case sGatewayPorts:
1067 1069 intptr = &options->gateway_ports;
1068 1070 arg = strdelim(&cp);
1069 1071 if (!arg || *arg == '\0')
1070 1072 fatal("%s line %d: missing yes/no/clientspecified "
1071 1073 "argument.", filename, linenum);
1072 1074 value = 0; /* silence compiler */
1073 1075 if (strcmp(arg, "clientspecified") == 0)
1074 1076 value = 2;
1075 1077 else if (strcmp(arg, "yes") == 0)
1076 1078 value = 1;
1077 1079 else if (strcmp(arg, "no") == 0)
1078 1080 value = 0;
1079 1081 else
1080 1082 fatal("%s line %d: Bad yes/no/clientspecified "
1081 1083 "argument: %s", filename, linenum, arg);
1082 1084 if (*activep && *intptr == -1)
1083 1085 *intptr = value;
1084 1086 break;
1085 1087
1086 1088 case sVerifyReverseMapping:
1087 1089 intptr = &options->verify_reverse_mapping;
1088 1090 goto parse_flag;
1089 1091
1090 1092 case sLogFacility:
1091 1093 intptr = (int *) &options->log_facility;
1092 1094 arg = strdelim(&cp);
1093 1095 value = log_facility_number(arg);
1094 1096 if (value == SYSLOG_FACILITY_NOT_SET)
1095 1097 fatal("%.200s line %d: unsupported log facility '%s'",
1096 1098 filename, linenum, arg ? arg : "<NONE>");
1097 1099 if (*intptr == -1)
1098 1100 *intptr = (SyslogFacility) value;
1099 1101 break;
1100 1102
1101 1103 case sLogLevel:
1102 1104 intptr = (int *) &options->log_level;
1103 1105 arg = strdelim(&cp);
1104 1106 value = log_level_number(arg);
1105 1107 if (value == SYSLOG_LEVEL_NOT_SET)
1106 1108 fatal("%.200s line %d: unsupported log level '%s'",
1107 1109 filename, linenum, arg ? arg : "<NONE>");
1108 1110 if (*intptr == -1)
1109 1111 *intptr = (LogLevel) value;
1110 1112 break;
1111 1113
1112 1114 case sAllowTcpForwarding:
1113 1115 intptr = &options->allow_tcp_forwarding;
1114 1116 goto parse_flag;
1115 1117
1116 1118 case sUsePrivilegeSeparation:
1117 1119 log("%s line %d: ignoring UsePrivilegeSeparation option value."
1118 1120 " This option is always on.", filename, linenum);
1119 1121 while (arg)
1120 1122 arg = strdelim(&cp);
1121 1123 break;
1122 1124
1123 1125 case sAllowUsers:
1124 1126 while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1125 1127 if (options->num_allow_users >= MAX_ALLOW_USERS)
1126 1128 fatal("%s line %d: too many allow users.",
1127 1129 filename, linenum);
1128 1130 options->allow_users[options->num_allow_users++] =
1129 1131 xstrdup(arg);
1130 1132 }
1131 1133 break;
1132 1134
1133 1135 case sDenyUsers:
1134 1136 while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1135 1137 if (options->num_deny_users >= MAX_DENY_USERS)
1136 1138 fatal( "%s line %d: too many deny users.",
1137 1139 filename, linenum);
1138 1140 options->deny_users[options->num_deny_users++] =
1139 1141 xstrdup(arg);
1140 1142 }
1141 1143 break;
1142 1144
1143 1145 case sAllowGroups:
1144 1146 while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1145 1147 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1146 1148 fatal("%s line %d: too many allow groups.",
1147 1149 filename, linenum);
1148 1150 options->allow_groups[options->num_allow_groups++] =
1149 1151 xstrdup(arg);
1150 1152 }
1151 1153 break;
1152 1154
1153 1155 case sDenyGroups:
1154 1156 while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1155 1157 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1156 1158 fatal("%s line %d: too many deny groups.",
1157 1159 filename, linenum);
1158 1160 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1159 1161 }
1160 1162 break;
1161 1163
1162 1164 case sCiphers:
1163 1165 arg = strdelim(&cp);
1164 1166 if (!arg || *arg == '\0')
1165 1167 fatal("%s line %d: Missing argument.", filename, linenum);
1166 1168 if (!ciphers_valid(arg))
1167 1169 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1168 1170 filename, linenum, arg ? arg : "<NONE>");
1169 1171 if (options->ciphers == NULL)
1170 1172 options->ciphers = xstrdup(arg);
1171 1173 break;
1172 1174
1173 1175 case sMacs:
1174 1176 arg = strdelim(&cp);
1175 1177 if (!arg || *arg == '\0')
1176 1178 fatal("%s line %d: Missing argument.", filename, linenum);
1177 1179 if (!mac_valid(arg))
1178 1180 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1179 1181 filename, linenum, arg ? arg : "<NONE>");
1180 1182 if (options->macs == NULL)
1181 1183 options->macs = xstrdup(arg);
1182 1184 break;
1183 1185
1184 1186 case sProtocol:
1185 1187 intptr = &options->protocol;
1186 1188 arg = strdelim(&cp);
1187 1189 if (!arg || *arg == '\0')
1188 1190 fatal("%s line %d: Missing argument.", filename, linenum);
1189 1191 value = proto_spec(arg);
1190 1192 if (value == SSH_PROTO_UNKNOWN)
1191 1193 fatal("%s line %d: Bad protocol spec '%s'.",
1192 1194 filename, linenum, arg ? arg : "<NONE>");
1193 1195 if (*intptr == SSH_PROTO_UNKNOWN)
1194 1196 *intptr = value;
1195 1197 break;
1196 1198
1197 1199 case sSubsystem:
1198 1200 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1199 1201 fatal("%s line %d: too many subsystems defined.",
1200 1202 filename, linenum);
1201 1203 }
1202 1204 arg = strdelim(&cp);
1203 1205 if (!arg || *arg == '\0')
1204 1206 fatal("%s line %d: Missing subsystem name.",
1205 1207 filename, linenum);
1206 1208 if (!*activep) {
1207 1209 arg = strdelim(&cp);
1208 1210 break;
1209 1211 }
1210 1212 for (i = 0; i < options->num_subsystems; i++)
1211 1213 if (strcmp(arg, options->subsystem_name[i]) == 0)
1212 1214 fatal("%s line %d: Subsystem '%s' already defined.",
1213 1215 filename, linenum, arg);
1214 1216 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1215 1217 arg = strdelim(&cp);
1216 1218 if (!arg || *arg == '\0')
1217 1219 fatal("%s line %d: Missing subsystem command.",
1218 1220 filename, linenum);
1219 1221 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1220 1222
1221 1223 /*
1222 1224 * Collect arguments (separate to executable), including the
1223 1225 * name of the executable, in a way that is easier to parse
1224 1226 * later.
1225 1227 */
1226 1228 p = xstrdup(arg);
1227 1229 len = strlen(p) + 1;
1228 1230 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1229 1231 len += 1 + strlen(arg);
1230 1232 p = xrealloc(p, len);
1231 1233 strlcat(p, " ", len);
1232 1234 strlcat(p, arg, len);
1233 1235 }
1234 1236 options->subsystem_args[options->num_subsystems] = p;
1235 1237 options->num_subsystems++;
1236 1238 break;
1237 1239
1238 1240 case sMaxStartups:
1239 1241 arg = strdelim(&cp);
1240 1242 if (!arg || *arg == '\0')
1241 1243 fatal("%s line %d: Missing MaxStartups spec.",
1242 1244 filename, linenum);
1243 1245 if ((n = sscanf(arg, "%d:%d:%d",
1244 1246 &options->max_startups_begin,
1245 1247 &options->max_startups_rate,
1246 1248 &options->max_startups)) == 3) {
1247 1249 if (options->max_startups_begin >
1248 1250 options->max_startups ||
1249 1251 options->max_startups_rate > 100 ||
1250 1252 options->max_startups_rate < 1)
1251 1253 fatal("%s line %d: Illegal MaxStartups spec.",
1252 1254 filename, linenum);
1253 1255 } else if (n != 1)
1254 1256 fatal("%s line %d: Illegal MaxStartups spec.",
1255 1257 filename, linenum);
1256 1258 else
1257 1259 options->max_startups = options->max_startups_begin;
1258 1260 break;
1259 1261
1260 1262 case sBanner:
1261 1263 charptr = &options->banner;
1262 1264 goto parse_filename;
1263 1265 /*
1264 1266 * These options can contain %X options expanded at
1265 1267 * connect time, so that you can specify paths like:
1266 1268 *
1267 1269 * AuthorizedKeysFile /etc/ssh_keys/%u
1268 1270 */
1269 1271 case sAuthorizedKeysFile:
1270 1272 case sAuthorizedKeysFile2:
1271 1273 charptr = (opcode == sAuthorizedKeysFile) ?
1272 1274 &options->authorized_keys_file :
1273 1275 &options->authorized_keys_file2;
1274 1276 goto parse_filename;
1275 1277
1276 1278 case sClientAliveInterval:
1277 1279 intptr = &options->client_alive_interval;
1278 1280 goto parse_time;
1279 1281
1280 1282 case sClientAliveCountMax:
1281 1283 intptr = &options->client_alive_count_max;
1282 1284 goto parse_int;
1283 1285
1284 1286 case sMaxAuthTries:
1285 1287 intptr = &options->max_auth_tries;
1286 1288 goto parse_int;
1287 1289
1288 1290 case sMaxAuthTriesLog:
1289 1291 intptr = &options->max_auth_tries_log;
1290 1292 goto parse_int;
1291 1293
1292 1294 case sLookupClientHostnames:
1293 1295 intptr = &options->lookup_client_hostnames;
1294 1296 goto parse_flag;
1295 1297
1296 1298 case sUseOpenSSLEngine:
1297 1299 intptr = &options->use_openssl_engine;
1298 1300 goto parse_flag;
1299 1301
1300 1302 case sChrootDirectory:
1301 1303 charptr = &options->chroot_directory;
1302 1304
1303 1305 arg = strdelim(&cp);
1304 1306 if (arg == NULL || *arg == '\0')
1305 1307 fatal("%s line %d: missing directory name for "
1306 1308 "ChrootDirectory.", filename, linenum);
1307 1309 if (*activep && *charptr == NULL)
1308 1310 *charptr = xstrdup(arg);
1309 1311 break;
1310 1312
1311 1313 case sPreUserauthHook:
1312 1314 charptr = &options->pre_userauth_hook;
1313 1315 goto parse_filename;
1314 1316
1315 1317 case sMatch:
1316 1318 if (cmdline)
1317 1319 fatal("Match directive not supported as a command-line "
1318 1320 "option");
1319 1321 value = match_cfg_line(&cp, linenum, user, host, address);
1320 1322 if (value < 0)
1321 1323 fatal("%s line %d: Bad Match condition", filename,
1322 1324 linenum);
1323 1325 *activep = value;
1324 1326 break;
1325 1327
1326 1328 case sDeprecated:
1327 1329 log("%s line %d: Deprecated option %s",
1328 1330 filename, linenum, arg);
1329 1331 while (arg)
1330 1332 arg = strdelim(&cp);
1331 1333 break;
1332 1334
1333 1335 case sPAMServicePrefix:
1334 1336 arg = strdelim(&cp);
1335 1337 if (!arg || *arg == '\0')
1336 1338 fatal("%s line %d: Missing argument.",
1337 1339 filename, linenum);
1338 1340 if (options->pam_service_name != NULL)
1339 1341 fatal("%s line %d: PAMServiceName and PAMServicePrefix "
1340 1342 "are mutually exclusive.", filename, linenum);
1341 1343 if (options->pam_service_prefix == NULL)
1342 1344 options->pam_service_prefix = xstrdup(arg);
1343 1345 break;
1344 1346
1345 1347 case sPAMServiceName:
1346 1348 arg = strdelim(&cp);
1347 1349 if (!arg || *arg == '\0')
1348 1350 fatal("%s line %d: Missing argument.",
1349 1351 filename, linenum);
1350 1352 if (options->pam_service_prefix != NULL)
1351 1353 fatal("%s line %d: PAMServiceName and PAMServicePrefix "
1352 1354 "are mutually exclusive.", filename, linenum);
1353 1355 if (options->pam_service_name == NULL)
1354 1356 options->pam_service_name = xstrdup(arg);
1355 1357 break;
1356 1358
1357 1359 default:
1358 1360 fatal("%s line %d: Missing handler for opcode %s (%d)",
1359 1361 filename, linenum, arg, opcode);
1360 1362 }
1361 1363 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1362 1364 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1363 1365 filename, linenum, arg);
1364 1366 return 0;
1365 1367 }
1366 1368
1367 1369
1368 1370 /* Reads the server configuration file. */
1369 1371
1370 1372 void
1371 1373 load_server_config(const char *filename, Buffer *conf)
1372 1374 {
1373 1375 char line[1024], *cp;
1374 1376 FILE *f;
1375 1377
1376 1378 debug2("%s: filename %s", __func__, filename);
1377 1379 if ((f = fopen(filename, "r")) == NULL) {
1378 1380 perror(filename);
1379 1381 exit(1);
1380 1382 }
1381 1383 buffer_clear(conf);
1382 1384 while (fgets(line, sizeof(line), f)) {
1383 1385 /*
1384 1386 * Trim out comments and strip whitespace
1385 1387 * NB - preserve newlines, they are needed to reproduce
1386 1388 * line numbers later for error messages
1387 1389 */
1388 1390 if ((cp = strchr(line, '#')) != NULL)
1389 1391 memcpy(cp, "\n", 2);
1390 1392 cp = line + strspn(line, " \t\r");
1391 1393
1392 1394 buffer_append(conf, cp, strlen(cp));
1393 1395 }
1394 1396 buffer_append(conf, "\0", 1);
1395 1397 fclose(f);
1396 1398 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1397 1399 }
1398 1400
1399 1401 void
1400 1402 parse_server_match_config(ServerOptions *options, const char *user,
1401 1403 const char *host, const char *address)
1402 1404 {
1403 1405 ServerOptions mo;
1404 1406
1405 1407 initialize_server_options(&mo);
1406 1408 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1407 1409 copy_set_server_options(options, &mo, 0);
1408 1410 }
1409 1411
1410 1412
1411 1413
1412 1414 /* Helper macros */
1413 1415 #define M_CP_INTOPT(n) do {\
1414 1416 if (src->n != -1) \
1415 1417 dst->n = src->n; \
1416 1418 } while (0)
1417 1419 #define M_CP_STROPT(n) do {\
1418 1420 if (src->n != NULL) { \
1419 1421 if (dst->n != NULL) \
1420 1422 xfree(dst->n); \
1421 1423 dst->n = src->n; \
1422 1424 } \
1423 1425 } while(0)
1424 1426
1425 1427 /*
1426 1428 * Copy any supported values that are set.
1427 1429 *
1428 1430 * If the preauth flag is set, we do not bother copying the the string or
1429 1431 * array values that are not used pre-authentication, because any that we
1430 1432 * do use must be explictly sent in mm_getpwnamallow().
1431 1433 */
1432 1434 void
1433 1435 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1434 1436 {
1435 1437 M_CP_INTOPT(password_authentication);
1436 1438 M_CP_INTOPT(gss_authentication);
1437 1439 M_CP_INTOPT(rsa_authentication);
1438 1440 M_CP_INTOPT(pubkey_authentication);
1439 1441 M_CP_INTOPT(hostbased_authentication);
1440 1442 M_CP_INTOPT(kbd_interactive_authentication);
1441 1443 M_CP_INTOPT(permit_root_login);
1442 1444 M_CP_INTOPT(permit_empty_passwd);
1443 1445 M_CP_INTOPT(allow_tcp_forwarding);
1444 1446 M_CP_INTOPT(gateway_ports);
1445 1447 M_CP_INTOPT(x11_display_offset);
1446 1448 M_CP_INTOPT(x11_forwarding);
1447 1449 M_CP_INTOPT(x11_use_localhost);
1448 1450 M_CP_INTOPT(max_auth_tries);
1449 1451 M_CP_STROPT(banner);
1450 1452
1451 1453 if (preauth)
1452 1454 return;
1453 1455 M_CP_STROPT(chroot_directory);
1454 1456 }
1455 1457
1456 1458 #undef M_CP_INTOPT
1457 1459 #undef M_CP_STROPT
1458 1460
1459 1461 void
1460 1462 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1461 1463 const char *user, const char *host, const char *address)
1462 1464 {
1463 1465 int active, linenum, bad_options = 0;
1464 1466 char *cp, *obuf, *cbuf;
1465 1467
1466 1468 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1467 1469
1468 1470 obuf = cbuf = xstrdup(buffer_ptr(conf));
1469 1471 active = user ? 0 : 1;
1470 1472 linenum = 1;
1471 1473 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1472 1474 if (process_server_config_line(options, cp, filename,
1473 1475 linenum++, &active, user, host, address) != 0)
1474 1476 bad_options++;
1475 1477 }
1476 1478 xfree(obuf);
1477 1479 if (bad_options > 0)
1478 1480 fatal("%s: terminating, %d bad configuration options",
1479 1481 filename, bad_options);
1480 1482 }
1481 1483
1482 1484
1483 1485 /*
1484 1486 * Note that "none" is a special path having the same affect on sshd
1485 1487 * configuration as not specifying ChrootDirectory at all.
1486 1488 */
1487 1489 int
1488 1490 chroot_requested(char *chroot_directory)
1489 1491 {
1490 1492 return (chroot_directory != NULL &&
1491 1493 strcasecmp(chroot_directory, "none") != 0);
1492 1494 }
↓ open down ↓ |
978 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX