Example #1
0
  /**
   * Encode an SPNEGO NegTokenInit blob
   *
   * @return byte[]
   * @exception IOException
   */
  public byte[] encode() throws IOException {
    // Create the list of objects to be encoded

    List objList = new ArrayList();

    objList.add(new DEROid(OID.ID_SPNEGO));

    // Build the sequence of tagged objects

    DERSequence derSeq = new DERSequence();
    derSeq.setTagNo(0);

    // mechTypes sequence

    DERSequence mechTypesSeq = new DERSequence();
    mechTypesSeq.setTagNo(0);

    for (int i = 0; i < m_mechTypes.length; i++) {
      Oid mechType = m_mechTypes[i];
      mechTypesSeq.addObject(new DEROid(mechType.toString()));
    }

    derSeq.addObject(mechTypesSeq);

    // mechListMIC
    //
    // Note: This field is not as specified

    if (m_mecListMICPrincipal != null) {
      DERSequence derMecSeq = new DERSequence();
      derMecSeq.setTagNo(3);

      DERGeneralString mecStr = new DERGeneralString(m_mecListMICPrincipal);
      mecStr.setTagNo(0);

      derMecSeq.addObject(mecStr);
      derSeq.addObject(derMecSeq);
    }

    // Add the sequence to the object list

    objList.add(derSeq);

    // Pack the objects

    DERBuffer derBuf = new DERBuffer();

    derBuf.packApplicationSpecific(objList);

    // Return the packed negTokenInit blob

    return derBuf.getBytes();
  }
  public static String serializeCredential(GSSCredential gssCredential)
      throws KerberosSerializationException {
    try {
      if (gssCredential == null) {
        throw new KerberosSerializationException("Null credential given as input");
      }

      if (!(gssCredential instanceof GSSCredentialImpl)) {
        throw new KerberosSerializationException(
            "Unknown credential type: " + gssCredential.getClass());
      }

      GSSCredentialImpl gssCredImpl = (GSSCredentialImpl) gssCredential;
      Oid[] mechs = gssCredImpl.getMechs();

      for (Oid oid : mechs) {
        if (oid.equals(KRB5_OID)) {
          int usage = gssCredImpl.getUsage(oid);
          boolean initiate =
              (usage == GSSCredential.INITIATE_ONLY || usage == GSSCredential.INITIATE_AND_ACCEPT);

          GSSCredentialSpi credentialSpi = gssCredImpl.getElement(oid, initiate);
          if (credentialSpi instanceof Krb5InitCredential) {
            Krb5InitCredential credential = (Krb5InitCredential) credentialSpi;
            KerberosTicket kerberosTicket =
                new KerberosTicket(
                    credential.getEncoded(),
                    credential.getClient(),
                    credential.getServer(),
                    credential.getSessionKey().getEncoded(),
                    credential.getSessionKeyType(),
                    credential.getFlags(),
                    credential.getAuthTime(),
                    credential.getStartTime(),
                    credential.getEndTime(),
                    credential.getRenewTill(),
                    credential.getClientAddresses());
            return serialize(kerberosTicket);
          } else {
            throw new KerberosSerializationException(
                "Unsupported type of credentialSpi: " + credentialSpi.getClass());
          }
        }
      }

      throw new KerberosSerializationException(
          "Kerberos credential not found. Available mechanisms: " + mechs);
    } catch (IOException e) {
      throw new KerberosSerializationException("Exception occured", e);
    } catch (GSSException e) {
      throw new KerberosSerializationException("Exception occured", e);
    }
  }
Example #3
0
  /**
   * Create an ASN.1, DER encoded representation for the GSSUP OID mechanism.
   *
   * @return the DER encoded representation of the GSSUP OID.
   */
  public static byte[] createGSSUPMechOID() {
    // kudos to org.ietf.jgss.Oid for the Oid utility need to strip the "oid:" part of the
    // GSSUPMechOID first.

    byte[] retval = {};
    try {
      Oid oid = new Oid(GSSUPMechOID.value.substring(4));
      retval = oid.getDER();
    } catch (GSSException e) {
      JacORBLogger.ROOT_LOGGER.caughtExceptionEncodingGSSUPMechOID(e);
    }
    return retval;
  }
Example #4
0
  /**
   * Create an ASN.1, DER encoded representation for the GSSUP OID mechanism.
   *
   * @return the DER encoded representation of the GSSUP OID.
   */
  public static byte[] createGSSUPMechOID() {
    // kudos to org.ietf.jgss.Oid for the Oid utility need to strip the "oid:" part of the
    // GSSUPMechOID first.

    byte[] retval = {};
    try {
      Oid oid = new Oid(GSSUPMechOID.value.substring(4));
      retval = oid.getDER();
    } catch (GSSException e) {
      log.warn("Caught exception while encoding GSSUPMechOID", e);
    }
    return retval;
  }
Example #5
0
  /**
   * Check if the OID list contains the specified OID
   *
   * @param oid Oid
   * @return boolean
   */
  public final boolean hasOid(Oid oid) {
    boolean foundOid = false;

    if (m_mechTypes != null) foundOid = oid.containedIn(m_mechTypes);

    return foundOid;
  }
