1 package org
.argeo
.cms
.internal
.kernel
;
4 import java
.io
.IOException
;
6 import java
.nio
.file
.ProviderNotFoundException
;
7 import java
.security
.KeyStore
;
8 import java
.security
.Provider
;
9 import java
.security
.Security
;
10 import java
.util
.Arrays
;
11 import java
.util
.Hashtable
;
13 import javax
.security
.auth
.Subject
;
14 import javax
.security
.auth
.callback
.Callback
;
15 import javax
.security
.auth
.callback
.CallbackHandler
;
16 import javax
.security
.auth
.callback
.NameCallback
;
17 import javax
.security
.auth
.callback
.PasswordCallback
;
18 import javax
.security
.auth
.callback
.UnsupportedCallbackException
;
19 import javax
.security
.auth
.login
.LoginContext
;
20 import javax
.security
.auth
.login
.LoginException
;
21 import javax
.security
.auth
.x500
.X500Principal
;
23 import org
.apache
.commons
.logging
.Log
;
24 import org
.apache
.commons
.logging
.LogFactory
;
25 import org
.argeo
.cms
.CmsException
;
26 import org
.argeo
.cms
.KernelHeader
;
27 import org
.argeo
.security
.crypto
.PkiUtils
;
28 import org
.bouncycastle
.jce
.provider
.BouncyCastleProvider
;
29 import org
.osgi
.framework
.BundleContext
;
30 import org
.osgi
.framework
.ServiceRegistration
;
31 import org
.osgi
.service
.useradmin
.UserAdmin
;
33 /** Authentication and user management. */
35 private final static Log log
;
37 log
= LogFactory
.getLog(NodeSecurity
.class);
38 // Make Bouncy Castle the default provider
39 Provider provider
= new BouncyCastleProvider();
40 int position
= Security
.insertProviderAt(provider
, 1);
42 log
.error("Provider " + provider
.getName()
43 + " already installed and could not be set as default");
44 Provider defaultProvider
= Security
.getProviders()[0];
45 if (!defaultProvider
.getName().equals(KernelHeader
.SECURITY_PROVIDER
))
46 log
.error("Provider name is " + defaultProvider
.getName()
47 + " but it should be " + KernelHeader
.SECURITY_PROVIDER
);
50 private final BundleContext bundleContext
;
51 private final NodeUserAdmin userAdmin
;
52 private final Subject kernelSubject
;
54 private ServiceRegistration
<UserAdmin
> userAdminReg
;
56 public NodeSecurity(BundleContext bundleContext
) {
57 // Configure JAAS first
58 URL url
= getClass().getClassLoader().getResource(
59 KernelConstants
.JAAS_CONFIG
);
60 System
.setProperty("java.security.auth.login.config",
61 url
.toExternalForm());
63 this.bundleContext
= bundleContext
;
64 this.kernelSubject
= logKernel();
65 userAdmin
= new NodeUserAdmin();
68 private Subject
logKernel() {
69 final Subject kernelSubject
= new Subject();
70 createKeyStoreIfNeeded();
72 CallbackHandler cbHandler
= new CallbackHandler() {
75 public void handle(Callback
[] callbacks
) throws IOException
,
76 UnsupportedCallbackException
{
78 ((NameCallback
) callbacks
[1]).setName(KernelHeader
.ROLE_KERNEL
);
80 ((PasswordCallback
) callbacks
[2]).setPassword("changeit"
83 ((PasswordCallback
) callbacks
[3]).setPassword("changeit"
88 LoginContext kernelLc
= new LoginContext(
89 KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
,
92 } catch (LoginException e
) {
93 throw new CmsException("Cannot log in kernel", e
);
98 public void publish() {
99 userAdminReg
= bundleContext
.registerService(UserAdmin
.class,
100 userAdmin
, userAdmin
.currentState());
105 userAdminReg
.unregister();
109 LoginContext kernelLc
= new LoginContext(
110 KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
);
112 } catch (LoginException e
) {
113 throw new CmsException("Cannot log in kernel", e
);
116 Security
.removeProvider(KernelHeader
.SECURITY_PROVIDER
);
119 public NodeUserAdmin
getUserAdmin() {
123 public Subject
getKernelSubject() {
124 return kernelSubject
;
127 private void createKeyStoreIfNeeded() {
128 char[] ksPwd
= "changeit".toCharArray();
129 char[] keyPwd
= Arrays
.copyOf(ksPwd
, ksPwd
.length
);
130 File keyStoreFile
= new File(KernelUtils
.getOsgiInstanceDir(),
132 if (!keyStoreFile
.exists()) {
134 keyStoreFile
.getParentFile().mkdirs();
135 KeyStore keyStore
= PkiUtils
.getKeyStore(keyStoreFile
, ksPwd
);
136 PkiUtils
.generateSelfSignedCertificate(keyStore
,
137 new X500Principal(KernelHeader
.ROLE_KERNEL
), keyPwd
);
138 PkiUtils
.saveKeyStore(keyStoreFile
, ksPwd
, keyStore
);
139 } catch (Exception e
) {
140 throw new CmsException("Cannot create key store "