121 * is granted to some code, it allows that code to
122 * accept connections on, connect to, or listen on any port between
123 * 1024 and 65535 on the local host.
124 *
125 * <p>Note: Granting code permission to accept or make connections to remote
126 * hosts may be dangerous because malevolent code can then more easily
127 * transfer and share confidential data among parties who may not
128 * otherwise have access to the data.
129 *
130 * @see java.security.Permissions
131 * @see SocketPermission
132 *
133 *
134 * @author Marianne Mueller
135 * @author Roland Schemers
136 *
137 * @serial exclude
138 */
139
140 public final class SocketPermission extends Permission
141 implements java.io.Serializable
142 {
143 private static final long serialVersionUID = -7204263841984476862L;
144
145 /**
146 * Connect to host:port
147 */
148 private final static int CONNECT = 0x1;
149
150 /**
151 * Listen on host:port
152 */
153 private final static int LISTEN = 0x2;
154
155 /**
156 * Accept a connection from host:port
157 */
158 private final static int ACCEPT = 0x4;
159
160 /**
161 * Resolve DNS queries
215
216 private transient boolean defaultDeny = false;
217
218 // true if this SocketPermission represents a hostname
219 // that failed our reverse mapping heuristic test
220 private transient boolean untrusted;
221 private transient boolean trusted;
222
223 // true if the sun.net.trustNameService system property is set
224 private static boolean trustNameService;
225
226 private static Debug debug = null;
227 private static boolean debugInit = false;
228
229 static {
230 Boolean tmp = java.security.AccessController.doPrivileged(
231 new sun.security.action.GetBooleanAction("sun.net.trustNameService"));
232 trustNameService = tmp.booleanValue();
233 }
234
235 private static synchronized Debug getDebug()
236 {
237 if (!debugInit) {
238 debug = Debug.getInstance("access");
239 debugInit = true;
240 }
241 return debug;
242 }
243
244 /**
245 * Creates a new SocketPermission object with the specified actions.
246 * The host is expressed as a DNS name, or as a numerical IP address.
247 * Optionally, a port or a portrange may be supplied (separated
248 * from the DNS name or IP address by a colon).
249 * <p>
250 * To specify the local machine, use "localhost" as the <i>host</i>.
251 * Also note: An empty <i>host</i> String ("") is equivalent to "localhost".
252 * <p>
253 * The <i>actions</i> parameter contains a comma-separated list of the
254 * actions granted for the specified host (and port(s)). Possible actions are
255 * "connect", "listen", "accept", "resolve", or
256 * any combination of those. "resolve" is automatically added
271 * including a colon followed by a port or port range.
272 * @param action the action string.
273 */
274 public SocketPermission(String host, String action) {
275 super(getHost(host));
276 // name initialized to getHost(host); NPE detected in getHost()
277 init(getName(), getMask(action));
278 }
279
280
281 SocketPermission(String host, int mask) {
282 super(getHost(host));
283 // name initialized to getHost(host); NPE detected in getHost()
284 init(getName(), mask);
285 }
286
287 private void setDeny() {
288 defaultDeny = true;
289 }
290
291 private static String getHost(String host)
292 {
293 if (host.equals("")) {
294 return "localhost";
295 } else {
296 /* IPv6 literal address used in this context should follow
297 * the format specified in RFC 2732;
298 * if not, we try to solve the unambiguous case
299 */
300 int ind;
301 if (host.charAt(0) != '[') {
302 if ((ind = host.indexOf(':')) != host.lastIndexOf(':')) {
303 /* More than one ":", meaning IPv6 address is not
304 * in RFC 2732 format;
305 * We will rectify user errors for all unambiguious cases
306 */
307 StringTokenizer st = new StringTokenizer(host, ":");
308 int tokens = st.countTokens();
309 if (tokens == 9) {
310 // IPv6 address followed by port
311 ind = host.lastIndexOf(':');
312 host = "[" + host.substring(0, ind) + "]" +
793 * Then <code>implies</code> checks each of the following, in order,
794 * and for each returns true if the stated condition is true:<p>
795 * <ul>
796 * <li> If this object was initialized with a single IP address and one of <i>p</i>'s
797 * IP addresses is equal to this object's IP address.<p>
798 * <li>If this object is a wildcard domain (such as *.sun.com), and
799 * <i>p</i>'s canonical name (the name without any preceding *)
800 * ends with this object's canonical host name. For example, *.sun.com
801 * implies *.eng.sun.com..<p>
802 * <li>If this object was not initialized with a single IP address, and one of this
803 * object's IP addresses equals one of <i>p</i>'s IP addresses.<p>
804 * <li>If this canonical name equals <i>p</i>'s canonical name.<p>
805 * </ul>
806 *
807 * If none of the above are true, <code>implies</code> returns false.
808 * @param p the permission to check against.
809 *
810 * @return true if the specified permission is implied by this object,
811 * false if not.
812 */
813
814 public boolean implies(Permission p) {
815 int i,j;
816
817 if (!(p instanceof SocketPermission))
818 return false;
819
820 if (p == this)
821 return true;
822
823 SocketPermission that = (SocketPermission) p;
824
825 return ((this.mask & that.mask) == that.mask) &&
826 impliesIgnoreMask(that);
827 }
828
829 /**
830 * Checks if the incoming Permission's action are a proper subset of
831 * the this object's actions.
832 * <P>
833 * Check, in the following order:
834 * <ul>
835 * <li> Checks that "p" is an instanceof a SocketPermission
836 * <li> Checks that "p"'s actions are a proper subset of the
837 * current object's actions.
838 * <li> Checks that "p"'s port range is included in this port range
839 * <li> If this object was initialized with an IP address, checks that
840 * one of "p"'s IP addresses is equal to this object's IP address.
841 * <li> If either object is a wildcard domain (i.e., "*.sun.com"),
842 * attempt to match based on the wildcard.
843 * <li> If this object was not initialized with an IP address, attempt
844 * to find a match based on the IP addresses in both objects.
845 * <li> Attempt to match on the canonical hostnames of both objects.
846 * </ul>
847 * @param p the incoming permission request
848 *
849 * @return true if "permission" is a proper subset of the current object,
850 * false if not.
851 */
852
853 boolean impliesIgnoreMask(SocketPermission that) {
854 int i,j;
855
856 if ((that.mask & RESOLVE) != that.mask) {
857 // check port range
858 if ((that.portrange[0] < this.portrange[0]) ||
859 (that.portrange[1] > this.portrange[1])) {
860 return false;
861 }
862 }
863
864 // allow a "*" wildcard to always match anything
865 if (this.wildcard && "".equals(this.cname))
866 return true;
867
868 // return if either one of these NetPerm objects are invalid...
869 if (this.invalid || that.invalid) {
870 return compareHostnames(that);
871 }
872
1212 }
1213
1214 /**
1215
1216 if (init'd with IP, key is IP as string)
1217 if wildcard, its the wild card
1218 else its the cname?
1219
1220 *
1221 * @see java.security.Permission
1222 * @see java.security.Permissions
1223 * @see java.security.PermissionCollection
1224 *
1225 *
1226 * @author Roland Schemers
1227 *
1228 * @serial include
1229 */
1230
1231 final class SocketPermissionCollection extends PermissionCollection
1232 implements Serializable
1233 {
1234 // Not serialized; see serialization section at end of class
1235 private transient List<SocketPermission> perms;
1236
1237 /**
1238 * Create an empty SocketPermissions object.
1239 *
1240 */
1241
1242 public SocketPermissionCollection() {
1243 perms = new ArrayList<SocketPermission>();
1244 }
1245
1246 /**
1247 * Adds a permission to the SocketPermissions. The key for the hash is
1248 * the name in the case of wildcards, or all the IP addresses.
1249 *
1250 * @param permission the Permission object to add.
1251 *
1252 * @exception IllegalArgumentException - if the permission is not a
1253 * SocketPermission
1254 *
1255 * @exception SecurityException - if this SocketPermissionCollection object
1256 * has been marked readonly
1257 */
1258
1259 public void add(Permission permission)
1260 {
1261 if (! (permission instanceof SocketPermission))
1262 throw new IllegalArgumentException("invalid permission: "+
1263 permission);
1264 if (isReadOnly())
1265 throw new SecurityException(
1266 "attempt to add a Permission to a readonly PermissionCollection");
1267
1268 // optimization to ensure perms most likely to be tested
1269 // show up early (4301064)
1270 synchronized (this) {
1271 perms.add(0, (SocketPermission)permission);
1272 }
1273 }
1274
1275 /**
1276 * Check and see if this collection of permissions implies the permissions
1277 * expressed in "permission".
1278 *
1279 * @param p the Permission object to compare
1280 *
1281 * @return true if "permission" is a proper subset of a permission in
1282 * the collection, false if not.
1283 */
1284
1285 public boolean implies(Permission permission)
1286 {
1287 if (! (permission instanceof SocketPermission))
1288 return false;
1289
1290 SocketPermission np = (SocketPermission) permission;
1291
1292 int desired = np.getMask();
1293 int effective = 0;
1294 int needed = desired;
1295
1296 synchronized (this) {
1297 int len = perms.size();
1298 //System.out.println("implies "+np);
1299 for (int i = 0; i < len; i++) {
1352 * serialization compatibility with earlier releases.
1353 */
1354 private void writeObject(ObjectOutputStream out) throws IOException {
1355 // Don't call out.defaultWriteObject()
1356
1357 // Write out Vector
1358 Vector<SocketPermission> permissions = new Vector<>(perms.size());
1359
1360 synchronized (this) {
1361 permissions.addAll(perms);
1362 }
1363
1364 ObjectOutputStream.PutField pfields = out.putFields();
1365 pfields.put("permissions", permissions);
1366 out.writeFields();
1367 }
1368
1369 /*
1370 * Reads in a Vector of SocketPermissions and saves them in the perms field.
1371 */
1372 private void readObject(ObjectInputStream in) throws IOException,
1373 ClassNotFoundException {
1374 // Don't call in.defaultReadObject()
1375
1376 // Read in serialized fields
1377 ObjectInputStream.GetField gfields = in.readFields();
1378
1379 // Get the one we want
1380 @SuppressWarnings("unchecked")
1381 Vector<SocketPermission> permissions = (Vector<SocketPermission>)gfields.get("permissions", null);
1382 perms = new ArrayList<SocketPermission>(permissions.size());
1383 perms.addAll(permissions);
1384 }
1385 }
|
121 * is granted to some code, it allows that code to
122 * accept connections on, connect to, or listen on any port between
123 * 1024 and 65535 on the local host.
124 *
125 * <p>Note: Granting code permission to accept or make connections to remote
126 * hosts may be dangerous because malevolent code can then more easily
127 * transfer and share confidential data among parties who may not
128 * otherwise have access to the data.
129 *
130 * @see java.security.Permissions
131 * @see SocketPermission
132 *
133 *
134 * @author Marianne Mueller
135 * @author Roland Schemers
136 *
137 * @serial exclude
138 */
139
140 public final class SocketPermission extends Permission
141 implements java.io.Serializable
142 {
143 private static final long serialVersionUID = -7204263841984476862L;
144
145 /**
146 * Connect to host:port
147 */
148 private final static int CONNECT = 0x1;
149
150 /**
151 * Listen on host:port
152 */
153 private final static int LISTEN = 0x2;
154
155 /**
156 * Accept a connection from host:port
157 */
158 private final static int ACCEPT = 0x4;
159
160 /**
161 * Resolve DNS queries
215
216 private transient boolean defaultDeny = false;
217
218 // true if this SocketPermission represents a hostname
219 // that failed our reverse mapping heuristic test
220 private transient boolean untrusted;
221 private transient boolean trusted;
222
223 // true if the sun.net.trustNameService system property is set
224 private static boolean trustNameService;
225
226 private static Debug debug = null;
227 private static boolean debugInit = false;
228
229 static {
230 Boolean tmp = java.security.AccessController.doPrivileged(
231 new sun.security.action.GetBooleanAction("sun.net.trustNameService"));
232 trustNameService = tmp.booleanValue();
233 }
234
235 private static synchronized Debug getDebug() {
236 if (!debugInit) {
237 debug = Debug.getInstance("access");
238 debugInit = true;
239 }
240 return debug;
241 }
242
243 /**
244 * Creates a new SocketPermission object with the specified actions.
245 * The host is expressed as a DNS name, or as a numerical IP address.
246 * Optionally, a port or a portrange may be supplied (separated
247 * from the DNS name or IP address by a colon).
248 * <p>
249 * To specify the local machine, use "localhost" as the <i>host</i>.
250 * Also note: An empty <i>host</i> String ("") is equivalent to "localhost".
251 * <p>
252 * The <i>actions</i> parameter contains a comma-separated list of the
253 * actions granted for the specified host (and port(s)). Possible actions are
254 * "connect", "listen", "accept", "resolve", or
255 * any combination of those. "resolve" is automatically added
270 * including a colon followed by a port or port range.
271 * @param action the action string.
272 */
273 public SocketPermission(String host, String action) {
274 super(getHost(host));
275 // name initialized to getHost(host); NPE detected in getHost()
276 init(getName(), getMask(action));
277 }
278
279
280 SocketPermission(String host, int mask) {
281 super(getHost(host));
282 // name initialized to getHost(host); NPE detected in getHost()
283 init(getName(), mask);
284 }
285
286 private void setDeny() {
287 defaultDeny = true;
288 }
289
290 private static String getHost(String host) {
291 if (host.equals("")) {
292 return "localhost";
293 } else {
294 /* IPv6 literal address used in this context should follow
295 * the format specified in RFC 2732;
296 * if not, we try to solve the unambiguous case
297 */
298 int ind;
299 if (host.charAt(0) != '[') {
300 if ((ind = host.indexOf(':')) != host.lastIndexOf(':')) {
301 /* More than one ":", meaning IPv6 address is not
302 * in RFC 2732 format;
303 * We will rectify user errors for all unambiguious cases
304 */
305 StringTokenizer st = new StringTokenizer(host, ":");
306 int tokens = st.countTokens();
307 if (tokens == 9) {
308 // IPv6 address followed by port
309 ind = host.lastIndexOf(':');
310 host = "[" + host.substring(0, ind) + "]" +
791 * Then <code>implies</code> checks each of the following, in order,
792 * and for each returns true if the stated condition is true:<p>
793 * <ul>
794 * <li> If this object was initialized with a single IP address and one of <i>p</i>'s
795 * IP addresses is equal to this object's IP address.<p>
796 * <li>If this object is a wildcard domain (such as *.sun.com), and
797 * <i>p</i>'s canonical name (the name without any preceding *)
798 * ends with this object's canonical host name. For example, *.sun.com
799 * implies *.eng.sun.com..<p>
800 * <li>If this object was not initialized with a single IP address, and one of this
801 * object's IP addresses equals one of <i>p</i>'s IP addresses.<p>
802 * <li>If this canonical name equals <i>p</i>'s canonical name.<p>
803 * </ul>
804 *
805 * If none of the above are true, <code>implies</code> returns false.
806 * @param p the permission to check against.
807 *
808 * @return true if the specified permission is implied by this object,
809 * false if not.
810 */
811 public boolean implies(Permission p) {
812 int i,j;
813
814 if (!(p instanceof SocketPermission))
815 return false;
816
817 if (p == this)
818 return true;
819
820 SocketPermission that = (SocketPermission) p;
821
822 return ((this.mask & that.mask) == that.mask) &&
823 impliesIgnoreMask(that);
824 }
825
826 /**
827 * Checks if the incoming Permission's action are a proper subset of
828 * the this object's actions.
829 * <P>
830 * Check, in the following order:
831 * <ul>
832 * <li> Checks that "p" is an instanceof a SocketPermission
833 * <li> Checks that "p"'s actions are a proper subset of the
834 * current object's actions.
835 * <li> Checks that "p"'s port range is included in this port range
836 * <li> If this object was initialized with an IP address, checks that
837 * one of "p"'s IP addresses is equal to this object's IP address.
838 * <li> If either object is a wildcard domain (i.e., "*.sun.com"),
839 * attempt to match based on the wildcard.
840 * <li> If this object was not initialized with an IP address, attempt
841 * to find a match based on the IP addresses in both objects.
842 * <li> Attempt to match on the canonical hostnames of both objects.
843 * </ul>
844 * @param that the incoming permission request
845 *
846 * @return true if "permission" is a proper subset of the current object,
847 * false if not.
848 */
849 boolean impliesIgnoreMask(SocketPermission that) {
850 int i,j;
851
852 if ((that.mask & RESOLVE) != that.mask) {
853 // check port range
854 if ((that.portrange[0] < this.portrange[0]) ||
855 (that.portrange[1] > this.portrange[1])) {
856 return false;
857 }
858 }
859
860 // allow a "*" wildcard to always match anything
861 if (this.wildcard && "".equals(this.cname))
862 return true;
863
864 // return if either one of these NetPerm objects are invalid...
865 if (this.invalid || that.invalid) {
866 return compareHostnames(that);
867 }
868
1208 }
1209
1210 /**
1211
1212 if (init'd with IP, key is IP as string)
1213 if wildcard, its the wild card
1214 else its the cname?
1215
1216 *
1217 * @see java.security.Permission
1218 * @see java.security.Permissions
1219 * @see java.security.PermissionCollection
1220 *
1221 *
1222 * @author Roland Schemers
1223 *
1224 * @serial include
1225 */
1226
1227 final class SocketPermissionCollection extends PermissionCollection
1228 implements Serializable
1229 {
1230 // Not serialized; see serialization section at end of class
1231 private transient List<SocketPermission> perms;
1232
1233 /**
1234 * Create an empty SocketPermissions object.
1235 *
1236 */
1237
1238 public SocketPermissionCollection() {
1239 perms = new ArrayList<SocketPermission>();
1240 }
1241
1242 /**
1243 * Adds a permission to the SocketPermissions. The key for the hash is
1244 * the name in the case of wildcards, or all the IP addresses.
1245 *
1246 * @param permission the Permission object to add.
1247 *
1248 * @exception IllegalArgumentException - if the permission is not a
1249 * SocketPermission
1250 *
1251 * @exception SecurityException - if this SocketPermissionCollection object
1252 * has been marked readonly
1253 */
1254 public void add(Permission permission) {
1255 if (! (permission instanceof SocketPermission))
1256 throw new IllegalArgumentException("invalid permission: "+
1257 permission);
1258 if (isReadOnly())
1259 throw new SecurityException(
1260 "attempt to add a Permission to a readonly PermissionCollection");
1261
1262 // optimization to ensure perms most likely to be tested
1263 // show up early (4301064)
1264 synchronized (this) {
1265 perms.add(0, (SocketPermission)permission);
1266 }
1267 }
1268
1269 /**
1270 * Check and see if this collection of permissions implies the permissions
1271 * expressed in "permission".
1272 *
1273 * @param permission the Permission object to compare
1274 *
1275 * @return true if "permission" is a proper subset of a permission in
1276 * the collection, false if not.
1277 */
1278
1279 public boolean implies(Permission permission)
1280 {
1281 if (! (permission instanceof SocketPermission))
1282 return false;
1283
1284 SocketPermission np = (SocketPermission) permission;
1285
1286 int desired = np.getMask();
1287 int effective = 0;
1288 int needed = desired;
1289
1290 synchronized (this) {
1291 int len = perms.size();
1292 //System.out.println("implies "+np);
1293 for (int i = 0; i < len; i++) {
1346 * serialization compatibility with earlier releases.
1347 */
1348 private void writeObject(ObjectOutputStream out) throws IOException {
1349 // Don't call out.defaultWriteObject()
1350
1351 // Write out Vector
1352 Vector<SocketPermission> permissions = new Vector<>(perms.size());
1353
1354 synchronized (this) {
1355 permissions.addAll(perms);
1356 }
1357
1358 ObjectOutputStream.PutField pfields = out.putFields();
1359 pfields.put("permissions", permissions);
1360 out.writeFields();
1361 }
1362
1363 /*
1364 * Reads in a Vector of SocketPermissions and saves them in the perms field.
1365 */
1366 private void readObject(ObjectInputStream in)
1367 throws IOException, ClassNotFoundException
1368 {
1369 // Don't call in.defaultReadObject()
1370
1371 // Read in serialized fields
1372 ObjectInputStream.GetField gfields = in.readFields();
1373
1374 // Get the one we want
1375 @SuppressWarnings("unchecked")
1376 Vector<SocketPermission> permissions = (Vector<SocketPermission>)gfields.get("permissions", null);
1377 perms = new ArrayList<SocketPermission>(permissions.size());
1378 perms.addAll(permissions);
1379 }
1380 }
|