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
;
32 import org
.springframework
.security
.authentication
.AuthenticationManager
;
33 import org
.springframework
.security
.core
.Authentication
;
34 import org
.springframework
.security
.core
.AuthenticationException
;
36 /** Authentication and user management. */
37 class NodeSecurity
implements AuthenticationManager
{
38 private final static Log log
;
40 log
= LogFactory
.getLog(NodeSecurity
.class);
41 // Make Bouncy Castle the default provider
42 Provider provider
= new BouncyCastleProvider();
43 int position
= Security
.insertProviderAt(provider
, 1);
45 log
.error("Provider " + provider
.getName()
46 + " already installed and could not be set as default");
47 Provider defaultProvider
= Security
.getProviders()[0];
48 if (!defaultProvider
.getName().equals(KernelHeader
.SECURITY_PROVIDER
))
49 log
.error("Provider name is " + defaultProvider
.getName()
50 + " but it should be " + KernelHeader
.SECURITY_PROVIDER
);
53 private final BundleContext bundleContext
;
54 private final NodeUserAdmin userAdmin
;
55 private final Subject kernelSubject
;
57 private ServiceRegistration
<AuthenticationManager
> authenticationManagerReg
;
59 private ServiceRegistration
<UserAdmin
> userAdminReg
;
61 public NodeSecurity(BundleContext bundleContext
) {
62 // Configure JAAS first
63 URL url
= getClass().getClassLoader().getResource(
64 KernelConstants
.JAAS_CONFIG
);
65 System
.setProperty("java.security.auth.login.config",
66 url
.toExternalForm());
68 this.bundleContext
= bundleContext
;
69 this.kernelSubject
= logKernel();
70 userAdmin
= new NodeUserAdmin();
73 private Subject
logKernel() {
74 final Subject kernelSubject
= new Subject();
75 createKeyStoreIfNeeded();
77 CallbackHandler cbHandler
= new CallbackHandler() {
80 public void handle(Callback
[] callbacks
) throws IOException
,
81 UnsupportedCallbackException
{
83 ((NameCallback
) callbacks
[1]).setName(KernelHeader
.ROLE_KERNEL
);
85 ((PasswordCallback
) callbacks
[2]).setPassword("changeit"
88 ((PasswordCallback
) callbacks
[3]).setPassword("changeit"
93 LoginContext kernelLc
= new LoginContext(
94 KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
,
97 } catch (LoginException e
) {
98 throw new CmsException("Cannot log in kernel", e
);
100 return kernelSubject
;
103 public void publish() {
104 userAdminReg
= bundleContext
.registerService(UserAdmin
.class,
105 userAdmin
, userAdmin
.currentState());
106 // dummy auth manager, in order to smooth transition from Argeo 1
107 authenticationManagerReg
= bundleContext
.registerService(
108 AuthenticationManager
.class, this, null);
112 authenticationManagerReg
.unregister();
115 userAdminReg
.unregister();
119 LoginContext kernelLc
= new LoginContext(
120 KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
);
122 } catch (LoginException e
) {
123 throw new CmsException("Cannot log in kernel", e
);
126 Security
.removeProvider(KernelHeader
.SECURITY_PROVIDER
);
129 public NodeUserAdmin
getUserAdmin() {
133 public Subject
getKernelSubject() {
134 return kernelSubject
;
138 public Authentication
authenticate(Authentication authentication
)
139 throws AuthenticationException
{
140 log
.error("Authentication manager is deprecated and should not be used.");
141 throw new ProviderNotFoundException(
142 "Authentication manager is deprecated and should not be used.");
145 private void createKeyStoreIfNeeded() {
146 char[] ksPwd
= "changeit".toCharArray();
147 char[] keyPwd
= Arrays
.copyOf(ksPwd
, ksPwd
.length
);
148 File keyStoreFile
= new File(KernelUtils
.getOsgiInstanceDir(),
150 if (!keyStoreFile
.exists()) {
152 keyStoreFile
.getParentFile().mkdirs();
153 KeyStore keyStore
= PkiUtils
.getKeyStore(keyStoreFile
, ksPwd
);
154 PkiUtils
.generateSelfSignedCertificate(keyStore
,
155 new X500Principal(KernelHeader
.ROLE_KERNEL
), keyPwd
);
156 PkiUtils
.saveKeyStore(keyStoreFile
, ksPwd
, keyStore
);
157 } catch (Exception e
) {
158 throw new CmsException("Cannot create key store "