use of org.apache.felix.framework.ext.SecurityProvider in project felix by apache.
the class SecurityActivator method start.
public synchronized void start(BundleContext context) throws Exception {
PermissionAdminImpl pai = null;
SecureAction action = new SecureAction();
Permissions permissions = new Permissions(context, action);
File tmp = context.getDataFile("security" + File.separator + "tmp");
if ((tmp == null) || (!tmp.isDirectory() && !tmp.mkdirs())) {
throw new IOException("Can't create tmp dir.");
}
// TODO: log something if we can not clean-up the tmp dir
File[] old = tmp.listFiles();
if (old != null) {
for (int i = 0; i < old.length; i++) {
old[i].delete();
}
}
if ("TRUE".equalsIgnoreCase(getProperty(context, SecurityConstants.ENABLE_PERMISSIONADMIN_PROP, SecurityConstants.ENABLE_PERMISSIONADMIN_VALUE))) {
File cache = context.getDataFile("security" + File.separator + "pa.txt");
if ((cache == null) || (!cache.isFile() && !cache.createNewFile())) {
throw new IOException("Can't create cache file");
}
pai = new PermissionAdminImpl(permissions, new PropertiesCache(cache, tmp, action));
}
ConditionalPermissionAdminImpl cpai = null;
if ("TRUE".equalsIgnoreCase(getProperty(context, SecurityConstants.ENABLE_CONDPERMADMIN_PROP, SecurityConstants.ENABLE_CONDPERMADMIN_VALUE))) {
File cpaCache = context.getDataFile("security" + File.separator + "cpa.txt");
if ((cpaCache == null) || (!cpaCache.isFile() && !cpaCache.createNewFile())) {
throw new IOException("Can't create cache file");
}
LocalPermissions localPermissions = new LocalPermissions(permissions);
cpai = new ConditionalPermissionAdminImpl(permissions, new Conditions(action), localPermissions, new PropertiesCache(cpaCache, tmp, action), pai);
}
if ((pai != null) || (cpai != null)) {
String crlList = getProperty(context, SecurityConstants.CRL_FILE_PROP, SecurityConstants.CRL_FILE_VALUE);
String storeList = getProperty(context, SecurityConstants.KEYSTORE_FILE_PROP, SecurityConstants.KEYSTORE_FILE_VALUE);
String passwdList = getProperty(context, SecurityConstants.KEYSTORE_PASS_PROP, SecurityConstants.KEYSTORE_PASS_VALUE);
String typeList = getProperty(context, SecurityConstants.KEYSTORE_TYPE_PROP, SecurityConstants.KEYSTORE_TYPE_VALUE);
String osgi_keystores = getProperty(context, Constants.FRAMEWORK_TRUST_REPOSITORIES, null);
if (osgi_keystores != null) {
StringTokenizer tok = new StringTokenizer(osgi_keystores, File.pathSeparator);
if (storeList.length() == 0) {
storeList += "file:" + tok.nextToken();
passwdList += " ";
typeList += "JKS";
}
while (tok.hasMoreTokens()) {
storeList += "|file:" + tok.nextToken();
passwdList += "| ";
typeList += "|JKS";
}
}
StringTokenizer storeTok = new StringTokenizer(storeList, "|");
StringTokenizer passwdTok = new StringTokenizer(passwdList, "|");
StringTokenizer typeTok = new StringTokenizer(typeList, "|");
if ((storeTok.countTokens() != typeTok.countTokens()) || (passwdTok.countTokens() != storeTok.countTokens())) {
throw new BundleException("Each CACerts keystore must have one type and one passwd entry and vice versa.");
}
SecurityProvider provider = new SecurityProviderImpl(crlList, typeList, passwdList, storeList, pai, cpai, action, ((Felix) context.getBundle(0)).getLogger());
((Felix) context.getBundle(0)).setSecurityProvider(provider);
}
if (pai != null) {
context.registerService(PermissionAdmin.class.getName(), pai, null);
}
if (cpai != null) {
context.registerService(ConditionalPermissionAdmin.class.getName(), cpai, null);
}
}
use of org.apache.felix.framework.ext.SecurityProvider in project felix by apache.
the class Felix method init.
/**
* @see org.osgi.framework.launch.Framework#init(org.osgi.framework.FrameworkListener[])
*/
@Override
public void init(final FrameworkListener... listeners) throws BundleException {
// The system bundle can only be initialized if it currently isn't started.
acquireBundleLock(this, Bundle.INSTALLED | Bundle.RESOLVED | Bundle.STARTING | Bundle.ACTIVE);
try {
if ((getState() == Bundle.INSTALLED) || (getState() == Bundle.RESOLVED)) {
String security = (String) m_configMap.get(Constants.FRAMEWORK_SECURITY);
if (security != null) {
if (System.getSecurityManager() != null) {
throw new SecurityException("SecurityManager already installed");
}
security = security.trim();
if (Constants.FRAMEWORK_SECURITY_OSGI.equalsIgnoreCase(security) || (security.length() == 0)) {
System.setSecurityManager(m_securityManager = new SecurityManager());
} else {
try {
System.setSecurityManager(m_securityManager = (SecurityManager) Class.forName(security).newInstance());
} catch (Throwable t) {
SecurityException se = new SecurityException("Unable to install custom SecurityManager: " + security);
se.initCause(t);
throw se;
}
}
}
// Generate a framework UUID.
// Spec says we get a new UUID for each invocation of init().
m_configMutableMap.put(FelixConstants.FRAMEWORK_UUID, Util.randomUUID());
// Initialize event dispatcher.
m_dispatcher.startDispatching();
// Create the bundle cache, if necessary, so that we can reload any
// installed bundles.
m_cache = (BundleCache) m_configMutableMap.get(FelixConstants.FRAMEWORK_BUNDLECACHE_IMPL);
if (m_cache == null) {
try {
m_cache = new BundleCache(m_logger, m_configMap);
} catch (Exception ex) {
m_logger.log(Logger.LOG_ERROR, "Error creating bundle cache.", ex);
throw new BundleException("Error creating bundle cache.", ex);
}
}
// we need to flush the bundle cache.
if (getState() == Bundle.INSTALLED) {
String clean = (String) m_configMap.get(Constants.FRAMEWORK_STORAGE_CLEAN);
if ((clean != null) && clean.equalsIgnoreCase(Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT)) {
try {
m_cache.delete();
} catch (Exception ex) {
throw new BundleException("Unable to flush bundle cache.", ex);
}
}
}
// Initialize installed bundle data structures.
Map[] maps = new Map[] { new HashMap<String, BundleImpl>(1), new TreeMap<Long, BundleImpl>() };
m_uninstalledBundles = new ArrayList<BundleImpl>(0);
// Add the system bundle to the set of installed bundles.
maps[LOCATION_MAP_IDX].put(_getLocation(), this);
maps[IDENTIFIER_MAP_IDX].put(new Long(0), this);
m_installedBundles = maps;
// state to be set to RESOLVED.
try {
m_resolver.resolve(Collections.singleton(adapt(BundleRevision.class)), Collections.EMPTY_SET);
} catch (ResolutionException ex) {
// This should never happen.
throw new BundleException("Unresolved constraint in System Bundle:" + ex.getUnresolvedRequirements());
}
// Reload the cached bundles before creating and starting the
// system bundle, since we want all cached bundles to be reloaded
// when we activate the system bundle and any subsequent system
// bundle activators passed into the framework constructor.
BundleArchive[] archives = null;
// First get cached bundle identifiers.
try {
archives = m_cache.getArchives();
} catch (Exception ex) {
m_logger.log(Logger.LOG_ERROR, "Unable to list saved bundles.", ex);
archives = null;
}
// Create system bundle activator and bundle context so we can activate it.
setActivator(new SystemBundleActivator());
setBundleContext(new BundleContextImpl(m_logger, this, this));
boolean javaVersionChanged = handleJavaVersionChange();
// Now load all cached bundles.
for (int i = 0; (archives != null) && (i < archives.length); i++) {
try {
// Keep track of the max bundle ID currently in use since we
// will need to use this as our next bundle ID value if the
// persisted value cannot be read.
m_nextId = Math.max(m_nextId, archives[i].getId() + 1);
// it now.
if (archives[i].getPersistentState() == Bundle.UNINSTALLED) {
archives[i].closeAndDelete();
} else // Otherwise re-install the cached bundle.
{
// Install the cached bundle.
reloadBundle(archives[i], javaVersionChanged);
}
} catch (Exception ex) {
fireFrameworkEvent(FrameworkEvent.ERROR, this, ex);
try {
m_logger.log(Logger.LOG_ERROR, "Unable to re-install " + archives[i].getLocation(), ex);
} catch (Exception ex2) {
m_logger.log(Logger.LOG_ERROR, "Unable to re-install cached bundle.", ex);
}
// TODO: FRAMEWORK - Perhaps we should remove the cached bundle?
}
}
for (Bundle extension : m_extensionManager.resolveExtensionBundles(this)) {
m_extensionManager.startExtensionBundle(this, (BundleImpl) extension);
}
// Now that we have loaded all cached bundles and have determined the
// max bundle ID of cached bundles, we need to try to load the next
// bundle ID from persistent storage. In case of failure, we should
// keep the max value.
m_nextId = Math.max(m_nextId, loadNextId());
// The framework is now in its startup sequence.
setBundleStateAndNotify(this, Bundle.STARTING);
// Now it is possible for threads to wait for the framework to stop,
// so create a gate for that purpose.
m_shutdownGate = new ThreadGate();
// add framework listeners
if (listeners != null) {
for (final FrameworkListener fl : listeners) {
addFrameworkListener(this, fl);
}
}
// Start services
m_resolver.start();
m_fwkWiring.start();
m_fwkStartLevel.start();
try {
Felix.m_secureAction.startActivator(getActivator(), _getBundleContext());
} catch (Throwable ex) {
m_dispatcher.stopDispatching();
m_logger.log(Logger.LOG_ERROR, "Unable to start system bundle.", ex);
throw new RuntimeException("Unable to start system bundle.");
}
// We have to check with the security provider (if there is one).
// This is to avoid having bundles in the cache that have been tampered with
SecurityProvider sp = getFramework().getSecurityProvider();
if ((sp != null) && (System.getSecurityManager() != null)) {
boolean locked = acquireGlobalLock();
if (!locked) {
throw new BundleException("Unable to acquire the global lock to check the bundle.");
}
try {
for (Object bundle : m_installedBundles[IDENTIFIER_MAP_IDX].values()) {
try {
if (bundle != this) {
setBundleProtectionDomain(((BundleImpl) bundle).adapt(BundleRevisionImpl.class));
}
} catch (Exception ex) {
((BundleImpl) bundle).close();
maps = new Map[] { new HashMap<String, BundleImpl>(m_installedBundles[LOCATION_MAP_IDX]), new TreeMap<Long, BundleImpl>(m_installedBundles[IDENTIFIER_MAP_IDX]) };
maps[LOCATION_MAP_IDX].remove(((BundleImpl) bundle)._getLocation());
maps[IDENTIFIER_MAP_IDX].remove(new Long(((BundleImpl) bundle).getBundleId()));
m_installedBundles = maps;
m_logger.log(Logger.LOG_ERROR, "Bundle in cache doesn't pass security check anymore.", ex);
}
}
} finally {
// Always release the global lock.
releaseGlobalLock();
}
}
m_extensionManager.startPendingExtensionBundles(Felix.this);
m_fwkWiring.refreshBundles(null);
// up class lookup for the system bundle.
synchronized (m_systemBundleClassCache) {
m_systemBundleClassCache.clear();
}
}
} finally {
releaseBundleLock(this);
if (listeners != null) {
for (final FrameworkListener fl : listeners) {
removeFrameworkListener(this, fl);
}
}
}
}
use of org.apache.felix.framework.ext.SecurityProvider in project felix by apache.
the class Felix method setBundleProtectionDomain.
void setBundleProtectionDomain(BundleRevisionImpl revisionImpl) throws Exception {
Object certificates = null;
SecurityProvider sp = getFramework().getSecurityProvider();
if ((sp != null) && (System.getSecurityManager() != null)) {
BundleImpl bundleImpl = revisionImpl.getBundle();
sp.checkBundle(bundleImpl);
Map signers = (Map) sp.getSignerMatcher(bundleImpl, Bundle.SIGNERS_TRUSTED);
certificates = signers.keySet().toArray(new java.security.cert.Certificate[signers.size()]);
}
revisionImpl.setProtectionDomain(new BundleProtectionDomain(revisionImpl, certificates));
}
Aggregations