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$" /> 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