Join us on LinkedIn Read our Blog

X.400 C API - Example Applications

Application Features

These examples do the following using the X.400 C API

  • submit X.400 messages
  • retrieve X.400 messages
  • retrieve delivery reports
  • retrieve IPNs

You can use the same application to submit/retrieve using either P3 or P7, by passing the appropriate argument into X400msOpen().

Note that (mostly) the examples used in this text will work with the values configured by the x400config program. The exceptions are:

  • the Organization in O/R addresses (which should be replaced by the hostname of the system running the MTA)
  • the IP address/hostname in Presentation Addresses
Full specification of the C API is here

Compatibility with quickconfig

The default values used in the applications and used here are designed to work as straightforwardly as possible with the configuration created by the quickconfig program. In particular the following users

P7 User to submit and retrieve messages via the Message Store:

 O/R Address:/CN=P7User1/OU=Sales/O=<hostname>/PRMD=TestPRMD/ADMD=TestADMD/C=<country>/
      Password: secret
      

P7 User to retrieve messages via the Message Store:

 O/R Address:/CN=P7User2/OU=Sales/O=<hostname>/PRMD=TestPRMD/ADMD=TestADMD/C=<country>/
Password:secret
      

P3 User to submit and retrieve messages via the MTA's P3 channel

O/R Address: /CN=P3User1/OU=Sales/O=<hostname>/PRMD=TestPRMD/ADMD=TestADMD/C=<country>/
Password: p3secret

Where <hostname> is the short hostname of the system on which the MTA is running. And <country> is the country code being used.

Compiling the Applications

To build the applications an example Makefile is supplied. On Linux run the command

# make -f Makefile.sdk.unix

Configuring the Applications

A set of common utilities for the applications is in x400_common.c. The rest of this text describes how to configure the Session object using the set_defaults() functions.

x400_common.c:void set_defaults(IFP intfunc, IFP strfunc, void* sp);

The applications call this function as follows:

set_defaults(X400msSetIntDefault, X400msSetStrDefault, (void*)sp);

You must call this after the Session object has been initialised using X400msOpen(). (Note that you can use any way of configuring these value you wish - but you must set the values in the Session object after calling X400msOpen() using X400msSetIntDefault,X400msSetStrDefault).

Submission via the Message Store (P7)

To connect to the Message Store you need:

  • Presentation Address of the Store
  • P7 Credentials (simple)
    • Password
    • O/R Name
      • Directory Name (optional)
      • O/R address

The Presentation Address of the Message Store, which includes the Internet address of the machine where it is running is held in the directory server. Use EMMA to check the value used by your Message Store.

x400_ms_address:\"3001\"/Internet=<hostname>+3001

The Credentials of the Message Store User,comprise an O/RName (DN and O/R address) and a password. Check in EMMA the value used by your Message Store User.

The following entries are used to configure credentials

x400_ms_user_addr: /CN=P7User1/OU=Sales/O=<hostname>/PRMD=TestPRMD/ADMD=TestADMD/C=<country>/
x400_ms_user_dn:"cn=fred,c=gb"

The password of the user that is binding to the Message Store to send or receive messages must be entered on the command line. You can check the user's password by editing its properties in EMMA.

The example P7 submission application is X400_mssend.c

The only value you must configure is the recipient to which the message will be sent. Make sure that the user referred to in the recip variable exists and the MTA knows how to route a message to recip. Use ckadr-x"<O/R address>" to check the O/R address.

Retrieval from the Message Store (P7)

This works in the same way as for Submission. The example P7 retrieval application is X400_msrcv.c

Generating and Verifying Cryptographic Signatures

The P3 and P7 API supports the generation of message signatures and their verification. There is support for two different forms of signatures which provide three X.400 services.

