diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 324b1a0f..0d5c59fe 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -1,22 +1,23 @@
# OpenAS2 Server
-# Version 3.4.0
+# Version 3.4.1
# RELEASE NOTES
-----
-The OpenAS2 project is pleased to announce the release of OpenAS2 3.4.0
+The OpenAS2 project is pleased to announce the release of OpenAS2 3.4.1
-The release download file is: OpenAS2Server-3.4.0.zip
+The release download file is: OpenAS2Server-3.4.1.zip
The zip file contains a PDF document (OpenAS2HowTo.pdf) providing information on installing and using the application.
## NOTE: Testing covers Java 8 to 17. The application should work for older versions down to Java 7 but they are not tested as part of the CI/CD pipeline.
-Version 3.4.0 - 2022-10-04
+Version 3.4.1 - 2022-12-04
This is an enhancement and minor bugfix release:
**IMPORTANT NOTE**: Please review upgrade notes below if you are upgrading
- 1. Support for splitting line based files into multiple file. This is useful for very large files where encryption consumes too much memory.
- 2. Support other databases than H2 for the WebUI commands.
- 3. Catch exceptions in the strm command processor to avoid crashing the command processor.
- 4. Pre-enhance AS2 properties before adding system properties to cater for $ in system properties
+ 1. Fix message attributes not being available to partnership config (eg attributes.filename)
+ 2. Add defensie coding for highly questionnable file names sent by partner containing an asterisk such as ".*"
+ 3. Further enhancements to the confog.xml extracting key values to properties to facilitate auto upgrades.
+ 4. Enhance helper scripts to support non-prompting execution allowing invocation from other scripts.
+ 5. Disable the WebUI module by default as it only runs with Java 11 and above.
##Upgrade Notes
diff --git a/Remote/pom.xml b/Remote/pom.xml
index c567809b..610a4cf7 100644
--- a/Remote/pom.xml
+++ b/Remote/pom.xml
@@ -4,7 +4,7 @@
net.sf.openas2
OpenAS2
- 3.4.0
+ 3.4.1
4.0.0
diff --git a/Server/pom.xml b/Server/pom.xml
index a7a18909..a9086169 100644
--- a/Server/pom.xml
+++ b/Server/pom.xml
@@ -7,7 +7,7 @@
net.sf.openas2
OpenAS2
- 3.4.0
+ 3.4.1
../pom.xml
diff --git a/Server/src/bin/find_java b/Server/src/bin/find_java
index f947991d..67679cae 100755
--- a/Server/src/bin/find_java
+++ b/Server/src/bin/find_java
@@ -1,6 +1,4 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-#!/bin/sh
+#!/bin/bash
# OS specific support. $var _must_ be set to either true or false.
darwin=false;
case "`uname`" in
@@ -46,7 +44,7 @@ if [ -z "$JAVA_HOME" ] ; then
fi
if [ -z "$JAVA_HOME" ]; then
- javaExecutable="`which javac`"
+ javaExecutable="`which java`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
diff --git a/Server/src/bin/gen_p12_key_par.sh b/Server/src/bin/gen_p12_key_par.sh
index ab4580c9..bbfa62ff 100755
--- a/Server/src/bin/gen_p12_key_par.sh
+++ b/Server/src/bin/gen_p12_key_par.sh
@@ -1,6 +1,7 @@
-#!/bin/sh
+#!/bin/bash
x=`basename $0`
+
if test $# -ne 4; then
echo "Generate a certificate to a PKCS12 key store."
echo "You must supply a target key store without the extension (extension will be added as .p12) and an alias for generated certificate."
@@ -44,17 +45,8 @@ if [ -n "$CERT_START_DATE" ]; then
fi
if [ -z $JAVA_HOME ]; then
- OS=$(uname -s) echo "Looking for JAVA_HOME on OS: ${OS}..."
- if [[ "${OS}" == *Darwin* ]]; then
- # Mac OS X platform
- JAVA_HOME=$(/usr/libexec/java_home)
- elif [[ "${OS}" == *Linux* ]]; then
- # Linux platform
- JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
- elif [[ "${OS}" == *MINGW* ]]; then
- # Windows NT platform
- echo "Windows not supported by this script"
- fi
+ baseDir=`dirname $0`
+ . ${baseDir}/find_java
fi
if [ -z $JAVA_HOME ]; then
echo "ERROR: Cannot find JAVA_HOME"
diff --git a/Server/src/bin/import_alias_from_keystore.sh b/Server/src/bin/import_alias_from_keystore.sh
index 855be1e1..1b77b072 100755
--- a/Server/src/bin/import_alias_from_keystore.sh
+++ b/Server/src/bin/import_alias_from_keystore.sh
@@ -29,18 +29,8 @@ tgtAlias=$4
action=$5
if [ -z $JAVA_HOME ]; then
- OS=$(uname -s)
-
- if [[ "${OS}" == *Darwin* ]]; then
- # Mac OS X platform
- JAVA_HOME=$(/usr/libexec/java_home)
- elif [[ "${OS}" == *Linux* ]]; then
- # Linux platform
- JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
- elif [[ "${OS}" == *MINGW* ]]; then
- # Windows NT platform
- echo "Windows not supported by this script"
- fi
+ baseDir=`dirname $0`
+ . ${baseDir}/find_java
fi
if [ -z $JAVA_HOME ]; then
diff --git a/Server/src/bin/import_public_cert.sh b/Server/src/bin/import_public_cert.sh
index 2601fdb1..e7a7f05e 100755
--- a/Server/src/bin/import_public_cert.sh
+++ b/Server/src/bin/import_public_cert.sh
@@ -27,18 +27,8 @@ certAlias=$3
action=$4
if [ -z $JAVA_HOME ]; then
- OS=$(uname -s)
-
- if [[ "${OS}" == *Darwin* ]]; then
- # Mac OS X platform
- JAVA_HOME=$(/usr/libexec/java_home)
- elif [[ "${OS}" == *Linux* ]]; then
- # Linux platform
- JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
- elif [[ "${OS}" == *MINGW* ]]; then
- # Windows NT platform
- echo "Windows not supported by this script"
- fi
+ baseDir=`dirname $0`
+ . ${baseDir}/find_java
fi
if [ -z $JAVA_HOME ]; then
diff --git a/Server/src/config/config.xml b/Server/src/config/config.xml
index 033112b4..c95a24c1 100644
--- a/Server/src/config/config.xml
+++ b/Server/src/config/config.xml
@@ -11,13 +11,18 @@
email.logger.enabled="false"
console.command.processor.enabled="true"
socket.command.processor.enabled="false"
- restapi.command.processor.enabled="true"
+ restapi.command.processor.enabled="false"
module.AS2SenderModule.enabled="true"
+ module.AS2SenderModule.readtimeout="60000"
module.MDNSenderModule.enabled="true"
module.DbTrackingModule.enabled="true"
module.MDNFileModule.enabled="true"
+ module.MDNFileModule.filename="$properties.storageBaseDir$/$mdn.msg.sender.as2_id$-$mdn.msg.receiver.as2_id$/mdn/$date.yyyy-MM-dd$/$mdn.msg.headers.message-id$"
module.MessageFileModule.enabled="true"
+ module.MessageFileModule.filename="$properties.storageBaseDir$/$msg.sender.as2_id$-$msg.receiver.as2_id$/inbox/$msg.headers.message-id$"
+ module.MessageFileModule.header="$properties.storageBaseDir$/$msg.sender.as2_id$-$msg.receiver.as2_id$/msgheaders/$date.yyyy-MM-dd$/$msg.headers.message-id$"
module.DirectoryResenderModule.enabled="true"
+ module.DirectoryResenderModule.resenddelay="60"
module.AS2ReceiverModule.http.enabled="true"
module.AS2ReceiverModule.http.port="10080"
module.AS2MDNReceiverModule.http.enabled="true"
@@ -27,6 +32,7 @@
module.AS2MDNReceiverModule.https.enabled="false"
module.AS2MDNReceiverModule.https.port="10444"
module.HealthCheckModule.enabled="false"
+ module.HealthCheckModule.port="10099"
async_mdn_receiver_port="$properties.module.AS2MDNReceiverModule.http.port$"
as2_async_mdn_url="http://localhost:$properties.async_mdn_receiver_port$"
as2_keystore="%home%/as2_certs.p12"
@@ -114,7 +120,8 @@
pendingMDNinfo="$properties.storageBaseDir$/pendinginfoMDN3"
resend_max_retries="5">
+ classname="org.openas2.processor.sender.AS2SenderModule"
+ readtimeout="$properties.module.AS2SenderModule.readtimeout$" />
-->
+
@@ -71,6 +72,7 @@
+
@@ -99,6 +101,7 @@
+
diff --git a/Server/src/main/java/org/openas2/message/BaseMessage.java b/Server/src/main/java/org/openas2/message/BaseMessage.java
index 5ddb71ff..a6d703a1 100644
--- a/Server/src/main/java/org/openas2/message/BaseMessage.java
+++ b/Server/src/main/java/org/openas2/message/BaseMessage.java
@@ -496,12 +496,15 @@ public String extractPayloadFilename() throws ParseException {
if (tmpFilename == null || tmpFilename.length() < 1) {
return null;
}
+ if (tmpFilename.indexOf("*") >= 0) {
+ LogFactory.getLog(BaseMessage.class.getSimpleName()).warn("The 'filename' in disposition contains an asterisk. Setting to null.");
+ return null;
+ }
try {
tmpFilename = IOUtil.getSafeFilename(tmpFilename);
} catch (OpenAS2Exception oae) {
- ParseException pe = new ParseException("Unable to extract a usable filename");
- pe.initCause(oae);
- throw pe;
+ LogFactory.getLog(BaseMessage.class.getSimpleName()).warn("Unable to extract a usable filename from: " + tmpFilename);
+ return null;
}
return tmpFilename;
}
diff --git a/Server/src/main/java/org/openas2/processor/receiver/AS2ReceiverHandler.java b/Server/src/main/java/org/openas2/processor/receiver/AS2ReceiverHandler.java
index 0ae74c6d..c317cb33 100644
--- a/Server/src/main/java/org/openas2/processor/receiver/AS2ReceiverHandler.java
+++ b/Server/src/main/java/org/openas2/processor/receiver/AS2ReceiverHandler.java
@@ -137,42 +137,44 @@ public void handle(NetModule owner, Socket s) {
if (LOG.isTraceEnabled()) {
LOG.trace("Received msg built from HTTP input stream: " + msg.toString() + msg.getLogMsgID());
}
- // TODO store HTTP request, headers, and data to file in Received folder -> use
- // message-id for filename?
+ // TODO store HTTP request, headers, and data to file in Received folder -> use message-id for filename?
try {
// Put received data in a MIME body part
ContentType receivedContentType = null;
try {
- /*
- * receivedPart = new MimeBodyPart(msg.getHeaders(), data);
- * msg.setData(receivedPart); receivedContentType = new
- * ContentType(receivedPart.getContentType());
- */
- receivedContentType = new ContentType(msg.getHeader(MimeUtil.MIME_CONTENT_TYPE_KEY));
-
- MimeBodyPart receivedPart = new MimeBodyPart();
- receivedPart.setDataHandler(new DataHandler(new ByteArrayDataSource(data, receivedContentType.toString(), null)));
- if (LOG.isTraceEnabled() && "true".equalsIgnoreCase(System.getProperty("logRxdMsgMimeBodyParts", "false"))) {
- LOG.trace("Received MimeBodyPart for inbound message: " + msg.getLogMsgID() + "\n" + MimeUtil.toString(receivedPart, true));
- }
- // Set "Content-Type" and "Content-Transfer-Encoding" to what is received in the
- // HTTP header
- // since it may not be set in the received mime body part
- receivedPart.setHeader(MimeUtil.MIME_CONTENT_TYPE_KEY, receivedContentType.toString());
-
- // Set the transfer encoding if necessary
- String cte = receivedPart.getEncoding();
- if (cte == null) {
- // Not in the MimeBodyPart so try the HTTP headers...
- cte = msg.getHeader("Content-Transfer-Encoding");
- // Nada ... set to system default
+ MimeBodyPart receivedPart = null;
+ if ("true".equals(msg.getPartnership().getAttributeOrProperty("use_old_mime_deserialise_method", "false"))) {
+ // TODO: Delete this when the new method is confirmed working reliably. Changed for 3.4.1
+ receivedContentType = new ContentType(msg.getHeader(MimeUtil.MIME_CONTENT_TYPE_KEY));
+
+ receivedPart = new MimeBodyPart();
+ receivedPart.setDataHandler(new DataHandler(new ByteArrayDataSource(data, receivedContentType.toString(), null)));
+ // Set "Content-Type" and "Content-Transfer-Encoding" to what is received in the
+ // HTTP header since it may not be set in the received mime body part
+ receivedPart.setHeader(MimeUtil.MIME_CONTENT_TYPE_KEY, receivedContentType.toString());
+
+ // Set the transfer encoding if necessary
+ String cte = receivedPart.getEncoding();
if (cte == null) {
- cte = Session.DEFAULT_CONTENT_TRANSFER_ENCODING;
+ // Not in the MimeBodyPart so try the HTTP headers...
+ cte = msg.getHeader("Content-Transfer-Encoding");
+ // Nada ... set to system default
+ if (cte == null) {
+ cte = Session.DEFAULT_CONTENT_TRANSFER_ENCODING;
+ }
+ receivedPart.setHeader("Content-Transfer-Encoding", cte);
+ } else if (LOG.isTraceEnabled()) {
+ LOG.trace("Received msg MimePart has transfer encoding: " + cte + msg.getLogMsgID());
}
- receivedPart.setHeader("Content-Transfer-Encoding", cte);
- } else if (LOG.isTraceEnabled()) {
- LOG.trace("Received msg MimePart has transfer encoding: " + cte + msg.getLogMsgID());
+ } else {
+ // We only need the Content-Type to rebuild the mime body part.
+ InternetHeaders ih = new InternetHeaders();
+ ih.setHeader(MimeUtil.MIME_CONTENT_TYPE_KEY, msg.getHeader(MimeUtil.MIME_CONTENT_TYPE_KEY));
+ receivedPart = new MimeBodyPart(ih, data);
+ }
+ if (LOG.isTraceEnabled() && "true".equalsIgnoreCase(System.getProperty("logRxdMsgMimeBodyParts", "false"))) {
+ LOG.trace("Received MimeBodyPart for inbound message: " + msg.getLogMsgID() + "\n" + MimeUtil.toString(receivedPart, true));
}
msg.setData(receivedPart);
} catch (Exception e) {
diff --git a/Server/src/main/java/org/openas2/processor/receiver/MessageBuilderModule.java b/Server/src/main/java/org/openas2/processor/receiver/MessageBuilderModule.java
index 83a7d305..21bbc73f 100644
--- a/Server/src/main/java/org/openas2/processor/receiver/MessageBuilderModule.java
+++ b/Server/src/main/java/org/openas2/processor/receiver/MessageBuilderModule.java
@@ -152,6 +152,8 @@ protected Message processDocument(File fileToSend, String filename) throws OpenA
}
fos.flush();
fos.close();
+ // Update the message's partnership with any additional attributes since initial call in case dynamic variables were not set initially
+ getSession().getPartnershipFactory().updatePartnership(msg, true);
processDocument(pendingFile, msg);
} catch (IOException e) {
throw new OpenAS2Exception("Failed to write output file for file splitting on file " + fileCount, e);
@@ -187,6 +189,8 @@ protected Message processDocument(File fileToSend, String filename) throws OpenA
logger.error(": " + e.getMessage(), e);
throw new OpenAS2Exception("Failed to move the inbound file " + fileToSend.getPath() + " to the processing location " + pendingFile.getName());
}
+ // Update the message's partnership with any additional attributes since initial call in case dynamic variables were not set initially
+ getSession().getPartnershipFactory().updatePartnership(msg, true);
return processDocument(pendingFile, msg);
}
}
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 cd2cf879..6610c594 100644
--- a/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java
+++ b/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java
@@ -36,6 +36,8 @@
import javax.mail.internet.InternetHeaders;
import javax.mail.internet.MimeBodyPart;
import javax.net.ssl.SSLHandshakeException;
+
+import java.io.EOFException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -642,12 +644,17 @@ protected void detectFailedSentMessages() {
File inFile = new File(pendingDir + File.separator + files[i]);
try {
AS2Message msg = new AS2Message();
- AS2Util.getMetaData(msg, inFile);
- AS2Util.cleanupFiles(msg, true);
String msgStr = "Pending information file detected that is past max wait time, Failure most likely due to not receiving MDN response in Async mode: " + inFile.getAbsolutePath();
+ try {
+ AS2Util.getMetaData(msg, inFile);
+ } catch (EOFException e) {
+ // the file is either corrupt or somehow invalid as we are trying to read stuff that just ain't there so change the default message
+ msgStr = "Detected a stale pending info file that is not in a valid format: " + inFile.getAbsolutePath();
+ }
msg.setLogMsg(msgStr);
msg.setStatus(Message.MSG_STATUS_MSG_TERMINATED_IN_ERROR);
logger.error(msg, null);
+ AS2Util.cleanupFiles(msg, true);
// Log significant msg state
msg.setOption("STATE", Message.MSG_STATE_MDN_ASYNC_RECEIVE_FAIL);
msg.trackMsgState(getSession());
diff --git a/Server/src/main/java/org/openas2/util/AS2Util.java b/Server/src/main/java/org/openas2/util/AS2Util.java
index d6d1705c..f081d11a 100644
--- a/Server/src/main/java/org/openas2/util/AS2Util.java
+++ b/Server/src/main/java/org/openas2/util/AS2Util.java
@@ -192,7 +192,7 @@ public static boolean checkMDN(AS2Message msg) throws DispositionException, Open
new DispositionType(disposition).validate();
} catch (DispositionException de) {
if (logger.isWarnEnabled()) {
- logger.warn("Disposition exception on MDN. Disposition: " + disposition + msg.getLogMsgID(), de);
+ logger.warn("Disposition error detected in MDN. Received disposition: " + disposition + msg.getLogMsgID(), de);
}
// Something wrong detected so flag it for later use
dispositionHasWarning = true;
@@ -223,7 +223,7 @@ public static boolean checkMDN(AS2Message msg) throws DispositionException, Open
String returnMIC = msg.getMDN().getAttribute(AS2MessageMDN.MDNA_MIC);
if (returnMIC == null || returnMIC.length() < 1) {
if (dispositionHasWarning) {
- // TODO: Think this should pribably throw error if MIC should have been returned
+ // TODO: Think this should probably throw error if MIC should have been returned
// but for now...
msg.setLogMsg("Returned MIC not found but disposition has warning so might be normal.");
logger.warn(msg);
@@ -589,10 +589,14 @@ public static void getMetaData(AS2Message msg, Session session) throws OpenAS2Ex
}
}
msg.setAttribute(FileAttribute.MA_PENDINGINFO, pendinginfofile);
- getMetaData(msg, iFile);
+ try {
+ getMetaData(msg, iFile);
+ } catch (EOFException e) {
+ throw new OpenAS2Exception("Could not parse pending info file. Appears to be invalid: " + iFile.getAbsolutePath(), e);
+ }
}
- public static void getMetaData(AS2Message msg, File inFile) throws OpenAS2Exception {
+ public static void getMetaData(AS2Message msg, File inFile) throws OpenAS2Exception, EOFException {
Log logger = LogFactory.getLog(AS2Util.class.getSimpleName());
ObjectInputStream pifois;
try {
diff --git a/changes.txt b/changes.txt
index d1162a10..f4908788 100644
--- a/changes.txt
+++ b/changes.txt
@@ -1,3 +1,13 @@
+Version 3.4.1 - 2022-12-04
+This is an enhancement and minor bugfix release:
+ **IMPORTANT NOTE**: Please review upgrade notes in the RELEASE-NOTES.md if you are upgrading
+
+ 1. Fix message attributes not being available to partnership config (eg attributes.filename)
+ 2. Add defensie coding for highly questionnable file names sent by partner containing an asterisk such as ".*"
+ 3. Further enhancements to the confog.xml extracting key values to properties to facilitate auto upgrades.
+ 4. Enhance helper scripts to support non-prompting execution allowing invocation from other scripts.
+ 5. Disable the WebUI module by default as it only runs with Java 11 and above.
+
Version 3.4.0 - 2022-10-04
This is an enhancement and minor bugfix release:
**IMPORTANT NOTE**: Please review upgrade notes in the RELEASE-NOTES.md if you are upgrading
diff --git a/docs/OpenAS2HowTo.odt b/docs/OpenAS2HowTo.odt
index 2ccff9d0..b82c63a3 100644
Binary files a/docs/OpenAS2HowTo.odt and b/docs/OpenAS2HowTo.odt differ
diff --git a/docs/OpenAS2HowTo.pdf b/docs/OpenAS2HowTo.pdf
index c47ea6eb..2fc52cb0 100644
Binary files a/docs/OpenAS2HowTo.pdf and b/docs/OpenAS2HowTo.pdf differ
diff --git a/pom.xml b/pom.xml
index 1896098c..bdd7d517 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
4.0.0
net.sf.openas2
OpenAS2
- 3.4.0
+ 3.4.1
OpenAS2
pom
@@ -52,27 +52,27 @@
org.bouncycastle
bcmail-jdk18on
- 1.71.1
+ 1.72
org.bouncycastle
bcpkix-jdk18on
- 1.71.1
+ 1.72
org.bouncycastle
bcprov-jdk18on
- 1.71.1
+ 1.72
org.bouncycastle
bcprov-ext-jdk18on
- 1.71
+ 1.72
org.bouncycastle
bcpg-jdk18on
- 1.71.1
+ 1.72.2
org.apache.commons
@@ -103,7 +103,7 @@
org.apache.httpcomponents
httpcore
- 4.4.15
+ 4.4.16
@@ -133,7 +133,7 @@
org.mockito
mockito-core
- 4.8.0
+ 4.9.0
test
@@ -157,25 +157,25 @@
org.glassfish.jersey.containers
jersey-container-grizzly2-http
- 3.1.0-M8
+ 3.1.0
jar
com.fasterxml.jackson.core
jackson-databind
- 2.13.4.1
+ 2.14.1
jar
org.glassfish.jersey.media
jersey-media-json-jackson
- 3.1.0-M8
+ 3.1.0
jar
org.glassfish.jersey.inject
jersey-hk2
- 3.1.0-M8
+ 3.1.0
@@ -196,7 +196,7 @@
io.sentry
sentry
- 6.4.2
+ 6.9.1