Example #6
0
 @Override
 public boolean equals(GSSName another) throws GSSException {
   if (!(another instanceof BogusGSSName)) {
     throw new GSSException(GSSException.BAD_NAMETYPE);
   }
   BogusGSSName otherName = (BogusGSSName) another;
   return name.equals(otherName.name) && oid.equals(otherName.oid);
 }
Example #7
0
  public void acceptSecContext(InputStream inStream, OutputStream outStream) throws GSSException {

    if (mechCtxt != null && currentState != IN_PROGRESS) {
      throw new GSSExceptionImpl(GSSException.FAILURE, "Illegal call to acceptSecContext");
    }

    GSSHeader gssHeader = null;
    int inTokenLen = -1;
    GSSCredentialSpi credElement = null;

    try {
      if (mechCtxt == null) {
        // mechOid will be null for an acceptor's context
        gssHeader = new GSSHeader(inStream);
        inTokenLen = gssHeader.getMechTokenLength();

        /*
         * Convert ObjectIdentifier to Oid
         */
        objId = gssHeader.getOid();
        mechOid = new Oid(objId.toString());
        // System.out.println("Entered GSSContextImpl.acceptSecContext"
        //                      + " with mechanism = " + mechOid);
        if (myCred != null) {
          credElement = myCred.getElement(mechOid, false);
        }

        mechCtxt = gssManager.getMechanismContext(credElement, mechOid);
        mechCtxt.setChannelBinding(channelBindings);

        currentState = IN_PROGRESS;
      } else {
        if (mechCtxt.getProvider().getName().equals("SunNativeGSS")
            || (GSSUtil.isSpNegoMech(mechOid))) {
          // do not parse GSS header for native provider and SPNEGO
        } else {
          // parse GSS Header
          gssHeader = new GSSHeader(inStream);
          if (!gssHeader.getOid().equals((Object) objId))
            throw new GSSExceptionImpl(
                GSSException.DEFECTIVE_TOKEN,
                "Mechanism not equal to " + mechOid.toString() + " in acceptSecContext token");
          inTokenLen = gssHeader.getMechTokenLength();
        }
      }

      byte[] obuf = mechCtxt.acceptSecContext(inStream, inTokenLen);

      if (obuf != null) {
        int retVal = obuf.length;
        if (mechCtxt.getProvider().getName().equals("SunNativeGSS")
            || (GSSUtil.isSpNegoMech(mechOid))) {
          // do not add GSS header for native provider and SPNEGO
        } else {
          // add GSS header
          gssHeader = new GSSHeader(objId, obuf.length);
          retVal += gssHeader.encode(outStream);
        }
        outStream.write(obuf);
      }

      if (mechCtxt.isEstablished()) {
        currentState = READY;
      }
    } catch (IOException e) {
      throw new GSSExceptionImpl(GSSException.DEFECTIVE_TOKEN, e.getMessage());
    }
  }
