@Override
    public String run() throws HttpAuthenticationException {
      // Get own Kerberos credentials for accepting connection
      GSSManager manager = GSSManager.getInstance();
      GSSContext gssContext = null;
      String serverPrincipal = getPrincipalWithoutRealm(serviceUGI.getUserName());
      try {
        // This Oid for Kerberos GSS-API mechanism.
        Oid kerberosMechOid = new Oid("1.2.840.113554.1.2.2");
        // Oid for SPNego GSS-API mechanism.
        Oid spnegoMechOid = new Oid("1.3.6.1.5.5.2");
        // Oid for kerberos principal name
        Oid krb5PrincipalOid = new Oid("1.2.840.113554.1.2.2.1");

        // GSS name for server
        GSSName serverName = manager.createName(serverPrincipal, krb5PrincipalOid);

        // GSS credentials for server
        GSSCredential serverCreds =
            manager.createCredential(
                serverName,
                GSSCredential.DEFAULT_LIFETIME,
                new Oid[] {kerberosMechOid, spnegoMechOid},
                GSSCredential.ACCEPT_ONLY);

        // Create a GSS context
        gssContext = manager.createContext(serverCreds);
        // Get service ticket from the authorization header
        String serviceTicketBase64 = getAuthHeader(request, authType);
        byte[] inToken = Base64.decodeBase64(serviceTicketBase64.getBytes());
        gssContext.acceptSecContext(inToken, 0, inToken.length);
        // Authenticate or deny based on its context completion
        if (!gssContext.isEstablished()) {
          throw new HttpAuthenticationException(
              "Kerberos authentication failed: "
                  + "unable to establish context with the service ticket "
                  + "provided by the client.");
        } else {
          return getPrincipalWithoutRealmAndHost(gssContext.getSrcName().toString());
        }
      } catch (GSSException e) {
        throw new HttpAuthenticationException("Kerberos authentication failed: ", e);
      } finally {
        if (gssContext != null) {
          try {
            gssContext.dispose();
          } catch (GSSException e) {
            // No-op
          }
        }
      }
    }
  /** {@inheritDoc} */
  @Override
  public Principal authenticate(GSSContext gssContext, boolean storeCred) {
    if (gssContext.isEstablished()) {
      GSSName gssName = null;
      try {
        gssName = gssContext.getSrcName();
      } catch (GSSException e) {
        log.warn(sm.getString("realmBase.gssNameFail"), e);
      }

      if (gssName != null) {
        String name = gssName.toString();

        if (isStripRealmForGss()) {
          int i = name.indexOf('@');
          if (i > 0) {
            // Zero so we don;t leave a zero length name
            name = name.substring(0, i);
          }
        }
        GSSCredential gssCredential = null;
        if (storeCred && gssContext.getCredDelegState()) {
          try {
            gssCredential = gssContext.getDelegCred();
          } catch (GSSException e) {
            if (log.isDebugEnabled()) {
              log.debug(sm.getString("realmBase.delegatedCredentialFail", name), e);
            }
          }
        }
        return getPrincipal(name, gssCredential);
      }
    }

    // Fail in all other cases
    return null;
  }
 boolean isEstablished() {
   return gssContext != null ? gssContext.isEstablished() : false;
 }
