Package org.ejbca.core.ejb.ca.auth

Source Code of org.ejbca.core.ejb.ca.auth.AuthenticationSessionTest

/*************************************************************************
*                                                                       *
*  EJBCA: The OpenSource Certificate Authority                          *
*                                                                       *
*  This software is free software; you can redistribute it and/or       *
*  modify it under the terms of the GNU Lesser General Public           *
*  License as published by the Free Software Foundation; either         *
*  version 2.1 of the License, or any later version.                    *
*                                                                       *
*  See terms of license at gnu.org.                                     *
*                                                                       *
*************************************************************************/

package org.ejbca.core.ejb.ca.auth;

import java.security.KeyPair;
import java.security.cert.X509Certificate;

import javax.persistence.PersistenceException;

import org.apache.log4j.Logger;
import org.ejbca.config.GlobalConfiguration;
import org.ejbca.core.ejb.ca.CaTestCase;
import org.ejbca.core.ejb.ca.sign.SignSessionRemote;
import org.ejbca.core.ejb.config.GlobalConfigurationSessionRemote;
import org.ejbca.core.ejb.keyrecovery.KeyRecoverySessionRemote;
import org.ejbca.core.ejb.ra.UserAdminSessionRemote;
import org.ejbca.core.model.AlgorithmConstants;
import org.ejbca.core.model.SecConst;
import org.ejbca.core.model.approval.ApprovalException;
import org.ejbca.core.model.approval.WaitingForApprovalException;
import org.ejbca.core.model.authorization.AuthorizationDeniedException;
import org.ejbca.core.model.ca.AuthLoginException;
import org.ejbca.core.model.ca.AuthStatusException;
import org.ejbca.core.model.log.Admin;
import org.ejbca.core.model.ra.ExtendedInformation;
import org.ejbca.core.model.ra.UserDataConstants;
import org.ejbca.core.model.ra.UserDataVO;
import org.ejbca.core.model.ra.raadmin.UserDoesntFullfillEndEntityProfile;
import org.ejbca.util.CryptoProviderTools;
import org.ejbca.util.InterfaceCache;
import org.ejbca.util.keystore.KeyTools;

/**
* Tests authentication session used by signer.
*
* @version $Id: AuthenticationSessionTest.java 11539 2011-03-17 13:15:51Z netmackan $
*/
public class AuthenticationSessionTest extends CaTestCase {
    private static final Logger log = Logger.getLogger(AuthenticationSessionTest.class);
    private static final Admin admin = new Admin(Admin.TYPE_CACOMMANDLINE_USER);
    private int caid = getTestCAId();

    private static final int MAXFAILEDLOGINS = 4;

    private static String username1;
    private static String pwd1;
    private static String username2;
    private static String pwd2;

    private AuthenticationSessionRemote authenticationSessionRemote = InterfaceCache.getAuthenticationSession();
    private KeyRecoverySessionRemote keyRecoverySession = InterfaceCache.getKeyRecoverySession();
    private GlobalConfigurationSessionRemote globalConfigurationSession = InterfaceCache.getGlobalConfigurationSession();
    private SignSessionRemote signSession = InterfaceCache.getSignSession();
    private UserAdminSessionRemote userAdminSession = InterfaceCache.getUserAdminSession();

    /** Creates a new TestAuthenticationSession object. */
    public AuthenticationSessionTest(String name) {
        super(name);
        assertTrue("Could not create TestCA.", createTestCA());
    }

    public void setUp() throws Exception {
        log.trace(">setUp()");
        CryptoProviderTools.installBCProvider();
        log.trace("<setUp()");
    }

    public void tearDown() throws Exception {
    }

    private void createUser(Admin admin, String username, String password, int caID, int endEntityProfileId, int certProfileId, int maxFailedLogins)
            throws PersistenceException, AuthorizationDeniedException, UserDoesntFullfillEndEntityProfile, ApprovalException,
            WaitingForApprovalException, Exception {
        log.info("createUser: username=" + username + ", certProfileId=" + certProfileId);
        UserDataVO userdata = new UserDataVO(username, "CN=" + username, caID, null, null, 1, endEntityProfileId, certProfileId, SecConst.TOKEN_SOFT_P12, 0,
                null);
        ExtendedInformation ei = new ExtendedInformation();
        ei.setMaxLoginAttempts(maxFailedLogins);
        ei.setRemainingLoginAttempts(maxFailedLogins);
        userdata.setExtendedinformation(ei);
        userdata.setPassword(password);
        userAdminSession.addUser(admin, userdata, true);
        UserDataVO userdata2 = userAdminSession.findUser(admin, userdata.getUsername());
        assertNotNull("findUser: " + userdata.getUsername(), userdata2);
    }

