Multiple user referentials working with IPA.
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / security / AbstractKeyring.java
index 779406a1dabc043172eabc4ab58682794d727bda..3de2e1451d89a5a7b5cafb16d2cbe54194d2e2aa 100644 (file)
@@ -1,18 +1,3 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
 package org.argeo.cms.security;
 
 import java.io.ByteArrayInputStream;
@@ -24,7 +9,6 @@ import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.Writer;
-import java.security.AccessController;
 import java.security.Provider;
 import java.security.Security;
 import java.util.Arrays;
@@ -40,12 +24,9 @@ import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 
-import org.apache.commons.io.IOUtils;
-import org.argeo.cms.CmsException;
-import org.argeo.node.NodeConstants;
-import org.argeo.node.security.CryptoKeyring;
-import org.argeo.node.security.Keyring;
-import org.argeo.node.security.PBEKeySpecCallback;
+import org.argeo.api.cms.CmsAuth;
+import org.argeo.util.CurrentSubject;
+import org.argeo.util.StreamUtils;
 
 /** username / password based keyring. TODO internationalize */
 public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
@@ -83,23 +64,24 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
 
        /** Triggers lazy initialization */
        protected SecretKey getSecretKey(char[] password) {
-               Subject subject = Subject.getSubject(AccessController.getContext());
+               Subject subject = CurrentSubject.current();
+               if (subject == null)
+                       throw new IllegalStateException("Current subject cannot be null");
                // we assume only one secrete key is available
                Iterator<SecretKey> iterator = subject.getPrivateCredentials(SecretKey.class).iterator();
-               if (!iterator.hasNext() || password!=null) {// not initialized
+               if (!iterator.hasNext() || password != null) {// not initialized
                        CallbackHandler callbackHandler = password == null ? new KeyringCallbackHandler()
                                        : new PasswordProvidedCallBackHandler(password);
                        ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
                        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
                        try {
-                               LoginContext loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_KEYRING, subject,
-                                               callbackHandler);
+                               LoginContext loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_KEYRING, subject, callbackHandler);
                                loginContext.login();
                                // FIXME will login even if password is wrong
                                iterator = subject.getPrivateCredentials(SecretKey.class).iterator();
                                return iterator.next();
                        } catch (LoginException e) {
-                               throw new CmsException("Keyring login failed", e);
+                               throw new IllegalStateException("Keyring login failed", e);
                        } finally {
                                Thread.currentThread().setContextClassLoader(currentContextClassLoader);
                        }
@@ -107,7 +89,7 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
                } else {
                        SecretKey secretKey = iterator.next();
                        if (iterator.hasNext())
-                               throw new CmsException("More than one secret key in private credentials");
+                               throw new IllegalStateException("More than one secret key in private credentials");
                        return secretKey;
                }
        }
@@ -127,10 +109,10 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
                try (InputStream in = getAsStream(path);
                                CharArrayWriter writer = new CharArrayWriter();
                                Reader reader = new InputStreamReader(in, charset);) {
-                       IOUtils.copy(reader, writer);
+                       StreamUtils.copy(reader, writer);
                        return writer.toCharArray();
                } catch (IOException e) {
-                       throw new CmsException("Cannot decrypt to char array", e);
+                       throw new IllegalStateException("Cannot decrypt to char array", e);
                } finally {
                        // IOUtils.closeQuietly(reader);
                        // IOUtils.closeQuietly(in);
@@ -152,7 +134,7 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
                                set(path, in);
                        }
                } catch (IOException e) {
-                       throw new CmsException("Cannot encrypt to char array", e);
+                       throw new IllegalStateException("Cannot encrypt to char array", e);
                } finally {
                        // IOUtils.closeQuietly(writer);
                        // IOUtils.closeQuietly(out);
@@ -165,7 +147,7 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
                        setup(password);
                SecretKey secretKey = getSecretKey(password);
                if (secretKey == null)
-                       throw new CmsException("Could not unlock keyring");
+                       throw new IllegalStateException("Could not unlock keyring");
        }
 
        protected Provider getSecurityProvider() {
@@ -223,7 +205,7 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
                        char[] password = passwordCb.getPassword();
                        return password;
                } catch (Exception e) {
-                       throw new CmsException("Cannot ask for a password", e);
+                       throw new IllegalStateException("Cannot ask for a password", e);
                }
 
        }