Author: sebb
Date: Thu Sep 5 11:23:15 2013
New Revision: 1520282
URL: http://svn.apache.org/r1520282
Log:
Proxy should support alias for keystore entry
Bugzilla Id: 55525
Modified:
jmeter/trunk/bin/jmeter.properties
jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/proxy/Proxy.java
jmeter/trunk/xdocs/changes.xml
Modified: jmeter/trunk/bin/jmeter.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1520282&r1=1520281&r2=1520282&view=diff
==============================================================================
--- jmeter/trunk/bin/jmeter.properties (original)
+++ jmeter/trunk/bin/jmeter.properties Thu Sep 5 11:23:15 2013
@@ -536,13 +536,19 @@ upgrade_properties=/bin/upgrade.properti
# use command-line flags for user-name and password
#http.proxyDomain=NTLM domain, if required by HTTPClient sampler
-# SSL configuration
-#proxy.cert.directory=.
+#---------------------------------------------------------------------------
+# JMeter Proxy Server configuration
+#---------------------------------------------------------------------------
+#proxy.cert.directory=<JMeter bin directory>
#proxy.cert.file=proxyserver.jks
#proxy.cert.type=JKS
#proxy.cert.keystorepass=password
#proxy.cert.keypassword=password
#proxy.cert.factory=SunX509
+# define this property if the keystore contains multiple aliases
+#proxy.cert.alias=<none>
+
+# SSL configuration
#proxy.ssl.protocol=SSLv3
#---------------------------------------------------------------------------
Modified: jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/proxy/Proxy.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/proxy/Proxy.java?rev=1520282&r1=1520281&r2=1520282&view=diff
==============================================================================
--- jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/proxy/Proxy.java (original)
+++ jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/proxy/Proxy.java Thu Sep
5 11:23:15 2013
@@ -32,15 +32,12 @@ import java.io.PrintStream;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
-import java.security.KeyManagementException;
+import java.security.GeneralSecurityException;
import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
import java.util.HashMap;
import java.util.Map;
+import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
@@ -106,6 +103,8 @@ public class Proxy extends Thread {
private static final String CERT_FILE =
JMeterUtils.getPropDefault("proxy.cert.file", CERT_FILE_DEFAULT); // $NON-NLS-1$
+ private static final String CERT_ALIAS = JMeterUtils.getProperty("proxy.cert.alias");
// $NON-NLS-1$
+
private static final String DEFAULT_PASSWORD = "password"; // $NON-NLS-1$
private static final SamplerCreatorFactory factory = new SamplerCreatorFactory();
@@ -301,49 +300,67 @@ public class Proxy extends Thread {
* Get SSL connection from hashmap, creating it if necessary.
*
* @param host
- * @return a ssl socket factory
+ * @return a ssl socket factory, or null if keystore could not be opened/processed
* @throws IOException
*/
- private SSLSocketFactory getSSLSocketFactory(String host) throws IOException {
+ private SSLSocketFactory getSSLSocketFactory(String host) {
synchronized (hashHost) {
if (hashHost.containsKey(host)) {
log.debug(port + "Good, already in map, host=" + host);
return hashHost.get(host);
}
- InputStream in = getCertificate();
- Exception except = null;
- if (in != null) {
- try {
- KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);
- ks.load(in, JMeterUtils.getPropDefault("proxy.cert.keystorepass", DEFAULT_PASSWORD).toCharArray());
// $NON-NLS-1$
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEYMANAGERFACTORY);
- kmf.init(ks, JMeterUtils.getPropDefault("proxy.cert.keypassword", DEFAULT_PASSWORD).toCharArray());
// $NON-NLS-1$
- SSLContext sslcontext = SSLContext.getInstance(SSLCONTEXT_PROTOCOL);
- sslcontext.init(kmf.getKeyManagers(), null, null);
- SSLSocketFactory sslFactory = sslcontext.getSocketFactory();
- hashHost.put(host, sslFactory);
- log.info(port + "KeyStore for SSL loaded OK and put host in map ("+host+")");
- return sslFactory;
- } catch (NoSuchAlgorithmException e) {
- except=e;
- } catch (KeyManagementException e) {
- except=e;
- } catch (KeyStoreException e) {
- except=e;
- } catch (UnrecoverableKeyException e) {
- except=e;
- } catch (CertificateException e) {
- except=e;
- } finally {
- if (except != null){
- log.error(port + "Problem with SSL certificate",except);
+ try {
+ SSLContext sslcontext = SSLContext.getInstance(SSLCONTEXT_PROTOCOL);
+ sslcontext.init(getKeyManagers(CERT_ALIAS), null, null);
+ SSLSocketFactory sslFactory = sslcontext.getSocketFactory();
+ hashHost.put(host, sslFactory);
+ log.info(port + "KeyStore for SSL loaded OK and put host in map ("+host+")");
+ return sslFactory;
+ } catch (GeneralSecurityException e) {
+ log.error(port + "Problem with SSL certificate", e);
+ } catch (IOException e) {
+ log.error(port + "Problem with keystore", e);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Return the key managers, wrapped if necessary to return a specific alias
+ *
+ * @param serverAlias the alias to return, or null to use whatever is present
+ * @return the key managers
+ * @throws GeneralSecurityException
+ * @throws IOException if the store cannot be opened or read or the alias is missing
+ */
+ private KeyManager[] getKeyManagers(String serverAlias) throws GeneralSecurityException,
IOException {
+ InputStream in = getCertificate();
+ if (in == null) {
+ throw new IOException("Cannot open keystore");
+ } else {
+ try {
+ KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);
+ ks.load(in, JMeterUtils.getPropDefault("proxy.cert.keystorepass", DEFAULT_PASSWORD).toCharArray());
// $NON-NLS-1$
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEYMANAGERFACTORY);
+ kmf.init(ks, JMeterUtils.getPropDefault("proxy.cert.keypassword", DEFAULT_PASSWORD).toCharArray());
// $NON-NLS-1$
+ final KeyManager[] keyManagers = kmf.getKeyManagers();
+ if (serverAlias == null) {
+ return keyManagers;
+ } else {
+ // Check if alias is suitable here, rather than waiting for connection
to fail
+ if (!ks.containsAlias(serverAlias)) {
+ throw new IOException("Keystore does not contain alias " + serverAlias);
+ }
+ final int keyManagerCount = keyManagers.length;
+ final KeyManager[] wrappedKeyManagers = new KeyManager[keyManagerCount];
+ for (int i =0; i < keyManagerCount; i++) {
+ wrappedKeyManagers[i] = new ServerAliasKeyManager(keyManagers[i],
serverAlias);
}
- IOUtils.closeQuietly(in);
+ return wrappedKeyManagers;
}
- } else {
- throw new IOException("Unable to read keystore");
+ } finally {
+ IOUtils.closeQuietly(in);
}
- return null;
}
}
Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1520282&r1=1520281&r2=1520282&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml (original)
+++ jmeter/trunk/xdocs/changes.xml Thu Sep 5 11:23:15 2013
@@ -353,6 +353,7 @@ Previously the default was 1, which coul
<li><bugzilla>53480</bugzilla> - Add Kerberos support to Http Sampler (HttpClient4).
Based on patch by Felix Schumacher (felix.schumacher at internetallee.de)</li>
<li><bugzilla>54874</bugzilla> - Support device in addition to source IP
address. Based on patch by Dan Fruehauf (malkodan at gmail.com)</li>
<li><bugzilla>55488</bugzilla> - Add .ico and .woff file extension to default
suggested exclusions in proxy recorder. Contributed by Antonio Gomes Rodrigues</li>
+<li><bugzilla>55525</bugzilla> - Proxy should support alias for keyserver
entry</li>
</ul>
<h3>Other samplers</h3>
|