blob: 352302b54ff191a95e11452ba9b7e1ccb057ff5f [file] [log] [blame]
Changhoon Yoon23dee8f2015-05-18 22:19:49 +09001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Changhoon Yoon23dee8f2015-05-18 22:19:49 +09003 *
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
Changhoon Yoon541ef712015-05-23 17:18:34 +090017package org.onosproject.security;
18
Changhoon Yoone71dfa42015-12-04 21:49:25 +090019import java.security.AccessController;
20import java.security.AccessControlContext;
Thomas Vachuska4c571ae2015-09-10 16:31:59 -070021import com.google.common.annotations.Beta;
Changhoon Yoone71dfa42015-12-04 21:49:25 +090022import com.google.common.cache.Cache;
23import com.google.common.cache.CacheBuilder;
Changhoon Yoone71dfa42015-12-04 21:49:25 +090024import java.util.concurrent.ExecutionException;
25import java.util.concurrent.TimeUnit;
Changhoon Yoon23dee8f2015-05-18 22:19:49 +090026/**
Changhoon Yoon541ef712015-05-23 17:18:34 +090027 * Aids SM-ONOS to perform API-level permission checking.
Changhoon Yoon23dee8f2015-05-18 22:19:49 +090028 */
Thomas Vachuska4c571ae2015-09-10 16:31:59 -070029@Beta
Changhoon Yoon23dee8f2015-05-18 22:19:49 +090030public final class AppGuard {
Changhoon Yoon23dee8f2015-05-18 22:19:49 +090031 private AppGuard() {
Heedo Kangd8241c72016-02-29 18:49:05 +090032
Changhoon Yoon23dee8f2015-05-18 22:19:49 +090033 }
34
Changhoon Yoon541ef712015-05-23 17:18:34 +090035 /**
36 * Checks if the caller has the required permission only when security-mode is enabled.
Changhoon Yoone71dfa42015-12-04 21:49:25 +090037 *
Changhoon Yoon541ef712015-05-23 17:18:34 +090038 * @param permission permission to be checked
39 */
Changhoon Yoonb856b812015-08-10 03:47:19 +090040 public static void checkPermission(AppPermission.Type permission) {
Changhoon Yoon23dee8f2015-05-18 22:19:49 +090041 SecurityManager sm = System.getSecurityManager();
Changhoon Yoone71dfa42015-12-04 21:49:25 +090042 if (sm == null) {
43 return;
44 }
Heedo Kangd8241c72016-02-29 18:49:05 +090045 AccessControlContext context = AccessController.getContext();
46 if (context == null) {
47 sm.checkPermission(new AppPermission((permission)));
Changhoon Yoone71dfa42015-12-04 21:49:25 +090048 } else {
Heedo Kangd8241c72016-02-29 18:49:05 +090049 int contextHash = context.hashCode() ^ permission.hashCode();
50 PermissionCheckCache.getInstance().checkCache(contextHash, new AppPermission(permission));
Changhoon Yoon23dee8f2015-05-18 22:19:49 +090051 }
Changhoon Yoon23dee8f2015-05-18 22:19:49 +090052 }
Changhoon Yoone71dfa42015-12-04 21:49:25 +090053
Changhoon Yoone71dfa42015-12-04 21:49:25 +090054 private static final class PermissionCheckCache {
55
56 private static final Cache<Integer, Boolean> CACHE = CacheBuilder.newBuilder()
57 .maximumSize(1000)
58 .expireAfterAccess(10, TimeUnit.MINUTES)
59 .build();
60
61 private PermissionCheckCache() {
62 }
63
64 private static class SingletonHelper {
65 private static final PermissionCheckCache INSTANCE = new PermissionCheckCache();
66 }
67
68 public static PermissionCheckCache getInstance() {
69 return SingletonHelper.INSTANCE;
70 }
71
72 public static void checkCache(int key, AppPermission perm) {
73 try {
74 CACHE.get(key, () -> {
75 System.getSecurityManager().checkPermission(perm);
76 return true;
77 });
78 } catch (ExecutionException e) {
79 System.getSecurityManager().checkPermission(perm);
80 }
81 }
82 }
Changhoon Yoon23dee8f2015-05-18 22:19:49 +090083}