alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (NativeGSSContext.java)

This example Java source code file (NativeGSSContext.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

delegationpermission, gsscredelement, gssexception, gssheader, gsslibstub, gssnameelement, gssnamespi, ioexception, messageprop, nativegsscontext, num_of_inquire_values, oid, outputstream, security, string

The NativeGSSContext.java Java example source code

/*
 * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.security.jgss.wrapper;

import org.ietf.jgss.*;
import java.security.Provider;
import sun.security.jgss.GSSHeader;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSExceptionImpl;
import sun.security.jgss.spi.*;
import sun.security.util.DerValue;
import sun.security.util.ObjectIdentifier;
import sun.security.jgss.spnego.NegTokenInit;
import sun.security.jgss.spnego.NegTokenTarg;
import javax.security.auth.kerberos.DelegationPermission;
import com.sun.security.jgss.InquireType;
import java.io.*;


/**
 * This class is essentially a wrapper class for the gss_ctx_id_t
 * structure of the native GSS library.
 * @author Valerie Peng
 * @since 1.6
 */
class NativeGSSContext implements GSSContextSpi {

    private static final int GSS_C_DELEG_FLAG = 1;
    private static final int GSS_C_MUTUAL_FLAG = 2;
    private static final int GSS_C_REPLAY_FLAG = 4;
    private static final int GSS_C_SEQUENCE_FLAG = 8;
    private static final int GSS_C_CONF_FLAG = 16;
    private static final int GSS_C_INTEG_FLAG = 32;
    private static final int GSS_C_ANON_FLAG = 64;
    private static final int GSS_C_PROT_READY_FLAG = 128;
    private static final int GSS_C_TRANS_FLAG = 256;

    private static final int NUM_OF_INQUIRE_VALUES = 6;

    private long pContext = 0; // Pointer to the gss_ctx_id_t structure
    private GSSNameElement srcName;
    private GSSNameElement targetName;
    private GSSCredElement cred;
    private boolean isInitiator;
    private boolean isEstablished;
    private Oid actualMech; // Assigned during context establishment

    private ChannelBinding cb;
    private GSSCredElement delegatedCred;
    private int flags;
    private int lifetime = GSSCredential.DEFAULT_LIFETIME;
    private final GSSLibStub cStub;

    private boolean skipDelegPermCheck;
    private boolean skipServicePermCheck;

    // Retrieve the (preferred) mech out of SPNEGO tokens, i.e.
    // NegTokenInit & NegTokenTarg
    private static Oid getMechFromSpNegoToken(byte[] token,
                                              boolean isInitiator)
        throws GSSException {
        Oid mech = null;
        if (isInitiator) {
            GSSHeader header = null;
            try {
                header = new GSSHeader(new ByteArrayInputStream(token));
            } catch (IOException ioe) {
                throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
            }
            int negTokenLen = header.getMechTokenLength();
            byte[] negToken = new byte[negTokenLen];
            System.arraycopy(token, token.length-negTokenLen,
                             negToken, 0, negToken.length);

            NegTokenInit ntok = new NegTokenInit(negToken);
            if (ntok.getMechToken() != null) {
                Oid[] mechList = ntok.getMechTypeList();
                mech = mechList[0];
            }
        } else {
            NegTokenTarg ntok = new NegTokenTarg(token);
            mech = ntok.getSupportedMech();
        }
        return mech;
    }

    // Perform the Service permission check
    private void doServicePermCheck() throws GSSException {
        if (System.getSecurityManager() != null) {
            String action = (isInitiator? "initiate" : "accept");
            // Need to check Service permission for accessing
            // initiator cred for SPNEGO during context establishment
            if (GSSUtil.isSpNegoMech(cStub.getMech()) && isInitiator
                && !isEstablished) {
                if (srcName == null) {
                    // Check by creating default initiator KRB5 cred
                    GSSCredElement tempCred =
                        new GSSCredElement(null, lifetime,
                                           GSSCredential.INITIATE_ONLY,
                                           GSSLibStub.getInstance(GSSUtil.GSS_KRB5_MECH_OID));
                    tempCred.dispose();
                } else {
                    String tgsName = Krb5Util.getTGSName(srcName);
                    Krb5Util.checkServicePermission(tgsName, action);
                }
            }
            String targetStr = targetName.getKrbName();
            Krb5Util.checkServicePermission(targetStr, action);
            skipServicePermCheck = true;
        }
    }

    // Perform the Delegation permission check
    private void doDelegPermCheck() throws GSSException {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            String targetStr = targetName.getKrbName();
            String tgsStr = Krb5Util.getTGSName(targetName);
            StringBuffer buf = new StringBuffer("\"");
            buf.append(targetStr).append("\" \"");
            buf.append(tgsStr).append('\"');
            String krbPrincPair = buf.toString();
            SunNativeProvider.debug("Checking DelegationPermission (" +
                                    krbPrincPair + ")");
            DelegationPermission perm =
                new DelegationPermission(krbPrincPair);
            sm.checkPermission(perm);
            skipDelegPermCheck = true;
        }
    }

    private byte[] retrieveToken(InputStream is, int mechTokenLen)
        throws GSSException {
        try {
            byte[] result = null;
            if (mechTokenLen != -1) {
                // Need to add back the GSS header for a complete GSS token
                SunNativeProvider.debug("Precomputed mechToken length: " +
                                         mechTokenLen);
                GSSHeader gssHeader = new GSSHeader
                    (new ObjectIdentifier(cStub.getMech().toString()),
                     mechTokenLen);
                ByteArrayOutputStream baos = new ByteArrayOutputStream(600);

                byte[] mechToken = new byte[mechTokenLen];
                int len = is.read(mechToken);
                assert(mechTokenLen == len);
                gssHeader.encode(baos);
                baos.write(mechToken);
                result = baos.toByteArray();
            } else {
                // Must be unparsed GSS token or SPNEGO's NegTokenTarg token
                assert(mechTokenLen == -1);
                DerValue dv = new DerValue(is);
                result = dv.toByteArray();
            }
            SunNativeProvider.debug("Complete Token length: " +
                                    result.length);
            return result;
        } catch (IOException ioe) {
            throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
        }
    }

    // Constructor for context initiator
    NativeGSSContext(GSSNameElement peer, GSSCredElement myCred,
                     int time, GSSLibStub stub) throws GSSException {
        if (peer == null) {
            throw new GSSException(GSSException.FAILURE, 1, "null peer");
        }
        cStub = stub;
        cred = myCred;
        targetName = peer;
        isInitiator = true;
        lifetime = time;

        if (GSSUtil.isKerberosMech(cStub.getMech())) {
            doServicePermCheck();
            if (cred == null) {
                cred = new GSSCredElement(null, lifetime,
                                          GSSCredential.INITIATE_ONLY, cStub);
            }
            srcName = cred.getName();
        }
    }

    // Constructor for context acceptor
    NativeGSSContext(GSSCredElement myCred, GSSLibStub stub)
        throws GSSException {
        cStub = stub;
        cred = myCred;

        if (cred != null) targetName = cred.getName();

        isInitiator = false;
        // Defer Service permission check for default acceptor cred
        // to acceptSecContext()
        if (GSSUtil.isKerberosMech(cStub.getMech()) && targetName != null) {
            doServicePermCheck();
        }

        // srcName and potentially targetName (when myCred is null)
        // will be set in GSSLibStub.acceptContext(...)
    }

    // Constructor for imported context
    NativeGSSContext(long pCtxt, GSSLibStub stub) throws GSSException {
        assert(pContext != 0);
        pContext = pCtxt;
        cStub = stub;

        // Set everything except cred, cb, delegatedCred
        long[] info = cStub.inquireContext(pContext);
        if (info.length != NUM_OF_INQUIRE_VALUES) {
            throw new RuntimeException("Bug w/ GSSLibStub.inquireContext()");
        }
        srcName = new GSSNameElement(info[0], cStub);
        targetName = new GSSNameElement(info[1], cStub);
        isInitiator = (info[2] != 0);
        isEstablished = (info[3] != 0);
        flags = (int) info[4];
        lifetime = (int) info[5];

        // Do Service Permission check when importing SPNEGO context
        // just to be safe
        Oid mech = cStub.getMech();
        if (GSSUtil.isSpNegoMech(mech) || GSSUtil.isKerberosMech(mech)) {
            doServicePermCheck();
        }
    }

    public Provider getProvider() {
        return SunNativeProvider.INSTANCE;
    }

    public byte[] initSecContext(InputStream is, int mechTokenLen)
        throws GSSException {
        byte[] outToken = null;
        if ((!isEstablished) && (isInitiator)) {
            byte[] inToken = null;
            // Ignore the specified input stream on the first call
            if (pContext != 0) {
                inToken = retrieveToken(is, mechTokenLen);
                SunNativeProvider.debug("initSecContext=> inToken len=" +
                    inToken.length);
            }

            if (!getCredDelegState()) skipDelegPermCheck = true;

            if (GSSUtil.isKerberosMech(cStub.getMech()) && !skipDelegPermCheck) {
                doDelegPermCheck();
            }

            long pCred = (cred == null? 0 : cred.pCred);
            outToken = cStub.initContext(pCred, targetName.pName,
                                         cb, inToken, this);
            SunNativeProvider.debug("initSecContext=> outToken len=" +
                (outToken == null ? 0 : outToken.length));

            // Only inspect the token when the permission check
            // has not been performed
            if (GSSUtil.isSpNegoMech(cStub.getMech()) && outToken != null) {
                // WORKAROUND for SEAM bug#6287358
                actualMech = getMechFromSpNegoToken(outToken, true);

                if (GSSUtil.isKerberosMech(actualMech)) {
                    if (!skipServicePermCheck) doServicePermCheck();
                    if (!skipDelegPermCheck) doDelegPermCheck();
                }
            }

            if (isEstablished) {
                if (srcName == null) {
                    srcName = new GSSNameElement
                        (cStub.getContextName(pContext, true), cStub);
                }
                if (cred == null) {
                    cred = new GSSCredElement(srcName, lifetime,
                                              GSSCredential.INITIATE_ONLY,
                                              cStub);
                }
            }
        }
        return outToken;
    }

    public byte[] acceptSecContext(InputStream is, int mechTokenLen)
        throws GSSException {
        byte[] outToken = null;
        if ((!isEstablished) && (!isInitiator)) {
            byte[] inToken = retrieveToken(is, mechTokenLen);
            SunNativeProvider.debug("acceptSecContext=> inToken len=" +
                                    inToken.length);
            long pCred = (cred == null? 0 : cred.pCred);
            outToken = cStub.acceptContext(pCred, cb, inToken, this);
            SunNativeProvider.debug("acceptSecContext=> outToken len=" +
                                    (outToken == null? 0 : outToken.length));

            if (targetName == null) {
                targetName = new GSSNameElement
                    (cStub.getContextName(pContext, false), cStub);
                // Replace the current default acceptor cred now that
                // the context acceptor name is available
                if (cred != null) cred.dispose();
                cred = new GSSCredElement(targetName, lifetime,
                                          GSSCredential.ACCEPT_ONLY, cStub);
            }

            // Only inspect token when the permission check has not
            // been performed
            if (GSSUtil.isSpNegoMech(cStub.getMech()) &&
                (outToken != null) && !skipServicePermCheck) {
                if (GSSUtil.isKerberosMech(getMechFromSpNegoToken
                                           (outToken, false))) {
                    doServicePermCheck();
                }
            }
        }
        return outToken;
    }

    public boolean isEstablished() {
        return isEstablished;
    }

    public void dispose() throws GSSException {
        srcName = null;
        targetName = null;
        cred = null;
        delegatedCred = null;
        if (pContext != 0) {
            pContext = cStub.deleteContext(pContext);
            pContext = 0;
        }
    }

    public int getWrapSizeLimit(int qop, boolean confReq,
                                int maxTokenSize)
        throws GSSException {
        return cStub.wrapSizeLimit(pContext, (confReq? 1:0), qop,
                                   maxTokenSize);
    }

    public byte[] wrap(byte[] inBuf, int offset, int len,
                       MessageProp msgProp) throws GSSException {
        byte[] data = inBuf;
        if ((offset != 0) || (len != inBuf.length)) {
            data = new byte[len];
            System.arraycopy(inBuf, offset, data, 0, len);
        }
        return cStub.wrap(pContext, data, msgProp);
    }
    public void wrap(byte inBuf[], int offset, int len,
                     OutputStream os, MessageProp msgProp)
        throws GSSException {
        try {
        byte[] result = wrap(inBuf, offset, len, msgProp);
        os.write(result);
        } catch (IOException ioe) {
            throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
        }
    }
    public int wrap(byte[] inBuf, int inOffset, int len, byte[] outBuf,
                    int outOffset, MessageProp msgProp)
        throws GSSException {
        byte[] result = wrap(inBuf, inOffset, len, msgProp);
        System.arraycopy(result, 0, outBuf, outOffset, result.length);
        return result.length;
    }
    public void wrap(InputStream inStream, OutputStream outStream,
                     MessageProp msgProp) throws GSSException {
        try {
            byte[] data = new byte[inStream.available()];
            int length = inStream.read(data);
            byte[] token = wrap(data, 0, length, msgProp);
            outStream.write(token);
        } catch (IOException ioe) {
            throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
        }
    }

    public byte[] unwrap(byte[] inBuf, int offset, int len,
                         MessageProp msgProp)
        throws GSSException {
        if ((offset != 0) || (len != inBuf.length)) {
            byte[] temp = new byte[len];
            System.arraycopy(inBuf, offset, temp, 0, len);
            return cStub.unwrap(pContext, temp, msgProp);
        } else {
            return cStub.unwrap(pContext, inBuf, msgProp);
        }
    }
    public int unwrap(byte[] inBuf, int inOffset, int len,
                      byte[] outBuf, int outOffset,
                      MessageProp msgProp) throws GSSException {
        byte[] result = null;
        if ((inOffset != 0) || (len != inBuf.length)) {
            byte[] temp = new byte[len];
            System.arraycopy(inBuf, inOffset, temp, 0, len);
            result = cStub.unwrap(pContext, temp, msgProp);
        } else {
            result = cStub.unwrap(pContext, inBuf, msgProp);
        }
        System.arraycopy(result, 0, outBuf, outOffset, result.length);
        return result.length;
    }
    public void unwrap(InputStream inStream, OutputStream outStream,
                       MessageProp msgProp) throws GSSException {
        try {
            byte[] wrapped = new byte[inStream.available()];
            int wLength = inStream.read(wrapped);
            byte[] data = unwrap(wrapped, 0, wLength, msgProp);
            outStream.write(data);
            outStream.flush();
        } catch (IOException ioe) {
            throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
        }
    }

    public int unwrap(InputStream inStream,
                      byte[] outBuf, int outOffset,
                      MessageProp msgProp) throws GSSException {
        byte[] wrapped = null;
        int wLength = 0;
        try {
            wrapped = new byte[inStream.available()];
            wLength = inStream.read(wrapped);
            byte[] result = unwrap(wrapped, 0, wLength, msgProp);
        } catch (IOException ioe) {
            throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
        }
        byte[] result = unwrap(wrapped, 0, wLength, msgProp);
        System.arraycopy(result, 0, outBuf, outOffset, result.length);
        return result.length;
    }

    public byte[] getMIC(byte[] in, int offset, int len,
                         MessageProp msgProp) throws GSSException {
        int qop = (msgProp == null? 0:msgProp.getQOP());
        byte[] inMsg = in;
        if ((offset != 0) || (len != in.length)) {
            inMsg = new byte[len];
            System.arraycopy(in, offset, inMsg, 0, len);
        }
        return cStub.getMic(pContext, qop, inMsg);
    }

    public void getMIC(InputStream inStream, OutputStream outStream,
                       MessageProp msgProp) throws GSSException {
        try {
            int length = 0;
            byte[] msg = new byte[inStream.available()];
            length = inStream.read(msg);

            byte[] msgToken = getMIC(msg, 0, length, msgProp);
            if ((msgToken != null) && msgToken.length != 0) {
                outStream.write(msgToken);
            }
        } catch (IOException ioe) {
            throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
        }
    }

    public void verifyMIC(byte[] inToken, int tOffset, int tLen,
                          byte[] inMsg, int mOffset, int mLen,
                          MessageProp msgProp) throws GSSException {
        byte[] token = inToken;
        byte[] msg = inMsg;
        if ((tOffset != 0) || (tLen != inToken.length)) {
            token = new byte[tLen];
            System.arraycopy(inToken, tOffset, token, 0, tLen);
        }
        if ((mOffset != 0) || (mLen != inMsg.length)) {
            msg = new byte[mLen];
            System.arraycopy(inMsg, mOffset, msg, 0, mLen);
        }
        cStub.verifyMic(pContext, token, msg, msgProp);
    }

    public void verifyMIC(InputStream tokStream, InputStream msgStream,
                          MessageProp msgProp) throws GSSException {
        try {
            byte[] msg = new byte[msgStream.available()];
            int mLength = msgStream.read(msg);
            byte[] tok = new byte[tokStream.available()];
            int tLength = tokStream.read(tok);
            verifyMIC(tok, 0, tLength, msg, 0, mLength, msgProp);
        } catch (IOException ioe) {
            throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
        }
    }

    public byte[] export() throws GSSException {
        byte[] result = cStub.exportContext(pContext);
        pContext = 0;
        return result;
    }

    private void changeFlags(int flagMask, boolean isEnable) {
        if (isInitiator && pContext == 0) {
            if (isEnable) {
                flags |= flagMask;
            } else {
                flags &= ~flagMask;
            }
        }
    }
    public void requestMutualAuth(boolean state) throws GSSException {
        changeFlags(GSS_C_MUTUAL_FLAG, state);
    }
    public void requestReplayDet(boolean state) throws GSSException {
        changeFlags(GSS_C_REPLAY_FLAG, state);
    }
    public void requestSequenceDet(boolean state) throws GSSException {
        changeFlags(GSS_C_SEQUENCE_FLAG, state);
    }
    public void requestCredDeleg(boolean state) throws GSSException {
        changeFlags(GSS_C_DELEG_FLAG, state);
    }
    public void requestAnonymity(boolean state) throws GSSException {
        changeFlags(GSS_C_ANON_FLAG, state);
    }
    public void requestConf(boolean state) throws GSSException {
        changeFlags(GSS_C_CONF_FLAG, state);
    }
    public void requestInteg(boolean state) throws GSSException {
        changeFlags(GSS_C_INTEG_FLAG, state);
    }
    public void requestDelegPolicy(boolean state) throws GSSException {
        // Not supported, ignore
    }
    public void requestLifetime(int lifetime) throws GSSException {
        if (isInitiator && pContext == 0) {
            this.lifetime = lifetime;
        }
    }
    public void setChannelBinding(ChannelBinding cb) throws GSSException {
        if (pContext == 0) {
            this.cb = cb;
        }
    }

    private boolean checkFlags(int flagMask) {
        return ((flags & flagMask) != 0);
    }
    public boolean getCredDelegState() {
        return checkFlags(GSS_C_DELEG_FLAG);
    }
    public boolean getMutualAuthState() {
        return checkFlags(GSS_C_MUTUAL_FLAG);
    }
    public boolean getReplayDetState() {
        return checkFlags(GSS_C_REPLAY_FLAG);
    }
    public boolean getSequenceDetState() {
        return checkFlags(GSS_C_SEQUENCE_FLAG);
    }
    public boolean getAnonymityState() {
        return checkFlags(GSS_C_ANON_FLAG);
    }
    public boolean isTransferable() throws GSSException {
        return checkFlags(GSS_C_TRANS_FLAG);
    }
    public boolean isProtReady() {
        return checkFlags(GSS_C_PROT_READY_FLAG);
    }
    public boolean getConfState() {
        return checkFlags(GSS_C_CONF_FLAG);
    }
    public boolean getIntegState() {
        return checkFlags(GSS_C_INTEG_FLAG);
    }
    public boolean getDelegPolicyState() {
        return false;
    }
    public int getLifetime() {
        return cStub.getContextTime(pContext);
    }
    public GSSNameSpi getSrcName() throws GSSException {
        return srcName;
    }
    public GSSNameSpi getTargName() throws GSSException {
        return targetName;
    }
    public Oid getMech() throws GSSException {
        if (isEstablished && actualMech != null) {
            return actualMech;
        } else {
            return cStub.getMech();
        }
    }
    public GSSCredentialSpi getDelegCred() throws GSSException {
        return delegatedCred;
    }
    public boolean isInitiator() {
        return isInitiator;
    }

    protected void finalize() throws Throwable {
        dispose();
    }

    public Object inquireSecContext(InquireType type)
            throws GSSException {
        throw new GSSException(GSSException.UNAVAILABLE, -1,
                "Inquire type not supported.");
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java NativeGSSContext.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.