Package com.jcraft.jsch

Source Code of com.jcraft.jsch.UserAuthGSSAPIWithMICGSSCredentials

/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 com.jcraft.jsch;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.airavata.gsi.ssh.GSSContextX509;
import org.apache.airavata.gsi.ssh.api.authentication.GSIAuthenticationInfo;
import org.globus.gsi.gssapi.GSSConstants;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.Oid;

/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
* Copyright(c)2004,2005,2006 ymnk, JCraft,Inc. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. The names of the authors may not
* be used to endorse or promote products derived from this software without
* specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS
* SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION)HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE)ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

/**
* This class now supports two mappings to the gssapi-with-mic method: x509
* (preferred) and krb5.
*
* @author Al Rossi
* @author Jeff Overbey
*/
public class UserAuthGSSAPIWithMICGSSCredentials extends UserAuth {

    private static final int SSH_MSG_USERAUTH_GSSAPI_RESPONSE = 60;
    private static final int SSH_MSG_USERAUTH_GSSAPI_TOKEN = 61;
    // private static final int SSH_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE = 63;
    private static final int SSH_MSG_USERAUTH_GSSAPI_ERROR = 64;
    private static final int SSH_MSG_USERAUTH_GSSAPI_ERRTOK = 65;
    private static final int SSH_MSG_USERAUTH_GSSAPI_MIC = 66;

    // this is the preferred order
    private static String[] supportedMethods = { "gssapi-with-mic.x509",
            "gssapi-with-mic.krb5" };
    private static byte[][] supportedOids;

    static {
        try {
            supportedOids = new byte[][] {
                    GSSConstants.MECH_OID.getDER(),
                    new Oid("1.2.840.113554.1.2.2").getDER() };
        } catch (GSSException gsse) {
            gsse.printStackTrace();
        }
    }

    @Override
    public boolean start(Session session) throws Exception {

        // this.userinfo = userinfo;
        Packet packet = session.packet;
        Buffer buf = session.buf;
        final String username = session.username;
        byte[] _username = Util.str2byte(username);

        // checkForSupportedOIDs
        List methods = new ArrayList();
        boolean found = false;
        for (int i = 0; i < supportedOids.length; i++) {
            found = found
                    || checkForSupportedOIDs(methods, packet, buf, i,
                    _username, session);
        }

        if (!found)
            return false;

        // logger.debug( "supported methods " + methods );

        boolean success = false;
        for (Iterator it = methods.iterator(); it.hasNext();) {
            String method = (String) it.next();
            success = tryMethod(username, _username, method, session, packet,
                    buf);
            if (success)
                break;
        }
        return success;

    }

    private boolean checkForSupportedOIDs(List methods, Packet packet,
                                          Buffer buf, int index, byte[] _username, Session session)
            throws Exception {
        packet.reset();

        // byte SSH_MSG_USERAUTH_REQUEST(50)
        // string user name(in ISO-10646 UTF-8 encoding)
        // string service name(in US-ASCII)
        // string "gssapi"(US-ASCII)
        // uint32 n, the number of OIDs client supports
        // string[n] mechanism OIDS
        buf.putByte((byte) SSH_MSG_USERAUTH_REQUEST);
        buf.putString(_username);
        buf.putString("ssh-connection".getBytes());
        buf.putString("gssapi-with-mic".getBytes());
        buf.putInt(1);
        buf.putString(supportedOids[index]);
        session.write(packet);

        while (true) {
            buf = session.read(buf);

            if (buf.buffer[5] == SSH_MSG_USERAUTH_FAILURE) {
                return false;
            }

            if (buf.buffer[5] == SSH_MSG_USERAUTH_GSSAPI_RESPONSE) {
                buf.getInt();
                buf.getByte();
                buf.getByte();
                byte[] message = buf.getString();
                // logger.debug( "OID " + supportedOids[index] );
                if (Util.array_equals(message, supportedOids[index])) {
                    methods.add(supportedMethods[index]);
                    // logger.debug( "OID MATCH, method is " + methods );
                    return true;
                }
            }

            if (buf.buffer[5] == SSH_MSG_USERAUTH_BANNER) {
                buf.getInt();
                buf.getByte();
                buf.getByte();
                byte[] _message = buf.getString();
                buf.getString();
                String message = Util.byte2str(_message);
                if (userinfo != null) {
                    userinfo.showMessage(message);
                }
                continue;
            }
            return false;
        }
    }

