/** * 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); } }
/** * 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; }
/** * 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; }
/** * 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; }
@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); }
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()); } }
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()); } }
/** * 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; }