Skip to content

Commit 7abf40c

Browse files
author
Jarrod Ribble
committed
Support separate keystore file and key passwords.
1 parent aaa4c22 commit 7abf40c

File tree

6 files changed

+37
-22
lines changed

6 files changed

+37
-22
lines changed

src/main/java/com/netiq/websockify/PortUnificationHandler.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,23 @@ public class PortUnificationHandler extends FrameDecoder {
4848
private final IProxyTargetResolver resolver;
4949
private final SSLSetting sslSetting;
5050
private final String keystore;
51-
private final String keystorePassword;
51+
private final String keystorePassword;
52+
private final String keystoreKeyPassword;
5253
private final String webDirectory;
5354
private Timer msgTimer = null;
5455

55-
private PortUnificationHandler(ClientSocketChannelFactory cf, IProxyTargetResolver resolver, SSLSetting sslSetting, String keystore, String keystorePassword, String webDirectory, final ChannelHandlerContext ctx) {
56-
this ( cf, resolver, sslSetting, keystore, keystorePassword, webDirectory);
56+
private PortUnificationHandler(ClientSocketChannelFactory cf, IProxyTargetResolver resolver, SSLSetting sslSetting, String keystore, String keystorePassword, String keystoreKeyPassword, String webDirectory, final ChannelHandlerContext ctx) {
57+
this ( cf, resolver, sslSetting, keystore, keystorePassword, keystoreKeyPassword, webDirectory);
5758
startDirectConnectionTimer(ctx);
5859
}
5960

60-
public PortUnificationHandler(ClientSocketChannelFactory cf, IProxyTargetResolver resolver, SSLSetting sslSetting, String keystore, String keystorePassword, String webDirectory) {
61+
public PortUnificationHandler(ClientSocketChannelFactory cf, IProxyTargetResolver resolver, SSLSetting sslSetting, String keystore, String keystorePassword, String keystoreKeyPassword, String webDirectory) {
6162
this.cf = cf;
6263
this.resolver = resolver;
6364
this.sslSetting = sslSetting;
6465
this.keystore = keystore;
6566
this.keystorePassword = keystorePassword;
67+
this.keystoreKeyPassword = keystoreKeyPassword;
6668
this.webDirectory = webDirectory;
6769
}
6870

@@ -148,11 +150,11 @@ private void enableSsl(ChannelHandlerContext ctx) {
148150

149151
Logger.getLogger(PortUnificationHandler.class.getName()).fine("SSL request from " + ctx.getChannel().getRemoteAddress() + ".");
150152

151-
SSLEngine engine = WebsockifySslContext.getInstance(keystore, keystorePassword).getServerContext().createSSLEngine();
153+
SSLEngine engine = WebsockifySslContext.getInstance(keystore, keystorePassword, keystoreKeyPassword).getServerContext().createSSLEngine();
152154
engine.setUseClientMode(false);
153155

154156
p.addLast("ssl", new SslHandler(engine));
155-
p.addLast("unificationA", new PortUnificationHandler(cf, resolver, SSLSetting.OFF, keystore, keystorePassword, webDirectory, ctx));
157+
p.addLast("unificationA", new PortUnificationHandler(cf, resolver, SSLSetting.OFF, keystore, keystorePassword, keystoreKeyPassword, webDirectory, ctx));
156158
p.remove(this);
157159
}
158160

src/main/java/com/netiq/websockify/Websockify.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ public class Websockify {
2929
@Option(name="--keystore-password",usage="password to the java keystore file. Required for SSL.")
3030
private String keystorePassword = null;
3131

32+
@Option(name="--keystore-key-password",usage="password to the private key in the java keystore file. If not specified the keystore-password value will be used.")
33+
private String keystoreKeyPassword = null;
34+
3235
@Argument(index=0,metaVar="source_port",usage="(required) local port the websockify server will listen on",required=true)
3336
private int sourcePort;
3437

@@ -92,6 +95,10 @@ public void doMain(String[] args) throws Exception {
9295
printUsage(System.err);
9396
System.exit(1);
9497
}
98+
99+
if (keystoreKeyPassword == null || keystoreKeyPassword.isEmpty()) {
100+
keystoreKeyPassword = keystorePassword;
101+
}
95102
}
96103

97104
System.out.println(
@@ -100,7 +107,7 @@ public void doMain(String[] args) throws Exception {
100107
if(sslSetting != SSLSetting.OFF) System.out.println("SSL is " + (sslSetting == SSLSetting.REQUIRED ? "required." : "enabled."));
101108

102109
WebsockifyServer wss = new WebsockifyServer ( );
103-
wss.connect ( sourcePort, targetHost, targetPort, sslSetting, keystore, keystorePassword, webDirectory );
110+
wss.connect ( sourcePort, targetHost, targetPort, sslSetting, keystore, keystorePassword, keystoreKeyPassword, webDirectory );
104111

105112
}
106113

src/main/java/com/netiq/websockify/WebsockifyProxyHandler.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.net.MalformedURLException;
2020
import java.net.URI;
2121
import java.net.URISyntaxException;
22-
import java.net.URL;
2322
import java.net.URLDecoder;
2423
import java.text.SimpleDateFormat;
2524
import java.util.Calendar;

src/main/java/com/netiq/websockify/WebsockifyProxyPipelineFactory.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,24 @@ public class WebsockifyProxyPipelineFactory implements ChannelPipelineFactory {
1515
private final SSLSetting sslSetting;
1616
private final String keystore;
1717
private final String keystorePassword;
18+
private final String keystoreKeyPassword;
1819
private final String webDirectory;
1920

20-
public WebsockifyProxyPipelineFactory(ClientSocketChannelFactory cf, IProxyTargetResolver resolver, SSLSetting sslSetting, String keystore, String keystorePassword, String webDirectory) {
21+
public WebsockifyProxyPipelineFactory(ClientSocketChannelFactory cf, IProxyTargetResolver resolver, SSLSetting sslSetting, String keystore, String keystorePassword, String keystoreKeyPassword, String webDirectory) {
2122
this.cf = cf;
2223
this.resolver = resolver;
2324
this.sslSetting = sslSetting;
2425
this.keystore = keystore;
2526
this.keystorePassword = keystorePassword;
27+
this.keystoreKeyPassword = keystoreKeyPassword;
2628
this.webDirectory = webDirectory;
2729
}
2830

2931
@Override
3032
public ChannelPipeline getPipeline() throws Exception {
3133
ChannelPipeline p = pipeline(); // Note the static import.
3234

33-
p.addLast("unification", new PortUnificationHandler(cf, resolver, sslSetting, keystore, keystorePassword, webDirectory));
35+
p.addLast("unification", new PortUnificationHandler(cf, resolver, sslSetting, keystore, keystorePassword, keystoreKeyPassword, webDirectory));
3436
return p;
3537

3638
}

src/main/java/com/netiq/websockify/WebsockifyServer.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ public void connect ( int localPort, String remoteHost, int remotePort )
3535

3636
public void connect ( int localPort, String remoteHost, int remotePort, String webDirectory )
3737
{
38-
connect ( localPort, remoteHost, remotePort, SSLSetting.OFF, null, null, webDirectory );
38+
connect ( localPort, remoteHost, remotePort, SSLSetting.OFF, null, null, null, webDirectory );
3939
}
4040

41-
public void connect ( int localPort, String remoteHost, int remotePort, SSLSetting sslSetting, String keystore, String keystorePassword, String webDirectory )
41+
public void connect ( int localPort, String remoteHost, int remotePort, SSLSetting sslSetting, String keystore, String keystorePassword, String keystoreKeyPassword, String webDirectory )
4242
{
43-
connect ( localPort, new StaticTargetResolver ( remoteHost, remotePort ), sslSetting, keystore, keystorePassword, webDirectory );
43+
connect ( localPort, new StaticTargetResolver ( remoteHost, remotePort ), sslSetting, keystore, keystorePassword, keystoreKeyPassword, webDirectory );
4444
}
4545

4646
public void connect ( int localPort, IProxyTargetResolver resolver )
@@ -50,17 +50,17 @@ public void connect ( int localPort, IProxyTargetResolver resolver )
5050

5151
public void connect ( int localPort, IProxyTargetResolver resolver, String webDirectory )
5252
{
53-
connect ( localPort, resolver, SSLSetting.OFF, null, null, webDirectory );
53+
connect ( localPort, resolver, SSLSetting.OFF, null, null, null, webDirectory );
5454
}
5555

56-
public void connect ( int localPort, IProxyTargetResolver resolver, SSLSetting sslSetting, String keystore, String keystorePassword, String webDirectory )
56+
public void connect ( int localPort, IProxyTargetResolver resolver, SSLSetting sslSetting, String keystore, String keystorePassword, String keystoreKeyPassword, String webDirectory )
5757
{
5858
if ( serverChannel != null )
5959
{
6060
close ( );
6161
}
6262

63-
sb.setPipelineFactory(new WebsockifyProxyPipelineFactory(cf, resolver, sslSetting, keystore, keystorePassword, webDirectory));
63+
sb.setPipelineFactory(new WebsockifyProxyPipelineFactory(cf, resolver, sslSetting, keystore, keystorePassword, keystoreKeyPassword, webDirectory));
6464

6565
// Start up the server.
6666
serverChannel = sb.bind(new InetSocketAddress(localPort));

src/main/java/com/netiq/websockify/WebsockifySslContext.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ public class WebsockifySslContext {
2121
/**
2222
* Returns the singleton instance for this class
2323
*/
24-
public static WebsockifySslContext getInstance(String keystore, String keystorePassword) {
24+
public static WebsockifySslContext getInstance(String keystore, String password, String keyPassword) {
2525
WebsockifySslContext context = SingletonHolder.INSTANCE_MAP.get(keystore);
2626
if ( context == null )
2727
{
28-
context = new WebsockifySslContext ( keystore, keystorePassword );
28+
context = new WebsockifySslContext ( keystore, password, keyPassword );
2929
SingletonHolder.INSTANCE_MAP.put(keystore, context);
3030
}
3131
return context;
@@ -40,11 +40,17 @@ public static WebsockifySslContext getInstance(String keystore, String keystoreP
4040
private static class SingletonHolder {
4141
public static final HashMap<String, WebsockifySslContext> INSTANCE_MAP = new HashMap<String, WebsockifySslContext>();
4242
}
43+
/**
44+
* Constructor for singleton
45+
*/
46+
private WebsockifySslContext(String keystore, String password) {
47+
this ( keystore, password, password );
48+
}
4349

4450
/**
4551
* Constructor for singleton
4652
*/
47-
private WebsockifySslContext(String keystore, String keystorePassword) {
53+
private WebsockifySslContext(String keystore, String password, String keyPassword) {
4854
try {
4955
// Key store (Server side certificate)
5056
String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm");
@@ -55,17 +61,16 @@ private WebsockifySslContext(String keystore, String keystorePassword) {
5561
SSLContext serverContext = null;
5662
try {
5763
String keyStoreFilePath = keystore;
58-
String keyStoreFilePassword = keystorePassword;
5964

6065
KeyStore ks = KeyStore.getInstance("JKS");
6166
FileInputStream fin = new FileInputStream(keyStoreFilePath);
62-
ks.load(fin, keyStoreFilePassword.toCharArray());
67+
ks.load(fin, password.toCharArray());
6368

6469
// Set up key manager factory to use our key store
6570
// Assume key password is the same as the key store file
6671
// password
6772
KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
68-
kmf.init(ks, keyStoreFilePassword.toCharArray());
73+
kmf.init(ks, keyPassword.toCharArray());
6974

7075
// Initialise the SSLContext to work with our key managers.
7176
serverContext = SSLContext.getInstance(PROTOCOL);

0 commit comments

Comments
 (0)