You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by fs...@apache.org on 2020/12/06 10:36:48 UTC
[jmeter] 03/04: Keystore password not reset on reload
This is an automated email from the ASF dual-hosted git repository.
fschumacher pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jmeter.git
commit 6701514938f743d864956e4564db13776f7a1f02
Author: Felix Schumacher <fe...@internetallee.de>
AuthorDate: Sun Dec 6 11:29:43 2020 +0100
Keystore password not reset on reload
Bugzilla Id: 64955
---
.../java/org/apache/jmeter/util/SSLManager.java | 94 ++++++++++++++--------
xdocs/changes.xml | 1 +
2 files changed, 61 insertions(+), 34 deletions(-)
diff --git a/src/core/src/main/java/org/apache/jmeter/util/SSLManager.java b/src/core/src/main/java/org/apache/jmeter/util/SSLManager.java
index 067ef5c..6b491eb 100644
--- a/src/core/src/main/java/org/apache/jmeter/util/SSLManager.java
+++ b/src/core/src/main/java/org/apache/jmeter/util/SSLManager.java
@@ -17,18 +17,24 @@
package org.apache.jmeter.util;
-import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.Locale;
+import javax.swing.JLabel;
import javax.swing.JOptionPane;
+import javax.swing.JPanel;
import javax.swing.JPasswordField;
import org.apache.commons.lang3.Validate;
@@ -37,6 +43,8 @@ import org.apache.jmeter.util.keystore.JmeterKeyStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import net.miginfocom.swing.MigLayout;
+
/**
* The SSLManager handles the KeyStore information for JMeter. Basically, it
* handles all the logic for loading and initializing all the JSSE parameters
@@ -75,7 +83,7 @@ public abstract class SSLManager {
private volatile boolean truststoreLoaded=false;
/** Have the password available */
- protected String defaultpw = System.getProperty(KEY_STORE_PASSWORD);
+ protected volatile String defaultpw = System.getProperty(KEY_STORE_PASSWORD);
private int keystoreAliasStartIndex;
@@ -130,20 +138,16 @@ public abstract class SSLManager {
// The string 'NONE' is used for the keystore location when using PKCS11
// https://docs.oracle.com/javase/8/docs/technotes/guides/security/p11guide.html#JSSE
if ("NONE".equalsIgnoreCase(fileName)) {
- this.keyStore.load(null, Validate.notNull(getPassword(), "Password should not be null"));
+ retryLoadKeys(null, false);
log.info("Total of {} aliases loaded OK from PKCS11", keyStore.getAliasCount());
} else {
File initStore = new File(fileName);
if (fileName.length() > 0 && initStore.exists()) {
- try (InputStream fis = new FileInputStream(initStore);
- InputStream fileInputStream = new BufferedInputStream(fis)) {
- this.keyStore.load(fileInputStream, getPassword());
- if (log.isInfoEnabled()) {
- log.info(
- "Total of {} aliases loaded OK from keystore",
- keyStore.getAliasCount());
- }
- }
+ retryLoadKeys(initStore, true);
+ if (log.isInfoEnabled()) {
+ log.info("Total of {} aliases loaded OK from keystore {}",
+ keyStore.getAliasCount(), fileName);
+ }
} else {
log.warn("Keystore file not found, loading empty keystore");
this.defaultpw = ""; // Ensure not null
@@ -162,6 +166,29 @@ public abstract class SSLManager {
return this.keyStore;
}
+ private void retryLoadKeys(File initStore, boolean allowEmptyPassword) throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException,
+ UnrecoverableKeyException {
+ for (int i=0; i<3; i++) {
+ String password = getPassword();
+ if (!allowEmptyPassword) {
+ Validate.notNull(password, "Password for keystore must not be null");
+ }
+ try {
+ if (initStore == null) {
+ this.keyStore.load(null, password);
+ } else {
+ try (InputStream fis = new FileInputStream(initStore)) {
+ this.keyStore.load(fis, password);
+ }
+ }
+ return;
+ } catch (IOException e) {
+ log.debug("Could not load keystore. Wrong password for keystore?", e);
+ }
+ this.defaultpw = null;
+ }
+ }
+
/*
* The password can be defined as a property; this dialogue is provided to allow it
* to be entered at run-time.
@@ -171,26 +198,26 @@ public abstract class SSLManager {
if (null == password) {
final GuiPackage guiInstance = GuiPackage.getInstance();
if (guiInstance != null) {
- synchronized (this) { // TODO is sync really needed?
- JPasswordField pwf = new JPasswordField(64);
- pwf.setEchoChar('*');
- int choice = JOptionPane.showConfirmDialog(
- guiInstance.getMainFrame(),
- pwf,
- JMeterUtils.getResString("ssl_pass_prompt"),
- JOptionPane.OK_CANCEL_OPTION,
- JOptionPane.PLAIN_MESSAGE);
- if (choice == JOptionPane.OK_OPTION) {
- char[] pwchars = pwf.getPassword();
- this.defaultpw = new String(pwchars);
- Arrays.fill(pwchars, '*');
- }
- System.setProperty(KEY_STORE_PASSWORD, this.defaultpw);
- password = this.defaultpw;
- }
- } else {
- log.warn("No password provided, and no GUI present so cannot prompt");
+ JPanel panel = new JPanel(new MigLayout("fillx, wrap 2", "[][fill, grow]"));
+ JLabel passwordLabel = new JLabel("Password: ");
+ JPasswordField pwf = new JPasswordField(64);
+ pwf.setEchoChar('*');
+ passwordLabel.setLabelFor(pwf);
+ panel.add(passwordLabel);
+ panel.add(pwf);
+ int choice = JOptionPane.showConfirmDialog(guiInstance.getMainFrame(), panel,
+ JMeterUtils.getResString("ssl_pass_prompt"), JOptionPane.OK_CANCEL_OPTION,
+ JOptionPane.PLAIN_MESSAGE);
+ if (choice == JOptionPane.OK_OPTION) {
+ char[] pwchars = pwf.getPassword();
+ this.defaultpw = new String(pwchars);
+ Arrays.fill(pwchars, '*');
+ }
+ System.setProperty(KEY_STORE_PASSWORD, this.defaultpw);
+ password = this.defaultpw;
}
+ } else {
+ log.warn("No password provided, and no GUI present so cannot prompt");
}
return password;
}
@@ -239,9 +266,8 @@ public abstract class SSLManager {
File initStore = new File(fileName);
if (initStore.exists()) {
- try (InputStream fis = new FileInputStream(initStore);
- InputStream fileInputStream = new BufferedInputStream(fis)) {
- this.trustStore.load(fileInputStream, null);
+ try (InputStream fis = new FileInputStream(initStore)) {
+ this.trustStore.load(fis, null);
log.info("Truststore loaded OK from file");
}
} else {
diff --git a/xdocs/changes.xml b/xdocs/changes.xml
index 0b6ee08..13e7d06 100644
--- a/xdocs/changes.xml
+++ b/xdocs/changes.xml
@@ -122,6 +122,7 @@ Summary
<h3>HTTP Samplers and Test Script Recorder</h3>
<ul>
+ <li><bug>64955</bug>Keystore password not reset on reload</li>
</ul>
<h3>Other Samplers</h3>