diff --git a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControl.java b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControl.java deleted file mode 100644 index 611cceaa71..0000000000 --- a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControl.java +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited - * - * Licensed 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.acegisecurity.providers.ldap.authenticator.controls; - -import javax.naming.ldap.Control; - - -/** - * A Password Policy request control.
Based on the information in the corresponding internet draft on LDAP - * password policy.
- * - * @author Stefan Zoerner - * @author Luke Taylor - * @version $Id$ - * - * @see PasswordPolicyResponseControl - * @see Password Policy for LDAP - * Directories - */ -public class PasswordPolicyControl implements Control { - //~ Static fields/initializers ===================================================================================== - - /** OID of the Password Policy Control */ - public static final String OID = "1.3.6.1.4.1.42.2.27.8.5.1"; - - //~ Instance fields ================================================================================================ - - private boolean critical; - - //~ Constructors =================================================================================================== - -/** - * Creates a non-critical (request) control. - */ - public PasswordPolicyControl() { - this(Control.NONCRITICAL); - } - -/** - * Creates a (request) control. - * - * @param critical indicates whether the control is - * critical for the client - */ - public PasswordPolicyControl(boolean critical) { - this.critical = critical; - } - - //~ Methods ======================================================================================================== - - /** - * Retrieves the ASN.1 BER encoded value of the LDAP control. The request value for this control is always - * empty. - * - * @return always null - */ - public byte[] getEncodedValue() { - return null; - } - - /** - * Returns the OID of the Password Policy Control. - * - * @return DOCUMENT ME! - */ - public String getID() { - return OID; - } - - /** - * Returns whether the control is critical for the client. - * - * @return DOCUMENT ME! - */ - public boolean isCritical() { - return critical; - } -} diff --git a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControlFactory.java b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControlFactory.java deleted file mode 100644 index c22cab48ed..0000000000 --- a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControlFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited - * - * Licensed 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.acegisecurity.providers.ldap.authenticator.controls; - -import javax.naming.ldap.Control; -import javax.naming.ldap.ControlFactory; - - -/** - * Transforms a control object to a PasswordPolicyResponseControl object, if appropriate. - * - * @author Stefan Zoerner - * @author Luke Taylor - * @version $Id$ - */ -public class PasswordPolicyControlFactory extends ControlFactory { - //~ Methods ======================================================================================================== - - /** - * Creates an instance of PasswordPolicyResponseControl if the passed control is a response control of this - * type. Attributes of the result are filled with the correct values (e.g. error code). - * - * @param ctl the control the check - * - * @return a response control of type PasswordPolicyResponseControl, or null - */ - public Control getControlInstance(Control ctl) { - if (ctl.getID().equals(PasswordPolicyControl.OID)) { - return new PasswordPolicyResponseControl(ctl.getEncodedValue()); - } - - return null; - } -} diff --git a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControl.java b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControl.java deleted file mode 100644 index 7eeffcd166..0000000000 --- a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControl.java +++ /dev/null @@ -1,360 +0,0 @@ -/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited - * - * Licensed 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.acegisecurity.providers.ldap.authenticator.controls; - -import netscape.ldap.ber.stream.BERChoice; -import netscape.ldap.ber.stream.BERElement; -import netscape.ldap.ber.stream.BEREnumerated; -import netscape.ldap.ber.stream.BERInteger; - -//import com.novell.ldap.asn1.LBERDecoder; -//import com.novell.ldap.asn1.ASN1Sequence; -//import com.novell.ldap.asn1.ASN1Tagged; -//import com.novell.ldap.asn1.ASN1OctetString; -import netscape.ldap.ber.stream.BERSequence; -import netscape.ldap.ber.stream.BERTag; -import netscape.ldap.ber.stream.BERTagDecoder; - -import org.acegisecurity.ldap.LdapDataAccessException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - - -/** - * Represent the response control received when a PasswordPolicyControl is used when binding to a - * directory. Currently tested with the OpenLDAP 2.3.19 implementation of the LDAP Password Policy Draft. It extends - * the request control with the control specific data. This is accomplished by the properties timeBeforeExpiration, - * graceLoginsRemaining and errorCodes. getEncodedValue returns the unchanged value of the response control as a byte - * array. - * - * @author Stefan Zoerner - * @author Luke Taylor - * @version $Id$ - * - * @see PasswordPolicyControl - * @see Stefan Zoerner's IBM developerworks - * article on LDAP controls. - */ -public class PasswordPolicyResponseControl extends PasswordPolicyControl { - //~ Static fields/initializers ===================================================================================== - - private static final Log logger = LogFactory.getLog(PasswordPolicyResponseControl.class); - public static final int ERROR_NONE = -1; - public static final int ERROR_PASSWORD_EXPIRED = 0; - public static final int ERROR_ACCOUNT_LOCKED = 1; - public static final int WARNINGS_DEFAULT = -1; - private static final String[] errorText = { - "password expired", "account locked", "change after reset", "password mod not allowed", - "must supply old password", "invalid password syntax", "password too short", "password too young", - "password in history" - }; - - //~ Instance fields ================================================================================================ - - private byte[] encodedValue; - private int errorCode = ERROR_NONE; - private int graceLoginsRemaining = WARNINGS_DEFAULT; - private int timeBeforeExpiration = WARNINGS_DEFAULT; - - //~ Constructors =================================================================================================== - - public PasswordPolicyResponseControl(byte[] encodedValue) { - this.encodedValue = encodedValue; - - //PPolicyDecoder decoder = new JLdapDecoder(); - PPolicyDecoder decoder = new NetscapeDecoder(); - - try { - decoder.decode(); - } catch (IOException e) { - throw new LdapDataAccessException("Failed to parse control value", e); - } - } - - //~ Methods ======================================================================================================== - - /** - * Returns the unchanged value of the response control. Returns the unchanged value of the response - * control as byte array. - * - * @return DOCUMENT ME! - */ - public byte[] getEncodedValue() { - return encodedValue; - } - - /** - * Returns the error code, or ERROR_NONE, if no error is present. - * - * @return the error code (0-8), or ERROR_NONE - */ - public int getErrorCode() { - return errorCode; - } - - /** - * Decodes the Ber encoded control data. The ASN.1 value of the control data is:
- * PasswordPolicyResponseValue ::= SEQUENCE { warning [0] CHOICE {
- * timeBeforeExpiration [0] INTEGER (0 .. maxInt),
- * graceAuthNsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL, error [1] ENUMERATED {
- * passwordExpired (0), accountLocked (1),
- * changeAfterReset (2), passwordModNotAllowed (3),
- * mustSupplyOldPassword (4), insufficientPasswordQuality (5),
- * passwordTooShort (6), passwordTooYoung (7),
- * passwordInHistory (8) } OPTIONAL }
- *
- * @return DOCUMENT ME!
- */
- /**
- * Returns the graceLoginsRemaining.
- *
- * @return Returns the graceLoginsRemaining.
- */
- public int getGraceLoginsRemaining() {
- return graceLoginsRemaining;
- }
-
- /**
- * Returns the timeBeforeExpiration.
- *
- * @return Returns the time before expiration in seconds
- */
- public int getTimeBeforeExpiration() {
- return timeBeforeExpiration;
- }
-
- /**
- * Checks whether an error is present.
- *
- * @return true, if an error is present
- */
- public boolean hasError() {
- return this.getErrorCode() != ERROR_NONE;
- }
-
- /**
- * Checks whether a warning is present.
- *
- * @return true, if a warning is present
- */
- public boolean hasWarning() {
- return (graceLoginsRemaining != WARNINGS_DEFAULT) || (timeBeforeExpiration != WARNINGS_DEFAULT);
- }
-
- public boolean isExpired() {
- return errorCode == ERROR_PASSWORD_EXPIRED;
- }
-
- /**
- * Determines whether an account locked error has been returned.
- *
- * @return true if the account is locked.
- */
- public boolean isLocked() {
- return errorCode == ERROR_ACCOUNT_LOCKED;
- }
-
- /**
- * Create a textual representation containing error and warning messages, if any are present.
- *
- * @return error and warning messages
- */
- public String toString() {
- StringBuffer sb = new StringBuffer("PasswordPolicyResponseControl");
-
- if (hasError()) {
- sb.append(", error: ").append(errorText[errorCode]);
- }
-
- if (graceLoginsRemaining != WARNINGS_DEFAULT) {
- sb.append(", warning: ").append(graceLoginsRemaining).append(" grace logins remain");
- }
-
- if (timeBeforeExpiration != WARNINGS_DEFAULT) {
- sb.append(", warning: time before expiration is ").append(timeBeforeExpiration);
- }
-
- if (!hasError() && !hasWarning()) {
- sb.append(" (no error, no warning)");
- }
-
- return sb.toString();
- }
-
- //~ Inner Interfaces ===============================================================================================
-
- private interface PPolicyDecoder {
- void decode() throws IOException;
- }
-
- //~ Inner Classes ==================================================================================================
-
- /**
- * Decoder based on Netscape ldapsdk library
- */
- private class NetscapeDecoder implements PPolicyDecoder {
- public void decode() throws IOException {
- int[] bread = {0};
- BERSequence seq = (BERSequence) BERElement.getElement(new SpecificTagDecoder(),
- new ByteArrayInputStream(encodedValue), bread);
-
- int size = seq.size();
-
- if (logger.isDebugEnabled()) {
- logger.debug("PasswordPolicyResponse, ASN.1 sequence has " + size + " elements");
- }
-
- for (int i = 0; i < seq.size(); i++) {
- BERTag elt = (BERTag) seq.elementAt(i);
-
- int tag = elt.getTag() & 0x1F;
-
- if (tag == 0) {
- BERChoice warning = (BERChoice) elt.getValue();
-
- BERTag content = (BERTag) warning.getValue();
- int value = ((BERInteger) content.getValue()).getValue();
-
- if ((content.getTag() & 0x1F) == 0) {
- timeBeforeExpiration = value;
- } else {
- graceLoginsRemaining = value;
- }
- } else if (tag == 1) {
- BEREnumerated error = (BEREnumerated) elt.getValue();
- errorCode = error.getValue();
- }
- }
- }
-
- class SpecificTagDecoder extends BERTagDecoder {
- /** Allows us to remember which of the two options we're decoding */
- private Boolean inChoice = null;
-
- public BERElement getElement(BERTagDecoder decoder, int tag, InputStream stream, int[] bytesRead,
- boolean[] implicit) throws IOException {
- tag &= 0x1F;
- implicit[0] = false;
-
- if (tag == 0) {
- // Either the choice or the time before expiry within it
- if (inChoice == null) {
- setInChoice(true);
-
- // Read the choice length from the stream (ignored)
- BERElement.readLengthOctets(stream, bytesRead);
-
- int[] componentLength = new int[1];
- BERElement choice = new BERChoice(decoder, stream, componentLength);
- bytesRead[0] += componentLength[0];
-
- // inChoice = null;
- return choice;
- } else {
- // Must be time before expiry
- return new BERInteger(stream, bytesRead);
- }
- } else if (tag == 1) {
- // Either the graceLogins or the error enumeration.
- if (inChoice == null) {
- // The enumeration
- setInChoice(false);
-
- return new BEREnumerated(stream, bytesRead);
- } else {
- if (inChoice.booleanValue()) {
- // graceLogins
- return new BERInteger(stream, bytesRead);
- }
- }
- }
-
- throw new LdapDataAccessException("Unexpected tag " + tag);
- }
-
- private void setInChoice(boolean inChoice) {
- this.inChoice = new Boolean(inChoice);
- }
- }
- }
-
-/** Decoder based on the OpenLDAP/Novell JLDAP library */
-
-// private class JLdapDecoder implements PPolicyDecoder {
-//
-// public void decode() throws IOException {
-//
-// LBERDecoder decoder = new LBERDecoder();
-//
-// ASN1Sequence seq = (ASN1Sequence)decoder.decode(encodedValue);
-//
-// if(seq == null) {
-//
-// }
-//
-// int size = seq.size();
-//
-// if(logger.isDebugEnabled()) {
-// logger.debug("PasswordPolicyResponse, ASN.1 sequence has " +
-// size + " elements");
-// }
-//
-// for(int i=0; i < size; i++) {
-//
-// ASN1Tagged taggedObject = (ASN1Tagged)seq.get(i);
-//
-// int tag = taggedObject.getIdentifier().getTag();
-//
-// ASN1OctetString value = (ASN1OctetString)taggedObject.taggedValue();
-// byte[] content = value.byteValue();
-//
-// if(tag == 0) {
-// parseWarning(content, decoder);
-//
-// } else if(tag == 1) {
-// // Error: set the code to the value
-// errorCode = content[0];
-// }
-// }
-// }
-//
-// private void parseWarning(byte[] content, LBERDecoder decoder) {
-// // It's the warning (choice). Parse the number and set either the
-// // expiry time or number of logins remaining.
-// ASN1Tagged taggedObject = (ASN1Tagged)decoder.decode(content);
-// int contentTag = taggedObject.getIdentifier().getTag();
-// content = ((ASN1OctetString)taggedObject.taggedValue()).byteValue();
-// int number;
-//
-// try {
-// number = ((Long)decoder.decodeNumeric(new ByteArrayInputStream(content), content.length)).intValue();
-// } catch(IOException e) {
-// throw new LdapDataAccessException("Failed to parse number ", e);
-// }
-//
-// if(contentTag == 0) {
-// timeBeforeExpiration = number;
-// } else if (contentTag == 1) {
-// graceLoginsRemaining = number;
-// }
-// }
-// }
-}
diff --git a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControlTests.java b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControlTests.java
deleted file mode 100644
index 1d5971589a..0000000000
--- a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControlTests.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
- *
- * Licensed 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.acegisecurity.providers.ldap.authenticator.controls;
-
-import junit.framework.TestCase;
-
-
-/**
- * Tests for PasswordPolicyResponse.
- *
- * @author Luke Taylor
- * @version $Id$
- */
-public class PasswordPolicyResponseControlTests extends TestCase {
- //~ Methods ========================================================================================================
-
- /**
- * Useful method for obtaining data from a server for use in tests
- */
-
-// public void testAgainstServer() throws Exception {
-// Hashtable env = new Hashtable();
-// env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
-// env.put(Context.PROVIDER_URL, "ldap://gorille:389/");
-// env.put(Context.SECURITY_AUTHENTICATION, "simple");
-// env.put(Context.SECURITY_PRINCIPAL, "cn=manager,dc=acegisecurity,dc=org");
-// env.put(Context.SECURITY_CREDENTIALS, "acegisecurity");
-//
-// InitialLdapContext ctx = new InitialLdapContext(env, null);
-//
-// Control[] rctls = { new PasswordPolicyControl(false) };
-//
-//
-// try {
-// ctx.addToEnvironment(LdapContext.CONTROL_FACTORIES, PasswordPolicyControlFactory.class.getName());
-// ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, "uid=bob,ou=people,dc=acegisecurity,dc=org" );
-// ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, "bobspassword");
-// ctx.reconnect(rctls);
-// } catch(NamingException ne) {
-// // Ok.
-// }
-//
-// PasswordPolicyResponseControl ctrl = getPPolicyResponseCtl(ctx);
-// System.out.println(ctrl);
-//
-// assertNotNull(ctrl);
-//
-// //com.sun.jndi.ldap.LdapPoolManager.showStats(System.out);
-// }
-
-// private PasswordPolicyResponseControl getPPolicyResponseCtl(InitialLdapContext ctx) throws NamingException {
-// Control[] ctrls = ctx.getResponseControls();
-//
-// for (int i = 0; ctrls != null && i < ctrls.length; i++) {
-// if (ctrls[i] instanceof PasswordPolicyResponseControl) {
-// return (PasswordPolicyResponseControl) ctrls[i];
-// }
-// }
-//
-// return null;
-// }
- public void testOpenLDAP33SecondsTillPasswordExpiryCtrlIsParsedCorrectly() {
- byte[] ctrlBytes = {0x30, 0x05, (byte) 0xA0, 0x03, (byte) 0xA0, 0x1, 0x21};
-
- PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(ctrlBytes);
-
- assertTrue(ctrl.hasWarning());
- assertEquals(33, ctrl.getTimeBeforeExpiration());
- }
-
- public void testOpenLDAP496GraceLoginsRemainingCtrlIsParsedCorrectly() {
- byte[] ctrlBytes = {0x30, 0x06, (byte) 0xA0, 0x04, (byte) 0xA1, 0x02, 0x01, (byte) 0xF0};
-
- PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(ctrlBytes);
-
- assertTrue(ctrl.hasWarning());
- assertEquals(496, ctrl.getGraceLoginsRemaining());
- }
-
- public void testOpenLDAP5GraceLoginsRemainingCtrlIsParsedCorrectly() {
- byte[] ctrlBytes = {0x30, 0x05, (byte) 0xA0, 0x03, (byte) 0xA1, 0x01, 0x05};
-
- PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(ctrlBytes);
-
- assertTrue(ctrl.hasWarning());
- assertEquals(5, ctrl.getGraceLoginsRemaining());
- }
-
- public void testOpenLDAPAccountLockedCtrlIsParsedCorrectly() {
- byte[] ctrlBytes = {0x30, 0x03, (byte) 0xA1, 0x01, 0x01};
-
- PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(ctrlBytes);
-
- assertTrue(ctrl.hasError() && ctrl.isLocked());
- assertFalse(ctrl.hasWarning());
- }
-
- public void testOpenLDAPPasswordExpiredCtrlIsParsedCorrectly() {
- byte[] ctrlBytes = {0x30, 0x03, (byte) 0xA1, 0x01, 0x00};
-
- PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(ctrlBytes);
-
- assertTrue(ctrl.hasError() && ctrl.isExpired());
- assertFalse(ctrl.hasWarning());
- }
-}