ONOS-1858, ONOS-1857, ONOS-1860, ONOS-1862, ONOS-1898 : SM-ONOS
Change-Id: I206e72521cf663466bfcc612e1896bb22d87da06
diff --git a/core/pom.xml b/core/pom.xml
index d48a58f..56dc848 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -36,6 +36,7 @@
<module>common</module>
<module>net</module>
<module>store</module>
+ <module>security</module>
</modules>
<dependencies>
diff --git a/core/security/impl/pom.xml b/core/security/impl/pom.xml
new file mode 100644
index 0000000..dd6e8db
--- /dev/null
+++ b/core/security/impl/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>onos-security</artifactId>
+ <groupId>org.onosproject</groupId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>bundle</packaging>
+
+ <artifactId>onos-security-impl</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.scr.annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-security-util</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.features</groupId>
+ <artifactId>org.apache.karaf.features.core</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/core/security/impl/src/main/java/org/onosproject/security/impl/PolicyBuilder.java b/core/security/impl/src/main/java/org/onosproject/security/impl/PolicyBuilder.java
new file mode 100644
index 0000000..bc21935
--- /dev/null
+++ b/core/security/impl/src/main/java/org/onosproject/security/impl/PolicyBuilder.java
@@ -0,0 +1,325 @@
+package org.onosproject.security.impl;
+
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.apache.commons.collections.FastHashMap;
+import org.onosproject.core.Permission;
+import org.onosproject.security.util.AppPermission;
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+import org.onosproject.app.ApplicationAdminService;
+import org.onosproject.app.ApplicationService;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.cluster.ClusterAdminService;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.core.CoreService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.mastership.MastershipAdminService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.device.DeviceAdminService;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.DeviceClockService;
+import org.onosproject.net.driver.DriverAdminService;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.host.HostAdminService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.HostClockService;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.IntentClockService;
+import org.onosproject.net.intent.PartitionService;
+import org.onosproject.net.link.LinkAdminService;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.proxyarp.ProxyArpService;
+import org.onosproject.net.resource.LabelResourceAdminService;
+import org.onosproject.net.resource.LinkResourceService;
+import org.onosproject.net.resource.LabelResourceService;
+import org.onosproject.net.statistic.StatisticService;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.net.topology.TopologyService;
+import org.onosproject.net.tunnel.TunnelAdminService;
+import org.onosproject.net.tunnel.TunnelService;
+import org.onosproject.store.service.StorageAdminService;
+import org.onosproject.store.service.StorageService;
+import org.osgi.framework.ServicePermission;
+import org.osgi.framework.PackagePermission;
+import org.osgi.framework.AdaptPermission;
+
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public final class PolicyBuilder {
+
+ private PolicyBuilder(){
+ }
+
+ public static PermissionInfo[] getApplicationPermissions(HashMap<Permission, Set<String>> serviceDirectory,
+ Set<Permission> permissions) {
+ Set<PermissionInfo> permSet = Sets.newHashSet();
+ Collections.addAll(permSet, getDefaultPerms());
+ for (Permission perm : permissions) {
+ permSet.add(new PermissionInfo(AppPermission.class.getName(), perm.name(), ""));
+ permSet.addAll(serviceDirectory.get(perm).stream().map(service -> new PermissionInfo(
+ ServicePermission.class.getName(), service, ServicePermission.GET)).collect(Collectors.toList()));
+ }
+ PermissionInfo[] permissionInfos = new PermissionInfo[permSet.size()];
+ return permSet.toArray(permissionInfos);
+ }
+
+ public static PermissionInfo[] getAdminApplicationPermissions(HashMap<Permission, Set<String>> serviceDirectory) {
+ Set<PermissionInfo> permSet = Sets.newHashSet();
+ Collections.addAll(permSet, getDefaultPerms());
+ Collections.addAll(permSet, getAdminDefaultPerms());
+ permSet.addAll(serviceDirectory.keySet().stream().map(perm ->
+ new PermissionInfo(AppPermission.class.getName(), perm.name(), "")).collect(Collectors.toList()));
+ PermissionInfo[] permissionInfos = new PermissionInfo[permSet.size()];
+ return permSet.toArray(permissionInfos);
+ }
+
+ public static PermissionInfo[] getDefaultPerms() {
+ return new PermissionInfo[]{
+ new PermissionInfo(PackagePermission.class.getName(), "*", PackagePermission.EXPORTONLY),
+ new PermissionInfo(PackagePermission.class.getName(), "*", PackagePermission.IMPORT),
+ new PermissionInfo(AdaptPermission.class.getName(), "*", AdaptPermission.ADAPT),
+ };
+ }
+ public static PermissionInfo[] getAdminDefaultPerms() {
+ return new PermissionInfo[]{
+ new PermissionInfo(ServicePermission.class.getName(),
+ ApplicationAdminService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ ClusterAdminService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ MastershipAdminService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ DeviceAdminService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ HostAdminService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ LinkAdminService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ DriverAdminService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ StorageAdminService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ LabelResourceAdminService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ TunnelAdminService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ ApplicationService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ ComponentConfigService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ CoreService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ ClusterService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ LeadershipService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ MastershipService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ DeviceService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ DeviceClockService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ DriverService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ FlowRuleService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ FlowObjectiveService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ GroupService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ HostService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ HostClockService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ IntentService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ IntentClockService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ IntentExtensionService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ PartitionService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ LinkService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ LinkResourceService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ LabelResourceService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ PacketService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ ProxyArpService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ StatisticService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ PathService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ TopologyService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ TunnelService.class.getName(), ServicePermission.GET),
+ new PermissionInfo(ServicePermission.class.getName(),
+ StorageService.class.getName(), ServicePermission.GET),
+ };
+ }
+
+
+ public static HashMap<Permission, Set<String>> getServiceDirectory() {
+
+ HashMap<Permission, Set<String>> serviceDirectory = new FastHashMap();
+
+ serviceDirectory.put(Permission.APP_READ, ImmutableSet.of(
+ ApplicationService.class.getName(), CoreService.class.getName()));
+ serviceDirectory.put(Permission.APP_EVENT, ImmutableSet.of(
+ ApplicationService.class.getName(), CoreService.class.getName()));
+ serviceDirectory.put(Permission.CONFIG_READ, ImmutableSet.of(
+ ComponentConfigService.class.getName()));
+ serviceDirectory.put(Permission.CONFIG_WRITE, ImmutableSet.of(
+ ComponentConfigService.class.getName()));
+ serviceDirectory.put(Permission.CLUSTER_READ, ImmutableSet.of(
+ ClusterService.class.getName(), LeadershipService.class.getName(),
+ MastershipService.class.getName()));
+ serviceDirectory.put(Permission.CLUSTER_WRITE, ImmutableSet.of(
+ LeadershipService.class.getName(), MastershipService.class.getName()));
+ serviceDirectory.put(Permission.CLUSTER_EVENT, ImmutableSet.of(
+ ClusterService.class.getName(), LeadershipService.class.getName(),
+ MastershipService.class.getName()));
+ serviceDirectory.put(Permission.DEVICE_READ, ImmutableSet.of(
+ DeviceService.class.getName(), DeviceClockService.class.getName()));
+ serviceDirectory.put(Permission.DEVICE_EVENT, ImmutableSet.of(
+ DeviceService.class.getName()));
+ serviceDirectory.put(Permission.DRIVER_READ, ImmutableSet.of(
+ DriverService.class.getName()));
+ serviceDirectory.put(Permission.DRIVER_WRITE, ImmutableSet.of(
+ DriverService.class.getName()));
+ serviceDirectory.put(Permission.FLOWRULE_READ, ImmutableSet.of(
+ FlowRuleService.class.getName()));
+ serviceDirectory.put(Permission.FLOWRULE_WRITE, ImmutableSet.of(
+ FlowRuleService.class.getName(), FlowObjectiveService.class.getName()));
+ serviceDirectory.put(Permission.FLOWRULE_EVENT, ImmutableSet.of(
+ FlowRuleService.class.getName()));
+ serviceDirectory.put(Permission.GROUP_READ, ImmutableSet.of(
+ GroupService.class.getName()));
+ serviceDirectory.put(Permission.GROUP_WRITE, ImmutableSet.of(
+ GroupService.class.getName()));
+ serviceDirectory.put(Permission.GROUP_EVENT, ImmutableSet.of(
+ GroupService.class.getName()));
+ serviceDirectory.put(Permission.HOST_READ, ImmutableSet.of(
+ HostService.class.getName(), HostClockService.class.getName()));
+ serviceDirectory.put(Permission.HOST_WRITE, ImmutableSet.of(
+ HostService.class.getName()));
+ serviceDirectory.put(Permission.HOST_EVENT, ImmutableSet.of(
+ HostService.class.getName()));
+ serviceDirectory.put(Permission.INTENT_READ, ImmutableSet.of(
+ IntentService.class.getName(), PartitionService.class.getName(),
+ IntentClockService.class.getName()));
+ serviceDirectory.put(Permission.INTENT_WRITE, ImmutableSet.of(
+ IntentService.class.getName()));
+ serviceDirectory.put(Permission.INTENT_EVENT, ImmutableSet.of(
+ IntentService.class.getName()));
+ serviceDirectory.put(Permission.LINK_READ, ImmutableSet.of(
+ LinkService.class.getName(), LinkResourceService.class.getName(),
+ LabelResourceService.class.getName()));
+ serviceDirectory.put(Permission.LINK_WRITE, ImmutableSet.of(
+ LinkResourceService.class.getName(), LabelResourceService.class.getName()));
+ serviceDirectory.put(Permission.LINK_EVENT, ImmutableSet.of(
+ LinkService.class.getName(), LinkResourceService.class.getName(),
+ LabelResourceService.class.getName()));
+ serviceDirectory.put(Permission.PACKET_READ, ImmutableSet.of(
+ PacketService.class.getName(), ProxyArpService.class.getName()));
+ serviceDirectory.put(Permission.PACKET_WRITE, ImmutableSet.of(
+ PacketService.class.getName(), ProxyArpService.class.getName()));
+ serviceDirectory.put(Permission.PACKET_EVENT, ImmutableSet.of(
+ PacketService.class.getName()));
+ serviceDirectory.put(Permission.STATISTIC_READ, ImmutableSet.of(
+ StatisticService.class.getName()));
+ serviceDirectory.put(Permission.TOPOLOGY_READ, ImmutableSet.of(
+ TopologyService.class.getName(), PathService.class.getName()));
+ serviceDirectory.put(Permission.TOPOLOGY_EVENT, ImmutableSet.of(
+ TopologyService.class.getName()));
+ serviceDirectory.put(Permission.TUNNEL_READ, ImmutableSet.of(
+ TunnelService.class.getName()));
+ serviceDirectory.put(Permission.TUNNEL_WRITE, ImmutableSet.of(
+ TunnelService.class.getName()));
+ serviceDirectory.put(Permission.TUNNEL_EVENT, ImmutableSet.of(
+ TunnelService.class.getName()));
+ serviceDirectory.put(Permission.STORAGE_WRITE, ImmutableSet.of(
+ StorageService.class.getName()));
+
+ return serviceDirectory;
+ }
+}
+
+
+// public static PermissionInfo[] getNonAdminPerms() {
+// return new PermissionInfo[]{
+// new PermissionInfo(PackagePermission.class.getName(), "*", PackagePermission.EXPORTONLY),
+// new PermissionInfo(PackagePermission.class.getName(), "*", PackagePermission.IMPORT),
+// new PermissionInfo(AdaptPermission.class.getName(), "*", AdaptPermission.ADAPT),
+// new PermissionInfo(ServicePermission.class.getName(),
+// ApplicationService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// ComponentConfigService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// CoreService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// ClusterService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// LeadershipService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// MastershipService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// DeviceService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// DeviceClockService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// DriverService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// FlowRuleService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// FlowObjectiveService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// GroupService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// HostService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// HostClockService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// IntentService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// IntentClockService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// IntentExtensionService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// PartitionService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// LinkService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// LinkResourceService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// LabelResourceService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// PacketService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// ProxyArpService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// StatisticService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// PathService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// TopologyService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// TunnelService.class.getName(), ServicePermission.GET),
+// new PermissionInfo(ServicePermission.class.getName(),
+// StorageService.class.getName(), ServicePermission.GET),
+// };
+// }
\ No newline at end of file
diff --git a/core/security/impl/src/main/java/org/onosproject/security/impl/SecurityModeManager.java b/core/security/impl/src/main/java/org/onosproject/security/impl/SecurityModeManager.java
new file mode 100644
index 0000000..dcca07c
--- /dev/null
+++ b/core/security/impl/src/main/java/org/onosproject/security/impl/SecurityModeManager.java
@@ -0,0 +1,263 @@
+package org.onosproject.security.impl;
+
+import org.apache.commons.collections.FastHashMap;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.karaf.features.BundleInfo;
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeaturesService;
+
+import org.onosproject.app.ApplicationAdminService;
+import org.onosproject.app.ApplicationEvent;
+import org.onosproject.app.ApplicationListener;
+import org.onosproject.app.ApplicationState;
+import org.onosproject.core.Application;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.Permission;
+import org.onosproject.security.util.AppPermission;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.PackagePermission;
+import org.osgi.framework.ServicePermission;
+import org.osgi.service.log.LogEntry;
+import org.osgi.service.log.LogListener;
+import org.osgi.service.log.LogReaderService;
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+import java.security.AccessControlException;
+import java.security.AllPermission;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.osgi.service.permissionadmin.PermissionAdmin;
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Security-Mode ONOS management implementation.
+ */
+
+//TODO : implement a dedicated distributed store for SM-ONOS
+
+@Component(immediate = true)
+public class SecurityModeManager {
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ApplicationAdminService appAdminService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FeaturesService featuresService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LogReaderService logReaderService;
+
+ private final Logger log = getLogger(getClass());
+
+ private SecurityBundleListener securityBundleListener = new SecurityBundleListener();
+
+ private SecurityApplicationListener securityApplicationListener = new SecurityApplicationListener();
+
+ private SecurityLogListener securityLogListener = new SecurityLogListener();
+
+ private Bundle bundle = null;
+
+ private BundleContext bundleContext = null;
+
+ private PermissionAdmin permissionAdmin = null;
+
+ private HashMap<String, ApplicationId> appTracker = null;
+
+ private HashMap<Permission, Set<String>> serviceDirectory = null;
+
+
+ @Activate
+ public void activate() {
+ if (System.getSecurityManager() == null) {
+ log.warn("J2EE security manager is disabled.");
+ deactivate();
+ return;
+ }
+ bundle = FrameworkUtil.getBundle(this.getClass());
+ bundleContext = bundle.getBundleContext();
+
+ bundleContext.addBundleListener(securityBundleListener);
+ appAdminService.addListener(securityApplicationListener);
+ logReaderService.addLogListener(securityLogListener);
+ appTracker = new FastHashMap();
+
+ permissionAdmin = getPermissionAdmin(bundleContext);
+ if (permissionAdmin == null) {
+ log.warn("Permission Admin not found.");
+ this.deactivate();
+ return;
+ }
+
+ serviceDirectory = PolicyBuilder.getServiceDirectory();
+
+ PermissionInfo[] allPerm = {
+ new PermissionInfo(AllPermission.class.getName(), "", ""), };
+
+ permissionAdmin.setPermissions(bundle.getLocation(), allPerm);
+ log.warn("Security-Mode Started");
+
+ }
+
+
+ @Deactivate
+ public void deactivate() {
+ bundleContext.removeBundleListener(securityBundleListener);
+ appAdminService.removeListener(securityApplicationListener);
+ logReaderService.removeLogListener(securityLogListener);
+ log.info("Stopped");
+
+ }
+
+ private class SecurityApplicationListener implements ApplicationListener {
+
+ @Override
+ public void event(ApplicationEvent event) {
+ //App needs to be restarted
+ if (event.type() == ApplicationEvent.Type.APP_PERMISSIONS_CHANGED) {
+ if (appAdminService.getState(event.subject().id()) == ApplicationState.ACTIVE) {
+ appAdminService.deactivate(event.subject().id());
+ print("Permissions updated (%s). Deactivating...",
+ event.subject().id().name());
+ }
+ }
+ }
+ }
+
+ private class SecurityBundleListener implements BundleListener {
+
+ @Override
+ public void bundleChanged(BundleEvent event) {
+ switch (event.getType()) {
+ case BundleEvent.INSTALLED:
+ setPermissions(event);
+ break;
+ case BundleEvent.UNINSTALLED:
+ clearPermissions(event);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private void clearPermissions(BundleEvent bundleEvent) {
+ if (appTracker.containsKey(bundleEvent.getBundle().getLocation())) {
+ permissionAdmin.setPermissions(bundleEvent.getBundle().getLocation(), new PermissionInfo[]{});
+ appTracker.remove(bundleEvent.getBundle().getLocation());
+ }
+ }
+
+ // find the location of the installed bundle and enforce policy
+ private void setPermissions(BundleEvent bundleEvent) {
+ for (Application app : appAdminService.getApplications()) {
+ if (getBundleLocations(app).contains(bundleEvent.getBundle().getLocation())) {
+ String location = bundleEvent.getBundle().getLocation();
+
+ Set<org.onosproject.core.Permission> permissions =
+ appAdminService.getPermissions(app.id());
+
+ //Permissions granted by user overrides the permissions specified in App.Xml file
+ if (permissions == null) {
+ permissions = app.permissions();
+ }
+
+ if (permissions.isEmpty()) {
+ print("Application %s has not been granted any permission.", app.id().name());
+ }
+
+ PermissionInfo[] perms = null;
+
+ switch (app.role()) {
+ case ADMIN:
+ perms = PolicyBuilder.getAdminApplicationPermissions(serviceDirectory);
+ break;
+ case REGULAR:
+ perms = PolicyBuilder.getApplicationPermissions(serviceDirectory, permissions);
+ break;
+ case UNSPECIFIED:
+ default:
+ //no role has been assigned.
+ perms = PolicyBuilder.getDefaultPerms();
+ log.warn("Application %s has no role assigned.", app.id().name());
+ break;
+ }
+ permissionAdmin.setPermissions(location, perms);
+ appTracker.put(location, app.id());
+ break;
+ }
+ }
+ }
+
+ //TODO: dispatch security policy violation event via distributed store
+ //immediately notify and deactivate the application upon policy violation
+ private class SecurityLogListener implements LogListener {
+ @Override
+ public void logged(LogEntry entry) {
+ if (entry != null) {
+ if (entry.getException() != null) {
+ ApplicationId applicationId = appTracker.get(entry.getBundle().getLocation());
+ if (applicationId != null) {
+ if (appAdminService.getState(applicationId).equals(ApplicationState.ACTIVE)) {
+ if (entry.getException() instanceof AccessControlException) {
+ java.security.Permission permission =
+ ((AccessControlException) entry.getException()).getPermission();
+ handleException(applicationId.name(), permission);
+ appAdminService.deactivate(applicationId);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void handleException(String name, java.security.Permission perm) {
+ if (perm instanceof ServicePermission || perm instanceof PackagePermission) {
+ print("%s has attempted to %s %s.", name, perm.getActions(), perm.getName());
+ } else if (perm instanceof AppPermission) {
+ print("%s has attempted to call an NB API that requires %s permission.",
+ name, perm.getName().toUpperCase());
+ } else {
+ print("%s has attempted to perform an action that requires %s", name, perm.toString());
+ }
+ print("POLICY VIOLATION: Deactivating %s.", name);
+
+ }
+ private void print(String format, Object... args) {
+ System.out.println(String.format("SM-ONOS: " + format, args));
+ log.warn(String.format(format, args));
+ }
+
+ private List<String> getBundleLocations(Application app) {
+ List<String> locations = new ArrayList();
+ for (String name : app.features()) {
+ try {
+ Feature feature = featuresService.getFeature(name);
+ locations.addAll(
+ feature.getBundles().stream().map(BundleInfo::getLocation).collect(Collectors.toList()));
+ } catch (Exception e) {
+ return locations;
+ }
+ }
+ return locations;
+ }
+
+ private PermissionAdmin getPermissionAdmin(BundleContext context) {
+ return (PermissionAdmin) context.getService(context.getServiceReference(PermissionAdmin.class.getName()));
+ }
+
+}
diff --git a/core/security/pom.xml b/core/security/pom.xml
new file mode 100644
index 0000000..984b04b
--- /dev/null
+++ b/core/security/pom.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>onos-core</artifactId>
+ <groupId>org.onosproject</groupId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>onos-security</artifactId>
+ <packaging>pom</packaging>
+ <modules>
+ <module>util</module>
+ <module>impl</module>
+ </modules>
+
+</project>
\ No newline at end of file
diff --git a/core/security/util/pom.xml b/core/security/util/pom.xml
new file mode 100644
index 0000000..a92beb6
--- /dev/null
+++ b/core/security/util/pom.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>onos-security</artifactId>
+ <groupId>org.onosproject</groupId>
+ <version>1.2.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>onos-security-util</artifactId>
+ <packaging>bundle</packaging>
+
+</project>
diff --git a/core/security/util/src/main/java/org/onosproject/security/util/AppGuard.java b/core/security/util/src/main/java/org/onosproject/security/util/AppGuard.java
new file mode 100644
index 0000000..f6808f6
--- /dev/null
+++ b/core/security/util/src/main/java/org/onosproject/security/util/AppGuard.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.security.util;
+
+/**
+ * Checks if the caller has the required permission to call each API.
+ */
+public final class AppGuard {
+
+ private AppGuard() {
+ }
+
+ public static boolean check(String perm) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ System.getSecurityManager().checkPermission(new AppPermission(perm));
+ }
+ return true;
+ }
+}
diff --git a/core/security/util/src/main/java/org/onosproject/security/util/AppPermission.java b/core/security/util/src/main/java/org/onosproject/security/util/AppPermission.java
new file mode 100644
index 0000000..c502764
--- /dev/null
+++ b/core/security/util/src/main/java/org/onosproject/security/util/AppPermission.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.security.util;
+
+import java.security.BasicPermission;
+
+/**
+ * Implementation of API access permission.
+ */
+public class AppPermission extends BasicPermission {
+
+ public AppPermission(String name) {
+ super(name.toUpperCase(), "");
+ }
+
+ public AppPermission(String name, String actions) {
+ super(name.toUpperCase(), actions);
+ }
+
+}