You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2019/08/16 07:58:12 UTC
[httpcomponents-core] branch 4.4.x updated: Execute
Socket[Channel]#connect under doPrivileged (#138)
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch 4.4.x
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
The following commit(s) were added to refs/heads/4.4.x by this push:
new 79d5ea0 Execute Socket[Channel]#connect under doPrivileged (#138)
79d5ea0 is described below
commit 79d5ea0d6633ae5a9e0d1e4409d56d290cc32ca8
Author: Simon Willnauer <si...@apache.org>
AuthorDate: Fri Aug 16 09:58:08 2019 +0200
Execute Socket[Channel]#connect under doPrivileged (#138)
* Execute Socket[Channel]#connect under doPrivileged
In order to allow users to run under a security manager that only grants
connect permission to the httpcore codebase the connect methods should
be executed in a doPriveledged block.
This is certainly not the only issue that users run into when they
install a SecurityManager with strict permissions but certainly the
most prominent and most likely one. Upstream components like the client
might also need to protect places accessing the proxy selector etc.
---
.../nio/reactor/DefaultConnectingIOReactor.java | 23 +++++++++++++++++++++-
.../apache/http/impl/pool/BasicConnFactory.java | 22 ++++++++++++++++++++-
2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultConnectingIOReactor.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultConnectingIOReactor.java
index 1dcea63..d9118a9 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultConnectingIOReactor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultConnectingIOReactor.java
@@ -35,6 +35,9 @@ import java.net.UnknownHostException;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -274,7 +277,25 @@ public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
sock.setReuseAddress(this.config.isSoReuseAddress());
sock.bind(request.getLocalAddress());
}
- final boolean connected = socketChannel.connect(request.getRemoteAddress());
+
+ final SocketAddress targetAddress = request.getRemoteAddress();
+ // Run this under a doPrivileged to support lib users that run under a SecurityManager this allows granting connect
+ // permissions only to this library
+ final boolean connected;
+ try {
+ connected = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<Boolean>() {
+ @Override
+ public Boolean run() throws IOException {
+ return socketChannel.connect(targetAddress);
+ };
+ });
+ } catch (final PrivilegedActionException e) {
+ Asserts.check(e.getCause() instanceof IOException,
+ "method contract violation only checked exceptions are wrapped: " + e.getCause());
+ // only checked exceptions are wrapped - error and RTExceptions are rethrown by doPrivileged
+ throw (IOException) e.getCause();
+ }
if (connected) {
final ChannelEntry entry = new ChannelEntry(socketChannel, request);
addChannel(entry);
diff --git a/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java b/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java
index 508fa52..4c11082 100644
--- a/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java
+++ b/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java
@@ -29,6 +29,9 @@ package org.apache.http.impl.pool;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
@@ -47,6 +50,7 @@ import org.apache.http.params.HttpParamConfig;
import org.apache.http.params.HttpParams;
import org.apache.http.pool.ConnFactory;
import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
/**
* A very basic {@link ConnFactory} implementation that creates
@@ -177,7 +181,23 @@ public class BasicConnFactory implements ConnFactory<HttpHost, HttpClientConnect
socket.setSoLinger(true, linger);
}
socket.setKeepAlive(this.sconfig.isSoKeepAlive());
- socket.connect(new InetSocketAddress(hostname, port), this.connectTimeout);
+ // Run this under a doPrivileged to support lib users that run under a SecurityManager this allows granting connect permissions
+ // only to this library
+ final InetSocketAddress address = new InetSocketAddress(hostname, port);
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ @Override
+ public Object run() throws IOException {
+ socket.connect(address, BasicConnFactory.this.connectTimeout);
+ return null;
+ }
+ });
+ } catch (final PrivilegedActionException e) {
+ Asserts.check(e.getCause() instanceof IOException,
+ "method contract violation only checked exceptions are wrapped: " + e.getCause());
+ // only checked exceptions are wrapped - error and RTExceptions are rethrown by doPrivileged
+ throw (IOException) e.getCause();
+ }
return this.connFactory.createConnection(socket);
}