001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 * $Id$
020 */
021
022package org.nuxeo.runtime.api.login;
023
024import java.io.IOException;
025import java.security.Principal;
026import java.util.HashMap;
027import java.util.Map;
028
029import javax.security.auth.Subject;
030import javax.security.auth.callback.Callback;
031import javax.security.auth.callback.CallbackHandler;
032import javax.security.auth.callback.UnsupportedCallbackException;
033import javax.security.auth.login.LoginException;
034import javax.security.auth.spi.LoginModule;
035
036import org.apache.commons.logging.Log;
037import org.apache.commons.logging.LogFactory;
038import org.nuxeo.runtime.api.Framework;
039
040/**
041 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
042 */
043public class SystemLoginModule implements LoginModule {
044
045    private static final Log log = LogFactory.getLog(SystemLoginModule.class);
046
047    protected Subject subject;
048
049    protected CallbackHandler callbackHandler;
050
051    protected Map<String, Object> sharedState = new HashMap<>();
052
053    protected boolean trace;
054
055    @Override
056    public void initialize(Subject subject, CallbackHandler callbackHandler,
057            Map<String, ?> sharedState, Map<String, ?> options) {
058        this.subject = subject;
059        this.sharedState.putAll(sharedState);
060        this.callbackHandler = callbackHandler;
061        trace = log.isTraceEnabled();
062    }
063
064    @Override
065    public boolean login() throws LoginException {
066        if (trace) {
067            log.trace("begin system login");
068        }
069        LoginService loginService =
070                Framework.getLocalService(LoginService.class);
071        if (loginService == null) {
072            throw new LoginException(
073                    "Nuxeo Login Service is not running - cannot do system login");
074        }
075        CredentialsCallback cb = new CredentialsCallback();
076        try {
077            callbackHandler.handle(new Callback[] { cb });
078        } catch (RuntimeException | IOException
079                | UnsupportedCallbackException e) {
080            LoginException ee =
081                    new LoginException("System login failed - callback failed");
082            ee.initCause(e);
083            throw ee;
084        }
085        Object credential = cb.getCredentials();
086        if (LoginComponent.isSystemLogin(credential)) {
087            Principal principal = (Principal) credential;
088            sharedState.put("javax.security.auth.login.name", principal);
089            sharedState.put("javax.security.auth.login.password", null);
090            if (trace) {
091                log.trace("System Login Succeded");
092            }
093            return true;
094        }
095        if (trace) {
096            log.trace("System Login Failed");
097        }
098        return false;
099    }
100
101    @Override
102    public boolean commit() throws LoginException {
103        if (trace) {
104            log.trace("commit, subject=" + subject);
105        }
106        return true;
107    }
108
109    @Override
110    public boolean abort() throws LoginException {
111        if (trace) {
112            log.trace("abort, subject=" + subject);
113        }
114        return true;
115    }
116
117    @Override
118    public boolean logout() throws LoginException {
119        if (trace) {
120            log.trace("logout, subject=" + subject);
121        }
122        return true;
123    }
124
125}