aboutsummaryrefslogtreecommitdiff
path: root/src/org/apache/harmony/javax/security/auth/login
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/apache/harmony/javax/security/auth/login')
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/AccountException.java31
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/AccountExpiredException.java31
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/AccountLockedException.java32
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/AccountNotFoundException.java32
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/AppConfigurationEntry.java95
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/Configuration.java102
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/CredentialException.java32
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/CredentialExpiredException.java32
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/CredentialNotFoundException.java32
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/FailedLoginException.java32
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/LoginContext.java548
-rw-r--r--src/org/apache/harmony/javax/security/auth/login/LoginException.java45
12 files changed, 1044 insertions, 0 deletions
diff --git a/src/org/apache/harmony/javax/security/auth/login/AccountException.java b/src/org/apache/harmony/javax/security/auth/login/AccountException.java
new file mode 100644
index 0000000..c86e801
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/AccountException.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+public class AccountException extends LoginException {
+
+ private static final long serialVersionUID = -2112878680072211787L;
+
+ public AccountException() {
+ super();
+ }
+
+ public AccountException(String message) {
+ super(message);
+ }
+}
diff --git a/src/org/apache/harmony/javax/security/auth/login/AccountExpiredException.java b/src/org/apache/harmony/javax/security/auth/login/AccountExpiredException.java
new file mode 100644
index 0000000..1e0ce4d
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/AccountExpiredException.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+public class AccountExpiredException extends AccountException {
+
+ private static final long serialVersionUID = -6064064890162661560L;
+
+ public AccountExpiredException() {
+ super();
+ }
+
+ public AccountExpiredException(String message) {
+ super(message);
+ }
+}
diff --git a/src/org/apache/harmony/javax/security/auth/login/AccountLockedException.java b/src/org/apache/harmony/javax/security/auth/login/AccountLockedException.java
new file mode 100644
index 0000000..47913a5
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/AccountLockedException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+public class AccountLockedException extends AccountException {
+
+ private static final long serialVersionUID = 8280345554014066334L;
+
+ public AccountLockedException() {
+ super();
+ }
+
+ public AccountLockedException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/org/apache/harmony/javax/security/auth/login/AccountNotFoundException.java b/src/org/apache/harmony/javax/security/auth/login/AccountNotFoundException.java
new file mode 100644
index 0000000..8ca9b96
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/AccountNotFoundException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+public class AccountNotFoundException extends AccountException {
+
+ private static final long serialVersionUID = 1498349563916294614L;
+
+ public AccountNotFoundException() {
+ super();
+ }
+
+ public AccountNotFoundException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/org/apache/harmony/javax/security/auth/login/AppConfigurationEntry.java b/src/org/apache/harmony/javax/security/auth/login/AppConfigurationEntry.java
new file mode 100644
index 0000000..2a735dc
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/AppConfigurationEntry.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+import java.util.Collections;
+import java.util.Map;
+
+
+
+public class AppConfigurationEntry {
+
+ // the login module options
+ private final Map<String, ?> options;
+
+ // the control flag
+ private final AppConfigurationEntry.LoginModuleControlFlag controlFlag;
+
+ // the login module name
+ private final String loginModuleName;
+
+ public AppConfigurationEntry(String loginModuleName,
+ AppConfigurationEntry.LoginModuleControlFlag controlFlag, Map<String, ?> options) {
+
+ if (loginModuleName == null || loginModuleName.length() == 0) {
+ throw new IllegalArgumentException("auth.26"); //$NON-NLS-1$
+ }
+
+ if (controlFlag == null) {
+ throw new IllegalArgumentException("auth.27"); //$NON-NLS-1$
+ }
+
+ if (options == null) {
+ throw new IllegalArgumentException("auth.1A"); //$NON-NLS-1$
+ }
+
+ this.loginModuleName = loginModuleName;
+ this.controlFlag = controlFlag;
+ this.options = Collections.unmodifiableMap(options);
+ }
+
+ public String getLoginModuleName() {
+ return loginModuleName;
+ }
+
+ public LoginModuleControlFlag getControlFlag() {
+ return controlFlag;
+ }
+
+ public Map<java.lang.String, ?> getOptions() {
+ return options;
+ }
+
+ public static class LoginModuleControlFlag {
+
+ // the control flag
+ private final String flag;
+
+ public static final LoginModuleControlFlag REQUIRED = new LoginModuleControlFlag(
+ "LoginModuleControlFlag: required"); //$NON-NLS-1$
+
+ public static final LoginModuleControlFlag REQUISITE = new LoginModuleControlFlag(
+ "LoginModuleControlFlag: requisite"); //$NON-NLS-1$
+
+ public static final LoginModuleControlFlag OPTIONAL = new LoginModuleControlFlag(
+ "LoginModuleControlFlag: optional"); //$NON-NLS-1$
+
+ public static final LoginModuleControlFlag SUFFICIENT = new LoginModuleControlFlag(
+ "LoginModuleControlFlag: sufficient"); //$NON-NLS-1$
+
+ // Creates the LoginModuleControlFlag object with specified a flag
+ private LoginModuleControlFlag(String flag) {
+ this.flag = flag;
+ }
+
+ @Override
+ public String toString() {
+ return flag;
+ }
+ }
+}
diff --git a/src/org/apache/harmony/javax/security/auth/login/Configuration.java b/src/org/apache/harmony/javax/security/auth/login/Configuration.java
new file mode 100644
index 0000000..74c371f
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/Configuration.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+import java.security.AccessController;
+import org.apache.harmony.javax.security.auth.AuthPermission;
+
+public abstract class Configuration {
+
+ // the current configuration
+ private static Configuration configuration;
+
+ // creates a AuthPermission object with a specify property
+ private static final AuthPermission GET_LOGIN_CONFIGURATION = new AuthPermission(
+ "getLoginConfiguration"); //$NON-NLS-1$
+
+ // creates a AuthPermission object with a specify property
+ private static final AuthPermission SET_LOGIN_CONFIGURATION = new AuthPermission(
+ "setLoginConfiguration"); //$NON-NLS-1$
+
+ // Key to security properties, defining default configuration provider.
+ private static final String LOGIN_CONFIGURATION_PROVIDER = "login.configuration.provider"; //$NON-NLS-1$
+
+ protected Configuration() {
+ super();
+ }
+
+ public static Configuration getConfiguration() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(GET_LOGIN_CONFIGURATION);
+ }
+ return getAccessibleConfiguration();
+ }
+
+ /**
+ * Reads name of default configuration provider from security.properties,
+ * loads the class and instantiates the provider.<br> In case of any
+ * exception, wraps it with SecurityException and throws further.
+ */
+ private static final Configuration getDefaultProvider() {
+ return new Configuration() {
+
+ @Override
+ public void refresh() {
+ }
+
+ @Override
+ public AppConfigurationEntry[] getAppConfigurationEntry(
+ String applicationName) {
+ return new AppConfigurationEntry[0];
+ }
+ };
+ }
+
+ /**
+ * Shortcut accessor for friendly classes, to skip security checks.
+ * If active configuration was set to <code>null</code>, tries to load a default
+ * provider, so this method never returns <code>null</code>. <br>
+ * This method is synchronized with setConfiguration()
+ */
+ static Configuration getAccessibleConfiguration() {
+ Configuration current = configuration;
+ if (current == null) {
+ synchronized (Configuration.class) {
+ if (configuration == null) {
+ configuration = getDefaultProvider();
+ }
+ return configuration;
+ }
+ }
+ return current;
+ }
+
+ public static void setConfiguration(Configuration configuration) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(SET_LOGIN_CONFIGURATION);
+ }
+ Configuration.configuration = configuration;
+ }
+
+ public abstract AppConfigurationEntry[] getAppConfigurationEntry(String applicationName);
+
+ public abstract void refresh();
+
+}
diff --git a/src/org/apache/harmony/javax/security/auth/login/CredentialException.java b/src/org/apache/harmony/javax/security/auth/login/CredentialException.java
new file mode 100644
index 0000000..e74e866
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/CredentialException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+public class CredentialException extends LoginException {
+
+ private static final long serialVersionUID = -4772893876810601859L;
+
+ public CredentialException() {
+ super();
+ }
+
+ public CredentialException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/org/apache/harmony/javax/security/auth/login/CredentialExpiredException.java b/src/org/apache/harmony/javax/security/auth/login/CredentialExpiredException.java
new file mode 100644
index 0000000..3ca3ad7
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/CredentialExpiredException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+public class CredentialExpiredException extends CredentialException {
+
+ private static final long serialVersionUID = -5344739593859737937L;
+
+ public CredentialExpiredException() {
+ super();
+ }
+
+ public CredentialExpiredException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/org/apache/harmony/javax/security/auth/login/CredentialNotFoundException.java b/src/org/apache/harmony/javax/security/auth/login/CredentialNotFoundException.java
new file mode 100644
index 0000000..ffd529f
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/CredentialNotFoundException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+public class CredentialNotFoundException extends CredentialException {
+
+ private static final long serialVersionUID = -7779934467214319475L;
+
+ public CredentialNotFoundException() {
+ super();
+ }
+
+ public CredentialNotFoundException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/org/apache/harmony/javax/security/auth/login/FailedLoginException.java b/src/org/apache/harmony/javax/security/auth/login/FailedLoginException.java
new file mode 100644
index 0000000..f689d99
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/FailedLoginException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+public class FailedLoginException extends LoginException {
+
+ private static final long serialVersionUID = 802556922354616286L;
+
+ public FailedLoginException() {
+ super();
+ }
+
+ public FailedLoginException(String message) {
+ super(message);
+ }
+
+} \ No newline at end of file
diff --git a/src/org/apache/harmony/javax/security/auth/login/LoginContext.java b/src/org/apache/harmony/javax/security/auth/login/LoginContext.java
new file mode 100644
index 0000000..7d46278
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/LoginContext.java
@@ -0,0 +1,548 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+
+import java.security.Security;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.harmony.javax.security.auth.Subject;
+import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
+import org.apache.harmony.javax.security.auth.callback.Callback;
+import org.apache.harmony.javax.security.auth.callback.UnsupportedCallbackException;
+import org.apache.harmony.javax.security.auth.spi.LoginModule;
+import org.apache.harmony.javax.security.auth.AuthPermission;
+
+import org.apache.harmony.javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
+
+
+
+public class LoginContext {
+
+ private static final String DEFAULT_CALLBACK_HANDLER_PROPERTY = "auth.login.defaultCallbackHandler"; //$NON-NLS-1$
+
+ /*
+ * Integer constants which serve as a replacement for the corresponding
+ * LoginModuleControlFlag.* constants. These integers are used later as
+ * index in the arrays - see loginImpl() and logoutImpl() methods
+ */
+ private static final int OPTIONAL = 0;
+
+ private static final int REQUIRED = 1;
+
+ private static final int REQUISITE = 2;
+
+ private static final int SUFFICIENT = 3;
+
+ // Subject to be used for this LoginContext's operations
+ private Subject subject;
+
+ /*
+ * Shows whether the subject was specified by user (true) or was created by
+ * this LoginContext itself (false).
+ */
+ private boolean userProvidedSubject;
+
+ // Shows whether we use installed or user-provided Configuration
+ private boolean userProvidedConfig;
+
+ // An user's AccessControlContext, used when user specifies
+ private AccessControlContext userContext;
+
+ /*
+ * Either a callback handler passed by the user or a wrapper for the user's
+ * specified handler - see init() below.
+ */
+ private CallbackHandler callbackHandler;
+
+ /*
+ * An array which keeps the instantiated and init()-ialized login modules
+ * and their states
+ */
+ private Module[] modules;
+
+ // Stores a shared state
+ private Map<String, ?> sharedState;
+
+ // A context class loader used to load [mainly] LoginModules
+ private ClassLoader contextClassLoader;
+
+ // Shows overall status - whether this LoginContext was successfully logged
+ private boolean loggedIn;
+
+ public LoginContext(String name) throws LoginException {
+ super();
+ init(name, null, null, null);
+ }
+
+ public LoginContext(String name, CallbackHandler cbHandler) throws LoginException {
+ super();
+ if (cbHandler == null) {
+ throw new LoginException("auth.34"); //$NON-NLS-1$
+ }
+ init(name, null, cbHandler, null);
+ }
+
+ public LoginContext(String name, Subject subject) throws LoginException {
+ super();
+ if (subject == null) {
+ throw new LoginException("auth.03"); //$NON-NLS-1$
+ }
+ init(name, subject, null, null);
+ }
+
+ public LoginContext(String name, Subject subject, CallbackHandler cbHandler)
+ throws LoginException {
+ super();
+ if (subject == null) {
+ throw new LoginException("auth.03"); //$NON-NLS-1$
+ }
+ if (cbHandler == null) {
+ throw new LoginException("auth.34"); //$NON-NLS-1$
+ }
+ init(name, subject, cbHandler, null);
+ }
+
+ public LoginContext(String name, Subject subject, CallbackHandler cbHandler,
+ Configuration config) throws LoginException {
+ super();
+ init(name, subject, cbHandler, config);
+ }
+
+ // Does all the machinery needed for the initialization.
+ private void init(String name, Subject subject, final CallbackHandler cbHandler,
+ Configuration config) throws LoginException {
+ userProvidedSubject = (this.subject = subject) != null;
+
+ //
+ // Set config
+ //
+ if (name == null) {
+ throw new LoginException("auth.00"); //$NON-NLS-1$
+ }
+
+ if (config == null) {
+ config = Configuration.getAccessibleConfiguration();
+ } else {
+ userProvidedConfig = true;
+ }
+
+ SecurityManager sm = System.getSecurityManager();
+
+ if (sm != null && !userProvidedConfig) {
+ sm.checkPermission(new AuthPermission("createLoginContext." + name));//$NON-NLS-1$
+ }
+
+ AppConfigurationEntry[] entries = config.getAppConfigurationEntry(name);
+ if (entries == null) {
+ if (sm != null && !userProvidedConfig) {
+ sm.checkPermission(new AuthPermission("createLoginContext.other")); //$NON-NLS-1$
+ }
+ entries = config.getAppConfigurationEntry("other"); //$NON-NLS-1$
+ if (entries == null) {
+ throw new LoginException("auth.35 " + name); //$NON-NLS-1$
+ }
+ }
+
+ modules = new Module[entries.length];
+ for (int i = 0; i < modules.length; i++) {
+ modules[i] = new Module(entries[i]);
+ }
+ //
+ // Set CallbackHandler and this.contextClassLoader
+ //
+
+ /*
+ * as some of the operations to be executed (i.e. get*ClassLoader,
+ * getProperty, class loading) are security-checked, then combine all of
+ * them into a single doPrivileged() call.
+ */
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+ public Void run() throws Exception {
+ // First, set the 'contextClassLoader'
+ contextClassLoader = Thread.currentThread().getContextClassLoader();
+ if (contextClassLoader == null) {
+ contextClassLoader = ClassLoader.getSystemClassLoader();
+ }
+ // then, checks whether the cbHandler is set
+ if (cbHandler == null) {
+ // well, let's try to find it
+ String klassName = Security
+ .getProperty(DEFAULT_CALLBACK_HANDLER_PROPERTY);
+ if (klassName == null || klassName.length() == 0) {
+ return null;
+ }
+ Class<?> klass = Class.forName(klassName, true, contextClassLoader);
+ callbackHandler = (CallbackHandler) klass.newInstance();
+ } else {
+ callbackHandler = cbHandler;
+ }
+ return null;
+ }
+ });
+ } catch (PrivilegedActionException ex) {
+ Throwable cause = ex.getCause();
+ throw (LoginException) new LoginException("auth.36").initCause(cause);//$NON-NLS-1$
+ }
+
+ if (userProvidedConfig) {
+ userContext = AccessController.getContext();
+ } else if (callbackHandler != null) {
+ userContext = AccessController.getContext();
+ callbackHandler = new ContextedCallbackHandler(callbackHandler);
+ }
+ }
+
+ public Subject getSubject() {
+ if (userProvidedSubject || loggedIn) {
+ return subject;
+ }
+ return null;
+ }
+
+ /**
+ * Warning: calling the method more than once may result in undefined
+ * behaviour if logout() method is not invoked before.
+ */
+ public void login() throws LoginException {
+ PrivilegedExceptionAction<Void> action = new PrivilegedExceptionAction<Void>() {
+ public Void run() throws LoginException {
+ loginImpl();
+ return null;
+ }
+ };
+ try {
+ if (userProvidedConfig) {
+ AccessController.doPrivileged(action, userContext);
+ } else {
+ AccessController.doPrivileged(action);
+ }
+ } catch (PrivilegedActionException ex) {
+ throw (LoginException) ex.getException();
+ }
+ }
+
+ /**
+ * The real implementation of login() method whose calls are wrapped into
+ * appropriate doPrivileged calls in login().
+ */
+ private void loginImpl() throws LoginException {
+ if (subject == null) {
+ subject = new Subject();
+ }
+
+ if (sharedState == null) {
+ sharedState = new HashMap<String, Object>();
+ }
+
+ // PHASE 1: Calling login()-s
+ Throwable firstProblem = null;
+
+ int[] logged = new int[4];
+ int[] total = new int[4];
+
+ for (Module module : modules) {
+ try {
+ // if a module fails during Class.forName(), then it breaks overall
+ // attempt - see catch() below
+ module.create(subject, callbackHandler, sharedState);
+
+ if (module.module.login()) {
+ ++total[module.getFlag()];
+ ++logged[module.getFlag()];
+ if (module.getFlag() == SUFFICIENT) {
+ break;
+ }
+ }
+ } catch (Throwable ex) {
+ if (firstProblem == null) {
+ firstProblem = ex;
+ }
+ if (module.klass == null) {
+ /*
+ * an exception occurred during class lookup - overall
+ * attempt must fail a little trick: increase the REQUIRED's
+ * number - this will look like a failed REQUIRED module
+ * later, so overall attempt will fail
+ */
+ ++total[REQUIRED];
+ break;
+ }
+ ++total[module.getFlag()];
+ // something happened after the class was loaded
+ if (module.getFlag() == REQUISITE) {
+ // ... and no need to walk down anymore
+ break;
+ }
+ }
+ }
+ // end of PHASE1,
+
+ // Let's decide whether we have either overall success or a total failure
+ boolean fail = true;
+
+ /*
+ * Note: 'failed[xxx]!=0' is not enough to check.
+ *
+ * Use 'logged[xx] != total[xx]' instead. This is because some modules
+ * might not be counted as 'failed' if an exception occurred during
+ * preload()/Class.forName()-ing. But, such modules still get counted in
+ * the total[].
+ */
+
+ // if any REQ* module failed - then it's failure
+ if (logged[REQUIRED] != total[REQUIRED] || logged[REQUISITE] != total[REQUISITE]) {
+ // fail = true;
+ } else {
+ if (total[REQUIRED] == 0 && total[REQUISITE] == 0) {
+ // neither REQUIRED nor REQUISITE was configured.
+ // must have at least one SUFFICIENT or OPTIONAL
+ if (logged[OPTIONAL] != 0 || logged[SUFFICIENT] != 0) {
+ fail = false;
+ }
+ //else { fail = true; }
+ } else {
+ fail = false;
+ }
+ }
+
+ int commited[] = new int[4];
+ // clear it
+ total[0] = total[1] = total[2] = total[3] = 0;
+ if (!fail) {
+ // PHASE 2:
+
+ for (Module module : modules) {
+ if (module.klass != null) {
+ ++total[module.getFlag()];
+ try {
+ module.module.commit();
+ ++commited[module.getFlag()];
+ } catch (Throwable ex) {
+ if (firstProblem == null) {
+ firstProblem = ex;
+ }
+ }
+ }
+ }
+ }
+
+ // need to decide once again
+ fail = true;
+ if (commited[REQUIRED] != total[REQUIRED] || commited[REQUISITE] != total[REQUISITE]) {
+ //fail = true;
+ } else {
+ if (total[REQUIRED] == 0 && total[REQUISITE] == 0) {
+ /*
+ * neither REQUIRED nor REQUISITE was configured. must have at
+ * least one SUFFICIENT or OPTIONAL
+ */
+ if (commited[OPTIONAL] != 0 || commited[SUFFICIENT] != 0) {
+ fail = false;
+ } else {
+ //fail = true;
+ }
+ } else {
+ fail = false;
+ }
+ }
+
+ if (fail) {
+ // either login() or commit() failed. aborting...
+
+ for (Module module : modules) {
+ try {
+ module.module.abort();
+ } catch ( /*LoginException*/Throwable ex) {
+ if (firstProblem == null) {
+ firstProblem = ex;
+ }
+ }
+ }
+ if (firstProblem instanceof PrivilegedActionException
+ && firstProblem.getCause() != null) {
+ firstProblem = firstProblem.getCause();
+ }
+ if (firstProblem instanceof LoginException) {
+ throw (LoginException) firstProblem;
+ }
+ throw (LoginException) new LoginException("auth.37").initCause(firstProblem); //$NON-NLS-1$
+ }
+ loggedIn = true;
+ }
+
+ public void logout() throws LoginException {
+ PrivilegedExceptionAction<Void> action = new PrivilegedExceptionAction<Void>() {
+ public Void run() throws LoginException {
+ logoutImpl();
+ return null;
+ }
+ };
+ try {
+ if (userProvidedConfig) {
+ AccessController.doPrivileged(action, userContext);
+ } else {
+ AccessController.doPrivileged(action);
+ }
+ } catch (PrivilegedActionException ex) {
+ throw (LoginException) ex.getException();
+ }
+ }
+
+ /**
+ * The real implementation of logout() method whose calls are wrapped into
+ * appropriate doPrivileged calls in logout().
+ */
+ private void logoutImpl() throws LoginException {
+ if (subject == null) {
+ throw new LoginException("auth.38"); //$NON-NLS-1$
+ }
+ loggedIn = false;
+ Throwable firstProblem = null;
+ int total = 0;
+ for (Module module : modules) {
+ try {
+ module.module.logout();
+ ++total;
+ } catch (Throwable ex) {
+ if (firstProblem == null) {
+ firstProblem = ex;
+ }
+ }
+ }
+ if (firstProblem != null || total == 0) {
+ if (firstProblem instanceof PrivilegedActionException
+ && firstProblem.getCause() != null) {
+ firstProblem = firstProblem.getCause();
+ }
+ if (firstProblem instanceof LoginException) {
+ throw (LoginException) firstProblem;
+ }
+ throw (LoginException) new LoginException("auth.37").initCause(firstProblem); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * <p>A class that servers as a wrapper for the CallbackHandler when we use
+ * installed Configuration, but not a passed one. See API docs on the
+ * LoginContext.</p>
+ *
+ * <p>Simply invokes the given handler with the given AccessControlContext.</p>
+ */
+ private class ContextedCallbackHandler implements CallbackHandler {
+ private final CallbackHandler hiddenHandlerRef;
+
+ ContextedCallbackHandler(CallbackHandler handler) {
+ super();
+ this.hiddenHandlerRef = handler;
+ }
+
+ public void handle(final Callback[] callbacks) throws IOException,
+ UnsupportedCallbackException {
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+ public Void run() throws IOException, UnsupportedCallbackException {
+ hiddenHandlerRef.handle(callbacks);
+ return null;
+ }
+ }, userContext);
+ } catch (PrivilegedActionException ex) {
+ if (ex.getCause() instanceof UnsupportedCallbackException) {
+ throw (UnsupportedCallbackException) ex.getCause();
+ }
+ throw (IOException) ex.getCause();
+ }
+ }
+ }
+
+ /**
+ * A private class that stores an instantiated LoginModule.
+ */
+ private final class Module {
+
+ // An initial info about the module to be used
+ AppConfigurationEntry entry;
+
+ // A mapping of LoginModuleControlFlag onto a simple int constant
+ int flag;
+
+ // The LoginModule itself
+ LoginModule module;
+
+ // A class of the module
+ Class<?> klass;
+
+ Module(AppConfigurationEntry entry) {
+ this.entry = entry;
+ LoginModuleControlFlag flg = entry.getControlFlag();
+ if (flg == LoginModuleControlFlag.OPTIONAL) {
+ flag = OPTIONAL;
+ } else if (flg == LoginModuleControlFlag.REQUISITE) {
+ flag = REQUISITE;
+ } else if (flg == LoginModuleControlFlag.SUFFICIENT) {
+ flag = SUFFICIENT;
+ } else {
+ flag = REQUIRED;
+ //if(flg!=LoginModuleControlFlag.REQUIRED) throw new Error()
+ }
+ }
+
+ int getFlag() {
+ return flag;
+ }
+
+ /**
+ * Loads class of the LoginModule, instantiates it and then calls
+ * initialize().
+ */
+ void create(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState)
+ throws LoginException {
+ String klassName = entry.getLoginModuleName();
+ if (klass == null) {
+ try {
+ klass = Class.forName(klassName, false, contextClassLoader);
+ } catch (ClassNotFoundException ex) {
+ throw (LoginException) new LoginException(
+ "auth.39 " + klassName).initCause(ex); //$NON-NLS-1$
+ }
+ }
+
+ if (module == null) {
+ try {
+ module = (LoginModule) klass.newInstance();
+ } catch (IllegalAccessException ex) {
+ throw (LoginException) new LoginException(
+ "auth.3A " + klassName) //$NON-NLS-1$
+ .initCause(ex);
+ } catch (InstantiationException ex) {
+ throw (LoginException) new LoginException(
+ "auth.3A" + klassName) //$NON-NLS-1$
+ .initCause(ex);
+ }
+ module.initialize(subject, callbackHandler, sharedState, entry.getOptions());
+ }
+ }
+ }
+}
diff --git a/src/org/apache/harmony/javax/security/auth/login/LoginException.java b/src/org/apache/harmony/javax/security/auth/login/LoginException.java
new file mode 100644
index 0000000..e9ea566
--- /dev/null
+++ b/src/org/apache/harmony/javax/security/auth/login/LoginException.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.javax.security.auth.login;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Base class for exceptions that are thrown when a login error occurs.
+ */
+public class LoginException extends GeneralSecurityException {
+
+ private static final long serialVersionUID = -4679091624035232488L;
+
+ /**
+ * Creates a new exception instance and initializes it with default values.
+ */
+ public LoginException() {
+ super();
+ }
+
+ /**
+ * Creates a new exception instance and initializes it with a given message.
+ *
+ * @param message the error message
+ */
+ public LoginException(String message) {
+ super(message);
+ }
+
+}