예제 #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();
  }
예제 #2
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());
    }
  }
예제 #3
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());
    }
  }