================================================
RTI Connext Hello_banish Example Application
================================================

Welcome to Connext! This example demonstrates the APIs
DDS_DomainParticipant_get_discovered_participant_subject_name,
DDS_DomainParticipant_get_discovered_participants_from_subject_name,
and DDS_DomainParticipant_banish_ignored_participants. You can read more about
these APIs in the Security Plugins User's Manual chapter called "Relevant
Connext APIs".


Compiling this Example
======================
You must set the environment variable NDDSHOME to your Connext
installation directory.

To build this example on a Windows platform, open the appropriate solution
file for your version of Microsoft Visual Studio in the win32 directory. Select
from the configuration pull-down menu: Debug, Release, Debug OpenSSL 1,
Release OpenSSL 1, Debug DLL, or Release DLL, where "DLL" is for dynamic
linking. By default, the OpenSSL version 3 crypto library is used. To use the
OpenSSL version 1 crypto library, select one of the "OpenSSL 1" configurations.

To build this example for a QNX platform, you must set the environment variables QNX_HOST
and QNX_TARGET. For example:

setenv QNX_BASE /opt/qnx660
setenv QNX_HOST ${QNX_BASE}/host/linux/x86
setenv QNX_TARGET ${QNX_BASE}/target/qnx6

To build this example on a Linux or macOS system, type the following in a command
shell:

  > make -f make/makefile_HelloWorld_<architecture>

This example is not supported on Android architectures.

All combinations of static/dynamic libraries and release/debug libraries are
supported. The dynamic libraries use the QoS profile for specifying the security plugin, and
the static libraries use code for that. Static/release is the default.
To use dynamic libraries, run:

 > make -f make/makefile_HelloWorld_<architecture> SHAREDLIB=1

To use debug libraries, run:

 > make -f make/makefile_HelloWorld_<architecture> DEBUG=1

By default, the OpenSSL version 3 crypto library is used. To use the OpenSSL
version 1 crypto library (which is required for RedHawk architectures), run:

> make -f make/makefile_HelloWorld_<architecture> OPENSSL1=1

or

> make -f make/makefile_HelloWorld_<architecture> CRYPTO_LIB=OPENSSL1

To use the wolfSSL crypto library, run:

> make -f make/makefile_HelloWorld_<architecture> WOLFSSL=1

or

> make -f make/makefile_HelloWorld_<architecture> CRYPTO_LIB=WOLFSSL

You can use the wolfSSL crypto library if your Connext installation includes the
Security Plugins for wolfSSL.

Running this Example
====================

Linux and macOS systems
-----------------------
If you are using dynamic libraries, your LD_LIBRARY_PATH must include
$NDDSHOME/lib/<architecture>.

You must also include the path to your crypto library. If you are compiling
against the Security Plugins with OpenSSL, your LD_LIBRARY_PATH must include
$NDDSHOME/third_party/openssl-<version>/<architecture>/<release or debug>/lib
(location of libcrypto.so).
If you are compiling against the Security Plugins for use with wolfSSL, your
LD_LIBRARY_PATH must include $NDDSHOME/third_party/wolfssl-<version>/<architecture>/<release or debug>/lib
(location of libwolfssl.so).

If you are compiling for wolfSSL, your LD_LIBRARY_PATH must also include the
path to the Security Plugins for wolfSSL libraries (libnddssecurity.so). Add
$NDDSHOME/lib/<architecture>/wolfssl-<version>/ to your LD_LIBRARY_PATH. Make
sure to add this before the path to the general libraries
($NDDSHOME/lib/<architecture>). Otherwise, your application may attempt to load
the default Security Plugins for OpenSSL library.

To run this example, type the following commands in two different command shells (one command in each shell), either
on the same machine or on different machines:

  > objs/<architecture>/HelloWorld_subscriber
  > objs/<architecture>/HelloWorld_publisher

Windows systems
---------------
If you are using dynamic libraries, your PATH must include
%NDDSHOME%\lib\<architecture> and %NDDSHOME%\third_party\openssl-<version>\<architecture>\<release or debug>\bin
(location of the libcrypto DLL).

