forked from netty/netty
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Wrap operations requiring SocketPermission with doPrivileged blocks
Motivation: Currently Netty does not wrap socket connect, bind, or accept operations in doPrivileged blocks. Nor does it wrap cases where a dns lookup might happen. This prevents an application utilizing the SecurityManager from isolating SocketPermissions to Netty. Modifications: I have introduced a class (SocketUtils) that wraps operations requiring SocketPermissions in doPrivileged blocks. Result: A user of Netty can grant SocketPermissions explicitly to the Netty jar, without granting it to the rest of their application.
- Loading branch information
1 parent
2d11331
commit 3344cd2
Showing
42 changed files
with
527 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
197 changes: 197 additions & 0 deletions
197
common/src/main/java/io/netty/util/internal/SocketUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
/* | ||
* Copyright 2016 The Netty Project | ||
* | ||
* The Netty Project licenses this file to you under the Apache License, | ||
* version 2.0 (the "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.netty.util.internal; | ||
|
||
import java.io.IOException; | ||
import java.net.InetAddress; | ||
import java.net.InetSocketAddress; | ||
import java.net.NetworkInterface; | ||
import java.net.ServerSocket; | ||
import java.net.Socket; | ||
import java.net.SocketAddress; | ||
import java.net.SocketException; | ||
import java.net.SocketPermission; | ||
import java.net.UnknownHostException; | ||
import java.nio.channels.DatagramChannel; | ||
import java.nio.channels.ServerSocketChannel; | ||
import java.nio.channels.SocketChannel; | ||
import java.security.AccessController; | ||
import java.security.PrivilegedAction; | ||
import java.security.PrivilegedActionException; | ||
import java.security.PrivilegedExceptionAction; | ||
import java.util.Enumeration; | ||
|
||
/** | ||
* Provides socket operations with privileges enabled. This is necessary for applications that use the | ||
* {@link SecurityManager} to restrict {@link SocketPermission} to their application. By asserting that these | ||
* operations are privileged, the operations can proceed even if some code in the calling chain lacks the appropriate | ||
* {@link SocketPermission}. | ||
*/ | ||
public final class SocketUtils { | ||
|
||
private SocketUtils() { | ||
} | ||
|
||
public static void connect(final Socket socket, final SocketAddress remoteAddress, final int timeout) | ||
throws IOException { | ||
try { | ||
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { | ||
@Override | ||
public Void run() throws IOException { | ||
socket.connect(remoteAddress, timeout); | ||
return null; | ||
} | ||
}); | ||
} catch (PrivilegedActionException e) { | ||
throw (IOException) e.getCause(); | ||
} | ||
} | ||
|
||
public static void bind(final Socket socket, final SocketAddress bindpoint) throws IOException { | ||
try { | ||
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { | ||
@Override | ||
public Void run() throws IOException { | ||
socket.bind(bindpoint); | ||
return null; | ||
} | ||
}); | ||
} catch (PrivilegedActionException e) { | ||
throw (IOException) e.getCause(); | ||
} | ||
} | ||
|
||
public static boolean connect(final SocketChannel socketChannel, final SocketAddress remoteAddress) | ||
throws IOException { | ||
try { | ||
return AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>() { | ||
@Override | ||
public Boolean run() throws IOException { | ||
return socketChannel.connect(remoteAddress); | ||
} | ||
}); | ||
} catch (PrivilegedActionException e) { | ||
throw (IOException) e.getCause(); | ||
} | ||
} | ||
|
||
public static void bind(final SocketChannel socketChannel, final SocketAddress address) throws IOException { | ||
try { | ||
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { | ||
@Override | ||
public Void run() throws IOException { | ||
socketChannel.bind(address); | ||
return null; | ||
} | ||
}); | ||
} catch (PrivilegedActionException e) { | ||
throw (IOException) e.getCause(); | ||
} | ||
} | ||
|
||
public static SocketChannel accept(final ServerSocketChannel serverSocketChannel) throws IOException { | ||
try { | ||
return AccessController.doPrivileged(new PrivilegedExceptionAction<SocketChannel>() { | ||
@Override | ||
public SocketChannel run() throws IOException { | ||
return serverSocketChannel.accept(); | ||
} | ||
}); | ||
} catch (PrivilegedActionException e) { | ||
throw (IOException) e.getCause(); | ||
} | ||
} | ||
|
||
public static void bind(final DatagramChannel networkChannel, final SocketAddress address) throws IOException { | ||
try { | ||
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { | ||
@Override | ||
public Void run() throws IOException { | ||
networkChannel.bind(address); | ||
return null; | ||
} | ||
}); | ||
} catch (PrivilegedActionException e) { | ||
throw (IOException) e.getCause(); | ||
} | ||
} | ||
|
||
public static SocketAddress localSocketAddress(final ServerSocket socket) { | ||
return AccessController.doPrivileged(new PrivilegedAction<SocketAddress>() { | ||
@Override | ||
public SocketAddress run() { | ||
return socket.getLocalSocketAddress(); | ||
} | ||
}); | ||
} | ||
|
||
public static InetAddress addressByName(final String hostname) throws UnknownHostException { | ||
try { | ||
return AccessController.doPrivileged(new PrivilegedExceptionAction<InetAddress>() { | ||
@Override | ||
public InetAddress run() throws UnknownHostException { | ||
return InetAddress.getByName(hostname); | ||
} | ||
}); | ||
} catch (PrivilegedActionException e) { | ||
throw (UnknownHostException) e.getCause(); | ||
} | ||
} | ||
|
||
public static InetAddress[] allAddressesByName(final String hostname) throws UnknownHostException { | ||
try { | ||
return AccessController.doPrivileged(new PrivilegedExceptionAction<InetAddress[]>() { | ||
@Override | ||
public InetAddress[] run() throws UnknownHostException { | ||
return InetAddress.getAllByName(hostname); | ||
} | ||
}); | ||
} catch (PrivilegedActionException e) { | ||
throw (UnknownHostException) e.getCause(); | ||
} | ||
} | ||
|
||
public static InetSocketAddress socketAddress(final String hostname, final int port) { | ||
return AccessController.doPrivileged(new PrivilegedAction<InetSocketAddress>() { | ||
@Override | ||
public InetSocketAddress run() { | ||
return new InetSocketAddress(hostname, port); | ||
} | ||
}); | ||
} | ||
|
||
public static Enumeration<InetAddress> addressesFromNetworkInterface(final NetworkInterface intf) { | ||
return AccessController.doPrivileged(new PrivilegedAction<Enumeration<InetAddress>>() { | ||
@Override | ||
public Enumeration<InetAddress> run() { | ||
return intf.getInetAddresses(); | ||
} | ||
}); | ||
} | ||
|
||
public static byte[] hardwareAddressFromNetworkInterface(final NetworkInterface intf) throws SocketException { | ||
try { | ||
return AccessController.doPrivileged(new PrivilegedExceptionAction<byte[]>() { | ||
@Override | ||
public byte[] run() throws SocketException { | ||
return intf.getHardwareAddress(); | ||
} | ||
}); | ||
} catch (PrivilegedActionException e) { | ||
throw (SocketException) e.getCause(); | ||
} | ||
} | ||
} |
Oops, something went wrong.