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