    /** tests creation of new users */
    public void test01CreateNewUser() throws Exception {
        log.trace(">test01CreateNewUser()");

        // Make user that we know later...
        username1 = genRandomUserName();
        pwd1 = genRandomPwd();
        String email = username1 + "@anatom.se";
        userAdminSession.addUser(admin, username1, pwd1, "C=SE, O=AnaTom, CN=" + username1, "rfc822name=" + email, email, false,
                SecConst.EMPTY_ENDENTITYPROFILE, SecConst.CERTPROFILE_FIXED_ENDUSER, SecConst.USER_ENDUSER, SecConst.TOKEN_SOFT_P12, 0, caid);
        log.debug("created user: " + username1 + ", " + pwd1 + ", C=SE, O=AnaTom, CN=" + username1);

        // Make another user that we know later...
        username2 = genRandomUserName();
        pwd2 = genRandomPwd();
        createUser(admin, username2, pwd2, caid, SecConst.EMPTY_ENDENTITYPROFILE, SecConst.CERTPROFILE_FIXED_ENDUSER, MAXFAILEDLOGINS);
        log.debug("created user: " + username2 + ", " + pwd2 + ", C=SE, O=AnaTom, CN=" + username2);

        log.trace("<test01CreateNewUser()");
    }

    /** Tests authentication of users */
    public void test02AuthenticateUser() throws Exception {
        log.trace(">test02AuthenticateUser()");
        // user that we know exists...
        log.debug("Username:" + username1 + "\npwd:" + pwd1);
        UserDataVO data = authenticationSessionRemote.authenticateUser(admin, username1, pwd1);

        log.debug("DN: " + data.getDN());
        assertTrue("DN is wrong", data.getDN().indexOf(username1) != -1);

        log.debug("Email: " + data.getEmail());
        assertNotNull("Email should not be null", data.getEmail());
        assertTrue("Email is wrong", data.getEmail().equals(username1 + "@anatom.se"));

        log.debug("Type: " + data.getType());
        assertTrue("Type is wrong", data.getType() == SecConst.USER_ENDUSER);
        log.trace("<test02AuthenticateUser()");
    }

    /** Tests filed authentication */
    public void test03FailAuthenticateUser() throws Exception {
        log.trace(">test03FailAuthenticateUser()");
        // Set status to GENERATED so authentication will fail
        userAdminSession.setUserStatus(admin, username1, UserDataConstants.STATUS_GENERATED);
        boolean authfailed = false;
        try {
            UserDataVO auth = authenticationSessionRemote.authenticateUser(admin, username1, pwd1);
            log.debug("Authenticated user: " + auth.getUsername());
        } catch (Exception e) {
            authfailed = true;
        }
        assertTrue("Authentication succeeded when it should have failed.", authfailed);
        log.trace("<test03FailAuthenticateUser()");
    }

    /** Tests more failed authentication */
    public void test04FailAuthenticateUser() throws Exception {
        log.trace(">test04FailAuthenticateUser()");
        // user that we know exists... but we issue wrong password
        boolean authfailed = false;
        try {
            UserDataVO auth = authenticationSessionRemote.authenticateUser(admin, username1, "abc123");
            log.debug("Authenticated user: " + auth.getUsername());
        } catch (Exception e) {
            authfailed = true;
        }
        assertTrue("Authentication succeeded when it should have failed.", authfailed);
        log.trace("<test04FailAuthenticateUser()");
    }

    /** Test reset of key recovery mark. */
    public void test05UnmarkKeyRecoveryOnFinish() throws Exception {
        log.trace(">test05UnmarkKeyRecoveryOnFinish()");

        GlobalConfiguration config = globalConfigurationSession.getCachedGlobalConfiguration(admin);
        boolean orgkeyrecconfig = config.getEnableKeyRecovery();
        config.setEnableKeyRecovery(true);
        globalConfigurationSession.saveGlobalConfigurationRemote(admin, config);

        // create certificate for user
        // Set status to NEW
        userAdminSession.setPassword(admin, username1, "foo123");
        userAdminSession.setUserStatus(admin, username1, UserDataConstants.STATUS_NEW);

        // Create a dummy certificate and keypair.
        KeyPair keys = KeyTools.genKeys("1024", AlgorithmConstants.KEYALGORITHM_RSA);
        X509Certificate cert = (X509Certificate) signSession.createCertificate(admin, username1, "foo123", keys.getPublic());

        // First mark the user for recovery
        keyRecoverySession.addKeyRecoveryData(admin, cert, username1, keys);
        userAdminSession.prepareForKeyRecovery(admin, username1, SecConst.EMPTY_ENDENTITYPROFILE, null);

        assertTrue("Failure the users keyrecovery session should have been marked", keyRecoverySession.isUserMarked(admin, username1));

        // Now finish the user (The actual test)
        UserDataVO userdata = userAdminSession.findUser(admin, username1);
        authenticationSessionRemote.finishUser(userdata);
        // And se if the user is still marked

        assertTrue("Failure the users keyrecovery session should have been unmarked", !keyRecoverySession.isUserMarked(admin, username1));

        // Clean up
        keyRecoverySession.removeAllKeyRecoveryData(admin, username1);

        config.setEnableKeyRecovery(orgkeyrecconfig);
        globalConfigurationSession.saveGlobalConfigurationRemote(admin, config);
        log.trace("<test05UnmarkKeyRecoveryOnFinish()");
    }

