SocketPermissionpublic final class SocketPermission extends Permission implements SerializableRegulates the access to network operations available through sockets through
permissions. A permission consists of a target (a host), and an associated
action list. The target should identify the host by either indicating the
(possibly wildcarded (eg. {@code .company.com})) DNS style name of the host
or its IP address in standard {@code nn.nn.nn.nn} ("dot") notation. The
action list can be made up of one or more of the following actions separated
by a comma:
- connect
- requests permission to connect to the host
- listen
- requests permission to listen for connections from the host
- accept
- requests permission to accept connections from the host
- resolve
- requests permission to resolve the hostname
Note that {@code resolve} is implied when any (or none) of the others are
present.
Access to a particular port can be requested by appending a colon and a
single digit to the name (eg. {@code .company.com:7000}). A range of port
numbers can also be specified, by appending a pattern of the form
LOW-HIGH where LOW and HIGH are valid port numbers. If
either LOW or HIGH is omitted it is equivalent to entering the
lowest or highest possible value respectively. For example:
{@code SocketPermission("www.company.com:7000-", "connect,accept")}
represents the permission to connect to and accept connections from {@code
www.company.com} on ports in the range {@code 7000} to {@code 65535}.
|
Fields Summary |
---|
private static final long | serialVersionUID | static final int | SP_CONNECT | static final int | SP_LISTEN | static final int | SP_ACCEPT | static final int | SP_RESOLVE | private static final String[] | actionNames | private transient boolean | isPartialWild | private transient boolean | isWild | private static final int | HIGHEST_PORT | private static final int | LOWEST_PORT | transient String | hostName | transient String | ipString | transient boolean | resolved | transient int | portMin | transient int | portMax | private String | actions | transient int | actionsMask |
Constructors Summary |
---|
public SocketPermission(String host, String action)Constructs a new {@code SocketPermission} instance. The hostname can be a
DNS name, an individual hostname, an IP address or the empty string which
implies {@code localhost}. The port or port range is optional.
The action list is a comma-separated list which can consists of the
possible operations {@code "connect"}, {@code "listen"}, {@code "accept"}
, and {@code "resolve"}. They are case-insensitive and can be put
together in any order. {@code "resolve"} is implied per default.
super(host.equals("") ? "localhost" : host); //$NON-NLS-1$ //$NON-NLS-2$
hostName = getHostString(host);
if (action == null) {
throw new NullPointerException();
}
if (action.equals("")) { //$NON-NLS-1$
throw new IllegalArgumentException();
}
setActions(action);
actions = toCanonicalActionString(action);
// Use host since we are only checking for port presence
parsePort(host, hostName);
|
Methods Summary |
---|
boolean | checkHost(java.net.SocketPermission sp)Determines whether or not this permission could refer to the same host as
sp.
if (isPartialWild) {
if (isWild) {
return true; // Match on any host
}
int length = hostName.length() - 1;
return sp.hostName.regionMatches(sp.hostName.length() - length,
hostName, 1, length);
}
// The ipString may not be the same, some hosts resolve to
// multiple ips
return (getIPString() != null && ipString.equals(sp.getIPString()))
|| hostName.equals(sp.hostName);
| public boolean | equals(java.lang.Object o)Compares the argument {@code o} to this instance and returns {@code true}
if they represent the same permission using a class specific comparison.
if (this == o) {
return true;
}
if (o == null || this.getClass() != o.getClass()) {
return false;
}
SocketPermission sp = (SocketPermission) o;
if (!hostName.equals(sp.hostName)) {
if (getIPString() == null || !ipString.equals(sp.getIPString())) {
return false;
}
}
if (this.actionsMask != SP_RESOLVE) {
if (this.portMin != sp.portMin) {
return false;
}
if (this.portMax != sp.portMax) {
return false;
}
}
return this.actionsMask == sp.actionsMask;
| public java.lang.String | getActions()Gets a comma-separated list of all actions allowed by this permission. If
more than one action is returned they follow this order: {@code connect},
{@code listen}, {@code accept}, {@code resolve}.
return actions;
| private java.lang.String | getHostString(java.lang.String host)Get the host part from the host[:port] one.
The host should be
host = (hostname | IPv4address | IPv6reference | IPv6 in full uncompressed form)
The wildcard "*" may be included once in a DNS name host specification. If it is included,
it must be in the leftmost position
host = host.trim();
int idx = -1;
idx = host.indexOf(':");
isPartialWild = (host.length() > 0 && host.charAt(0) == '*");
if (isPartialWild) {
resolved = true;
isWild = (host.length() == 1);
if (isWild) {
return host;
}
if (idx > -1) {
host = host.substring(0, idx);
}
return host.toLowerCase();
}
int lastIdx = host.lastIndexOf(':");
if (idx == lastIdx) {
if (-1 != idx) {
// only one colon, should be port
host = host.substring(0, idx);
}
return host.toLowerCase();
}
// maybe ipv6
boolean isFirstBracket = (host.charAt(0) == '[");
if (!isFirstBracket) {
// No bracket, should be in full form
int colonNum = 0;
for (int i = 0; i < host.length(); ++i) {
if (host.charAt(i) == ':") {
colonNum++;
}
}
// Get rid of the colon before port
if (8 == colonNum) {
host = host.substring(0, lastIdx);
}
if (Inet6Util.isIP6AddressInFullForm(host)) {
return host.toLowerCase();
}
throw new IllegalArgumentException(Msg.getString("K004a") + " "
+ host);
}
// forward bracket found
int bbracketIdx = host.indexOf(']");
if (-1 == bbracketIdx) {
// no back bracket found, wrong
throw new IllegalArgumentException(Msg.getString("K004a") + " "
+ host);
}
host = host.substring(0, bbracketIdx + 1);
if (Inet6Util.isValidIP6Address(host)) {
return host.toLowerCase();
}
throw new IllegalArgumentException(Msg.getString("K004a") + " " + host);
| private java.lang.String | getIPString()
if (!resolved) {
try {
ipString = InetAddress.getHostNameInternal(hostName);
} catch (UnknownHostException e) {
// ignore
}
resolved = true;
}
return ipString;
| public int | hashCode()Returns the hash value for this {@code SocketPermission} instance. Any
two objects which returns {@code true} when passed to {@code equals()}
must return the same value as a result of this method.
return hostName.hashCode() ^ actionsMask ^ portMin ^ portMax;
| public boolean | implies(java.security.Permission p)Checks whether this {@code SocketPermission} instance allows all actions
which are allowed by the given permission object {@code p}. All argument
permission actions, hosts and ports must be implied by this permission
instance in order to return {@code true}. This permission may imply
additional actions not present in the argument permission.
SocketPermission sp;
try {
sp = (SocketPermission) p;
} catch (ClassCastException e) {
return false;
}
// tests if the action list of p is the subset of the one of the
// receiver
if (sp == null || (actionsMask & sp.actionsMask) != sp.actionsMask) {
return false;
}
// only check the port range if the action string of the current object
// is not "resolve"
if (!p.getActions().equals("resolve")) { //$NON-NLS-1$
if ((sp.portMin < this.portMin) || (sp.portMax > this.portMax)) {
return false;
}
}
// Verify the host is valid
return checkHost(sp);
| public java.security.PermissionCollection | newPermissionCollection()Creates a new {@code PermissionCollection} to store {@code
SocketPermission} objects.
return new SocketPermissionCollection();
| private void | parsePort(java.lang.String hostPort, java.lang.String host)Parse the port, including the minPort, maxPort
String port = hostPort.substring(host.length());
String emptyString = ""; //$NON-NLS-1$
if (emptyString.equals(port)) {
// Not specified
portMin = 80;
portMax = 80;
return;
}
if (":*".equals(port)) {
// The port range should be 0-65535
portMin = 0;
portMax = 65535;
return;
}
// Omit ':'
port = port.substring(1);
int negIdx = port.indexOf('-");
String strPortMin = emptyString;
String strPortMax = emptyString;
if (-1 == negIdx) {
// No neg mark, only one number
strPortMin = port;
strPortMax = port;
} else {
strPortMin = port.substring(0, negIdx);
strPortMax = port.substring(negIdx + 1);
if (emptyString.equals(strPortMin)) {
strPortMin = "0";
}
if (emptyString.equals(strPortMax)) {
strPortMax = "65535";
}
}
try {
portMin = Integer.valueOf(strPortMin).intValue();
portMax = Integer.valueOf(strPortMax).intValue();
if (portMin > portMax) {
throw new IllegalArgumentException(Msg.getString("K0049") + " " + port); //$NON-NLS-1$
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException(Msg.getString("K004a") + " " + port); //$NON-NLS-1$
}
| private void | readObject(java.io.ObjectInputStream stream)
stream.defaultReadObject();
// Initialize locals
isPartialWild = false;
isWild = false;
portMin = LOWEST_PORT;
portMax = HIGHEST_PORT;
actionsMask = SP_RESOLVE;
hostName = getHostString(getName());
parsePort(getName(), hostName);
setActions(actions);
| private void | setActions(java.lang.String actions)Stores the actions for this permission as a bit field.
if (actions.equals("")) { //$NON-NLS-1$
return;
}
boolean parsing = true;
String action;
StringBuffer sb = new StringBuffer();
int pos = 0, length = actions.length();
while (parsing) {
char c;
sb.setLength(0);
while (pos < length && (c = actions.charAt(pos++)) != ',") {
sb.append(c);
}
if (pos == length) {
parsing = false;
}
action = sb.toString().trim().toLowerCase();
if (action.equals(actionNames[SP_CONNECT])) {
actionsMask |= SP_CONNECT;
} else if (action.equals(actionNames[SP_LISTEN])) {
actionsMask |= SP_LISTEN;
} else if (action.equals(actionNames[SP_ACCEPT])) {
actionsMask |= SP_ACCEPT;
} else if (action.equals(actionNames[SP_RESOLVE])) {
// do nothing
} else {
throw new IllegalArgumentException(Msg.getString("K0048", //$NON-NLS-1$
action));
}
}
| private java.lang.String | toCanonicalActionString(java.lang.String action)Creates a canonical action list.
if (action == null || action.equals("") || actionsMask == SP_RESOLVE) { //$NON-NLS-1$
return actionNames[SP_RESOLVE]; // If none specified return the
}
// implied action resolve
StringBuffer sb = new StringBuffer();
if ((actionsMask & SP_CONNECT) == SP_CONNECT) {
sb.append(',");
sb.append(actionNames[SP_CONNECT]);
}
if ((actionsMask & SP_LISTEN) == SP_LISTEN) {
sb.append(',");
sb.append(actionNames[SP_LISTEN]);
}
if ((actionsMask & SP_ACCEPT) == SP_ACCEPT) {
sb.append(',");
sb.append(actionNames[SP_ACCEPT]);
}
sb.append(',");
sb.append(actionNames[SP_RESOLVE]);// Resolve is always implied
// Don't copy the first ','.
return actions = sb.substring(1, sb.length());
| private void | writeObject(java.io.ObjectOutputStream stream)
stream.defaultWriteObject();
|
|