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