1 package org
.argeo
.cms
.internal
.kernel
;
4 import java
.io
.IOException
;
6 import java
.security
.KeyStore
;
7 import java
.security
.Provider
;
8 import java
.security
.Security
;
9 import java
.util
.Arrays
;
11 import javax
.security
.auth
.Subject
;
12 import javax
.security
.auth
.callback
.Callback
;
13 import javax
.security
.auth
.callback
.CallbackHandler
;
14 import javax
.security
.auth
.callback
.NameCallback
;
15 import javax
.security
.auth
.callback
.PasswordCallback
;
16 import javax
.security
.auth
.callback
.UnsupportedCallbackException
;
17 import javax
.security
.auth
.login
.LoginContext
;
18 import javax
.security
.auth
.login
.LoginException
;
19 import javax
.security
.auth
.x500
.X500Principal
;
21 import org
.apache
.commons
.logging
.Log
;
22 import org
.apache
.commons
.logging
.LogFactory
;
23 import org
.argeo
.cms
.CmsException
;
24 import org
.argeo
.cms
.auth
.AuthConstants
;
25 import org
.bouncycastle
.jce
.provider
.BouncyCastleProvider
;
27 /** Low-level kernel security */
29 public final static int HARDENED
= 3;
30 public final static int STAGING
= 2;
31 public final static int DEV
= 1;
33 final static String SECURITY_PROVIDER
= "BC";// Bouncy Castle
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(SECURITY_PROVIDER
))
46 log
.error("Provider name is " + defaultProvider
.getName()
47 + " but it should be " + SECURITY_PROVIDER
);
50 private final Subject kernelSubject
;
51 private int securityLevel
= STAGING
;
53 public NodeSecurity() {
54 // Configure JAAS first
55 URL url
= getClass().getClassLoader().getResource(
56 KernelConstants
.JAAS_CONFIG
);
57 System
.setProperty("java.security.auth.login.config",
58 url
.toExternalForm());
60 this.kernelSubject
= logInKernel();
63 private Subject
logInKernel() {
64 final Subject kernelSubject
= new Subject();
65 createKeyStoreIfNeeded();
67 CallbackHandler cbHandler
= new CallbackHandler() {
70 public void handle(Callback
[] callbacks
) throws IOException
,
71 UnsupportedCallbackException
{
73 ((NameCallback
) callbacks
[1])
74 .setName(AuthConstants
.ROLE_KERNEL
);
76 ((PasswordCallback
) callbacks
[2]).setPassword("changeit"
79 ((PasswordCallback
) callbacks
[3]).setPassword("changeit"
84 LoginContext kernelLc
= new LoginContext(
85 KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
,
88 } catch (LoginException e
) {
89 throw new CmsException("Cannot log in kernel", e
);
97 LoginContext kernelLc
= new LoginContext(
98 KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
);
100 } catch (LoginException e
) {
101 throw new CmsException("Cannot log out kernel", e
);
104 Security
.removeProvider(SECURITY_PROVIDER
);
107 public Subject
getKernelSubject() {
108 return kernelSubject
;
111 public synchronized int getSecurityLevel() {
112 return securityLevel
;
115 public void setSecurityLevel(int newValue
) {
116 if (newValue
!= STAGING
|| newValue
!= DEV
)
117 throw new CmsException("Invalid value for security level "
119 if (newValue
>= securityLevel
)
120 throw new CmsException(
121 "Impossible to increase security level (from "
122 + securityLevel
+ " to " + newValue
+ ")");
123 securityLevel
= newValue
;
126 private void createKeyStoreIfNeeded() {
127 char[] ksPwd
= "changeit".toCharArray();
128 char[] keyPwd
= Arrays
.copyOf(ksPwd
, ksPwd
.length
);
129 File keyStoreFile
= new File(KernelUtils
.getOsgiInstanceDir(),
131 if (!keyStoreFile
.exists()) {
133 keyStoreFile
.getParentFile().mkdirs();
134 KeyStore keyStore
= PkiUtils
.getKeyStore(keyStoreFile
, ksPwd
);
135 PkiUtils
.generateSelfSignedCertificate(keyStore
,
136 new X500Principal(AuthConstants
.ROLE_KERNEL
), keyPwd
);
137 PkiUtils
.saveKeyStore(keyStoreFile
, ksPwd
, keyStore
);
138 } catch (Exception e
) {
139 throw new CmsException("Cannot create key store "