1 package org
.argeo
.cms
.internal
.kernel
;
3 import java
.io
.IOException
;
5 import java
.nio
.file
.Files
;
6 import java
.nio
.file
.Path
;
7 import java
.security
.AllPermission
;
8 import java
.util
.Dictionary
;
10 import java
.util
.Locale
;
11 import java
.util
.concurrent
.ExecutorService
;
12 import java
.util
.concurrent
.Executors
;
14 import javax
.security
.auth
.login
.Configuration
;
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
;
42 * Activates the kernel. Gives access to kernel information for the rest of the
43 * bundle (and only it)
45 public class Activator
implements BundleActivator
{
46 private final static Log log
= LogFactory
.getLog(Activator
.class);
48 private static Activator instance
;
50 // TODO make it configurable
51 private boolean hardened
= false;
53 private BundleContext bc
;
55 private LogReaderService logReaderService
;
57 private NodeLogger logger
;
58 private CmsState nodeState
;
59 private CmsDeployment nodeDeployment
;
60 private CmsInstance nodeInstance
;
62 private ServiceTracker
<UserAdmin
, NodeUserAdmin
> userAdminSt
;
63 private ExecutorService internalExecutorService
;
66 public void start(BundleContext bundleContext
) throws Exception
{
67 Runtime
.getRuntime().addShutdownHook(new CmsShutdown());
69 this.bc
= bundleContext
;
70 this.logReaderService
= getService(LogReaderService
.class);
71 this.internalExecutorService
= Executors
.newFixedThreadPool(Runtime
.getRuntime().availableProcessors());
78 userAdminSt
= new ServiceTracker
<>(instance
.bc
, UserAdmin
.class, null);
80 if (log
.isTraceEnabled())
81 log
.trace("Kernel bundle started");
82 } catch (Throwable e
) {
83 log
.error("## FATAL: CMS activator failed", e
);
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
);
95 // explicitly load JAAS configuration
96 Configuration
.getConfiguration();
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));
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));
125 SecurityProfile securityProfile
= new SecurityProfile() {
127 securityProfile
.applySystemPermissions(permissionAdmin
);
133 private void initArgeoLogger() {
134 logger
= new NodeLogger(logReaderService
);
135 bc
.registerService(ArgeoLogger
.class, logger
, null);
138 private void initNode() throws IOException
{
140 Path stateUuidPath
= bc
.getDataFile("stateUuid").toPath();
142 if (Files
.exists(stateUuidPath
)) {
143 stateUuid
= Files
.readAllLines(stateUuidPath
).get(0);
145 stateUuid
= bc
.getProperty(Constants
.FRAMEWORK_UUID
);
146 Files
.write(stateUuidPath
, stateUuid
.getBytes());
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
);
154 nodeDeployment
= new CmsDeployment();
155 bc
.registerService(NodeDeployment
.class, nodeDeployment
, null);
158 nodeInstance
= new CmsInstance();
159 bc
.registerService(NodeInstance
.class, nodeInstance
, null);
163 public void stop(BundleContext bundleContext
) throws Exception
{
165 if (nodeInstance
!= null)
166 nodeInstance
.shutdown();
167 if (nodeDeployment
!= null)
168 nodeDeployment
.shutdown();
169 if (nodeState
!= null)
170 nodeState
.shutdown();
172 if (userAdminSt
!= null)
175 internalExecutorService
.shutdown();
178 this.logReaderService
= null;
179 // this.configurationAdmin = null;
180 } catch (Exception e
) {
181 log
.error("CMS activator shutdown failed", e
);
185 private <T
> T
getService(Class
<T
> clazz
) {
186 ServiceReference
<T
> sr
= bc
.getServiceReference(clazz
);
188 throw new CmsException("No service available for " + clazz
);
189 return bc
.getService(sr
);
192 public static NodeState
getNodeState() {
193 return instance
.nodeState
;
196 public static GSSCredential
getAcceptorCredentials() {
197 return getNodeUserAdmin().getAcceptorCredentials();
200 public static boolean isSingleUser() {
201 return getNodeUserAdmin().isSingleUser();
204 public static UserAdmin
getUserAdmin() {
205 return (UserAdmin
) getNodeUserAdmin();
208 public static String
getHttpProxySslHeader() {
209 return KernelUtils
.getFrameworkProp(NodeConstants
.HTTP_PROXY_SSL_DN
);
212 public static IdentClient
getIdentClient(String remoteAddr
) {
213 if (!IdentClient
.isDefaultAuthdPassphraseFileAvailable())
215 // TODO make passphrase more configurable
216 return new IdentClient(remoteAddr
);
219 private static NodeUserAdmin
getNodeUserAdmin() {
222 res
= instance
.userAdminSt
.waitForService(60000);
223 } catch (InterruptedException e
) {
224 throw new CmsException("Cannot retrieve Node user admin", e
);
227 throw new CmsException("No Node user admin found");
230 // ServiceReference<UserAdmin> sr =
231 // instance.bc.getServiceReference(UserAdmin.class);
232 // NodeUserAdmin userAdmin = (NodeUserAdmin) instance.bc.getService(sr);
237 static ExecutorService
getInternalExecutorService() {
238 return instance
.internalExecutorService
;
241 // static CmsSecurity getCmsSecurity() {
242 // return instance.nodeSecurity;
245 public String
[] getLocales() {
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();