<commit_before>/*-------------------------------------------------------------------------
*
* Copyright (c) 2008-2014, PostgreSQL Global Development Group
*
*
*-------------------------------------------------------------------------
*/

package org.postgresql.gss;

import org.ietf.jgss.*;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import java.security.PrivilegedAction;

import java.io.IOException;
import java.sql.SQLException;

import org.postgresql.core.PGStream;
import org.postgresql.core.Logger;
import org.postgresql.util.*;


public class MakeGSS
{

    public static void authenticate(PGStream pgStream, String host, String user, String password, String jaasApplicationName, String kerberosServerName, Logger logger, boolean useSpnego) throws IOException, SQLException
    {
        if (logger.logDebug())
            logger.debug(" <=BE AuthenticationReqGSS");

        Object result = null;

        if (jaasApplicationName == null)
            jaasApplicationName = "pgjdbc";
        if (kerberosServerName == null)
            kerberosServerName = "postgres";

        try {
            LoginContext lc = new LoginContext(jaasApplicationName, new GSSCallbackHandler(user, password));
            lc.login();

            Subject sub = lc.getSubject();
            PrivilegedAction action = new GssAction(pgStream, host, user, password, kerberosServerName, logger, useSpnego);
            result = Subject.doAs(sub, action);
        } catch (Exception e) {
            throw new PSQLException(GT.tr("GSS Authentication failed"), PSQLState.CONNECTION_FAILURE, e);
        }

        if (result instanceof IOException)
            throw (IOException)result;
        else if (result instanceof SQLException)
            throw (SQLException)result;
        else if (result != null)
            throw new PSQLException(GT.tr("GSS Authentication failed"), PSQLState.CONNECTION_FAILURE, (Exception)result);

    }

}

class GssAction implements PrivilegedAction
{
    private final PGStream pgStream;
    private final String host;
    private final String user;
    private final String password;
    private final String kerberosServerName;
    private final Logger logger;
    private final boolean useSpnego;

    public GssAction(PGStream pgStream, String host, String user, String password, String kerberosServerName, Logger logger, boolean useSpnego)
    {
        this.pgStream = pgStream;
        this.host = host;
        this.user = user;
        this.password = password;
        this.kerberosServerName = kerberosServerName;
        this.logger = logger;
        this.useSpnego = useSpnego;
    }

    private static boolean hasSpnegoSupport(GSSManager manager) throws GSSException {

        org.ietf.jgss.Oid spnego = new org.ietf.jgss.Oid("1.3.6.1.5.5.2");
        org.ietf.jgss.Oid mechs[] = manager.getMechs();

        for (int i = 0; i < mechs.length; ++i) {
            if (mechs[i].equals(spnego)) {
                return true;
            }
        }

        return false;
    }

