1 package org
.argeo
.cms
.internal
.kernel
;
3 import static org
.argeo
.cms
.internal
.kernel
.KernelUtils
.getOsgiInstanceDir
;
6 import java
.io
.IOException
;
8 import java
.security
.KeyStore
;
9 import java
.security
.Provider
;
10 import java
.security
.Security
;
11 import java
.util
.Arrays
;
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
.auth
.AuthConstants
;
27 import org
.bouncycastle
.jce
.provider
.BouncyCastleProvider
;
29 /** Low-level kernel security */
30 class NodeSecurity
implements KernelConstants
{
31 public final static int HARDENED
= 3;
32 public final static int STAGING
= 2;
33 public final static int DEV
= 1;
35 private final boolean firstInit
;
37 private final Subject kernelSubject
;
38 private int securityLevel
= STAGING
;
40 private final File keyStoreFile
;
42 public NodeSecurity() {
43 // Configure JAAS first
44 URL url
= getClass().getClassLoader().getResource(
45 KernelConstants
.JAAS_CONFIG
);
46 System
.setProperty("java.security.auth.login.config",
47 url
.toExternalForm());
48 // log.debug("JASS config: " + url.toExternalForm());
49 // disable Jetty autostart
50 // System.setProperty("org.eclipse.equinox.http.jetty.autostart",
53 firstInit
= !new File(getOsgiInstanceDir(), DIR_NODE
).exists();
55 this.keyStoreFile
= new File(KernelUtils
.getOsgiInstanceDir(),
57 this.kernelSubject
= logInKernel();
60 private Subject
logInKernel() {
61 final Subject kernelSubject
= new Subject();
62 createKeyStoreIfNeeded();
64 CallbackHandler cbHandler
= new CallbackHandler() {
67 public void handle(Callback
[] callbacks
) throws IOException
,
68 UnsupportedCallbackException
{
70 ((NameCallback
) callbacks
[1])
71 .setName(AuthConstants
.ROLE_KERNEL
);
73 ((PasswordCallback
) callbacks
[2]).setPassword("changeit"
76 ((PasswordCallback
) callbacks
[3]).setPassword("changeit"
81 LoginContext kernelLc
= new LoginContext(
82 KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
,
85 } catch (LoginException e
) {
86 throw new CmsException("Cannot log in kernel", e
);
94 LoginContext kernelLc
= new LoginContext(
95 KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
);
97 } catch (LoginException e
) {
98 throw new CmsException("Cannot log out kernel", e
);
101 Security
.removeProvider(SECURITY_PROVIDER
);
104 public Subject
getKernelSubject() {
105 return kernelSubject
;
108 public synchronized int getSecurityLevel() {
109 return securityLevel
;
112 public boolean isFirstInit() {
116 public void setSecurityLevel(int newValue
) {
117 if (newValue
!= STAGING
|| newValue
!= DEV
)
118 throw new CmsException("Invalid value for security level "
120 if (newValue
>= securityLevel
)
121 throw new CmsException(
122 "Impossible to increase security level (from "
123 + securityLevel
+ " to " + newValue
+ ")");
124 securityLevel
= newValue
;
127 private void createKeyStoreIfNeeded() {
128 char[] ksPwd
= "changeit".toCharArray();
129 char[] keyPwd
= Arrays
.copyOf(ksPwd
, ksPwd
.length
);
130 if (!keyStoreFile
.exists()) {
132 keyStoreFile
.getParentFile().mkdirs();
133 KeyStore keyStore
= PkiUtils
.getKeyStore(keyStoreFile
, ksPwd
);
134 PkiUtils
.generateSelfSignedCertificate(keyStore
,
135 new X500Principal(AuthConstants
.ROLE_KERNEL
), keyPwd
);
136 PkiUtils
.saveKeyStore(keyStoreFile
, ksPwd
, keyStore
);
137 } catch (Exception e
) {
138 throw new CmsException("Cannot create key store "
144 File
getHttpServerKeyStore() {
148 private final static String SECURITY_PROVIDER
= "BC";// Bouncy Castle
149 private final static Log log
;
151 log
= LogFactory
.getLog(NodeSecurity
.class);
152 // Make Bouncy Castle the default provider
153 Provider provider
= new BouncyCastleProvider();
154 int position
= Security
.insertProviderAt(provider
, 1);
156 log
.error("Provider " + provider
.getName()
157 + " already installed and could not be set as default");
158 Provider defaultProvider
= Security
.getProviders()[0];
159 if (!defaultProvider
.getName().equals(SECURITY_PROVIDER
))
160 log
.error("Provider name is " + defaultProvider
.getName()
161 + " but it should be " + SECURITY_PROVIDER
);