Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/security/auth/login/Configuration.java
38918 views
1
/*
2
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package javax.security.auth.login;
27
28
import javax.security.auth.AuthPermission;
29
30
import java.security.AccessController;
31
import java.security.PrivilegedAction;
32
import java.security.PrivilegedExceptionAction;
33
import java.security.PrivilegedActionException;
34
import java.security.NoSuchAlgorithmException;
35
import java.security.NoSuchProviderException;
36
import java.security.Provider;
37
import java.security.Security;
38
import java.util.Objects;
39
40
import sun.security.jca.GetInstance;
41
42
/**
43
* A Configuration object is responsible for specifying which LoginModules
44
* should be used for a particular application, and in what order the
45
* LoginModules should be invoked.
46
*
47
* <p> A login configuration contains the following information.
48
* Note that this example only represents the default syntax for the
49
* {@code Configuration}. Subclass implementations of this class
50
* may implement alternative syntaxes and may retrieve the
51
* {@code Configuration} from any source such as files, databases,
52
* or servers.
53
*
54
* <pre>
55
* Name {
56
* ModuleClass Flag ModuleOptions;
57
* ModuleClass Flag ModuleOptions;
58
* ModuleClass Flag ModuleOptions;
59
* };
60
* Name {
61
* ModuleClass Flag ModuleOptions;
62
* ModuleClass Flag ModuleOptions;
63
* };
64
* other {
65
* ModuleClass Flag ModuleOptions;
66
* ModuleClass Flag ModuleOptions;
67
* };
68
* </pre>
69
*
70
* <p> Each entry in the {@code Configuration} is indexed via an
71
* application name, <i>Name</i>, and contains a list of
72
* LoginModules configured for that application. Each {@code LoginModule}
73
* is specified via its fully qualified class name.
74
* Authentication proceeds down the module list in the exact order specified.
75
* If an application does not have a specific entry,
76
* it defaults to the specific entry for "<i>other</i>".
77
*
78
* <p> The <i>Flag</i> value controls the overall behavior as authentication
79
* proceeds down the stack. The following represents a description of the
80
* valid values for <i>Flag</i> and their respective semantics:
81
*
82
* <pre>
83
* 1) Required - The {@code LoginModule} is required to succeed.
84
* If it succeeds or fails, authentication still continues
85
* to proceed down the {@code LoginModule} list.
86
*
87
* 2) Requisite - The {@code LoginModule} is required to succeed.
88
* If it succeeds, authentication continues down the
89
* {@code LoginModule} list. If it fails,
90
* control immediately returns to the application
91
* (authentication does not proceed down the
92
* {@code LoginModule} list).
93
*
94
* 3) Sufficient - The {@code LoginModule} is not required to
95
* succeed. If it does succeed, control immediately
96
* returns to the application (authentication does not
97
* proceed down the {@code LoginModule} list).
98
* If it fails, authentication continues down the
99
* {@code LoginModule} list.
100
*
101
* 4) Optional - The {@code LoginModule} is not required to
102
* succeed. If it succeeds or fails,
103
* authentication still continues to proceed down the
104
* {@code LoginModule} list.
105
* </pre>
106
*
107
* <p> The overall authentication succeeds only if all <i>Required</i> and
108
* <i>Requisite</i> LoginModules succeed. If a <i>Sufficient</i>
109
* {@code LoginModule} is configured and succeeds,
110
* then only the <i>Required</i> and <i>Requisite</i> LoginModules prior to
111
* that <i>Sufficient</i> {@code LoginModule} need to have succeeded for
112
* the overall authentication to succeed. If no <i>Required</i> or
113
* <i>Requisite</i> LoginModules are configured for an application,
114
* then at least one <i>Sufficient</i> or <i>Optional</i>
115
* {@code LoginModule} must succeed.
116
*
117
* <p> <i>ModuleOptions</i> is a space separated list of
118
* {@code LoginModule}-specific values which are passed directly to
119
* the underlying LoginModules. Options are defined by the
120
* {@code LoginModule} itself, and control the behavior within it.
121
* For example, a {@code LoginModule} may define options to support
122
* debugging/testing capabilities. The correct way to specify options in the
123
* {@code Configuration} is by using the following key-value pairing:
124
* <i>debug="true"</i>. The key and value should be separated by an
125
* 'equals' symbol, and the value should be surrounded by double quotes.
126
* If a String in the form, ${system.property}, occurs in the value,
127
* it will be expanded to the value of the system property.
128
* Note that there is no limit to the number of
129
* options a {@code LoginModule} may define.
130
*
131
* <p> The following represents an example {@code Configuration} entry
132
* based on the syntax above:
133
*
134
* <pre>
135
* Login {
136
* com.sun.security.auth.module.UnixLoginModule required;
137
* com.sun.security.auth.module.Krb5LoginModule optional
138
* useTicketCache="true"
139
* ticketCache="${user.home}${/}tickets";
140
* };
141
* </pre>
142
*
143
* <p> This {@code Configuration} specifies that an application named,
144
* "Login", requires users to first authenticate to the
145
* <i>com.sun.security.auth.module.UnixLoginModule</i>, which is
146
* required to succeed. Even if the <i>UnixLoginModule</i>
147
* authentication fails, the
148
* <i>com.sun.security.auth.module.Krb5LoginModule</i>
149
* still gets invoked. This helps hide the source of failure.
150
* Since the <i>Krb5LoginModule</i> is <i>Optional</i>, the overall
151
* authentication succeeds only if the <i>UnixLoginModule</i>
152
* (<i>Required</i>) succeeds.
153
*
154
* <p> Also note that the LoginModule-specific options,
155
* <i>useTicketCache="true"</i> and
156
* <i>ticketCache=${user.home}${/}tickets"</i>,
157
* are passed to the <i>Krb5LoginModule</i>.
158
* These options instruct the <i>Krb5LoginModule</i> to
159
* use the ticket cache at the specified location.
160
* The system properties, <i>user.home</i> and <i>/</i>
161
* (file.separator), are expanded to their respective values.
162
*
163
* <p> There is only one Configuration object installed in the runtime at any
164
* given time. A Configuration object can be installed by calling the
165
* {@code setConfiguration} method. The installed Configuration object
166
* can be obtained by calling the {@code getConfiguration} method.
167
*
168
* <p> If no Configuration object has been installed in the runtime, a call to
169
* {@code getConfiguration} installs an instance of the default
170
* Configuration implementation (a default subclass implementation of this
171
* abstract class).
172
* The default Configuration implementation can be changed by setting the value
173
* of the {@code login.configuration.provider} security property to the fully
174
* qualified name of the desired Configuration subclass implementation.
175
*
176
* <p> Application code can directly subclass Configuration to provide a custom
177
* implementation. In addition, an instance of a Configuration object can be
178
* constructed by invoking one of the {@code getInstance} factory methods
179
* with a standard type. The default policy type is "JavaLoginConfig".
180
* See the Configuration section in the <a href=
181
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
182
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
183
* for a list of standard Configuration types.
184
*
185
* @see javax.security.auth.login.LoginContext
186
* @see java.security.Security security properties
187
*/
188
public abstract class Configuration {
189
190
private static Configuration configuration;
191
192
private final java.security.AccessControlContext acc =
193
java.security.AccessController.getContext();
194
195
private static void checkPermission(String type) {
196
SecurityManager sm = System.getSecurityManager();
197
if (sm != null) {
198
sm.checkPermission(new AuthPermission
199
("createLoginConfiguration." + type));
200
}
201
}
202
203
/**
204
* Sole constructor. (For invocation by subclass constructors, typically
205
* implicit.)
206
*/
207
protected Configuration() { }
208
209
/**
210
* Get the installed login Configuration.
211
*
212
* <p>
213
*
214
* @return the login Configuration. If a Configuration object was set
215
* via the {@code Configuration.setConfiguration} method,
216
* then that object is returned. Otherwise, a default
217
* Configuration object is returned.
218
*
219
* @exception SecurityException if the caller does not have permission
220
* to retrieve the Configuration.
221
*
222
* @see #setConfiguration
223
*/
224
public static Configuration getConfiguration() {
225
226
SecurityManager sm = System.getSecurityManager();
227
if (sm != null)
228
sm.checkPermission(new AuthPermission("getLoginConfiguration"));
229
230
synchronized (Configuration.class) {
231
if (configuration == null) {
232
String config_class = null;
233
config_class = AccessController.doPrivileged
234
(new PrivilegedAction<String>() {
235
public String run() {
236
return java.security.Security.getProperty
237
("login.configuration.provider");
238
}
239
});
240
if (config_class == null) {
241
config_class = "sun.security.provider.ConfigFile";
242
}
243
244
try {
245
final String finalClass = config_class;
246
Configuration untrustedImpl = AccessController.doPrivileged(
247
new PrivilegedExceptionAction<Configuration>() {
248
public Configuration run() throws ClassNotFoundException,
249
InstantiationException,
250
IllegalAccessException {
251
Class<? extends Configuration> implClass = Class.forName(
252
finalClass, false,
253
Thread.currentThread().getContextClassLoader()
254
).asSubclass(Configuration.class);
255
return implClass.newInstance();
256
}
257
});
258
AccessController.doPrivileged(
259
new PrivilegedExceptionAction<Void>() {
260
public Void run() {
261
setConfiguration(untrustedImpl);
262
return null;
263
}
264
}, Objects.requireNonNull(untrustedImpl.acc)
265
);
266
} catch (PrivilegedActionException e) {
267
Exception ee = e.getException();
268
if (ee instanceof InstantiationException) {
269
throw (SecurityException) new
270
SecurityException
271
("Configuration error:" +
272
ee.getCause().getMessage() +
273
"\n").initCause(ee.getCause());
274
} else {
275
throw (SecurityException) new
276
SecurityException
277
("Configuration error: " +
278
ee.toString() +
279
"\n").initCause(ee);
280
}
281
}
282
}
283
return configuration;
284
}
285
}
286
287
/**
288
* Set the login {@code Configuration}.
289
*
290
* <p>
291
*
292
* @param configuration the new {@code Configuration}
293
*
294
* @exception SecurityException if the current thread does not have
295
* Permission to set the {@code Configuration}.
296
*
297
* @see #getConfiguration
298
*/
299
public static void setConfiguration(Configuration configuration) {
300
SecurityManager sm = System.getSecurityManager();
301
if (sm != null)
302
sm.checkPermission(new AuthPermission("setLoginConfiguration"));
303
Configuration.configuration = configuration;
304
}
305
306
/**
307
* Returns a Configuration object of the specified type.
308
*
309
* <p> This method traverses the list of registered security providers,
310
* starting with the most preferred Provider.
311
* A new Configuration object encapsulating the
312
* ConfigurationSpi implementation from the first
313
* Provider that supports the specified type is returned.
314
*
315
* <p> Note that the list of registered providers may be retrieved via
316
* the {@link Security#getProviders() Security.getProviders()} method.
317
*
318
* @param type the specified Configuration type. See the Configuration
319
* section in the <a href=
320
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
321
* Java Cryptography Architecture Standard Algorithm Name
322
* Documentation</a> for a list of standard Configuration types.
323
*
324
* @param params parameters for the Configuration, which may be null.
325
*
326
* @return the new Configuration object.
327
*
328
* @exception SecurityException if the caller does not have permission
329
* to get a Configuration instance for the specified type.
330
*
331
* @exception NullPointerException if the specified type is null.
332
*
333
* @exception IllegalArgumentException if the specified parameters
334
* are not understood by the ConfigurationSpi implementation
335
* from the selected Provider.
336
*
337
* @exception NoSuchAlgorithmException if no Provider supports a
338
* ConfigurationSpi implementation for the specified type.
339
*
340
* @see Provider
341
* @since 1.6
342
*/
343
public static Configuration getInstance(String type,
344
Configuration.Parameters params)
345
throws NoSuchAlgorithmException {
346
347
checkPermission(type);
348
try {
349
GetInstance.Instance instance = GetInstance.getInstance
350
("Configuration",
351
ConfigurationSpi.class,
352
type,
353
params);
354
return new ConfigDelegate((ConfigurationSpi)instance.impl,
355
instance.provider,
356
type,
357
params);
358
} catch (NoSuchAlgorithmException nsae) {
359
return handleException (nsae);
360
}
361
}
362
363
/**
364
* Returns a Configuration object of the specified type.
365
*
366
* <p> A new Configuration object encapsulating the
367
* ConfigurationSpi implementation from the specified provider
368
* is returned. The specified provider must be registered
369
* in the provider list.
370
*
371
* <p> Note that the list of registered providers may be retrieved via
372
* the {@link Security#getProviders() Security.getProviders()} method.
373
*
374
* @param type the specified Configuration type. See the Configuration
375
* section in the <a href=
376
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
377
* Java Cryptography Architecture Standard Algorithm Name
378
* Documentation</a> for a list of standard Configuration types.
379
*
380
* @param params parameters for the Configuration, which may be null.
381
*
382
* @param provider the provider.
383
*
384
* @return the new Configuration object.
385
*
386
* @exception SecurityException if the caller does not have permission
387
* to get a Configuration instance for the specified type.
388
*
389
* @exception NullPointerException if the specified type is null.
390
*
391
* @exception IllegalArgumentException if the specified provider
392
* is null or empty,
393
* or if the specified parameters are not understood by
394
* the ConfigurationSpi implementation from the specified provider.
395
*
396
* @exception NoSuchProviderException if the specified provider is not
397
* registered in the security provider list.
398
*
399
* @exception NoSuchAlgorithmException if the specified provider does not
400
* support a ConfigurationSpi implementation for the specified
401
* type.
402
*
403
* @see Provider
404
* @since 1.6
405
*/
406
public static Configuration getInstance(String type,
407
Configuration.Parameters params,
408
String provider)
409
throws NoSuchProviderException, NoSuchAlgorithmException {
410
411
if (provider == null || provider.length() == 0) {
412
throw new IllegalArgumentException("missing provider");
413
}
414
415
checkPermission(type);
416
try {
417
GetInstance.Instance instance = GetInstance.getInstance
418
("Configuration",
419
ConfigurationSpi.class,
420
type,
421
params,
422
provider);
423
return new ConfigDelegate((ConfigurationSpi)instance.impl,
424
instance.provider,
425
type,
426
params);
427
} catch (NoSuchAlgorithmException nsae) {
428
return handleException (nsae);
429
}
430
}
431
432
/**
433
* Returns a Configuration object of the specified type.
434
*
435
* <p> A new Configuration object encapsulating the
436
* ConfigurationSpi implementation from the specified Provider
437
* object is returned. Note that the specified Provider object
438
* does not have to be registered in the provider list.
439
*
440
* @param type the specified Configuration type. See the Configuration
441
* section in the <a href=
442
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
443
* Java Cryptography Architecture Standard Algorithm Name
444
* Documentation</a> for a list of standard Configuration types.
445
*
446
* @param params parameters for the Configuration, which may be null.
447
*
448
* @param provider the Provider.
449
*
450
* @return the new Configuration object.
451
*
452
* @exception SecurityException if the caller does not have permission
453
* to get a Configuration instance for the specified type.
454
*
455
* @exception NullPointerException if the specified type is null.
456
*
457
* @exception IllegalArgumentException if the specified Provider is null,
458
* or if the specified parameters are not understood by
459
* the ConfigurationSpi implementation from the specified Provider.
460
*
461
* @exception NoSuchAlgorithmException if the specified Provider does not
462
* support a ConfigurationSpi implementation for the specified
463
* type.
464
*
465
* @see Provider
466
* @since 1.6
467
*/
468
public static Configuration getInstance(String type,
469
Configuration.Parameters params,
470
Provider provider)
471
throws NoSuchAlgorithmException {
472
473
if (provider == null) {
474
throw new IllegalArgumentException("missing provider");
475
}
476
477
checkPermission(type);
478
try {
479
GetInstance.Instance instance = GetInstance.getInstance
480
("Configuration",
481
ConfigurationSpi.class,
482
type,
483
params,
484
provider);
485
return new ConfigDelegate((ConfigurationSpi)instance.impl,
486
instance.provider,
487
type,
488
params);
489
} catch (NoSuchAlgorithmException nsae) {
490
return handleException (nsae);
491
}
492
}
493
494
private static Configuration handleException(NoSuchAlgorithmException nsae)
495
throws NoSuchAlgorithmException {
496
Throwable cause = nsae.getCause();
497
if (cause instanceof IllegalArgumentException) {
498
throw (IllegalArgumentException)cause;
499
}
500
throw nsae;
501
}
502
503
/**
504
* Return the Provider of this Configuration.
505
*
506
* <p> This Configuration instance will only have a Provider if it
507
* was obtained via a call to {@code Configuration.getInstance}.
508
* Otherwise this method returns null.
509
*
510
* @return the Provider of this Configuration, or null.
511
*
512
* @since 1.6
513
*/
514
public Provider getProvider() {
515
return null;
516
}
517
518
/**
519
* Return the type of this Configuration.
520
*
521
* <p> This Configuration instance will only have a type if it
522
* was obtained via a call to {@code Configuration.getInstance}.
523
* Otherwise this method returns null.
524
*
525
* @return the type of this Configuration, or null.
526
*
527
* @since 1.6
528
*/
529
public String getType() {
530
return null;
531
}
532
533
/**
534
* Return Configuration parameters.
535
*
536
* <p> This Configuration instance will only have parameters if it
537
* was obtained via a call to {@code Configuration.getInstance}.
538
* Otherwise this method returns null.
539
*
540
* @return Configuration parameters, or null.
541
*
542
* @since 1.6
543
*/
544
public Configuration.Parameters getParameters() {
545
return null;
546
}
547
548
/**
549
* Retrieve the AppConfigurationEntries for the specified <i>name</i>
550
* from this Configuration.
551
*
552
* <p>
553
*
554
* @param name the name used to index the Configuration.
555
*
556
* @return an array of AppConfigurationEntries for the specified <i>name</i>
557
* from this Configuration, or null if there are no entries
558
* for the specified <i>name</i>
559
*/
560
public abstract AppConfigurationEntry[] getAppConfigurationEntry
561
(String name);
562
563
/**
564
* Refresh and reload the Configuration.
565
*
566
* <p> This method causes this Configuration object to refresh/reload its
567
* contents in an implementation-dependent manner.
568
* For example, if this Configuration object stores its entries in a file,
569
* calling {@code refresh} may cause the file to be re-read.
570
*
571
* <p> The default implementation of this method does nothing.
572
* This method should be overridden if a refresh operation is supported
573
* by the implementation.
574
*
575
* @exception SecurityException if the caller does not have permission
576
* to refresh its Configuration.
577
*/
578
public void refresh() { }
579
580
/**
581
* This subclass is returned by the getInstance calls. All Configuration
582
* calls are delegated to the underlying ConfigurationSpi.
583
*/
584
private static class ConfigDelegate extends Configuration {
585
586
private ConfigurationSpi spi;
587
private Provider p;
588
private String type;
589
private Configuration.Parameters params;
590
591
private ConfigDelegate(ConfigurationSpi spi, Provider p,
592
String type, Configuration.Parameters params) {
593
this.spi = spi;
594
this.p = p;
595
this.type = type;
596
this.params = params;
597
}
598
599
public String getType() { return type; }
600
601
public Configuration.Parameters getParameters() { return params; }
602
603
public Provider getProvider() { return p; }
604
605
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
606
return spi.engineGetAppConfigurationEntry(name);
607
}
608
609
public void refresh() {
610
spi.engineRefresh();
611
}
612
}
613
614
/**
615
* This represents a marker interface for Configuration parameters.
616
*
617
* @since 1.6
618
*/
619
public static interface Parameters { }
620
}
621
622