    public Object run() {

        try {

            GSSManager manager = GSSManager.getInstance();
 
            org.ietf.jgss.Oid desiredMechs[] = new org.ietf.jgss.Oid[1];
            if (useSpnego && hasSpnegoSupport(manager)) {
                desiredMechs[0] = new org.ietf.jgss.Oid("1.3.6.1.5.5.2");
            } else {
                desiredMechs[0] = new org.ietf.jgss.Oid("1.2.840.113554.1.2.2");
            }
 
            GSSName clientName = manager.createName(user, GSSName.NT_USER_NAME);
            GSSCredential clientCreds = manager.createCredential(clientName, 8*3600, desiredMechs, GSSCredential.INITIATE_ONLY);

            GSSName serverName = manager.createName(kerberosServerName + "@" + host, GSSName.NT_HOSTBASED_SERVICE);

            GSSContext secContext = manager.createContext(serverName, desiredMechs[0], clientCreds, GSSContext.DEFAULT_LIFETIME);
            secContext.requestMutualAuth(true);

            byte inToken[] = new byte[0];
            byte outToken[] = null;

            boolean established = false;
            while (!established) {
                outToken = secContext.initSecContext(inToken, 0, inToken.length);


                if (outToken != null) {
                    if (logger.logDebug())
                        logger.debug(" FE=> Password(GSS Authentication Token)");

                    pgStream.SendChar('p');
                    pgStream.SendInteger4(4 + outToken.length);
                    pgStream.Send(outToken);<commit_msg>GSS: reuse existing Subject and GssCredentials<commit_after>/*-------------------------------------------------------------------------
*
* Copyright (c) 2008-2014, PostgreSQL Global Development Group
*
*
*-------------------------------------------------------------------------
*/

package org.postgresql.gss;

import org.ietf.jgss.*;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import java.security.AccessController;
import java.security.PrivilegedAction;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Set;

import org.postgresql.core.PGStream;
import org.postgresql.core.Logger;
import org.postgresql.util.*;


public class MakeGSS
{

    public static void authenticate(PGStream pgStream, String host, String user, String password, String jaasApplicationName, String kerberosServerName, Logger logger, boolean useSpnego) throws IOException, SQLException
    {
        if (logger.logDebug())
            logger.debug(" <=BE AuthenticationReqGSS");

        Object result = null;

        if (jaasApplicationName == null)
            jaasApplicationName = "pgjdbc";
        if (kerberosServerName == null)
            kerberosServerName = "postgres";

        try {
            GSSCredential gssCredential = null;
            Subject sub = Subject.getSubject(AccessController.getContext());
            if(sub == null) {
                LoginContext lc = new LoginContext(jaasApplicationName, new GSSCallbackHandler(user, password));
                lc.login();
                sub = lc.getSubject();
            } else {
                Set<GSSCredential> gssCreds = sub.getPrivateCredentials(GSSCredential.class);
                if (gssCreds != null && gssCreds.size() > 0) {
                    gssCredential = gssCreds.iterator().next();
                } else {
                    throw new PSQLException(GT.tr("GSS No valid credentials in subject"), PSQLState.CONNECTION_FAILURE);
                }
            }
            PrivilegedAction action = new GssAction(pgStream, gssCredential, host, user, password, kerberosServerName, logger, useSpnego);

            result = Subject.doAs(sub, action);
        } catch (Exception e) {
            throw new PSQLException(GT.tr("GSS Authentication failed"), PSQLState.CONNECTION_FAILURE, e);
        }

        if (result instanceof IOException)
            throw (IOException)result;
        else if (result instanceof SQLException)
            throw (SQLException)result;
        else if (result != null)
            throw new PSQLException(GT.tr("GSS Authentication failed"), PSQLState.CONNECTION_FAILURE, (Exception)result);

    }

}

class GssAction implements PrivilegedAction
{
    private final PGStream pgStream;
    private final String host;
    private final String user;
    private final String password;
    private final String kerberosServerName;
    private final Logger logger;
    private final boolean useSpnego;
    private final GSSCredential clientCredentials;


    public GssAction(PGStream pgStream, GSSCredential clientCredentials, String host, String user, String password, String kerberosServerName, Logger logger, boolean useSpnego)
    {
        this.pgStream = pgStream;
        this.clientCredentials = clientCredentials;
        this.host = host;
        this.user = user;
        this.password = password;
        this.kerberosServerName = kerberosServerName;
        this.logger = logger;
        this.useSpnego = useSpnego;
    }

    private static boolean hasSpnegoSupport(GSSManager manager) throws GSSException {

        org.ietf.jgss.Oid spnego = new org.ietf.jgss.Oid("1.3.6.1.5.5.2");
        org.ietf.jgss.Oid mechs[] = manager.getMechs();

        for (int i = 0; i < mechs.length; ++i) {
            if (mechs[i].equals(spnego)) {
                return true;
            }
        }

        return false;
    }

    public Object run() {

        try {

            GSSManager manager = GSSManager.getInstance();
            GSSCredential clientCreds = null;
            org.ietf.jgss.Oid desiredMechs[] = new org.ietf.jgss.Oid[1];
            if(clientCredentials == null) {
                if (useSpnego && hasSpnegoSupport(manager)) {
                    desiredMechs[0] = new org.ietf.jgss.Oid("1.3.6.1.5.5.2");
                } else {
                    desiredMechs[0] = new org.ietf.jgss.Oid("1.2.840.113554.1.2.2");
                }
                GSSName clientName = manager.createName(user, GSSName.NT_USER_NAME);
                clientCreds = manager.createCredential(clientName, 8*3600, desiredMechs, GSSCredential.INITIATE_ONLY);
            } else {
                desiredMechs[0] = new org.ietf.jgss.Oid("1.2.840.113554.1.2.2");
                clientCreds = clientCredentials;
            }

            GSSName serverName = manager.createName(kerberosServerName + "@" + host, GSSName.NT_HOSTBASED_SERVICE);

            GSSContext secContext = manager.createContext(serverName, desiredMechs[0], clientCreds, GSSContext.DEFAULT_LIFETIME);
            secContext.requestMutualAuth(true);

            byte inToken[] = new byte[0];
            byte outToken[] = null;

            boolean established = false;
            while (!established) {
                outToken = secContext.initSecContext(inToken, 0, inToken.length);


                if (outToken != null) {
                    if (logger.logDebug())
                        logger.debug(" FE=> Password(GSS Authentication Token)");

                    pgStream.SendChar('p');
                    pgStream.SendInteger4(4 + outToken.length);
                    pgStream.Send(outToken);
{'fraction_non_alphanumeric': 0.1244853950205842, 'fraction_numerical': 0.011370319545187219, 'mean_word_length': 2.162740235585865, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 7, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6251598', 'n_tokens_mistral': 2942, 'n_tokens_neox': 2824, 'n_words': 637}