/* * ==================== * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common Development * and Distribution License("CDDL") (the "License"). You may not use this file * except in compliance with the License. * * You can obtain a copy of the License at * http://IdentityConnectors.dev.java.net/legal/license.txt * See the License for the specific language governing permissions and limitations * under the License. * * When distributing the Covered Code, include this CDDL Header Notice in each file * and include the License file at identityconnectors/legal/license.txt. * If applicable, add the following below this CDDL Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * ==================== */ package org.identityconnectors.ldap.schema; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import javax.naming.directory.Attribute; import javax.naming.directory.BasicAttribute; import org.identityconnectors.common.security.GuardedString; import org.identityconnectors.common.security.SecurityUtil; public abstract class GuardedPasswordAttribute { public static GuardedPasswordAttribute create(String attrName, GuardedString password) { return new Simple(attrName, password); } public static GuardedPasswordAttribute create(String attrName) { return new Empty(attrName); } public abstract void access(Accessor accessor); public interface Accessor { void access(Attribute passwordAttribute); } private static final class Simple extends GuardedPasswordAttribute { private final String attrName; private final GuardedString password; private Simple(String attrName, GuardedString password) { this.attrName = attrName; this.password = password; } public void access(final Accessor accessor) { password.access(new GuardedString.Accessor() { public void access(char[] clearChars) { // TODO this is still not good enough. Need a simple and reliable // way to convert UTF-16 to UTF-8 bytes. CharBuffer charBuf = CharBuffer.wrap(clearChars); ByteBuffer byteBuf = Charset.forName("UTF-8").encode(charBuf); try { byteBuf.rewind(); byte[] bytes = new byte[byteBuf.limit()]; byteBuf.get(bytes); try { BasicAttribute attr = new BasicAttribute(attrName, bytes); accessor.access(attr); } finally { SecurityUtil.clear(bytes); } } finally { byteBuf.rewind(); while (byteBuf.remaining() > 0) { byteBuf.put((byte) 0); } } } }); } } private static final class Empty extends GuardedPasswordAttribute { private final String attrName; private Empty(String attrName) { this.attrName = attrName; } @Override public void access(Accessor accessor) { accessor.access(new BasicAttribute(attrName)); } } }