Skip to content

Commit

Permalink
Merge branch 'jwp/fileleak1' of https://github.com/looker/puma into l…
Browse files Browse the repository at this point in the history
…ooker-jwp/fileleak1
  • Loading branch information
nateberkopec committed Sep 8, 2020
2 parents 6d00226 + 8304338 commit f537856
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 12 deletions.
1 change: 1 addition & 0 deletions History.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
* Fix recursive `prune_bundler` (#2319).
* Ensure that TCP_CORK is usable
* Fix corner case when request body is chunked (#2326)
* Fix filehandle leak in MiniSSL (#2299)

* Refactor
* Remove unused loader argument from Plugin initializer (#2095)
Expand Down
52 changes: 40 additions & 12 deletions ext/puma_http11/org/jruby/puma/MiniSSL.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
Expand All @@ -32,6 +33,8 @@
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

import static javax.net.ssl.SSLEngineResult.Status;
import static javax.net.ssl.SSLEngineResult.HandshakeStatus;
Expand Down Expand Up @@ -130,31 +133,56 @@ public MiniSSL(Ruby runtime, RubyClass klass) {
super(runtime, klass);
}

private static Map<String, KeyManagerFactory> keyManagerFactoryMap = new ConcurrentHashMap<String, KeyManagerFactory>();
private static Map<String, TrustManagerFactory> trustManagerFactoryMap = new ConcurrentHashMap<String, TrustManagerFactory>();

@JRubyMethod(meta = true)
public static IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext) {
RubyClass klass = (RubyClass) recv;
public static synchronized IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
// Create the KeyManagerFactory and TrustManagerFactory for this server
String keystoreFile = miniSSLContext.callMethod(context, "keystore").convertToString().asJavaString();
char[] password = miniSSLContext.callMethod(context, "keystore_pass").convertToString().asJavaString().toCharArray();

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream is = new FileInputStream(keystoreFile);
try {
ks.load(is, password);
} finally {
is.close();
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, password);
keyManagerFactoryMap.put(keystoreFile, kmf);

KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
is = new FileInputStream(keystoreFile);
try {
ts.load(is, password);
} finally {
is.close();
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
trustManagerFactoryMap.put(keystoreFile, tmf);

RubyClass klass = (RubyClass) recv;
return klass.newInstance(context,
new IRubyObject[] { miniSSLContext },
Block.NULL_BLOCK);
}

@JRubyMethod
public IRubyObject initialize(ThreadContext threadContext, IRubyObject miniSSLContext)
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());

char[] password = miniSSLContext.callMethod(threadContext, "keystore_pass").convertToString().asJavaString().toCharArray();
String keystoreFile = miniSSLContext.callMethod(threadContext, "keystore").convertToString().asJavaString();
ks.load(new FileInputStream(keystoreFile), password);
ts.load(new FileInputStream(keystoreFile), password);

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, password);

TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
KeyManagerFactory kmf = keyManagerFactoryMap.get(keystoreFile);
TrustManagerFactory tmf = trustManagerFactoryMap.get(keystoreFile);
if(kmf == null || tmf == null) {
throw new KeyStoreException("Could not find KeyManagerFactory/TrustManagerFactory for keystore: " + keystoreFile);
}

SSLContext sslCtx = SSLContext.getInstance("TLS");

Expand Down

0 comments on commit f537856

Please sign in to comment.