Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion Server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<!-- DO NOT CHANGE THIS "groupId" WITHOUT CHANGING XMLSession.getManifestAttributes.MANIFEST_VENDOR_ID_ATTRIB -->
<groupId>net.sf.openas2</groupId>
<artifactId>OpenAS2</artifactId>
<version>4.6.3</version>
<version>4.7.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
44 changes: 35 additions & 9 deletions Server/src/main/java/org/openas2/util/AS2Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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);

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -525,20 +545,25 @@ 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);
}

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) {
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions changes.txt
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>net.sf.openas2</groupId>
<artifactId>OpenAS2</artifactId>
<version>4.6.3</version>
<version>4.7.0</version>
<name>OpenAS2</name>
<packaging>pom</packaging>

Expand Down Expand Up @@ -76,7 +76,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.18.0</version>
<version>3.19.0</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
Expand All @@ -91,7 +91,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.3.232</version>
<version>2.4.240</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
<dependency>
Expand Down Expand Up @@ -146,7 +146,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.18</version>
<version>1.5.19</version>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
Expand Down