001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.security.plugins;
023:
024: import java.io.File;
025: import java.io.FileInputStream;
026: import java.io.IOException;
027: import java.io.CharArrayWriter;
028: import java.io.InterruptedIOException;
029: import java.io.RandomAccessFile;
030:
031: import org.jboss.logging.Logger;
032:
033: /** Read a password from a file specified via the ctor and then overwrite
034: the file contents with garbage, and then remove it. This may be used as a
035: password accessor in conjunction with the JaasSecurityDomain
036: {CLASS}org.jboss.security.plugins.TmpFilePassword:password-file
037: format of the KeyStorePass attribute.
038:
039: This class waits until the file exists if it does not when toCharArray()
040: is called. It prints out to the console every 10 seconds the path to
041: the file it is waiting on until the file is created.
042:
043: @author Scott.Stark@jboss.org
044: @version $Revison:$
045: */
046: public class TmpFilePassword {
047: private static Logger log = Logger.getLogger(TmpFilePassword.class);
048: private File passwordFile;
049: private long timeoutSystemTime;
050:
051: /**
052: * Load a password file file. Invokes this(file, null).
053: * @param file - the file to load the password from.
054: */
055: public TmpFilePassword(String file) {
056: this (file, null);
057: }
058:
059: /**
060: * Load a password from file.
061: *
062: * @param file - the file to load the password from.
063: * @param timeout - the timeout in milliseconds. If null, no
064: * timeout will be used.
065: */
066: public TmpFilePassword(String file, String timeout) {
067: passwordFile = new File(file);
068: if (timeout != null) {
069: long ms = Long.parseLong(timeout);
070: timeoutSystemTime = System.currentTimeMillis() + ms;
071: }
072: }
073:
074: public char[] toCharArray() throws IOException {
075: while (passwordFile.exists() == false) {
076: log.info("Waiting for password file: "
077: + passwordFile.getAbsolutePath());
078: try {
079: Thread.sleep(10 * 1000);
080: } catch (InterruptedException e) {
081: log.info("Exiting wait on InterruptedException");
082: break;
083: }
084: long now = System.currentTimeMillis();
085: if (now > timeoutSystemTime)
086: throw new InterruptedIOException(
087: "Timed out waiting for: "
088: + passwordFile.getAbsolutePath());
089: }
090: FileInputStream fis = new FileInputStream(passwordFile);
091: CharArrayWriter writer = new CharArrayWriter();
092: int b;
093: while ((b = fis.read()) >= 0) {
094: if (b == '\r' || b == '\n')
095: continue;
096: writer.write(b);
097: }
098: fis.close();
099: char[] password = writer.toCharArray();
100: writer.reset();
101: for (int n = 0; n < password.length; n++)
102: writer.write('\0');
103:
104: // Overwrite the password file
105: try {
106: RandomAccessFile raf = new RandomAccessFile(passwordFile,
107: "rws");
108: for (int i = 0; i < 10; i++) {
109: raf.seek(0);
110: for (int j = 0; j < password.length; j++)
111: raf.write(j);
112: }
113: raf.close();
114: if (passwordFile.delete() == false)
115: log.warn("Was not able to delete the password file");
116: } catch (Exception e) {
117: log.warn("Failed to zero the password file", e);
118: }
119: return password;
120: }
121: }
|