Exemple #4
0
  public Object run() {

    try {

      org.ietf.jgss.Oid desiredMechs[] = new org.ietf.jgss.Oid[1];
      desiredMechs[0] = new org.ietf.jgss.Oid("1.2.840.113554.1.2.2");

      GSSManager manager = GSSManager.getInstance();

      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);
          pgStream.flush();
        }

        if (!secContext.isEstablished()) {
          int response = pgStream.ReceiveChar();
          // Error
          if (response == 'E') {
            int l_elen = pgStream.ReceiveInteger4();
            ServerErrorMessage l_errorMsg =
                new ServerErrorMessage(pgStream.ReceiveString(l_elen - 4), logger.getLogLevel());

            if (logger.logDebug()) logger.debug(" <=BE ErrorMessage(" + l_errorMsg + ")");

            return new PSQLException(l_errorMsg);

          } else if (response == 'R') {

            if (logger.logDebug()) logger.debug(" <=BE AuthenticationGSSContinue");

            int len = pgStream.ReceiveInteger4();
            int type = pgStream.ReceiveInteger4();
            // should check type = 8
            inToken = pgStream.Receive(len - 8);
          } else {
            // Unknown/unexpected message type.
            return new PSQLException(
                GT.tr("Protocol error.  Session setup failed."),
                PSQLState.CONNECTION_UNABLE_TO_CONNECT);
          }
        } else {
          established = true;
        }
      }

    } catch (IOException e) {
      return e;
    } catch (GSSException gsse) {
      return new PSQLException(
          GT.tr("GSS Authentication failed"), PSQLState.CONNECTION_FAILURE, gsse);
    }

    return null;
  }
  public void authenticate(AuthenticationProtocolClient authenticationprotocolclient, String s)
      throws IOException, TerminatedStateException {
    try {
      logger.finest("Registering gss-ssh return messages.");
      authenticationprotocolclient.registerMessage(
          com.sshtools.j2ssh.authentication.SshMsgUserauthGssapiResponse.class, 60);
      authenticationprotocolclient.registerMessage(
          com.sshtools.j2ssh.authentication.SshMsgUserauthGssapiToken.class, 61);
      authenticationprotocolclient.registerMessage(
          com.sshtools.j2ssh.authentication.SshMsgUserauthGssapiError.class, 64);
      authenticationprotocolclient.registerMessage(
          com.sshtools.j2ssh.authentication.SshMsgUserauthGssapiErrtok.class, 65);
      logger.finest("Sending gssapi user auth request.");
      ByteArrayWriter bytearraywriter = new ByteArrayWriter();
      bytearraywriter.writeUINT32(new UnsignedInteger32(1L));
      byte abyte0[] = GSSConstants.MECH_OID.getDER();
      bytearraywriter.writeBinaryString(abyte0);
      logger.finest("Username:"******"gssapi", bytearraywriter.toByteArray());
      authenticationprotocolclient.sendMessage(sshmsguserauthrequest);
      logger.finest("Receiving user auth response:");
      SshMsgUserauthGssapiResponse sshmsguserauthgssapiresponse =
          (SshMsgUserauthGssapiResponse) authenticationprotocolclient.readMessage(60);
      ByteArrayReader bytearrayreader =
          new ByteArrayReader(sshmsguserauthgssapiresponse.getRequestData());
      byte abyte1[] = bytearrayreader.readBinaryString();
      if (logger.isLoggable(Level.FINEST)) {
        logger.log(Level.FINEST, "Mechanism requested: " + GSSConstants.MECH_OID);
        logger.log(Level.FINEST, "Mechanism selected: " + new Oid(abyte1));
        logger.log(Level.FINEST, "Verify that selected mechanism is GSSAPI.");
      }
      if (!GSSConstants.MECH_OID.equals(new Oid(abyte1))) {
        logger.warning("Mechanism do not match!");
        throw new IOException("Mechanism do not match!");
      }
      logger.finest("Creating GSS context base on grid credentials.");
      GlobusGSSManagerImpl globusgssmanagerimpl = new GlobusGSSManagerImpl();

      HostAuthorization gssAuth = new HostAuthorization(null);
      GSSName targetName = gssAuth.getExpectedName(null, hostname);

      GSSContext gsscontext =
          globusgssmanagerimpl.createContext(
              targetName, new Oid(abyte1), gsscredential, GSSCredential.INDEFINITE_LIFETIME - 1);
      gsscontext.requestCredDeleg(true);
      gsscontext.requestMutualAuth(true);
      gsscontext.requestReplayDet(true);
      gsscontext.requestSequenceDet(true);
      // MOD
      // gsscontext.requestConf(false);
      gsscontext.requestConf(true);

      Object type = GSIConstants.DELEGATION_TYPE_LIMITED;
      gsscontext.requestCredDeleg(false);
      ((ExtendedGSSContext) gsscontext).setOption(GSSConstants.DELEGATION_TYPE, type);

      logger.finest("Starting GSS token exchange.");
      byte abyte2[] = new byte[0];
      do {
        if (gsscontext.isEstablished()) break;
        byte abyte3[] = gsscontext.initSecContext(abyte2, 0, abyte2.length);
        if (abyte3 != null) {
          ByteArrayWriter bytearraywriter1 = new ByteArrayWriter();
          bytearraywriter1.writeBinaryString(abyte3);
          SshMsgUserauthGssapiToken sshmsguserauthgssapitoken =
              new SshMsgUserauthGssapiToken(bytearraywriter1.toByteArray());
          authenticationprotocolclient.sendMessage(sshmsguserauthgssapitoken);
        }
        if (!gsscontext.isEstablished()) {
          SshMsgUserauthGssapiToken sshmsguserauthgssapitoken1 =
              (SshMsgUserauthGssapiToken) authenticationprotocolclient.readMessage(61);
          ByteArrayReader bytearrayreader1 =
              new ByteArrayReader(sshmsguserauthgssapitoken1.getRequestData());
          abyte2 = bytearrayreader1.readBinaryString();
        }
      } while (true);
      logger.log(Level.FINEST, "Sending gssapi exchange complete.");
      SshMsgUserauthGssapiExchangeComplete sshmsguserauthgssapiexchangecomplete =
          new SshMsgUserauthGssapiExchangeComplete();
      authenticationprotocolclient.sendMessage(sshmsguserauthgssapiexchangecomplete);
      if (logger.isLoggable(Level.FINEST)) {
        logger.log(
            Level.FINEST,
            "Context established.\nInitiator : "
                + gsscontext.getSrcName()
                + "\nAcceptor  : "
                + gsscontext.getTargName()
                + "\nLifetime  : "
                + gsscontext.getLifetime()
                + "\nIntegrity   : "
                + gsscontext.getIntegState()
                + "\nConfidentiality   : "
                + gsscontext.getConfState()
                + "\nAnonymity : "
                + gsscontext.getAnonymityState());
      }
    } catch (Throwable t) {
      logger.log(Level.WARNING, "Got Exception: ", t);
      throw new TerminatedStateException(AuthenticationProtocolState.FAILED);
    }
  }
  /**
   * Handle a SOCKS v5 response from the proxy server.
   *
   * @param nextFilter the next filter
   * @param buf the buffered data received
   * @param step the current step in the authentication process
   */
  protected void handleResponse(final NextFilter nextFilter, final IoBuffer buf, int step)
      throws Exception {
    int len = 2;
    if (step == SocksProxyConstants.SOCKS5_GREETING_STEP) {
      // Send greeting message
      byte method = buf.get(1);

      if (method == SocksProxyConstants.NO_ACCEPTABLE_AUTH_METHOD) {
        throw new IllegalStateException(
            "No acceptable authentication method to use with " + "the socks proxy server");
      }

      getSession().setAttribute(SELECTED_AUTH_METHOD, method);

    } else if (step == SocksProxyConstants.SOCKS5_AUTH_STEP) {
      // Authentication to the SOCKS server
      byte method = (Byte) getSession().getAttribute(Socks5LogicHandler.SELECTED_AUTH_METHOD);

      if (method == SocksProxyConstants.GSSAPI_AUTH) {
        int oldPos = buf.position();

        if (buf.get(0) != 0x01) {
          throw new IllegalStateException("Authentication failed");
        }
        if (buf.get(1) == 0xFF) {
          throw new IllegalStateException(
              "Authentication failed: GSS API Security Context Failure");
        }

        if (buf.remaining() >= 2) {
          byte[] size = new byte[2];
          buf.get(size);
          int s = ByteUtilities.makeIntFromByte2(size);
          if (buf.remaining() >= s) {
            byte[] token = new byte[s];
            buf.get(token);
            getSession().setAttribute(GSS_TOKEN, token);
            len = 0;
          } else {
            // buf.position(oldPos);
            return;
          }
        } else {
          buf.position(oldPos);
          return;
        }
      } else if (buf.get(1) != SocksProxyConstants.V5_REPLY_SUCCEEDED) {
        throw new IllegalStateException("Authentication failed");
      }

    } else if (step == SocksProxyConstants.SOCKS5_REQUEST_STEP) {
      // Send the request
      byte addressType = buf.get(3);
      len = 6;
      if (addressType == SocksProxyConstants.IPV6_ADDRESS_TYPE) {
        len += 16;
      } else if (addressType == SocksProxyConstants.IPV4_ADDRESS_TYPE) {
        len += 4;
      } else if (addressType == SocksProxyConstants.DOMAIN_NAME_ADDRESS_TYPE) {
        len += 1 + (buf.get(4));
      } else {
        throw new IllegalStateException("Unknwon address type");
      }

      if (buf.remaining() >= len) {
        // handle response
        byte status = buf.get(1);
        LOGGER.debug("  response status: {}", SocksProxyConstants.getReplyCodeAsString(status));

        if (status == SocksProxyConstants.V5_REPLY_SUCCEEDED) {
          buf.position(buf.position() + len);
          setHandshakeComplete();
          return;
        }

        throw new Exception(
            "Proxy handshake failed - Code: 0x" + ByteUtilities.asHex(new byte[] {status}));
      }

      return;
    }

    if (len > 0) {
      buf.position(buf.position() + len);
    }

    // Move to the handshaking next step if not in the middle of
    // the authentication process
    boolean isAuthenticating = false;
    if (step == SocksProxyConstants.SOCKS5_AUTH_STEP) {
      byte method = (Byte) getSession().getAttribute(Socks5LogicHandler.SELECTED_AUTH_METHOD);
      if (method == SocksProxyConstants.GSSAPI_AUTH) {
        GSSContext ctx = (GSSContext) getSession().getAttribute(GSS_CONTEXT);
        if (ctx == null || !ctx.isEstablished()) {
          isAuthenticating = true;
        }
      }
    }

    if (!isAuthenticating) {
      getSession().setAttribute(HANDSHAKE_STEP, ++step);
    }

    doHandshake(nextFilter);
  }
  /**
   * Encodes the authentication packet for supported authentication methods.
   *
   * @param request the socks proxy request data
   * @return the encoded buffer
   * @throws GSSException when something fails while using GSSAPI
   */
  private IoBuffer encodeGSSAPIAuthenticationPacket(final SocksProxyRequest request)
      throws GSSException {
    GSSContext ctx = (GSSContext) getSession().getAttribute(GSS_CONTEXT);
    if (ctx == null) {
      // first step in the authentication process
      GSSManager manager = GSSManager.getInstance();
      GSSName serverName = manager.createName(request.getServiceKerberosName(), null);
      Oid krb5OID = new Oid(SocksProxyConstants.KERBEROS_V5_OID);

      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Available mechs:");
        for (Oid o : manager.getMechs()) {
          if (o.equals(krb5OID)) {
            LOGGER.debug("Found Kerberos V OID available");
          }
          LOGGER.debug("{} with oid = {}", manager.getNamesForMech(o), o);
        }
      }

      ctx = manager.createContext(serverName, krb5OID, null, GSSContext.DEFAULT_LIFETIME);

      ctx.requestMutualAuth(true); // Mutual authentication
      ctx.requestConf(false);
      ctx.requestInteg(false);

      getSession().setAttribute(GSS_CONTEXT, ctx);
    }

    byte[] token = (byte[]) getSession().getAttribute(GSS_TOKEN);
    if (token != null) {
      LOGGER.debug("  Received Token[{}] = {}", token.length, ByteUtilities.asHex(token));
    }
    IoBuffer buf = null;

    if (!ctx.isEstablished()) {
      // token is ignored on the first call
      if (token == null) {
        token = new byte[32];
      }

      token = ctx.initSecContext(token, 0, token.length);

      // Send a token to the server if one was generated by
      // initSecContext
      if (token != null) {
        LOGGER.debug("  Sending Token[{}] = {}", token.length, ByteUtilities.asHex(token));

        getSession().setAttribute(GSS_TOKEN, token);
        buf = IoBuffer.allocate(4 + token.length);
        buf.put(
            new byte[] {
              SocksProxyConstants.GSSAPI_AUTH_SUBNEGOTIATION_VERSION,
              SocksProxyConstants.GSSAPI_MSG_TYPE
            });

        buf.put(ByteUtilities.intToNetworkByteOrder(token.length, 2));
        buf.put(token);
      }
    }

    return buf;
  }