Search in sources :

Example 1 with AS2NoModuleException

use of com.helger.as2lib.processor.AS2NoModuleException in project as2-lib by phax.

the class AS2MDNReceiverHandler method receiveMDN.

// Asynch MDN 2007-03-12
/**
 * method for receiving and processing Async MDN sent from receiver.
 *
 * @param aMsg
 *        The MDN message
 * @param aData
 *        The MDN content
 * @param aResponseHandler
 *        The HTTP response handler for setting the correct HTTP response code
 * @param aResHelper
 *        Resource helper
 * @throws AS2Exception
 *         In case of error
 * @throws IOException
 *         In case of IO error
 */
protected final void receiveMDN(@Nonnull final AS2Message aMsg, final byte[] aData, @Nonnull final IAS2HttpResponseHandler aResponseHandler, @Nonnull final AS2ResourceHelper aResHelper) throws AS2Exception, IOException {
    try {
        // Create a MessageMDN and copy HTTP headers
        final IMessageMDN aMDN = new AS2MessageMDN(aMsg);
        // copy headers from msg to MDN from msg
        aMDN.headers().setAllHeaders(aMsg.headers());
        final MimeBodyPart aPart = new MimeBodyPart(AS2HttpHelper.getAsInternetHeaders(aMDN.headers()), aData);
        aMDN.setData(aPart);
        // get the MDN partnership info
        aMDN.partnership().setSenderAS2ID(aMDN.getHeader(CHttpHeader.AS2_FROM));
        aMDN.partnership().setReceiverAS2ID(aMDN.getHeader(CHttpHeader.AS2_TO));
        // Set the appropriate keystore aliases
        aMDN.partnership().setSenderX509Alias(aMsg.partnership().getReceiverX509Alias());
        aMDN.partnership().setReceiverX509Alias(aMsg.partnership().getSenderX509Alias());
        // Update the partnership
        getModule().getSession().getPartnershipFactory().updatePartnership(aMDN, false);
        final ICertificateFactory aCertFactory = getModule().getSession().getCertificateFactory();
        final X509Certificate aSenderCert = aCertFactory.getCertificate(aMDN, ECertificatePartnershipType.SENDER);
        final boolean bUseCertificateInBodyPart;
        final ETriState eUseCertificateInBodyPart = aMsg.partnership().getVerifyUseCertificateInBodyPart();
        if (eUseCertificateInBodyPart.isDefined()) {
            // Use per partnership
            bUseCertificateInBodyPart = eUseCertificateInBodyPart.getAsBooleanValue();
        } else {
            // Use global value
            bUseCertificateInBodyPart = getModule().getSession().isCryptoVerifyUseCertificateInBodyPart();
        }
        AS2Helper.parseMDN(aMsg, aSenderCert, bUseCertificateInBodyPart, getVerificationCertificateConsumer(), aResHelper);
        // in order to name & save the mdn with the original AS2-From + AS2-To +
        // Message id.,
        // the 3 msg attributes have to be reset before calling MDNFileModule
        aMsg.partnership().setSenderAS2ID(aMDN.getHeader(CHttpHeader.AS2_TO));
        aMsg.partnership().setReceiverAS2ID(aMDN.getHeader(CHttpHeader.AS2_FROM));
        getModule().getSession().getPartnershipFactory().updatePartnership(aMsg, false);
        aMsg.setMessageID(aMDN.attrs().getAsString(AS2MessageMDN.MDNA_ORIG_MESSAGEID));
        try {
            getModule().getSession().getMessageProcessor().handle(IProcessorStorageModule.DO_STOREMDN, aMsg, null);
        } catch (final AS2ComponentNotFoundException | AS2NoModuleException ex) {
        // No message processor found
        // Or no module found in message processor
        }
        // check if the mic (message integrity check) is correct
        final boolean bMICMatch = checkAsyncMDN(aMsg);
        HTTPHelper.sendSimpleHTTPResponse(aResponseHandler, bMICMatch ? CHttp.HTTP_OK : CHttp.HTTP_NOT_FOUND);
        final String sDisposition = aMDN.attrs().getAsString(AS2MessageMDN.MDNA_DISPOSITION);
        if (m_aIncomingMDNCallback != null)
            m_aIncomingMDNCallback.onIncomingMDN(false, aMDN, aMDN.getHeader(CHttpHeader.AS2_FROM), aMDN.getHeader(CHttpHeader.AS2_TO), sDisposition, aMDN.attrs().getAsString(AS2MessageMDN.MDNA_MIC), aMDN.attrs().getAsString(AS2MessageMDN.MDNA_ORIG_MESSAGEID), aMDN.attrs().getAsBoolean(AS2Message.ATTRIBUTE_RECEIVED_SIGNED, false), bMICMatch);
        DispositionType.createFromString(sDisposition).validate(aMsg, aMDN.getText());
    } catch (final IOException ex) {
        HTTPHelper.sendSimpleHTTPResponse(aResponseHandler, CHttp.HTTP_BAD_REQUEST);
        throw ex;
    } catch (final Exception ex) {
        HTTPHelper.sendSimpleHTTPResponse(aResponseHandler, CHttp.HTTP_BAD_REQUEST);
        throw WrappedAS2Exception.wrap(ex).setSourceMsg(aMsg);
    }
}
Also used : AS2MessageMDN(com.helger.as2lib.message.AS2MessageMDN) ETriState(com.helger.commons.state.ETriState) ICertificateFactory(com.helger.as2lib.cert.ICertificateFactory) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) MessagingException(javax.mail.MessagingException) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) AS2Exception(com.helger.as2lib.exception.AS2Exception) WrappedAS2Exception(com.helger.as2lib.exception.WrappedAS2Exception) IOException(java.io.IOException) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) IMessageMDN(com.helger.as2lib.message.IMessageMDN) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 2 with AS2NoModuleException

