GithubHelp home page GithubHelp logo

holodeck-b2b / hb2b-as2 Goto Github PK

View Code? Open in Web Editor NEW
6.0 3.0 1.0 342 KB

An extension for Holodeck B2B to support message exchanges using the AS2 protocol

License: GNU General Public License v3.0

Java 100.00%
as2 rfc4130 edelivery

hb2b-as2's Introduction

Holodeck B2B

Holodeck B2B is a standalone B2B messaging solution. This project includes support for the OASIS specifications for ebMS3 and the AS4 profile. Java based, it will run on most platforms.

It is designed with extensibility in mind providing an interface layer (API) which you can find in the Interfaces module, and lots of documentation inside the code.


For more information on using Holodeck B2B visit the website at http://holodeck-b2b.org
Lead developer: Sander Fieten
Code hosted at https://github.com/holodeck-b2b/Holodeck-B2B
Issue tracker https://github.com/holodeck-b2b/Holodeck-B2B/issues

Installation

Prerequisites

Java 8 or higher is required to run Holodeck B2B.

Getting started guide

To help you set up your first instance of Holodeck B2B, you will find a step-by-step guide to setting up Holodeck B2B on the project website.

Contributing

We are using the simplified Github workflow to accept modifications which means you should:

  • create an issue related to the problem you want to fix or the function you want to add (good for traceability and cross-reference)
  • fork the repository
  • create a branch (optionally with the reference to the issue in the name)
  • write your code, including comments
  • commit incrementally with readable and detailed commit messages
  • run integration tests to check everything works on runtime
  • Update the changelog with a short description of the changes including a reference to the issues fixed
  • submit a pull request against the 'next' branch of this repository

If your contribution is more than a patch, please contact us beforehand to discuss which branch you can best submit the pull request to.

Submitting bugs

You can report issues directly on the project Issue Tracker. Please document the steps to reproduce your problem in as much detail as you can (if needed and possible include screenshots).

Versioning

Version numbering follows the Semantic versioning approach.

License