    /**
     * Tests that (maxNumFailedLogins-1) tries can be done and then after a
     * correct login the remainingLoginAttempts is reset so that
     * (maxNumFailedLogins) can be performed before the account is locked which
     * is then tested by trying to login using the correct password.
     */
    public void test06MultipleFailedLogins() throws Exception {
        log.trace(">test06FailedLoginsThenCorrect()");

        assertEquals(MAXFAILEDLOGINS, 4);

        // Test that we don't lock the account to early
        loginMaxNumFailedLoginsMinusOneAndThenOk(username2, pwd2);

        // Test that we lock the account
        loginUntilLocked(username2, pwd2);

        // Reset the status
        userAdminSession.setUserStatus(admin, username2, UserDataConstants.STATUS_NEW);

        // After reset: Test that we don't lock the account to early
        loginMaxNumFailedLoginsMinusOneAndThenOk(username2, pwd2);

        // After reset: Test that we lock the account
        loginUntilLocked(username2, pwd2);

        log.trace("<test06FailedLoginsThenCorrect()");
    }

    private void loginMaxNumFailedLoginsMinusOneAndThenOk(String username, String password) throws Exception {
        // Login attempt: 1
        try {
            authenticationSessionRemote.authenticateUser(admin, username, "_wrong-password_");
            fail("Authentication succeeded when it should have failed.");
        } catch (AuthLoginException e) {
            // OK
        }
        // Login attempt: 2
        try {
            authenticationSessionRemote.authenticateUser(admin, username, "_wrong-password_");
            fail("Authentication succeeded when it should have failed.");
        } catch (AuthLoginException e) {
            // OK
        }
        // Login attempt: 3
        try {
            authenticationSessionRemote.authenticateUser(admin, username, "_wrong-password_");
            fail("Authentication succeeded when it should have failed.");
        } catch (AuthLoginException e) {
            // OK
        }
        // Login attempt: 4: This time with the right password which should work
        try {
            authenticationSessionRemote.authenticateUser(admin, username, password);
        } catch (AuthStatusException e) { // This time the status is wrong
            fail("The account shold not have been locked");
        } catch (AuthLoginException e) {
            fail("Authentication should have succeeded");
        }
    }

    private void loginUntilLocked(String username, String password) throws Exception {
        // Login attempt: 1
        try {
            authenticationSessionRemote.authenticateUser(admin, username, "_wrong-password_");
            fail("Authentication succeeded when it should have failed.");
        } catch (AuthLoginException e) {
            // OK
        }
        // Login attempt: 2
        try {
            authenticationSessionRemote.authenticateUser(admin, username, "_wrong-password_");
            fail("Authentication succeeded when it should have failed.");
        } catch (AuthLoginException e) {
            // OK
        }
        // Login attempt: 3
        try {
            authenticationSessionRemote.authenticateUser(admin, username, "_wrong-password_");
            fail("Authentication succeeded when it should have failed.");
        } catch (AuthLoginException e) {
            // OK
        }
        // Login attempt: 4
        try {
            authenticationSessionRemote.authenticateUser(admin, username, "_wrong-password_");
            fail("Authentication succeeded when it should have failed.");
        } catch (AuthLoginException e) {
            // OK
        }
        // Login attempt: 5: This time with the right password but the account
        // should have been locked
        try {
            authenticationSessionRemote.authenticateUser(admin, username, password);
            fail("Authentication succeeded when it should have failed.");
        } catch (AuthStatusException e) { // This time the status is wrong
            // OK
        }

        // Login attempt: 6: Should still be locked
        try {
            authenticationSessionRemote.authenticateUser(admin, username, password);
            fail("Authentication succeeded when it should have failed.");
        } catch (AuthStatusException e) { // This time the status is wrong
            // OK
        }

        // Login attempt: 7: Should still be locked
        try {
            authenticationSessionRemote.authenticateUser(admin, username, password);
            fail("Authentication succeeded when it should have failed.");
        } catch (AuthStatusException e) { // This time the status is wrong
            // OK
        }
    }

    /** Delete user after completed tests */
    public void test98DeleteUsers() throws Exception {
        log.trace(">test98DeleteUsers()");

        userAdminSession.deleteUser(admin, username1);
        log.debug("deleted user: " + username1);

        userAdminSession.deleteUser(admin, username2);
        log.debug("deleted user: " + username2);

        log.trace("<test98eleteUsers()");
    }

    public void test99RemoveTestCA() throws Exception {
        removeTestCA();
    }
}
TOP

Related Classes of org.ejbca.core.ejb.ca.auth.AuthenticationSessionTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.