@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; }
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; }