View Javadoc
1   package org.argeo.cms.internal.kernel;
2   
3   import java.io.FilePermission;
4   import java.lang.reflect.ReflectPermission;
5   import java.net.SocketPermission;
6   import java.security.AllPermission;
7   import java.util.PropertyPermission;
8   
9   import javax.security.auth.AuthPermission;
10  
11  import org.argeo.api.NodeUtils;
12  import org.osgi.framework.AdminPermission;
13  import org.osgi.framework.Bundle;
14  import org.osgi.framework.BundleContext;
15  import org.osgi.framework.FrameworkUtil;
16  import org.osgi.framework.ServicePermission;
17  import org.osgi.service.cm.ConfigurationPermission;
18  import org.osgi.service.condpermadmin.BundleLocationCondition;
19  import org.osgi.service.condpermadmin.ConditionInfo;
20  import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
21  import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
22  import org.osgi.service.condpermadmin.ConditionalPermissionUpdate;
23  import org.osgi.service.permissionadmin.PermissionAdmin;
24  import org.osgi.service.permissionadmin.PermissionInfo;
25  
26  /** Security profile based on OSGi {@link PermissionAdmin}. */
27  public interface SecurityProfile {
28  	BundleContext bc = FrameworkUtil.getBundle(SecurityProfile.class).getBundleContext();
29  
30  	default void applySystemPermissions(ConditionalPermissionAdmin permissionAdmin) {
31  		ConditionalPermissionUpdate update = permissionAdmin.newConditionalPermissionUpdate();
32  		// Self
33  		String nodeAPiBundleLocation = locate(NodeUtils.class);
34  		update.getConditionalPermissionInfos()
35  				.add(permissionAdmin.newConditionalPermissionInfo(null,
36  						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
37  								new String[] { nodeAPiBundleLocation }) },
38  						new PermissionInfo[] { new PermissionInfo(AllPermission.class.getName(), null, null) },
39  						ConditionalPermissionInfo.ALLOW));
40  		String cmsBundleLocation = locate(SecurityProfile.class);
41  		update.getConditionalPermissionInfos()
42  				.add(permissionAdmin.newConditionalPermissionInfo(null,
43  						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
44  								new String[] { cmsBundleLocation }) },
45  						new PermissionInfo[] { new PermissionInfo(AllPermission.class.getName(), null, null) },
46  						ConditionalPermissionInfo.ALLOW));
47  		String frameworkBundleLocation = bc.getBundle(0).getLocation();
48  		update.getConditionalPermissionInfos()
49  				.add(permissionAdmin.newConditionalPermissionInfo(null,
50  						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
51  								new String[] { frameworkBundleLocation }) },
52  						new PermissionInfo[] { new PermissionInfo(AllPermission.class.getName(), null, null) },
53  						ConditionalPermissionInfo.ALLOW));
54  		// All
55  		// FIXME understand why Jetty and Jackrabbit require that
56  		update.getConditionalPermissionInfos()
57  				.add(permissionAdmin.newConditionalPermissionInfo(null, null, new PermissionInfo[] {
58  						new PermissionInfo(SocketPermission.class.getName(), "localhost:7070", "listen,resolve"),
59  						new PermissionInfo(FilePermission.class.getName(), "<<ALL FILES>>", "read,write,delete"),
60  						new PermissionInfo(PropertyPermission.class.getName(), "DEBUG", "read"),
61  						new PermissionInfo(PropertyPermission.class.getName(), "STOP.*", "read"),
62  						new PermissionInfo(PropertyPermission.class.getName(), "org.apache.jackrabbit.*", "read"),
63  						new PermissionInfo(RuntimePermission.class.getName(), "*", "*"), },
64  						ConditionalPermissionInfo.ALLOW));
65  
66  		// Eclipse
67  		// update.getConditionalPermissionInfos()
68  		// .add(permissionAdmin.newConditionalPermissionInfo(null,
69  		// new ConditionInfo[] { new
70  		// ConditionInfo(BundleLocationCondition.class.getName(),
71  		// new String[] { "*/org.eclipse.*" }) },
72  		// new PermissionInfo[] { new
73  		// PermissionInfo(RuntimePermission.class.getName(), "*", "*"),
74  		// new PermissionInfo(AdminPermission.class.getName(), "*", "*"),
75  		// new PermissionInfo(ServicePermission.class.getName(), "*", "get"),
76  		// new PermissionInfo(ServicePermission.class.getName(), "*",
77  		// "register"),
78  		// new PermissionInfo(TopicPermission.class.getName(), "*", "publish"),
79  		// new PermissionInfo(TopicPermission.class.getName(), "*",
80  		// "subscribe"),
81  		// new PermissionInfo(PropertyPermission.class.getName(), "osgi.*",
82  		// "read"),
83  		// new PermissionInfo(PropertyPermission.class.getName(), "eclipse.*",
84  		// "read"),
85  		// new PermissionInfo(PropertyPermission.class.getName(),
86  		// "org.eclipse.*", "read"),
87  		// new PermissionInfo(PropertyPermission.class.getName(), "equinox.*",
88  		// "read"),
89  		// new PermissionInfo(PropertyPermission.class.getName(), "xml.*",
90  		// "read"),
91  		// new PermissionInfo("org.eclipse.equinox.log.LogPermission", "*",
92  		// "log"), },
93  		// ConditionalPermissionInfo.ALLOW));
94  		update.getConditionalPermissionInfos()
95  				.add(permissionAdmin.newConditionalPermissionInfo(null,
96  						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
97  								new String[] { "*/org.eclipse.*" }) },
98  						new PermissionInfo[] { new PermissionInfo(AllPermission.class.getName(), null, null), },
99  						ConditionalPermissionInfo.ALLOW));
100 		update.getConditionalPermissionInfos()
101 				.add(permissionAdmin.newConditionalPermissionInfo(null,
102 						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
103 								new String[] { "*/org.apache.felix.*" }) },
104 						new PermissionInfo[] { new PermissionInfo(AllPermission.class.getName(), null, null), },
105 						ConditionalPermissionInfo.ALLOW));
106 
107 		// Configuration admin
108 //		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
109 //				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
110 //						new String[] { locate(configurationAdmin.getService().getClass()) }) },
111 //				new PermissionInfo[] { new PermissionInfo(ConfigurationPermission.class.getName(), "*", "configure"),
112 //						new PermissionInfo(AdminPermission.class.getName(), "*", "*"),
113 //						new PermissionInfo(PropertyPermission.class.getName(), "osgi.*", "read"), },
114 //				ConditionalPermissionInfo.ALLOW));
115 
116 		// Bitronix
117 //		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
118 //				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
119 //						new String[] { locate(BitronixTransactionManager.class) }) },
120 //				new PermissionInfo[] { new PermissionInfo(PropertyPermission.class.getName(), "bitronix.tm.*", "read"),
121 //						new PermissionInfo(RuntimePermission.class.getName(), "getClassLoader", null),
122 //						new PermissionInfo(MBeanServerPermission.class.getName(), "createMBeanServer", null),
123 //						new PermissionInfo(MBeanPermission.class.getName(), "bitronix.tm.*", "registerMBean"),
124 //						new PermissionInfo(MBeanTrustPermission.class.getName(), "register", null) },
125 //				ConditionalPermissionInfo.ALLOW));
126 
127 		// DS
128 		Bundle dsBundle = findBundle("org.eclipse.equinox.ds");
129 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
130 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
131 						new String[] { dsBundle.getLocation() }) },
132 				new PermissionInfo[] { new PermissionInfo(ConfigurationPermission.class.getName(), "*", "configure"),
133 						new PermissionInfo(AdminPermission.class.getName(), "*", "*"),
134 						new PermissionInfo(ServicePermission.class.getName(), "*", "get"),
135 						new PermissionInfo(ServicePermission.class.getName(), "*", "register"),
136 						new PermissionInfo(PropertyPermission.class.getName(), "osgi.*", "read"),
137 						new PermissionInfo(PropertyPermission.class.getName(), "xml.*", "read"),
138 						new PermissionInfo(PropertyPermission.class.getName(), "equinox.*", "read"),
139 						new PermissionInfo(RuntimePermission.class.getName(), "accessDeclaredMembers", null),
140 						new PermissionInfo(RuntimePermission.class.getName(), "getClassLoader", null),
141 						new PermissionInfo(ReflectPermission.class.getName(), "suppressAccessChecks", null), },
142 				ConditionalPermissionInfo.ALLOW));
143 
144 		// Jetty
145 		// Bundle jettyUtilBundle = findBundle("org.eclipse.equinox.http.jetty");
146 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
147 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
148 						new String[] { "*/org.eclipse.jetty.*" }) },
149 				new PermissionInfo[] {
150 						new PermissionInfo(FilePermission.class.getName(), "<<ALL FILES>>", "read,write,delete"), },
151 				ConditionalPermissionInfo.ALLOW));
152 		Bundle servletBundle = findBundle("javax.servlet");
153 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
154 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
155 						new String[] { servletBundle.getLocation() }) },
156 				new PermissionInfo[] { new PermissionInfo(PropertyPermission.class.getName(),
157 						"org.glassfish.web.rfc2109_cookie_names_enforced", "read") },
158 				ConditionalPermissionInfo.ALLOW));
159 
160 		// required to be able to get the BundleContext in the customizer
161 		Bundle jettyCustomizerBundle = findBundle("org.argeo.ext.equinox.jetty");
162 		update.getConditionalPermissionInfos()
163 				.add(permissionAdmin.newConditionalPermissionInfo(null,
164 						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
165 								new String[] { jettyCustomizerBundle.getLocation() }) },
166 						new PermissionInfo[] { new PermissionInfo(AdminPermission.class.getName(), "*", "*"), },
167 						ConditionalPermissionInfo.ALLOW));
168 
169 		// Blueprint
170 //		Bundle blueprintBundle = findBundle("org.eclipse.gemini.blueprint.core");
171 //		update.getConditionalPermissionInfos()
172 //				.add(permissionAdmin.newConditionalPermissionInfo(null,
173 //						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
174 //								new String[] { blueprintBundle.getLocation() }) },
175 //						new PermissionInfo[] { new PermissionInfo(RuntimePermission.class.getName(), "*", null),
176 //								new PermissionInfo(AdminPermission.class.getName(), "*", "*"), },
177 //						ConditionalPermissionInfo.ALLOW));
178 //		Bundle blueprintExtenderBundle = findBundle("org.eclipse.gemini.blueprint.extender");
179 //		update.getConditionalPermissionInfos()
180 //				.add(permissionAdmin
181 //						.newConditionalPermissionInfo(null,
182 //								new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
183 //										new String[] { blueprintExtenderBundle.getLocation() }) },
184 //								new PermissionInfo[] { new PermissionInfo(RuntimePermission.class.getName(), "*", null),
185 //										new PermissionInfo(PropertyPermission.class.getName(), "org.eclipse.gemini.*",
186 //												"read"),
187 //										new PermissionInfo(AdminPermission.class.getName(), "*", "*"),
188 //										new PermissionInfo(ServicePermission.class.getName(), "*", "register"), },
189 //								ConditionalPermissionInfo.ALLOW));
190 //		Bundle springCoreBundle = findBundle("org.springframework.core");
191 //		update.getConditionalPermissionInfos()
192 //				.add(permissionAdmin.newConditionalPermissionInfo(null,
193 //						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
194 //								new String[] { springCoreBundle.getLocation() }) },
195 //						new PermissionInfo[] { new PermissionInfo(RuntimePermission.class.getName(), "*", null),
196 //								new PermissionInfo(AdminPermission.class.getName(), "*", "*"), },
197 //						ConditionalPermissionInfo.ALLOW));
198 //		Bundle blueprintIoBundle = findBundle("org.eclipse.gemini.blueprint.io");
199 //		update.getConditionalPermissionInfos()
200 //				.add(permissionAdmin.newConditionalPermissionInfo(null,
201 //						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
202 //								new String[] { blueprintIoBundle.getLocation() }) },
203 //						new PermissionInfo[] { new PermissionInfo(RuntimePermission.class.getName(), "*", null),
204 //								new PermissionInfo(AdminPermission.class.getName(), "*", "*"), },
205 //						ConditionalPermissionInfo.ALLOW));
206 
207 		// Equinox
208 		Bundle registryBundle = findBundle("org.eclipse.equinox.registry");
209 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
210 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
211 						new String[] { registryBundle.getLocation() }) },
212 				new PermissionInfo[] { new PermissionInfo(PropertyPermission.class.getName(), "eclipse.*", "read"),
213 						new PermissionInfo(PropertyPermission.class.getName(), "osgi.*", "read"),
214 						new PermissionInfo(FilePermission.class.getName(), "<<ALL FILES>>", "read,write,delete"), },
215 				ConditionalPermissionInfo.ALLOW));
216 
217 		Bundle equinoxUtilBundle = findBundle("org.eclipse.equinox.util");
218 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
219 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
220 						new String[] { equinoxUtilBundle.getLocation() }) },
221 				new PermissionInfo[] { new PermissionInfo(PropertyPermission.class.getName(), "equinox.*", "read"),
222 						new PermissionInfo(ServicePermission.class.getName(), "*", "get"),
223 						new PermissionInfo(ServicePermission.class.getName(), "*", "register"), },
224 				ConditionalPermissionInfo.ALLOW));
225 		Bundle equinoxCommonBundle = findBundle("org.eclipse.equinox.common");
226 		update.getConditionalPermissionInfos()
227 				.add(permissionAdmin.newConditionalPermissionInfo(null,
228 						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
229 								new String[] { equinoxCommonBundle.getLocation() }) },
230 						new PermissionInfo[] { new PermissionInfo(AdminPermission.class.getName(), "*", "*"), },
231 						ConditionalPermissionInfo.ALLOW));
232 
233 		Bundle consoleBundle = findBundle("org.eclipse.equinox.console");
234 		update.getConditionalPermissionInfos()
235 				.add(permissionAdmin.newConditionalPermissionInfo(null,
236 						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
237 								new String[] { consoleBundle.getLocation() }) },
238 						new PermissionInfo[] { new PermissionInfo(ServicePermission.class.getName(), "*", "register"),
239 								new PermissionInfo(AdminPermission.class.getName(), "*", "listener") },
240 						ConditionalPermissionInfo.ALLOW));
241 		Bundle preferencesBundle = findBundle("org.eclipse.equinox.preferences");
242 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
243 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
244 						new String[] { preferencesBundle.getLocation() }) },
245 				new PermissionInfo[] {
246 						new PermissionInfo(FilePermission.class.getName(), "<<ALL FILES>>", "read,write,delete"), },
247 				ConditionalPermissionInfo.ALLOW));
248 		Bundle appBundle = findBundle("org.eclipse.equinox.app");
249 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
250 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
251 						new String[] { appBundle.getLocation() }) },
252 				new PermissionInfo[] {
253 						new PermissionInfo(FilePermission.class.getName(), "<<ALL FILES>>", "read,write,delete"), },
254 				ConditionalPermissionInfo.ALLOW));
255 
256 		// Jackrabbit
257 		Bundle jackrabbitCoreBundle = findBundle("org.apache.jackrabbit.core");
258 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
259 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
260 						new String[] { jackrabbitCoreBundle.getLocation() }) },
261 				new PermissionInfo[] {
262 						new PermissionInfo(FilePermission.class.getName(), "<<ALL FILES>>", "read,write,delete"),
263 						new PermissionInfo(PropertyPermission.class.getName(), "*", "read,write"),
264 						new PermissionInfo(AuthPermission.class.getName(), "getSubject", null),
265 						new PermissionInfo(AuthPermission.class.getName(), "getLoginConfiguration", null),
266 						new PermissionInfo(AuthPermission.class.getName(), "createLoginContext.Jackrabbit", null), },
267 				ConditionalPermissionInfo.ALLOW));
268 		Bundle jackrabbitDataBundle = findBundle("org.apache.jackrabbit.data");
269 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
270 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
271 						new String[] { jackrabbitDataBundle.getLocation() }) },
272 				new PermissionInfo[] { new PermissionInfo(PropertyPermission.class.getName(), "*", "read,write") },
273 				ConditionalPermissionInfo.ALLOW));
274 		Bundle jackrabbitCommonBundle = findBundle("org.apache.jackrabbit.jcr.commons");
275 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
276 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
277 						new String[] { jackrabbitCommonBundle.getLocation() }) },
278 				new PermissionInfo[] { new PermissionInfo(AuthPermission.class.getName(), "getSubject", null),
279 						new PermissionInfo(AuthPermission.class.getName(), "createLoginContext.Jackrabbit", null), },
280 				ConditionalPermissionInfo.ALLOW));
281 
282 		Bundle jackrabbitExtBundle = findBundle("org.argeo.ext.jackrabbit");
283 		update.getConditionalPermissionInfos()
284 				.add(permissionAdmin.newConditionalPermissionInfo(null,
285 						new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
286 								new String[] { jackrabbitExtBundle.getLocation() }) },
287 						new PermissionInfo[] { new PermissionInfo(AuthPermission.class.getName(), "*", "*"), },
288 						ConditionalPermissionInfo.ALLOW));
289 
290 		// Tika
291 		Bundle tikaCoreBundle = findBundle("org.apache.tika.core");
292 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
293 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
294 						new String[] { tikaCoreBundle.getLocation() }) },
295 				new PermissionInfo[] { new PermissionInfo(PropertyPermission.class.getName(), "*", "read,write"),
296 						new PermissionInfo(AdminPermission.class.getName(), "*", "*") },
297 				ConditionalPermissionInfo.ALLOW));
298 		Bundle luceneBundle = findBundle("org.apache.lucene");
299 		update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
300 				new ConditionInfo[] { new ConditionInfo(BundleLocationCondition.class.getName(),
301 						new String[] { luceneBundle.getLocation() }) },
302 				new PermissionInfo[] {
303 						new PermissionInfo(FilePermission.class.getName(), "<<ALL FILES>>", "read,write,delete"),
304 						new PermissionInfo(PropertyPermission.class.getName(), "*", "read"),
305 						new PermissionInfo(AdminPermission.class.getName(), "*", "*") },
306 				ConditionalPermissionInfo.ALLOW));
307 
308 		// COMMIT
309 		update.commit();
310 	}
311 
312 	/** @return bundle location */
313 	default String locate(Class<?> clzz) {
314 		return FrameworkUtil.getBundle(clzz).getLocation();
315 	}
316 
317 	/** Can be null */
318 	default Bundle findBundle(String symbolicName) {
319 		for (Bundle b : bc.getBundles())
320 			if (b.getSymbolicName().equals(symbolicName))
321 				return b;
322 		return null;
323 	}
324 
325 }