]> git.argeo.org Git - lgpl/argeo-commons.git/blob - Activator.java
3fbed28f410c037316ed1975019120abcb18fdf4
[lgpl/argeo-commons.git] / Activator.java
1 package org.argeo.cms.internal.kernel;
2
3 import java.io.IOException;
4 import java.net.URL;
5 import java.security.AllPermission;
6 import java.util.Dictionary;
7 import java.util.List;
8 import java.util.Locale;
9 import java.util.concurrent.ExecutorService;
10 import java.util.concurrent.Executors;
11
12 import javax.security.auth.login.Configuration;
13
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16 import org.argeo.api.ArgeoLogger;
17 import org.argeo.api.NodeConstants;
18 import org.argeo.api.NodeDeployment;
19 import org.argeo.api.NodeInstance;
20 import org.argeo.api.NodeState;
21 import org.argeo.ident.IdentClient;
22 import org.ietf.jgss.GSSCredential;
23 import org.osgi.framework.Bundle;
24 import org.osgi.framework.BundleActivator;
25 import org.osgi.framework.BundleContext;
26 import org.osgi.framework.Constants;
27 import org.osgi.framework.FrameworkUtil;
28 import org.osgi.service.condpermadmin.BundleLocationCondition;
29 import org.osgi.service.condpermadmin.ConditionInfo;
30 import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
31 import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
32 import org.osgi.service.condpermadmin.ConditionalPermissionUpdate;
33 import org.osgi.service.log.LogReaderService;
34 import org.osgi.service.permissionadmin.PermissionInfo;
35 import org.osgi.service.useradmin.UserAdmin;
36 import org.osgi.util.tracker.ServiceTracker;
37
38 /**
39 * Activates the kernel. Gives access to kernel information for the rest of the
40 * bundle (and only it)
41 */
42 public class Activator implements BundleActivator {
43 private final static Log log = LogFactory.getLog(Activator.class);
44
45 private static Activator instance;
46
47 // TODO make it configurable
48 private boolean hardened = false;
49
50 private static BundleContext bundleContext;
51
52 private LogReaderService logReaderService;
53
54 private NodeLogger logger;
55 private CmsState nodeState;
56 private CmsDeployment nodeDeployment;
57 private CmsInstance nodeInstance;
58
59 private ServiceTracker<UserAdmin, NodeUserAdmin> userAdminSt;
60 private ExecutorService internalExecutorService;
61
62 static {
63 Bundle bundle = FrameworkUtil.getBundle(Activator.class);
64 if (bundle != null) {
65 bundleContext = bundle.getBundleContext();
66 }
67 }
68
69 void init() {
70 Runtime.getRuntime().addShutdownHook(new CmsShutdown());
71 instance = this;
72 // this.bc = bundleContext;
73 if (bundleContext != null)
74 this.logReaderService = getService(LogReaderService.class);
75 this.internalExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
76
77 try {
78 initSecurity();
79 initArgeoLogger();
80 initNode();
81
82 if (log.isTraceEnabled())
83 log.trace("Kernel bundle started");
84 } catch (Throwable e) {
85 log.error("## FATAL: CMS activator failed", e);
86 }
87 }
88
89 void destroy() {
90 try {
91 if (nodeInstance != null)
92 nodeInstance.shutdown();
93 if (nodeDeployment != null)
94 nodeDeployment.shutdown();
95 if (nodeState != null)
96 nodeState.shutdown();
97
98 if (userAdminSt != null)
99 userAdminSt.close();
100
101 internalExecutorService.shutdown();
102 instance = null;
103 bundleContext = null;
104 this.logReaderService = null;
105 // this.configurationAdmin = null;
106 } catch (Exception e) {
107 log.error("CMS activator shutdown failed", e);
108 }
109 }
110
111 private void initSecurity() {
112 if (System.getProperty(KernelConstants.JAAS_CONFIG_PROP) == null) {
113 String jaasConfig = KernelConstants.JAAS_CONFIG;
114 URL url = getClass().getResource(jaasConfig);
115 // System.setProperty(KernelConstants.JAAS_CONFIG_PROP,
116 // url.toExternalForm());
117 KernelUtils.setJaasConfiguration(url);
118 }
119 // explicitly load JAAS configuration
120 Configuration.getConfiguration();
121
122 // code-level permissions
123 String osgiSecurity = KernelUtils.getFrameworkProp(Constants.FRAMEWORK_SECURITY);
124 if (osgiSecurity != null && Constants.FRAMEWORK_SECURITY_OSGI.equals(osgiSecurity)) {
125 // TODO rather use a tracker?
126 ConditionalPermissionAdmin permissionAdmin = bundleContext
127 .getService(bundleContext.getServiceReference(ConditionalPermissionAdmin.class));
128 if (!hardened) {
129 // All permissions to all bundles
130 ConditionalPermissionUpdate update = permissionAdmin.newConditionalPermissionUpdate();
131 update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
132 new ConditionInfo[] {
133 new ConditionInfo(BundleLocationCondition.class.getName(), new String[] { "*" }) },
134 new PermissionInfo[] { new PermissionInfo(AllPermission.class.getName(), null, null) },
135 ConditionalPermissionInfo.ALLOW));
136 // TODO data admin permission
137 // PermissionInfo dataAdminPerm = new PermissionInfo(AuthPermission.class.getName(),
138 // "createLoginContext." + NodeConstants.LOGIN_CONTEXT_DATA_ADMIN, null);
139 // update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
140 // new ConditionInfo[] {
141 // new ConditionInfo(BundleLocationCondition.class.getName(), new String[] { "*" }) },
142 // new PermissionInfo[] { dataAdminPerm }, ConditionalPermissionInfo.DENY));
143 // update.getConditionalPermissionInfos().add(permissionAdmin.newConditionalPermissionInfo(null,
144 // new ConditionInfo[] {
145 // new ConditionInfo(BundleSignerCondition.class.getName(), new String[] { "CN=\"Eclipse.org Foundation, Inc.\", OU=IT, O=\"Eclipse.org Foundation, Inc.\", L=Nepean, ST=Ontario, C=CA" }) },
146 // new PermissionInfo[] { dataAdminPerm }, ConditionalPermissionInfo.ALLOW));
147 update.commit();
148 } else {
149 SecurityProfile securityProfile = new SecurityProfile() {
150 };
151 securityProfile.applySystemPermissions(permissionAdmin);
152 }
153 }
154
155 }
156
157 private void initArgeoLogger() {
158 logger = new NodeLogger(logReaderService);
159 if (bundleContext != null)
160 bundleContext.registerService(ArgeoLogger.class, logger, null);
161 }
162
163 private void initNode() throws IOException {
164 // Node state
165 nodeState = new CmsState();
166 registerService(NodeState.class, nodeState, null);
167
168 // Node deployment
169 nodeDeployment = new CmsDeployment();
170 // registerService(NodeDeployment.class, nodeDeployment, null);
171
172 // Node instance
173 nodeInstance = new CmsInstance();
174 registerService(NodeInstance.class, nodeInstance, null);
175 }
176
177 public static <T> void registerService(Class<T> clss, T service, Dictionary<String, ?> properties) {
178 if (bundleContext != null) {
179 bundleContext.registerService(clss, service, properties);
180 }
181
182 }
183
184 public static <T> T getService(Class<T> clss) {
185 if (bundleContext != null) {
186 return bundleContext.getService(bundleContext.getServiceReference(clss));
187 } else {
188 return null;
189 }
190 }
191
192 /*
193 * OSGi
194 */
195
196 @Override
197 public void start(BundleContext bc) throws Exception {
198 if (!bc.getBundle().equals(bundleContext.getBundle()))
199 throw new IllegalStateException(
200 "Bundle " + bc.getBundle() + " is not consistent with " + bundleContext.getBundle());
201 init();
202 userAdminSt = new ServiceTracker<>(bundleContext, UserAdmin.class, null);
203 userAdminSt.open();
204 }
205
206 @Override
207 public void stop(BundleContext bc) throws Exception {
208 if (!bc.getBundle().equals(bundleContext.getBundle()))
209 throw new IllegalStateException(
210 "Bundle " + bc.getBundle() + " is not consistent with " + bundleContext.getBundle());
211 destroy();
212 }
213
214 // private <T> T getService(Class<T> clazz) {
215 // ServiceReference<T> sr = bundleContext.getServiceReference(clazz);
216 // if (sr == null)
217 // throw new IllegalStateException("No service available for " + clazz);
218 // return bundleContext.getService(sr);
219 // }
220
221 public static NodeState getNodeState() {
222 return instance.nodeState;
223 }
224
225 public static GSSCredential getAcceptorCredentials() {
226 return getNodeUserAdmin().getAcceptorCredentials();
227 }
228
229 @Deprecated
230 public static boolean isSingleUser() {
231 return getNodeUserAdmin().isSingleUser();
232 }
233
234 public static UserAdmin getUserAdmin() {
235 return (UserAdmin) getNodeUserAdmin();
236 }
237
238 public static String getHttpProxySslHeader() {
239 return KernelUtils.getFrameworkProp(NodeConstants.HTTP_PROXY_SSL_DN);
240 }
241
242 public static IdentClient getIdentClient(String remoteAddr) {
243 if (!IdentClient.isDefaultAuthdPassphraseFileAvailable())
244 return null;
245 // TODO make passphrase more configurable
246 return new IdentClient(remoteAddr);
247 }
248
249 private static NodeUserAdmin getNodeUserAdmin() {
250 NodeUserAdmin res;
251 try {
252 res = instance.userAdminSt.waitForService(60000);
253 } catch (InterruptedException e) {
254 throw new IllegalStateException("Cannot retrieve Node user admin", e);
255 }
256 if (res == null)
257 throw new IllegalStateException("No Node user admin found");
258
259 return res;
260 // ServiceReference<UserAdmin> sr =
261 // instance.bc.getServiceReference(UserAdmin.class);
262 // NodeUserAdmin userAdmin = (NodeUserAdmin) instance.bc.getService(sr);
263 // return userAdmin;
264
265 }
266
267 static ExecutorService getInternalExecutorService() {
268 return instance.internalExecutorService;
269 }
270
271 // static CmsSecurity getCmsSecurity() {
272 // return instance.nodeSecurity;
273 // }
274
275 public String[] getLocales() {
276 // TODO optimize?
277 List<Locale> locales = getNodeState().getLocales();
278 String[] res = new String[locales.size()];
279 for (int i = 0; i < locales.size(); i++)
280 res[i] = locales.get(i).toString();
281 return res;
282 }
283
284 static BundleContext getBundleContext() {
285 return bundleContext;
286 }
287
288 public static void main(String[] args) {
289 instance = new Activator();
290 instance.init();
291 }
292
293 }