Example #8
0
  public int initSecContext(InputStream inStream, OutputStream outStream) throws GSSException {

    if (mechCtxt != null && currentState != IN_PROGRESS) {
      throw new GSSExceptionImpl(GSSException.FAILURE, "Illegal call to initSecContext");
    }

    GSSHeader gssHeader = null;
    int inTokenLen = -1;
    GSSCredentialSpi credElement = null;
    boolean firstToken = false;

    try {
      if (mechCtxt == null) {
        if (myCred != null) {
          try {
            credElement = myCred.getElement(mechOid, true);
          } catch (GSSException ge) {
            if (GSSUtil.isSpNegoMech(mechOid) && ge.getMajor() == GSSException.NO_CRED) {
              credElement = myCred.getElement(myCred.getMechs()[0], true);
            } else {
              throw ge;
            }
          }
        }
        GSSNameSpi nameElement = targName.getElement(mechOid);
        mechCtxt = gssManager.getMechanismContext(nameElement, credElement, reqLifetime, mechOid);
        mechCtxt.requestConf(reqConfState);
        mechCtxt.requestInteg(reqIntegState);
        mechCtxt.requestCredDeleg(reqCredDelegState);
        mechCtxt.requestMutualAuth(reqMutualAuthState);
        mechCtxt.requestReplayDet(reqReplayDetState);
        mechCtxt.requestSequenceDet(reqSequenceDetState);
        mechCtxt.requestAnonymity(reqAnonState);
        mechCtxt.setChannelBinding(channelBindings);
        mechCtxt.requestDelegPolicy(reqDelegPolicyState);

        objId = new ObjectIdentifier(mechOid.toString());

        currentState = IN_PROGRESS;
        firstToken = true;
      } else {
        if (mechCtxt.getProvider().getName().equals("SunNativeGSS")
            || GSSUtil.isSpNegoMech(mechOid)) {
          // do not parse GSS header for native provider or SPNEGO
          // mech
        } else {
          // parse GSS header
          gssHeader = new GSSHeader(inStream);
          if (!gssHeader.getOid().equals((Object) objId))
            throw new GSSExceptionImpl(
                GSSException.DEFECTIVE_TOKEN,
                "Mechanism not equal to " + mechOid.toString() + " in initSecContext token");
          inTokenLen = gssHeader.getMechTokenLength();
        }
      }

      byte[] obuf = mechCtxt.initSecContext(inStream, inTokenLen);

      int retVal = 0;

      if (obuf != null) {
        retVal = obuf.length;
        if (mechCtxt.getProvider().getName().equals("SunNativeGSS")
            || (!firstToken && GSSUtil.isSpNegoMech(mechOid))) {
          // do not add GSS header for native provider or SPNEGO
          // except for the first SPNEGO token
        } else {
          // add GSS header
          gssHeader = new GSSHeader(objId, obuf.length);
          retVal += gssHeader.encode(outStream);
        }
        outStream.write(obuf);
      }

      if (mechCtxt.isEstablished()) currentState = READY;

      return retVal;

    } catch (IOException e) {
      throw new GSSExceptionImpl(GSSException.DEFECTIVE_TOKEN, e.getMessage());
    }
  }
  public String generateToken(String authServer) throws Throwable {

    try {
      if (this.stripPort) {
        authServer = authServer.substring(0, authServer.indexOf(":"));
      }

      if (log.isDebugEnabled()) {
        log.debug("init " + authServer);
      }
      /* Using the SPNEGO OID is the correct method.
       * Kerberos v5 works for IIS but not JBoss. Unwrapping
       * the initial token when using SPNEGO OID looks like what is
       * described here...
       *
       * http://msdn.microsoft.com/en-us/library/ms995330.aspx
       *
       * Another helpful URL...
       *
       * http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tsec_SPNEGO_token.html
       *
       * Unfortunately SPNEGO is JRE >=1.6.
       */

      /** Try SPNEGO by default, fall back to Kerberos later if error */
      negotiationOid = new Oid(SPNEGO_OID);

      boolean tryKerberos = false;
      try {
        GSSManager manager = GSSManager.getInstance();
        GSSName serverName = manager.createName("HTTP/" + authServer, null);
        gssContext =
            manager.createContext(
                serverName.canonicalize(negotiationOid),
                negotiationOid,
                null,
                GSSContext.DEFAULT_LIFETIME);
        gssContext.requestMutualAuth(true);
        gssContext.requestCredDeleg(true);
      } catch (GSSException ex) {
        log.error("generateToken", ex);
        // BAD MECH means we are likely to be using 1.5, fall back to Kerberos MECH.
        // Rethrow any other exception.
        if (ex.getMajor() == GSSException.BAD_MECH) {
          log.debug("GSSException BAD_MECH, retry with Kerberos MECH");
          tryKerberos = true;
        } else {
          throw ex;
        }
      }
      if (tryKerberos) {
        /* Kerberos v5 GSS-API mechanism defined in RFC 1964.*/
        log.debug("Using Kerberos MECH " + KERBEROS_OID);
        negotiationOid = new Oid(KERBEROS_OID);
        GSSManager manager = GSSManager.getInstance();
        GSSName serverName = manager.createName("HTTP/" + authServer, null);
        gssContext =
            manager.createContext(
                serverName.canonicalize(negotiationOid),
                negotiationOid,
                null,
                GSSContext.DEFAULT_LIFETIME);
        gssContext.requestMutualAuth(true);
        gssContext.requestCredDeleg(true);
      }
      if (token == null) {
        token = new byte[0];
      }
      token = gssContext.initSecContext(token, 0, token.length);
      if (token == null) {
        throw new Exception("GSS security context initialization failed");
      }

      /*
       * IIS accepts Kerberos and SPNEGO tokens. Some other servers Jboss, Glassfish?
       * seem to only accept SPNEGO. Below wraps Kerberos into SPNEGO token.
       */
      if (spengoGenerator != null && negotiationOid.toString().equals(KERBEROS_OID)) {
        token = spengoGenerator.generateSpnegoDERObject(token);
      }

      String tokenstr = new String(Base64.encode(token));
      if (log.isDebugEnabled()) {
        log.debug("Sending response '" + tokenstr + "' back to the auth server");
      }
      return "Negotiate " + tokenstr;
    } catch (GSSException gsse) {
      log.error("generateToken", gsse);
      if (gsse.getMajor() == GSSException.DEFECTIVE_CREDENTIAL
          || gsse.getMajor() == GSSException.CREDENTIALS_EXPIRED)
        throw new Exception(gsse.getMessage(), gsse);
      if (gsse.getMajor() == GSSException.NO_CRED) throw new Exception(gsse.getMessage(), gsse);
      if (gsse.getMajor() == GSSException.DEFECTIVE_TOKEN
          || gsse.getMajor() == GSSException.DUPLICATE_TOKEN
          || gsse.getMajor() == GSSException.OLD_TOKEN)
        throw new Exception(gsse.getMessage(), gsse);
      // other error
      throw new Exception(gsse.getMessage());
    } catch (IOException ex) {
      throw new Exception(ex.getMessage());
    }
  }
Example #10
0
  /**
   * 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;
  }