diff --git a/Bundle/pom.xml b/Bundle/pom.xml index fa550330..c1c13903 100644 --- a/Bundle/pom.xml +++ b/Bundle/pom.xml @@ -6,7 +6,7 @@ net.sf.openas2 OpenAS2 - 2.5.0-SNAPSHOT + 2.5.0 openas2-osgi diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 3cadd44b..98a25a71 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -8,7 +8,7 @@ The release download file is: OpenAS2Server-2.5.0.zip The zip file contains a PDF document (OpenAS2HowTo.pdf) providing information on installing and using the application. -Version 2.5.0 - 2018-05-15 +Version 2.5.0 - 2018-07-02 This is an enhancement and bugfix release: **IMPORTANT NOTE**: Please review upgrade notes below if you are upgrading @@ -24,6 +24,9 @@ This is an enhancement and bugfix release: 10. Change attribute name for overriding Message-ID format at partnership level to match name at system level. NB See upgrade notes for attribute name change. 11. Allow modules to have scheduled tasks using the HasSchedule implementation. 12. Add scheduled task to detect failed sent messages where files are not cleaned up. (Fixes https://sourceforge.net/p/openas2/tickets/5/) + 13. Allow attributes in partnership element to reference other partnership elements and resolve the references at load time. + 14. Default sample in partnerships.xml for "as2_mdn_options" to use the "sign" attribute value for the micalg value. + 15. Support AS2 ID with spaces in the value. ##Upgrade Notes See the openAS2HowTo appendix for the general process on upgrading OpenAS2. @@ -34,6 +37,7 @@ This is an enhancement and bugfix release: ### If upgrading from versions older than 2.5.0: 1. Change the name of the MDN sender module from "AsynchMDNSenderModule" to "MDNSenderModule" in the config.xml if using your existing config.xml file in the upgrade. 2. Change the name of the partnership attribute "messageid" to "as2_message_id_format" if used in any partnership definition. + 3. Change the "as2_mdn_options" attribute to use $attribute.sign$ instead of hard coded signing algorithm ### If upgrading from versions older than 2.4.1: diff --git a/Remote/pom.xml b/Remote/pom.xml index 6dc2c450..8df445b3 100644 --- a/Remote/pom.xml +++ b/Remote/pom.xml @@ -4,7 +4,7 @@ net.sf.openas2 OpenAS2 - 2.5.0-SNAPSHOT + 2.5.0 4.0.0 diff --git a/Server/pom.xml b/Server/pom.xml index 11644b02..4c9eea1c 100644 --- a/Server/pom.xml +++ b/Server/pom.xml @@ -6,7 +6,7 @@ net.sf.openas2 OpenAS2 - 2.5.0-SNAPSHOT2 + 2.5.0 openas2-server diff --git a/Server/src/main/java/org/openas2/cert/PKCS12CertificateFactory.java b/Server/src/main/java/org/openas2/cert/PKCS12CertificateFactory.java index 1d5e94ed..938c2c11 100644 --- a/Server/src/main/java/org/openas2/cert/PKCS12CertificateFactory.java +++ b/Server/src/main/java/org/openas2/cert/PKCS12CertificateFactory.java @@ -28,7 +28,6 @@ import org.openas2.message.MessageMDN; import org.openas2.params.InvalidParameterException; import org.openas2.partner.Partnership; -import org.openas2.partner.SecurePartnership; import org.openas2.schedule.HasSchedule; import org.openas2.support.FileMonitorAdapter; import org.openas2.util.AS2Util; @@ -49,10 +48,10 @@ public String getAlias(Partnership partnership, String partnershipType) throws O if (partnershipType == Partnership.PTYPE_RECEIVER) { - alias = partnership.getReceiverID(SecurePartnership.PID_X509_ALIAS); + alias = partnership.getReceiverID(Partnership.PID_X509_ALIAS); } else if (partnershipType == Partnership.PTYPE_SENDER) { - alias = partnership.getSenderID(SecurePartnership.PID_X509_ALIAS); + alias = partnership.getSenderID(Partnership.PID_X509_ALIAS); } if (alias == null) diff --git a/Server/src/main/java/org/openas2/lib/partner/IPartnership.java b/Server/src/main/java/org/openas2/lib/partner/IPartnership.java deleted file mode 100644 index 15b9811c..00000000 --- a/Server/src/main/java/org/openas2/lib/partner/IPartnership.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.openas2.lib.partner; - -public class IPartnership { - public static final String ATTRIBUTE_ENCRYPTION_ALGORITHM = "encrypt"; - public static final String ATTRIBUTE_SIGNATURE_ALGORITHM = "sign"; - public static final String ATTRIBUTE_SUBJECT = "subject"; - public static final String ATTRIBUTE_SOURCE = "source"; - public static final String ATTRIBUTE_DESTINATION = "destination"; - public static final String ATTRIBUTE_MDN_OPTIONS = "mdnoptions"; - public static final String ATTRIBUTE_COMPRESSION_TYPE = "compression"; - -} diff --git a/Server/src/main/java/org/openas2/message/AS2Message.java b/Server/src/main/java/org/openas2/message/AS2Message.java index 75a2f939..848899c3 100644 --- a/Server/src/main/java/org/openas2/message/AS2Message.java +++ b/Server/src/main/java/org/openas2/message/AS2Message.java @@ -1,7 +1,6 @@ package org.openas2.message; import org.openas2.params.InvalidParameterException; -import org.openas2.partner.AS2Partnership; import org.openas2.partner.Partnership; @@ -26,8 +25,8 @@ public boolean isRequestingMDN() { public boolean isConfiguredForMDN() { Partnership p = getPartnership(); - return ((p.getAttribute(AS2Partnership.PA_AS2_MDN_TO) != null) - && (p.getAttribute(AS2Partnership.PA_AS2_MDN_OPTIONS) != null)); + return ((p.getAttribute(Partnership.PA_AS2_MDN_TO) != null) + && (p.getAttribute(Partnership.PA_AS2_MDN_OPTIONS) != null)); } @@ -38,7 +37,7 @@ public boolean isRequestingAsynchMDN() { public boolean isConfiguredForAsynchMDN() { Partnership p = getPartnership(); - return (p.getAttribute(AS2Partnership.PA_AS2_RECEIPT_OPTION) != null); + return (p.getAttribute(Partnership.PA_AS2_RECEIPT_OPTION) != null); } public String getAsyncMDNurl() { diff --git a/Server/src/main/java/org/openas2/partner/AS2Partnership.java b/Server/src/main/java/org/openas2/partner/AS2Partnership.java deleted file mode 100644 index b0f41d63..00000000 --- a/Server/src/main/java/org/openas2/partner/AS2Partnership.java +++ /dev/null @@ -1,20 +0,0 @@ - -package org.openas2.partner; - - -public interface AS2Partnership { - public static final String PID_AS2 = "as2_id"; // AS2 ID - public static final String PA_AS2_URL = "as2_url"; // URL destination for AS2 transactions - public static final String PA_AS2_MDN_TO = "as2_mdn_to"; // Fill in to request an MDN for a transaction - public static final String PA_AS2_MDN_OPTIONS = "as2_mdn_options"; // Requested options for returned MDN - public static final String PA_AS2_RECEIPT_OPTION = "as2_receipt_option"; // URL destination for an async MDN - public static final String PA_RESEND_MAX_RETRIES = "resend_max_retries"; // format to use for message-id if not default - public static final String PA_CUSTOM_MIME_HEADERS = "custom_mime_headers"; // list of nme/value pairs for setting custom mime headers - public static final String PA_ADD_CUSTOM_MIME_HEADERS_TO_HTTP = "add_custom_mime_headers_to_http"; // Add the custom mime headers (if any) to HTTP header if "true" - public static final String PA_CUSTOM_MIME_HEADER_NAMES_FROM_FILENAME = "custom_mime_header_names_from_filename"; // List of header names to be set from parsed filename - public static final String PA_CUSTOM_MIME_HEADER_NAME_DELIMITERS_IN_FILENAME = "custom_mime_header_name_delimiters_in_filename"; // Delimiters to split filename into values - public static final String PA_CUSTOM_MIME_HEADER_NAMES_REGEX_ON_FILENAME = "custom_mime_header_names_regex_on_filename"; // Regex to split filename into values - - public static final String PA_ATTRIB_NAMES_FROM_FILENAME = "attribute_names_from_filename"; // List of attribute names to be set from parsed filename - public static final String PA_ATTRIB_VALUES_REGEX_ON_FILENAME = "attribute_values_regex_on_filename"; // Regex to split filename into values -} diff --git a/Server/src/main/java/org/openas2/partner/ASXPartnership.java b/Server/src/main/java/org/openas2/partner/ASXPartnership.java deleted file mode 100644 index 433589d0..00000000 --- a/Server/src/main/java/org/openas2/partner/ASXPartnership.java +++ /dev/null @@ -1,12 +0,0 @@ - -package org.openas2.partner; - -public interface ASXPartnership { - public static final String PA_MDN_SUBJECT = "mdnsubject"; // Subject sent in MDN messages - /* - * If set and an error occurs while processing a document, an error MDN will not be sent. This - * flag was made because some AS2 products don't provide email or some other external notification - * when an error MDN is received. - */ - public static final String PA_BLOCK_ERROR_MDN = "blockerrormdn"; -} diff --git a/Server/src/main/java/org/openas2/partner/BasePartnershipFactory.java b/Server/src/main/java/org/openas2/partner/BasePartnershipFactory.java index c077e9d0..4b954d6b 100644 --- a/Server/src/main/java/org/openas2/partner/BasePartnershipFactory.java +++ b/Server/src/main/java/org/openas2/partner/BasePartnershipFactory.java @@ -54,12 +54,12 @@ public void updatePartnership(Message msg, boolean overwrite) throws OpenAS2Exce msg.getPartnership().copy(partnership); // Now set dynamic parms based on file name if configured to String filename = msg.getAttribute(FileAttribute.MA_FILENAME); - String filenameToParmsList = msg.getPartnership().getAttribute(AS2Partnership.PA_ATTRIB_NAMES_FROM_FILENAME); + String filenameToParmsList = msg.getPartnership().getAttribute(Partnership.PAIB_NAMES_FROM_FILENAME); if (filename != null && filenameToParmsList != null && filenameToParmsList.length() > 0) { String[] headerNames = filenameToParmsList.split("\\s*,\\s*"); - String regex = msg.getPartnership().getAttribute(AS2Partnership.PA_ATTRIB_VALUES_REGEX_ON_FILENAME); + String regex = msg.getPartnership().getAttribute(Partnership.PAIB_VALUES_REGEX_ON_FILENAME); if (regex != null) { Pattern p = Pattern.compile(regex); diff --git a/Server/src/main/java/org/openas2/partner/Partnership.java b/Server/src/main/java/org/openas2/partner/Partnership.java index 3c64c306..44b99c4f 100644 --- a/Server/src/main/java/org/openas2/partner/Partnership.java +++ b/Server/src/main/java/org/openas2/partner/Partnership.java @@ -12,24 +12,51 @@ public class Partnership implements Serializable { + + /* identifier to define if context is sending or receiving */ public static final String PTYPE_SENDER = "sender"; // Sender partner type public static final String PTYPE_RECEIVER = "receiver"; // Receiver partner type + + /* partner definition attributes */ + public static final String PID_AS2 = "as2_id"; // AS2 ID + public static final String PID_X509_ALIAS = "x509_alias"; // Alias to an X509 Certificate public static final String PID_EMAIL = "email"; // Email address - public static final String PA_PROTOCOL = "protocol"; // AS1 or AS2 + + /* partnership definition attributes */ public static final String PA_SUBJECT = "subject"; // Subject sent in messages public static final String PA_CONTENT_TRANSFER_ENCODING = "content_transfer_encoding"; // optional content transfer enc value public static final String PA_REMOVE_PROTECTION_ATTRIB = "remove_cms_algorithm_protection_attrib"; // Some AS2 systems do not support the attribute public static final String PA_SET_CONTENT_TRANSFER_ENCODING_OMBP = "set_content_transfer_encoding_on_outer_mime_bodypart"; // optional content transfer enc value public static final String PA_RESEND_REQUIRES_NEW_MESSAGE_ID = "resend_requires_new_message_id"; // list of nme/value pairs for setting custom mime headers - /** - * - */ + public static final String PA_COMPRESSION_TYPE = "compression"; + public static final String PA_SIGNATURE_ALGORITHM = "sign"; + public static final String PA_ENCRYPTION_ALGORITHM = "encrypt"; + public static final String PA_AS2_URL = "as2_url"; // URL destination for AS2 transactions + public static final String PA_AS2_MDN_TO = "as2_mdn_to"; // Fill in to request an MDN for a transaction + public static final String PA_AS2_MDN_OPTIONS = "as2_mdn_options"; // Requested options for returned MDN + public static final String PA_AS2_RECEIPT_OPTION = "as2_receipt_option"; // URL destination for an async MDN + public static final String PA_RESEND_MAX_RETRIES = "resend_max_retries"; // format to use for message-id if not default + public static final String PA_CUSTOM_MIME_HEADERS = "custom_mime_headers"; // list of nme/value pairs for setting custom mime headers + public static final String PA_ADD_CUSTOM_MIME_HEADERS_TO_HTTP = "add_custom_mime_headers_to_http"; // Add the custom mime headers (if any) to HTTP header if "true" + public static final String PA_CUSTOM_MIME_HEADER_NAMES_FROM_FILENAME = "custom_mime_header_names_from_filename"; // List of header names to be set from parsed filename + public static final String PA_CUSTOM_MIME_HEADER_NAME_DELIMITERS_IN_FILENAME = "custom_mime_header_name_delimiters_in_filename"; // Delimiters to split filename into values + public static final String PA_CUSTOM_MIME_HEADER_NAMES_REGEX_ON_FILENAME = "custom_mime_header_names_regex_on_filename"; // Regex to split filename into values + public static final String PAIB_NAMES_FROM_FILENAME = "attribute_names_from_filename"; // List of attribute names to be set from parsed filename + public static final String PAIB_VALUES_REGEX_ON_FILENAME = "attribute_values_regex_on_filename"; // Regex to split filename into values + + /* + * If set and an error occurs while processing a document, an error MDN will not be sent. This + * flag was made because some AS2 products don't provide email or some other external notification + * when an error MDN is received. + */ + public static final String PA_BLOCK_ERROR_MDN = "blockerrormdn"; + + private static final long serialVersionUID = -8365608387462470629L; private Map attributes; private Map receiverIDs; private Map senderIDs; private String name; - public String getName() { return name; } @@ -173,7 +200,7 @@ public void copy(Partnership partnership) { public boolean isAsyncMDN() { - String receiptOptions = getAttribute(AS2Partnership.PA_AS2_RECEIPT_OPTION); + String receiptOptions = getAttribute(Partnership.PA_AS2_RECEIPT_OPTION); return (receiptOptions != null && receiptOptions.length() > 0); } diff --git a/Server/src/main/java/org/openas2/partner/SecurePartnership.java b/Server/src/main/java/org/openas2/partner/SecurePartnership.java deleted file mode 100644 index 94695172..00000000 --- a/Server/src/main/java/org/openas2/partner/SecurePartnership.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.openas2.partner; - - -public interface SecurePartnership { - public static final String PID_X509_ALIAS = "x509_alias"; // Alias to an X509 Certificate - public static final String PA_ENCRYPT = "encrypt"; // Set this to the algorithm to use for encryption, check AS2Util constants for values - public static final String PA_SIGN = "sign"; // Set this to the signature digest algorithm to sign sent messages -} diff --git a/Server/src/main/java/org/openas2/partner/XMLPartnershipFactory.java b/Server/src/main/java/org/openas2/partner/XMLPartnershipFactory.java index 3d963c61..201a425a 100644 --- a/Server/src/main/java/org/openas2/partner/XMLPartnershipFactory.java +++ b/Server/src/main/java/org/openas2/partner/XMLPartnershipFactory.java @@ -26,6 +26,7 @@ import org.openas2.WrappedException; import org.openas2.params.InvalidParameterException; import org.openas2.support.FileMonitorAdapter; +import org.openas2.util.AS2Util; import org.openas2.util.XMLUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -128,6 +129,7 @@ private void loadAttributes(Node node, Partnership partnership) { Map nodes = XMLUtil.mapAttributeNodes(node.getChildNodes(), "attribute", "name", "value"); + AS2Util.attributeEnhancer(nodes); partnership.getAttributes().putAll(nodes); } @@ -155,7 +157,7 @@ private void loadPartnerIDs(Map partners, String partnershipName if (partnerNode == null) { - throw new OpenAS2Exception("Partnership " + partnershipName + " is missing sender"); + throw new OpenAS2Exception("Partnership \"" + partnershipName + "\" is missing sender"); } Map partnerAttr = XMLUtil.mapAttributes(partnerNode); diff --git a/Server/src/main/java/org/openas2/processor/msgtracking/BaseMsgTrackingModule.java b/Server/src/main/java/org/openas2/processor/msgtracking/BaseMsgTrackingModule.java index 15240605..c6d1fe6b 100644 --- a/Server/src/main/java/org/openas2/processor/msgtracking/BaseMsgTrackingModule.java +++ b/Server/src/main/java/org/openas2/processor/msgtracking/BaseMsgTrackingModule.java @@ -5,11 +5,10 @@ import org.openas2.OpenAS2Exception; import org.openas2.Session; -import org.openas2.lib.partner.IPartnership; import org.openas2.message.AS2MessageMDN; import org.openas2.message.Message; import org.openas2.message.MessageMDN; -import org.openas2.partner.AS2Partnership; +import org.openas2.partner.Partnership; import org.openas2.processor.BaseProcessorModule; import org.openas2.processor.resender.ResenderModule; @@ -59,19 +58,19 @@ protected Map buildMap(Message msg, Map options) map.put(FIELDS.RESEND_COUNT, (String) options.get(ResenderModule.OPTION_RETRIES)); } //map.put(FIELDS.RESEND_COUNT, ); - String sender = msg.getPartnership().getSenderID(AS2Partnership.PID_AS2); - if (sender == null) sender = mdn.getPartnership().getSenderID(AS2Partnership.PID_AS2); + String sender = msg.getPartnership().getSenderID(Partnership.PID_AS2); + if (sender == null) sender = mdn.getPartnership().getSenderID(Partnership.PID_AS2); map.put(FIELDS.SENDER_ID, sender); - String receiver = msg.getPartnership().getReceiverID(AS2Partnership.PID_AS2); - if (receiver == null) receiver = mdn.getPartnership().getReceiverID(AS2Partnership.PID_AS2); + String receiver = msg.getPartnership().getReceiverID(Partnership.PID_AS2); + if (receiver == null) receiver = mdn.getPartnership().getReceiverID(Partnership.PID_AS2); map.put(FIELDS.RECEIVER_ID, receiver); map.put(FIELDS.STATUS, msg.getStatus()); String state = (String) options.get("STATE"); map.put(FIELDS.STATE, state); map.put(FIELDS.STATE_MSG, Message.STATE_MSGS.get(state)); - map.put(FIELDS.SIGNATURE_ALGORITHM, msg.getPartnership().getAttribute(IPartnership.ATTRIBUTE_SIGNATURE_ALGORITHM)); - map.put(FIELDS.ENCRYPTION_ALGORITHM, msg.getPartnership().getAttribute(IPartnership.ATTRIBUTE_ENCRYPTION_ALGORITHM)); - map.put(FIELDS.COMPRESSION, msg.getPartnership().getAttribute(IPartnership.ATTRIBUTE_COMPRESSION_TYPE)); + map.put(FIELDS.SIGNATURE_ALGORITHM, msg.getPartnership().getAttribute(Partnership.PA_SIGNATURE_ALGORITHM)); + map.put(FIELDS.ENCRYPTION_ALGORITHM, msg.getPartnership().getAttribute(Partnership.PA_ENCRYPTION_ALGORITHM)); + map.put(FIELDS.COMPRESSION, msg.getPartnership().getAttribute(Partnership.PA_COMPRESSION_TYPE)); map.put(FIELDS.FILE_NAME, msg.getPayloadFilename()); map.put(FIELDS.CONTENT_TYPE, msg.getContentType()); map.put(FIELDS.CONTENT_TRANSFER_ENCODING, msg.getHeader("Content-Transfer-Encoding")); 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 9fead080..846bba5e 100644 --- a/Server/src/main/java/org/openas2/processor/receiver/AS2MDNReceiverHandler.java +++ b/Server/src/main/java/org/openas2/processor/receiver/AS2MDNReceiverHandler.java @@ -15,7 +15,7 @@ import org.openas2.message.AS2MessageMDN; import org.openas2.message.Message; import org.openas2.message.MessageMDN; -import org.openas2.partner.AS2Partnership; +import org.openas2.partner.Partnership; import org.openas2.util.AS2Util; import org.openas2.util.ByteArrayDataSource; import org.openas2.util.HTTPUtil; @@ -102,8 +102,8 @@ public void handle(NetModule owner, Socket s) String to = msg.getHeader("AS2-To"); msg.setHeader("AS2-To", msg.getHeader("AS2-From")); msg.setHeader("AS2-From", to); - msg.getPartnership().setSenderID(AS2Partnership.PID_AS2, msg.getHeader("AS2-From")); - msg.getPartnership().setReceiverID(AS2Partnership.PID_AS2, msg.getHeader("AS2-To")); + msg.getPartnership().setSenderID(Partnership.PID_AS2, msg.getHeader("AS2-From")); + msg.getPartnership().setReceiverID(Partnership.PID_AS2, msg.getHeader("AS2-To")); getModule().getSession().getPartnershipFactory().updatePartnership(msg, true); // Create a MessageMDN 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 98bb2f72..abaf29f5 100644 --- a/Server/src/main/java/org/openas2/processor/receiver/AS2ReceiverHandler.java +++ b/Server/src/main/java/org/openas2/processor/receiver/AS2ReceiverHandler.java @@ -37,8 +37,6 @@ import org.openas2.message.NetAttribute; import org.openas2.params.MessageParameters; import org.openas2.params.ParameterParser; -import org.openas2.partner.AS2Partnership; -import org.openas2.partner.ASXPartnership; import org.openas2.partner.Partnership; import org.openas2.processor.sender.SenderModule; import org.openas2.processor.storage.StorageModule; @@ -194,8 +192,8 @@ public void handle(NetModule owner, Socket s) { // Extract AS2 ID's from header, find the message's partnership and update the // message try { - msg.getPartnership().setSenderID(AS2Partnership.PID_AS2, msg.getHeader("AS2-From")); - msg.getPartnership().setReceiverID(AS2Partnership.PID_AS2, msg.getHeader("AS2-To")); + msg.getPartnership().setSenderID(Partnership.PID_AS2, msg.getHeader("AS2-From")); + msg.getPartnership().setReceiverID(Partnership.PID_AS2, msg.getHeader("AS2-To")); getModule().getSession().getPartnershipFactory().updatePartnership(msg, false); } catch (OpenAS2Exception oae) { @@ -451,7 +449,7 @@ protected boolean sendResponse(AS2Message msg, BufferedOutputStream out, Disposi String text) { boolean mdnBlocked = false; - mdnBlocked = (msg.getPartnership().getAttribute(ASXPartnership.PA_BLOCK_ERROR_MDN) != null); + mdnBlocked = (msg.getPartnership().getAttribute(Partnership.PA_BLOCK_ERROR_MDN) != null); if (!mdnBlocked) { @@ -518,12 +516,12 @@ public MessageMDN createMDN(Session session, AS2Message msg, String mic, // get the MDN partnership info // not sure that it should be this way since the config should relfect the inbound original message settings but ... - mdn.getPartnership().setSenderID(AS2Partnership.PID_AS2, mdn.getHeader("AS2-From")); - mdn.getPartnership().setReceiverID(AS2Partnership.PID_AS2, mdn.getHeader("AS2-To")); + mdn.getPartnership().setSenderID(Partnership.PID_AS2, mdn.getHeader("AS2-From")); + mdn.getPartnership().setReceiverID(Partnership.PID_AS2, mdn.getHeader("AS2-To")); session.getPartnershipFactory().updatePartnership(mdn, true); mdn.setHeader("From", msg.getPartnership().getReceiverID(Partnership.PID_EMAIL)); - String subject = mdn.getPartnership().getAttribute(ASXPartnership.PA_MDN_SUBJECT); + String subject = mdn.getPartnership().getAttribute(Partnership.PA_SUBJECT); if (subject != null) { mdn.setHeader("Subject", ParameterParser.parse(subject, new MessageParameters(msg))); @@ -536,7 +534,7 @@ public MessageMDN createMDN(Session session, AS2Message msg, String mic, + msg.getAttribute(NetAttribute.MA_DESTINATION_PORT)); mdn.setAttribute(AS2MessageMDN.MDNA_ORIG_RECIPIENT, "rfc822; " + msg.getHeader("AS2-To")); mdn.setAttribute(AS2MessageMDN.MDNA_FINAL_RECIPIENT, "rfc822; " - + msg.getPartnership().getReceiverID(AS2Partnership.PID_AS2)); + + msg.getPartnership().getReceiverID(Partnership.PID_AS2)); mdn.setAttribute(AS2MessageMDN.MDNA_ORIG_MESSAGEID, msg.getHeader("Message-ID")); mdn.setAttribute(AS2MessageMDN.MDNA_DISPOSITION, disposition.toString()); diff --git a/Server/src/main/java/org/openas2/processor/receiver/AS2ReceiverModule.java b/Server/src/main/java/org/openas2/processor/receiver/AS2ReceiverModule.java index bb4b1b79..04c139bc 100644 --- a/Server/src/main/java/org/openas2/processor/receiver/AS2ReceiverModule.java +++ b/Server/src/main/java/org/openas2/processor/receiver/AS2ReceiverModule.java @@ -2,15 +2,15 @@ import org.openas2.message.NetAttribute; import org.openas2.params.MessageParameters; -import org.openas2.partner.AS2Partnership; +import org.openas2.partner.Partnership; public class AS2ReceiverModule extends NetModule { // Macros for responses public static final String MSG_SENDER = "$" + MessageParameters.KEY_SENDER + "." + - AS2Partnership.PID_AS2 + "$"; + Partnership.PID_AS2 + "$"; public static final String MSG_RECEIVER = "$" + MessageParameters.KEY_RECEIVER + "." + - AS2Partnership.PID_AS2 + "$"; + Partnership.PID_AS2 + "$"; public static final String MSG_DATE = "$" + MessageParameters.KEY_HEADERS + ".date" + "$"; public static final String MSG_SUBJECT = "$" + MessageParameters.KEY_HEADERS + ".subject" + "$"; public static final String MSG_SOURCE_ADDRESS = "$" + MessageParameters.KEY_ATTRIBUTES + "." + 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 f374627d..043f1205 100644 --- a/Server/src/main/java/org/openas2/processor/receiver/MessageBuilderModule.java +++ b/Server/src/main/java/org/openas2/processor/receiver/MessageBuilderModule.java @@ -27,7 +27,6 @@ import org.openas2.params.InvalidParameterException; import org.openas2.params.MessageParameters; import org.openas2.params.ParameterParser; -import org.openas2.partner.AS2Partnership; import org.openas2.partner.Partnership; import org.openas2.processor.resender.ResenderModule; import org.openas2.processor.sender.SenderModule; @@ -111,11 +110,11 @@ protected Message processDocument(InputStream ip, String filename) throws OpenAS fis = null; doc = null; } - String customHeaderList = msg.getPartnership().getAttribute(AS2Partnership.PA_CUSTOM_MIME_HEADER_NAMES_FROM_FILENAME); + String customHeaderList = msg.getPartnership().getAttribute(Partnership.PA_CUSTOM_MIME_HEADER_NAMES_FROM_FILENAME); if (customHeaderList != null && customHeaderList.length() > 0) { String[] headerNames = customHeaderList.split("\\s*,\\s*"); - String delimiters = msg.getPartnership().getAttribute(AS2Partnership.PA_CUSTOM_MIME_HEADER_NAME_DELIMITERS_IN_FILENAME); + String delimiters = msg.getPartnership().getAttribute(Partnership.PA_CUSTOM_MIME_HEADER_NAME_DELIMITERS_IN_FILENAME); if (logger.isTraceEnabled()) logger.trace("Adding custom headers based on message file name to custom headers map. Delimeters: " + delimiters + msg.getLogMsgID()); if (delimiters != null) { @@ -139,7 +138,7 @@ protected Message processDocument(InputStream ip, String filename) throws OpenAS } else { - String regex = msg.getPartnership().getAttribute(AS2Partnership.PA_CUSTOM_MIME_HEADER_NAMES_REGEX_ON_FILENAME); + String regex = msg.getPartnership().getAttribute(Partnership.PA_CUSTOM_MIME_HEADER_NAMES_REGEX_ON_FILENAME); if (regex != null) { Pattern p = Pattern.compile(regex); @@ -169,7 +168,7 @@ protected Message processDocument(InputStream ip, String filename) throws OpenAS if (logger.isTraceEnabled()) logger.trace("PARTNERSHIP parms: " + msg.getPartnership().getAttributes() + msg.getLogMsgID()); // Retry count - first try on partnership then directory polling module - String maxRetryCnt = msg.getPartnership().getAttribute(AS2Partnership.PA_RESEND_MAX_RETRIES); + String maxRetryCnt = msg.getPartnership().getAttribute(Partnership.PA_RESEND_MAX_RETRIES); if (maxRetryCnt == null || maxRetryCnt.length() < 1) { maxRetryCnt = getSession().getProcessor().getParameters().get(PARAM_RESEND_MAX_RETRIES); @@ -234,8 +233,8 @@ public Message buildMessageMetadata(String filename) throws OpenAS2Exception getSession().getPartnershipFactory().updatePartnership(msg, true); msg.updateMessageID(); // Set the sender and receiver in the Message object headers - msg.setHeader("AS2-To", msg.getPartnership().getReceiverID(AS2Partnership.PID_AS2)); - msg.setHeader("AS2-From", msg.getPartnership().getSenderID(AS2Partnership.PID_AS2)); + msg.setHeader("AS2-To", msg.getPartnership().getReceiverID(Partnership.PID_AS2)); + msg.setHeader("AS2-From", msg.getPartnership().getSenderID(Partnership.PID_AS2)); // Now build the filename since it is by default dependent on having sender and receiver ID String pendingFile = AS2Util.buildPendingFileName(msg, getSession().getProcessor(), "pendingmdn"); msg.setAttribute(FileAttribute.MA_PENDINGFILE, pendingFile); 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 f78606e2..9bd94eea 100644 --- a/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java +++ b/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java @@ -34,9 +34,7 @@ import org.openas2.message.MessageMDN; import org.openas2.message.NetAttribute; import org.openas2.params.InvalidParameterException; -import org.openas2.partner.AS2Partnership; import org.openas2.partner.Partnership; -import org.openas2.partner.SecurePartnership; import org.openas2.processor.resender.ResenderModule; import org.openas2.schedule.HasSchedule; import org.openas2.util.AS2Util; @@ -122,7 +120,7 @@ public void handle(String action, Message msg, Map options) thro { } } - String url = msg.getPartnership().getAttribute(AS2Partnership.PA_AS2_URL); + String url = msg.getPartnership().getAttribute(Partnership.PA_AS2_URL); try { // Create the HTTP connection and set up headers @@ -165,12 +163,12 @@ protected void checkRequired(Message msg) throws InvalidParameterException try { InvalidParameterException.checkValue(msg, "ContentType", msg.getContentType()); - InvalidParameterException.checkValue(msg, "Attribute: " + AS2Partnership.PA_AS2_URL, - partnership.getAttribute(AS2Partnership.PA_AS2_URL)); - InvalidParameterException.checkValue(msg, "Receiver: " + AS2Partnership.PID_AS2, - partnership.getReceiverID(AS2Partnership.PID_AS2)); - InvalidParameterException.checkValue(msg, "Sender: " + AS2Partnership.PID_AS2, - partnership.getSenderID(AS2Partnership.PID_AS2)); + InvalidParameterException.checkValue(msg, "Attribute: " + Partnership.PA_AS2_URL, + partnership.getAttribute(Partnership.PA_AS2_URL)); + InvalidParameterException.checkValue(msg, "Receiver: " + Partnership.PID_AS2, + partnership.getReceiverID(Partnership.PID_AS2)); + InvalidParameterException.checkValue(msg, "Sender: " + Partnership.PID_AS2, + partnership.getSenderID(Partnership.PID_AS2)); InvalidParameterException.checkValue(msg, "Subject", msg.getSubject()); InvalidParameterException.checkValue(msg, "Sender: " + Partnership.PID_EMAIL, partnership.getSenderID(Partnership.PID_EMAIL)); @@ -209,7 +207,7 @@ private void sendMessage(String url, Message msg, MimeBodyPart securedData, Stri { msg.setLogMsg("Error sending message. URL: " + url + " ::: Response Code: " + rc + " " + resp.getStatusPhrase() - + " ::: Response Message: " + resp.getBody()); + + " ::: Response Message: " + resp.getBody().toString()); logger.error(msg); throw new HttpResponseException(url, rc, resp.getStatusPhrase()); } @@ -224,7 +222,7 @@ private void processResponse(Message msg, ResponseWrapper response) { if (!msg.isConfiguredForMDN()) return; // Check if it will be a Sync or AsyncMDN - if (msg.getPartnership().getAttribute(AS2Partnership.PA_AS2_RECEIPT_OPTION) != null) { + if (msg.getPartnership().getAttribute(Partnership.PA_AS2_RECEIPT_OPTION) != null) { // Async MDN msg.setStatus(Message.MSG_STATUS_MDN_WAIT); } else { @@ -241,7 +239,7 @@ private void processResponse(Message msg, ResponseWrapper response) { } msg.setStatus(Message.MSG_STATUS_MDN_PROCESS_INIT); try { - AS2Util.processMDN((AS2Message) msg, response.getBody().getBytes(), null, false, getSession(), this); + AS2Util.processMDN((AS2Message) msg, response.getBody(), null, false, getSession(), this); // Log significant msg state msg.setOption("STATE", Message.MSG_STATE_MSG_SENT_MDN_RECEIVED_OK); msg.trackMsgState(getSession()); @@ -312,8 +310,8 @@ protected MimeBodyPart secure(Message msg) throws Exception contentTxfrEncoding = Session.DEFAULT_CONTENT_TRANSFER_ENCODING; } - boolean encrypt = partnership.getAttribute(SecurePartnership.PA_ENCRYPT) != null; - boolean sign = partnership.getAttribute(SecurePartnership.PA_SIGN) != null; + boolean encrypt = partnership.getAttribute(Partnership.PA_ENCRYPTION_ALGORITHM) != null; + boolean sign = partnership.getAttribute(Partnership.PA_SIGNATURE_ALGORITHM) != null; if (!sign) { @@ -374,7 +372,7 @@ protected MimeBodyPart secure(Message msg) throws Exception X509Certificate senderCert = certFx.getCertificate(msg, Partnership.PTYPE_SENDER); PrivateKey senderKey = certFx.getPrivateKey(msg, senderCert); - String digest = partnership.getAttribute(SecurePartnership.PA_SIGN); + String digest = partnership.getAttribute(Partnership.PA_SIGNATURE_ALGORITHM); if (logger.isDebugEnabled()) { @@ -415,7 +413,7 @@ protected MimeBodyPart secure(Message msg) throws Exception { //Add any additional headers since this will be the outermost Mime body part if configured addCustomOuterMimeHeaders(msg, dataBP); - String algorithm = partnership.getAttribute(SecurePartnership.PA_ENCRYPT); + String algorithm = partnership.getAttribute(Partnership.PA_ENCRYPTION_ALGORITHM); X509Certificate receiverCert = certFx.getCertificate(msg, Partnership.PTYPE_RECEIVER); dataBP = AS2Util.getCryptoHelper().encrypt(dataBP, receiverCert, algorithm, contentTxfrEncoding); @@ -440,7 +438,7 @@ protected MimeBodyPart secure(Message msg) throws Exception } protected void addCustomHeaders(Message msg) throws OpenAS2Exception { - String customHeaders = msg.getPartnership().getAttribute(AS2Partnership.PA_CUSTOM_MIME_HEADERS); + String customHeaders = msg.getPartnership().getAttribute(Partnership.PA_CUSTOM_MIME_HEADERS); if (customHeaders != null && customHeaders.length() > 0) { if (logger.isTraceEnabled()) @@ -522,24 +520,24 @@ protected InternetHeaders getHttpHeaders(Message msg, MimeBodyPart securedData) cte = Session.DEFAULT_CONTENT_TRANSFER_ENCODING; } ih.addHeader("Content-Transfer-Encoding", cte); - ih.addHeader("Recipient-Address", partnership.getAttribute(AS2Partnership.PA_AS2_URL)); - String rId = partnership.getReceiverID(AS2Partnership.PID_AS2); + ih.addHeader("Recipient-Address", partnership.getAttribute(Partnership.PA_AS2_URL)); + String rId = partnership.getReceiverID(Partnership.PID_AS2); if (rId.contains(" ")) rId = "\"" + rId + "\""; ih.addHeader("AS2-To", rId); - String sId = partnership.getSenderID(AS2Partnership.PID_AS2); + String sId = partnership.getSenderID(Partnership.PID_AS2); if (sId.contains(" ")) sId = "\"" + sId + "\""; ih.addHeader("AS2-From", sId); ih.addHeader("Subject", msg.getSubject()); ih.addHeader("From", partnership.getSenderID(Partnership.PID_EMAIL)); - String dispTo = partnership.getAttribute(AS2Partnership.PA_AS2_MDN_TO); + String dispTo = partnership.getAttribute(Partnership.PA_AS2_MDN_TO); if (dispTo != null) { ih.addHeader("Disposition-Notification-To", dispTo); } - String dispOptions = partnership.getAttribute(AS2Partnership.PA_AS2_MDN_OPTIONS); + String dispOptions = partnership.getAttribute(Partnership.PA_AS2_MDN_OPTIONS); if (dispOptions != null) { ih.addHeader("Disposition-Notification-Options", dispOptions); } - String receiptOption = partnership.getAttribute(AS2Partnership.PA_AS2_RECEIPT_OPTION); + String receiptOption = partnership.getAttribute(Partnership.PA_AS2_RECEIPT_OPTION); if (receiptOption != null) { ih.addHeader("Receipt-Delivery-Option", receiptOption); } @@ -552,7 +550,7 @@ protected InternetHeaders getHttpHeaders(Message msg, MimeBodyPart securedData) if (contentDisp != null) { ih.addHeader("Content-Disposition", contentDisp); } - if ("true".equalsIgnoreCase((partnership.getAttribute(AS2Partnership.PA_ADD_CUSTOM_MIME_HEADERS_TO_HTTP)))) { + if ("true".equalsIgnoreCase((partnership.getAttribute(Partnership.PA_ADD_CUSTOM_MIME_HEADERS_TO_HTTP)))) { if (logger.isTraceEnabled()) { logger.trace("Adding custom headers to HTTP..." + msg.getLogMsgID()); } @@ -654,7 +652,7 @@ protected void calcAndStoreMic(Message msg, MimeBodyPart mbp, boolean includeHea // includeHeaders = (msg.getHistory().getItems().size() > 1); DispositionOptions dispOptions = new DispositionOptions(msg.getPartnership().getAttribute( - AS2Partnership.PA_AS2_MDN_OPTIONS)); + Partnership.PA_AS2_MDN_OPTIONS)); msg.setCalculatedMIC(AS2Util.getCryptoHelper().calculateMIC(mbp, dispOptions.getMicalg() , includeHeaders, msg.getPartnership().isPreventCanonicalization())); if (logger.isTraceEnabled()) diff --git a/Server/src/main/java/org/openas2/test/MimeBodyPartEncodingTest.java b/Server/src/main/java/org/openas2/test/MimeBodyPartEncodingTest.java index 9e048639..ca0342bb 100644 --- a/Server/src/main/java/org/openas2/test/MimeBodyPartEncodingTest.java +++ b/Server/src/main/java/org/openas2/test/MimeBodyPartEncodingTest.java @@ -24,7 +24,6 @@ import org.openas2.params.InvalidParameterException; import org.openas2.params.MessageParameters; import org.openas2.partner.Partnership; -import org.openas2.partner.SecurePartnership; import org.openas2.util.AS2Util; import org.openas2.util.ByteArrayDataSource; @@ -121,7 +120,7 @@ public static void main(String[] args) X509Certificate senderCert = certFx.getCertificate(msg, Partnership.PTYPE_SENDER); PrivateKey senderKey = certFx.getPrivateKey(msg, senderCert); - String digest = msg.getPartnership().getAttribute(SecurePartnership.PA_SIGN); + String digest = msg.getPartnership().getAttribute(Partnership.PA_SIGNATURE_ALGORITHM); System.out.println("Params for creating signed body part:: SIGN DIGEST: " + digest + "\n CERT ALG NAME EXTRACTED: " + senderCert.getSigAlgName() @@ -142,7 +141,7 @@ public static void main(String[] args) fos.close(); System.out.println("MimeBodyPart written to: " + testFile); - String algorithm = msg.getPartnership().getAttribute(SecurePartnership.PA_ENCRYPT); + String algorithm = msg.getPartnership().getAttribute(Partnership.PA_ENCRYPTION_ALGORITHM); X509Certificate receiverCert = certFx.getCertificate(msg, Partnership.PTYPE_RECEIVER); signedMbp = AS2Util.getCryptoHelper().encrypt(signedMbp, receiverCert, algorithm, contentTxfrEncoding); testFile = TestConfig.TEST_OUTPUT_FOLDER + "/" + TestConfig.TEST_DEFAULT_TGT_FILE_NAME + ".encrypted"; diff --git a/Server/src/main/java/org/openas2/util/AS2Util.java b/Server/src/main/java/org/openas2/util/AS2Util.java index a3641667..58b5da02 100644 --- a/Server/src/main/java/org/openas2/util/AS2Util.java +++ b/Server/src/main/java/org/openas2/util/AS2Util.java @@ -42,7 +42,6 @@ import org.openas2.params.MessageParameters; import org.openas2.params.ParameterParser; import org.openas2.params.RandomParameters; -import org.openas2.partner.AS2Partnership; import org.openas2.partner.Partnership; import org.openas2.processor.Processor; import org.openas2.processor.msgtracking.BaseMsgTrackingModule; @@ -98,6 +97,15 @@ public static void parseMDN(Message msg, X509Certificate receiver) throws OpenAS Log logger = LogFactory.getLog(AS2Util.class.getSimpleName()); MessageMDN mdn = msg.getMDN(); MimeBodyPart mainPart = mdn.getData(); + if (logger.isTraceEnabled() && "true".equalsIgnoreCase(System.getProperty("logRxdMdnMimeBodyParts", "false"))) + { + try { + logger.trace("Received MimeBodyPart for inbound MDN: " + msg.getLogMsgID() + + "\n" + MimeUtil.toString(mainPart, true)); + } catch (Exception e) { + logger.trace("Failed to log the MimeBodyPart as part of trace logging: " + e.getMessage()); + } + } try { ICryptoHelper ch = getCryptoHelper(); @@ -116,12 +124,6 @@ public static void parseMDN(Message msg, X509Certificate receiver) throws OpenAS { MimeMultipart reportParts = new MimeMultipart(mainPart.getDataHandler().getDataSource()); - if (logger.isTraceEnabled() && "true".equalsIgnoreCase(System.getProperty("logRxdMdnMimeBodyParts", "false"))) - { - logger.trace("Received MimeBodyPart for inbound MDN: " + msg.getLogMsgID() - + "\n" + MimeUtil.toString(mainPart, true)); - } - if (reportParts != null) { ContentType reportType = new ContentType(reportParts.getContentType()); @@ -265,11 +267,15 @@ public static boolean checkMDN(AS2Message msg) throws DispositionException, Open * RFC 6362 specifies that the sent attachments should be * considered invalid and retransmitted */ - String errmsg = "MIC algorithm returned by partner is not the same as the algorithm requested, original MIC alg: " + String errmsg = "MIC algorithm returned by partner is not the same as the algorithm requested but must be the same per RFC4130 section 7.4.3. Original MIC alg: " + cMicAlg + " ::: returned MIC alg: " + rMicAlg - + "\n\t\tPartner probably not implemented AS2 spec correctly or does not support the requested algorithm. Check that the \"as2_mdn_options\" attribute for the partner uses the same algorithm as the \"sign\" attribute."; + + "\n\t\tEnsure that Partner supports the requested algorithm and the \"" + + Partnership.PA_AS2_MDN_OPTIONS + + "\" attribute for the outbound partnership uses the same algorithm as the \" +" + + Partnership.PA_SIGNATURE_ALGORITHM + + "\" attribute."; throw new OpenAS2Exception(errmsg + " Forcing Resend"); } } @@ -457,8 +463,8 @@ public static void processMDN(AS2Message msg, byte[] data, OutputStream out, boo MessageMDN mdn = msg.getMDN(); if (logger.isTraceEnabled()) logger.trace("HTTP headers in received MDN: " + AS2Util.printHeaders(mdn.getHeaders().getAllHeaders())); // get the MDN partnership info - mdn.getPartnership().setSenderID(AS2Partnership.PID_AS2, mdn.getHeader("AS2-From")); - mdn.getPartnership().setReceiverID(AS2Partnership.PID_AS2, mdn.getHeader("AS2-To")); + mdn.getPartnership().setSenderID(Partnership.PID_AS2, mdn.getHeader("AS2-From")); + mdn.getPartnership().setReceiverID(Partnership.PID_AS2, mdn.getHeader("AS2-To")); session.getPartnershipFactory().updatePartnership(mdn, false); MimeBodyPart part; @@ -760,6 +766,31 @@ public static String removeAngleBrackets(String srcString) { return srcString.replaceAll("^<([^>]+)>$", "$1"); } + public static void attributeEnhancer(Map attribs) throws OpenAS2Exception { + Pattern PATTERN = Pattern.compile("\\$attribute\\.([^\\$]++)\\$"); + for (Map.Entry entry : attribs.entrySet()) { + String input = entry.getValue(); + StringBuffer strBuf = new StringBuffer(); + Matcher matcher = PATTERN.matcher(input); + boolean hasChanged = false; + while (matcher.find()) { + String key = matcher.group(1); + String value = attribs.get(key); + hasChanged = true; + if (value == null) { + throw new OpenAS2Exception("Missing attribute value for replacement: " + matcher.group()); + } else { + matcher.appendReplacement(strBuf,Matcher.quoteReplacement(value)); + } + } + if (hasChanged) { + matcher.appendTail(strBuf); + attribs.put(entry.getKey(), strBuf.toString()); + } + } + } + + public static String printHeaders(Enumeration
hdrs) { return printHeaders(hdrs, " == ", "\n\t\t"); diff --git a/Server/src/main/java/org/openas2/util/ResponseWrapper.java b/Server/src/main/java/org/openas2/util/ResponseWrapper.java index eb170496..a949b7fd 100644 --- a/Server/src/main/java/org/openas2/util/ResponseWrapper.java +++ b/Server/src/main/java/org/openas2/util/ResponseWrapper.java @@ -1,11 +1,12 @@ package org.openas2.util; -import java.io.BufferedReader; -import java.io.InputStreamReader; - +import java.io.IOException; import javax.mail.internet.InternetHeaders; +import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; +import org.apache.http.util.EntityUtils; +import org.openas2.OpenAS2Exception; public class ResponseWrapper { private String _transferTimeMs = "-1"; // amount of time in milliseconds taken to send a message and receive a response @@ -13,27 +14,27 @@ public class ResponseWrapper { private String _statusPhrase = null; private InternetHeaders _headers = new InternetHeaders(); - private String _body = null; + private byte[] _body = null; - public ResponseWrapper(HttpResponse response) { + public ResponseWrapper(HttpResponse response) throws OpenAS2Exception { super(); setStatusCode(response.getStatusLine().getStatusCode()); setStatusPhrase(response.getStatusLine().getReasonPhrase()); - try { - BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent()))); - - StringBuilder sb = new StringBuilder(200); - String output; - while ((output = br.readLine()) != null) { - sb.append(output).append("\n"); - } - - setBody(sb.toString()); - } catch (Exception e) { - setBody(e.toString()); + for (org.apache.http.Header header : response.getAllHeaders()) { + this.addHeaderLine(header.toString()); } - } + + HttpEntity entity = response.getEntity(); + if (entity == null) return; + byte[] data = null; + try { + data = EntityUtils.toByteArray(entity); + } catch (IOException e) { + throw new OpenAS2Exception("Failed to read response content", e); + } + setBody(data); + } public InternetHeaders getHeaders() { return _headers; @@ -71,11 +72,11 @@ public void setStatusPhrase(String statusPhrase) { this._statusPhrase = statusPhrase; } - public String getBody() { + public byte[] getBody() { return _body; } - protected void setBody(String body) { + protected void setBody(byte[] body) { this._body = body; } diff --git a/Server/src/main/java/org/openas2/util/StringUtil.java b/Server/src/main/java/org/openas2/util/StringUtil.java index 17016b0e..e4d41a79 100644 --- a/Server/src/main/java/org/openas2/util/StringUtil.java +++ b/Server/src/main/java/org/openas2/util/StringUtil.java @@ -76,6 +76,7 @@ public static String parseParameterisedString(String paramString, Message msg) t } public static String removeDoubleQuotes(String srcString) { + if (srcString == null) return null; return srcString.replaceAll("^\"([^\"]+)\"$", "$1"); } diff --git a/Server/src/test/java/org/openas2/app/AttributeEnhancerTest.java b/Server/src/test/java/org/openas2/app/AttributeEnhancerTest.java new file mode 100644 index 00000000..eb276344 --- /dev/null +++ b/Server/src/test/java/org/openas2/app/AttributeEnhancerTest.java @@ -0,0 +1,36 @@ +package org.openas2.app; + +import static org.junit.Assert.assertThat; + +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.Matchers.equalTo; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; +import org.openas2.OpenAS2Exception; +import org.openas2.util.AS2Util; + +@RunWith(MockitoJUnitRunner.class) + +public class AttributeEnhancerTest { + + @Test + public void enhancesAttributes() { + Map attribs = new HashMap(); + attribs.put("key1", "ValueOfKey1"); + attribs.put("key2", "ValueOfKey2"); + attribs.put("key3", "Replaced with $attribute.key1$"); + attribs.put("key4", "Replaced with $attribute.key2$ and $attribute.key1$"); + + try { + AS2Util.attributeEnhancer(attribs); + } catch (OpenAS2Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + assertThat("Key 3 has been replaced", attribs.get("key3"), equalTo("Replaced with ValueOfKey1")); + assertThat("Key 4 has been replaced", attribs.get("key4"), equalTo("Replaced with ValueOfKey2 and ValueOfKey1")); + } +} diff --git a/Server/src/test/java/org/openas2/app/HTTPUtilTest.java b/Server/src/test/java/org/openas2/app/HTTPUtilTest.java index 0570a0dd..e8bf3fb6 100644 --- a/Server/src/test/java/org/openas2/app/HTTPUtilTest.java +++ b/Server/src/test/java/org/openas2/app/HTTPUtilTest.java @@ -10,7 +10,7 @@ import org.mockito.junit.MockitoJUnitRunner; import org.openas2.message.AS2Message; import org.openas2.message.Message; -import org.openas2.partner.AS2Partnership; +import org.openas2.partner.Partnership; import org.openas2.util.HTTPUtil; @RunWith(MockitoJUnitRunner.class) @@ -33,9 +33,9 @@ public void handlesMultiEntryAS2IdWithSpacesAndQuotes() { hdrs.addHeader(toIdKey, toId); hdrs.addHeader(toIdKey, "\"" + toId + "\""); HTTPUtil.cleanIdHeaders(msg.getHeaders()); - msg.getPartnership().setSenderID(AS2Partnership.PID_AS2, msg.getHeader(fromIdKey)); - msg.getPartnership().setReceiverID(AS2Partnership.PID_AS2, msg.getHeader(toIdKey)); - assertThat("Duplicate FROM headers have been removed", msg.getPartnership().getSenderID(AS2Partnership.PID_AS2), equalTo(fromId)); - assertThat("Duplicate TO headers have been removed", msg.getPartnership().getReceiverID(AS2Partnership.PID_AS2), equalTo(toId)); + msg.getPartnership().setSenderID(Partnership.PID_AS2, msg.getHeader(fromIdKey)); + msg.getPartnership().setReceiverID(Partnership.PID_AS2, msg.getHeader(toIdKey)); + assertThat("Duplicate FROM headers have been removed", msg.getPartnership().getSenderID(Partnership.PID_AS2), equalTo(fromId)); + assertThat("Duplicate TO headers have been removed", msg.getPartnership().getReceiverID(Partnership.PID_AS2), equalTo(toId)); } } diff --git a/Server/src/test/java/org/openas2/app/OpenAS2ServerTest.java b/Server/src/test/java/org/openas2/app/OpenAS2ServerTest.java index 11f1c9fe..3f92e83b 100644 --- a/Server/src/test/java/org/openas2/app/OpenAS2ServerTest.java +++ b/Server/src/test/java/org/openas2/app/OpenAS2ServerTest.java @@ -24,7 +24,6 @@ import org.openas2.ComponentNotFoundException; import org.openas2.TestPartner; import org.openas2.TestResource; -import org.openas2.partner.AS2Partnership; import org.openas2.partner.Partnership; import org.openas2.partner.PartnershipFactory; import org.openas2.util.DateUtil; @@ -181,11 +180,11 @@ private static void enhancePartners() throws ComponentNotFoundException, FileNot for (Map.Entry pair: partners.entrySet()) { if (pair.getKey().equals(partnerB.getName())) { Map partner = (Map)pair.getValue(); - partnerB.setAs2Id(partner.get(AS2Partnership.PID_AS2)); + partnerB.setAs2Id(partner.get(Partnership.PID_AS2)); } else if (pair.getKey().equals(partnerA.getName())) { Map partner = (Map)pair.getValue(); - partnerA.setAs2Id(partner.get(AS2Partnership.PID_AS2)); + partnerA.setAs2Id(partner.get(Partnership.PID_AS2)); } } String partnershipFolderAtoB = partnerA.getAs2Id() + "-" + partnerB.getAs2Id(); @@ -215,7 +214,7 @@ private static void getPartnership() throws Exception { Partnership p = new Partnership(); Partnership asyncPartnership = pf.getPartnership(p, false); if (asyncPartnership != null) { - asyncPartnership.setAttribute(AS2Partnership.PA_AS2_RECEIPT_OPTION, "http://localhost:20081"); + asyncPartnership.setAttribute(Partnership.PA_AS2_RECEIPT_OPTION, "http://localhost:20081"); } else { throw new Exception("Could not set partnership to ~ASYNC mode"); diff --git a/Server/src/test/java/org/openas2/message/AS2MessageMDNTest.java b/Server/src/test/java/org/openas2/message/AS2MessageMDNTest.java index 0622e1df..ae5ba26f 100644 --- a/Server/src/test/java/org/openas2/message/AS2MessageMDNTest.java +++ b/Server/src/test/java/org/openas2/message/AS2MessageMDNTest.java @@ -8,7 +8,6 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; -import org.openas2.partner.AS2Partnership; import org.openas2.partner.Partnership; import org.openas2.util.Properties; @@ -38,8 +37,8 @@ public class AS2MessageMDNTest { public void setUp() throws Exception { when(message.getPartnership()).thenReturn(partnership); - when(partnership.getReceiverID(matches(AS2Partnership.PID_AS2))).thenReturn("receiverId"); - when(partnership.getSenderID(matches(AS2Partnership.PID_AS2))).thenReturn("senderId"); + when(partnership.getReceiverID(matches(Partnership.PID_AS2))).thenReturn("receiverId"); + when(partnership.getSenderID(matches(Partnership.PID_AS2))).thenReturn("senderId"); when(message.getPartnership().getAttributeOrProperty(anyString(), (String)any())) .thenAnswer( new Answer() { diff --git a/Server/src/test/java/org/openas2/params/ParameterParserTest.java b/Server/src/test/java/org/openas2/params/ParameterParserTest.java index 64377fbd..cd2b8d59 100644 --- a/Server/src/test/java/org/openas2/params/ParameterParserTest.java +++ b/Server/src/test/java/org/openas2/params/ParameterParserTest.java @@ -7,7 +7,6 @@ import org.mockito.junit.MockitoJUnitRunner; import org.openas2.message.AS2Message; import org.openas2.message.MessageMDN; -import org.openas2.partner.AS2Partnership; import org.openas2.partner.Partnership; import org.openas2.util.Properties; import org.openas2.util.StringUtil; @@ -27,10 +26,10 @@ public class ParameterParserTest { private static final String homeValue = "/My/Home/Dir"; // Parameter string and regex test for various params private String[][] positiveTests = { - { prefix + "$msg.sender." + AS2Partnership.PID_AS2 + "$_$msg.receiver." + AS2Partnership.PID_AS2 + "$", + { prefix + "$msg.sender." + Partnership.PID_AS2 + "$_$msg.receiver." + Partnership.PID_AS2 + "$", prefix + senderId + "_" + receiverId }, - { "$mdn.msg.sender." + AS2Partnership.PID_AS2 + "$", senderId }, - { "$mdn.sender." + AS2Partnership.PID_AS2 + "$", senderId }, + { "$mdn.msg.sender." + Partnership.PID_AS2 + "$", senderId }, + { "$mdn.sender." + Partnership.PID_AS2 + "$", senderId }, { "$date.yyyyMMddHHmmssZ$", "[0-9]{14}[-+][0-9]{4}" }, { "$rand.1234$-$rand.UUID$-$rand.shortUUID$", "[0-9]{4}-[a-fA-F0-9-]{36}-[a-zA-Z0-9]*" }, { prefix + "$$$rand.12345$", prefix + "\\$[0-9]{5}" }, @@ -50,8 +49,8 @@ public void setUp() throws Exception { when(mdn.getMessage()).thenReturn(message); when(message.getPartnership()).thenReturn(partnership); when(mdn.getPartnership()).thenReturn(partnership); - when(partnership.getReceiverID(eq(AS2Partnership.PID_AS2))).thenReturn(receiverId); - when(partnership.getSenderID(eq(AS2Partnership.PID_AS2))).thenReturn(senderId); + when(partnership.getReceiverID(eq(Partnership.PID_AS2))).thenReturn(receiverId); + when(partnership.getSenderID(eq(Partnership.PID_AS2))).thenReturn(senderId); Properties.setProperty(Properties.APP_BASE_DIR_PROP, homeValue); } diff --git a/Server/src/test/resources/OpenAS2ServerTest/OpenAS2A/config/partnerships.xml b/Server/src/test/resources/OpenAS2ServerTest/OpenAS2A/config/partnerships.xml index 8a763fdc..d8123e84 100644 --- a/Server/src/test/resources/OpenAS2ServerTest/OpenAS2A/config/partnerships.xml +++ b/Server/src/test/resources/OpenAS2ServerTest/OpenAS2A/config/partnerships.xml @@ -21,7 +21,7 @@ + value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, $attribute.sign$"/> diff --git a/Server/src/test/resources/OpenAS2ServerTest/OpenAS2B/config/partnerships.xml b/Server/src/test/resources/OpenAS2ServerTest/OpenAS2B/config/partnerships.xml index c9563d7e..05a3a894 100644 --- a/Server/src/test/resources/OpenAS2ServerTest/OpenAS2B/config/partnerships.xml +++ b/Server/src/test/resources/OpenAS2ServerTest/OpenAS2B/config/partnerships.xml @@ -20,7 +20,7 @@ + value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, $attribute.sign$"/> diff --git a/Server/src/test/resources/SingleServerTest/OpenAS2A/config/partnerships.xml b/Server/src/test/resources/SingleServerTest/OpenAS2A/config/partnerships.xml index bda31169..732a8ff0 100644 --- a/Server/src/test/resources/SingleServerTest/OpenAS2A/config/partnerships.xml +++ b/Server/src/test/resources/SingleServerTest/OpenAS2A/config/partnerships.xml @@ -21,7 +21,7 @@ + value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, $attribute.sign$"/> diff --git a/changes.txt b/changes.txt index 07a531ff..fb1f319b 100644 --- a/changes.txt +++ b/changes.txt @@ -1,3 +1,24 @@ +Version 2.5.0 - 2018-07-02 +This is an enhancement and bugfix release: + IMPORTANT NOTE: Please review upgrade notes in the RELEASE-NOTES.md if you are upgrading + + 1. Supports Java 7 and up. Java 6 (Java 1.6) is no longer supported. + 2. Provide "log" command to dynamically alter logging levels in real time without restarting the application. + 3. Rationalize MDN sending so that Synchronous and Asynchronous are processed by a single module. NB See upgrade notes for class name change. + 4. Move HTTP header folding removal to HTTPUtils for centralised management + 5. Make the HTTP "User-Agent" header configurable via a property. + 6. Default "Message-Id" format complies with https://www.ietf.org/rfc/rfc2822.txt section 3.6.4. + 7. Provide ability to configure emails for successfully received and sent files. + 8. Upgrade libraries to the latest release. + 9. Support using system environment variables in config.xml + 10. Change attribute name for overriding Message-ID format at partnership level to match name at system level. NB See upgrade notes for attribute name change. + 11. Allow modules to have scheduled tasks using the HasSchedule implementation. + 12. Add scheduled task to detect failed sent messages where files are not cleaned up. (Fixes https://sourceforge.net/p/openas2/tickets/5/) + 13. Allow attributes in partnership element to reference other partnership elements and resolve the references at load time. + 14. Default sample in partnerships.xml for "as2_mdn_options" to use the "sign" attribute value for the micalg value. + 15. Support AS2 ID with spaces in the value. + + Version 2.4.3 - 2017-10-20 This is a minor bugfix release: IMPORTANT NOTE: Please review upgrade notes below if you are upgrading diff --git a/pom.xml b/pom.xml index 47ee798b..8e39c868 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 net.sf.openas2 OpenAS2 - 2.5.0-SNAPSHOT2 + 2.5.0 OpenAS2 pom