To run this example, type the following commands in two different command shells (one command in each shell), either
on the same machine or on different machines:

  > objs\<architecture>\HelloWorld_subscriber.exe
  > objs\<architecture>\HelloWorld_publisher.exe

VxWorks Kernel Mode
-------------------
In case the application is linked dynamically (using SHAREDLIB=1 when compiling the example with make),
run these commands to load the Connext libraries:
  -> ld 1 < <NDDSHOME>/lib/<architecture>/libnddscore.so
  -> ld 1 < <NDDSHOME>/lib/<architecture>/libnddsc.so
  -> ld 1 < <NDDSHOME>/lib/<architecture>/libnddssecurity.so

Then load the publisher and subscriber modules:
  -> ld 1 < objs/<architecture>/HelloWorld_publisher.so
  -> ld 1 < objs/<architecture>/HelloWorld_subscriber.so

If you compiled the pubsub single DKM (using the "pubsub" argument when calling make), load it instead:
  -> ld 1 < objs/<architecture>/HelloWorld_pubsub.so

Before running the publisher and subscriber, make sure that your current working
directory is in the hello_banish folder. This directory must contain the USER_QOS_PROFILES.xml. Otherwise,
the publisher and subscriber won't be able to read the example QoS profiles. Also, take into account
that the USER_QOS_PROFILES.xml relies on files under <rti_workspace>/examples/dds_security being relative paths, so make
sure the location is available in your target.
Spawn the corresponding kernel tasks with the following commands:
  -> taskSpawn "Publisher", 100, 0x01000000, <stack_size>, publisher_main, <domain_id>, <sample_count>, <profile>
  -> taskSpawn "Subscriber", 100, 0x01000000, <stack_size>, subscriber_main, <domain_id>, <sample_count>, <profile>

VxWorks RTP Mode
----------------
If the example was dynamically linked, the Connext libraries must be
available in the VxWorks target so LD_LIBRARY_PATH can point to it,
along with any system libraries from the VSB (such as libc.so.1). Before
running the example make sure you set the LD_LIBRARY_PATH:
  -> putenv "LD_LIBRARY_PATH=<path_to_ndds_libraries>;<path_to_system_libraries>"

Run the examples from the hello_banish folder so the provided USER_QOS_PROFILES.xml
file is used. Also, take into account that the USER_QOS_PROFILES.xml relies on
files under <rti_workspace>/examples/dds_security being relative paths, so make
sure the location is available in your target.
  -> cmd rtp exec objs/<architecture>/HelloWorld_publisher.vxe -- <domain_id> <sample_count> <profile>
  -> cmd rtp exec objs/<architecture>/HelloWorld_subscriber.vxe -- <domain_id> <sample_count> <profile>

Accepted parameters
-------------------
This example is a modified version of an rtiddsgen generated HelloWorld application.
It has been modified to use security profiles. On the publisher side, the first
two parameters are the domain ID and sample count, just like the hello_world example.
On the subscriber side, the first parameter is the domain ID. This example uses
ECDSA-ECDH.
On the subscriber side, to run this example using peer03, the third
command-line argument should be "C".

Demonstrating banish_ignored_participants and InstanceHandle-to-Subject-Name conversions
----------------------------------------------------------------------------------------
The example uses a scripted set of actions in order to demonstrate the APIs.
If you prefer to choose your own set of actions, you can uncomment this line in
HelloWorld_publisher.c:

/* #define RTI_INTERACTIVE_MODE */

The following steps are suggested for the demonstration:

1. Run objs/x64Linux4gcc7.3.0/HelloWorld_subscriber <domainId>
2. Run objs/x64Linux4gcc7.3.0/HelloWorld_subscriber <domainId> <sampleCount> C
3. Run objs/x64Linux4gcc7.3.0/HelloWorld_publisher <domainId>
4. Type "2" to print discovered subject names.

