Source Code Cross Referenced for SocketPermission.java in  » 6.0-JDK-Modules » j2me » java » net » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » java.net 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * @(#)SocketPermission.java	1.48 06/10/10
0003:         *
0004:         * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved.  
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER  
0006:         *   
0007:         * This program is free software; you can redistribute it and/or  
0008:         * modify it under the terms of the GNU General Public License version  
0009:         * 2 only, as published by the Free Software Foundation.   
0010:         *   
0011:         * This program is distributed in the hope that it will be useful, but  
0012:         * WITHOUT ANY WARRANTY; without even the implied warranty of  
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
0014:         * General Public License version 2 for more details (a copy is  
0015:         * included at /legal/license.txt).   
0016:         *   
0017:         * You should have received a copy of the GNU General Public License  
0018:         * version 2 along with this work; if not, write to the Free Software  
0019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  
0020:         * 02110-1301 USA   
0021:         *   
0022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa  
0023:         * Clara, CA 95054 or visit www.sun.com if you need additional  
0024:         * information or have any questions. 
0025:         *
0026:         */
0027:
0028:        package java.net;
0029:
0030:        import java.util.Enumeration;
0031:        import java.util.Vector;
0032:        import java.util.List;
0033:        import java.util.ArrayList;
0034:        import java.util.Collections;
0035:        import java.util.StringTokenizer;
0036:        import java.net.InetAddress;
0037:        import java.security.Permission;
0038:        import java.security.PermissionCollection;
0039:        import java.io.Serializable;
0040:        import java.io.ObjectStreamField;
0041:        import java.io.ObjectOutputStream;
0042:        import java.io.ObjectInputStream;
0043:        import java.io.IOException;
0044:        import sun.security.util.SecurityConstants;
0045:
0046:        /**
0047:         * This class represents access to a network via sockets.
0048:         * A SocketPermission consists of a 
0049:         * host specification and a set of "actions" specifying ways to
0050:         * connect to that host. The host is specified as
0051:         * <pre>
0052:         *    host = (hostname | IPv4address | iPv6reference) [:portrange]
0053:         *    portrange = portnumber | -portnumber | portnumber-[portnumber]
0054:         * </pre>
0055:         * The host is expressed as a DNS name, as a numerical IP address,
0056:         * or as "localhost" (for the local machine).
0057:         * The wildcard "*" may be included once in a DNS name host
0058:         * specification. If it is included, it must be in the leftmost 
0059:         * position, as in "*.sun.com".
0060:         * <p>
0061:         * The format of the IPv6reference should follow that specified in <a
0062:         * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC&nbsp;2732: Format
0063:         * for Literal IPv6 Addresses in URLs</i></a>:
0064:         * <pre>
0065:         *    ipv6reference = "[" IPv6address "]"
0066:         *</pre>
0067:         * For example, you can construct a SocketPermission instance
0068:         * as the following:
0069:         * <pre>
0070:         *    String hostAddress = inetaddress.getHostAddress();
0071:         *    if (inetaddress instanceof Inet6Address) {
0072:         *        sp = new SocketPermission("[" + hostAddress + "]:" + port, action);
0073:         *    } else {
0074:         *        sp = new SocketPermission(hostAddress + ":" + port, action);
0075:         *    }
0076:         * </pre>
0077:         * or
0078:         * <pre>
0079:         *    String host = url.getHost();
0080:         *    sp = new SocketPermission(host + ":" + port, action);
0081:         * </pre>
0082:         * <p>
0083:         * The <A HREF="Inet6Address.html#lform">full uncompressed form</A> of
0084:         * an IPv6 literal address is also valid.
0085:         * <p>
0086:         * The port or portrange is optional. A port specification of the 
0087:         * form "N-", where <i>N</i> is a port number, signifies all ports
0088:         * numbered <i>N</i> and above, while a specification of the
0089:         * form "-N" indicates all ports numbered <i>N</i> and below.
0090:         * <p>
0091:         * The possible ways to connect to the host are 
0092:         * <pre>
0093:         * accept
0094:         * connect
0095:         * listen
0096:         * resolve
0097:         * </pre>
0098:         * The "listen" action is only meaningful when used with "localhost". 
0099:         * The "resolve" action is implied when any of the other actions are present.
0100:         * The action "resolve" refers to host/ip name service lookups.
0101:         * 
0102:         * <p>As an example of the creation and meaning of SocketPermissions,  
0103:         * note that if the following permission:
0104:         * 
0105:         * <pre>
0106:         *   p1 = new SocketPermission("puffin.eng.sun.com:7777", "connect,accept");
0107:         * </pre>
0108:         * 
0109:         * is granted to some code, it allows that code to connect to port 7777 on
0110:         * <code>puffin.eng.sun.com</code>, and to accept connections on that port.
0111:         * 
0112:         * <p>Similarly, if the following permission:
0113:         * 
0114:         * <pre>
0115:         *   p1 = new SocketPermission("puffin.eng.sun.com:7777", "connect,accept");
0116:         *   p2 = new SocketPermission("localhost:1024-", "accept,connect,listen");
0117:         * </pre>
0118:         * 
0119:         * is granted to some code, it allows that code to 
0120:         * accept connections on, connect to, or listen on any port between
0121:         * 1024 and 65535 on the local host.
0122:         *
0123:         * <p>Note: Granting code permission to accept or make connections to remote
0124:         * hosts may be dangerous because malevolent code can then more easily
0125:         * transfer and share confidential data among parties who may not
0126:         * otherwise have access to the data.
0127:         * 
0128:         * @see java.security.Permissions
0129:         * @see SocketPermission
0130:         *
0131:         * @version 1.41 10/27/00
0132:         *
0133:         * @author Marianne Mueller
0134:         * @author Roland Schemers 
0135:         *
0136:         * @serial exclude
0137:         */
0138:
0139:        public final class SocketPermission extends Permission implements 
0140:                java.io.Serializable {
0141:            private static final long serialVersionUID = -7204263841984476862L;
0142:
0143:            /**
0144:             * Connect to host:port
0145:             */
0146:            private final static int CONNECT = 0x1;
0147:
0148:            /**
0149:             * Listen on host:port
0150:             */
0151:            private final static int LISTEN = 0x2;
0152:
0153:            /**
0154:             * Accept a connection from host:port
0155:             */
0156:            private final static int ACCEPT = 0x4;
0157:
0158:            /**
0159:             * Resolve DNS queries
0160:             */
0161:            private final static int RESOLVE = 0x8;
0162:
0163:            /**
0164:             * No actions
0165:             */
0166:            private final static int NONE = 0x0;
0167:
0168:            /**
0169:             * All actions
0170:             */
0171:            private final static int ALL = CONNECT | LISTEN | ACCEPT | RESOLVE;
0172:
0173:            // various port constants
0174:            private static final int PORT_MIN = 0;
0175:            private static final int PORT_MAX = 65535;
0176:            private static final int PRIV_PORT_MAX = 1023;
0177:
0178:            // the actions mask
0179:            private transient int mask;
0180:
0181:            /**
0182:             * the actions string. 
0183:             *
0184:             * @serial
0185:             */
0186:
0187:            private String actions; // Left null as long as possible, then
0188:            // created and re-used in the getAction function.
0189:
0190:            // hostname part as it is passed
0191:            private transient String hostname;
0192:
0193:            // the canonical name of the host
0194:            // in the case of "*.foo.com", cname is ".foo.com".
0195:
0196:            private transient String cname;
0197:
0198:            // all the IP addresses of the host 
0199:            private transient InetAddress[] addresses;
0200:
0201:            // true if the hostname is a wildcard (e.g. "*.sun.com")
0202:            private transient boolean wildcard;
0203:
0204:            // true if we were initialized with a single numeric IP address
0205:            private transient boolean init_with_ip;
0206:
0207:            // true if this SocketPermission represents an invalid/unknown host
0208:            // used for implies when the delayed lookup has already failed
0209:            private transient boolean invalid;
0210:
0211:            // port range on host
0212:            private transient int[] portrange;
0213:
0214:            // true if the trustProxy system property is set
0215:            private static boolean trustProxy;
0216:
0217:            static {
0218:                Boolean tmp = (Boolean) java.security.AccessController
0219:                        .doPrivileged(new sun.security.action.GetBooleanAction(
0220:                                "trustProxy"));
0221:                trustProxy = tmp.booleanValue();
0222:            }
0223:
0224:            /**
0225:             * Creates a new SocketPermission object with the specified actions.
0226:             * The host is expressed as a DNS name, or as a numerical IP address.
0227:             * Optionally, a port or a portrange may be supplied (separated
0228:             * from the DNS name or IP address by a colon).
0229:             * <p>
0230:             * To specify the local machine, use "localhost" as the <i>host</i>.
0231:             * Also note: An empty <i>host</i> String ("") is equivalent to "localhost".
0232:             * <p>
0233:             * The <i>actions</i> parameter contains a comma-separated list of the
0234:             * actions granted for the specified host (and port(s)). Possible actions are
0235:             * "connect", "listen", "accept", "resolve", or 
0236:             * any combination of those. "resolve" is automatically added
0237:             * when any of the other three are specified.
0238:             * <p>
0239:             * Examples of SocketPermission instantiation are the following: 
0240:             * <pre>
0241:             *    nr = new SocketPermission("www.catalog.com", "connect");
0242:             *    nr = new SocketPermission("www.sun.com:80", "connect");
0243:             *    nr = new SocketPermission("*.sun.com", "connect");
0244:             *    nr = new SocketPermission("*.edu", "resolve");
0245:             *    nr = new SocketPermission("204.160.241.0", "connect");
0246:             *    nr = new SocketPermission("localhost:1024-65535", "listen");
0247:             *    nr = new SocketPermission("204.160.241.0:1024-65535", "connect");
0248:             * </pre>
0249:             * 
0250:             * @param host the hostname or IPaddress of the computer, optionally
0251:             * including a colon followed by a port or port range. 
0252:             * @param action the action string.
0253:             */
0254:            public SocketPermission(String host, String action) {
0255:                super (getHost(host));
0256:                // name initialized to getHost(host); NPE detected in getHost()
0257:                init(getName(), getMask(action));
0258:            }
0259:
0260:            SocketPermission(String host, int mask) {
0261:                super (getHost(host));
0262:                // name initialized to getHost(host); NPE detected in getHost()
0263:                init(getName(), mask);
0264:            }
0265:
0266:            private static String getHost(String host) {
0267:                if (host.equals("")) {
0268:                    return "localhost";
0269:                } else {
0270:                    /* IPv6 literal address used in this context should follow
0271:                     * the format specified in RFC 2732;
0272:                     * if not, we try to solve the unambiguous case
0273:                     */
0274:                    int ind;
0275:                    if (host.charAt(0) != '[') {
0276:                        if ((ind = host.indexOf(':')) != host.lastIndexOf(':')) {
0277:                            /* More than one ":", meaning IPv6 address is not
0278:                             * in RFC 2732 format;
0279:                             * We will rectify user errors for all unambiguious cases
0280:                             */
0281:                            StringTokenizer st = new StringTokenizer(host, ":");
0282:                            int tokens = st.countTokens();
0283:                            if (tokens == 9) {
0284:                                // IPv6 address followed by port
0285:                                ind = host.lastIndexOf(':');
0286:                                host = "[" + host.substring(0, ind) + "]"
0287:                                        + host.substring(ind);
0288:                            } else if (tokens == 8 && host.indexOf("::") == -1) {
0289:                                // IPv6 address only, not followed by port
0290:                                host = "[" + host + "]";
0291:                            } else {
0292:                                // could be ambiguous
0293:                                throw new IllegalArgumentException("Ambiguous"
0294:                                        + " hostport part");
0295:                            }
0296:                        }
0297:                    }
0298:                    return host;
0299:                }
0300:            }
0301:
0302:            private int[] parsePort(String port) throws Exception {
0303:
0304:                if (port == null || port.equals("") || port.equals("*")) {
0305:                    return new int[] { PORT_MIN, PORT_MAX };
0306:                }
0307:
0308:                int dash = port.indexOf('-');
0309:
0310:                if (dash == -1) {
0311:                    int p = Integer.parseInt(port);
0312:                    return new int[] { p, p };
0313:                } else {
0314:                    String low = port.substring(0, dash);
0315:                    String high = port.substring(dash + 1);
0316:                    int l, h;
0317:
0318:                    if (low.equals("")) {
0319:                        l = PORT_MIN;
0320:                    } else {
0321:                        l = Integer.parseInt(low);
0322:                    }
0323:
0324:                    if (high.equals("")) {
0325:                        h = PORT_MAX;
0326:                    } else {
0327:                        h = Integer.parseInt(high);
0328:                    }
0329:                    if (l < 0 || h < 0 || h < l)
0330:                        throw new IllegalArgumentException("invalid port range");
0331:
0332:                    return new int[] { l, h };
0333:                }
0334:            }
0335:
0336:            /**
0337:             * Initialize the SocketPermission object. We don't do any DNS lookups
0338:             * as this point, instead we hold off until the implies method is
0339:             * called.
0340:             */
0341:            private void init(String host, int mask) {
0342:                // Set the integer mask that represents the actions
0343:
0344:                if ((mask & ALL) != mask)
0345:                    throw new IllegalArgumentException("invalid actions mask");
0346:
0347:                // always OR in RESOLVE if we allow any of the others
0348:                this .mask = mask | RESOLVE;
0349:
0350:                // Parse the host name.  A name has up to three components, the
0351:                // hostname, a port number, or two numbers representing a port
0352:                // range.   "www.sun.com:8080-9090" is a valid host name. 
0353:
0354:                // With IPv6 an address can be 2010:836B:4179::836B:4179 
0355:                // An IPv6 address needs to be enclose in [] 
0356:                // For ex: [2010:836B:4179::836B:4179]:8080-9090 
0357:                // Refer to RFC 2732 for more information. 
0358:
0359:                int rb = 0;
0360:                int start = 0, end = 0;
0361:                int sep = -1;
0362:                String hostport = host;
0363:                if (host.charAt(0) == '[') {
0364:                    start = 1;
0365:                    rb = host.indexOf(']');
0366:                    if (rb != -1) {
0367:                        host = host.substring(start, rb);
0368:                    } else {
0369:                        throw new IllegalArgumentException(
0370:                                "invalid host/port: " + host);
0371:                    }
0372:                    sep = hostport.indexOf(':', rb + 1);
0373:                } else {
0374:                    start = 0;
0375:                    sep = host.indexOf(':', rb);
0376:                    end = sep;
0377:                    if (sep != -1) {
0378:                        host = host.substring(start, end);
0379:                    }
0380:                }
0381:
0382:                if (sep != -1) {
0383:                    String port = hostport.substring(sep + 1);
0384:                    try {
0385:                        portrange = parsePort(port);
0386:                    } catch (Exception e) {
0387:                        throw new IllegalArgumentException(
0388:                                "invalid port range: " + port);
0389:                    }
0390:                } else {
0391:                    portrange = new int[] { PORT_MIN, PORT_MAX };
0392:                }
0393:
0394:                hostname = host;
0395:
0396:                // is this a domain wildcard specification
0397:                if (host.lastIndexOf('*') > 0) {
0398:                    throw new IllegalArgumentException(
0399:                            "invalid host wildcard specification");
0400:                } else if (host.startsWith("*")) {
0401:                    wildcard = true;
0402:                    if (host.equals("*")) {
0403:                        cname = "";
0404:                    } else if (host.startsWith("*.")) {
0405:                        cname = host.substring(1).toLowerCase();
0406:                    } else {
0407:                        throw new IllegalArgumentException(
0408:                                "invalid host wildcard specification");
0409:                    }
0410:                    return;
0411:                } else {
0412:                    if (host.length() > 0) {
0413:                        // see if we are being initialized with an IP address.
0414:                        char ch = host.charAt(0);
0415:                        if (ch == ':' || Character.digit(ch, 16) != -1) {
0416:                            byte ip[] = Inet4Address.textToNumericFormat(host);
0417:                            if (ip == null) {
0418:                                ip = Inet6Address.textToNumericFormat(host);
0419:                            }
0420:                            if (ip != null) {
0421:                                try {
0422:                                    addresses = new InetAddress[] { InetAddress
0423:                                            .getByAddress(ip) };
0424:                                    init_with_ip = true;
0425:                                } catch (UnknownHostException uhe) {
0426:                                    // this shouldn't happen
0427:                                    invalid = true;
0428:                                }
0429:                            }
0430:                        }
0431:                    }
0432:                }
0433:            }
0434:
0435:            /**
0436:             * Convert an action string to an integer actions mask. 
0437:             *
0438:             * @param action the action string
0439:             * @return the action mask
0440:             */
0441:            private static int getMask(String action) {
0442:
0443:                if (action == null) {
0444:                    throw new NullPointerException("action can't be null");
0445:                }
0446:
0447:                if (action.equals("")) {
0448:                    throw new IllegalArgumentException("action can't be empty");
0449:                }
0450:
0451:                int mask = NONE;
0452:
0453:                // Check against use of constants (used heavily within the JDK)
0454:                if (action == SecurityConstants.SOCKET_RESOLVE_ACTION) {
0455:                    return RESOLVE;
0456:                } else if (action == SecurityConstants.SOCKET_CONNECT_ACTION) {
0457:                    return CONNECT;
0458:                } else if (action == SecurityConstants.SOCKET_LISTEN_ACTION) {
0459:                    return LISTEN;
0460:                } else if (action == SecurityConstants.SOCKET_ACCEPT_ACTION) {
0461:                    return ACCEPT;
0462:                } else if (action == SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION) {
0463:                    return CONNECT | ACCEPT;
0464:                }
0465:
0466:                char[] a = action.toCharArray();
0467:
0468:                int i = a.length - 1;
0469:                if (i < 0)
0470:                    return mask;
0471:
0472:                while (i != -1) {
0473:                    char c;
0474:
0475:                    // skip whitespace
0476:                    while ((i != -1)
0477:                            && ((c = a[i]) == ' ' || c == '\r' || c == '\n'
0478:                                    || c == '\f' || c == '\t'))
0479:                        i--;
0480:
0481:                    // check for the known strings
0482:                    int matchlen;
0483:
0484:                    if (i >= 6 && (a[i - 6] == 'c' || a[i - 6] == 'C')
0485:                            && (a[i - 5] == 'o' || a[i - 5] == 'O')
0486:                            && (a[i - 4] == 'n' || a[i - 4] == 'N')
0487:                            && (a[i - 3] == 'n' || a[i - 3] == 'N')
0488:                            && (a[i - 2] == 'e' || a[i - 2] == 'E')
0489:                            && (a[i - 1] == 'c' || a[i - 1] == 'C')
0490:                            && (a[i] == 't' || a[i] == 'T')) {
0491:                        matchlen = 7;
0492:                        mask |= CONNECT;
0493:
0494:                    } else if (i >= 6 && (a[i - 6] == 'r' || a[i - 6] == 'R')
0495:                            && (a[i - 5] == 'e' || a[i - 5] == 'E')
0496:                            && (a[i - 4] == 's' || a[i - 4] == 'S')
0497:                            && (a[i - 3] == 'o' || a[i - 3] == 'O')
0498:                            && (a[i - 2] == 'l' || a[i - 2] == 'L')
0499:                            && (a[i - 1] == 'v' || a[i - 1] == 'V')
0500:                            && (a[i] == 'e' || a[i] == 'E')) {
0501:                        matchlen = 7;
0502:                        mask |= RESOLVE;
0503:
0504:                    } else if (i >= 5 && (a[i - 5] == 'l' || a[i - 5] == 'L')
0505:                            && (a[i - 4] == 'i' || a[i - 4] == 'I')
0506:                            && (a[i - 3] == 's' || a[i - 3] == 'S')
0507:                            && (a[i - 2] == 't' || a[i - 2] == 'T')
0508:                            && (a[i - 1] == 'e' || a[i - 1] == 'E')
0509:                            && (a[i] == 'n' || a[i] == 'N')) {
0510:                        matchlen = 6;
0511:                        mask |= LISTEN;
0512:
0513:                    } else if (i >= 5 && (a[i - 5] == 'a' || a[i - 5] == 'A')
0514:                            && (a[i - 4] == 'c' || a[i - 4] == 'C')
0515:                            && (a[i - 3] == 'c' || a[i - 3] == 'C')
0516:                            && (a[i - 2] == 'e' || a[i - 2] == 'E')
0517:                            && (a[i - 1] == 'p' || a[i - 1] == 'P')
0518:                            && (a[i] == 't' || a[i] == 'T')) {
0519:                        matchlen = 6;
0520:                        mask |= ACCEPT;
0521:
0522:                    } else {
0523:                        // parse error
0524:                        throw new IllegalArgumentException(
0525:                                "invalid permission: " + action);
0526:                    }
0527:
0528:                    // make sure we didn't just match the tail of a word
0529:                    // like "ackbarfaccept".  Also, skip to the comma.
0530:                    boolean seencomma = false;
0531:                    while (i >= matchlen && !seencomma) {
0532:                        switch (a[i - matchlen]) {
0533:                        case ',':
0534:                            seencomma = true;
0535:                            /*FALLTHROUGH*/
0536:                        case ' ':
0537:                        case '\r':
0538:                        case '\n':
0539:                        case '\f':
0540:                        case '\t':
0541:                            break;
0542:                        default:
0543:                            throw new IllegalArgumentException(
0544:                                    "invalid permission: " + action);
0545:                        }
0546:                        i--;
0547:                    }
0548:
0549:                    // point i at the location of the comma minus one (or -1).
0550:                    i -= matchlen;
0551:                }
0552:
0553:                return mask;
0554:            }
0555:
0556:            /**
0557:             * attempt to get the fully qualified domain name
0558:             *
0559:             */
0560:            void getCanonName() throws UnknownHostException {
0561:                if (cname != null || invalid)
0562:                    return;
0563:
0564:                // attempt to get the canonical name
0565:
0566:                try {
0567:                    // first get the IP addresses if we don't have them yet
0568:                    // this is because we need the IP address to then get 
0569:                    // FQDN.
0570:                    if (addresses == null) {
0571:                        getIP();
0572:                    }
0573:
0574:                    // we have to do this check, otherwise we might not
0575:                    // get the fully qualified domain name
0576:                    if (init_with_ip) {
0577:                        cname = addresses[0].getHostName(false).toLowerCase();
0578:                    } else {
0579:                        cname = InetAddress.getByName(
0580:                                addresses[0].getHostAddress()).getHostName(
0581:                                false).toLowerCase();
0582:                    }
0583:                } catch (UnknownHostException uhe) {
0584:                    invalid = true;
0585:                    throw uhe;
0586:                }
0587:            }
0588:
0589:            /**
0590:             * get IP addresses. Sets invalid to true if we can't get them.
0591:             *
0592:             */
0593:            void getIP() throws UnknownHostException {
0594:                if (addresses != null || wildcard || invalid)
0595:                    return;
0596:
0597:                try {
0598:                    // now get all the IP addresses
0599:                    String host;
0600:                    if (getName().charAt(0) == '[') {
0601:                        // Literal IPv6 address
0602:                        host = getName().substring(1, getName().indexOf(']'));
0603:                    } else {
0604:                        int i = getName().indexOf(":");
0605:                        if (i == -1)
0606:                            host = getName();
0607:                        else {
0608:                            host = getName().substring(0, i);
0609:                        }
0610:                    }
0611:
0612:                    addresses = new InetAddress[] { InetAddress.getAllByName0(
0613:                            host, false)[0] };
0614:
0615:                } catch (UnknownHostException uhe) {
0616:                    invalid = true;
0617:                    throw uhe;
0618:                } catch (IndexOutOfBoundsException iobe) {
0619:                    invalid = true;
0620:                    throw new UnknownHostException(getName());
0621:                }
0622:            }
0623:
0624:            /**
0625:             * Checks if this socket permission object "implies" the 
0626:             * specified permission.
0627:             * <P>
0628:             * More specifically, this method first ensures that all of the following
0629:             * are true (and returns false if any of them are not):<p>
0630:             * <ul>
0631:             * <li> <i>p</i> is an instanceof SocketPermission,<p>
0632:             * <li> <i>p</i>'s actions are a proper subset of this
0633:             * object's actions, and<p>
0634:             * <li> <i>p</i>'s port range is included in this port range. Note:
0635:             * port range is ignored when p only contains the action, 'resolve'.<p>
0636:             * </ul>
0637:             * 
0638:             * Then <code>implies</code> checks each of the following, in order,
0639:             * and for each returns true if the stated condition is true:<p>
0640:             * <ul>
0641:             * <li> If this object was initialized with a single IP address and one of <i>p</i>'s 
0642:             * IP addresses is equal to this object's IP address.<p>
0643:             * <li>If this object is a wildcard domain (such as *.sun.com), and
0644:             * <i>p</i>'s canonical name (the name without any preceding *)
0645:             * ends with this object's canonical host name. For example, *.sun.com
0646:             * implies *.eng.sun.com..<p>
0647:             * <li>If this object was not initialized with a single IP address, and one of this
0648:             * object's IP addresses equals one of <i>p</i>'s IP addresses.<p>
0649:             * <li>If this canonical name equals <i>p</i>'s canonical name.<p>
0650:             * </ul>
0651:             * 
0652:             * If none of the above are true, <code>implies</code> returns false.
0653:             * @param p the permission to check against.
0654:             *
0655:             * @return true if the specified permission is implied by this object,
0656:             * false if not.  
0657:             */
0658:
0659:            public boolean implies(Permission p) {
0660:                int i, j;
0661:
0662:                if (!(p instanceof  SocketPermission))
0663:                    return false;
0664:
0665:                SocketPermission that = (SocketPermission) p;
0666:
0667:                return ((this .mask & that.mask) == that.mask)
0668:                        && impliesIgnoreMask(that);
0669:            }
0670:
0671:            /**
0672:             * Checks if the incoming Permission's action are a proper subset of
0673:             * the this object's actions.
0674:             * <P>
0675:             * Check, in the following order:
0676:             * <ul>
0677:             * <li> Checks that "p" is an instanceof a SocketPermission
0678:             * <li> Checks that "p"'s actions are a proper subset of the
0679:             * current object's actions.
0680:             * <li> Checks that "p"'s port range is included in this port range
0681:             * <li> If this object was initialized with an IP address, checks that 
0682:             *      one of "p"'s IP addresses is equal to this object's IP address.
0683:             * <li> If either object is a wildcard domain (i.e., "*.sun.com"),
0684:             *      attempt to match based on the wildcard.
0685:             * <li> If this object was not initialized with an IP address, attempt
0686:             *      to find a match based on the IP addresses in both objects.
0687:             * <li> Attempt to match on the canonical hostnames of both objects.
0688:             * </ul>
0689:             * @param p the incoming permission request
0690:             *
0691:             * @return true if "permission" is a proper subset of the current object,
0692:             * false if not.  
0693:             */
0694:
0695:            boolean impliesIgnoreMask(SocketPermission that) {
0696:                int i, j;
0697:
0698:                if ((that.mask & RESOLVE) != that.mask) {
0699:                    // check port range
0700:                    if ((that.portrange[0] < this .portrange[0])
0701:                            || (that.portrange[1] > this .portrange[1])) {
0702:                        return false;
0703:                    }
0704:                }
0705:
0706:                // allow a "*" wildcard to always match anything
0707:                if (this .wildcard && "".equals(this .cname))
0708:                    return true;
0709:
0710:                // return if either one of these NetPerm objects are invalid...
0711:                if (this .invalid || that.invalid) {
0712:                    return (trustProxy ? inProxyWeTrust(that) : false);
0713:                }
0714:
0715:                try {
0716:                    if (this .init_with_ip) { // we only check IP addresses
0717:                        if (that.wildcard)
0718:                            return false;
0719:
0720:                        if (that.init_with_ip) {
0721:                            return (this .addresses[0].equals(that.addresses[0]));
0722:                        } else {
0723:                            if (that.addresses == null) {
0724:                                that.getIP();
0725:                            }
0726:                            for (i = 0; i < that.addresses.length; i++) {
0727:                                if (this .addresses[0].equals(that.addresses[i]))
0728:                                    return true;
0729:                            }
0730:                        }
0731:                        // since "this" was initialized with an IP address, we
0732:                        // don't check any other cases
0733:                        return false;
0734:                    }
0735:
0736:                    // check and see if we have any wildcards...
0737:                    if (this .wildcard || that.wildcard) {
0738:                        // if they are both wildcards, return true iff
0739:                        // that's cname ends with this cname (i.e., *.sun.com
0740:                        // implies *.eng.sun.com)
0741:                        if (this .wildcard && that.wildcard)
0742:                            return (that.cname.endsWith(this .cname));
0743:
0744:                        // a non-wildcard can't imply a wildcard
0745:                        if (that.wildcard)
0746:                            return false;
0747:
0748:                        // this is a wildcard, lets see if that's cname ends with
0749:                        // it...
0750:                        if (that.cname == null) {
0751:                            that.getCanonName();
0752:                        }
0753:                        return (that.cname.endsWith(this .cname));
0754:                    }
0755:
0756:                    // comapare IP addresses
0757:                    if (this .addresses == null) {
0758:                        this .getIP();
0759:                    }
0760:
0761:                    if (that.addresses == null) {
0762:                        that.getIP();
0763:                    }
0764:
0765:                    for (j = 0; j < this .addresses.length; j++) {
0766:                        for (i = 0; i < that.addresses.length; i++) {
0767:                            if (this .addresses[j].equals(that.addresses[i]))
0768:                                return true;
0769:                        }
0770:                    }
0771:
0772:                    // If all else fails, compare hostnames?
0773:                    // Do we really want this?
0774:                    if (this .cname == null) {
0775:                        this .getCanonName();
0776:                    }
0777:
0778:                    if (that.cname == null) {
0779:                        that.getCanonName();
0780:                    }
0781:
0782:                    return (this .cname.equalsIgnoreCase(that.cname));
0783:
0784:                } catch (UnknownHostException uhe) {
0785:                    if (trustProxy)
0786:                        return inProxyWeTrust(that);
0787:                }
0788:
0789:                // make sure the first thing that is done here is to return
0790:                // false. If not, uncomment the return false in the above catch.
0791:
0792:                return false;
0793:            }
0794:
0795:            private boolean inProxyWeTrust(SocketPermission that) {
0796:                // if we trust the proxy, we see if the original names/IPs passed
0797:                // in were equal.
0798:
0799:                String this Host = hostname;
0800:                String thatHost = that.hostname;
0801:
0802:                if (this Host == null)
0803:                    return false;
0804:                else
0805:                    return this Host.equalsIgnoreCase(thatHost);
0806:
0807:            }
0808:
0809:            /**
0810:             * Checks two SocketPermission objects for equality. 
0811:             * <P>
0812:             * @param obj the object to test for equality with this object.
0813:             * 
0814:             * @return true if <i>obj</i> is a SocketPermission, and has the
0815:             *  same hostname, port range, and actions as this
0816:             *  SocketPermission object. However, port range will be ignored
0817:             *  in the comparison if <i>obj</i> only contains the action, 'resolve'.
0818:             */
0819:            public boolean equals(Object obj) {
0820:                if (obj == this )
0821:                    return true;
0822:
0823:                if (!(obj instanceof  SocketPermission))
0824:                    return false;
0825:
0826:                SocketPermission that = (SocketPermission) obj;
0827:
0828:                //this is (overly?) complex!!!
0829:
0830:                // check the mask first
0831:                if (this .mask != that.mask)
0832:                    return false;
0833:
0834:                if ((that.mask & RESOLVE) != that.mask) {
0835:                    // now check the port range...
0836:                    if ((this .portrange[0] != that.portrange[0])
0837:                            || (this .portrange[1] != that.portrange[1])) {
0838:                        return false;
0839:                    }
0840:                }
0841:
0842:                // short cut. This catches:
0843:                //  "crypto" equal to "crypto", or
0844:                // "1.2.3.4" equal to "1.2.3.4.", or 
0845:                //  "*.edu" equal to "*.edu", but it 
0846:                //  does not catch "crypto" equal to
0847:                // "crypto.eng.sun.com".
0848:
0849:                if (this .getName().equalsIgnoreCase(that.getName())) {
0850:                    return true;
0851:                }
0852:
0853:                // we now attempt to get the Canonical (FQDN) name and
0854:                // compare that. If this fails, about all we can do is return
0855:                // false.
0856:
0857:                try {
0858:                    this .getCanonName();
0859:                    that.getCanonName();
0860:                } catch (UnknownHostException uhe) {
0861:                    return false;
0862:                }
0863:
0864:                if (this .invalid || that.invalid)
0865:                    return false;
0866:
0867:                if (this .cname != null) {
0868:                    return this .cname.equalsIgnoreCase(that.cname);
0869:                }
0870:
0871:                return false;
0872:            }
0873:
0874:            /**
0875:             * Returns the hash code value for this object.
0876:             *
0877:             * @return a hash code value for this object.
0878:             */
0879:
0880:            public int hashCode() {
0881:                /*
0882:                 * If this SocketPermission was initialized with an IP address
0883:                 * or a wildcard, use getName().hashCode(), otherwise use
0884:                 * the hashCode() of the host name returned from 
0885:                 * java.net.InetAddress.getHostName method.
0886:                 */
0887:
0888:                if (init_with_ip || wildcard) {
0889:                    return this .getName().hashCode();
0890:                }
0891:
0892:                try {
0893:                    getCanonName();
0894:                } catch (UnknownHostException uhe) {
0895:
0896:                }
0897:
0898:                if (invalid || cname == null)
0899:                    return this .getName().hashCode();
0900:                else
0901:                    return this .cname.hashCode();
0902:            }
0903:
0904:            /**
0905:             * Return the current action mask.
0906:             *
0907:             * @return the actions mask.
0908:             */
0909:
0910:            int getMask() {
0911:                return mask;
0912:            }
0913:
0914:            /**
0915:             * Returns the "canonical string representation" of the actions in the
0916:             * specified mask.
0917:             * Always returns present actions in the following order: 
0918:             * connect, listen, accept, resolve.  
0919:             *
0920:             * @param mask a specific integer action mask to translate into a string
0921:             * @return the canonical string representation of the actions
0922:             */
0923:            private static String getActions(int mask) {
0924:                StringBuffer sb = new StringBuffer();
0925:                boolean comma = false;
0926:
0927:                if ((mask & CONNECT) == CONNECT) {
0928:                    comma = true;
0929:                    sb.append("connect");
0930:                }
0931:
0932:                if ((mask & LISTEN) == LISTEN) {
0933:                    if (comma)
0934:                        sb.append(',');
0935:                    else
0936:                        comma = true;
0937:                    sb.append("listen");
0938:                }
0939:
0940:                if ((mask & ACCEPT) == ACCEPT) {
0941:                    if (comma)
0942:                        sb.append(',');
0943:                    else
0944:                        comma = true;
0945:                    sb.append("accept");
0946:                }
0947:
0948:                if ((mask & RESOLVE) == RESOLVE) {
0949:                    if (comma)
0950:                        sb.append(',');
0951:                    else
0952:                        comma = true;
0953:                    sb.append("resolve");
0954:                }
0955:
0956:                return sb.toString();
0957:            }
0958:
0959:            /**
0960:             * Returns the canonical string representation of the actions.
0961:             * Always returns present actions in the following order: 
0962:             * connect, listen, accept, resolve.  
0963:             *
0964:             * @return the canonical string representation of the actions.
0965:             */
0966:            public String getActions() {
0967:                if (actions == null)
0968:                    actions = getActions(this .mask);
0969:
0970:                return actions;
0971:            }
0972:
0973:            /**
0974:             * Returns a new PermissionCollection object for storing SocketPermission 
0975:             * objects.
0976:             * <p>
0977:             * SocketPermission objects must be stored in a manner that allows them 
0978:             * to be inserted into the collection in any order, but that also enables the 
0979:             * PermissionCollection <code>implies</code>
0980:             * method to be implemented in an efficient (and consistent) manner.
0981:             *
0982:             * @return a new PermissionCollection object suitable for storing SocketPermissions.
0983:             */
0984:
0985:            public PermissionCollection newPermissionCollection() {
0986:                return new SocketPermissionCollection();
0987:            }
0988:
0989:            /**
0990:             * WriteObject is called to save the state of the SocketPermission 
0991:             * to a stream. The actions are serialized, and the superclass
0992:             * takes care of the name.
0993:             */
0994:            private synchronized void writeObject(java.io.ObjectOutputStream s)
0995:                    throws IOException {
0996:                // Write out the actions. The superclass takes care of the name
0997:                // call getActions to make sure actions field is initialized
0998:                if (actions == null)
0999:                    getActions();
1000:                s.defaultWriteObject();
1001:            }
1002:
1003:            /**
1004:             * readObject is called to restore the state of the SocketPermission from
1005:             * a stream.
1006:             */
1007:            private synchronized void readObject(java.io.ObjectInputStream s)
1008:                    throws IOException, ClassNotFoundException {
1009:                // Read in the action, then initialize the rest
1010:                s.defaultReadObject();
1011:                init(getName(), getMask(actions));
1012:            }
1013:
1014:            /*
1015:            public String toString() 
1016:            {
1017:            StringBuffer s = new StringBuffer(super.toString() + "\n" +
1018:                "cname = " + cname + "\n" +
1019:                "wildcard = " + wildcard + "\n" +
1020:                "invalid = " + invalid + "\n" +
1021:            	    "portrange = " + portrange[0] + "," + portrange[1] + "\n");
1022:            if (addresses != null) for (int i=0; i<addresses.length; i++) {
1023:                s.append( addresses[i].getHostAddress());
1024:                s.append("\n");
1025:            } else {
1026:                s.append("(no addresses)\n");
1027:            }
1028:
1029:            return s.toString();
1030:            }
1031:
1032:            public static void main(String args[]) throws Exception {
1033:            SocketPermission this_ = new SocketPermission(args[0], "connect");
1034:            SocketPermission that_ = new SocketPermission(args[1], "connect");
1035:            System.out.println("-----\n");
1036:            System.out.println("this.implies(that) = " + this_.implies(that_));
1037:            System.out.println("-----\n");
1038:            System.out.println("this = "+this_);
1039:            System.out.println("-----\n");
1040:            System.out.println("that = "+that_);
1041:            System.out.println("-----\n");
1042:
1043:            SocketPermissionCollection nps = new SocketPermissionCollection();
1044:            nps.add(this_);
1045:            nps.add(new SocketPermission("www-leland.stanford.edu","connect"));
1046:            nps.add(new SocketPermission("www-sun.com","connect"));
1047:            System.out.println("nps.implies(that) = " + nps.implies(that_));
1048:            System.out.println("-----\n");
1049:            }
1050:             */
1051:        }
1052:
1053:        /**
1054:
1055:         if (init'd with IP, key is IP as string)
1056:         if wildcard, its the wild card
1057:         else its the cname?
1058:
1059:         *
1060:         * @see java.security.Permission
1061:         * @see java.security.Permissions
1062:         * @see java.security.PermissionCollection
1063:         *
1064:         * @version 1.41 10/27/00
1065:         *
1066:         * @author Roland Schemers
1067:         *
1068:         * @serial include
1069:         */
1070:
1071:        final class SocketPermissionCollection extends PermissionCollection
1072:                implements  Serializable {
1073:            // Not serialized; see serialization section at end of class
1074:            private transient List perms;
1075:
1076:            /**
1077:             * Create an empty SocketPermissions object.
1078:             *
1079:             */
1080:
1081:            public SocketPermissionCollection() {
1082:                perms = new ArrayList();
1083:            }
1084:
1085:            /**
1086:             * Adds a permission to the SocketPermissions. The key for the hash is
1087:             * the name in the case of wildcards, or all the IP addresses.
1088:             *
1089:             * @param permission the Permission object to add.
1090:             *
1091:             * @exception IllegalArgumentException - if the permission is not a
1092:             *                                       SocketPermission
1093:             *
1094:             * @exception SecurityException - if this SocketPermissionCollection object
1095:             *                                has been marked readonly
1096:             */
1097:
1098:            public void add(Permission permission) {
1099:                if (!(permission instanceof  SocketPermission))
1100:                    throw new IllegalArgumentException("invalid permission: "
1101:                            + permission);
1102:                if (isReadOnly())
1103:                    throw new SecurityException(
1104:                            "attempt to add a Permission to a readonly PermissionCollection");
1105:
1106:                // No need to synchronize because all adds are done sequentially
1107:                // before any implies() calls
1108:
1109:                // optimization to ensure perms most likely to be tested
1110:                // show up early (4301064)
1111:                perms.add(0, permission);
1112:            }
1113:
1114:            /**
1115:             * Check and see if this collection of permissions implies the permissions 
1116:             * expressed in "permission".
1117:             *
1118:             * @param p the Permission object to compare
1119:             *
1120:             * @return true if "permission" is a proper subset of a permission in 
1121:             * the collection, false if not.
1122:             */
1123:
1124:            public boolean implies(Permission permission) {
1125:                if (!(permission instanceof  SocketPermission))
1126:                    return false;
1127:
1128:                SocketPermission np = (SocketPermission) permission;
1129:
1130:                int desired = np.getMask();
1131:                int effective = 0;
1132:                int needed = desired;
1133:
1134:                int len = perms.size();
1135:                //System.out.println("implies "+np);
1136:                for (int i = 0; i < len; i++) {
1137:                    SocketPermission x = (SocketPermission) perms.get(i);
1138:                    //System.out.println("  trying "+x);
1139:                    if (((needed & x.getMask()) != 0)
1140:                            && x.impliesIgnoreMask(np)) {
1141:                        effective |= x.getMask();
1142:                        if ((effective & desired) == desired)
1143:                            return true;
1144:                        needed = (desired ^ effective);
1145:                    }
1146:                }
1147:                return false;
1148:            }
1149:
1150:            /**
1151:             * Returns an enumeration of all the SocketPermission objects in the 
1152:             * container.
1153:             *
1154:             * @return an enumeration of all the SocketPermission objects.
1155:             */
1156:
1157:            public Enumeration elements() {
1158:                // Convert Iterator into Enumeration
1159:                return Collections.enumeration(perms);
1160:            }
1161:
1162:            private static final long serialVersionUID = 2787186408602843674L;
1163:
1164:            // Need to maintain serialization interoperability with earlier releases,
1165:            // which had the serializable field:
1166:
1167:            // 
1168:            // The SocketPermissions for this set.
1169:            // @serial
1170:            // 
1171:            // private Vector permissions;
1172:
1173:            /**
1174:             * @serialField permissions java.util.Vector
1175:             *     A list of the SocketPermissions for this set.
1176:             */
1177:            private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
1178:                    "permissions", Vector.class), };
1179:
1180:            /**
1181:             * @serialData "permissions" field (a Vector containing the SocketPermissions).
1182:             */
1183:            /*
1184:             * Writes the contents of the perms field out as a Vector for
1185:             * serialization compatibility with earlier releases.
1186:             */
1187:            private void writeObject(ObjectOutputStream out) throws IOException {
1188:                // Don't call out.defaultWriteObject()
1189:
1190:                // Write out Vector
1191:                Vector permissions = new Vector(perms.size());
1192:                permissions.addAll(perms);
1193:
1194:                ObjectOutputStream.PutField pfields = out.putFields();
1195:                pfields.put("permissions", permissions);
1196:                out.writeFields();
1197:            }
1198:
1199:            /*
1200:             * Reads in a Vector of SocketPermissions and saves them in the perms field.
1201:             */
1202:            private void readObject(ObjectInputStream in) throws IOException,
1203:                    ClassNotFoundException {
1204:                // Don't call in.defaultReadObject()
1205:
1206:                // Read in serialized fields
1207:                ObjectInputStream.GetField gfields = in.readFields();
1208:
1209:                // Get the one we want
1210:                Vector permissions = (Vector) gfields.get("permissions", null);
1211:                perms = new ArrayList(permissions.size());
1212:                perms.addAll(permissions);
1213:            }
1214:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.