* 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 Load more
* 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) {