Output if using OpenSSL:
    C = US, ST = CA, O = Real Time Innovations, CN = RTI ECDSA01 (p256) PEER03, emailAddress = ecdsa01Peer03@rti.com
    C = US, ST = CA, O = Real Time Innovations, CN = RTI ECDSA01 (p256) PEER01, emailAddress = ecdsa01Peer01@rti.com
    Writing HelloWorld Secure, count 1
    Writing HelloWorld Secure, count 2
    Writing HelloWorld Secure, count 3
    Writing HelloWorld Secure, count 4
    Options:
    0: continue
    1: exit
    2: print discovered subject names
    3: ignore participants with a specific subject name
    4: banish ignored participants

5. Type "3".

You will see this prompt:
    enter the subject name of the participants you want to ignore

6. Let's imagine that the application somehow gets notified by some CA-like entity that "PEER03" is no longer trustworthy. So now, copy-paste "C = US, ST = CA, O = Real Time Innovations, CN = RTI ECDSA01 (p256) PEER03, emailAddress = ecdsa01Peer03@rti.com".

Output:
    ignored 1 participants with subject name C = US, ST = CA, O = Real Time Innovations, CN = RTI ECDSA01 (p256) PEER03, emailAddress = ecdsa01Peer03@rti.com

    Writing HelloWorld Secure, count 5
    Writing HelloWorld Secure, count 6
    Writing HelloWorld Secure, count 7
    Writing HelloWorld Secure, count 8
    Options:
    0: continue
    1: exit
    2: print discovered subject names
    3: ignore participants with a specific subject name
    4: banish ignored participants

At this point, both subscribers still receive data because they're on the same multicast address. We need to do a banish to truly take out the ignored participant.

7. Type "4".

Output:
    Writing HelloWorld Secure, count 9
    Writing HelloWorld Secure, count 10
    Writing HelloWorld Secure, count 11
    Writing HelloWorld Secure, count 12
    Options:
    0: continue
    1: exit
    2: print discovered subject names
    3: ignore participants with a specific subject name
    4: banish ignored participants

The "C" subscriber output:
    ERROR [0xE996155C,0x994E3471,0x0A31A5C6:0x000001C1{Domain=12}|DECODE RTPS message from 0xD284C6E5,0x5BF53ACE,0xE3452571:0x000001C1|LC:Security]RTI_Security_Cryptography_decode_rtps_message:{"DDS:Security:LogTopicV2":{"f":"10","s":"1","t":{"s":"1656027341","n":"830317998"},"h":"bld-ubuntu1804","i":"0.0.0.0","a":"RTI Secure DDS Application","p":"22330","k":"33554496","x":[{"DDS":[{"domain_id":"12"},{"guid":"E996155C.994E3471.0A31A5C6.000001C1"},{"plugin_class":"DDS:Crypto:AES-GCM-GMAC"},{"plugin_method":"RTI_Security_Cryptography_decode_rtps_message"}]}],"m":"getDecryptCryptoState"}}

The non-"C" subscriber output:
    Received data:

       msg: "Hello World Secure (9)"
    Received data:

       msg: "Hello World Secure (10)"
    Received data:

       msg: "Hello World Secure (11)"
    HelloWorld subscriber sleeping for 4 sec...
    Received data:

       msg: "Hello World Secure (12)"

Note that there's no change in SubscriptionMatched count. For the non-"C"
subscriber, we do not see

    subscription matched count changed by -1. Current count: 0
    subscription matched count changed by 1. Current count: 1

That's because the banishing process is seamless. The publisher didn't have to
delete and recreate its participant in order to regenerate and redistribute key
material.

Note that if using wolfSSL, the printed subject names look different:
    /C=US/ST=CA/O=Real Time Innovations/CN=RTI ECDSA01 (p256) PEER03/emailAddress=ecdsa01Peer03@rti.com
    /C=US/ST=CA/O=Real Time Innovations/CN=RTI ECDSA01 (p256) PEER01/emailAddress=ecdsa01Peer01@rti.com

Troubleshooting this Example
============================
If you see the following error:

Cryptography_encrypt:error:0607B083:lib(6):func(123):reason(131)

you are likely linking against an older version of OpenSSL. You need version
1.0.1c or later.

For more information, please consult the "RTI Security Plugins Getting Started
Guide".
