/* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2004-2010. * Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.tools.ldapdecoder.protocol; import com.slamd.asn1.ASN1Boolean; import com.slamd.asn1.ASN1Element; import com.slamd.asn1.ASN1OctetString; import com.slamd.asn1.ASN1Sequence; /** * This class defines an LDAP control, which provides additional information * that may be used when processing an LDAP operation. * * * @author Neil A. Wilson */ public class LDAPControl { /** * The ASN.1 type that should be used for a sequence of controls. */ public static final byte CONTROL_SEQUENCE_TYPE = (byte) 0xA0; // The value for this control. private ASN1OctetString controlValue; // Indicates whether this control should be considered critical. private boolean isCritical; // The OID for this LDAP control. private String controlOID; /** * Creates a new LDAP control with the specified OID. It will not be critical * and will not have a value. * * @param controlOID The OID for this control. */ public LDAPControl(String controlOID) { this.controlOID = controlOID; this.isCritical = false; this.controlValue = null; } /** * Creates a new LDAP control with the specified OID, criticality, and value. * * @param controlOID The OID for this control. * @param isCritical Indicates whether this control should be marked * critical. * @param controlValue The value for this control. */ public LDAPControl(String controlOID, boolean isCritical, ASN1OctetString controlValue) { this.controlOID = controlOID; this.isCritical = isCritical; this.controlValue = controlValue; } /** * Retrieves the OID for this control. * * @return The OID for this control. */ public String getControlOID() { return controlOID; } /** * Indicates whether this control is marked critical. * * @return <CODE>true</CODE> if this control is marked critical, or * <CODE>false</CODE> if not. */ public boolean isCritical() { return isCritical; } /** * Retrieves the value for this control. * * @return The value for this control, or <CODE>null</CODE> if it does not * have a value. */ public ASN1OctetString getValue() { return controlValue; } /** * Encodes this control to an ASN.1 element. * * @return The ASN.1 element containing the encoded control. */ public ASN1Element encode() { ASN1Element[] controlElements; if (controlValue == null) { if (isCritical) { controlElements = new ASN1Element[] { new ASN1OctetString(controlOID), new ASN1Boolean(isCritical) }; } else { controlElements = new ASN1Element[] { new ASN1OctetString(controlOID) }; } } else { controlElements = new ASN1Element[] { new ASN1OctetString(controlOID), new ASN1Boolean(isCritical), controlValue }; } return new ASN1Sequence(controlElements); } /** * Encodes the provided array of controls to an ASN.1 sequence suitable for * including in an LDAP message. * * @param controls The set of controls to be encoded. * * @return The ASN.1 element containing the encoded controls. */ public static ASN1Element encode(LDAPControl[] controls) { ASN1Element[] controlElements = new ASN1Element[controls.length]; for (int i=0; i < controlElements.length; i++) { controlElements[i] = controls[i].encode(); } return new ASN1Sequence(CONTROL_SEQUENCE_TYPE, controlElements); } /** * Decodes the provided ASN.1 element as an LDAP control. * * @param element The ASN.1 element to decode as an LDAP control. * * @return The decoded LDAP control. * * @throws ProtocolException If a problem occurs while decoding the ASN.1 * element as an LDAP control. */ public static LDAPControl decode(ASN1Element element) throws ProtocolException { String controlOID; boolean isCritical = false; ASN1OctetString controlValue = null; ASN1Element[] controlElements; try { controlElements = element.decodeAsSequence().getElements(); } catch (Exception e) { throw new ProtocolException("Unable to decode ASN.1 element as a " + "control sequence", e); } if ((controlElements.length == 0) || (controlElements.length > 3)) { throw new ProtocolException("There must be between 1 and 3 elements in " + "an LDAP control sequence"); } try { controlOID = controlElements[0].decodeAsOctetString().getStringValue(); } catch (Exception e) { throw new ProtocolException("Unable to decode control OID", e); } if (controlElements.length >= 2) { if ((controlElements.length == 2) && (controlElements[1].getType() == ASN1Element.ASN1_OCTET_STRING_TYPE)) { try { controlValue = controlElements[1].decodeAsOctetString(); } catch (Exception e) { throw new ProtocolException("Unable to decode control value", e); } } else { try { isCritical = controlElements[1].decodeAsBoolean().getBooleanValue(); } catch (Exception e) { throw new ProtocolException("Unable to decode control criticality", e); } } } if (controlElements.length == 3) { try { controlValue = controlElements[2].decodeAsOctetString(); } catch (Exception e) { throw new ProtocolException("Unable to decode control value", e); } } try { if (controlOID.equals(ManageDSAITControl.MANAGE_DSA_IT_CONTROL_OID)) { return new ManageDSAITControl(isCritical); } else if (controlOID.equals( PersistentSearchControl.PERSISTENT_SEARCH_CONTROL_OID)) { return new PersistentSearchControl(isCritical, controlValue); } else if (controlOID.equals(EntryChangeNotificationControl. ENTRY_CHANGE_NOTIFICATION_CONTROL_OID)) { return new EntryChangeNotificationControl(isCritical, controlValue); } else if (controlOID.equals( PasswordExpiredControl.PASSWORD_EXPIRED_CONTROL_OID)) { return new PasswordExpiredControl(isCritical); } else if (controlOID.equals( PasswordExpiringControl.PASSWORD_EXPIRING_CONTROL_OID)) { return new PasswordExpiringControl(isCritical, controlValue); } else if (controlOID.equals( PasswordPolicyControl.PASSWORD_POLICY_CONTROL_OID)) { return new PasswordPolicyControl(isCritical, controlValue); } else if (controlOID.equals( ServerSortRequestControl.SERVER_SORT_REQUEST_CONTROL_OID)) { return new ServerSortRequestControl(isCritical, controlValue); } else if (controlOID.equals( ServerSortResponseControl.SERVER_SORT_RESPONSE_CONTROL_OID)) { return new ServerSortResponseControl(isCritical, controlValue); } else if (controlOID.equals(VLVRequestControl.VLV_REQUEST_CONTROL_OID)) { return new VLVRequestControl(isCritical, controlValue); } else if (controlOID.equals(VLVResponseControl.VLV_RESPONSE_CONTROL_OID)) { return new VLVResponseControl(isCritical, controlValue); } else if (controlOID.equals( ProxiedAuthV1Control.PROXIED_AUTH_V1_CONTROL_OID)) { return new ProxiedAuthV1Control(isCritical, controlValue); } else if (controlOID.equals( ProxiedAuthV2Control.PROXIED_AUTH_V2_CONTROL_OID)) { return new ProxiedAuthV2Control(isCritical, controlValue); } else if (controlOID.equals( RealAttributesOnlyControl.REAL_ATTRIBUTES_ONLY_CONTROL_OID)) { return new RealAttributesOnlyControl(isCritical); } else if (controlOID.equals( GetEffectiveRightsControl.GET_EFFECTIVE_RIGHTS_CONTROL_OID)) { return new GetEffectiveRightsControl(isCritical, controlValue); } else if (controlOID.equals( AuthorizationIDRequestControl.AUTHORIZATION_ID_REQUEST_OID)) { return new AuthorizationIDRequestControl(isCritical); } else if (controlOID.equals( AuthorizationIDResponseControl.AUTHORIZATION_ID_RESPONSE_OID)) { return new AuthorizationIDResponseControl(isCritical, controlValue); } else if (controlOID.equals(PagedResultsControl.PAGED_RESULTS_CONTROL_OID)) { return new PagedResultsControl(isCritical, controlValue); } } catch (Exception e) {} return new LDAPControl(controlOID, isCritical, controlValue); } /** * Decodes the provided ASN.1 element as a set of LDAP controls. * * @param element The ASN.1 element to decode as a set of LDAP controls. * * @return The decoded array of controls. * * @throws ProtocolException If a problem occurs while decoding the set of * controls. */ public static LDAPControl[] decodeControls(ASN1Element element) throws ProtocolException { ASN1Element[] controlElements; try { controlElements = element.decodeAsSequence().getElements(); } catch (Exception e) { throw new ProtocolException("Unable to decode ASN.1 element as a " + "sequence of controls", e); } LDAPControl[] controls = new LDAPControl[controlElements.length]; for (int i=0; i < controlElements.length; i++) { controls[i] = decode(controlElements[i]); } return controls; } /** * Retrieves a string representation of this control. * * @return A string representation of this control. */ public String toString() { return toString(0); } /** * Retrieves a string representation of this control with the specified * indent. * * @param indent The number of spaces to indent the output. * * @return A string representation of this control with the specified indent. */ public String toString(int indent) { StringBuilder indentBuf = new StringBuilder(indent); for (int i=0; i < indent; i++) { indentBuf.append(' '); } StringBuilder buffer = new StringBuilder(); buffer.append(indentBuf).append("LDAP Control").append(LDAPMessage.EOL); buffer.append(indentBuf).append(" OID: ").append(controlOID). append(LDAPMessage.EOL); buffer.append(indentBuf).append(" Criticality: "). append(isCritical).append(LDAPMessage.EOL); if (controlValue != null) { byte[] valueBytes = controlValue.getValue(); buffer.append(indentBuf).append(" Value: ").append(LDAPMessage.EOL); buffer.append(LDAPMessage.byteArrayToString(valueBytes, (indent+8))); } return buffer.toString(); } }