+++ /dev/null
-package org.argeo.cms.internal.kernel;
-
-import java.io.IOException;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.auth.kerberos.KerberosPrincipal;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
-import org.apache.commons.httpclient.auth.AuthPolicy;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-import org.apache.commons.httpclient.cookie.CookiePolicy;
-import org.apache.commons.httpclient.params.DefaultHttpParams;
-import org.apache.commons.httpclient.params.HttpMethodParams;
-import org.apache.commons.httpclient.params.HttpParams;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.CmsException;
-import org.argeo.cms.internal.http.NodeHttp;
-import org.argeo.cms.internal.http.client.SpnegoAuthScheme;
-import org.argeo.cms.internal.http.client.HttpCredentialProvider;
-import org.argeo.naming.DnsBrowser;
-import org.argeo.node.NodeConstants;
-import org.ietf.jgss.GSSCredential;
-import org.ietf.jgss.GSSException;
-import org.ietf.jgss.GSSManager;
-import org.ietf.jgss.GSSName;
-import org.ietf.jgss.Oid;
-
-/** Low-level kernel security */
-@Deprecated
-public class CmsSecurity implements KernelConstants {
- private final static Log log = LogFactory.getLog(CmsSecurity.class);
- // http://java.sun.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
- private final static Oid KERBEROS_OID;
- static {
- try {
- KERBEROS_OID = new Oid("1.3.6.1.5.5.2");
- } catch (GSSException e) {
- throw new IllegalStateException("Cannot create Kerberos OID", e);
- }
- }
-
- public final static int DEPLOYED = 30;
- public final static int STANDALONE = 20;
- public final static int DEV = 10;
- public final static int UNKNOWN = 0;
-
- private String hostname;
-
- private final int securityLevel;
- private Subject nodeSubject;
-
- // IPA
- private String kerberosDomain;
- private String service = null;
- private GSSCredential acceptorCredentials;
-
- private Path nodeKeyTab = KernelUtils.getOsgiInstancePath(KernelConstants.NODE_KEY_TAB_PATH);
-
- CmsSecurity() {
-
- if (!DeployConfig.isInitialized()) // first init
- FirstInit.prepareInstanceArea();
-
- securityLevel = evaluateSecurityLevel();
-
- if (securityLevel == DEPLOYED) {
- // Register client-side SPNEGO auth scheme
- AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class);
- HttpParams params = DefaultHttpParams.getDefaultParams();
- ArrayList<String> schemes = new ArrayList<>();
- schemes.add(SpnegoAuthScheme.NAME);// SPNEGO preferred
- // schemes.add(AuthPolicy.BASIC);// incompatible with Basic
- params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
- params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider());
- params.setParameter(HttpMethodParams.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
- // params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
- }
-
- // Configure JAAS first
- if (System.getProperty(JAAS_CONFIG_PROP) == null) {
- String jaasConfig = securityLevel < DEPLOYED ? JAAS_CONFIG : JAAS_CONFIG_IPA;
- URL url = getClass().getClassLoader().getResource(jaasConfig);
- System.setProperty(JAAS_CONFIG_PROP, url.toExternalForm());
- }
- // explicitly load JAAS configuration
- Configuration.getConfiguration();
- nodeSubject = logInKernel();
-
- // firstInit = !new File(getOsgiInstanceDir(), DIR_NODE).exists();
-
- // this.keyStoreFile = new File(KernelUtils.getOsgiInstanceDir(),
- // "node.p12");
- // createKeyStoreIfNeeded();
- }
-
- private int evaluateSecurityLevel() {
- int res = UNKNOWN;
- try (DnsBrowser dnsBrowser = new DnsBrowser()) {
- InetAddress localhost = InetAddress.getLocalHost();
- hostname = localhost.getHostName();
- String dnsZone = hostname.substring(hostname.indexOf('.') + 1);
- String ipfromDns = dnsBrowser.getRecord(hostname, localhost instanceof Inet6Address ? "AAAA" : "A");
- boolean consistentIp = localhost.getHostAddress().equals(ipfromDns);
- kerberosDomain = dnsBrowser.getRecord("_kerberos." + dnsZone, "TXT");
- if (consistentIp && kerberosDomain != null && Files.exists(nodeKeyTab)) {
- res = DEPLOYED;
- } else {
- res = STANDALONE;
- kerberosDomain = null;
- // FIXME make state more robust
- }
- } catch (UnknownHostException e) {
- hostname = "localhost";
- log.warn("Cannot determine hostname, using " + hostname + ":" + e.getMessage());
- res = STANDALONE;
- } catch (Exception e) {
- log.warn("Exception when evaluating security level, setting it to DEV", e);
- res = DEV;
- }
-
- if (res == UNKNOWN)
- throw new CmsException("Undefined security level");
- return res;
- }
-
- private Subject logInKernel() {
- final Subject nodeSubject = new Subject();
-
- CallbackHandler callbackHandler;
- if (Files.exists(nodeKeyTab)) {
- service = NodeHttp.DEFAULT_SERVICE;
- // service = NodeConstants.NODE_SERVICE;
- callbackHandler = new CallbackHandler() {
-
- @Override
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
- for (Callback callback : callbacks)
- if (callback instanceof NameCallback)
- ((NameCallback) callback).setName(getKerberosServicePrincipal());
-
- }
- };
- try {
- LoginContext kernelLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_NODE, nodeSubject,
- callbackHandler);
- kernelLc.login();
- } catch (LoginException e) {
- throw new CmsException("Cannot log in kernel", e);
- }
- } else {
- callbackHandler = null;
- // try {
- // callbackHandler = (CallbackHandler)
- // Class.forName("com.sun.security.auth.callback.TextCallbackHandler")
- // .newInstance();
- // } catch (ReflectiveOperationException e) {
- // throw new CmsException("Cannot create text callback handler", e);
- // }
- try {
- LoginContext kernelLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_NODE, nodeSubject);
- kernelLc.login();
- } catch (LoginException e) {
- throw new CmsException("Cannot log in kernel", e);
- }
- }
-
- if (securityLevel >= DEPLOYED) {
- acceptorCredentials = logInAsAcceptor(nodeSubject);
- }
- return nodeSubject;
- }
-
- private String getKerberosServicePrincipal() {
- if (hostname == null || "locahost".equals(hostname) || kerberosDomain == null || service == null)
- throw new IllegalStateException("Cannot determine kerberos principal");
- return service + "/" + hostname + "@" + kerberosDomain;
- }
-
- private GSSCredential logInAsAcceptor(Subject nodeSubject) {
- // GSS
- Iterator<KerberosPrincipal> krb5It = nodeSubject.getPrincipals(KerberosPrincipal.class).iterator();
- if (!krb5It.hasNext())
- return null;
- KerberosPrincipal krb5Principal = null;
- while (krb5It.hasNext()) {
- KerberosPrincipal principal = krb5It.next();
- if (service == null && krb5Principal == null)// first as default
- krb5Principal = principal;
- if (service != null && principal.getName().equals(getKerberosServicePrincipal()))
- krb5Principal = principal;
- }
-
- if (krb5Principal == null)
- return null;
-
- GSSManager manager = GSSManager.getInstance();
- try {
- GSSName gssName = manager.createName(krb5Principal.getName(), null);
- GSSCredential serverCredentials = Subject.doAs(nodeSubject, new PrivilegedExceptionAction<GSSCredential>() {
-
- @Override
- public GSSCredential run() throws GSSException {
- return manager.createCredential(gssName, GSSCredential.INDEFINITE_LIFETIME, KERBEROS_OID,
- GSSCredential.ACCEPT_ONLY);
-
- }
-
- });
- if (log.isDebugEnabled())
- log.debug("GSS acceptor configured for " + krb5Principal);
- return serverCredentials;
- } catch (Exception gsse) {
- throw new CmsException("Cannot create acceptor credentials for " + krb5Principal, gsse);
- }
- }
- //
- // private Subject logInHardenedKernel() {
- // final Subject kernelSubject = new Subject();
- // createKeyStoreIfNeeded();
- //
- // CallbackHandler cbHandler = new CallbackHandler() {
- //
- // @Override
- // public void handle(Callback[] callbacks) throws IOException,
- // UnsupportedCallbackException {
- // // alias
- //// ((NameCallback) callbacks[1]).setName(AuthConstants.ROLE_KERNEL);
- // // store pwd
- // ((PasswordCallback) callbacks[2]).setPassword("changeit".toCharArray());
- // // key pwd
- // ((PasswordCallback) callbacks[3]).setPassword("changeit".toCharArray());
- // }
- // };
- // try {
- // LoginContext kernelLc = new
- // LoginContext(KernelConstants.LOGIN_CONTEXT_HARDENED_KERNEL,
- // kernelSubject,
- // cbHandler);
- // kernelLc.login();
- // } catch (LoginException e) {
- // throw new CmsException("Cannot log in kernel", e);
- // }
- // return kernelSubject;
- // }
-
- void destroy() {
- // Logout kernel
- try {
- LoginContext kernelLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_NODE, nodeSubject);
- kernelLc.logout();
- } catch (LoginException e) {
- throw new CmsException("Cannot log out kernel", e);
- }
-
- // Security.removeProvider(SECURITY_PROVIDER);
- }
-
- public synchronized int getSecurityLevel() {
- return securityLevel;
- }
-
-// public String getKerberosDomain() {
-// return kerberosDomain;
-// }
-
-// public Subject getNodeSubject() {
-// return nodeSubject;
-// }
-
-// public GSSCredential getServerCredentials() {
-// return acceptorCredentials;
-// }
-
- // public void setSecurityLevel(int newValue) {
- // if (newValue != STANDALONE || newValue != DEV)
- // throw new CmsException("Invalid value for security level " + newValue);
- // if (newValue >= securityLevel)
- // throw new CmsException(
- // "Impossible to increase security level (from " + securityLevel + " to " +
- // newValue + ")");
- // securityLevel = newValue;
- // }
-
- // private void createKeyStoreIfNeeded() {
- // // for (Provider provider : Security.getProviders())
- // // System.out.println(provider.getName());
- //
- // char[] ksPwd = "changeit".toCharArray();
- // char[] keyPwd = Arrays.copyOf(ksPwd, ksPwd.length);
- // if (!keyStoreFile.exists()) {
- // try {
- // keyStoreFile.getParentFile().mkdirs();
- // KeyStore keyStore = PkiUtils.getKeyStore(keyStoreFile, ksPwd);
- // // PkiUtils.generateSelfSignedCertificate(keyStore, new
- // // X500Principal(AuthConstants.ROLE_KERNEL), 1024,
- // // keyPwd);
- // PkiUtils.saveKeyStore(keyStoreFile, ksPwd, keyStore);
- // if (log.isDebugEnabled())
- // log.debug("Created keystore " + keyStoreFile);
- // } catch (Exception e) {
- // if (keyStoreFile.length() == 0)
- // keyStoreFile.delete();
- // log.error("Cannot create keystore " + keyStoreFile, e);
- // }
- // }
- // }
-
- // private final static String SECURITY_PROVIDER = "BC";// Bouncy Castle
- // private final static Log log;
- // static {
- // log = LogFactory.getLog(NodeSecurity.class);
- // // Make Bouncy Castle the default provider
- // Provider provider = new BouncyCastleProvider();
- // int position = Security.insertProviderAt(provider, 1);
- // if (position == -1)
- // log.error("Provider " + provider.getName()
- // + " already installed and could not be set as default");
- // Provider defaultProvider = Security.getProviders()[0];
- // if (!defaultProvider.getName().equals(SECURITY_PROVIDER))
- // log.error("Provider name is " + defaultProvider.getName()
- // + " but it should be " + SECURITY_PROVIDER);
- // }
-}