use of com.helger.as2lib.processor.AS2NoModuleException in project as2-lib by phax.

the class AsynchMDNSenderModule method _sendViaHTTP.

private void _sendViaHTTP(@Nonnull final AS2Message aMsg, @Nonnull final DispositionType aDisposition, @Nullable final IHTTPOutgoingDumper aOutgoingDumper, @Nonnull final AS2ResourceHelper aResHelper) throws AS2Exception, IOException, MessagingException {
    final IMessageMDN aMdn = aMsg.getMDN();
    // Create a HTTP connection
    final String sUrl = aMsg.getAsyncMDNurl();
    final EHttpMethod eRequestMethod = EHttpMethod.POST;
    // MDN is a small message. We will always use CHttp
    final AS2HttpClient aConn = getHttpClient(sUrl, eRequestMethod, getSession().getHttpProxy());
    try {
        if (aOutgoingDumper != null)
            aOutgoingDumper.start(sUrl, aMsg);
        if (LOGGER.isInfoEnabled())
            LOGGER.info("Connecting to " + sUrl + aMsg.getLoggingText());
        // Set all custom headers first (so that they are overridden with the
        // mandatory ones in here)
        // Use HttpHeaderMap and not String to ensure name casing is identical!
        final HttpHeaderMap aHeaderMap = aMdn.headers().getClone();
        aHeaderMap.setHeader(CHttpHeader.CONNECTION, CAS2Header.DEFAULT_CONNECTION);
        aHeaderMap.setHeader(CHttpHeader.USER_AGENT, CAS2Header.DEFAULT_USER_AGENT);
        final boolean bQuoteHeaderValues = isQuoteHeaderValues();
        final AS2HttpHeaderSetter aHeaderSetter = new AS2HttpHeaderSetter(aConn, aOutgoingDumper, bQuoteHeaderValues);
        // Copy all the header from mdn to the RequestProperties of conn
        // Unification needed, because original MDN headers may contain newlines
        aHeaderMap.forEachSingleHeader(aHeaderSetter::setHttpHeader, true, false);
        if (aOutgoingDumper != null)
            aOutgoingDumper.finishedHeaders();
        aMsg.attrs().putIn(CNetAttribute.MA_DESTINATION_IP, aConn.getURL().getHost());
        aMsg.attrs().putIn(CNetAttribute.MA_DESTINATION_PORT, aConn.getURL().getPort());
        final InputStream aMsgIS = aMdn.getData().getInputStream();
        // Transfer the data
        final StopWatch aSW = StopWatch.createdStarted();
        final long nBytes = aConn.send(aMsgIS, (EContentTransferEncoding) null, aOutgoingDumper, aResHelper);
        aSW.stop();
        if (LOGGER.isInfoEnabled())
            LOGGER.info("AS2 MDN transferred " + AS2IOHelper.getTransferRate(nBytes, aSW) + aMsg.getLoggingText());
        if (aOutgoingDumper != null)
            aOutgoingDumper.finishedPayload();
        final int nHttpResponseCode = aConn.getResponseCode();
        if (getOutgoingHttpCallback() != null)
            getOutgoingHttpCallback().onOutgoingHttpMessage(false, aMsg.getAS2From(), aMsg.getAS2To(), aMsg.getMessageID(), (MIC) null, (EContentTransferEncoding) null, sUrl, nHttpResponseCode);
        // Check the HTTP Response code
        if (AS2HttpClient.isErrorResponseCode(nHttpResponseCode)) {
            if (LOGGER.isErrorEnabled())
                LOGGER.error("sent AsyncMDN [" + aDisposition.getAsString() + "] Fail(" + nHttpResponseCode + ") " + aMsg.getLoggingText());
            throw new AS2HttpResponseException(sUrl, nHttpResponseCode, aConn.getResponseMessage());
        }
        if (LOGGER.isInfoEnabled())
            LOGGER.info("sent AsyncMDN [" + aDisposition.getAsString() + "] OK(" + nHttpResponseCode + ") " + aMsg.getLoggingText());
        // log & store mdn into backup folder.
        try {
            getSession().getMessageProcessor().handle(IProcessorStorageModule.DO_STOREMDN, aMsg, null);
        } catch (final AS2ComponentNotFoundException | AS2NoModuleException ex) {
        // No message processor found
        // Or no module found in message processor
        }
    } finally {
        aConn.disconnect();
    }
}
Also used : EContentTransferEncoding(com.helger.mail.cte.EContentTransferEncoding) InputStream(java.io.InputStream) MIC(com.helger.as2lib.crypto.MIC) StopWatch(com.helger.commons.timing.StopWatch) HttpHeaderMap(com.helger.commons.http.HttpHeaderMap) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) AS2HttpHeaderSetter(com.helger.as2lib.util.http.AS2HttpHeaderSetter) EHttpMethod(com.helger.commons.http.EHttpMethod) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) IMessageMDN(com.helger.as2lib.message.IMessageMDN) AS2HttpClient(com.helger.as2lib.util.http.AS2HttpClient)