The Holodeck B2B core is licensed under the General Public License V3 (GPLv3) which is included in the license.txt in the root of the project. This means you are not allowed to integrate Holodeck B2B in a closed source product. You can however use Holodeck B2B together with your closed source product as long as you only use the provided interfaces (API's) to communicate with the Holodeck B2B core. For this purpose, the interfaces module is licensed under the Lesser General Public License V3 (LGPLv3).

To implement the cryptographic algorithms Holodeck B2B uses the Bouncy Castle library provided by The Legion of the Bouncy Castle Inc., see the bc_license.txt file.

Support

Commercial Holodeck B2B support is provided by Chasquis. Visit Chasquis-consulting.com for more information.

hb2b-as2's People

Contributors

holodeck-b2b avatar renates avatar sfieten avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

mikeurs

hb2b-as2's Issues

Logging in/out messages

I'm trying to implement Holodeck AS2, but I cannot see any incoming and outgoing messages in logs (as in AS4 they go to soap_out.log and soap_in.log). With out this logs it is very difficult to test connection.
Is there some setting I should use and is not described in README.md/SetUp?

Outgoing signed MDN is missing MIME body part with signature

When Holodeck replies to an incoming message with a signed MDN required, the whole body part with the signature seems to be missing, which results in a failure within the third party AS2 software receiving this MDN.

Here's the incoming HTTP traffic on recipients side (http wire log):

http-outgoing-4 << "HTTP/1.1 200 OK[\r][\n]"
http-outgoing-4 << "date: Thu, 13 Jan 2022 17:32:48 +0100 (CET)[\r][\n]"
http-outgoing-4 << "message-id: <ff4a410f-ac1b-42ec-ae62-0314b129f5d0@h-3fd9f07440a52c22.3fd9e12bf13ce588>[\r][\n]"
http-outgoing-4 << "as2-to: party1[\r][\n]"
http-outgoing-4 << "as2-from: party2[\r][\n]"
http-outgoing-4 << "subject: MDN for message: party1_5_1642091564456@party2[\r][\n]"
http-outgoing-4 << "original-message-id: party1_5_1642091564456@party2[\r][\n]"
http-outgoing-4 << "Transfer-Encoding: chunked[\r][\n]"
http-outgoing-4 << "Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-512; [\r][\n]"
http-outgoing-4 << "[0x9]boundary="----=_Part_31_1636597266.1642091575797"[\r][\n]"
http-outgoing-4 << "Connection: Keep-Alive[\r][\n]"
http-outgoing-4 << "[\r][\n]"
http-outgoing-4 << "245[\r][\n]"
http-outgoing-4 << "------=_Part_31_1636597266.1642091575797[\r][\n]"
http-outgoing-4 << "Content-Type: multipart/report; report-type=disposition-notification; [\r][\n]"
http-outgoing-4 << "[0x9]boundary="----=_Part_30_1249395444.1642091568534"[\r][\n]"
http-outgoing-4 << "[\r][\n]"
http-outgoing-4 << "------=_Part_30_1249395444.1642091568534[\r][\n]"
http-outgoing-4 << "Content-Type: text/plain[\r][\n]"
http-outgoing-4 << "Content-Transfer-Encoding: 7bit[\r][\n]"
http-outgoing-4 << "[\r][\n]"
http-outgoing-4 << "This is an automatically generated MDN for the AS2 message[message-id:<party1_5_1642091564456@party2>] received from party1.[\r][\n]"
http-outgoing-4 << "[\r][\n]"
http-outgoing-4 << "The message was processed successfully.[\r][\n]"
http-outgoing-4 << "[\r][\n]"
http-outgoing-4 << "------=_Part_30_1249395444.1642091568534[\r][\n]"
http-outgoing-4 << "Content-Type: message/disposition-notification[\r][\n]"
http-outgoing-4 << "Content-Transfer-Encoding: 7bit[\r][\n]"
http-outgoing-4 << "[\r][\n]"
http-outgoing-4 << "[\r][\n]"
http-outgoing-4 << "0[\r][\n]"
http-outgoing-4 << "[\r][\n]"

Note at the bottom, that there is no content within the message/disposition-notification part.

This seems to be caused within MDNInfo:334:

reportPart.setContent(reportPartContent.toString(), Constants.MDN_DISPOSITION_MIME_TYPE);

Out of curiosity, I changed the type to MIME_PLAIN_TEXT. I'm not familiar with the MIME API though and not sure, if this is the correct fix to apply:

reportPart.setContent(reportPartContent.toString(), MIME_PLAIN_TEXT);

This fixes the missing MIME body, the resulting HTTP now looks like this and can be processed by the third party software:

http-outgoing-5 << "HTTP/1.1 200 OK[\r][\n]"
http-outgoing-5 << "date: Thu, 13 Jan 2022 17:38:01 +0100 (CET)[\r][\n]"
http-outgoing-5 << "message-id: <575a3e72-23c4-44da-8303-b1655403b61c@h-3fe6f1877f99f381.3fcb43698190a908>[\r][\n
http-outgoing-5 << "as2-to: party1[\r][\n]"
http-outgoing-5 << "as2-from: party2[\r][\n]"
http-outgoing-5 << "subject: MDN for message: party1_6_1642091880580@party2[\r][\n]"
http-outgoing-5 << "original-message-id: party1_6_1642091880580@party2[\r][\n]"
http-outgoing-5 << "Transfer-Encoding: chunked[\r][\n]"
http-outgoing-5 << "Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-512; [\r][
http-outgoing-5 << "[0x9]boundary="----=_Part_1_944891477.1642091881210"[\r][\n]"
http-outgoing-5 << "Connection: Keep-Alive[\r][\n]"
http-outgoing-5 << "[\r][\n]"
http-outgoing-5 << "82b[\r][\n]"
http-outgoing-5 << "------=_Part_1_944891477.1642091881210[\r][\n]"
http-outgoing-5 << "Content-Type: multipart/report; report-type=disposition-notification; [\r][\n]"
http-outgoing-5 << "[0x9]boundary="----=_Part_0_914351271.1642091881190"[\r][\n]"
http-outgoing-5 << "[\r][\n]"
http-outgoing-5 << "------=_Part_0_914351271.1642091881190[\r][\n]"
http-outgoing-5 << "Content-Type: text/plain[\r][\n]"
http-outgoing-5 << "Content-Transfer-Encoding: 7bit[\r][\n]"
http-outgoing-5 << "[\r][\n]"
http-outgoing-5 << "This is an automatically generated MDN for the AS2 message[message-id:<party1_6_16420918805
http-outgoing-5 << "[\r][\n]"
http-outgoing-5 << "The message was processed successfully.[\r][\n]"
http-outgoing-5 << "[\r][\n]"
http-outgoing-5 << "------=_Part_0_914351271.1642091881190[\r][\n]"
http-outgoing-5 << "Content-Type: message/disposition-notification[\r][\n]"
http-outgoing-5 << "Content-Transfer-Encoding: 7bit[\r][\n]"
http-outgoing-5 << "[\r][\n]"
http-outgoing-5 << "Reporting-UA:host.docker.internal;HolodeckB2B 5.3.1[\r][\n]"
http-outgoing-5 << "Final-Recipient:as2;party1[\r][\n]"
http-outgoing-5 << "Original-Message-ID:<party1_6_1642091880580@party2>[\r][\n]"
http-outgoing-5 << "Disposition:automatic-action/MDN-sent-automatically;processed[\r][\n]"
http-outgoing-5 << "Received-Content-MIC:+jZd8+RmIfRh3JkOuU4aD67Mi70G17N8a9TKrkxOFww=,sha-256[\r][\n]"
http-outgoing-5 << "[\r][\n]"
http-outgoing-5 << "------=_Part_0_914351271.1642091881190--[\r][\n]"
http-outgoing-5 << "[\r][\n]"
http-outgoing-5 << "------=_Part_1_944891477.1642091881210[\r][\n]"
http-outgoing-5 << "Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data[\r][\n]"
http-outgoing-5 << "Content-Transfer-Encoding: base64[\r][\n]"
http-outgoing-5 << "Content-Disposition: attachment; filename="smime.p7s"[\r][\n]"
http-outgoing-5 << "Content-Description: S/MIME Cryptographic Signature[\r][\n]"
http-outgoing-5 << "[\r][\n]"
http-outgoing-5 << "MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgMFADCABgkqhkiG9w0BBwEAADGCAj8w[\r][\n]"
http-outgoing-5 << "ggI7AgEBMFkwTDEMMAoGA1UECBMDTlJXMQswCQYDVQQGEwJERTESMBAGA1UEChMJU09QVElNIEFH[\r][\n]"
http-outgoing-5 << "MRswGQYDVQQDExJuYjAxMjIyLnNvcHRpbS5uZXQCCQCpUX933TKnmTANBglghkgBZQMEAgMFAKCB[\r][\n]"
http-outgoing-5 << "uDAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMjAxMTMxNjM4MDFa[\r][\n]"
http-outgoing-5 << "MC0GCSqGSIb3DQEJNDEgMB4wDQYJYIZIAWUDBAIDBQChDQYJKoZIhvcNAQENBQAwTwYJKoZIhvcN[\r][\n]"
http-outgoing-5 << "AQkEMUIEQH+I3FRITDjK/5/FlKDvnVbicEVA4OFoRyB+ouIiZIiL8HJXvQn03lSWzTDUj28K+dw/[\r][\n]"
http-outgoing-5 << "eaJREv/jmDSEyWJDvPwwDQYJKoZIhvcNAQENBQAEggEArfpSskDUp8T+YqfmTB8EsBPLUotDoh0L[\r][\n]"
http-outgoing-5 << "TqtgN1hZpAicZSL3Ye6o26Y0bvwS9PPZleumfyaAANi/ivO6QdPtQEIp/tCJ6jXB96EV+A9svjpZ[\r][\n]"
http-outgoing-5 << "IpmL8KkwEtDzaYcIgu2rrmeXuFk7iMfgiSExcRIZVP9WmzEcCYtJNQm7HwuT5fuwnBpwojx6KKs5[\r][\n]"
http-outgoing-5 << "lQpPxmVqOCTliLSi6TbcW9CQUg/4JlSu9DOut7T3qBgdM1R5QVbv8lXPBMO/7daOhRK584a3tNnE[\r][\n]"
http-outgoing-5 << "V4kuefczKh0P7Le8LWGNdqX8kZvGiFh68VtIu7ade5Zmlwb//jNx2avqgOTr1f5sUpbVu8Rjv7nM[\r][\n]"
http-outgoing-5 << "0pJUDwAAAAAAAA==[\r][\n]"
http-outgoing-5 << "------=_Part_1_944891477.1642091881210--[\r][\n]"
http-outgoing-5 << "[\r][\n]"
http-outgoing-5 << "0[\r][\n]"
http-outgoing-5 << "[\r][\n]"

AS2 MepBinding configuration

Hi!

I'm trying to set up a HolodeckB2B instance to send AS2 messages. From the readme:

To indicate that a P-Mode configures an AS2 message exchange the MEP Binding parameter must be set
http://holodeck-b2b.org/pmode/mepBinding/as2.

The link unfortonately gives me HTTP 404. I set my MEP and MEP Binding like this:

<mep>http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/oneWay</mep>
<mepBinding>http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/push</mepBinding>

This way however, Holodeck send my messages using AS4. How should I set up my P-mode, to use AS2?

(the as2 extension, to my best knowledge is installed)

Thanks,
Gergely

Edit:
Realized that the url is not some additional info about setting the MEP, but that should be the actual value of the setting. It works now!

Use disposition messages as specified in RFC4130

Currently if an error occurs in the processing of a received message a generic "Error: unexpected-processing-error" disposition message is included in the MDN. Although it correctly signals that the message couldn't be processed succesfully, it would be better to use the disposition message as described in section 7.4.3 of RFC4130.

HTTP headers are not checked case insensitively

Testing exchange with a third party AS2 software, we noticed that this extension does not check the HTTP headers case insensitively within GenericMessageInfo. So, exchange with any third party software sending headers like AS2-From or AS2-To is not supported, unless the headers are sent in lowercase.

ReadUserMessageInfo:

log.debug("Get the general message info of the User Message from msgCtx");
GenericMessageInfo generalInfo = (GenericMessageInfo) procCtx.getProperty(Constants.CTX_AS2_GENERAL_DATA);
        
// Check that at least the party ids of the sender and receiver are included in the message
final String fromId = generalInfo.getFromPartyId();
final String toId = generalInfo.getToPartyId();        
if (Utils.isNullOrEmpty(fromId) || Utils.isNullOrEmpty(toId)) {
   log.error("Received message does not contain AS2-To and/or AS2-From header(s)!"); // <---- ERROR is logged here

A potential fix (verified to work) is to put the HTTP headers into a TreeMap with a case insensitive comparator:

    public GenericMessageInfo(final Map<String, String> httpHeaders) {
        // If there are no HTTP headers, no information is avaible and an "empty" object is created
        if (Utils.isNullOrEmpty(httpHeaders))
            return;

        Map<String, String> caseInsensitiveHeaders = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        caseInsensitiveHeaders.putAll(httpHeaders);

        messageId = caseInsensitiveHeaders.get(MESSAGE_ID_HEADER);
        refToMessageId = caseInsensitiveHeaders.get(REF_TO_MESSAGE_ID_HEADER);
        try {
        	timestamp = new MimeDateParser(caseInsensitiveHeaders.get(TIMESTAMP_HEADER)).parse();
        } catch (NullPointerException | ParseException notaDate) {
            timestamp = null;
        }
        subject = caseInsensitiveHeaders.get(SUBJECT_HEADER);
        fromPartyId = caseInsensitiveHeaders.get(SENDER_ID_HEADER);
        toPartyId = caseInsensitiveHeaders.get(RECEIVER_ID_HEADER);
        originalRecipient = caseInsensitiveHeaders.get(ORIGINAL_RECIPIENT);
        finalRecipient = caseInsensitiveHeaders.get(FINAL_RECIPIENT);
    }

BUILD FAILURE

Failed to execute goal on project hb2b-as2: Could not resolve dependencies for project org.holodeckb2b:hb2b-as2:jar:1.1.1: The following artifacts could not be resolved: org.holodeckb2b:holodeckb2b-core:jar:4.1.1, org.holodeckb2b:holodeckb2b-security:jar:4.1.1: Could not find artifact org.holodeckb2b:holodeckb2b-core:jar:4.1.1 in central (https://repo.maven.apache.org/maven2)

PEPPOL AS2 conformance test

Hello.

I am trying to run the PEPPOL AS2 conformance test. I have received successfully a message, but when I am trying to send the same message back, all I get is TRANSPORT_FAILURE with no other error or indication. Probably this is not the right place to address the issue, but I have run out of ideas and any help will be valuable.

Thank you.

Request should write AS2-Version HTTP header

Although not required by the specification, applications conformant to AS2 version 1.0 or 1.1 should write this header to indicate this.

This extensions supports compression, so AS2-Version 1.1 should be reported. This is also noted in Constants.java:

/**
  * The AS2 version supported by this Holodeck B2B extension. Since compression is supported this should be 1.1
*/
public static final String AS2_VERSION = "1.1";

HTTP headers are not checked case insensitively in CheckMDNRequest

Testing exchange with a third party AS2 software, we noticed that this extension does not check the HTTP headers case insensitively within CheckMDNRequest. So, exchange with any third party software sending headers like AS2-From or AS2-To or Disposition-Notification-To, Disposition-Notification-Options, etc. is not supported, unless the headers are sent in lowercase.

Therefore, no MDN will be sent back to the sender when headers were not sent in lowercase.

Header processing CheckMDNRequest should be fixed like this (fix verified locally):

// Get the HTTP headers
final Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

//noinspection unchecked
headers.putAll((Map<String, String>) procCtx.getParentContext().getProperty(MessageContext.TRANSPORT_HEADERS));

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.