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();
}
}