Example 3 with AS2NoModuleException

use of com.helger.as2lib.processor.AS2NoModuleException in project as2-lib by phax.

the class AS2ReceiverHandler method handleIncomingMessage.

/**
 * This method can be used to handle an incoming HTTP message AFTER the
 * headers where extracted.
 *
 * @param sClientInfo
 *        Client connection info
 * @param aMsgData
 *        The message body
 * @param aMsg
 *        The AS2 message that will be filled by this method
 * @param aResponseHandler
 *        The response handler which handles HTTP error messages as well as
 *        synchronous MDN.
 */
public void handleIncomingMessage(@Nonnull final String sClientInfo, @Nonnull final DataSource aMsgData, @Nonnull final AS2Message aMsg, @Nonnull final IAS2HttpResponseHandler aResponseHandler) {
    // handler, to avoid the decrypted content gets removed (see issue #135)
    try (final AS2ResourceHelper aResHelper = new AS2ResourceHelper()) {
        try {
            final IAS2Session aSession = m_aReceiverModule.getSession();
            try {
                // Put received data in a MIME body part
                final String sReceivedContentType = AS2HttpHelper.getCleanContentType(aMsg.getHeader(CHttpHeader.CONTENT_TYPE));
                final MimeBodyPart aReceivedPart = new MimeBodyPart();
                aReceivedPart.setDataHandler(new DataHandler(aMsgData));
                // Header must be set AFTER the DataHandler!
                aReceivedPart.setHeader(CHttpHeader.CONTENT_TYPE, sReceivedContentType);
                aMsg.setData(aReceivedPart);
            } catch (final Exception ex) {
                throw new AS2DispositionException(DispositionType.createError("unexpected-processing-error"), AbstractActiveNetModule.DISP_PARSING_MIME_FAILED, ex);
            }
            // update the message
            try {
                final String sAS2From = aMsg.getAS2From();
                aMsg.partnership().setSenderAS2ID(sAS2From);
                final String sAS2To = aMsg.getAS2To();
                aMsg.partnership().setReceiverAS2ID(sAS2To);
                // Fill all partnership attributes etc.
                aSession.getPartnershipFactory().updatePartnership(aMsg, false);
            } catch (final AS2Exception ex) {
                throw AS2DispositionException.wrap(ex, () -> DispositionType.createError("authentication-failed"), () -> AbstractActiveNetModule.DISP_PARTNERSHIP_NOT_FOUND);
            }
            // Per RFC5402 compression is always before encryption but can be before
            // or after signing of message but only in one place
            final ICryptoHelper aCryptoHelper = AS2Helper.getCryptoHelper();
            boolean bIsDecompressed = false;
            // Decrypt and verify signature of the data, and attach data to the
            // message
            decrypt(aMsg, aResHelper);
            if (aCryptoHelper.isCompressed(aMsg.getContentType())) {
                if (LOGGER.isTraceEnabled())
                    LOGGER.trace("Decompressing received message before checking signature...");
                decompress(aMsg);
                bIsDecompressed = true;
            }
            verify(aMsg, aResHelper);
            if (aCryptoHelper.isCompressed(aMsg.getContentType())) {
                // or after signing of message but only in one place
                if (bIsDecompressed) {
                    throw new AS2DispositionException(DispositionType.createError("decompression-failed"), AbstractActiveNetModule.DISP_DECOMPRESSION_ERROR, new Exception("Message has already been decompressed. Per RFC5402 it cannot occur twice."));
                }
                if (LOGGER.isTraceEnabled())
                    if (aMsg.attrs().containsKey(AS2Message.ATTRIBUTE_RECEIVED_SIGNED))
                        LOGGER.trace("Decompressing received message after verifying signature...");
                    else
                        LOGGER.trace("Decompressing received message after decryption...");
                decompress(aMsg);
                bIsDecompressed = true;
            }
            if (LOGGER.isTraceEnabled())
                try {
                    LOGGER.trace("SMIME Decrypted Content-Disposition: " + aMsg.getContentDisposition() + "\n      Content-Type received: " + aMsg.getContentType() + "\n      HEADERS after decryption: " + aMsg.getData().getAllHeaders() + "\n      Content-Disposition in MSG detData() MIMEPART after decryption: " + aMsg.getData().getContentType());
                } catch (final MessagingException ex) {
                    if (LOGGER.isErrorEnabled())
                        LOGGER.error("Failed to trace message: " + aMsg, ex);
                }
            // Validate the received message before storing
            try {
                aSession.getMessageProcessor().handle(IProcessorStorageModule.DO_VALIDATE_BEFORE_STORE, aMsg, null);
            } catch (final AS2NoModuleException ex) {
            // No module installed - ignore
            } catch (final AS2Exception ex) {
                // Issue 90 - use CRLF as separator
                throw AS2DispositionException.wrap(ex, () -> DispositionType.createError("unexpected-processing-error"), () -> StringHelper.getConcatenatedOnDemand(AbstractActiveNetModule.DISP_VALIDATION_FAILED, CHttp.EOL, _getDispositionText(ex)));
            }
            // Store the received message
            try {
                aSession.getMessageProcessor().handle(IProcessorStorageModule.DO_STORE, aMsg, null);
            } catch (final AS2NoModuleException ex) {
            // No module installed - ignore
            } catch (final AS2Exception ex) {
                // Issue 90 - use CRLF as separator
                throw AS2DispositionException.wrap(ex, () -> DispositionType.createError("unexpected-processing-error"), () -> StringHelper.getConcatenatedOnDemand(AbstractActiveNetModule.DISP_STORAGE_FAILED, CHttp.EOL, _getDispositionText(ex)));
            }
            // Validate the received message after storing
            try {
                aSession.getMessageProcessor().handle(IProcessorStorageModule.DO_VALIDATE_AFTER_STORE, aMsg, null);
            } catch (final AS2NoModuleException ex) {
            // No module installed - ignore
            } catch (final AS2Exception ex) {
                // Issue 90 - use CRLF as separator
                throw AS2DispositionException.wrap(ex, () -> DispositionType.createError("unexpected-processing-error"), () -> StringHelper.getConcatenatedOnDemand(AbstractActiveNetModule.DISP_VALIDATION_FAILED, CHttp.EOL, _getDispositionText(ex)));
            }
            try {
                if (aMsg.isRequestingMDN()) {
                    if (LOGGER.isTraceEnabled())
                        LOGGER.trace("AS2 message is requesting an MDN");
                    // Transmit a success MDN if requested
                    sendMDN(sClientInfo, aResponseHandler, aMsg, DispositionType.createSuccess(), AbstractActiveNetModule.DISP_SUCCESS, ESuccess.SUCCESS);
                } else {
                    if (LOGGER.isTraceEnabled())
                        LOGGER.trace("AS2 message is not requesting an MDN - just sending HTTP 200 (OK)");
                    // Just send a HTTP OK
                    HTTPHelper.sendSimpleHTTPResponse(aResponseHandler, CHttp.HTTP_OK);
                    if (LOGGER.isInfoEnabled())
                        LOGGER.info("sent HTTP OK " + sClientInfo + aMsg.getLoggingText());
                }
            } catch (final Exception ex) {
                throw new AS2Exception("Error creating and returning MDN, message was stilled processed", ex);
            }
        } catch (final AS2DispositionException ex) {
            sendMDN(sClientInfo, aResponseHandler, aMsg, ex.getDisposition(), ex.getText(), ESuccess.FAILURE);
            m_aReceiverModule.handleError(aMsg, ex);
        } catch (final AS2Exception ex) {
            m_aReceiverModule.handleError(aMsg, ex);
        } finally {
            // close the temporary shared stream if it exists
            final TempSharedFileInputStream sis = aMsg.getTempSharedFileInputStream();
            if (null != sis) {
                try {
                    sis.closeAll();
                } catch (final IOException e) {
                    LOGGER.error("Exception while closing TempSharedFileInputStream", e);
                }
            }
        }
    }
}
Also used : MessagingException(javax.mail.MessagingException) TempSharedFileInputStream(com.helger.as2lib.util.http.TempSharedFileInputStream) DataHandler(javax.activation.DataHandler) IOException(java.io.IOException) ICryptoHelper(com.helger.as2lib.crypto.ICryptoHelper) MessagingException(javax.mail.MessagingException) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) AS2DispositionException(com.helger.as2lib.disposition.AS2DispositionException) AS2ProcessorException(com.helger.as2lib.processor.AS2ProcessorException) CMSException(org.bouncycastle.cms.CMSException) AS2Exception(com.helger.as2lib.exception.AS2Exception) WrappedAS2Exception(com.helger.as2lib.exception.WrappedAS2Exception) IOException(java.io.IOException) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) IAS2Session(com.helger.as2lib.session.IAS2Session) AS2ResourceHelper(com.helger.as2lib.util.AS2ResourceHelper) AS2DispositionException(com.helger.as2lib.disposition.AS2DispositionException) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) AS2Exception(com.helger.as2lib.exception.AS2Exception) WrappedAS2Exception(com.helger.as2lib.exception.WrappedAS2Exception) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 4 with AS2NoModuleException

