summaryrefslogtreecommitdiff
path: root/java/net
diff options
context:
space:
mode:
authorGary Benson <gbenson@redhat.com>2006-09-14 13:43:39 +0000
committerGary Benson <gbenson@redhat.com>2006-09-14 13:43:39 +0000
commit76074e7e82247a39031b9031396fdad9abd3ed98 (patch)
tree21b37702d808cfeef1bfe748bbd82f9e692b905c /java/net
parentc09ef45dc0dbebcbbcd4ff6c4caf5db1f2dab4f5 (diff)
downloadclasspath-76074e7e82247a39031b9031396fdad9abd3ed98.tar.gz
2006-09-14 Gary Benson <gbenson@redhat.com>
* java/net/InetAddress.java (internalGetCanonicalHostName): New method. (getCanonicalHostName): Use internalGetCanonicalHostName. (getByLiteral): New method. (getAllByName): Use getByLiteral. * java/net/SocketPermission.java (host): Replaced with... (hostname, address): New fields. (equals, hashcode): Reflect the above. (setHostPort): Parse host into hostname or address. (implies): Rewrite host checks.
Diffstat (limited to 'java/net')
-rw-r--r--java/net/InetAddress.java49
-rw-r--r--java/net/SocketPermission.java161
2 files changed, 173 insertions, 37 deletions
diff --git a/java/net/InetAddress.java b/java/net/InetAddress.java
index b5d66c285..a67358832 100644
--- a/java/net/InetAddress.java
+++ b/java/net/InetAddress.java
@@ -311,20 +311,27 @@ public class InetAddress implements Serializable
/**
* Returns the canonical hostname represented by this InetAddress
- *
- * @since 1.4
*/
- public String getCanonicalHostName()
+ String internalGetCanonicalHostName()
{
- String hostname;
try
{
- hostname = VMInetAddress.getHostByAddr(addr);
+ return VMInetAddress.getHostByAddr(addr);
}
catch (UnknownHostException e)
{
return getHostAddress();
}
+ }
+
+ /**
+ * Returns the canonical hostname represented by this InetAddress
+ *
+ * @since 1.4
+ */
+ public String getCanonicalHostName()
+ {
+ String hostname = internalGetCanonicalHostName();
SecurityManager sm = System.getSecurityManager();
if (sm != null)
@@ -492,6 +499,34 @@ public class InetAddress implements Serializable
}
/**
+ * Returns an InetAddress object representing the IP address of
+ * the given literal IP address in dotted decimal format such as
+ * "127.0.0.1". This is used by SocketPermission.setHostPort()
+ * to parse literal IP addresses without performing a DNS lookup.
+ *
+ * @param literal The literal IP address to create the InetAddress
+ * object from
+ *
+ * @return The address of the host as an InetAddress object, or
+ * null if the IP address is invalid.
+ */
+ static InetAddress getByLiteral(String literal)
+ {
+ byte[] address = VMInetAddress.aton(literal);
+ if (address == null)
+ return null;
+
+ try
+ {
+ return getByAddress(address);
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
* Returns an InetAddress object representing the IP address of the given
* hostname. This name can be either a hostname such as "www.urbanophile.com"
* or an IP address in dotted decimal format such as "127.0.0.1". If the
@@ -542,9 +577,9 @@ public class InetAddress implements Serializable
return new InetAddress[] {LOCALHOST};
// Check if hostname is an IP address
- byte[] address = VMInetAddress.aton(hostname);
+ InetAddress address = getByLiteral(hostname);
if (address != null)
- return new InetAddress[] {getByAddress(address)};
+ return new InetAddress[] {address};
// Perform security check before resolving
SecurityManager sm = System.getSecurityManager();
diff --git a/java/net/SocketPermission.java b/java/net/SocketPermission.java
index 97e93dcbb..2d6343dc5 100644
--- a/java/net/SocketPermission.java
+++ b/java/net/SocketPermission.java
@@ -117,11 +117,18 @@ public final class SocketPermission extends Permission implements Serializable
static final long serialVersionUID = -7204263841984476862L;
/**
- * A hostname (possibly wildcarded) or IP address (IPv4 or IPv6).
+ * A hostname (possibly wildcarded). Will be set if and only if
+ * this object was initialized with a hostname.
*/
- private transient String host;
+ private transient String hostname = null;
/**
+ * An IP address (IPv4 or IPv6). Will be set if and only if this
+ * object was initialized with a single literal IP address.
+ */
+ private transient InetAddress address = null;
+
+ /**
* A range of ports.
*/
private transient int minport;
@@ -225,7 +232,7 @@ public final class SocketPermission extends Permission implements Serializable
private void setHostPort(String hostport)
{
// Split into host and ports
- String ports;
+ String host, ports;
if (hostport.charAt(0) == '[')
{
// host is a bracketed IPv6 address
@@ -234,6 +241,10 @@ public final class SocketPermission extends Permission implements Serializable
throw new IllegalArgumentException("Unmatched '['");
host = hostport.substring(1, end);
+ address = InetAddress.getByLiteral(host);
+ if (address == null)
+ throw new IllegalArgumentException("Bad IPv6 address");
+
if (end == hostport.length() - 1)
ports = "";
else if (hostport.charAt(end + 1) == ':')
@@ -255,6 +266,15 @@ public final class SocketPermission extends Permission implements Serializable
host = hostport.substring(0, sep);
ports = hostport.substring(sep + 1);
}
+
+ address = InetAddress.getByLiteral(host);
+ if (address == null)
+ {
+ if (host.lastIndexOf('*') > 0)
+ throw new IllegalArgumentException("Bad hostname");
+
+ hostname = host;
+ }
}
// Parse and validate the ports
@@ -362,10 +382,25 @@ public final class SocketPermission extends Permission implements Serializable
else
return false;
- return p.actionmask == actionmask &&
- p.minport == minport &&
- p.maxport == maxport &&
- p.host.equals(host);
+ if (p.actionmask != actionmask ||
+ p.minport != minport ||
+ p.maxport != maxport)
+ return false;
+
+ if (address != null)
+ {
+ if (p.address == null)
+ return false;
+ else
+ return p.address.equals(address);
+ }
+ else
+ {
+ if (p.hostname == null)
+ return false;
+ else
+ return p.hostname.equals(hostname);
+ }
}
/**
@@ -376,7 +411,12 @@ public final class SocketPermission extends Permission implements Serializable
*/
public int hashCode()
{
- return actionmask + minport + maxport + host.hashCode();
+ int code = actionmask + minport + maxport;
+ if (address != null)
+ code += address.hashCode();
+ else
+ code += hostname.hashCode();
+ return code;
}
/**
@@ -416,6 +456,44 @@ public final class SocketPermission extends Permission implements Serializable
}
/**
+ * Returns an array of all IP addresses represented by this object.
+ */
+ private InetAddress[] getAddresses()
+ {
+ if (address != null)
+ return new InetAddress[] {address};
+
+ try
+ {
+ return InetAddress.getAllByName(hostname);
+ }
+ catch (UnknownHostException e)
+ {
+ return new InetAddress[0];
+ }
+ }
+
+ /**
+ * Returns the canonical hostname represented by this object,
+ * or null if this object represents a wildcarded domain.
+ */
+ private String getCanonicalHostName()
+ {
+ if (address != null)
+ return address.internalGetCanonicalHostName();
+ if (hostname.charAt(0) == '*')
+ return null;
+ try
+ {
+ return InetAddress.getByName(hostname).internalGetCanonicalHostName();
+ }
+ catch (UnknownHostException e)
+ {
+ return null;
+ }
+ }
+
+ /**
* Returns true if the permission object passed it is implied by the
* this permission. This will be true if:
*
@@ -450,6 +528,11 @@ public final class SocketPermission extends Permission implements Serializable
else
return false;
+ // If p was initialised with an empty hostname then we do not
+ // imply it. This is not part of the spec, but it seems necessary.
+ if (p.hostname != null && p.hostname.length() == 0)
+ return false;
+
// Next check the actions
if ((p.actionmask & actionmask) != p.actionmask)
return false;
@@ -459,36 +542,54 @@ public final class SocketPermission extends Permission implements Serializable
return false;
// Finally check the hosts
- if (host.equals(p.host))
- return true;
+ String p_canon = null;
- // Try the canonical names
- String ourcanonical = null;
- String theircanonical = null;
- try
+ // Return true if this object was initialized with a single
+ // IP address which one of p's IP addresses is equal to.
+ if (address != null)
{
- ourcanonical = InetAddress.getByName(host).getHostName();
- theircanonical = InetAddress.getByName(p.host).getHostName();
+ InetAddress[] addrs = p.getAddresses();
+ for (int i = 0; i < addrs.length; i++)
+ {
+ if (address.equals(addrs[i]))
+ return true;
+ }
}
- catch (UnknownHostException e)
+
+ // Return true if this object is a wildcarded domain that
+ // p's canonical name matches.
+ if (hostname != null && hostname.charAt(0) == '*')
{
- // Who didn't resolve? Just assume current address is canonical enough
- // Is this ok to do?
- if (ourcanonical == null)
- ourcanonical = host;
- if (theircanonical == null)
- theircanonical = p.host;
+ p_canon = p.getCanonicalHostName();
+ if (p_canon != null && p_canon.endsWith(hostname.substring(1)))
+ return true;
+
}
- if (ourcanonical.equals(theircanonical))
- return true;
+ // Return true if this one of this object's IP addresses
+ // is equal to one of p's.
+ if (address == null)
+ {
+ InetAddress[] addrs = p.getAddresses();
+ InetAddress[] p_addrs = p.getAddresses();
+
+ for (int i = 0; i < addrs.length; i++)
+ {
+ for (int j = 0; j < p_addrs.length; j++)
+ {
+ if (addrs[i].equals(p_addrs[j]))
+ return true;
+ }
+ }
+ }
- // Well, last chance. Try for a wildcard
- if (host.indexOf("*.") != -1)
+ // Return true if this object's canonical name equals p's.
+ String canon = getCanonicalHostName();
+ if (canon != null)
{
- String wild_domain =
- host.substring(host.indexOf("*" + 1));
- if (theircanonical.endsWith(wild_domain))
+ if (p_canon == null)
+ p_canon = p.getCanonicalHostName();
+ if (p_canon != null && canon.equals(p_canon))
return true;
}