You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by le...@apache.org on 2007/10/11 11:42:14 UTC
svn commit: r583755 - in
/harmony/enhanced/classlib/branches/java6/modules/auth: META-INF/ make/
src/main/java/common/org/apache/harmony/auth/
src/main/java/common/org/apache/harmony/auth/module/
src/test/java/common/org/apache/harmony/auth/tests/module/
Author: leoli
Date: Thu Oct 11 02:42:13 2007
New Revision: 583755
URL: http://svn.apache.org/viewvc?rev=583755&view=rev
Log:
Apply patch for HARMONY-4918([classlib][auth][java6]Harmony lacks support for LdapLoginModule).
Added:
harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/LdapPrincipal.java (with props)
harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/UserPrincipal.java (with props)
harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/module/LdapLoginModule.java (with props)
harmony/enhanced/classlib/branches/java6/modules/auth/src/test/java/common/org/apache/harmony/auth/tests/module/LdapLoginModuleTest.java (with props)
Modified:
harmony/enhanced/classlib/branches/java6/modules/auth/META-INF/MANIFEST.MF
harmony/enhanced/classlib/branches/java6/modules/auth/make/exclude.common
Modified: harmony/enhanced/classlib/branches/java6/modules/auth/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/auth/META-INF/MANIFEST.MF?rev=583755&r1=583754&r2=583755&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/auth/META-INF/MANIFEST.MF (original)
+++ harmony/enhanced/classlib/branches/java6/modules/auth/META-INF/MANIFEST.MF Thu Oct 11 02:42:13 2007
@@ -30,6 +30,7 @@
javax.crypto.spec,
javax.naming,
javax.naming.directory,
+ javax.naming.ldap,
org.apache.harmony.kernel.vm,
org.apache.harmony.security,
org.apache.harmony.security.asn1,
Modified: harmony/enhanced/classlib/branches/java6/modules/auth/make/exclude.common
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/auth/make/exclude.common?rev=583755&r1=583754&r2=583755&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/auth/make/exclude.common (original)
+++ harmony/enhanced/classlib/branches/java6/modules/auth/make/exclude.common Thu Oct 11 02:42:13 2007
@@ -1,4 +1,6 @@
# excluded to avoid random failures
org/apache/harmony/auth/tests/module/Krb5LoginModuleTest.java
# jndi provider does not exist now
-org/apache/harmony/auth/tests/module/JndiLoginModuleTest.java
\ No newline at end of file
+org/apache/harmony/auth/tests/module/JndiLoginModuleTest.java
+# ldap provider does not exist now
+org/apache/harmony/auth/tests/module/LdapLoginModuleTest.java
\ No newline at end of file
Added: harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/LdapPrincipal.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/LdapPrincipal.java?rev=583755&view=auto
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/LdapPrincipal.java (added)
+++ harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/LdapPrincipal.java Thu Oct 11 02:42:13 2007
@@ -0,0 +1,80 @@
+/*
+ * 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.auth;
+
+import java.io.Serializable;
+import java.security.Principal;
+
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+
+import org.apache.harmony.auth.internal.nls.Messages;
+
+public class LdapPrincipal implements Serializable, Principal {
+
+ private static final long serialVersionUID = 6820120005580754861L;
+
+ // User name
+ private LdapName name;
+
+ /**
+ * Sole constructor.
+ * @param name user name
+ * @throws NullPointerException if name is null
+ */
+ public LdapPrincipal(String name) throws InvalidNameException{
+ if (name == null) {
+ throw new NullPointerException(Messages.getString("auth.00")); //$NON-NLS-1$
+ }
+ this.name = new LdapName(name);
+ }
+
+ public String getName() {
+ // TODO Auto-generated method stub
+ return name.toString();
+ }
+
+ /**
+ * Returns string representation of this object
+ */
+ @Override
+ public String toString() {
+ return "LdapPrincipal, name=" + name; //$NON-NLS-1$
+ }
+
+ /**
+ * Compares two UserPrincipal objects.<br>
+ * Two principal objects are considered equal if they are both of type
+ * UnixPrincipal and their names are equal.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof LdapPrincipal) {
+ return name.equals(((LdapPrincipal) o).name);
+ }
+ return false;
+ }
+
+ /**
+ * Return hash code of this object.
+ */
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+}
Propchange: harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/LdapPrincipal.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/UserPrincipal.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/UserPrincipal.java?rev=583755&view=auto
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/UserPrincipal.java (added)
+++ harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/UserPrincipal.java Thu Oct 11 02:42:13 2007
@@ -0,0 +1,77 @@
+/*
+ * 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.auth;
+
+import java.io.Serializable;
+import java.security.Principal;
+
+import org.apache.harmony.auth.internal.nls.Messages;
+
+public class UserPrincipal implements Serializable, Principal {
+
+ private static final long serialVersionUID = 892106070870210969L;
+
+ // User name
+ private String name;
+
+ /**
+ * Sole constructor.
+ * @param name user name
+ * @throws NullPointerException if name is null
+ */
+ public UserPrincipal(String name) {
+ if (name == null) {
+ throw new NullPointerException(Messages.getString("auth.00")); //$NON-NLS-1$
+ }
+ this.name = name;
+ }
+
+ public String getName() {
+ // TODO Auto-generated method stub
+ return name;
+ }
+
+ /**
+ * Returns string representation of this object
+ */
+ @Override
+ public String toString() {
+ return "UserPrincipal, name=" + name; //$NON-NLS-1$
+ }
+
+ /**
+ * Compares two UserPrincipal objects.<br>
+ * Two principal objects are considered equal if they are both of type
+ * UnixPrincipal and their names are equal.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof UserPrincipal) {
+ return name.equals(((UserPrincipal) o).name);
+ }
+ return false;
+ }
+
+ /**
+ * Return hash code of this object.
+ */
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+}
Propchange: harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/UserPrincipal.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/module/LdapLoginModule.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/module/LdapLoginModule.java?rev=583755&view=auto
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/module/LdapLoginModule.java (added)
+++ harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/module/LdapLoginModule.java Thu Oct 11 02:42:13 2007
@@ -0,0 +1,420 @@
+/*
+ * 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.auth.module;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.naming.AuthenticationException;
+import javax.naming.Context;
+import javax.naming.InvalidNameException;
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import org.apache.harmony.auth.LdapPrincipal;
+import org.apache.harmony.auth.UserPrincipal;
+
+public class LdapLoginModule extends SharedStateManager implements LoginModule {
+
+ private static enum LdapAuthMode{
+ search_first("search-first mode"),
+ authentication_first("authentication-first mode"),
+ authentication_only("authentication-only mode");
+
+ private String strValue;
+ LdapAuthMode(String str){
+ strValue = str;
+ }
+
+ public String toString(){
+ return strValue;
+ }
+ };
+
+ //harmony lacks ldap provider
+ private final String LDAP_FACTORY = "";
+
+ private LoginModuleUtils.LoginModuleStatus status = new LoginModuleUtils.LoginModuleStatus();
+
+ private Subject subject;
+
+ private CallbackHandler callbackHandler;
+
+ private Map<String, ?> options;
+
+ private String ldapUserProvider;
+
+ private String userID;
+
+ private char[] userPassword;
+
+ private LdapPrincipal ldapPrincipal;
+
+ private UserPrincipal userPrincipal;
+
+ private UserPrincipal extraUserPrincipal;
+
+ private boolean useSSL = false;
+
+ private LdapAuthMode ldapAuthMode;
+
+ private String userFilter;
+
+ private String authIdentity;
+
+ private String authzIdentity;
+
+ private String ldapPrincipalEntryName;
+
+ public boolean abort() throws LoginException {
+ LoginModuleUtils.ACTION action = status.checkAbout();
+ if (action.equals(LoginModuleUtils.ACTION.no_action)) {
+ if (status.isLoggined()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ clear();
+ debugUtil.recordDebugInfo("[LdapLoginModule] aborted authentication\n");
+ if(status.isCommitted()){
+ debugUtil.recordDebugInfo("[LdapLoginModule]: logged out Subject\n");
+ }
+ debugUtil.printAndClearDebugInfo();
+ status.logouted();
+ return true;
+ }
+
+ public boolean commit() throws LoginException {
+ LoginModuleUtils.ACTION action = status.checkCommit();
+ switch (action) {
+ case no_action:
+ return true;
+ case logout:
+ clear();
+ throw new LoginException("Fail to login");
+ default:
+ if (subject.isReadOnly()) {
+ clear();
+ throw new LoginException("Subject is readonly.");
+ }
+ subject.getPrincipals().add(ldapPrincipal);
+ debugUtil.recordDebugInfo("[LdapLoginModule] added LadpPrincipal \""+ ldapPrincipalEntryName + "\" to Subject\n");
+ subject.getPrincipals().add(userPrincipal);
+ debugUtil.recordDebugInfo("[LdapLoginModule] added UserPrincipal \""+ userID + "\" to Subject\n");
+ if(extraUserPrincipal != null){
+ subject.getPrincipals().add(extraUserPrincipal);
+ debugUtil.recordDebugInfo("[LdapLoginModule] added UserPrincipal \""+ authzIdentity + "\" to Subject\n");
+ }
+ debugUtil.printAndClearDebugInfo();
+ status.committed();
+ clearPass();
+ return true;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void initialize(Subject subject, CallbackHandler callbackHandler,
+ Map<String, ?> sharedState, Map<String, ?> options) {
+ this.subject = subject;
+ this.callbackHandler = callbackHandler;
+ this.sharedState = (Map<String, Object>) sharedState;
+ if (null == options) {
+ throw new NullPointerException();
+ }
+ this.options = options;
+ debugUtil = new DebugUtil(options);
+ prepareSharedState(sharedState,options);
+ processForOptions();
+ status.initialized();
+ }
+
+ public boolean login() throws LoginException {
+ LoginModuleUtils.ACTION action = status.checkLogin();
+ if (action.equals(LoginModuleUtils.ACTION.no_action)) {
+ return true;
+ }
+ getLdapParameters();
+ loginWithSharedState();
+/* if(useFirstPass || tryFirstPass){
+ getUserIdentityFromSharedStatus();
+ }
+ else{
+ getUserIdentityFromCallbackHandler();
+ }
+ boolean passAuth = false;
+ passAuth = mainAuthenticationProcess();
+ if (!passAuth) {
+ if(tryFirstPass){
+ recordDebugInfo("[LdapLoginModule] tryFirstPass failed with:" + new FailedLoginException("Login incorrect").toString() + "\n");
+ getUserIdentityFromCallbackHandler();
+ passAuth = mainAuthenticationProcess();
+ if(!passAuth){
+ recordDebugInfo("[LdapLoginModule] regular authentication failed\n");
+ printAndClearDebugInfo();
+ throw new FailedLoginException("Cannot bind to LDAP server");
+ }
+ else{
+ recordDebugInfo("[LdapLoginModule] regular authentication succeeded\n");
+ }
+ }
+ else {
+ if (useFirstPass) {
+ recordDebugInfo("[LdapLoginModule] useFirstPass failed with:"
+ + new FailedLoginException("Cannot bind to LDAP server")
+ .toString() + "\n");
+ } else {
+ recordDebugInfo("[LdapLoginModule] regular authentication failed\n");
+ }
+ printAndClearDebugInfo();
+ throw new FailedLoginException("Cannot bind to LDAP server");
+ }
+ }
+ else{
+ if(tryFirstPass){
+ recordDebugInfo("[LdapLoginModule] tryFirstPass ");
+ }
+ else if(useFirstPass){
+ recordDebugInfo("[LdapLoginModule] useFirstPass ");
+ }
+ else{
+ recordDebugInfo("[LdapLoginModule] authentication ");
+ }
+ recordDebugInfo("succeeded\n");
+ }
+ storePass();*/
+ try {
+ getPrinclpalsFromLdap();
+ } catch (InvalidNameException e) {
+ throw new LoginException("Error to get principal from ldap");
+ }
+ debugUtil.printAndClearDebugInfo();
+ status.logined();
+ return true;
+ }
+
+ public boolean logout() throws LoginException {
+ LoginModuleUtils.ACTION action = status.checkLogout();
+ if (action.equals(LoginModuleUtils.ACTION.no_action)) {
+ return true;
+ }
+ clear();
+ debugUtil.recordDebugInfo("[LdapLoginModule] logged out Subject\n");
+ debugUtil.printAndClearDebugInfo();
+ status.logouted();
+ return true;
+ }
+
+ private void clear() throws LoginException {
+ LoginModuleUtils.clearPassword(userPassword);
+ userPassword = null;
+ if (ldapPrincipal != null) {
+ subject.getPrincipals().remove(ldapPrincipal);
+ ldapPrincipal = null;
+ }
+
+ if (userPrincipal != null) {
+ subject.getPrincipals().remove(userPrincipal);
+ userPrincipal = null;
+ }
+
+ if (extraUserPrincipal != null) {
+ subject.getPrincipals().remove(extraUserPrincipal);
+ extraUserPrincipal = null;
+ }
+ status.logouted();
+ }
+
+ protected boolean mainAuthenticationProcess() throws LoginException{
+ Hashtable<String, String> env = new Hashtable<String, String>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, LDAP_FACTORY);
+ env.put(Context.PROVIDER_URL, ldapUserProvider);
+ if(useSSL){
+ env.put(Context.SECURITY_PROTOCOL, "ssl");
+ }
+ DirContext ctx;
+ debugUtil.recordDebugInfo("[LdapLoginModule] attempting to authenticate user: "+ userID +"\n");
+ try{
+ if(ldapAuthMode == LdapAuthMode.search_first){
+ boolean logined = false;
+ env.put(Context.SECURITY_AUTHENTICATION, "none");
+ ctx = new InitialDirContext(env);
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ debugUtil.recordDebugInfo("[LdapLoginModule] searching for entry belonging to user: "+ userID +"\n");
+ NamingEnumeration enumer = ctx.search("", userFilter, constraints);
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ while(enumer.hasMore()){
+ NameClassPair item = (NameClassPair) enumer.next();
+ try{
+ env.put(Context.SECURITY_PRINCIPAL, "simple");
+ env.put(Context.SECURITY_PRINCIPAL, item.getNameInNamespace());
+ env.put(Context.SECURITY_CREDENTIALS, new String(userPassword));
+ ctx = new InitialDirContext(env);
+ ldapPrincipalEntryName = item.getNameInNamespace();
+ debugUtil.recordDebugInfo("[LdapLoginModule] found entry: " + ldapPrincipalEntryName + "\n");
+ logined = true;
+ break;
+ }
+ catch(AuthenticationException e){
+
+ }
+ }
+ if(!logined){
+ return false;
+ }
+ }
+ else{
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ env.put(Context.SECURITY_PRINCIPAL, authIdentity);
+ env.put(Context.SECURITY_CREDENTIALS, new String(userPassword));
+ try{
+ ctx = new InitialDirContext(env);
+ }
+ catch(AuthenticationException e){
+ return false;
+ }
+ if(ldapAuthMode == LdapAuthMode.authentication_only){
+ ldapPrincipalEntryName = authIdentity;
+ }
+ else{
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ debugUtil.recordDebugInfo("[LdapLoginModule] searching for entry belonging to user: "+ userID +"\n");
+ NamingEnumeration enumer = ctx.search("", userFilter, constraints);
+ if(enumer.hasMore()){
+ NameClassPair item = (NameClassPair) enumer.next();
+ ldapPrincipalEntryName = item.getNameInNamespace();
+ debugUtil.recordDebugInfo("[LdapLoginModule] found entry: " + ldapPrincipalEntryName + "\n");
+ }
+ else{
+ return false;
+ }
+ }
+ }
+ }
+ catch(NamingException e){
+ return false;
+ }
+ return true;
+ }
+
+ private void processForOptions() {
+ Object optionValue = null;
+
+ optionValue = options.get("useSSL");
+ if (optionValue != null && optionValue.equals("true")) {
+ useSSL = true;
+ }
+
+ userFilter = (String)options.get("userFilter");
+ authIdentity = (String)options.get("authIdentity");
+ authzIdentity = (String)options.get("authzIdentity");
+ if(authIdentity==null){
+ ldapAuthMode = LdapAuthMode.search_first;
+ }
+ else if(userFilter==null){
+ ldapAuthMode = LdapAuthMode.authentication_only;
+ }
+ else{
+ ldapAuthMode = LdapAuthMode.authentication_first;
+ }
+ debugUtil.recordDebugInfo("[LdapLoginModule] "+ ldapAuthMode + "\n");
+ if(useSSL){
+ debugUtil.recordDebugInfo("[LdapLoginModule] SSL enabled\n");
+ }
+ else{
+ debugUtil.recordDebugInfo("[LdapLoginModule] SSL disabled\n");
+ }
+ debugUtil.printAndClearDebugInfo();
+ }
+
+ private void getLdapParameters()throws LoginException{
+ ldapUserProvider = (String)options.get("userProvider");
+ if (ldapUserProvider == null) {
+ throw new LoginException("Unable to locate the LDAP directory service");
+ }
+ debugUtil.recordDebugInfo("[LdapLoginModule] user provider: " + ldapUserProvider + "\n");
+ }
+
+ protected void getUserIdentityFromCallbackHandler() throws LoginException {
+
+ if (callbackHandler == null) {
+ throw new LoginException("no CallbackHandler available");
+ }
+ ArrayList<Callback> callbacks = new ArrayList<Callback>();
+ NameCallback jndiNameCallback = new NameCallback("User ID");
+ callbacks.add(jndiNameCallback);
+ PasswordCallback jndiPasswordCallback = new PasswordCallback(
+ "User Password", false);
+ callbacks.add(jndiPasswordCallback);
+ try {
+ callbackHandler.handle(callbacks.toArray(new Callback[callbacks
+ .size()]));
+ } catch (Exception e) {
+ throw new LoginException(e.toString());
+ }
+ userID = jndiNameCallback.getName();
+ userPassword = jndiPasswordCallback.getPassword();
+ }
+
+ private void getPrinclpalsFromLdap() throws InvalidNameException{
+ ldapPrincipal = new LdapPrincipal(ldapPrincipalEntryName);
+ userPrincipal = new UserPrincipal(userID);
+ if(authzIdentity != null){
+ extraUserPrincipal = new UserPrincipal(authzIdentity);
+ }
+ }
+
+ @Override
+ protected String getModuleName() {
+ return "LdapLoginModule";
+ }
+
+ @Override
+ protected String getUserName() {
+ return userID;
+ }
+
+ @Override
+ protected char[] getUserPassword() {
+ return userPassword;
+ }
+
+ @Override
+ protected void setUserName(String userName) {
+ this.userID = userName;
+ }
+
+ @Override
+ protected void setUserPassword(char[] userPassword) {
+ this.userPassword = userPassword;
+ }
+}
Propchange: harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/module/LdapLoginModule.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/classlib/branches/java6/modules/auth/src/test/java/common/org/apache/harmony/auth/tests/module/LdapLoginModuleTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/auth/src/test/java/common/org/apache/harmony/auth/tests/module/LdapLoginModuleTest.java?rev=583755&view=auto
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/auth/src/test/java/common/org/apache/harmony/auth/tests/module/LdapLoginModuleTest.java (added)
+++ harmony/enhanced/classlib/branches/java6/modules/auth/src/test/java/common/org/apache/harmony/auth/tests/module/LdapLoginModuleTest.java Thu Oct 11 02:42:13 2007
@@ -0,0 +1,336 @@
+/*
+ * 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.auth.tests.module;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.auth.module.LdapLoginModule;
+import org.apache.harmony.auth.UserPrincipal;
+
+
+public class LdapLoginModuleTest extends TestCase {
+
+ // module options
+ private HashMap<String, String> options = new HashMap<String, String>();
+
+ private final String USER_PROVIDER_URL = "ldap://9.181.106.121:389/ou=People,o=JNDITutorial,dc=my-domain,dc=com";
+
+ protected void setUp() throws Exception {
+ options.put("userProvider", USER_PROVIDER_URL);
+ options.put("useSSL", "false");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ options.clear();
+ }
+
+ /**
+ * Test method for {@link org.apache.harmony.auth.module.LdapLoginModule#abort()}.
+ */
+ public void test_abort() throws LoginException{
+ LdapLoginModule jlm = new LdapLoginModule();
+ try {
+ assertFalse("Should return false if login failed or no login", jlm
+ .abort());
+ } catch (LoginException e) {
+ fail("Abort failed");
+ }
+ Subject subject = new Subject();
+ subject.setReadOnly();
+ jlm.initialize(subject, null, null, options);
+ try {
+ assertFalse("Should return false if login failed or no login", jlm
+ .abort());
+ } catch (Exception e) {
+ fail("Not any exception here");
+ }
+ subject = new Subject();
+ jlm.initialize(subject, new FaultCallbackHandler(), null, options);
+ try {
+ jlm.login();
+ fail("login should fail");
+ } catch (LoginException e) {
+ assertFalse("Should return false because of login failure", jlm
+ .abort());
+ }
+ subject = new Subject();
+ options.put("authIdentity","cn=Manager,dc=my-domain,dc=com");
+ jlm.initialize(subject, new MockCallbackHandler(), null, options);
+ jlm.login();
+ assertTrue("Should return true if login was successful", jlm
+ .abort());
+ }
+
+ /**
+ * Test method for {@link org.apache.harmony.auth.module.LdapLoginModule#commit()}.
+ */
+ public void test_commit() {
+ LdapLoginModule module = new LdapLoginModule();
+ Subject subject = new Subject();
+ options.put("authIdentity","cn=Manager,dc=my-domain,dc=com");
+ module.initialize(subject, new MockCallbackHandler(), null, options);
+ try {
+ assertTrue("Login should be successful", module.login());
+ module.commit();
+ } catch (LoginException e) {
+ fail("Login shouldn't fail");
+ }
+ Set<Principal> principals = subject.getPrincipals();
+ assertFalse("Should get at least one principal", principals.isEmpty());
+ subject = new Subject();
+ subject.setReadOnly();
+ module.initialize(subject, new MockCallbackHandler(), null, options);
+ try {
+ assertFalse("Commit shouldn't be successful", module.commit());
+ fail("Should throw LoginException here because of trying to clear read-only subject");
+ } catch (LoginException e) {
+ // expected LoginException here
+ }
+ }
+
+ /**
+ * Test method for {@link org.apache.harmony.auth.module.LdapLoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)}.
+ */
+ public void test_initialize() {
+ LdapLoginModule module = new LdapLoginModule();
+ try {
+ module.initialize(null, null, null, null);
+ fail("Should throw NullPointerException here.");
+ } catch (NullPointerException e) {
+ // expected NullPointerException
+ }
+ }
+
+ /**
+ * Test method for {@link org.apache.harmony.auth.module.LdapLoginModule#login()}.
+ */
+ public void test_login() {
+ LdapLoginModule module = new LdapLoginModule();
+ HashMap<String, String> emptyOptions = new HashMap<String, String>();
+ module.initialize(null, new MockCallbackHandler(), null, emptyOptions);
+ try {
+ module.login();
+ fail("Should throw LoginException here.");
+ } catch (LoginException e) {
+ // expected LoginException
+ }
+
+ options.put("authIdentity","cn=Manager,dc=my-domain,dc=com");
+ Subject subject = new Subject();
+ module.initialize(subject, new MockCallbackHandler(), null, options);
+ try {
+ assertTrue("Login should be successful", module.login());
+ } catch (LoginException e) {
+ fail("Login shouldn't fail");
+ }
+ module.initialize(subject, new FaultCallbackHandler(), null, options);
+ try {
+ assertFalse("Login shouldn't be successful", module.login());
+ fail("Login should fail");
+ } catch (LoginException e) {
+ // expected Loginexception here
+ }
+ }
+
+ /**
+ * Test method for {@link org.apache.harmony.auth.module.LdapLoginModule#logout()}.
+ */
+ public void test_logout() {
+ LdapLoginModule module = new LdapLoginModule();
+ Subject subject = new Subject();
+ options.put("authIdentity","cn=Manager,dc=my-domain,dc=com");
+ module.initialize(subject, new MockCallbackHandler(), null, options);
+ try {
+ assertTrue("Login should be successful", module.login());
+ module.commit();
+ } catch (LoginException e) {
+ fail("Login shouldn't fail");
+ }
+ Set<Principal> principals = subject.getPrincipals();
+ assertFalse("Should get at least one principal", principals.isEmpty());
+ try {
+ assertTrue("Should be true", module.logout());
+ } catch (LoginException e) {
+ fail("Logout failed");
+ }
+ principals = subject.getPrincipals();
+ assertTrue("Principals should be cleared", principals.isEmpty());
+ }
+
+ public void test_optionsAndSharedStatus() throws LoginException{
+ options.put("authIdentity","cn=Manager,dc=my-domain,dc=com");
+ options.put("authzIdentity","testAuthzIdentityOption");
+ LdapLoginModule module = new LdapLoginModule();
+ Subject subject = new Subject();
+ module.initialize(subject, new MockCallbackHandler(), null, options);
+ try {
+ module.login();
+ module.commit();
+ assertTrue("Should get a principal from authzIdentity option",subject.getPrincipals().contains(new UserPrincipal("testAuthzIdentityOption")));
+ }
+ catch(LoginException e){
+ fail("Login failed");
+ }
+ finally{
+ module.logout();
+ }
+
+ options.put("debug", "true");
+ options.put("useFirstPass", "true");
+ HashMap<String, Object> status = new HashMap<String,Object>();
+ status.put("javax.security.auth.login.name", "leo");
+ status.put("javax.security.auth.login.password", "faultPass".toCharArray());
+ subject = new Subject();
+ module.initialize(subject, new MockCallbackHandler(), status, options);
+ try {
+ module.login();
+ fail("Should be failed for using password from shared state");
+ }
+ catch(LoginException e){
+ //expected LoginException here
+ }
+
+ options.remove("useFirstPass");
+ options.put("tryFirstPass", "true");
+ module.initialize(subject, new MockCallbackHandler(), status, options);
+ try {
+ module.login();
+ module.commit();
+ }
+ catch(LoginException e){
+ fail("Login should be failed");
+ }
+ finally{
+ module.logout();
+ }
+
+ options.remove("tryFirstPass");
+ options.put("clearPass", "true");
+ status.put("javax.security.auth.login.name", "leo");
+ status.put("javax.security.auth.login.password", "passw0rd".toCharArray());
+ module.initialize(subject, new MockCallbackHandler(), status, options);
+ try {
+ module.login();
+ module.commit();
+ assertNull("javax.security.auth.login.name in shared state should be null when clearPass switch on",status.get("javax.security.auth.login.name"));
+ assertNull("javax.security.auth.login.password in shared state should be null when clearPass switch on",status.get("javax.security.auth.login.password"));
+ } catch (LoginException e) {
+ fail("Login shouldn't fail");
+ }
+ finally{
+ module.logout();
+ }
+
+ status = new HashMap<String,Object>();
+ options.remove("clearPass");
+ options.put("storePass", "true");
+ module.initialize(subject, new FaultCallbackHandler(), status, options);
+ try {
+ module.login();
+ module.commit();
+ } catch (LoginException e) {
+ assertNull("javax.security.auth.login.name in shared state should be null when login failed",status.get("javax.security.auth.login.name"));
+ assertNull("javax.security.auth.login.password in shared state should be null when login failed",status.get("javax.security.auth.login.password"));
+ }
+ finally{
+ module.logout();
+ }
+
+ module.initialize(subject, new MockCallbackHandler(), status, options);
+ try {
+ module.login();
+ module.commit();
+ } catch (LoginException e) {
+ fail("Login failed");
+ }
+ finally{
+ module.logout();
+ }
+ assertNotNull("javax.security.auth.login.name should be stored in shared state when storePass switch on",status.get("javax.security.auth.login.name"));
+ assertNotNull("javax.security.auth.login.password should be stored in shared state when storePass switch on",status.get("javax.security.auth.login.password"));
+
+ status.put("javax.security.auth.login.name", "tester");
+ status.put("javax.security.auth.login.password", "testerPass");
+ module.initialize(subject, new MockCallbackHandler(), status, options);
+ try {
+ module.login();
+ module.commit();
+ } catch (LoginException e) {
+ fail("Login failed");
+ }
+ finally{
+ module.logout();
+ }
+ assertEquals("Should't override the username value in sharedState",status.get("javax.security.auth.login.name"),"tester");
+ assertEquals("Should't override the password value in sharedState",status.get("javax.security.auth.login.password"),"testerPass");
+ }
+
+ static private class MockCallbackHandler implements CallbackHandler{
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for(int i=0;i<callbacks.length;i++){
+ if(callbacks[i] instanceof NameCallback){
+ NameCallback nc = (NameCallback)callbacks[i];
+ nc.setName("leo");
+ }
+ else if(callbacks[i] instanceof PasswordCallback){
+ PasswordCallback pc = (PasswordCallback)callbacks[i];
+ pc.setPassword("secret".toCharArray());
+ }
+ else
+ {
+ throw new Error(callbacks[i].getClass().toString());
+ }
+ }
+ }
+ }
+
+ static private class FaultCallbackHandler implements CallbackHandler{
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for(int i=0;i<callbacks.length;i++){
+ if(callbacks[i] instanceof NameCallback){
+ NameCallback nc = (NameCallback)callbacks[i];
+ nc.setName("leo");
+ }
+ else if(callbacks[i] instanceof PasswordCallback){
+ PasswordCallback pc = (PasswordCallback)callbacks[i];
+ pc.setPassword("password".toCharArray());
+ }
+ else
+ {
+ throw new Error(callbacks[i].getClass().toString());
+ }
+ }
+ }
+ }
+}
Propchange: harmony/enhanced/classlib/branches/java6/modules/auth/src/test/java/common/org/apache/harmony/auth/tests/module/LdapLoginModuleTest.java
------------------------------------------------------------------------------
svn:eol-style = native