use of com.helger.as2lib.processor.AS2NoModuleException in project as2-lib by phax.

the class AS2ReceiverHandler method sendMDN.

protected void sendMDN(@Nonnull final String sClientInfo, @Nonnull final IAS2HttpResponseHandler aResponseHandler, @Nonnull final AS2Message aMsg, @Nonnull final DispositionType aDisposition, @Nonnull final String sText, @Nonnull final ESuccess eSuccess) {
    final boolean bAllowErrorMDN = !aMsg.partnership().isBlockErrorMDN();
    if (eSuccess.isSuccess() || bAllowErrorMDN) {
        try {
            final IAS2Session aSession = m_aReceiverModule.getSession();
            final IMessageMDN aMdn = AS2Helper.createMDN(aSession, aMsg, aDisposition, sText);
            if (aMsg.isRequestingAsynchMDN()) {
                // if asyncMDN requested, close existing synchronous connection and
                // initiate separate MDN send
                final HttpHeaderMap aHeaders = new HttpHeaderMap();
                aHeaders.setContentLength(0);
                try (final NonBlockingByteArrayOutputStream aData = new NonBlockingByteArrayOutputStream()) {
                    // Empty data
                    // Ideally this would be HTTP 204 (no content)
                    aResponseHandler.sendHttpResponse(CHttp.HTTP_OK, aHeaders, aData);
                }
                if (LOGGER.isInfoEnabled())
                    LOGGER.info("Setup to send async MDN [" + aDisposition.getAsString() + "] " + sClientInfo + aMsg.getLoggingText());
                // trigger explicit async sending
                aSession.getMessageProcessor().handle(IProcessorSenderModule.DO_SEND_ASYNC_MDN, aMsg, null);
            } else {
                // otherwise, send sync MDN back on same connection
                if (LOGGER.isInfoEnabled())
                    LOGGER.info("Sending back sync MDN [" + aDisposition.getAsString() + "] " + sClientInfo + aMsg.getLoggingText());
                // Get data and therefore content length for sync MDN
                try (final NonBlockingByteArrayOutputStream aData = new NonBlockingByteArrayOutputStream()) {
                    final MimeBodyPart aPart = aMdn.getData();
                    StreamHelper.copyInputStreamToOutputStream(aPart.getInputStream(), aData);
                    aMdn.headers().setContentLength(aData.size());
                    // start HTTP response
                    aResponseHandler.sendHttpResponse(CHttp.HTTP_OK, aMdn.headers(), aData);
                }
                // Save sent MDN for later examination
                try {
                    aSession.getMessageProcessor().handle(IProcessorStorageModule.DO_STOREMDN, aMsg, null);
                } catch (final AS2ComponentNotFoundException | AS2NoModuleException ex) {
                // No message processor found
                // or No module found in message processor
                }
                if (LOGGER.isInfoEnabled())
                    LOGGER.info("sent MDN [" + aDisposition.getAsString() + "] " + sClientInfo + aMsg.getLoggingText());
            }
        } catch (final Exception ex) {
            WrappedAS2Exception.wrap(ex).terminate(aMsg);
        }
    }
}
Also used : HttpHeaderMap(com.helger.commons.http.HttpHeaderMap) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) NonBlockingByteArrayOutputStream(com.helger.commons.io.stream.NonBlockingByteArrayOutputStream) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) IMessageMDN(com.helger.as2lib.message.IMessageMDN) MimeBodyPart(javax.mail.internet.MimeBodyPart) MessagingException(javax.mail.MessagingException) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) AS2DispositionException(com.helger.as2lib.disposition.AS2DispositionException) AS2ProcessorException(com.helger.as2lib.processor.AS2ProcessorException) CMSException(org.bouncycastle.cms.CMSException) AS2Exception(com.helger.as2lib.exception.AS2Exception) WrappedAS2Exception(com.helger.as2lib.exception.WrappedAS2Exception) IOException(java.io.IOException) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) IAS2Session(com.helger.as2lib.session.IAS2Session)

