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 */
27 class NodeSecurity
implements KernelConstants
{
28 private final static Log log
= LogFactory
.getLog(NodeSecurity
.class);
30 public final static int HARDENED
= 3;
31 public final static int STAGING
= 2;
32 public final static int DEV
= 1;
34 private final boolean firstInit
;
36 private final Subject kernelSubject
;
37 private int securityLevel
= STAGING
;
39 private final File keyStoreFile
;
41 public NodeSecurity() {
42 // Configure JAAS first
43 URL url
= getClass().getClassLoader().getResource(KernelConstants
.JAAS_CONFIG
);
44 System
.setProperty("java.security.auth.login.config", url
.toExternalForm());
45 // log.debug("JASS config: " + url.toExternalForm());
46 // disable Jetty autostart
47 // System.setProperty("org.eclipse.equinox.http.jetty.autostart",
50 firstInit
= !new File(getOsgiInstanceDir(), DIR_NODE
).exists();
52 this.keyStoreFile
= new File(KernelUtils
.getOsgiInstanceDir(), "node.p12");
53 createKeyStoreIfNeeded();
54 if (keyStoreFile
.exists())
55 this.kernelSubject
= logInHardenedKernel();
57 this.kernelSubject
= logInKernel();
60 private Subject
logInKernel() {
61 final Subject kernelSubject
= new Subject();
63 LoginContext kernelLc
= new LoginContext(KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
);
65 } catch (LoginException e
) {
66 throw new CmsException("Cannot log in kernel", e
);
71 private Subject
logInHardenedKernel() {
72 final Subject kernelSubject
= new Subject();
73 createKeyStoreIfNeeded();
75 CallbackHandler cbHandler
= new CallbackHandler() {
78 public void handle(Callback
[] callbacks
) throws IOException
, UnsupportedCallbackException
{
80 ((NameCallback
) callbacks
[1]).setName(AuthConstants
.ROLE_KERNEL
);
82 ((PasswordCallback
) callbacks
[2]).setPassword("changeit".toCharArray());
84 ((PasswordCallback
) callbacks
[3]).setPassword("changeit".toCharArray());
88 LoginContext kernelLc
= new LoginContext(KernelConstants
.LOGIN_CONTEXT_HARDENED_KERNEL
, kernelSubject
,
91 } catch (LoginException e
) {
92 throw new CmsException("Cannot log in kernel", e
);
100 LoginContext kernelLc
= new LoginContext(KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
);
102 } catch (LoginException e
) {
103 throw new CmsException("Cannot log out kernel", e
);
106 // Security.removeProvider(SECURITY_PROVIDER);
109 public Subject
getKernelSubject() {
110 return kernelSubject
;
113 public synchronized int getSecurityLevel() {
114 return securityLevel
;
117 public boolean isFirstInit() {
121 public void setSecurityLevel(int newValue
) {
122 if (newValue
!= STAGING
|| newValue
!= DEV
)
123 throw new CmsException("Invalid value for security level " + newValue
);
124 if (newValue
>= securityLevel
)
125 throw new CmsException(
126 "Impossible to increase security level (from " + securityLevel
+ " to " + newValue
+ ")");
127 securityLevel
= newValue
;
130 private void createKeyStoreIfNeeded() {
131 // for (Provider provider : Security.getProviders())
132 // System.out.println(provider.getName());
134 char[] ksPwd
= "changeit".toCharArray();
135 char[] keyPwd
= Arrays
.copyOf(ksPwd
, ksPwd
.length
);
136 if (!keyStoreFile
.exists()) {
138 keyStoreFile
.getParentFile().mkdirs();
139 KeyStore keyStore
= PkiUtils
.getKeyStore(keyStoreFile
, ksPwd
);
140 PkiUtils
.generateSelfSignedCertificate(keyStore
, new X500Principal(AuthConstants
.ROLE_KERNEL
), 1024,
142 PkiUtils
.saveKeyStore(keyStoreFile
, ksPwd
, keyStore
);
143 if (log
.isDebugEnabled())
144 log
.debug("Created keystore " + keyStoreFile
);
145 } catch (Exception e
) {
146 if (keyStoreFile
.length() == 0)
147 keyStoreFile
.delete();
148 log
.error("Cannot create keystore " + keyStoreFile
, e
);
153 File
getHttpServerKeyStore() {
157 // private final static String SECURITY_PROVIDER = "BC";// Bouncy Castle
158 // private final static Log log;
160 // log = LogFactory.getLog(NodeSecurity.class);
161 // // Make Bouncy Castle the default provider
162 // Provider provider = new BouncyCastleProvider();
163 // int position = Security.insertProviderAt(provider, 1);
164 // if (position == -1)
165 // log.error("Provider " + provider.getName()
166 // + " already installed and could not be set as default");
167 // Provider defaultProvider = Security.getProviders()[0];
168 // if (!defaultProvider.getName().equals(SECURITY_PROVIDER))
169 // log.error("Provider name is " + defaultProvider.getName()
170 // + " but it should be " + SECURITY_PROVIDER);