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
.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
;
26 /** Low-level kernel security */
28 class NodeSecurity
implements KernelConstants
{
29 private final static Log log
= LogFactory
.getLog(NodeSecurity
.class);
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(KernelConstants
.JAAS_CONFIG
);
45 System
.setProperty("java.security.auth.login.config", url
.toExternalForm());
46 // log.debug("JASS config: " + url.toExternalForm());
47 // disable Jetty autostart
48 // System.setProperty("org.eclipse.equinox.http.jetty.autostart",
51 firstInit
= !new File(getOsgiInstanceDir(), DIR_NODE
).exists();
53 this.keyStoreFile
= new File(KernelUtils
.getOsgiInstanceDir(), "node.p12");
54 createKeyStoreIfNeeded();
55 if (keyStoreFile
.exists())
56 this.kernelSubject
= logInHardenedKernel();
58 this.kernelSubject
= logInKernel();
61 private Subject
logInKernel() {
62 final Subject kernelSubject
= new Subject();
64 LoginContext kernelLc
= new LoginContext(KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
);
66 } catch (LoginException e
) {
67 throw new CmsException("Cannot log in kernel", e
);
72 private Subject
logInHardenedKernel() {
73 final Subject kernelSubject
= new Subject();
74 createKeyStoreIfNeeded();
76 CallbackHandler cbHandler
= new CallbackHandler() {
79 public void handle(Callback
[] callbacks
) throws IOException
, UnsupportedCallbackException
{
81 // ((NameCallback) callbacks[1]).setName(AuthConstants.ROLE_KERNEL);
83 ((PasswordCallback
) callbacks
[2]).setPassword("changeit".toCharArray());
85 ((PasswordCallback
) callbacks
[3]).setPassword("changeit".toCharArray());
89 LoginContext kernelLc
= new LoginContext(KernelConstants
.LOGIN_CONTEXT_HARDENED_KERNEL
, kernelSubject
,
92 } catch (LoginException e
) {
93 throw new CmsException("Cannot log in kernel", e
);
101 LoginContext kernelLc
= new LoginContext(KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
);
103 } catch (LoginException e
) {
104 throw new CmsException("Cannot log out kernel", e
);
107 // Security.removeProvider(SECURITY_PROVIDER);
110 public Subject
getKernelSubject() {
111 return kernelSubject
;
114 public synchronized int getSecurityLevel() {
115 return securityLevel
;
118 public boolean isFirstInit() {
122 public void setSecurityLevel(int newValue
) {
123 if (newValue
!= STAGING
|| newValue
!= DEV
)
124 throw new CmsException("Invalid value for security level " + newValue
);
125 if (newValue
>= securityLevel
)
126 throw new CmsException(
127 "Impossible to increase security level (from " + securityLevel
+ " to " + newValue
+ ")");
128 securityLevel
= newValue
;
131 private void createKeyStoreIfNeeded() {
132 // for (Provider provider : Security.getProviders())
133 // System.out.println(provider.getName());
135 char[] ksPwd
= "changeit".toCharArray();
136 char[] keyPwd
= Arrays
.copyOf(ksPwd
, ksPwd
.length
);
137 if (!keyStoreFile
.exists()) {
139 keyStoreFile
.getParentFile().mkdirs();
140 KeyStore keyStore
= PkiUtils
.getKeyStore(keyStoreFile
, ksPwd
);
141 // PkiUtils.generateSelfSignedCertificate(keyStore, new X500Principal(AuthConstants.ROLE_KERNEL), 1024,
143 PkiUtils
.saveKeyStore(keyStoreFile
, ksPwd
, keyStore
);
144 if (log
.isDebugEnabled())
145 log
.debug("Created keystore " + keyStoreFile
);
146 } catch (Exception e
) {
147 if (keyStoreFile
.length() == 0)
148 keyStoreFile
.delete();
149 log
.error("Cannot create keystore " + keyStoreFile
, e
);
154 File
getHttpServerKeyStore() {
158 // private final static String SECURITY_PROVIDER = "BC";// Bouncy Castle
159 // private final static Log log;
161 // log = LogFactory.getLog(NodeSecurity.class);
162 // // Make Bouncy Castle the default provider
163 // Provider provider = new BouncyCastleProvider();
164 // int position = Security.insertProviderAt(provider, 1);
165 // if (position == -1)
166 // log.error("Provider " + provider.getName()
167 // + " already installed and could not be set as default");
168 // Provider defaultProvider = Security.getProviders()[0];
169 // if (!defaultProvider.getName().equals(SECURITY_PROVIDER))
170 // log.error("Provider name is " + defaultProvider.getName()
171 // + " but it should be " + SECURITY_PROVIDER);