Example 5 with AS2NoModuleException

use of com.helger.as2lib.processor.AS2NoModuleException in project as2-lib by phax.

the class AS2SenderModule method receiveSyncMDN.

/**
 * @param aMsg
 *        AS2Message
 * @param aHttpClient
 *        URLConnection
 * @param aOriginalMIC
 *        mic value from original msg
 * @param aIncomingDumper
 *        Incoming dumper. May be <code>null</code>.
 * @param aResHelper
 *        Resource helper
 * @throws AS2Exception
 *         in case of an error
 * @throws IOException
 *         in case of an IO error
 */
protected void receiveSyncMDN(@Nonnull final AS2Message aMsg, @Nonnull final AS2HttpClient aHttpClient, @Nonnull final MIC aOriginalMIC, @Nullable final IHTTPIncomingDumper aIncomingDumper, @Nonnull final AS2ResourceHelper aResHelper) throws AS2Exception, IOException {
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("Receiving synchronous MDN for message" + aMsg.getLoggingText());
    try {
        // Create a MessageMDN and copy HTTP headers
        final IMessageMDN aMDN = new AS2MessageMDN(aMsg);
        // Bug in ph-commons 9.1.3 in addAllHeaders!
        aMDN.headers().addAllHeaders(aHttpClient.getResponseHeaderFields());
        // Receive the MDN data
        final InputStream aConnIS = aHttpClient.getInputStream();
        final NonBlockingByteArrayOutputStream aMDNStream = new NonBlockingByteArrayOutputStream();
        // Retrieve the whole MDN content
        StreamHelper.copyByteStream().from(aConnIS).closeFrom(true).to(aMDNStream).closeTo(true).limit(StringParser.parseLong(aMDN.getHeader(CHttpHeader.CONTENT_LENGTH), -1)).build();
        // Dump collected message
        if (aIncomingDumper != null)
            aIncomingDumper.dumpIncomingRequest(aMDN.headers().getAllHeaderLines(true), aMDNStream.getBufferOrCopy(), aMDN);
        if (LOGGER.isTraceEnabled()) {
            // Debug print the whole MDN stream
            LOGGER.trace("Retrieved MDN stream data:\n" + aMDNStream.getAsString(StandardCharsets.ISO_8859_1));
        }
        final MimeBodyPart aPart = new MimeBodyPart(AS2HttpHelper.getAsInternetHeaders(aMDN.headers()), aMDNStream.getBufferOrCopy());
        aMDN.setData(aPart);
        // get the MDN partnership info
        aMDN.partnership().setSenderAS2ID(aMDN.getHeader(CHttpHeader.AS2_FROM));
        aMDN.partnership().setReceiverAS2ID(aMDN.getHeader(CHttpHeader.AS2_TO));
        // Set the appropriate key store aliases
        aMDN.partnership().setSenderX509Alias(aMsg.partnership().getReceiverX509Alias());
        aMDN.partnership().setReceiverX509Alias(aMsg.partnership().getSenderX509Alias());
        // Update the partnership
        getSession().getPartnershipFactory().updatePartnership(aMDN, false);
        final ICertificateFactory aCertFactory = getSession().getCertificateFactory();
        final X509Certificate aSenderCert = aCertFactory.getCertificate(aMDN, ECertificatePartnershipType.SENDER);
        boolean bUseCertificateInBodyPart;
        final ETriState eUseCertificateInBodyPart = aMsg.partnership().getVerifyUseCertificateInBodyPart();
        if (eUseCertificateInBodyPart.isDefined()) {
            // Use per partnership
            bUseCertificateInBodyPart = eUseCertificateInBodyPart.getAsBooleanValue();
        } else {
            // Use global value
            bUseCertificateInBodyPart = getSession().isCryptoVerifyUseCertificateInBodyPart();
        }
        AS2Helper.parseMDN(aMsg, aSenderCert, bUseCertificateInBodyPart, m_aVerificationCertificateConsumer, aResHelper);
        try {
            getSession().getMessageProcessor().handle(IProcessorStorageModule.DO_STOREMDN, aMsg, null);
        } catch (final AS2ComponentNotFoundException | AS2NoModuleException ex) {
        // No message processor found
        // Or no module found in message processor
        }
        final String sDisposition = aMDN.attrs().getAsString(AS2MessageMDN.MDNA_DISPOSITION);
        if (LOGGER.isInfoEnabled())
            LOGGER.info("Received synchronous AS2 MDN [" + sDisposition + "]" + aMsg.getLoggingText());
        // Asynch MDN 2007-03-12
        // Verify if the original mic is equal to the mic in returned MDN
        final String sReturnMIC = aMDN.attrs().getAsString(AS2MessageMDN.MDNA_MIC);
        final MIC aReturnMIC = MIC.parse(sReturnMIC);
        // Catch ReturnMIC == null in case the attribute is simply missing
        final boolean bMICMatch = aOriginalMIC != null && aReturnMIC != null && aReturnMIC.equals(aOriginalMIC);
        if (bMICMatch) {
            // MIC was matched - all good
            m_aMICMatchingHandler.onMICMatch(aMsg, sReturnMIC);
        } else {
            // file was sent completely but the returned mic was not matched,
            m_aMICMatchingHandler.onMICMismatch(aMsg, aOriginalMIC == null ? null : aOriginalMIC.getAsAS2String(), sReturnMIC);
        }
        if (m_aIncomingMDNCallback != null)
            m_aIncomingMDNCallback.onIncomingMDN(true, aMDN, aMDN.getHeader(CHttpHeader.AS2_FROM), aMDN.getHeader(CHttpHeader.AS2_TO), sDisposition, aMDN.attrs().getAsString(AS2MessageMDN.MDNA_MIC), aMDN.attrs().getAsString(AS2MessageMDN.MDNA_ORIG_MESSAGEID), aMDN.attrs().getAsBoolean(AS2Message.ATTRIBUTE_RECEIVED_SIGNED, false), bMICMatch);
        DispositionType.createFromString(sDisposition).validate(aMsg, aMDN.getText());
    } catch (final IOException ex) {
        throw ex;
    } catch (final Exception ex) {
        throw WrappedAS2Exception.wrap(ex).setSourceMsg(aMsg);
    }
}
Also used : AS2MessageMDN(com.helger.as2lib.message.AS2MessageMDN) ETriState(com.helger.commons.state.ETriState) InputStream(java.io.InputStream) MIC(com.helger.as2lib.crypto.MIC) NonBlockingByteArrayOutputStream(com.helger.commons.io.stream.NonBlockingByteArrayOutputStream) ICertificateFactory(com.helger.as2lib.cert.ICertificateFactory) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) MessagingException(javax.mail.MessagingException) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) AS2DispositionException(com.helger.as2lib.disposition.AS2DispositionException) AS2Exception(com.helger.as2lib.exception.AS2Exception) WrappedAS2Exception(com.helger.as2lib.exception.WrappedAS2Exception) IOException(java.io.IOException) AS2InvalidParameterException(com.helger.as2lib.params.AS2InvalidParameterException) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) IMessageMDN(com.helger.as2lib.message.IMessageMDN) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Aggregations

