use of com.helger.as2lib.message.AS2MessageMDN in project as2-lib by phax.
the class AS2MDNReceiverHandler method reparse.
public void reparse(@Nonnull final AS2Message aMsg, @Nonnull final AS2HttpClient aHttpClient, @Nullable final IHTTPIncomingDumper aIncomingDumper) throws AS2Exception {
// 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
byte[] aMDNBytes = null;
try (final NonBlockingByteArrayOutputStream aMDNStream = new NonBlockingByteArrayOutputStream()) {
final InputStream aIS = aHttpClient.getInputStream();
final CopyByteStreamBuilder aBuilder = StreamHelper.copyByteStream().from(aIS).closeFrom(true).to(aMDNStream).closeTo(false);
// Retrieve the message content
final long nContentLength = StringParser.parseLong(aMDN.getHeader(CHttpHeader.CONTENT_LENGTH), -1);
if (nContentLength >= 0)
aBuilder.limit(nContentLength);
aBuilder.build();
aMDNBytes = aMDNStream.toByteArray();
} catch (final IOException ex) {
LOGGER.error("Error reparsing", ex);
}
if (aIncomingDumper != null)
aIncomingDumper.dumpIncomingRequest(aMDN.headers().getAllHeaderLines(true), aMDNBytes != null ? aMDNBytes : ArrayHelper.EMPTY_BYTE_ARRAY, aMDN);
MimeBodyPart aPart = null;
if (aMDNBytes != null)
try {
aPart = new MimeBodyPart(AS2HttpHelper.getAsInternetHeaders(aMDN.headers()), aMDNBytes);
} catch (final MessagingException ex) {
LOGGER.error("Error creating MimeBodyPart for received MDN", ex);
}
aMDN.setData(aPart);
// get the MDN partnership info
aMDN.partnership().setSenderAS2ID(aMDN.getHeader(CHttpHeader.AS2_FROM));
aMDN.partnership().setReceiverAS2ID(aMDN.getHeader(CHttpHeader.AS2_TO));
}
use of com.helger.as2lib.message.AS2MessageMDN 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);
}
}
use of com.helger.as2lib.message.AS2MessageMDN in project as2-lib by phax.
the class AS2Helper method createMDN.
/**
* Create a new MDN
*
* @param aSession
* AS2 session to be used. May not be <code>null</code>.
* @param aMsg
* The source AS2 message for which the MDN is to be created. May not
* be <code>null</code>.
* @param aDisposition
* The disposition - either success or error. May not be
* <code>null</code>.
* @param sText
* The text to be send. May not be <code>null</code>.
* @return The created MDN object which is already attached to the passed
* source AS2 message.
* @throws Exception
* In case of an error
*/
@Nonnull
public static IMessageMDN createMDN(@Nonnull final IAS2Session aSession, @Nonnull final AS2Message aMsg, @Nonnull final DispositionType aDisposition, @Nonnull final String sText) throws Exception {
ValueEnforcer.notNull(aSession, "AS2Session");
ValueEnforcer.notNull(aMsg, "AS2Message");
ValueEnforcer.notNull(aDisposition, "Disposition");
ValueEnforcer.notNull(sText, "Text");
final Partnership aPartnership = aMsg.partnership();
final AS2MessageMDN aMDN = new AS2MessageMDN(aMsg);
aMDN.headers().setHeader(CHttpHeader.AS2_VERSION, aSession.getAS2VersionID());
aMDN.headers().setHeader(CHttpHeader.DATE, AS2DateHelper.getFormattedDateNow(CAS2Header.DEFAULT_DATE_FORMAT));
aMDN.headers().setHeader(CHttpHeader.SERVER, CAS2Info.NAME_VERSION);
aMDN.headers().setHeader(CHttpHeader.MIME_VERSION, CAS2Header.DEFAULT_MIME_VERSION);
aMDN.headers().setHeader(CHttpHeader.AS2_FROM, aPartnership.getReceiverAS2ID());
aMDN.headers().setHeader(CHttpHeader.AS2_TO, aPartnership.getSenderAS2ID());
// 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(aPartnership.getReceiverX509Alias());
aMDN.partnership().setReceiverX509Alias(aPartnership.getSenderX509Alias());
// Update the partnership
try {
aSession.getPartnershipFactory().updatePartnership(aMDN, true);
} catch (final AS2PartnershipNotFoundException ex) {
// This would block sending an MDN in case a PartnershipNotFoundException
// was the reason for sending the MDN :)
}
aMDN.headers().setHeader(CHttpHeader.FROM, aPartnership.getReceiverEmail());
final String sSubject = aMDN.partnership().getMDNSubject();
if (sSubject != null) {
aMDN.headers().setHeader(CHttpHeader.SUBJECT, new MessageParameters(aMsg).format(sSubject));
} else {
aMDN.headers().setHeader(CHttpHeader.SUBJECT, "Your Requested MDN Response");
}
// Content-Transfer-Encoding for outgoing MDNs
final String sCTE = aPartnership.getContentTransferEncodingSend(EContentTransferEncoding.AS2_DEFAULT.getID());
aMDN.headers().addHeader(CHttpHeader.CONTENT_TRANSFER_ENCODING, sCTE);
aMDN.setText(new MessageParameters(aMsg).format(sText));
aMDN.attrs().putIn(AS2MessageMDN.MDNA_REPORTING_UA, CAS2Info.NAME_VERSION + "@" + aMsg.attrs().getAsString(CNetAttribute.MA_DESTINATION_IP) + ":" + aMsg.attrs().getAsString(CNetAttribute.MA_DESTINATION_PORT));
aMDN.attrs().putIn(AS2MessageMDN.MDNA_ORIG_RECIPIENT, "rfc822; " + aMsg.getHeader(CHttpHeader.AS2_TO));
aMDN.attrs().putIn(AS2MessageMDN.MDNA_FINAL_RECIPIENT, "rfc822; " + aPartnership.getReceiverAS2ID());
aMDN.attrs().putIn(AS2MessageMDN.MDNA_ORIG_MESSAGEID, aMsg.getHeader(CHttpHeader.MESSAGE_ID));
aMDN.attrs().putIn(AS2MessageMDN.MDNA_DISPOSITION, aDisposition.getAsString());
final String sDispositionOptions = aMsg.getHeader(CHttpHeader.DISPOSITION_NOTIFICATION_OPTIONS);
final DispositionOptions aDispositionOptions = DispositionOptions.createFromString(sDispositionOptions);
ECryptoAlgorithmSign eSigningAlgorithm = aDispositionOptions.getFirstMICAlg();
if (eSigningAlgorithm == null) {
// Try from partnership (#93)
final String sSigningAlgorithm = aPartnership.getSigningAlgorithm();
eSigningAlgorithm = ECryptoAlgorithmSign.getFromIDOrNull(sSigningAlgorithm);
if (eSigningAlgorithm == null) {
if (LOGGER.isWarnEnabled())
LOGGER.warn("The partnership signing algorithm name '" + sSigningAlgorithm + "' is unknown.");
}
}
MIC aMIC = null;
if (eSigningAlgorithm != null) {
// If the source message was signed or encrypted, include the headers -
// see message sending for details
final boolean bIncludeHeadersInMIC = aPartnership.getSigningAlgorithm() != null || aPartnership.getEncryptAlgorithm() != null || aPartnership.getCompressionType() != null;
aMIC = getCryptoHelper().calculateMIC(aMsg.getData(), eSigningAlgorithm, bIncludeHeadersInMIC);
}
if (aMIC != null)
aMDN.attrs().putIn(AS2MessageMDN.MDNA_MIC, aMIC.getAsAS2String());
boolean bSignMDN = false;
boolean bIncludeCertificateInSignedContent = false;
if (aDispositionOptions.getProtocol() != null) {
if (aDispositionOptions.isProtocolRequired() || aDispositionOptions.hasMICAlg()) {
// Sign if required or if optional and a MIC algorithm is present
bSignMDN = true;
// Include certificate in signed content?
final ETriState eIncludeCertificateInSignedContent = aPartnership.getIncludeCertificateInSignedContent();
if (eIncludeCertificateInSignedContent.isDefined()) {
// Use per partnership
bIncludeCertificateInSignedContent = eIncludeCertificateInSignedContent.getAsBooleanValue();
} else {
// Use global value
bIncludeCertificateInSignedContent = aSession.isCryptoSignIncludeCertificateInBodyPart();
}
}
}
final boolean bUseOldRFC3851MicAlgs = aPartnership.isRFC3851MICAlgs();
final boolean bRemoveCmsAlgorithmProtect = aPartnership.isRemoveCmsAlgorithmProtect();
createMDNData(aSession, aMDN, bSignMDN, bIncludeCertificateInSignedContent, aDispositionOptions.getFirstMICAlg(), bUseOldRFC3851MicAlgs, bRemoveCmsAlgorithmProtect);
aMDN.updateMessageID();
// store MDN into msg in case AsynchMDN is sent fails, needs to be resent by
// send module
aMsg.setMDN(aMDN);
return aMDN;
}
use of com.helger.as2lib.message.AS2MessageMDN in project as2-lib by phax.
the class ReadMDNFuncTest method testReadMDNIssue97.
@Test
@Ignore("Part does not contain MimeMultipart")
public void testReadMDNIssue97() throws Exception {
final String sPrefix = "mdn/issue97";
final IReadableResource aHeaderRes = new ClassPathResource(sPrefix + ".header");
assertTrue(aHeaderRes.exists());
final IReadableResource aPayloadRes = new ClassPathResource(sPrefix + ".payload");
assertTrue(aPayloadRes.exists());
if (false) {
final IReadableResource aCertRes = new ClassPathResource(sPrefix + ".pem");
assertTrue(aCertRes.exists());
}
final HttpHeaderMap aHeaders = new HttpHeaderMap();
try (NonBlockingBufferedReader aBR = new NonBlockingBufferedReader(aHeaderRes.getReader(StandardCharsets.ISO_8859_1))) {
String s;
while ((s = aBR.readLine()) != null) {
final int i = s.indexOf(':');
final String sName = s.substring(0, i).trim();
final String sValue = s.substring(i + 1).trim();
aHeaders.addHeader(sName, sValue);
}
}
if (false)
assertEquals("<MOKOsi42435716cf621589dnode1POP000046@sfgt1.unix.fina.hr>", aHeaders.getFirstHeaderValue("Message-ID"));
// final X509Certificate aCert =
// CertificateHelper.convertStringToCertficateOrNull
// (StreamHelper.getAllBytesAsString (aCertRes,
// StandardCharsets.ISO_8859_1));
// assertNotNull (aCert);
final AS2Message aMsg = new AS2Message();
// Create a MessageMDN and copy HTTP headers
final IMessageMDN aMDN = new AS2MessageMDN(aMsg);
aMDN.headers().addAllHeaders(aHeaders);
final MimeBodyPart aPart = new MimeBodyPart(AS2HttpHelper.getAsInternetHeaders(aMDN.headers()), StreamHelper.getAllBytes(aPayloadRes));
assertNotNull(aPart);
aMsg.getMDN().setData(aPart);
final ICryptoHelper aCryptoHelper = AS2Helper.getCryptoHelper();
assertTrue(aCryptoHelper.isSigned(aPart));
assertFalse(aCryptoHelper.isEncrypted(aPart));
assertFalse(aCryptoHelper.isCompressed(aPart.getContentType()));
try (final AS2ResourceHelper aResHelper = new AS2ResourceHelper()) {
final Consumer<X509Certificate> aCertHolder = null;
AS2Helper.parseMDN(aMsg, null, true, aCertHolder, aResHelper);
}
}
use of com.helger.as2lib.message.AS2MessageMDN 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);
}
}
Aggregations