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