001/*
002 *  Copyright 2016 Anyware Services
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 */
016package org.ametys.plugins.core.impl.checker;
017
018import java.io.IOException;
019import java.security.PrivilegedAction;
020import java.security.PrivilegedActionException;
021import java.security.PrivilegedExceptionAction;
022import java.util.List;
023
024import javax.security.auth.Subject;
025import javax.security.auth.login.LoginContext;
026import javax.security.auth.login.LoginException;
027
028import org.apache.avalon.framework.context.Context;
029import org.apache.avalon.framework.context.ContextException;
030import org.apache.avalon.framework.context.Contextualizable;
031import org.ietf.jgss.GSSContext;
032import org.ietf.jgss.GSSCredential;
033import org.ietf.jgss.GSSException;
034import org.ietf.jgss.GSSManager;
035import org.ietf.jgss.Oid;
036
037import org.ametys.plugins.core.impl.authentication.KerberosCredentialProvider;
038import org.ametys.runtime.model.checker.ItemChecker;
039import org.ametys.runtime.model.checker.ItemCheckerTestFailureException;
040import org.ametys.runtime.plugin.component.AbstractLogEnabled;
041
042/**
043 * This checks that the parameters are the one of a Kerberos server
044 */
045public class KerberosChecker extends AbstractLogEnabled implements ItemChecker, Contextualizable
046{
047    /** The avalon context */
048    protected Context _context;
049
050    public void contextualize(Context context) throws ContextException
051    {
052        _context = context;
053    }
054    
055    public void check(List<String> values) throws ItemCheckerTestFailureException
056    {
057        String kdc = values.get(0);
058        String realm = values.get(1);
059        String login = values.get(2);
060        String password = values.get(3);
061        
062        try
063        {
064            LoginContext loginContext = KerberosCredentialProvider.createLoginContext(kdc, realm, login, password, _context);
065
066            final Subject subject = loginContext.getSubject(); 
067            
068            GSSManager manager = GSSManager.getInstance();
069            
070            PrivilegedExceptionAction<GSSCredential> action = new PrivilegedExceptionAction<>() 
071            {
072                public GSSCredential run() throws GSSException 
073                {
074                    return manager.createCredential(null, GSSCredential.INDEFINITE_LIFETIME, new Oid("1.3.6.1.5.5.2"), GSSCredential.INITIATE_ONLY);
075                } 
076            };
077            
078            GSSCredential gssCredential = Subject.doAs(loginContext.getSubject(), action);
079            final GSSContext gssContext = GSSManager.getInstance().createContext(gssCredential);
080
081            // The GSS context initiation has to be performed as a privileged action.
082            byte[] serviceTicket = Subject.doAs(subject, new PrivilegedAction<byte[]>() 
083            {
084                public byte[] run()
085                {
086                    try
087                    {
088                        byte[] token = new byte[0];
089                        // This is a one pass context initialization.
090                        gssContext.requestMutualAuth(false);
091                        gssContext.requestCredDeleg(false);
092                        return gssContext.initSecContext(token, 0, token.length);
093                    }
094                    catch (GSSException e)
095                    {
096                        throw new ItemCheckerTestFailureException("aaa (" + e.getMessage() + ")", e);
097                    }
098                }
099            });
100
101            System.out.println(serviceTicket);
102        }
103        catch (IOException | LoginException | ContextException | GSSException | PrivilegedActionException e)
104        {
105            throw new ItemCheckerTestFailureException("Unable to connect to the KDC (" + e.getMessage() + ")", e);
106        }
107    }
108}