AS2NoModuleException (com.helger.as2lib.processor.AS2NoModuleException)5 AS2ComponentNotFoundException (com.helger.as2lib.session.AS2ComponentNotFoundException)5 AS2Exception (com.helger.as2lib.exception.AS2Exception)4 WrappedAS2Exception (com.helger.as2lib.exception.WrappedAS2Exception)4 IMessageMDN (com.helger.as2lib.message.IMessageMDN)4 IOException (java.io.IOException)4 MessagingException (javax.mail.MessagingException)4 MimeBodyPart (javax.mail.internet.MimeBodyPart)4 AS2DispositionException (com.helger.as2lib.disposition.AS2DispositionException)3 SMIMEException (org.bouncycastle.mail.smime.SMIMEException)3 ICertificateFactory (com.helger.as2lib.cert.ICertificateFactory)2 MIC (com.helger.as2lib.crypto.MIC)2 AS2MessageMDN (com.helger.as2lib.message.AS2MessageMDN)2 AS2ProcessorException (com.helger.as2lib.processor.AS2ProcessorException)2 IAS2Session (com.helger.as2lib.session.IAS2Session)2 HttpHeaderMap (com.helger.commons.http.HttpHeaderMap)2 NonBlockingByteArrayOutputStream (com.helger.commons.io.stream.NonBlockingByteArrayOutputStream)2 ETriState (com.helger.commons.state.ETriState)2 InputStream (java.io.InputStream)2 X509Certificate (java.security.cert.X509Certificate)2