jdk/src/share/classes/java/net/SocketPermission.java
changeset 22339 e91bfaf4360d
parent 21334 c60dfce46a77
child 22341 4689530d03b9
equal deleted inserted replaced
22338:fda2b44112c7 22339:e91bfaf4360d
    32 import java.util.Collections;
    32 import java.util.Collections;
    33 import java.util.StringTokenizer;
    33 import java.util.StringTokenizer;
    34 import java.net.InetAddress;
    34 import java.net.InetAddress;
    35 import java.security.Permission;
    35 import java.security.Permission;
    36 import java.security.PermissionCollection;
    36 import java.security.PermissionCollection;
       
    37 import java.security.PrivilegedAction;
       
    38 import java.security.AccessController;
       
    39 import java.security.Security;
    37 import java.io.Serializable;
    40 import java.io.Serializable;
    38 import java.io.ObjectStreamField;
    41 import java.io.ObjectStreamField;
    39 import java.io.ObjectOutputStream;
    42 import java.io.ObjectOutputStream;
    40 import java.io.ObjectInputStream;
    43 import java.io.ObjectInputStream;
    41 import java.io.IOException;
    44 import java.io.IOException;
    87  * <p>
    90  * <p>
    88  * The port or portrange is optional. A port specification of the
    91  * The port or portrange is optional. A port specification of the
    89  * form "N-", where <i>N</i> is a port number, signifies all ports
    92  * form "N-", where <i>N</i> is a port number, signifies all ports
    90  * numbered <i>N</i> and above, while a specification of the
    93  * numbered <i>N</i> and above, while a specification of the
    91  * form "-N" indicates all ports numbered <i>N</i> and below.
    94  * form "-N" indicates all ports numbered <i>N</i> and below.
       
    95  * The special port value {@code 0} refers to the entire <i>ephemeral</i>
       
    96  * port range. This is a fixed range of ports a system may use to
       
    97  * allocate dynamic ports from. The actual range may be system dependent.
    92  * <p>
    98  * <p>
    93  * The possible ways to connect to the host are
    99  * The possible ways to connect to the host are
    94  * <pre>
   100  * <pre>
    95  * accept
   101  * accept
    96  * connect
   102  * connect
    97  * listen
   103  * listen
    98  * resolve
   104  * resolve
    99  * </pre>
   105  * </pre>
   100  * The "listen" action is only meaningful when used with "localhost".
   106  * The "listen" action is only meaningful when used with "localhost" and
       
   107  * means the ability to bind to a specified port.
   101  * The "resolve" action is implied when any of the other actions are present.
   108  * The "resolve" action is implied when any of the other actions are present.
   102  * The action "resolve" refers to host/ip name service lookups.
   109  * The action "resolve" refers to host/ip name service lookups.
   103  * <P>
   110  * <P>
   104  * The actions string is converted to lowercase before processing.
   111  * The actions string is converted to lowercase before processing.
   105  * <p>As an example of the creation and meaning of SocketPermissions,
   112  * <p>As an example of the creation and meaning of SocketPermissions,
   174 
   181 
   175     // various port constants
   182     // various port constants
   176     private static final int PORT_MIN = 0;
   183     private static final int PORT_MIN = 0;
   177     private static final int PORT_MAX = 65535;
   184     private static final int PORT_MAX = 65535;
   178     private static final int PRIV_PORT_MAX = 1023;
   185     private static final int PRIV_PORT_MAX = 1023;
       
   186     private static final int DEF_EPH_LOW = 49152;
   179 
   187 
   180     // the actions mask
   188     // the actions mask
   181     private transient int mask;
   189     private transient int mask;
   182 
   190 
   183     /**
   191     /**
   223     // true if the sun.net.trustNameService system property is set
   231     // true if the sun.net.trustNameService system property is set
   224     private static boolean trustNameService;
   232     private static boolean trustNameService;
   225 
   233 
   226     private static Debug debug = null;
   234     private static Debug debug = null;
   227     private static boolean debugInit = false;
   235     private static boolean debugInit = false;
       
   236 
       
   237     // ephemeral port range for this system
       
   238     private static final int ephemeralLow = initEphemeralPorts(
       
   239         "low", DEF_EPH_LOW
       
   240     );
       
   241     private static final int ephemeralHigh = initEphemeralPorts(
       
   242         "high", PORT_MAX
       
   243     );
   228 
   244 
   229     static {
   245     static {
   230         Boolean tmp = java.security.AccessController.doPrivileged(
   246         Boolean tmp = java.security.AccessController.doPrivileged(
   231                 new sun.security.action.GetBooleanAction("sun.net.trustNameService"));
   247                 new sun.security.action.GetBooleanAction("sun.net.trustNameService"));
   232         trustNameService = tmp.booleanValue();
   248         trustNameService = tmp.booleanValue();
   358             return new int[] {l, h};
   374             return new int[] {l, h};
   359         }
   375         }
   360     }
   376     }
   361 
   377 
   362     /**
   378     /**
       
   379      * Returns true if the permission has specified zero
       
   380      * as its value (or lower bound) signifying the ephemeral range
       
   381      */
       
   382     private boolean includesEphemerals() {
       
   383         return portrange[0] == 0;
       
   384     }
       
   385 
       
   386     /**
   363      * Initialize the SocketPermission object. We don't do any DNS lookups
   387      * Initialize the SocketPermission object. We don't do any DNS lookups
   364      * as this point, instead we hold off until the implies method is
   388      * as this point, instead we hold off until the implies method is
   365      * called.
   389      * called.
   366      */
   390      */
   367     private void init(String host, int mask) {
   391     private void init(String host, int mask) {
   848      */
   872      */
   849     boolean impliesIgnoreMask(SocketPermission that) {
   873     boolean impliesIgnoreMask(SocketPermission that) {
   850         int i,j;
   874         int i,j;
   851 
   875 
   852         if ((that.mask & RESOLVE) != that.mask) {
   876         if ((that.mask & RESOLVE) != that.mask) {
   853             // check port range
   877 
       
   878             // check simple port range
   854             if ((that.portrange[0] < this.portrange[0]) ||
   879             if ((that.portrange[0] < this.portrange[0]) ||
   855                     (that.portrange[1] > this.portrange[1])) {
   880                     (that.portrange[1] > this.portrange[1])) {
       
   881 
       
   882                 // if either includes the ephemeral range, do full check
       
   883                 if (this.includesEphemerals() || that.includesEphemerals()) {
       
   884                     if (!inRange(this.portrange[0], this.portrange[1],
       
   885                                      that.portrange[0], that.portrange[1]))
       
   886                     {
       
   887                                 return false;
       
   888                     }
       
   889                 } else {
   856                     return false;
   890                     return false;
       
   891                 }
   857             }
   892             }
   858         }
   893         }
   859 
   894 
   860         // allow a "*" wildcard to always match anything
   895         // allow a "*" wildcard to always match anything
   861         if (this.wildcard && "".equals(this.cname))
   896         if (this.wildcard && "".equals(this.cname))
  1166         // Read in the action, then initialize the rest
  1201         // Read in the action, then initialize the rest
  1167         s.defaultReadObject();
  1202         s.defaultReadObject();
  1168         init(getName(),getMask(actions));
  1203         init(getName(),getMask(actions));
  1169     }
  1204     }
  1170 
  1205 
       
  1206     /**
       
  1207      * Check the system/security property for the ephemeral port range
       
  1208      * for this system. The suffix is either "high" or "low"
       
  1209      */
       
  1210     private static int initEphemeralPorts(String suffix, int defval) {
       
  1211         return AccessController.doPrivileged(
       
  1212             new PrivilegedAction<Integer>(){
       
  1213                 public Integer run() {
       
  1214                     int val = Integer.getInteger(
       
  1215                             "jdk.net.ephemeralPortRange."+suffix, -1
       
  1216                     );
       
  1217                     if (val != -1) {
       
  1218                         return val;
       
  1219                     } else {
       
  1220                         String prop = Security.getProperty(
       
  1221                             "network.ephemeralPortRange."+suffix
       
  1222                         );
       
  1223                         try {
       
  1224                                 val = Integer.parseInt(prop);
       
  1225                         } catch (NumberFormatException e) {
       
  1226                             // shouldn't happen
       
  1227                             return defval;
       
  1228                         }
       
  1229                     }
       
  1230                     return val;
       
  1231                 }
       
  1232             }
       
  1233         );
       
  1234     }
       
  1235 
       
  1236     /**
       
  1237      * Check if the target range is within the policy range
       
  1238      * together with the ephemeral range for this platform
       
  1239      * (if policy includes ephemeral range)
       
  1240      */
       
  1241     private static boolean inRange(
       
  1242         int policyLow, int policyHigh, int targetLow, int targetHigh
       
  1243     )
       
  1244     {
       
  1245         if (targetLow == 0) {
       
  1246             // check policy includes ephemeral range
       
  1247             if (!inRange(policyLow, policyHigh, ephemeralLow, ephemeralHigh)) {
       
  1248                 return false;
       
  1249             }
       
  1250             if (targetHigh == 0) {
       
  1251                 // nothing left to do
       
  1252                 return true;
       
  1253             }
       
  1254             // continue check with first real port number
       
  1255             targetLow = 1;
       
  1256         }
       
  1257 
       
  1258         if (policyLow == 0 && policyHigh == 0) {
       
  1259             // ephemeral range only
       
  1260             return targetLow >= ephemeralLow && targetHigh <= ephemeralHigh;
       
  1261         }
       
  1262 
       
  1263         if (policyLow != 0) {
       
  1264             // simple check of policy only
       
  1265             return targetLow >= policyLow && targetHigh <= policyHigh;
       
  1266         }
       
  1267 
       
  1268         // policyLow == 0 which means possibly two ranges to check
       
  1269 
       
  1270         // first check if policy and ephem range overlap/contiguous
       
  1271 
       
  1272         if (policyHigh >= ephemeralLow - 1) {
       
  1273             return targetHigh <= ephemeralHigh;
       
  1274         }
       
  1275 
       
  1276         // policy and ephem range do not overlap
       
  1277 
       
  1278         // target range must lie entirely inside policy range or eph range
       
  1279 
       
  1280         return  (targetLow <= policyHigh && targetHigh <= policyHigh) ||
       
  1281                 (targetLow >= ephemeralLow && targetHigh <= ephemeralHigh);
       
  1282     }
  1171     /*
  1283     /*
  1172     public String toString()
  1284     public String toString()
  1173     {
  1285     {
  1174         StringBuffer s = new StringBuffer(super.toString() + "\n" +
  1286         StringBuffer s = new StringBuffer(super.toString() + "\n" +
  1175             "cname = " + cname + "\n" +
  1287             "cname = " + cname + "\n" +