2437 lines · 93.5 KB · Java
RawDownload
     *          AccessControlContext.     *     * @param pppe a Principal specified in a policy grant entry.     *     * @return true if the current thread's pList "contains" the     *          principal in the policy entry, pppe.  This method     *          also returns true if the policy entry's principal     *          appropriately wildcarded.     */    private boolean checkEntryPs(Principal[] pList,                                PolicyParser.PrincipalEntry pppe) {         for (int i = 0; i < pList.length; i++) {             if (pppe.principalClass.equals                        (PolicyParser.PrincipalEntry.WILDCARD_CLASS) ||                pppe.principalClass.equals                        (pList[i].getClass().getName())) {                 if (pppe.principalName.equals                        (PolicyParser.PrincipalEntry.WILDCARD_NAME) ||                    pppe.principalName.equals                        (pList[i].getName())) {                     return true;                }            }        }        return false;    }     /**     * <p>     *     * @param sp the SelfPermission that needs to be expanded <p>     *     * @param entryPs list of principals for the Policy entry.     *     * @param pdp Principal array from the current ProtectionDomain.     *     * @param perms the PermissionCollection where the individual     *                  Permissions will be added after expansion.     */     private void expandSelf(SelfPermission sp,                            List<PolicyParser.PrincipalEntry> entryPs,                            Principal[] pdp,                            Permissions perms) {         if (entryPs == null || entryPs.size() == 0) {            // No principals in the grant to substitute            if (debug != null) {                debug.println("Ignoring permission "                                + sp.getSelfType()                                + " with target name ("                                + sp.getSelfName() + ").  "                                + "No Principal(s) specified "                                + "in the grant clause.  "                                + "SELF-based target names are "                                + "only valid in the context "                                + "of a Principal-based grant entry."                             );            }            return;        }        int startIndex = 0;        int v;        StringBuilder sb = new StringBuilder();        while ((v = sp.getSelfName().indexOf(SELF, startIndex)) != -1) {             // add non-SELF string            sb.append(sp.getSelfName().substring(startIndex, v));             // expand SELF            ListIterator<PolicyParser.PrincipalEntry> pli =                                                entryPs.listIterator();            while (pli.hasNext()) {                PolicyParser.PrincipalEntry pppe = pli.next();                String[][] principalInfo = getPrincipalInfo(pppe,pdp);                for (int i = 0; i < principalInfo.length; i++) {                    if (i != 0) {                        sb.append(", ");                    }                    sb.append(principalInfo[i][0] + " " +                        "\"" + principalInfo[i][1] + "\"");                }                if (pli.hasNext()) {                    sb.append(", ");                }            }            startIndex = v + SELF.length();        }        // add remaining string (might be the entire string)        sb.append(sp.getSelfName().substring(startIndex));         if (debug != null) {            debug.println("  expanded:\n\t" + sp.getSelfName()                        + "\n  into:\n\t" + sb.toString());        }        try {            // first try to instantiate the permission            perms.add(getInstance(sp.getSelfType(),                                sb.toString(),                                sp.getSelfActions()));        } catch (ClassNotFoundException cnfe) {            // ok, the permission is not in the bootclasspath.            // before we add an UnresolvedPermission, check to see            // whether this perm already belongs to the collection.            // if so, use that perm's ClassLoader to create a new            // one.            Class<?> pc = null;            synchronized (perms) {                Enumeration<Permission> e = perms.elements();                while (e.hasMoreElements()) {                    Permission pElement = e.nextElement();                    if (pElement.getClass().getName().equals(sp.getSelfType())) {                        pc = pElement.getClass();                        break;                    }                }            }            if (pc == null) {                // create an UnresolvedPermission                perms.add(new UnresolvedPermission(sp.getSelfType(),                                                        sb.toString(),                                                        sp.getSelfActions(),                                                        sp.getCerts()));            } else {                try {                    // we found an instantiated permission.                    // use its class loader to instantiate a new permission.                    Constructor<?> c;                    // name parameter can not be null                    if (sp.getSelfActions() == null) {                        try {                            c = pc.getConstructor(PARAMS1);                            perms.add((Permission)c.newInstance                                 (new Object[] {sb.toString()}));                        } catch (NoSuchMethodException ne) {                            c = pc.getConstructor(PARAMS2);                            perms.add((Permission)c.newInstance                                 (new Object[] {sb.toString(),                                                sp.getSelfActions() }));                        }                    } else {                        c = pc.getConstructor(PARAMS2);                        perms.add((Permission)c.newInstance                           (new Object[] {sb.toString(),                                          sp.getSelfActions()}));                    }                } catch (Exception nme) {                    if (debug != null) {                        debug.println("self entry expansion " +                        " instantiation failed: "                        +  nme.toString());                    }                }            }        } catch (Exception e) {            if (debug != null) {                debug.println(e.toString());            }        }    }     /**     * return the principal class/name pair in the 2D array.     * array[x][y]:     x corresponds to the array length.     *                  if (y == 0), it's the principal class.     *                  if (y == 1), it's the principal name.     */    private String[][] getPrincipalInfo        (PolicyParser.PrincipalEntry pe, Principal[] pdp) {         // there are 3 possibilities:        // 1) the entry's Principal class and name are not wildcarded        // 2) the entry's Principal name is wildcarded only        // 3) the entry's Principal class and name are wildcarded         if (!pe.principalClass.equals            (PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&            !pe.principalName.equals            (PolicyParser.PrincipalEntry.WILDCARD_NAME)) {             // build an info array for the principal            // from the Policy entry            String[][] info = new String[1][2];            info[0][0] = pe.principalClass;            info[0][1] = pe.principalName;            return info;         } else if (!pe.principalClass.equals                   (PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&                   pe.principalName.equals                   (PolicyParser.PrincipalEntry.WILDCARD_NAME)) {             // build an info array for every principal            // in the current domain which has a principal class            // that is equal to policy entry principal class name            List<Principal> plist = new ArrayList<>();            for (int i = 0; i < pdp.length; i++) {                if(pe.principalClass.equals(pdp[i].getClass().getName()))                    plist.add(pdp[i]);            }            String[][] info = new String[plist.size()][2];            int i = 0;            java.util.Iterator<Principal> pIterator = plist.iterator();            while (pIterator.hasNext()) {                Principal p = pIterator.next();                info[i][0] = p.getClass().getName();                info[i][1] = p.getName();                i++;            }            return info;         } else {             // build an info array for every            // one of the current Domain's principals             String[][] info = new String[pdp.length][2];             for (int i = 0; i < pdp.length; i++) {                info[i][0] = pdp[i].getClass().getName();                info[i][1] = pdp[i].getName();            }            return info;        }    }     /*     * Returns the signer certificates from the list of certificates     * associated with the given code source.     *     * The signer certificates are those certificates that were used     * to verifysigned code originating from the codesource location.     *     * This method assumes that in the given code source, each signer     * certificate is followed by its supporting certificate chain     * (which may be empty), and that the signer certificate and its     * supporting certificate chain are ordered bottom-to-top     * (i.e., with the signer certificate first and the (root) certificate     * authority last).     */    protected Certificate[] getSignerCertificates(CodeSource cs) {        Certificate[] certs = null;        if ((certs = cs.getCertificates()) == null)            return null;        for (int i=0; i<certs.length; i++) {            if (!(certs[i] instanceof X509Certificate))                return cs.getCertificates();        }         // Do we have to do anything?        int i = 0;        int count = 0;        while (i < certs.length) {            count++;            while (((i+1) < certs.length)                   && ((X509Certificate)certs[i]).getIssuerDN().equals(                           ((X509Certificate)certs[i+1]).getSubjectDN())) {                i++;            }            i++;        }        if (count == certs.length)            // Done            return certs;         ArrayList<Certificate> userCertList = new ArrayList<>();        i = 0;        while (i < certs.length) {            userCertList.add(certs[i]);            while (((i+1) < certs.length)                   && ((X509Certificate)certs[i]).getIssuerDN().equals(                           ((X509Certificate)certs[i+1]).getSubjectDN())) {                i++;            }            i++;        }        Certificate[] userCerts = new Certificate[userCertList.size()];        userCertList.toArray(userCerts);        return userCerts;    }     private CodeSource canonicalizeCodebase(CodeSource cs,                                            boolean extractSignerCerts) {         String path = null;         CodeSource canonCs = cs;        URL u = cs.getLocation();        if (u != null) {            if (u.getProtocol().equals("jar")) {                // unwrap url embedded inside jar url                String spec = u.getFile();                int separator = spec.indexOf("!/");                if (separator != -1) {                    try {                        u = new URL(spec.substring(0, separator));                    } catch (MalformedURLException e) {                        // Fail silently. In this case, url stays what                        // it was above                    }                }            }            if (u.getProtocol().equals("file")) {                boolean isLocalFile = false;                String host = u.getHost();                isLocalFile = (host == null || host.equals("") ||                    host.equals("~") || host.equalsIgnoreCase("localhost"));                 if (isLocalFile) {                    path = u.getFile().replace('/', File.separatorChar);                    path = ParseUtil.decode(path);                }            }        }         if (path != null) {            try {                URL csUrl = null;                path = canonPath(path);                csUrl = ParseUtil.fileToEncodedURL(new File(path));                 if (extractSignerCerts) {                    canonCs = new CodeSource(csUrl,                                             getSignerCertificates(cs));                } else {                    canonCs = new CodeSource(csUrl,                                             cs.getCertificates());                }            } catch (IOException ioe) {                // leave codesource as it is, unless we have to extract its                // signer certificates                if (extractSignerCerts) {                    canonCs = new CodeSource(cs.getLocation(),                                             getSignerCertificates(cs));                }            }        } else {            if (extractSignerCerts) {                canonCs = new CodeSource(cs.getLocation(),                                         getSignerCertificates(cs));            }        }        return canonCs;    }     // Wrapper to return a canonical path that avoids calling getCanonicalPath()    // with paths that are intended to match all entries in the directory    private static String canonPath(String path) throws IOException {        if (path.endsWith("*")) {            path = path.substring(0, path.length()-1) + "-";            path = new File(path).getCanonicalPath();            return path.substring(0, path.length()-1) + "*";        } else {            return new File(path).getCanonicalPath();        }    }     private String printPD(ProtectionDomain pd) {        Principal[] principals = pd.getPrincipals();        String pals = "<no principals>";        if (principals != null && principals.length > 0) {            StringBuilder palBuf = new StringBuilder("(principals ");            for (int i = 0; i < principals.length; i++) {                palBuf.append(principals[i].getClass().getName() +                              " \"" + principals[i].getName() +                              "\"");                if (i < principals.length-1)                    palBuf.append(", ");                else                    palBuf.append(")");            }            pals = palBuf.toString();        }        return "PD CodeSource: "                + pd.getCodeSource()                +"\n\t" + "PD ClassLoader: "                + pd.getClassLoader()                +"\n\t" + "PD Principals: "                + pals;    }     /**     * return true if no replacement was performed,     * or if replacement succeeded.     */    private boolean replacePrincipals(        List<PolicyParser.PrincipalEntry> principals, KeyStore keystore) {         if (principals == null || principals.size() == 0 || keystore == null)            return true;         ListIterator<PolicyParser.PrincipalEntry> i = principals.listIterator();        while (i.hasNext()) {            PolicyParser.PrincipalEntry pppe = i.next();            if (pppe.principalClass.equals(PolicyParser.REPLACE_NAME)) {                 // perform replacement                // (only X509 replacement is possible now)                String name;                if ((name = getDN(pppe.principalName, keystore)) == null) {                    return false;                }                 if (debug != null) {                    debug.println("  Replacing \"" +                        pppe.principalName +                        "\" with " +                        X500PRINCIPAL + "/\"" +                        name +                        "\"");                }                 pppe.principalClass = X500PRINCIPAL;                pppe.principalName = name;            }        }        // return true if no replacement was performed,        // or if replacement succeeded        return true;    }     private void expandPermissionName(PolicyParser.PermissionEntry pe,                                        KeyStore keystore) throws Exception {        // short cut the common case        if (pe.name == null || pe.name.indexOf("${{", 0) == -1) {            return;        }         int startIndex = 0;        int b, e;        StringBuilder sb = new StringBuilder();        while ((b = pe.name.indexOf("${{", startIndex)) != -1) {            e = pe.name.indexOf("}}", b);            if (e < 1) {                break;            }            sb.append(pe.name.substring(startIndex, b));             // get the value in ${{...}}            String value = pe.name.substring(b+3, e);             // parse up to the first ':'            int colonIndex;            String prefix = value;            String suffix;            if ((colonIndex = value.indexOf(":")) != -1) {                prefix = value.substring(0, colonIndex);            }             // handle different prefix possibilities            if (prefix.equalsIgnoreCase("self")) {                // do nothing - handled later                sb.append(pe.name.substring(b, e+2));                startIndex = e+2;                continue;            } else if (prefix.equalsIgnoreCase("alias")) {                // get the suffix and perform keystore alias replacement                if (colonIndex == -1) {                    MessageFormat form = new MessageFormat                        (ResourcesMgr.getString                        ("alias.name.not.provided.pe.name."));                    Object[] source = {pe.name};                    throw new Exception(form.format(source));                }                suffix = value.substring(colonIndex+1);                if ((suffix = getDN(suffix, keystore)) == null) {                    MessageFormat form = new MessageFormat                        (ResourcesMgr.getString                        ("unable.to.perform.substitution.on.alias.suffix"));                    Object[] source = {value.substring(colonIndex+1)};                    throw new Exception(form.format(source));                }                 sb.append(X500PRINCIPAL + " \"" + suffix + "\"");                startIndex = e+2;            } else {                MessageFormat form = new MessageFormat                        (ResourcesMgr.getString                        ("substitution.value.prefix.unsupported"));                Object[] source = {prefix};                throw new Exception(form.format(source));            }        }         // copy the rest of the value        sb.append(pe.name.substring(startIndex));         // replace the name with expanded value        if (debug != null) {            debug.println("  Permission name expanded from:\n\t" +                        pe.name + "\nto\n\t" + sb.toString());        }        pe.name = sb.toString();    }     private String getDN(String alias, KeyStore keystore) {

Lines 1501–2000 of 2437. Previous lines