Committed by
Gerrit Code Review
ONOS-1858, ONOS-1857, ONOS-1860, ONOS-1862, ONOS-1898 : SM-ONOS
Change-Id: I206e72521cf663466bfcc612e1896bb22d87da06
Showing
14 changed files
with
723 additions
and
0 deletions
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.cli.security; | ||
18 | + | ||
19 | +import org.apache.karaf.shell.console.completer.StringsCompleter; | ||
20 | +import org.onosproject.app.ApplicationService; | ||
21 | +import org.onosproject.cli.AbstractCompleter; | ||
22 | +import org.onosproject.core.Application; | ||
23 | + | ||
24 | +import java.util.Iterator; | ||
25 | +import java.util.List; | ||
26 | +import java.util.SortedSet; | ||
27 | + | ||
28 | +import static org.onosproject.cli.AbstractShellCommand.get; | ||
29 | + | ||
30 | +/** | ||
31 | + * Application name completer for permission command. | ||
32 | + */ | ||
33 | +public class PermissionApplicationNameCompleter extends AbstractCompleter { | ||
34 | + @Override | ||
35 | + public int complete(String buffer, int cursor, List<String> candidates) { | ||
36 | + // Delegate string completer | ||
37 | + StringsCompleter delegate = new StringsCompleter(); | ||
38 | + | ||
39 | + // Fetch our service and feed it's offerings to the string completer | ||
40 | + ApplicationService service = get(ApplicationService.class); | ||
41 | + Iterator<Application> it = service.getApplications().iterator(); | ||
42 | + SortedSet<String> strings = delegate.getStrings(); | ||
43 | + while (it.hasNext()) { | ||
44 | + Application app = it.next(); | ||
45 | + strings.add(app.id().name()); | ||
46 | + } | ||
47 | + | ||
48 | + // Now let the completer do the work for figuring out what to offer. | ||
49 | + return delegate.complete(buffer, cursor, candidates); | ||
50 | + } | ||
51 | +} |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.cli.security; | ||
18 | + | ||
19 | +import com.google.common.collect.ImmutableSet; | ||
20 | +import com.google.common.collect.Sets; | ||
21 | +import org.apache.karaf.shell.commands.Argument; | ||
22 | +import org.apache.karaf.shell.commands.Command; | ||
23 | +import org.onosproject.app.ApplicationAdminService; | ||
24 | +import org.onosproject.cli.AbstractShellCommand; | ||
25 | +import org.onosproject.core.Application; | ||
26 | +import org.onosproject.core.ApplicationId; | ||
27 | +import org.onosproject.core.Permission; | ||
28 | + | ||
29 | +import java.util.Set; | ||
30 | +import java.util.stream.Collectors; | ||
31 | + | ||
32 | +/** | ||
33 | + * Manages application permissions. | ||
34 | + */ | ||
35 | +@Command(scope = "onos", name = "perm", | ||
36 | + description = "Manages application permissions") | ||
37 | +public class PermissionCommand extends AbstractShellCommand { | ||
38 | + | ||
39 | + static final String ADD = "add"; | ||
40 | + static final String REMOVE = "remove"; | ||
41 | + static final String LIST = "list"; | ||
42 | + static final String CLEAR = "clear"; | ||
43 | + | ||
44 | + | ||
45 | + @Argument(index = 0, name = "command", | ||
46 | + description = "Command name (add|remove)", | ||
47 | + required = true, multiValued = false) | ||
48 | + String command = null; | ||
49 | + | ||
50 | + @Argument(index = 1, name = "name", description = "Application name", | ||
51 | + required = true, multiValued = false) | ||
52 | + String name = null; | ||
53 | + | ||
54 | + @Argument(index = 2, name = "permissions", description = "List of permissions", | ||
55 | + required = false, multiValued = true) | ||
56 | + String[] permissions = null; | ||
57 | + | ||
58 | + @Override | ||
59 | + protected void execute() { | ||
60 | + ApplicationAdminService applicationAdminService = get(ApplicationAdminService.class); | ||
61 | + Set<Permission> newPermSet = Sets.newHashSet(); | ||
62 | + if (command.equals(ADD)) { | ||
63 | + ApplicationId appId = applicationAdminService.getId(name); | ||
64 | + if (appId == null) { | ||
65 | + print("No such application: %s", name); | ||
66 | + return; | ||
67 | + } | ||
68 | + Application app = applicationAdminService.getApplication(appId); | ||
69 | + | ||
70 | + for (String perm : permissions) { | ||
71 | + try { | ||
72 | + Permission permission = Permission.valueOf(perm); | ||
73 | + newPermSet.add(permission); | ||
74 | + } catch (IllegalArgumentException e) { | ||
75 | + print("%s is not a valid permission.", perm); | ||
76 | + return; | ||
77 | + } | ||
78 | + | ||
79 | + } | ||
80 | + Set<Permission> oldPermSet = applicationAdminService.getPermissions(appId); | ||
81 | + if (oldPermSet != null) { | ||
82 | + newPermSet.addAll(oldPermSet); | ||
83 | + } else { | ||
84 | + newPermSet.addAll(app.permissions()); | ||
85 | + } | ||
86 | + applicationAdminService.setPermissions(appId, ImmutableSet.copyOf(newPermSet)); | ||
87 | + | ||
88 | + } else if (command.equals(REMOVE)) { | ||
89 | + ApplicationId appId = applicationAdminService.getId(name); | ||
90 | + Application app = applicationAdminService.getApplication(appId); | ||
91 | + if (appId == null) { | ||
92 | + print("No such application: %s", name); | ||
93 | + return; | ||
94 | + } | ||
95 | + Set<Permission> oldPermSet = applicationAdminService.getPermissions(appId); | ||
96 | + if (oldPermSet == null) { | ||
97 | + oldPermSet = app.permissions(); | ||
98 | + } | ||
99 | + Set<String> clearPermSet = Sets.newHashSet(permissions); | ||
100 | + newPermSet.addAll(oldPermSet.stream().filter( | ||
101 | + perm -> !clearPermSet.contains(perm.name().toUpperCase())).collect(Collectors.toList())); | ||
102 | + applicationAdminService.setPermissions(appId, ImmutableSet.copyOf(newPermSet)); | ||
103 | + } else if (command.equals(CLEAR)) { | ||
104 | + ApplicationId appId = applicationAdminService.getId(name); | ||
105 | + if (appId == null) { | ||
106 | + print("No such application: %s", name); | ||
107 | + return; | ||
108 | + } | ||
109 | + applicationAdminService.setPermissions(appId, ImmutableSet.of()); | ||
110 | + print("Cleared the permission list of %s.", appId.name()); | ||
111 | + } else if (command.equals(LIST)) { | ||
112 | + ApplicationId appId = applicationAdminService.getId(name); | ||
113 | + if (appId == null) { | ||
114 | + print("No such application: %s", name); | ||
115 | + return; | ||
116 | + } | ||
117 | + Application app = applicationAdminService.getApplication(appId); | ||
118 | + Set<Permission> userPermissions = applicationAdminService.getPermissions(appId); | ||
119 | + Set<Permission> defaultPermissions = app.permissions(); | ||
120 | + print("Application Role"); | ||
121 | + print("\trole=%s", app.role().name()); | ||
122 | + | ||
123 | + if (defaultPermissions != null) { | ||
124 | + if (!defaultPermissions.isEmpty()) { | ||
125 | + print("Default permissions (specified in app.xml)"); | ||
126 | + for (Permission perm : defaultPermissions) { | ||
127 | + print("\tpermission=%s", perm.name()); | ||
128 | + } | ||
129 | + } else { | ||
130 | + print("(No default permissions specified in app.xml)"); | ||
131 | + } | ||
132 | + } | ||
133 | + if (userPermissions != null) { | ||
134 | + if (!userPermissions.isEmpty()) { | ||
135 | + print("User permissions"); | ||
136 | + for (Permission perm : userPermissions) { | ||
137 | + print("\tpermission=%s", perm.name()); | ||
138 | + } | ||
139 | + } else { | ||
140 | + print("(User has removed all the permissions"); | ||
141 | + } | ||
142 | + } | ||
143 | + | ||
144 | + } | ||
145 | + } | ||
146 | +} |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.cli.security; | ||
18 | + | ||
19 | +import com.google.common.collect.ImmutableList; | ||
20 | +import org.onosproject.cli.AbstractChoicesCompleter; | ||
21 | + | ||
22 | +import java.util.List; | ||
23 | + | ||
24 | +import static org.onosproject.cli.security.PermissionCommand.*; | ||
25 | +/** | ||
26 | + * Permission command completer. | ||
27 | + */ | ||
28 | +public class PermissionCommandCompleter extends AbstractChoicesCompleter { | ||
29 | + @Override | ||
30 | + protected List<String> choices() { | ||
31 | + return ImmutableList.of(ADD, REMOVE, CLEAR, LIST); | ||
32 | + } | ||
33 | +} |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.cli.security; | ||
18 | + | ||
19 | +import org.apache.karaf.shell.console.completer.ArgumentCompleter; | ||
20 | +import org.onosproject.cli.AbstractChoicesCompleter; | ||
21 | +import org.onosproject.core.Permission; | ||
22 | + | ||
23 | +import java.util.ArrayList; | ||
24 | +import java.util.List; | ||
25 | + | ||
26 | +/** | ||
27 | + * Permission Name Completer. | ||
28 | + */ | ||
29 | +public class PermissionNameCompleter extends AbstractChoicesCompleter { | ||
30 | + @Override | ||
31 | + protected List<String> choices() { | ||
32 | + List<String> permNames = new ArrayList<>(); | ||
33 | + | ||
34 | + ArgumentCompleter.ArgumentList list = getArgumentList(); | ||
35 | + String cmd = list.getArguments()[1]; | ||
36 | + if (cmd.equals("add") || cmd.equals("remove")) { | ||
37 | + for (Permission perm : Permission.values()) { | ||
38 | + permNames.add(perm.name()); | ||
39 | + } | ||
40 | + } | ||
41 | + return permNames; | ||
42 | + } | ||
43 | + | ||
44 | + | ||
45 | +} |
... | @@ -21,6 +21,15 @@ | ... | @@ -21,6 +21,15 @@ |
21 | </command> | 21 | </command> |
22 | 22 | ||
23 | <command> | 23 | <command> |
24 | + <action class="org.onosproject.cli.security.PermissionCommand"/> | ||
25 | + <completers> | ||
26 | + <ref component-id="permCommandCompleter"/> | ||
27 | + <ref component-id="permAppNameCompleter"/> | ||
28 | + <ref component-id="permNameCompleter"/> | ||
29 | + </completers> | ||
30 | + </command> | ||
31 | + | ||
32 | + <command> | ||
24 | <action class="org.onosproject.cli.app.ApplicationsListCommand"/> | 33 | <action class="org.onosproject.cli.app.ApplicationsListCommand"/> |
25 | </command> | 34 | </command> |
26 | 35 | ||
... | @@ -360,6 +369,9 @@ | ... | @@ -360,6 +369,9 @@ |
360 | </command> | 369 | </command> |
361 | </command-bundle> | 370 | </command-bundle> |
362 | 371 | ||
372 | + <bean id="permAppNameCompleter" class="org.onosproject.cli.security.PermissionApplicationNameCompleter"/> | ||
373 | + <bean id="permCommandCompleter" class="org.onosproject.cli.security.PermissionCommandCompleter"/> | ||
374 | + <bean id="permNameCompleter" class="org.onosproject.cli.security.PermissionNameCompleter"/> | ||
363 | <bean id="appCommandCompleter" class="org.onosproject.cli.app.ApplicationCommandCompleter"/> | 375 | <bean id="appCommandCompleter" class="org.onosproject.cli.app.ApplicationCommandCompleter"/> |
364 | <bean id="appNameCompleter" class="org.onosproject.cli.app.ApplicationNameCompleter"/> | 376 | <bean id="appNameCompleter" class="org.onosproject.cli.app.ApplicationNameCompleter"/> |
365 | <bean id="allAppNameCompleter" class="org.onosproject.cli.app.AllApplicationNamesCompleter"/> | 377 | <bean id="allAppNameCompleter" class="org.onosproject.cli.app.AllApplicationNamesCompleter"/> | ... | ... |
... | @@ -36,6 +36,7 @@ | ... | @@ -36,6 +36,7 @@ |
36 | <module>common</module> | 36 | <module>common</module> |
37 | <module>net</module> | 37 | <module>net</module> |
38 | <module>store</module> | 38 | <module>store</module> |
39 | + <module>security</module> | ||
39 | </modules> | 40 | </modules> |
40 | 41 | ||
41 | <dependencies> | 42 | <dependencies> | ... | ... |
core/security/impl/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!-- | ||
3 | + ~ Copyright 2015 Open Networking Laboratory | ||
4 | + ~ | ||
5 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + ~ you may not use this file except in compliance with the License. | ||
7 | + ~ You may obtain a copy of the License at | ||
8 | + ~ | ||
9 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + ~ | ||
11 | + ~ Unless required by applicable law or agreed to in writing, software | ||
12 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + ~ See the License for the specific language governing permissions and | ||
15 | + ~ limitations under the License. | ||
16 | + --> | ||
17 | + | ||
18 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
19 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
20 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
21 | + <parent> | ||
22 | + <artifactId>onos-security</artifactId> | ||
23 | + <groupId>org.onosproject</groupId> | ||
24 | + <version>1.2.0-SNAPSHOT</version> | ||
25 | + <relativePath>../pom.xml</relativePath> | ||
26 | + </parent> | ||
27 | + <modelVersion>4.0.0</modelVersion> | ||
28 | + <packaging>bundle</packaging> | ||
29 | + | ||
30 | + <artifactId>onos-security-impl</artifactId> | ||
31 | + | ||
32 | + <dependencies> | ||
33 | + <dependency> | ||
34 | + <groupId>org.osgi</groupId> | ||
35 | + <artifactId>org.osgi.core</artifactId> | ||
36 | + </dependency> | ||
37 | + <dependency> | ||
38 | + <groupId>org.osgi</groupId> | ||
39 | + <artifactId>org.osgi.compendium</artifactId> | ||
40 | + </dependency> | ||
41 | + <dependency> | ||
42 | + <groupId>org.apache.felix</groupId> | ||
43 | + <artifactId>org.apache.felix.scr.annotations</artifactId> | ||
44 | + </dependency> | ||
45 | + <dependency> | ||
46 | + <groupId>org.onosproject</groupId> | ||
47 | + <artifactId>onos-api</artifactId> | ||
48 | + </dependency> | ||
49 | + <dependency> | ||
50 | + <groupId>org.onosproject</groupId> | ||
51 | + <artifactId>onos-security-util</artifactId> | ||
52 | + <version>${project.version}</version> | ||
53 | + </dependency> | ||
54 | + <dependency> | ||
55 | + <groupId>org.apache.karaf.features</groupId> | ||
56 | + <artifactId>org.apache.karaf.features.core</artifactId> | ||
57 | + </dependency> | ||
58 | + </dependencies> | ||
59 | + | ||
60 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
This diff is collapsed. Click to expand it.
1 | +package org.onosproject.security.impl; | ||
2 | + | ||
3 | +import org.apache.commons.collections.FastHashMap; | ||
4 | +import org.apache.felix.scr.annotations.Component; | ||
5 | +import org.apache.felix.scr.annotations.Reference; | ||
6 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
7 | +import org.apache.felix.scr.annotations.Activate; | ||
8 | +import org.apache.felix.scr.annotations.Deactivate; | ||
9 | +import org.apache.karaf.features.BundleInfo; | ||
10 | +import org.apache.karaf.features.Feature; | ||
11 | +import org.apache.karaf.features.FeaturesService; | ||
12 | + | ||
13 | +import org.onosproject.app.ApplicationAdminService; | ||
14 | +import org.onosproject.app.ApplicationEvent; | ||
15 | +import org.onosproject.app.ApplicationListener; | ||
16 | +import org.onosproject.app.ApplicationState; | ||
17 | +import org.onosproject.core.Application; | ||
18 | +import org.onosproject.core.ApplicationId; | ||
19 | +import org.onosproject.core.Permission; | ||
20 | +import org.onosproject.security.util.AppPermission; | ||
21 | +import org.osgi.framework.Bundle; | ||
22 | +import org.osgi.framework.BundleContext; | ||
23 | +import org.osgi.framework.BundleEvent; | ||
24 | +import org.osgi.framework.BundleListener; | ||
25 | +import org.osgi.framework.FrameworkUtil; | ||
26 | +import org.osgi.framework.PackagePermission; | ||
27 | +import org.osgi.framework.ServicePermission; | ||
28 | +import org.osgi.service.log.LogEntry; | ||
29 | +import org.osgi.service.log.LogListener; | ||
30 | +import org.osgi.service.log.LogReaderService; | ||
31 | +import org.osgi.service.permissionadmin.PermissionInfo; | ||
32 | + | ||
33 | +import java.security.AccessControlException; | ||
34 | +import java.security.AllPermission; | ||
35 | +import java.util.ArrayList; | ||
36 | +import java.util.HashMap; | ||
37 | +import java.util.List; | ||
38 | +import java.util.Set; | ||
39 | +import java.util.stream.Collectors; | ||
40 | + | ||
41 | +import org.osgi.service.permissionadmin.PermissionAdmin; | ||
42 | +import org.slf4j.Logger; | ||
43 | + | ||
44 | +import static org.slf4j.LoggerFactory.getLogger; | ||
45 | + | ||
46 | +/** | ||
47 | + * Security-Mode ONOS management implementation. | ||
48 | + */ | ||
49 | + | ||
50 | +//TODO : implement a dedicated distributed store for SM-ONOS | ||
51 | + | ||
52 | +@Component(immediate = true) | ||
53 | +public class SecurityModeManager { | ||
54 | + | ||
55 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
56 | + protected ApplicationAdminService appAdminService; | ||
57 | + | ||
58 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
59 | + protected FeaturesService featuresService; | ||
60 | + | ||
61 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
62 | + protected LogReaderService logReaderService; | ||
63 | + | ||
64 | + private final Logger log = getLogger(getClass()); | ||
65 | + | ||
66 | + private SecurityBundleListener securityBundleListener = new SecurityBundleListener(); | ||
67 | + | ||
68 | + private SecurityApplicationListener securityApplicationListener = new SecurityApplicationListener(); | ||
69 | + | ||
70 | + private SecurityLogListener securityLogListener = new SecurityLogListener(); | ||
71 | + | ||
72 | + private Bundle bundle = null; | ||
73 | + | ||
74 | + private BundleContext bundleContext = null; | ||
75 | + | ||
76 | + private PermissionAdmin permissionAdmin = null; | ||
77 | + | ||
78 | + private HashMap<String, ApplicationId> appTracker = null; | ||
79 | + | ||
80 | + private HashMap<Permission, Set<String>> serviceDirectory = null; | ||
81 | + | ||
82 | + | ||
83 | + @Activate | ||
84 | + public void activate() { | ||
85 | + if (System.getSecurityManager() == null) { | ||
86 | + log.warn("J2EE security manager is disabled."); | ||
87 | + deactivate(); | ||
88 | + return; | ||
89 | + } | ||
90 | + bundle = FrameworkUtil.getBundle(this.getClass()); | ||
91 | + bundleContext = bundle.getBundleContext(); | ||
92 | + | ||
93 | + bundleContext.addBundleListener(securityBundleListener); | ||
94 | + appAdminService.addListener(securityApplicationListener); | ||
95 | + logReaderService.addLogListener(securityLogListener); | ||
96 | + appTracker = new FastHashMap(); | ||
97 | + | ||
98 | + permissionAdmin = getPermissionAdmin(bundleContext); | ||
99 | + if (permissionAdmin == null) { | ||
100 | + log.warn("Permission Admin not found."); | ||
101 | + this.deactivate(); | ||
102 | + return; | ||
103 | + } | ||
104 | + | ||
105 | + serviceDirectory = PolicyBuilder.getServiceDirectory(); | ||
106 | + | ||
107 | + PermissionInfo[] allPerm = { | ||
108 | + new PermissionInfo(AllPermission.class.getName(), "", ""), }; | ||
109 | + | ||
110 | + permissionAdmin.setPermissions(bundle.getLocation(), allPerm); | ||
111 | + log.warn("Security-Mode Started"); | ||
112 | + | ||
113 | + } | ||
114 | + | ||
115 | + | ||
116 | + @Deactivate | ||
117 | + public void deactivate() { | ||
118 | + bundleContext.removeBundleListener(securityBundleListener); | ||
119 | + appAdminService.removeListener(securityApplicationListener); | ||
120 | + logReaderService.removeLogListener(securityLogListener); | ||
121 | + log.info("Stopped"); | ||
122 | + | ||
123 | + } | ||
124 | + | ||
125 | + private class SecurityApplicationListener implements ApplicationListener { | ||
126 | + | ||
127 | + @Override | ||
128 | + public void event(ApplicationEvent event) { | ||
129 | + //App needs to be restarted | ||
130 | + if (event.type() == ApplicationEvent.Type.APP_PERMISSIONS_CHANGED) { | ||
131 | + if (appAdminService.getState(event.subject().id()) == ApplicationState.ACTIVE) { | ||
132 | + appAdminService.deactivate(event.subject().id()); | ||
133 | + print("Permissions updated (%s). Deactivating...", | ||
134 | + event.subject().id().name()); | ||
135 | + } | ||
136 | + } | ||
137 | + } | ||
138 | + } | ||
139 | + | ||
140 | + private class SecurityBundleListener implements BundleListener { | ||
141 | + | ||
142 | + @Override | ||
143 | + public void bundleChanged(BundleEvent event) { | ||
144 | + switch (event.getType()) { | ||
145 | + case BundleEvent.INSTALLED: | ||
146 | + setPermissions(event); | ||
147 | + break; | ||
148 | + case BundleEvent.UNINSTALLED: | ||
149 | + clearPermissions(event); | ||
150 | + break; | ||
151 | + default: | ||
152 | + break; | ||
153 | + } | ||
154 | + } | ||
155 | + } | ||
156 | + | ||
157 | + private void clearPermissions(BundleEvent bundleEvent) { | ||
158 | + if (appTracker.containsKey(bundleEvent.getBundle().getLocation())) { | ||
159 | + permissionAdmin.setPermissions(bundleEvent.getBundle().getLocation(), new PermissionInfo[]{}); | ||
160 | + appTracker.remove(bundleEvent.getBundle().getLocation()); | ||
161 | + } | ||
162 | + } | ||
163 | + | ||
164 | + // find the location of the installed bundle and enforce policy | ||
165 | + private void setPermissions(BundleEvent bundleEvent) { | ||
166 | + for (Application app : appAdminService.getApplications()) { | ||
167 | + if (getBundleLocations(app).contains(bundleEvent.getBundle().getLocation())) { | ||
168 | + String location = bundleEvent.getBundle().getLocation(); | ||
169 | + | ||
170 | + Set<org.onosproject.core.Permission> permissions = | ||
171 | + appAdminService.getPermissions(app.id()); | ||
172 | + | ||
173 | + //Permissions granted by user overrides the permissions specified in App.Xml file | ||
174 | + if (permissions == null) { | ||
175 | + permissions = app.permissions(); | ||
176 | + } | ||
177 | + | ||
178 | + if (permissions.isEmpty()) { | ||
179 | + print("Application %s has not been granted any permission.", app.id().name()); | ||
180 | + } | ||
181 | + | ||
182 | + PermissionInfo[] perms = null; | ||
183 | + | ||
184 | + switch (app.role()) { | ||
185 | + case ADMIN: | ||
186 | + perms = PolicyBuilder.getAdminApplicationPermissions(serviceDirectory); | ||
187 | + break; | ||
188 | + case REGULAR: | ||
189 | + perms = PolicyBuilder.getApplicationPermissions(serviceDirectory, permissions); | ||
190 | + break; | ||
191 | + case UNSPECIFIED: | ||
192 | + default: | ||
193 | + //no role has been assigned. | ||
194 | + perms = PolicyBuilder.getDefaultPerms(); | ||
195 | + log.warn("Application %s has no role assigned.", app.id().name()); | ||
196 | + break; | ||
197 | + } | ||
198 | + permissionAdmin.setPermissions(location, perms); | ||
199 | + appTracker.put(location, app.id()); | ||
200 | + break; | ||
201 | + } | ||
202 | + } | ||
203 | + } | ||
204 | + | ||
205 | + //TODO: dispatch security policy violation event via distributed store | ||
206 | + //immediately notify and deactivate the application upon policy violation | ||
207 | + private class SecurityLogListener implements LogListener { | ||
208 | + @Override | ||
209 | + public void logged(LogEntry entry) { | ||
210 | + if (entry != null) { | ||
211 | + if (entry.getException() != null) { | ||
212 | + ApplicationId applicationId = appTracker.get(entry.getBundle().getLocation()); | ||
213 | + if (applicationId != null) { | ||
214 | + if (appAdminService.getState(applicationId).equals(ApplicationState.ACTIVE)) { | ||
215 | + if (entry.getException() instanceof AccessControlException) { | ||
216 | + java.security.Permission permission = | ||
217 | + ((AccessControlException) entry.getException()).getPermission(); | ||
218 | + handleException(applicationId.name(), permission); | ||
219 | + appAdminService.deactivate(applicationId); | ||
220 | + } | ||
221 | + } | ||
222 | + } | ||
223 | + } | ||
224 | + } | ||
225 | + } | ||
226 | + } | ||
227 | + | ||
228 | + private void handleException(String name, java.security.Permission perm) { | ||
229 | + if (perm instanceof ServicePermission || perm instanceof PackagePermission) { | ||
230 | + print("%s has attempted to %s %s.", name, perm.getActions(), perm.getName()); | ||
231 | + } else if (perm instanceof AppPermission) { | ||
232 | + print("%s has attempted to call an NB API that requires %s permission.", | ||
233 | + name, perm.getName().toUpperCase()); | ||
234 | + } else { | ||
235 | + print("%s has attempted to perform an action that requires %s", name, perm.toString()); | ||
236 | + } | ||
237 | + print("POLICY VIOLATION: Deactivating %s.", name); | ||
238 | + | ||
239 | + } | ||
240 | + private void print(String format, Object... args) { | ||
241 | + System.out.println(String.format("SM-ONOS: " + format, args)); | ||
242 | + log.warn(String.format(format, args)); | ||
243 | + } | ||
244 | + | ||
245 | + private List<String> getBundleLocations(Application app) { | ||
246 | + List<String> locations = new ArrayList(); | ||
247 | + for (String name : app.features()) { | ||
248 | + try { | ||
249 | + Feature feature = featuresService.getFeature(name); | ||
250 | + locations.addAll( | ||
251 | + feature.getBundles().stream().map(BundleInfo::getLocation).collect(Collectors.toList())); | ||
252 | + } catch (Exception e) { | ||
253 | + return locations; | ||
254 | + } | ||
255 | + } | ||
256 | + return locations; | ||
257 | + } | ||
258 | + | ||
259 | + private PermissionAdmin getPermissionAdmin(BundleContext context) { | ||
260 | + return (PermissionAdmin) context.getService(context.getServiceReference(PermissionAdmin.class.getName())); | ||
261 | + } | ||
262 | + | ||
263 | +} |
core/security/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
5 | + <modelVersion>4.0.0</modelVersion> | ||
6 | + | ||
7 | + <parent> | ||
8 | + <artifactId>onos-core</artifactId> | ||
9 | + <groupId>org.onosproject</groupId> | ||
10 | + <version>1.2.0-SNAPSHOT</version> | ||
11 | + <relativePath>../pom.xml</relativePath> | ||
12 | + </parent> | ||
13 | + | ||
14 | + <artifactId>onos-security</artifactId> | ||
15 | + <packaging>pom</packaging> | ||
16 | + <modules> | ||
17 | + <module>util</module> | ||
18 | + <module>impl</module> | ||
19 | + </modules> | ||
20 | + | ||
21 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
core/security/util/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
5 | + <modelVersion>4.0.0</modelVersion> | ||
6 | + | ||
7 | + <parent> | ||
8 | + <artifactId>onos-security</artifactId> | ||
9 | + <groupId>org.onosproject</groupId> | ||
10 | + <version>1.2.0-SNAPSHOT</version> | ||
11 | + </parent> | ||
12 | + | ||
13 | + <artifactId>onos-security-util</artifactId> | ||
14 | + <packaging>bundle</packaging> | ||
15 | + | ||
16 | +</project> |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.security.util; | ||
18 | + | ||
19 | +/** | ||
20 | + * Checks if the caller has the required permission to call each API. | ||
21 | + */ | ||
22 | +public final class AppGuard { | ||
23 | + | ||
24 | + private AppGuard() { | ||
25 | + } | ||
26 | + | ||
27 | + public static boolean check(String perm) { | ||
28 | + SecurityManager sm = System.getSecurityManager(); | ||
29 | + if (sm != null) { | ||
30 | + System.getSecurityManager().checkPermission(new AppPermission(perm)); | ||
31 | + } | ||
32 | + return true; | ||
33 | + } | ||
34 | +} |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.security.util; | ||
18 | + | ||
19 | +import java.security.BasicPermission; | ||
20 | + | ||
21 | +/** | ||
22 | + * Implementation of API access permission. | ||
23 | + */ | ||
24 | +public class AppPermission extends BasicPermission { | ||
25 | + | ||
26 | + public AppPermission(String name) { | ||
27 | + super(name.toUpperCase(), ""); | ||
28 | + } | ||
29 | + | ||
30 | + public AppPermission(String name, String actions) { | ||
31 | + super(name.toUpperCase(), actions); | ||
32 | + } | ||
33 | + | ||
34 | +} |
... | @@ -123,6 +123,13 @@ | ... | @@ -123,6 +123,13 @@ |
123 | <bundle>mvn:org.onosproject/onos-cli/@ONOS-VERSION</bundle> | 123 | <bundle>mvn:org.onosproject/onos-cli/@ONOS-VERSION</bundle> |
124 | </feature> | 124 | </feature> |
125 | 125 | ||
126 | + <feature name="onos-security" version="@FEATURE-VERSION" | ||
127 | + description="Security-Mode ONOS"> | ||
128 | + <!--<bundle>mvn:org.onosproject/onos-security-felix/2.2.0-ONOS</bundle>--> | ||
129 | + <bundle>mvn:org.onosproject/onos-security-impl/@ONOS-VERSION</bundle> | ||
130 | + <bundle>mvn:org.onosproject/onos-security-util/@ONOS-VERSION</bundle> | ||
131 | + </feature> | ||
132 | + | ||
126 | <!-- Deprecated! For standalone testing only. --> | 133 | <!-- Deprecated! For standalone testing only. --> |
127 | <feature name="onos-core-trivial" version="@FEATURE-VERSION" | 134 | <feature name="onos-core-trivial" version="@FEATURE-VERSION" |
128 | description="ONOS trivial core components"> | 135 | description="ONOS trivial core components"> | ... | ... |
-
Please register or login to post a comment