diff --git a/src/org/apache/tomcat/util/net/jss/PlainPasswordFile.java b/src/org/apache/tomcat/util/net/jss/PlainPasswordFile.java index 1ed3359..a74d1ad 100644 --- a/src/org/apache/tomcat/util/net/jss/PlainPasswordFile.java +++ b/src/org/apache/tomcat/util/net/jss/PlainPasswordFile.java @@ -19,27 +19,96 @@ package org.apache.tomcat.util.net.jss; +import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.util.Enumeration; import java.util.Properties; public class PlainPasswordFile implements IPasswordStore { private String mPwdPath = ""; private Properties mPwdStore; - private static final String PASSWORD_WRITER_HEADER = ""; + private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(PlainPasswordFile.class); public PlainPasswordFile() { + mPwdStore = new Properties(); } + /** + * Initialization method to read passwords(key and element pairs) from a file. + *

+ * Every property occupies one line of the input stream. Each line is terminated by a line terminator ( + * \n or \r or \r\n). Lines are processed until end of + * file is reached. + *

+ * A line that contains only whitespace or whose first non-whitespace character is an ASCII # + * is ignored (thus, # indicates comment line). + *

+ * Every line other than a blank line or a comment line describes one property to be added to the table. + * The characters before the delimiter = forms the key and the characters after + * the = is assigned as value to the key. + *

+ * As an example, each of the following lines specify the key "Truth" and the associated element + * value "Beauty": + *

+ * + *

+     * Truth = Beauty
+     * Truth= Beauty
+     * Truth                    =Beauty
+     * 
+ * + *

+ * Note that the space appearing before/after = is ignored. However, the space appearing in between are + * stored. + *

+ * Example: + * + *

+     * Welcome Message  = Hello World
+     * 
+ * + * assigns value Hello World to key Welcome Message + *

+ * + * If the line doesn't have the delimiter =, the method throws an IOException + * + * @param pwdPath the input file path. + * @exception IOException if an error occurred when reading from the + * input stream. + */ public void init(String pwdPath) throws IOException { - mPwdStore = new Properties(); + logger.debug("PlainPasswordFile: Initializing PlainPasswordFile"); // initialize mPwdStore mPwdPath = pwdPath; - FileInputStream file = new FileInputStream(mPwdPath); - mPwdStore.load(file); + try (FileInputStream file = new FileInputStream(mPwdPath); + InputStreamReader isr = new InputStreamReader(file); + BufferedReader br = new BufferedReader(isr)) { + + String line; + int index = 1; + while ((line = br.readLine()) != null) { + // Remove any leading or trailing spaces + line = line.trim(); + + if (line.startsWith("#") || line.isEmpty()) + continue; + + String[] parts = line.split("=", 2); + if (parts.length < 2) { + throw new IOException("Missing delimiter '=' in file " + mPwdPath + " in line " + index); + } + + // Load key value into the password store + mPwdStore.put(parts[0].trim(), parts[1].trim()); + index++; + } + } } public String getPassword(String tag) { @@ -60,9 +129,22 @@ public Object putPassword(String tag, String password) { return mPwdStore.setProperty(tag, password); } - public void commit() throws IOException, ClassCastException, - NullPointerException { - FileOutputStream file = new FileOutputStream(mPwdPath); - mPwdStore.store(file, PASSWORD_WRITER_HEADER); + public synchronized void commit() + throws IOException, ClassCastException, NullPointerException { + try (FileOutputStream file = new FileOutputStream(mPwdPath); + OutputStreamWriter osw = new OutputStreamWriter(file); + BufferedWriter bw = new BufferedWriter(osw)) { + + for (Enumeration e = mPwdStore.keys(); e.hasMoreElements();) { + String key = ((String) e.nextElement()).trim(); + String val = ((String) mPwdStore.get(key)).trim(); + bw.write(key + "=" + val); + bw.newLine(); + } + } + } + + public int getSize() { + return mPwdStore.size(); } }