/* * Copyright (c) 2016 Dell EMC Software * All Rights Reserved */ package com.iwave.ext.windows.winrm.ntlm.state; import org.apache.http.Header; import org.apache.http.HttpClientConnection; import org.apache.http.HttpHeaders; import org.apache.http.HttpResponse; import org.apache.http.protocol.HttpContext; import com.iwave.ext.windows.winrm.ntlm.NTLMConstants; import com.iwave.ext.windows.winrm.ntlm.NTLMCrypt; import com.iwave.ext.windows.winrm.ntlm.NTLMDecryptedEntity; import com.iwave.ext.windows.winrm.ntlm.NTLMUtils; /** * This state will ping-pong back and forth with EncryptingState in order to continue encrypting/decrypting messages. We will * know that the message needs to be decrypted because there will be a header with an element * protocol=application/HTTP-SPNEGO-session-encrypted */ public final class DecryptingState extends NTLMState { /** The NTLM crypt mechanism to use to encrypt/decrypt messages. */ private NTLMCrypt crypt; /** * Instantiates a state that will handle all decryption for NTLM. * * @param crypt * the encryption mechanism to use */ public DecryptingState(NTLMCrypt crypt) { this.crypt = crypt; } @Override public boolean accepts(HttpResponse response) { // This probably isn't a perfect test; it accepts any Content-Type header that claims to be SPNEGO Header[] headers = response.getHeaders(HttpHeaders.CONTENT_TYPE); for (Header header : headers) { if (header != null && header.getValue().contains(NTLMConstants.CONTENT_TYPE_FOR_SPNEGO)) { return true; } } return false; } @Override public void handle(HttpResponse response, HttpClientConnection conn, HttpContext context) { String boundary = NTLMUtils.getBoundary(response); if (boundary == null) { throw new RuntimeException("Unable to find boundary in http message"); } NTLMDecryptedEntity entity = new NTLMDecryptedEntity(response.getEntity(), crypt, boundary); // Set the content type header in our response to the content type of the decrypted message response.setHeader(entity.getContentType()); response.setEntity(entity); } @Override public NTLMState getNextState() { return new EncryptingState(crypt); } }