Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 30762 invoked from network); 13 Jul 2010 19:00:55 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 13 Jul 2010 19:00:55 -0000 Received: (qmail 42983 invoked by uid 500); 13 Jul 2010 19:00:55 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 42927 invoked by uid 500); 13 Jul 2010 19:00:55 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 42920 invoked by uid 99); 13 Jul 2010 19:00:55 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 13 Jul 2010 19:00:55 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 13 Jul 2010 19:00:51 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id E96FC23889B3; Tue, 13 Jul 2010 18:59:57 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r963824 - in /directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/authn/ppolicy: ./ PasswordPolicyTest.java Date: Tue, 13 Jul 2010 18:59:57 -0000 To: commits@directory.apache.org From: kayyagari@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100713185957.E96FC23889B3@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: kayyagari Date: Tue Jul 13 18:59:57 2010 New Revision: 963824 URL: http://svn.apache.org/viewvc?rev=963824&view=rev Log: o test case for pwdpolicy implementation Added: directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/authn/ppolicy/ directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/authn/ppolicy/PasswordPolicyTest.java Added: directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/authn/ppolicy/PasswordPolicyTest.java URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/authn/ppolicy/PasswordPolicyTest.java?rev=963824&view=auto ============================================================================== --- directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/authn/ppolicy/PasswordPolicyTest.java (added) +++ directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/authn/ppolicy/PasswordPolicyTest.java Tue Jul 13 18:59:57 2010 @@ -0,0 +1,253 @@ +/* + * 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.directory.server.core.authn.ppolicy; + + +import static org.apache.directory.server.core.integ.IntegrationUtils.getAdminNetworkConnection; +import static org.apache.directory.server.core.integ.IntegrationUtils.getNetworkConnectionAs; +import static org.apache.directory.shared.ldap.codec.controls.ppolicy.PasswordPolicyErrorEnum.INSUFFICIENT_PASSWORD_QUALITY; +import static org.apache.directory.shared.ldap.codec.controls.ppolicy.PasswordPolicyErrorEnum.PASSWORD_TOO_SHORT; +import static org.apache.directory.shared.ldap.codec.controls.ppolicy.PasswordPolicyErrorEnum.PASSWORD_TOO_YOUNG; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.apache.directory.ldap.client.api.LdapConnection; +import org.apache.directory.ldap.client.api.message.AbstractResponseWithResult; +import org.apache.directory.ldap.client.api.message.AddRequest; +import org.apache.directory.ldap.client.api.message.AddResponse; +import org.apache.directory.ldap.client.api.message.ModifyRequest; +import org.apache.directory.ldap.client.api.message.ModifyResponse; +import org.apache.directory.server.annotations.CreateLdapServer; +import org.apache.directory.server.annotations.CreateTransport; +import org.apache.directory.server.core.annotations.CreateDS; +import org.apache.directory.server.core.authn.AuthenticationInterceptor; +import org.apache.directory.server.core.authn.PasswordPolicyConfiguration; +import org.apache.directory.server.core.authn.PasswordUtil; +import org.apache.directory.server.core.integ.AbstractLdapTestUnit; +import org.apache.directory.server.core.integ.FrameworkRunner; +import org.apache.directory.server.core.integ.IntegrationUtils; +import org.apache.directory.shared.ldap.codec.controls.ppolicy.PasswordPolicyRequestControl; +import org.apache.directory.shared.ldap.codec.controls.ppolicy.PasswordPolicyResponseControl; +import org.apache.directory.shared.ldap.codec.controls.ppolicy.PasswordPolicyResponseControlDecoder; +import org.apache.directory.shared.ldap.constants.LdapSecurityConstants; +import org.apache.directory.shared.ldap.constants.SchemaConstants; +import org.apache.directory.shared.ldap.entry.DefaultEntry; +import org.apache.directory.shared.ldap.entry.Entry; +import org.apache.directory.shared.ldap.entry.EntryAttribute; +import org.apache.directory.shared.ldap.message.ResultCodeEnum; +import org.apache.directory.shared.ldap.message.control.Control; +import org.apache.directory.shared.ldap.name.DN; +import org.apache.directory.shared.ldap.util.StringTools; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Test cases for testing PasswordPolicy implementation. + * + * @author Apache Directory Project + */ +@RunWith(FrameworkRunner.class) +@CreateLdapServer ( + transports = + { + @CreateTransport( protocol = "LDAP" ), + @CreateTransport( protocol = "LDAPS" ) + }) +@CreateDS( enableChangeLog=false ) +public class PasswordPolicyTest extends AbstractLdapTestUnit +{ + private PasswordPolicyConfiguration policyConfig; + + private static final PasswordPolicyRequestControl PP_REQ_CTRL = new PasswordPolicyRequestControl(); + + private static final PasswordPolicyResponseControlDecoder decoder = new PasswordPolicyResponseControlDecoder(); + + + @Before + public void setPwdPolicy() + { + policyConfig = new PasswordPolicyConfiguration(); + + policyConfig.setPwdMaxAge( 110 ); + policyConfig.setPwdFailureCountInterval( 30 ); + policyConfig.setPwdMaxFailure( 2 ); + policyConfig.setPwdLockout( true ); + policyConfig.setPwdLockoutDuration( 0 ); + policyConfig.setPwdMinLength( 5 ); + policyConfig.setPwdInHistory( 5 ); + policyConfig.setPwdExpireWarning( 600 ); + policyConfig.setPwdGraceAuthNLimit( 5 ); + policyConfig.setPwdCheckQuality( 2 ); // DO NOT allow the password if its quality can't be checked + + AuthenticationInterceptor authInterceptor = ( AuthenticationInterceptor ) service + .getInterceptor( AuthenticationInterceptor.class.getName() ); + authInterceptor.setPwdPolicyConfig( policyConfig ); + } + + + @After + public void closeConnections() + { + IntegrationUtils.closeConnections(); + } + + + @Test + public void testAddUserWithClearTextPwd() throws Exception + { + LdapConnection connection = getAdminNetworkConnection( ldapServer ); + + DN userDn = new DN( "cn=user,ou=system" ); + Entry userEntry = new DefaultEntry( userDn ); + userEntry.add( SchemaConstants.OBJECT_CLASS, SchemaConstants.PERSON_OC ); + userEntry.add( SchemaConstants.CN_AT, "user" ); + userEntry.add( SchemaConstants.SN_AT, "user_sn" ); + userEntry.add( SchemaConstants.USER_PASSWORD_AT, "1234".getBytes() ); + + AddRequest addReq = new AddRequest( userEntry ); + addReq.add( PP_REQ_CTRL ); + + AddResponse addResp = connection.add( addReq ); + assertEquals( ResultCodeEnum.CONSTRAINT_VIOLATION, addResp.getLdapResult().getResultCode() ); + + PasswordPolicyResponseControl respCtrl = getPwdRespCtrl( addResp ); + assertNotNull( respCtrl ); + assertEquals( PASSWORD_TOO_SHORT, respCtrl.getPasswordPolicyError() ); + + EntryAttribute pwdAt = userEntry.get( SchemaConstants.USER_PASSWORD_AT ); + pwdAt.clear(); + pwdAt.add( "12345".getBytes() ); + + addResp = connection.add( addReq ); + assertEquals( ResultCodeEnum.SUCCESS, addResp.getLdapResult().getResultCode() ); + respCtrl = getPwdRespCtrl( addResp ); + assertNull( respCtrl ); + + LdapConnection userConnection = getNetworkConnectionAs( ldapServer, userDn.getName(), "12345" ); + assertNotNull( userConnection ); + assertTrue( userConnection.isAuthenticated() ); + } + + + @Test + public void testAddUserWithHashedPwd() throws Exception + { + LdapConnection connection = getAdminNetworkConnection( ldapServer ); + + byte[] password = PasswordUtil.encryptPassword( "12345".getBytes(), LdapSecurityConstants.HASH_METHOD_CRYPT, null ); + String strPwd = "{crypt}" + StringTools.utf8ToString( password ); + password = strPwd.getBytes(); + + DN userDn = new DN( "cn=hashedpwd,ou=system" ); + Entry userEntry = new DefaultEntry( userDn ); + userEntry.add( SchemaConstants.OBJECT_CLASS, SchemaConstants.PERSON_OC ); + userEntry.add( SchemaConstants.CN_AT, "hashedpwd" ); + userEntry.add( SchemaConstants.SN_AT, "hashedpwd_sn" ); + userEntry.add( SchemaConstants.USER_PASSWORD_AT, password ); + + AddRequest addReq = new AddRequest( userEntry ); + addReq.add( PP_REQ_CTRL ); + + AddResponse addResp = connection.add( addReq ); + assertEquals( ResultCodeEnum.CONSTRAINT_VIOLATION, addResp.getLdapResult().getResultCode() ); + + PasswordPolicyResponseControl respCtrl = getPwdRespCtrl( addResp ); + assertNotNull( respCtrl ); + assertEquals( INSUFFICIENT_PASSWORD_QUALITY, respCtrl.getPasswordPolicyError() ); + + policyConfig.setPwdCheckQuality( 1 ); // allow the password if its quality can't be checked + EntryAttribute pwdAt = userEntry.get( SchemaConstants.USER_PASSWORD_AT ); + pwdAt.clear(); + pwdAt.add( password ); + + addResp = connection.add( addReq ); + assertEquals( ResultCodeEnum.SUCCESS, addResp.getLdapResult().getResultCode() ); + respCtrl = getPwdRespCtrl( addResp ); + assertNull( respCtrl ); + + LdapConnection userConnection = getNetworkConnectionAs( ldapServer, userDn.getName(), StringTools.utf8ToString( password ) ); + assertNotNull( userConnection ); + assertTrue( userConnection.isAuthenticated() ); + } + + + @Test + public void testPwdMinAge() throws Exception + { + policyConfig.setPwdMinAge( 5 ); + + LdapConnection connection = getAdminNetworkConnection( ldapServer ); + + DN userDn = new DN( "cn=user,ou=system" ); + Entry userEntry = new DefaultEntry( userDn ); + userEntry.add( SchemaConstants.OBJECT_CLASS, SchemaConstants.PERSON_OC ); + userEntry.add( SchemaConstants.CN_AT, "user" ); + userEntry.add( SchemaConstants.SN_AT, "user_sn" ); + userEntry.add( SchemaConstants.USER_PASSWORD_AT, "12345".getBytes() ); + + AddRequest addReq = new AddRequest( userEntry ); + addReq.add( PP_REQ_CTRL ); + + AddResponse addResp = connection.add( addReq ); + assertEquals( ResultCodeEnum.SUCCESS, addResp.getLdapResult().getResultCode() ); + + PasswordPolicyResponseControl respCtrl = getPwdRespCtrl( addResp ); + assertNull( respCtrl ); + + ModifyRequest modReq = new ModifyRequest( userDn ); + modReq.add( PP_REQ_CTRL ); + modReq.replace( SchemaConstants.USER_PASSWORD_AT, "123456" ); + + ModifyResponse modResp = connection.modify( modReq ); + assertEquals( ResultCodeEnum.CONSTRAINT_VIOLATION, modResp.getLdapResult().getResultCode() ); + + respCtrl = getPwdRespCtrl( modResp ); + assertEquals( PASSWORD_TOO_YOUNG, respCtrl.getPasswordPolicyError() ); + + Thread.sleep( 5000 ); + + modResp = connection.modify( modReq ); + assertEquals( ResultCodeEnum.SUCCESS, modResp.getLdapResult().getResultCode() ); + + LdapConnection userConnection = getNetworkConnectionAs( ldapServer, userDn.getName(), "123456" ); + assertNotNull( userConnection ); + assertTrue( userConnection.isAuthenticated() ); + } + + private PasswordPolicyResponseControl getPwdRespCtrl( AbstractResponseWithResult resp ) throws Exception + { + Control ctrl = resp.getControl( PP_REQ_CTRL.getOid() ); + if ( ctrl == null ) + { + return null; + } + + PasswordPolicyResponseControl respCtrl = new PasswordPolicyResponseControl(); + // System.out.println( StringTools.dumpBytes( ctrl.getValue() ) ); + decoder.decode( ctrl.getValue(), respCtrl ); + + return respCtrl; + } +}