package com.hwlcn.ldap.util; import java.lang.reflect.Method; import java.util.Arrays; import java.util.concurrent.atomic.AtomicBoolean; import com.hwlcn.core.annotation.ThreadSafety; import com.hwlcn.ldap.ldap.sdk.LDAPException; import com.hwlcn.ldap.ldap.sdk.ResultCode; import static com.hwlcn.ldap.util.UtilityMessages.*; @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) public final class PasswordReader extends Thread { private final AtomicBoolean stopRequested; private final Object startMutex; private PasswordReader() { startMutex = new Object(); stopRequested = new AtomicBoolean(false); setName("Password Reader Thread"); setDaemon(true); setPriority(Thread.MAX_PRIORITY); } public static byte[] readPassword() throws LDAPException { try { final Method consoleMethod = System.class.getMethod("console"); final Object consoleObject = consoleMethod.invoke(null); final Method readPasswordMethod = consoleObject.getClass().getMethod("readPassword"); final char[] pwChars = (char[]) readPasswordMethod.invoke(consoleObject); final ByteStringBuffer buffer = new ByteStringBuffer(); buffer.append(pwChars); Arrays.fill(pwChars, '\u0000'); final byte[] pwBytes = buffer.toByteArray(); buffer.clear(true); return pwBytes; } catch (final Exception e) { Debug.debugException(e); } try { final PasswordReader r = new PasswordReader(); try { synchronized (r.startMutex) { r.start(); r.startMutex.wait(); } final ByteStringBuffer buffer = new ByteStringBuffer(); while (true) { final int byteRead = System.in.read(); if ((byteRead < 0) || (byteRead == 0x0A)) { break; } else if (byteRead == 0x0D) { final int nextCharacter = System.in.read(); if ((nextCharacter < 0) || (byteRead == 0x0A)) { break; } else { buffer.append((byte) byteRead); buffer.append((byte) nextCharacter); } } else { buffer.append((byte) byteRead); } } final byte[] pwBytes = buffer.toByteArray(); buffer.clear(true); return pwBytes; } finally { r.stopRequested.set(true); } } catch (final Exception e) { Debug.debugException(e); throw new LDAPException(ResultCode.LOCAL_ERROR, ERR_PW_READER_FAILURE.get(StaticUtils.getExceptionMessage(e)), e); } } @Override() public void run() { synchronized (startMutex) { startMutex.notifyAll(); } while (! stopRequested.get()) { System.out.print("\u0008 "); yield(); } } }