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" + |