    private boolean tryMethod(String username, byte[] _username, String method,
                              Session session, Packet packet, Buffer buf) throws Exception {
        GSSContext context = null;
        try {
            Class c = Class.forName(session.getConfig(method));
            context = (GSSContext) (c.newInstance());

        } catch (Exception e) {
            // logger.error( "could not instantiate GSSContext", e );
            return false;
        }

        // Get the credentials and set them
        // Not a good way, but we dont have any choice
        if (session instanceof ExtendedSession) {
            GSIAuthenticationInfo authenticationInfo = ((ExtendedSession) session).getAuthenticationInfo();

            if (context instanceof GSSContextX509) {
                ((GSSContextX509) context).setCredential(authenticationInfo.getCredentials());
            }
        }

        // logger.debug( "GOT CONTEXT: " + context );


        // FIXME
        // if ( userinfo instanceof IX509UserInfo ) {
        // if ( context instanceof GSSContextX509 ) {
        // GSSCredential credential = ( ( IX509UserInfo )userinfo
        // ).getCredential();
        // logger.debug( "user info credential = " + credential );
        // ( ( GSSContextX509 )context ).setCredential( credential );
        // }
        // }

        try {
            context.create(username, session.host);
        } catch (JSchException e) {
            // logger.error( "context creation failed", e );
            return false;
        }

        byte[] token = new byte[0];

        while (!context.isEstablished()) {
            try {
                token = context.init(token, 0, token.length);
            } catch (JSchException e) {
                // logger.error( "context initialization failed", e );
                // TODO
                // ERRTOK should be sent?
                // byte SSH_MSG_USERAUTH_GSSAPI_ERRTOK
                // string error token
                return false;
            }

            if (token != null) {
                packet.reset();
                buf.putByte((byte) SSH_MSG_USERAUTH_GSSAPI_TOKEN);
                buf.putString(token);
                session.write(packet);
            }

            if (!context.isEstablished()) {
                buf = session.read(buf);

                if (buf.buffer[5] == SSH_MSG_USERAUTH_GSSAPI_ERROR) {
                    // uint32 major_status
                    // uint32 minor_status
                    // string message
                    // string language tag
                    buf = session.read(buf);
                } else if (buf.buffer[5] == SSH_MSG_USERAUTH_GSSAPI_ERRTOK) {
                    buf = session.read(buf);
                }

                if (buf.buffer[5] == SSH_MSG_USERAUTH_FAILURE) {
                    return false;
                }

                buf.getInt();
                buf.getByte();
                buf.getByte();
                token = buf.getString();
            }
        }

        Buffer mbuf = new Buffer();
        // string session identifier
        // byte SSH_MSG_USERAUTH_REQUEST
        // string user name
        // string service
        // string "gssapi-with-mic"
        mbuf.putString(session.getSessionId());
        mbuf.putByte((byte) SSH_MSG_USERAUTH_REQUEST);
        mbuf.putString(_username);
        mbuf.putString("ssh-connection".getBytes());
        mbuf.putString("gssapi-with-mic".getBytes());

        byte[] mic = context.getMIC(mbuf.buffer, 0, mbuf.getLength());

        if (mic == null) { // there was an error in the getMIC call
            return false;
        }

        packet.reset();
        buf.putByte((byte) SSH_MSG_USERAUTH_GSSAPI_MIC);
        buf.putString(mic);
        session.write(packet);

        context.dispose();

        buf = session.read(buf);
        if (buf.buffer[5] == SSH_MSG_USERAUTH_SUCCESS) {
            return true;
        }
        if (buf.buffer[5] == SSH_MSG_USERAUTH_FAILURE) {
            buf.getInt();
            buf.getByte();
            buf.getByte();
            byte[] foo = buf.getString();
            int partial_success = buf.getByte();
            if (partial_success != 0) {
                throw new JSchPartialAuthException(new String(foo));
            }
        }
        return false;
    }
}
TOP

Related Classes of com.jcraft.jsch.UserAuthGSSAPIWithMICGSSCredentials

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.