Add a way to get the cached bundle location for a bundle and remove support for signed bundles from the core (will be reintroduced as an extension bundle soon) FELIX-22.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@506753 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java b/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
index a1e0718..bbc08dc 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
@@ -1,4 +1,4 @@
-/*
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -19,7 +19,6 @@
package org.apache.felix.framework.cache;
import java.io.*;
-import java.util.Collection;
import org.apache.felix.framework.Logger;
import org.apache.felix.framework.util.ObjectInputStreamX;
@@ -94,7 +93,6 @@
private int m_startLevel = -1;
private long m_lastModified = -1;
private BundleRevision[] m_revisions = null;
- private Collection m_trustedCaCerts = null;
private long m_refreshCount = -1;
@@ -125,10 +123,8 @@
* @param is input stream from which to read the bundle content.
* @throws Exception if any error occurs.
**/
- public BundleArchive(
- Logger logger, File archiveRootDir, long id, String location, InputStream is,
- Collection trustedCaCerts)
- throws Exception
+ public BundleArchive(Logger logger, File archiveRootDir, long id,
+ String location, InputStream is) throws Exception
{
m_logger = logger;
m_archiveRootDir = archiveRootDir;
@@ -139,7 +135,6 @@
"Bundle ID cannot be less than or equal to zero.");
}
m_originalLocation = location;
- m_trustedCaCerts = trustedCaCerts;
// Save state.
initialize();
@@ -160,13 +155,11 @@
* @param id the bundle identifier associated with the archive.
* @throws Exception if any error occurs.
**/
- public BundleArchive(Logger logger, File archiveRootDir,
- Collection trustedCaCerts)
+ public BundleArchive(Logger logger, File archiveRootDir)
throws Exception
{
m_logger = logger;
m_archiveRootDir = archiveRootDir;
- m_trustedCaCerts = trustedCaCerts;
// Add a revision for each one that already exists in the file
// system. The file system might contain more than one revision
@@ -479,7 +472,7 @@
{
return m_lastModified;
}
-
+
// Get bundle last modification time file.
File lastModFile = new File(m_archiveRootDir, BUNDLE_LASTMODIFIED_FILE);
@@ -514,7 +507,7 @@
* @param lastModified The time of the last modification to set for
* this archive. According to the OSGi specification this time is
* set each time a bundle is installed, updated or uninstalled.
- *
+ *
* @throws Exception if any error occurs.
**/
public synchronized void setLastModified(long lastModified) throws Exception
@@ -773,16 +766,6 @@
return true;
}
- public synchronized java.security.cert.Certificate[] getCertificates()
- {
- return m_revisions[m_revisions.length -1].getCertificates();
- }
-
- public synchronized String[] getDNChains()
- {
- return m_revisions[m_revisions.length -1].getDNChains();
- }
-
private synchronized String getRevisionLocation(int revision) throws Exception
{
InputStream is = null;
@@ -1102,8 +1085,6 @@
throw ex;
}
- result.setTrustedCaCerts(m_trustedCaCerts);
-
return result;
}
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java b/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
index 8a6bdea..b48a070 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
@@ -1,4 +1,4 @@
-/*
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -85,17 +85,14 @@
private Logger m_logger = null;
private File m_profileDir = null;
private BundleArchive[] m_archives = null;
- private Collection m_trustedCaCerts = null;
private static SecureAction m_secureAction = new SecureAction();
- public BundleCache(PropertyResolver cfg, Logger logger,
- Collection trustedCaCerts)
+ public BundleCache(PropertyResolver cfg, Logger logger)
throws Exception
{
m_cfg = cfg;
m_logger = logger;
- m_trustedCaCerts = trustedCaCerts;
initialize();
}
@@ -147,8 +144,7 @@
{
// Create the archive and add it to the list of archives.
BundleArchive ba =
- new BundleArchive(m_logger, archiveRootDir, id, location, is,
- m_trustedCaCerts);
+ new BundleArchive(m_logger, archiveRootDir, id, location, is);
BundleArchive[] tmp = new BundleArchive[m_archives.length + 1];
System.arraycopy(m_archives, 0, tmp, 0, m_archives.length);
tmp[m_archives.length] = ba;
@@ -334,8 +330,7 @@
// Recreate the bundle archive.
try
{
- archiveList.add(
- new BundleArchive(m_logger, children[i], m_trustedCaCerts));
+ archiveList.add(new BundleArchive(m_logger, children[i]));
}
catch (Exception ex)
{
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java b/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
index cb3a9e7..608592b 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
@@ -1,4 +1,4 @@
-/*
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -48,11 +48,6 @@
private Logger m_logger;
private File m_revisionRootDir = null;
private String m_location = null;
- private Collection m_trustedCaCerts = null;
- private X509Certificate[] m_certificates = null;
- private String[] m_subjectDNChain = null;
- private boolean m_certInitDone = (System.getSecurityManager() == null);
- private boolean m_subjectDNInitDone = (System.getSecurityManager() == null);
/**
* <p>
@@ -175,707 +170,10 @@
**/
public abstract void dispose() throws Exception;
- protected void setTrustedCaCerts(Collection trustedCaCerts)
- {
- m_trustedCaCerts = trustedCaCerts;
- }
-
- public X509Certificate[] getCertificates()
- {
- if (m_certInitDone)
- {
- return m_certificates;
- }
-
- if (m_trustedCaCerts == null)
- {
- return null;
- }
-
- try
- {
- m_certificates = getRevisionCertificates();
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- // TODO: log this or something
- }
- finally
- {
- m_certInitDone = true;
- }
-
- return m_certificates;
- }
-
- protected abstract X509Certificate[] getRevisionCertificates() throws Exception;
-
- public String[] getDNChains()
- {
- if (m_subjectDNInitDone)
- {
- return m_subjectDNChain;
- }
-
- try
- {
- X509Certificate[] certificates = getCertificates();
-
- if (certificates == null)
- {
- return null;
- }
-
- List rootChains = new ArrayList();
-
- getRootChains(certificates, rootChains);
-
- List result = new ArrayList();
-
- for (Iterator rootIter = rootChains.iterator();rootIter.hasNext();)
- {
- StringBuffer buffer = new StringBuffer();
-
- List chain = (List) rootIter.next();
-
- Iterator iter = chain.iterator();
-
- X509Certificate current = (X509Certificate) iter.next();
-
- try
- {
- buffer.append(parseSubjectDN(current.getTBSCertificate()));
-
- while (iter.hasNext())
- {
- buffer.append(';');
-
- current = (X509Certificate) iter.next();
-
- buffer.append(parseSubjectDN(current.getTBSCertificate()));
- }
-
- result.add(buffer.toString());
-
- }
- catch (Exception ex)
- {
- // something went wrong during parsing -
- // it might be that the cert contained an unsupported OID
- ex.printStackTrace();
- // TODO: log this or something
- }
- }
-
- if (!result.isEmpty())
- {
- m_subjectDNChain = (String[]) result.toArray(new String[result.size()]);
- }
- }
- finally
- {
- m_subjectDNInitDone = true;
- }
-
- return m_subjectDNChain;
- }
-
- protected X509Certificate[] getCertificatesForJar(JarFile bundle)
- throws Exception
- {
- if (bundle.getManifest() == null)
- {
- return null;
- }
-
- List bundleEntries = new ArrayList();
-
- Enumeration entries = bundle.entries();
-
- while (entries.hasMoreElements())
- {
- JarEntry entry = (JarEntry) entries.nextElement();
- bundleEntries.add(entry);
- InputStream is = bundle.getInputStream(entry);
- byte[] read = new byte[4096];
- while (is.read(read) != -1)
- {
- // read the entry
- }
- is.close();
- }
- bundle.close();
-
- List certificateChains = new ArrayList();
-
- for (Iterator iter = bundleEntries.iterator();iter.hasNext();)
- {
- JarEntry entry = (JarEntry) iter.next();
-
- if (entry.isDirectory() || entry.getName().startsWith("META-INF"))
- {
- continue;
- }
-
- Certificate[] certificates = entry.getCertificates();
-
- if ((certificates == null) || (certificates.length == 0))
- {
- return null;
- }
-
- List chains = new ArrayList();
-
- getRootChains(certificates, chains);
-
- if (certificateChains.isEmpty())
- {
- certificateChains.addAll(chains);
- }
- else
- {
- for (Iterator iter2 = certificateChains.iterator();iter2.hasNext();)
- {
- X509Certificate cert = (X509Certificate) ((List) iter2.next()).get(0);
- boolean found = false;
- for (Iterator iter3 = chains.iterator();iter3.hasNext();)
- {
- X509Certificate cert2 = (X509Certificate) ((List) iter3.next()).get(0);
-
- if (cert.getSubjectDN().equals(cert2.getSubjectDN()) && cert.equals(cert2))
- {
- found = true;
- break;
- }
- }
- if (!found)
- {
- iter2.remove();
- }
- }
- }
-
- if (certificateChains.isEmpty())
- {
- return null;
- }
- }
-
- List result = new ArrayList();
-
- for (Iterator iter = certificateChains.iterator();iter.hasNext();)
- {
- result.addAll((List) iter.next());
- }
-
- return (X509Certificate[]) result.toArray(new X509Certificate[result.size()]);
- }
-
- protected void getRootChains(Certificate[] certificates, List chains)
- {
- List chain = new ArrayList();
-
- for (int i = 0; i < certificates.length - 1; i++)
- {
- chain.add(certificates[i]);
- if (!((X509Certificate)certificates[i + 1]).getSubjectDN().equals(
- ((X509Certificate)certificates[i]).getIssuerDN()))
- {
-
- if (trusted((X509Certificate) certificates[i]))
- {
- chains.add(chain);
- }
-
- chain = new ArrayList();
- }
- }
- // The final entry in the certs array is always
- // a "root" certificate
- chain.add(certificates[certificates.length - 1]);
-
- if (trusted((X509Certificate) certificates[certificates.length - 1]))
- {
- chains.add(chain);
- }
- }
-
- // @return true if
- // m_trustedCaCerts.contains(cert) || cert issued by any of m_trustedCaCerts
- protected boolean trusted(X509Certificate cert)
- {
- if (m_trustedCaCerts == null)
- {
- return false;
- }
-
- // m_trustedCaCerts.contains(cert) ? return true
- for (Iterator iter = m_trustedCaCerts.iterator();iter.hasNext();)
- {
- X509Certificate trustedCaCert = (X509Certificate) iter.next();
-
- // If the cert has the same SubjectDN
- // as a trusted CA, check whether
- // the two certs are the same.
- if (cert.getSubjectDN().equals(trustedCaCert.getSubjectDN()))
- {
- if (cert.equals(trustedCaCert))
- {
- try
- {
- cert.checkValidity();
- trustedCaCert.checkValidity();
- return true;
- }
- catch (CertificateException ex)
- {
- System.err.println("WARNING: Invalid certificate [" + ex + "]");
- }
- }
- }
- }
-
- // cert issued by any of m_trustedCaCerts ? return true : return false
- for (Iterator iter = m_trustedCaCerts.iterator();iter.hasNext();)
- {
- X509Certificate trustedCaCert = (X509Certificate) iter.next();
-
- if (cert.getIssuerDN().equals(trustedCaCert.getSubjectDN()))
- {
- try
- {
- cert.verify(trustedCaCert.getPublicKey());
- cert.checkValidity();
- trustedCaCert.checkValidity();
- return true;
- }
- catch (Exception ex)
- {
- System.err.println("WARNING: Invalid certificate [" + ex + "]");
- }
- }
- }
-
- return false;
- }
-
- /*
- * This is deep magiK, bare with me. The problem is that we don't get
- * access to the original subject dn in a certificate without resorting to
- * sun.* classes or running on something > OSGi-minimum/jdk1.3. Furthermore,
- * we need access to it because there is no other way to escape it properly.
- * Note, this is due to missing of a public X500Name in OSGI-minimum/jdk1.3
- * a.k.a foundation.
+ /**
+ * Returns the url of the cached bundle if possible.
*
- * The solution is to get the DER encoded TBS certificate bytes via the
- * available java methods and parse-out the subject dn in canonical form by
- * hand. This is possible without deploying a full-blown BER encoder/decoder
- * due to java already having done all the cumbersome verification and
- * normalization work.
- *
- * The following skips through the TBS certificate bytes until it reaches and
- * subsequently parses the subject dn. If the below makes immediate sense to
- * you - you either are a X509/X501/DER expert or quite possibly mad. In any
- * case, please seek medical care immediately.
+ * @return the url of the cached bundle as a string or null if not possible.
*/
- protected String parseSubjectDN(byte[] tbsCertEncoded) throws Exception
- {
- // init
- tbs_buffer = tbsCertEncoded;
- tbs_offset = 0;
-
- try // this is a finally block that resets the tbs_buffer to null after we're done
- {
- // TBSCertificate ::= SEQUENCE {
- // version [0] EXPLICIT Version DEFAULT v1,
- // serialNumber CertificateSerialNumber,
- // signature AlgorithmIdentifier,
- // issuer Name,
- // validity Validity,
- // subject Name,
- //
- // WE CAN STOP!
- //
- // subjectPublicKeyInfo SubjectPublicKeyInfo,
- // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
- // -- If present, version must be v2 or v3
- // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
- // -- If present, version must be v2 or v3
- // extensions [3] EXPLICIT Extensions OPTIONAL
- // -- If present, version must be v3
- // }
-
- next();
- next();
- // if a version is present skip it
- if (tbs_tag == 0)
- {
- next();
- tbs_offset += tbs_length;
- }
- tbs_offset += tbs_length;
- // skip the serialNumber
- next();
- next();
- tbs_offset += tbs_length;
- // skip the signature
- next();
- tbs_offset += tbs_length;
- // skip the issuer
- // The issuer is a sequence of sets of issuer dns like the subject later on -
- // we just skip it.
- next();
- int endOffset = tbs_offset + tbs_length;
-
- int seqTagOffset = tbs_tagOffset;
-
- // skip the sequence
- while (endOffset > tbs_offset)
- {
- next();
-
- int endOffset2 = tbs_offset + tbs_length;
-
- int seqTagOffset2 = tbs_tagOffset;
-
- // skip each set
- while (endOffset2 > tbs_offset)
- {
- next();
- next();
- tbs_offset += tbs_length;
- next();
- tbs_offset += tbs_length;
- }
-
- tbs_tagOffset = seqTagOffset2;
- }
-
- tbs_tagOffset = seqTagOffset;
- // skip the validity which contains two dates to be skiped
- next();
- next();
- tbs_offset += tbs_length;
- next();
- tbs_offset += tbs_length;
- next();
- // Now extract the subject dns and add them to attributes
- List attributes = new ArrayList();
-
- endOffset = tbs_offset + tbs_length;
-
- seqTagOffset = tbs_tagOffset;
-
- // for each set of rdns
- while (endOffset > tbs_offset)
- {
- next();
- int endOffset2 = tbs_offset + tbs_length;
-
- // store tag offset
- int seqTagOffset2 = tbs_tagOffset;
-
- List rdn = new ArrayList();
-
- // for each rdn in the set
- while (endOffset2 > tbs_offset)
- {
- next();
- next();
- tbs_offset += tbs_length;
- // parse the oid of the rdn
- int oidElement = 1;
- for (int i = 0; i < tbs_length; i++, ++oidElement)
- {
- while ((tbs_buffer[tbs_contentOffset + i] & 0x80) == 0x80)
- {
- i++;
- }
- }
- int[] oid = new int[oidElement];
- for (int id = 1, i = 0; id < oid.length; id++, i++)
- {
- int octet = tbs_buffer[tbs_contentOffset + i];
- oidElement = octet & 0x7F;
- while ((octet & 0x80) != 0)
- {
- i++;
- octet = tbs_buffer[tbs_contentOffset + i];
- oidElement = oidElement << 7 | (octet & 0x7f);
- }
- oid[id] = oidElement;
- }
- // The first OID is special
- if (oid[1] > 79)
- {
- oid[0] = 2;
- oid[1] = oid[1] - 80;
- }
- else
- {
- oid[0] = oid[1] / 40;
- oid[1] = oid[1] % 40;
- }
- // Now parse the value of the rdn
- next();
- String str = null;
- int tagTmp = tbs_tag;
- tbs_offset += tbs_length;
- switch(tagTmp)
- {
- case 30: // BMPSTRING
- case 22: // IA5STRING
- case 27: // GENERALSTRING
- case 19: // PRINTABLESTRING
- case 20: // TELETEXSTRING && T61STRING
- case 28: // UNIVERSALSTRING
- str = new String(tbs_buffer, tbs_contentOffset,
- tbs_length);
- break;
- case 12: // UTF8_STRING
- str = new String(tbs_buffer, tbs_contentOffset,
- tbs_length, "UTF-8");
- break;
- default: // OCTET
- byte[] encoded = new byte[tbs_offset - tbs_tagOffset];
- System.arraycopy(tbs_buffer, tbs_tagOffset, encoded,
- 0, encoded.length);
- // Note, I'm not sure this is allowed by the spec
- // i.e., whether OCTET subjects are allowed at all
- // but it shouldn't harm doing it anyways (we just
- // convert it into a hex string prefixed with \#).
- str = toHexString(encoded);
- break;
- }
-
- rdn.add(new Object[]{mapOID(oid), makeCanonical(str)});
- }
-
- attributes.add(rdn);
- tbs_tagOffset = seqTagOffset2;
- }
-
- tbs_tagOffset = seqTagOffset;
-
- StringBuffer result = new StringBuffer();
-
- for (int i = attributes.size() - 1; i >= 0; i--)
- {
- List rdn = (List) attributes.get(i);
- Collections.sort(rdn, new Comparator()
- {
- public int compare(Object obj1, Object obj2)
- {
- return ((String) ((Object[]) obj1)[0]).compareTo(
- ((String) ((Object[])obj2)[0]));
- }
- });
-
- for (Iterator iter = rdn.iterator();iter.hasNext();)
- {
- Object[] att = (Object[]) iter.next();
- result.append((String) att[0]);
- result.append('=');
- result.append((String) att[1]);
-
- if (iter.hasNext())
- {
- // multi-valued RDN
- result.append('+');
- }
- }
-
- if (i != 0)
- {
- result.append(',');
- }
- }
-
- // the spec says:
- // return result.toString().toUpperCase(Locale.US).toLowerCase(Locale.US);
- // but that doesn't make no sense to me whatsoever hence,
- return result.toString().toLowerCase(Locale.US);
- }
- finally
- {
- tbs_buffer = null;
- }
- }
-
- private byte[] tbs_buffer = null;
- private int tbs_offset = 0;
- private int tbs_tagOffset = 0;
- private int tbs_tag = -1;
- private int tbs_length = -1;
- private int tbs_contentOffset = -1;
-
- // Determine the type of the current sequence (tbs_tab), and the length and
- // offset of it (tbs_length and tbs_tagOffset) plus increment the global
- // offset (tbs_offset) accordingly. Note, we don't need to check for
- // the indefinite length because this is supposed to be DER not BER (and
- // we implicitly assume that java only gives us valid DER).
- private void next()
- {
- tbs_tagOffset = tbs_offset;
- tbs_tag = tbs_buffer[tbs_offset++] & 0xFF;
- tbs_length = tbs_buffer[tbs_offset++] & 0xFF;
- // There are two kinds of length forms - make sure we use the right one
- if ((tbs_length & 0x80) != 0)
- {
- // its the long kind
- int numOctets = tbs_length & 0x7F;
- // hence, convert it
- tbs_length = tbs_buffer[tbs_offset++] & 0xFF;
- for (int i = 1; i < numOctets; i++)
- {
- int ch = tbs_buffer[tbs_offset++] & 0xFF;
- tbs_length = (tbs_length << 8) + ch;
- }
- }
- tbs_contentOffset = tbs_offset;
- }
-
- private String makeCanonical(String value)
- {
- int len = value.length();
-
- if (len == 0)
- {
- return value;
- }
-
- StringBuffer result = new StringBuffer(len);
-
- int i = 0;
- if (value.charAt(0) == '#')
- {
- result.append('\\');
- result.append('#');
- i++;
- }
- for (;i < len; i++)
- {
- char c = value.charAt(i);
-
- switch (c)
- {
- case ' ':
- int pos = result.length();
- // remove leading spaces and
- // remove all spaces except one in any sequence of spaces
- if ((pos == 0) || (result.charAt(pos - 1) == ' '))
- {
- break;
- }
- result.append(' ');
- break;
- case '"':
- case '\\':
- case ',':
- case '+':
- case '<':
- case '>':
- case ';':
- result.append('\\');
- default:
- result.append(c);
- }
- }
-
- // count down until first none space to remove trailing spaces
- i = result.length() - 1;
- while ((i > -1) && (result.charAt(i) == ' '))
- {
- i--;
- }
-
- result.setLength(i + 1);
-
- return result.toString();
- }
-
- private String toHexString(byte[] encoded)
- {
- StringBuffer result = new StringBuffer();
-
- result.append('#');
-
- for (int i = 0; i < encoded.length; i++)
- {
- int c = (encoded[i] >> 4) & 0x0F;
- if (c < 10)
- {
- result.append((char) (c + 48));
- }
- else
- {
- result.append((char) (c + 87));
- }
-
- c = encoded[i] & 0x0F;
-
- if (c < 10)
- {
- result.append((char) (c + 48));
- }
- else
- {
- result.append((char) (c + 87));
- }
- }
-
- return result.toString();
- }
-
- private static final Map OID2NAME = new HashMap();
-
- static
- {
- // see core-spec 2.3.5
- OID2NAME.put("2.5.4.3", "cn");
- OID2NAME.put("2.5.4.4", "sn");
- OID2NAME.put("2.5.4.6", "c");
- OID2NAME.put("2.5.4.7", "l");
- OID2NAME.put("2.5.4.8", "st");
- OID2NAME.put("2.5.4.10", "o");
- OID2NAME.put("2.5.4.11", "ou");
- OID2NAME.put("2.5.4.12", "title");
- OID2NAME.put("2.5.4.42", "givenname");
- OID2NAME.put("2.5.4.43", "initials");
- OID2NAME.put("2.5.4.44", "generationqualifier");
- OID2NAME.put("2.5.4.46", "dnqualifier");
- OID2NAME.put("2.5.4.9", "street");
- OID2NAME.put("0.9.2342.19200300.100.1.25", "dc");
- OID2NAME.put("0.9.2342.19200300.100.1.1", "uid");
- OID2NAME.put("1.2.840.113549.1.9.1", "emailaddress");
- OID2NAME.put("2.5.4.5", "serialnumber");
- // p.s.: it sucks that the spec doesn't list some of the oids used
- // p.p.s: it sucks that the spec doesn't list the short form for all names
- // In summary, there is a certain amount of guess-work involved but I'm
- // fairly certain I've got it right.
- }
-
- // This just creates a string of the oid and looks for its name in the
- // known names map OID2NAME. There might be faster implementations :-)
- private String mapOID(int[] oid)
- {
- StringBuffer oidString = new StringBuffer();
-
- oidString.append(oid[0]);
- for (int i = 1;i < oid.length;i++)
- {
- oidString.append('.');
- oidString.append(oid[i]);
- }
-
- String result = (String) OID2NAME.get(oidString.toString());
-
- if (result == null)
- {
- throw new IllegalArgumentException("Unknown oid: " + oidString.toString());
- }
-
- return result;
- }
+ public abstract String getCachedBundleURL();
}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
index 996e535..a686feb 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
@@ -1,4 +1,4 @@
-/*
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -19,6 +19,7 @@
package org.apache.felix.framework.cache;
import java.io.*;
+import java.net.MalformedURLException;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.jar.*;
@@ -183,180 +184,16 @@
// by the parent bundle archive.
}
- protected X509Certificate[] getRevisionCertificates() throws Exception
+ public String getCachedBundleURL()
{
- File tmp = new File(getRevisionRootDir(), BUNDLE_JAR_FILE);
-
- if (BundleCache.getSecureAction().fileExists(tmp))
- {
- BundleCache.getSecureAction().deleteFile(tmp);
- }
-
try
{
- BundleCache.copyStreamToFile(new RevisionToInputStream(m_refDir),
- tmp);
-
- JarFile bundle = BundleCache.getSecureAction().openJAR(tmp);
-
- return getCertificatesForJar(bundle);
+ return m_refDir.toURL().toString();
}
- finally
+ catch (MalformedURLException ex)
{
- try
- {
- if (BundleCache.getSecureAction().fileExists(tmp))
- {
- BundleCache.getSecureAction().deleteFile(tmp);
- }
- }
- catch (Exception e)
- {
- // Not much we can do
- }
- }
- }
-
- private class RevisionToInputStream extends InputStream
- {
- class OutputStreamBuffer extends OutputStream
- {
- ByteArrayOutputStream outBuffer = null;
-
- public void write(int b)
- {
- outBuffer.write(b);
- }
- }
-
- private File m_revisionDir = null;
- private File[] m_content = null;
- private File m_manifest = null;
- private ByteArrayInputStream m_buffer = null;
- private int m_current = 0;
- private OutputStreamBuffer m_outputBuffer = new OutputStreamBuffer();
- private JarOutputStream m_output = null;
-
- RevisionToInputStream(File revisionDir) throws IOException
- {
- m_revisionDir = revisionDir;
-
- m_outputBuffer.outBuffer = new ByteArrayOutputStream();
-
- m_manifest = new File(m_revisionDir, "META-INF/MANIFEST.MF");
-
- m_output = new JarOutputStream(m_outputBuffer);
-
- readNext(m_manifest, false);
-
- m_content = listFilesRecursive(revisionDir);
- }
-
- private File[] listFilesRecursive(File dir)
- {
- File[] children = BundleCache.getSecureAction().listDirectory(dir);
- File[] combined = children;
- for (int i = 0; i < children.length; i++)
- {
- if (BundleCache.getSecureAction().isFileDirectory(children[i]))
- {
- File[] grandchildren = listFilesRecursive(children[i]);
- if (grandchildren.length > 0)
- {
- File[] tmp = new File[combined.length + grandchildren.length];
- System.arraycopy(combined, 0, tmp, 0, combined.length);
- System.arraycopy(grandchildren, 0, tmp, combined.length, grandchildren.length);
- combined = tmp;
- }
- }
- }
- return combined;
- }
-
- private boolean readNext(File file, boolean close) throws IOException
- {
- if (BundleCache.getSecureAction().isFileDirectory(file))
- {
- return false;
- }
-
- m_outputBuffer.outBuffer = new ByteArrayOutputStream();
-
- InputStream in = null;
- try
- {
- in = BundleCache.getSecureAction().getFileInputStream(file);
-
- JarEntry entry = new JarEntry(
- file.getPath().substring(m_revisionDir.getPath().length() + 1));
-
-
- m_output.putNextEntry(entry);
-
- int c = -1;
-
- while ((c = in.read()) != -1)
- {
- m_output.write(c);
- }
- }
- finally
- {
- if (in != null)
- {
- in.close();
- }
- }
-
- m_output.closeEntry();
-
- m_output.flush();
-
- if (close)
- {
- m_output.close();
- m_output = null;
- }
-
- m_buffer = new ByteArrayInputStream(m_outputBuffer.outBuffer.toByteArray());
-
- m_outputBuffer.outBuffer = null;
-
- return true;
- }
-
- public int read() throws IOException
- {
- if ((m_output == null) && (m_buffer == null))
- {
- return -1;
- }
-
- if (m_buffer != null)
- {
- int result = m_buffer.read();
-
- if (result == -1)
- {
- m_buffer = null;
- return read();
- }
- else
- {
- return result;
- }
- }
-
- while ((m_current < m_content.length) &&
- (m_content[m_current].equals(m_manifest) ||
- !readNext(m_content[m_current], (m_current + 1) == m_content.length)))
- {
- m_current++;
- }
-
- m_current++;
-
- return read();
+ // This should never happen.
+ return null;
}
}
}
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java b/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
index efc2bb3..c7306af 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
@@ -1,4 +1,4 @@
-/*
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -19,8 +19,7 @@
package org.apache.felix.framework.cache;
import java.io.*;
-import java.net.URL;
-import java.net.URLConnection;
+import java.net.*;
import java.security.PrivilegedActionException;
import java.security.cert.X509Certificate;
import java.util.*;
@@ -253,6 +252,19 @@
// by the parent bundle archive.
}
+ public String getCachedBundleURL()
+ {
+ try
+ {
+ return m_bundleFile.toURL().toString();
+ }
+ catch (MalformedURLException ex)
+ {
+ // This should never happen.
+ return null;
+ }
+ }
+
//
// Private methods.
//
@@ -449,9 +461,4 @@
}
}
}
-
- protected X509Certificate[] getRevisionCertificates() throws Exception
- {
- return getCertificatesForJar(BundleCache.getSecureAction().openJAR(m_bundleFile, true));
- }
}
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/SystemBundleArchive.java b/framework/src/main/java/org/apache/felix/framework/cache/SystemBundleArchive.java
index 9441340..d3ebc81 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/SystemBundleArchive.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/SystemBundleArchive.java
@@ -1,4 +1,4 @@
-/*
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -69,6 +69,11 @@
{
}
+ public String getCachedBundleURL()
+ {
+ return null;
+ }
+
protected X509Certificate[] getRevisionCertificates()
{
return null;
diff --git a/framework/src/main/java/org/osgi/framework/AdminPermission.java b/framework/src/main/java/org/osgi/framework/AdminPermission.java
index 08bd714..e03a6e8 100644
--- a/framework/src/main/java/org/osgi/framework/AdminPermission.java
+++ b/framework/src/main/java/org/osgi/framework/AdminPermission.java
@@ -18,11 +18,12 @@
*/
package org.osgi.framework;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.security.*;
import java.util.*;
import org.apache.felix.framework.FilterImpl;
-import org.apache.felix.framework.SignerMatcher;
/**
* <p>
@@ -32,17 +33,17 @@
**/
public final class AdminPermission extends BasicPermission
{
- static final long serialVersionUID = 307051004521261705L;
+ static final long serialVersionUID = 307051004521261705L;
- public static final String CLASS = "class";
- public static final String EXECUTE = "execute";
- public static final String EXTENSIONLIFECYCLE = "extensionLifecycle";
- public static final String LIFECYCLE = "lifecycle";
- public static final String LISTENER = "listener";
- public static final String METADATA = "metadata";
- public static final String RESOLVE = "resolve";
- public static final String RESOURCE = "resource";
- public static final String STARTLEVEL = "startlevel";
+ public static final String CLASS = "class";
+ public static final String EXECUTE = "execute";
+ public static final String EXTENSIONLIFECYCLE = "extensionLifecycle";
+ public static final String LIFECYCLE = "lifecycle";
+ public static final String LISTENER = "listener";
+ public static final String METADATA = "metadata";
+ public static final String RESOLVE = "resolve";
+ public static final String RESOURCE = "resource";
+ public static final String STARTLEVEL = "startlevel";
private static final int CLASS_MASK = 1;
private static final int EXECUTE_MASK = 2;
@@ -76,7 +77,7 @@
public AdminPermission()
{
this("*", ALL_MASK);
- }
+ }
// This constructor is only used when checking a granted admin permission.
public AdminPermission(Bundle bundle, String actions)
@@ -101,43 +102,43 @@
m_actionMask = actionMask;
}
- public boolean equals(Object obj)
+ public boolean equals(Object obj)
{
- if (obj == this)
+ if (obj == this)
{
- return true;
- }
-
- if (!(obj instanceof AdminPermission))
- {
- return false;
- }
-
- AdminPermission p = (AdminPermission) obj;
-
- return getName().equals(p.getName()) && (m_actionMask == p.m_actionMask);
+ return true;
}
- public int hashCode()
- {
- return getName().hashCode() ^ getActions().hashCode();
+ if (!(obj instanceof AdminPermission))
+ {
+ return false;
}
- public String getActions()
+ AdminPermission p = (AdminPermission) obj;
+
+ return getName().equals(p.getName()) && (m_actionMask == p.m_actionMask);
+ }
+
+ public int hashCode()
+ {
+ return getName().hashCode() ^ getActions().hashCode();
+ }
+
+ public String getActions()
{
if (m_actions == null)
{
m_actions = createActionString(m_actionMask);
}
- return m_actions;
- }
+ return m_actions;
+ }
- public boolean implies(Permission p)
+ public boolean implies(Permission p)
{
- if (!(p instanceof AdminPermission))
+ if (!(p instanceof AdminPermission))
{
- return false;
- }
+ return false;
+ }
AdminPermission admin = (AdminPermission) p;
@@ -185,12 +186,12 @@
}
return m_filterImpl.match(admin.getBundleDictionary());
- }
+ }
- public PermissionCollection newPermissionCollection()
+ public PermissionCollection newPermissionCollection()
{
- return new AdminPermissionCollection();
- }
+ return new AdminPermissionCollection();
+ }
private Dictionary getBundleDictionary()
{
@@ -213,6 +214,8 @@
public Object run()
{
m_bundleDict.put("location", m_bundle.getLocation());
+
+ createSigner(m_bundle, m_bundleDict);
return null;
}
});
@@ -220,13 +223,34 @@
else
{
m_bundleDict.put("location", m_bundle.getLocation());
+ createSigner(m_bundle, m_bundleDict);
}
-
- m_bundleDict.put("signer", new SignerMatcher(m_bundle));
}
return m_bundleDict;
}
+ private static void createSigner(Bundle bundle, Dictionary dict)
+ {
+ try
+ {
+ Method method = bundle.getClass().getDeclaredMethod(
+ "getSignerMatcher", null);
+ method.setAccessible(true);
+
+ Object signer = method.invoke(bundle, null);
+
+ if (signer != null)
+ {
+ dict.put("signer", signer);
+ }
+ }
+ catch (Exception ex)
+ {
+// TODO: log this or something
+ ex.printStackTrace();
+ }
+ }
+
private static int parseActions(String actions)
{
if (actions == null)
@@ -365,8 +389,8 @@
final class AdminPermissionCollection extends PermissionCollection
{
- private static final long serialVersionUID = 3747361397420496672L;
- private HashMap m_map = new HashMap();
+ private static final long serialVersionUID = 3747361397420496672L;
+ private HashMap m_map = new HashMap();
public void add(Permission permission)
{