Types of signature:

  • Message Origin Authentication Check (which provides Originator Authentication
  • Message Token (which provides Content Integrity and Message Sequence Integrity

MOACs are per message signatures, whereas Message Tokens are per recipient.

To use this feature of the API, you need to do two things:

  • Configure a Security Environment for the application
  • Set the security attributes within the application

X.400 API Security Environment

There are three parts to configuring your Security Environment

  • Security ID
  • The specifies a pathname in which there is n x509 subdirectory which contains your PKCS12 files which contain your certificate and private key

  • Identity DN
  • This is the DirectoryName which is the Subject of the Certificate in the PKCS12 file you wish to use for signing messages. (NB - currently you also need a PKCS12 to initialise the X.509 subsystem when verifying messages).

  • Passphrase
  • The Passprase protecting the private key in the PKCS12 file. NB the need for this attribute can be removed by creating a file in the same directory as your PKCS12 file with the same name and the pphr suffix. This file must contain the passphrase with no CR or LF.

To set the above values use the following attributes
  • X400_S_SEC_IDENTITY (using X400msSetStrDefault)
  • X400_S_SEC_IDENTITY_DN (using X400msSetStrDefault)
  • X400_S_SEC_IDENTITY_PASSPHRASE (using X400msSetStrDefault)

NB you can also set a different security environment by recipient or message by using X400msRecipAddStrParam() or X400msMsgAddStrParam() respectively. This might be required when a message or recipient requires a different PKCS12 file for signing. This has no relevance when verifying, when the default (per session) Security Environment is always used.

When signing failures are identified by the return values from X400msMsgSend().

For verification, a richer set of values can be returned using X400msRecipGetIntParam() and X400msRecipGetStrParam(). A certificate object can also be returned using X400RecipGetCert() and X400msMsgGetCert() for certificates provided by the originator to verify the signature of the Message Token and MOAC respectively.

The following example applications are provided which illustrate how to generate and verify signed messages.

  • x400_mssend_sign.c
  • This sends a message with a MOAC

  • x400_msrcv_sign.c
  • This receives a message and displays information about the MOAC

  • x400_mssend_msg_tok_sign.c
  • This sends a message with a Message Token

  • x400_msrcv_msg_tok_sign.c
  • This receives a message and displays information about the Message Token

Running the Applications

Unix

To run the applications you simply run the executable from the command line. No arguments are required.

Submitting a message:

[root@dhcp-164 c]# ./x400_mssend
Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [0]: 
Your ORAddress [/CN=P7User2/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/] > 
Password [secret]: 
Presentation Address ["3001"/Internet=dhcp-164.isode.net+3001] > 
Message recipient [/CN=P7User2/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/]: 
Subject [A Test Message from X.400 C API]: 
message priority is 0 ( 0 - normal, 1 - non-urgent, 2 - urgent)
military message priority is 0 ( 0 - low, 1 - high)
no binary file set - not sending X400_T_BINARY
no binary file set - not sending forwarded BP
Message submitted successfully

Retrieving a message:

[root@dhcp-164 c]# ./x400_msrcv 
Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [0]: 
Your ORAddress [/CN=P7User2/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/] >
Password [secret]: 
Presentation Address ["3001"/Internet=dhcp-164.isode.net+3001] >
Registered AutoAlert autoaction (id = 10) OK 
Deregistered AutoAlert autoaction (id = 10) OK 
1 messages waiting
Getting message
MsgGet successfully got message 
Message Identifier: [/PRMD=TestPRMD/ADMD=TestADMD/C=GB/;dhcp-164.i.0426701-080216.193428] 
Originator: /CN=P7User2/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/
There are 1 recipients
Envelope Recipient 1: /CN=P7User2/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/
Primary Recipient 1: /CN=P7User2/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/
There is no Redirection History 
Subject: A Test Message from X.400 C API
Number of attachments is 2
Get attachment 1
got complex bodypart
Get Bodypart 1
got Bodypart 1, type = 407
got Bodypart 1, type = General Text
got 25 bytes of Bodypart data
Printable Data for BP is:
 First line
Second line
Get attachment 2
got text or binary attachment
Printable Data for BP is:
 First line
Second line
[root@dhcp-164 c]# 

Windows

To aid in submitting and receiving messages the example programs have been pre-compilied by Isode. These example programs are located within $(BINDIR) typically C:\Program Files\Isode\bin These example programs work in the same way as their unix counterparts, and are compilied from the same code.

Submission directly to the MTA (P3)

Configuration of P3 Submission is similar to P7. You need to configure

  • Presentation Address of the MTA's P3 channel
  • P3 Credentials (simple)
    • Password
    • O/R Name
      • Directory Name (optional)
      • O/R address
      x400_mta_address:\"593\"/Internet=<hostname>
      x400_mta_user_name:"cn=P3User1;c=gb $ /CN=P7User1/OU=Sales/O=<hostname>/PRMD=TestPRMD/ADMD=TestADMD/C=<country>/"
      

Note that, unlike P7, the O/R name is configured as a single value with an DN and O/R Address separated by a "$" (rather than separate DN and O/R address)

To make the X400_mssend.c application use P3, you need only change the argument to the X400msOpen()function. Configure the recipient in the same way as for P7.

Retrieval directly from the MTA (P3)

This works in the same way as for P3 Submission. The example P3 submission application is X400_msrcv.c

Running the Applications

To run the applications you simply run the executable from the command line. No arguments are required.

Submitting a message:

Unix

[root@dhcp-164 c]# ./x400_mssend
Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [0]: 1
Your ORAddress [/CN=P3User1/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/] > 
Password [p3secret]: 
Presentation Address ["593"/Internet=dhcp-164.isode.net] > 
Message recipient [/CN=P7User2/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/]: 
Subject [A Test Message from X.400 C API]: 
message priority is 0 ( 0 - normal, 1 - non-urgent, 2 - urgent)
military message priority is 0 ( 0 - low, 1 - high)
no binary file set - not sending X400_T_BINARY
no binary file set - not sending forwarded BP
Message submitted successfully

Retrieving a message:

[root@dhcp-164 c]# ./x400_msrcv 
Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [0]: 2
Your ORAddress [/CN=P3User1/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/] > 
Password [p3secret]: 
Presentation Address ["593"/Internet=dhcp-164.isode.net] > 
1 messages waiting
Getting message
MsgGet successfully got message
Message Identifier: [/PRMD=TestPRMD/ADMD=TestADMD/C=GB/;dhcp-164.i.0516701-080216.202106]
Originator: /CN=P3User1/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/
There are 1 recipients
Envelope Recipient 1: /CN=P3User1/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/
Primary Recipient 1: /CN=P3User1/OU=Sales/O=dhcp-164/PRMD=TestPRMD/ADMD=TestADMD/C=GB/
There is no Redirection History
Subject: A Test Message from X.400 C API
Number of attachments is 2
Get attachment 1
got complex bodypart
Get Bodypart 1
got Bodypart 1, type = 407
got Bodypart 1, type = General Text
got 25 bytes of Bodypart data
Printable Data for BP is:
 First line
Second line
Get attachment 2
got text or binary attachment
Printable Data for BP is:
 First line
Second line

Windows

To aid in submitting and receiving messages the example programs have been pre-compilied by Isode. These example programs are located within $(BINDIR) typically C:\Program Files\Isode\bin These example programs work in the same way as their unix counterparts, and are compilied from the same code.