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