diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index d6eccfda..637e51ad 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,19 +1,19 @@ # OpenAS2 Server -# Version 4.6.3 +# Version 4.7.0 # RELEASE NOTES ----- -The OpenAS2 project is pleased to announce the release of OpenAS2 4.6.3 +The OpenAS2 project is pleased to announce the release of OpenAS2 4.7.0 -The release download file is: OpenAS2Server-4.6.3.zip +The release download file is: OpenAS2Server-4.7.0.zip The zip file contains a PDF document (OpenAS2HowTo.pdf) providing information on installing and using the application. ## NOTE: Testing covers Java 11 to 21. ## Java 8 is NO LONGER SUPPORTED. -Version 4.6.3 - 2025-09-29 +Version 4.7.0 - 2025-10-28 -This is a bugfix release. -1. Avoid concurrent processing error that occurs after files after sent as part of the cleanup process. +This is a minor enhancement release. +1. Enhance MDN processing to extract possible responses from partner that provide information on why the partner rejected the AS2 transaction. ##Upgrade Notes diff --git a/Server/pom.xml b/Server/pom.xml index 264b39c9..4865d992 100644 --- a/Server/pom.xml +++ b/Server/pom.xml @@ -7,7 +7,7 @@ net.sf.openas2 OpenAS2 - 4.6.3 + 4.7.0 ../pom.xml diff --git a/Server/src/main/java/org/openas2/processor/receiver/AS2MDNReceiverHandler.java b/Server/src/main/java/org/openas2/processor/receiver/AS2MDNReceiverHandler.java index b4db286d..da00ca57 100644 --- a/Server/src/main/java/org/openas2/processor/receiver/AS2MDNReceiverHandler.java +++ b/Server/src/main/java/org/openas2/processor/receiver/AS2MDNReceiverHandler.java @@ -109,10 +109,10 @@ public void handle(NetModule owner, Socket s) { logger.trace("Incoming ASYNC MDN message - MDN struct: " + mdn.toString()); } try { - boolean partnerIdentificationProblem = AS2Util.processMDN(msg, data, s.getOutputStream(), true, getModule().getSession(), this.getClass()); + boolean mdnResponseIssue = AS2Util.processMDN(msg, data, s.getOutputStream(), true, getModule().getSession(), this.getClass()); // Assume that appropriate logging and state handling was done upstream if an error occurred so only log state change for success - if (!partnerIdentificationProblem) { - // Logger state + if (!mdnResponseIssue) { + // Log state msg.setOption("STATE", Message.MSG_STATE_MSG_SENT_MDN_RECEIVED_OK); msg.trackMsgState(getModule().getSession()); } diff --git a/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java b/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java index b7e0d6d1..6dd84f3d 100644 --- a/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java +++ b/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java @@ -234,12 +234,11 @@ private void processResponse(Message msg, ResponseWrapper response) { } msg.setStatus(Message.MSG_STATUS_MDN_PROCESS_INIT); try { - @SuppressWarnings("unused") - boolean partnerIdentificationProblem = AS2Util.processMDN((AS2Message) msg, response.getBody(), null, false, getSession(), this.getClass()); - // Possibly a place for adding suspicious activity tracking here? - // if (partnerIdentificationProblem) { - // trackSuspiciousActivity(msg); - // } + // Assume that appropriate logging and state handling was done upstream if an error occurred so only log state change for success + boolean mdnResponseIssue = AS2Util.processMDN((AS2Message) msg, response.getBody(), null, false, getSession(), this.getClass()); + if (mdnResponseIssue) { + logger.warn("There was an issue identified processing the response fropm the p[artner. Review upstream log messages for details on the probklem."); + } } catch (Exception e) { /* Processing of the MDN would have done extensive error handling so only log an error if the error * is an not OpenAS2 custom error. diff --git a/Server/src/main/java/org/openas2/util/AS2Util.java b/Server/src/main/java/org/openas2/util/AS2Util.java index 35079d60..8716640a 100644 --- a/Server/src/main/java/org/openas2/util/AS2Util.java +++ b/Server/src/main/java/org/openas2/util/AS2Util.java @@ -85,7 +85,13 @@ public static String generateMessageID(Message msg, boolean isMDN) throws Invali return id; } - public static void parseMDN(Message msg, X509Certificate receiver) throws OpenAS2Exception { + /** + * @param msg- the AS2 message that is being processed + * @param receiver - the receivers X509 certificate + * @return - a boolean indicating if the extracted response indicated an issue processing the AS2 message that was sent. Message state is NOT updated in this method. + * @throws OpenAS2Exception - thrown if there are issues trying to extract the response from the partner + */ + public static boolean parseMDN(Message msg, X509Certificate receiver) throws OpenAS2Exception { Logger logger = LoggerFactory.getLogger(AS2Util.class); MessageMDN mdn = msg.getMDN(); MimeBodyPart mainPart = mdn.getData(); @@ -106,13 +112,12 @@ public static void parseMDN(Message msg, X509Certificate receiver) throws OpenAS } catch (Exception e1) { logger.error("Error parsing MDN: " + org.openas2.util.Logging.getExceptionMsg(e1), e1); throw new OpenAS2Exception("Failed to verify signature of received MDN."); - } try { MimeMultipart reportParts = new MimeMultipart(mainPart.getDataHandler().getDataSource()); - if (reportParts != null) { + if (reportParts != null && reportParts.getCount() > 0) { ContentType reportType = new ContentType(reportParts.getContentType()); Charset charset = getCharset(reportType, msg, logger); @@ -141,11 +146,27 @@ public static void parseMDN(Message msg, X509Certificate receiver) throws OpenAS } else { // No multipart/report so now what? logger.warn("MDN received from partner but did not contain a multipart/report section. " + msg.getLogMsgID()); + int reportCount = reportParts.getCount(); + MimeBodyPart reportPart; + for (int j = 0; j < reportCount; j++) { + reportPart = (MimeBodyPart) reportParts.getBodyPart(j); + logger.warn("Received MimeBodyPart from Multipart for inbound MDN: " + msg.getLogMsgID() + "\n" + MimeUtil.toString(reportPart, true)); + } + return false; } + } else { + logger.error("The received MimeBodyPart for inbound MDN did not contain a standard MDN response. This is probably because an error occurred on the remote side processing the message. Review the response below for possible reasons: " + msg.getLogMsgID() + "\n" + MimeUtil.toString(mainPart, true)); + return false; } } catch (Exception e) { + try { + logger.error("Failed to extract report from received MimeBodyPart for inbound MDN: " + msg.getLogMsgID() + "\n" + MimeUtil.toString(mainPart, true)); + } catch (Exception e1) { + // Do nothing + } throw new OpenAS2Exception("Failed to parse MDN: " + org.openas2.util.Logging.getExceptionMsg(e), e); } + return true; } private static String getMimeBodyPartText(MimeBodyPart part, Charset charset) throws MessagingException, IOException { @@ -180,7 +201,7 @@ private static Charset getCharset(ContentType contentType, Message msg, Logger l * @param msg - the original message sent to the partner that the MDN * relates to * @return true if mdn processed - * @throws DispositionException - something wrong t=with the Disposition + * @throws DispositionException - something wrong with the Disposition * structure * @throws OpenAS2Exception - an internally handled error has occurred */ @@ -473,12 +494,11 @@ public static boolean resend(Session session, Class sourceClass, String how, * @param session - Session object * @param sourceClass - who invoked this method - * @return partnerIdentificationProblem - boolean indicating that the partnership for this MDN not identified + * @return mdnResponseIssue - boolean indicating that the MDN processing identified an issue. * @throws OpenAS2Exception - an internally handled error has occurred * @throws IOException - the IO system has a problem * - * TODO:: Possibly do away with returning a boolean as it does not add value ATM */ public static boolean processMDN(AS2Message msg, byte[] data, OutputStream out, boolean isAsyncMDN, Session session, Class sourceClass) throws OpenAS2Exception, IOException { Logger logger = LoggerFactory.getLogger(AS2Util.class); @@ -525,7 +545,12 @@ public static boolean processMDN(AS2Message msg, byte[] data, OutputStream out, if (logger.isTraceEnabled()) { logger.trace("Parsing MDN: " + mdn.toString() + msg.getLogMsgID()); } - AS2Util.parseMDN(msg, senderCert); + if (!AS2Util.parseMDN(msg, senderCert)) { + msg.setStatus(Message.MSG_STATUS_MSG_TERMINATED_IN_ERROR); + msg.setOption("STATE", Message.MSG_STATE_MSG_SENT_MDN_RECEIVED_ERROR); + msg.trackMsgState(session); + return false; + } if (isAsyncMDN) { getMetaData(msg, session); @@ -533,12 +558,12 @@ public static boolean processMDN(AS2Message msg, byte[] data, OutputStream out, msg.setStatus(Message.MSG_STATUS_MDN_VERIFY); if (logger.isTraceEnabled()) { - logger.trace("MDN parsed. \n Payload file name: " + msg.getPayloadFilename() + "\n Checking MDN report..." + msg.getLogMsgID()); + logger.trace("MDN parsed. Payload file name: " + msg.getPayloadFilename() + "\n Checking MDN report..." + msg.getLogMsgID()); } try { AS2Util.checkMDN(msg); /* - * If the MDN was successfully received send correct HTTP response irrespective + * If the MDN was successfully received, send correct HTTP response irrespective * of possible error conditions due to disposition errors or MIC mismatch */ if (isAsyncMDN) { @@ -652,6 +677,7 @@ public static void getMetaData(AS2Message msg, Session session) throws OpenAS2Ex getMetaData(msg, iFile); } + @SuppressWarnings("unchecked") public static void getMetaData(AS2Message msg, File inFile) throws OpenAS2Exception { Logger logger = LoggerFactory.getLogger(AS2Util.class); ObjectInputStream pifois; diff --git a/changes.txt b/changes.txt index 18b252f5..23862e22 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,11 @@ **IMPORTANT NOTE**: Please review upgrade notes in the RELEASE-NOTES.md if you are upgrading +Version 4.7.0 - 2025-10-28 + +This is a minor enhancement release. +1. Enhance MDN processing to extract possible responses from partner that provide information on why the partner rejected the AS2 transaction. + + Version 4.6.3 - 2025-09-29 This is a bugfix release. diff --git a/pom.xml b/pom.xml index 4d2909b8..983f7fb9 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 net.sf.openas2 OpenAS2 - 4.6.3 + 4.7.0 OpenAS2 pom @@ -76,7 +76,7 @@ org.apache.commons commons-lang3 - 3.18.0 + 3.19.0 commons-cli @@ -91,7 +91,7 @@ com.h2database h2 - 2.3.232 + 2.4.240 @@ -146,7 +146,7 @@ ch.qos.logback logback-classic - 1.5.18 + 1.5.19 jakarta.ws.rs