examples/x400_mssend_strong.c

This is an example program which submits a message either indirectly via the P7 Message Store or directly to the MTA's P3 responder. This program will use strong authentication using a supplied PKCS#12 file and a configured CA certificates directory.

/*
* Copyright (c) 2025-2026, Isode Limited, London, England.
* All rights reserved.
*
* Acquisition and use of this software and related materials for any
* purpose requires a written licence agreement from Isode Limited,
* or a written licence from an organisation licenced by Isode Limited
* to grant such a licence.
*/
/*
* @VERSION@
* Simple example program for submitting a message via a message store using strong
* authentication.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include "example.h"
#include "ms_example.h"
#include "time.h"
#include <errno.h>
#include <fcntl.h>
#include <seclabel_api.h> /* For security labels */
#include <x400_msapi.h>
static char *optstr = "u371m:d:p:w:M:D:P:W:o:O:r:l:R:y:C:iaqsAvf:kK:B:H:b:Y:U:";
/* These are the data items used to construct the message for submission */
static char *default_recip = "/CN=P7User1/O=attlee/PRMD=TestPRMD/ADMD=TestADMD/C=GB/";
char *recip;
static const char text[] = "First line\r\nSecond line\r\n";
static char *binary_data;
static char *fwd_subject = "Forwarded message subject";
static int add_binary_attachment(struct X400msMessage *mp, char *filename_to_send);
static int add_fwd_bp(struct X400msMessage *mp, char *recip_orn, char *recip_dn);
static int add_ftbp(struct X400msMessage *mp);
static void usage(void);
IC_CDECL int tokeniseMTAName(const char *MTAName, char **mtaName, char **gdi);
int main(int argc, char **argv) {
char pa[BUFSIZ];
char orn[BUFSIZ];
char tmp[BUFSIZ];
int status;
struct X400msSession *sp;
struct X400msMessage *mp;
struct X400Recipient *rp;
int contype;
char *def_oraddr;
char *def_dn;
char *def_pa;
if (get_args(argc, argv, optstr)) {
usage();
exit(-1);
}
printf("Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [%d]: ", x400_contype);
contype = ic_fgetc(x400_contype, stdin);
if (contype != 10) {
ic_fgetc(x400_contype, stdin);
}
if (contype < '0' || '2' < contype) {
contype = x400_contype;
}
else {
contype -= '0';
}
if (contype == 0) {
def_oraddr = x400_ms_user_addr;
def_dn = x400_ms_user_dn;
def_pa = x400_ms_presentation_address;
}
else {
def_oraddr = x400_mta_user_addr;
def_dn = x400_mta_user_dn;
def_pa = x400_mta_presentation_address;
}
printf("Your ORAddress [%s] > ", def_oraddr);
ic_fgets(orn, sizeof orn, stdin);
if ((strlen(orn) > 0) && (orn[strlen(orn) - 1] == '\n')) {
orn[strlen(orn) - 1] = '\0';
}
if (orn[0] == '\0') {
strcpy(orn, def_oraddr);
}
/* Presentation Address */
printf("Presentation Address [%s] > ", def_pa);
ic_fgets(pa, sizeof pa, stdin);
if ((strlen(pa) > 0) && (pa[strlen(pa) - 1] == '\n')) {
pa[strlen(pa) - 1] = '\0';
}
if (pa[0] == '\0') {
strcpy(pa, def_pa);
}
if (talking_to_marben_ms) {
}
// Build the strong credentials.
char *credentials = NULL;
if (x400_contype == 0) {
// P7 (UA->MS)
credentials =
X400msBuildCredentials(MS_BIND_STRONG_P7, passphrase, NULL, identity_filename, trusted_ca_certs_dir, x400_ms_user_addr, NULL, NULL);
}
else if (x400_contype == 1 || x400_contype == 2) {
// P3 (UA->MTA). 1 is submit only, 2 bidirectional.
char *mtaName = NULL;
char *mtaGdi = NULL;
tokeniseMTAName(x400_mtaname_gdi, &mtaName, &mtaGdi);
if (!mtaName || !mtaGdi) {
if (mtaName) {
free(mtaName);
}
if (!mtaGdi) {
free(mtaGdi);
}
fprintf(stderr, "Error parsing -H argument as 'MTA name;GDI': '%s'\n", x400_mtaname_gdi);
return 1;
}
credentials =
X400msBuildCredentials(MS_BIND_STRONG_P3, passphrase, NULL, identity_filename, trusted_ca_certs_dir, x400_mta_user_addr, mtaName, mtaGdi);
free(mtaName);
free(mtaGdi);
}
// We've got what we need - now open an API session.
status = X400msOpen(contype, orn, def_dn, credentials, pa, NULL, &sp);
free(credentials);
if (status != X400_E_NOERROR) {
fprintf(stderr, "Error in Open: %s\n", X400msError(status));
exit(status);
}
if (talking_to_marben_ms) {
}
// Setup logging.
/* Turn on generation of extended-subject heading extension */
/* Turn on error on duplicate string attribute setting */
/* Configure the character sets to be used for Teletex syntax fields
(X400_S_FREE_FORM_NAME, X400_T_TELETEX, X400_S_SUBJECT). If not
explicitly configured, the default set of 102, 103, 106, 107
will be assumed. The string below adds Cyrillic (8859-5) into the list. */
X400msSetStrDefault(sp, X400_S_TELETEX_CHARSETS, "102 103 106 107 144", -1);
/* Configure the character sets to be used for Graphic string syntax fields
(X400_S_FTBP_APPLICATION_REFERENCE_STR, X400_S_FTBP_CONTENT_DESCRIPTION,
X400_S_FTBP_FILENAME). If not explicitly configured, a default of
character set 6 (US-ASCII) will be assumed.
The string below adds Cyrillic (8859-5) into the list. */
if (x400_default_recipient != NULL) {
recip = x400_default_recipient;
}
else {
recip = default_recip;
}
printf("Message recipient [%s]: ", recip);
ic_fgets(tmp, sizeof tmp, stdin);
if ((strlen(tmp) > 0) && (tmp[strlen(tmp) - 1] == '\n')) {
tmp[strlen(tmp) - 1] = '\0';
}
if (strlen(tmp) != 0) {
recip = strdup(tmp);
}
printf("Subject [%s]: ", subject);
ic_fgets(tmp, sizeof tmp, stdin);
if ((strlen(tmp) > 0) && (tmp[strlen(tmp) - 1] == '\n')) {
tmp[strlen(tmp) - 1] = '\0';
}
if (strlen(tmp) != 0) {
subject = strdup(tmp);
}
status = X400msMsgNew(sp, X400_MSG_MESSAGE, &mp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgNew returned error: %s\n", X400msError(status));
exit(status);
}
status = X400msRecipNew(mp, X400_RECIP_STANDARD, &rp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipNew returned error: %s\n", X400msError(status));
exit(status);
}
status = X400msRecipAddStrParam(rp, X400_S_OR_ADDRESS, recip, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400msRecipAddStrParam(rp, X400_S_DIRECTORY_NAME, "CN=recipient;c=gb", -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400msMsgAddStrParam(mp, X400_S_OR_ADDRESS, orn, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400msMsgAddStrParam(mp, X400_S_DIRECTORY_NAME, "CN=originator;c=gb", -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
// Ask for delivery reports.
printf("delivery report request %d ( 1 - No, 2 - Yes)\n", x400_dr_req);
status = X400msRecipAddIntParam(rp, X400_N_REPORT_REQUEST, x400_dr_req);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* Ask for read receipts */
printf("read notification request %d ( 1 - RN, 2 - NRN, 4 - return of IPM with NRN )\n", x400_rn_req);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddIntParam returned error: %s\n", X400msError(status));
exit(status);
}
if (1) {
char *contid = "ContID00001";
/* Content identifier so we can correlate with submission result */
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400msMsgAddIntParam %d returned error: %s\n", X400_S_CONTENT_IDENTIFIER, X400msError(status));
exit(status);
}
}
/* content return request on report - 0 = no */
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400msMsgAddIntParam %d returned error: %s\n", X400_N_CONTENT_RETURN_REQUEST, X400msError(status));
exit(status);
}
/* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
printf("message priority is %d ( 0 - normal, 1 - non-urgent, 2 - urgent)\n", x400_default_priority);
status = X400msMsgAddIntParam(mp, X400_N_PRIORITY, x400_default_priority);
if (status != X400_E_NOERROR) {
return (status);
}
/* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
printf("military message priority is %d ( 0 - low, 1 - high)\n", x400_default_priority);
if (status != X400_E_NOERROR) {
return (status);
}
/* subject */
{
time_t t;
time(&t);
char tmp_buffer[255];
// NB strip newline from ctime result
snprintf(tmp_buffer, 244, "%s '%s' '%.19s'", subject, get_x400_pty_str_from_4406(x400_default_priority), ctime(&t));
printf("Subject is '%s'\n", tmp_buffer);
status = X400msMsgAddStrParam(mp, X400_S_SUBJECT, tmp_buffer, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
}
status = add_sec_label(mp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "Failed to add Security Label: %s\n", X400msError(status));
return (status);
}
else {
fprintf(stderr, "added Security Label\n");
}
/* content type */
status = X400msMsgAddStrParam(mp, X400_S_EXTERNAL_CONTENT_TYPE, "1.3.26.0.4406.0.4.1", -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* 8859-1 attachment */
status = X400msMsgAddStrParam(mp, X400_T_ISO8859_1, text, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400ms returned error: %s\n", X400msError(status));
exit(status);
}
/* now an IA5 body part using the bodypart func */
status = X400msMsgAddAttachment(mp, X400_T_IA5TEXT, text, strlen(text));
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_IA5TEXT BP\n");
return (status);
}
/* or a Binary body part using the bodypart func */
if (filename_to_send != NULL) {
status = add_binary_attachment(mp, filename_to_send);
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_BINARY BP\n");
return (status);
}
status = add_fwd_bp(mp, orn, def_dn);
if (status != X400_E_NOERROR) {
printf("failed to add forwarded BP\n");
return (status);
}
}
else {
printf("no binary file set - not sending X400_T_BINARY\n");
printf("no binary file set - not sending forwarded BP\n");
}
/* File Transfer Body Part using the bodypart func */
status = add_ftbp(mp);
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_BINARY BP\n");
return (status);
}
#ifdef USE_SEC_LABEL
{
#define XML_BUFSIZE 1024
#define STRING_BUFSIZE 1024
const char *xml_filename = "seclabel.xml";
char xml_content[XML_BUFSIZE];
char str_content[STRING_BUFSIZE];
int str_len = STRING_BUFSIZE;
FILE *fd = NULL;
/* Read in the security label XML file */
fd = fopen(xml_filename, "r");
if (fd == NULL) {
fprintf(stderr, "Failed to open %s : %s\n", xml_filename, strerror(errno));
}
fread(&xml_content, XML_BUFSIZE, 1, fd);
fclose(fd);
status = SecLabelInit("Example program");
if (status != SECLABEL_E_NOERROR) {
fprintf(stderr, "SecLabelInit returned error %d\n", status);
exit(1);
}
/* Use SecLabelParse to turn the XML into an octet string */
status = SecLabelParse(xml_content, str_content, STRING_BUFSIZE, &str_len);
if (status != SECLABEL_E_NOERROR) {
fprintf(stderr, "SecLabelParse returned error %d\n", status);
exit(1);
}
/* Add the octet string to the message pointer */
status = X400msMsgAddStrParam(mp, X400_S_SECURITY_LABEL, str_content, str_len);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
}
#endif
status = X400msMsgSend(mp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgSend returned error: %s\n", X400msError(status));
if (status == X400_E_RECIPIENT_ERROR) {
int n = 1;
struct X400Recipient *irp;
int ss = X400_E_NOERROR;
while (ss == X400_E_NOERROR) {
ss = X400msRecipGet(mp, X400_RECIP_INVALID, n, &irp);
if (ss == X400_E_NOERROR) {
char buf[1024];
size_t retlen;
int s;
fprintf(stderr, "A recipient with ");
s = X400msRecipGetStrParam(irp, X400_S_OR_ADDRESS, buf, 1024, &retlen);
if (s == X400_E_NOERROR) {
buf[retlen] = '\0';
fprintf(stderr, "ORAddress %s ", buf);
}
s = X400msRecipGetStrParam(irp, X400_S_DIRECTORY_NAME, buf, 1024, &retlen);
if (s == X400_E_NOERROR) {
buf[retlen] = '\0';
fprintf(stderr, " and DN %s", buf);
}
fprintf(stderr, " was rejected\n");
n++;
}
}
}
}
else {
char buf[1024];
size_t retlen;
char *databuf = buf;
printf("Message submitted successfully\n");
status = X400msMsgGetStrParam(mp, X400_S_MESSAGE_IDENTIFIER, buf, 1024, &retlen);
if (status != X400_E_NOERROR) {
fprintf(stderr, "No MessageId present from submission result: error %d\n", status);
}
else {
buf[retlen] = '\0';
printf("MessageId from Submission Result = %s\n", buf);
}
status = X400msMsgGetStrParam(mp, X400_S_MESSAGE_SUBMISSION_TIME, buf, 1024, &retlen);
if (status != X400_E_NOERROR) {
fprintf(stderr, "No MessageSubmissionTime present from submission result: error %d\n", status);
}
else {
buf[retlen] = '\0';
printf("MessageSubmissionTime from Submission Result = %s\n", buf);
}
status = X400msMsgGetStrParam(mp, X400_S_CONTENT_IDENTIFIER, buf, 1024, &retlen);
if (status != X400_E_NOERROR) {
fprintf(stderr, "No ContentIdentifier present from submission result: error %d\n", status);
}
else {
buf[retlen] = '\0';
printf("ContentIdentifier from Submission Result = %s\n", buf);
}
/* Get binary representation and store to file */
/* First pass to find out how big it needs to be */
status = X400msMsgGetRaw(sp, mp, databuf, 0, &retlen);
if (status != X400_E_NOSPACE) {
fprintf(stderr, "Failed to get raw message length: error %d\n", status);
}
else {
struct X400msMessage *newmsg;
int newtype;
databuf = (char *)malloc(retlen);
printf("Data buffer length required = %d\n", (int)retlen);
status = X400msMsgGetRaw(sp, mp, databuf, retlen, &retlen);
if (status != X400_E_NOERROR) {
fprintf(stderr, "Failed to get raw message: error %d\n", status);
}
else {
/* Dump to file */
FILE *fd = fopen("message.dump", "w");
if (fd == NULL) {
fprintf(stderr, "Failed to open file message.dump\n");
}
else {
if (fwrite(databuf, 1, retlen, fd) < retlen) {
fprintf(stderr, "Failed to write message to file message.dump\n");
}
else {
fprintf(stdout, "Dumped message to file message.dump\n");
}
fclose(fd);
}
}
/* And try to reconstruct message from bytes */
status = X400msMsgFromRaw(sp, databuf, retlen, &newmsg, &newtype);
if (status != X400_E_NOERROR) {
fprintf(stderr, "Failed to create message from bytes: error %d\n", status);
}
free(databuf);
}
}
status = X400msMsgDelete(mp, 0);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgDelete returned error: %s\n", X400msError(status));
exit(status);
}
mp = NULL;
rp = NULL;
status = X400msClose(sp);
exit(status);
/* NOTREACHED */
}
static int add_binary_attachment(struct X400msMessage *mp, char *filename) {
int fd;
int file_size;
struct stat buf;
int fs = 0;
int status;
printf("sending file %s\n", filename);
if ((fd = open(filename_to_send, O_RDONLY)) == -1) {
printf("Failed to open content file %s: ", filename);
}
if (fstat(fd, &buf) != 0) {
close(fd);
printf("Can't fstat file %s %d", filename, errno);
}
file_size = buf.st_size;
printf("Content file size = %d\n", file_size);
binary_data = (char *)malloc(file_size);
if (binary_data == NULL) {
}
if ((fs = read(fd, binary_data, file_size)) == -1) {
printf("Cannot read from binary file %d\n", errno);
return (X400_E_SYSERROR);
}
close(fd);
status = X400msMsgAddAttachment(mp, X400_T_BINARY, binary_data, fs);
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_BINARY BP\n");
return (status);
}
return (status);
}
static int add_fwd_bp(struct X400msMessage *mp, char *orig_orn, char *orig_dn) {
struct X400Message *x400_mp;
struct X400Recipient *rp;
int status;
int num_atts = 0;
printf("sending fwd bp \n");
status = X400MsgNew(X400_MSG_MESSAGE, &x400_mp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400MsgNew returned error: %s\n", X400msError(status));
exit(status);
}
status = X400MsgAddStrParam(x400_mp, X400_S_MESSAGE_DELIVERY_TIME, "090909090909Z", (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400MsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400MsgAddStrParam(x400_mp, X400_S_MESSAGE_SUBMISSION_TIME, "090909090909Z", (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400MsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* envelope originator OR address */
status = X400MsgAddStrParam(x400_mp, X400_S_OR_ADDRESS, orig_orn, (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400MsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400MsgAddStrParam(x400_mp, X400_S_DIRECTORY_NAME, orig_dn, (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400MsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* add originator into headers */
status = X400RecipNew(X400_ORIGINATOR, &rp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipNew returned error: %s\n", X400msError(status));
exit(status);
}
/* put in OR Address part of OR Name */
status = X400RecipAddStrParam(rp, X400_S_OR_ADDRESS, recip, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* put in DN part of OR Name */
status = X400RecipAddStrParam(rp, X400_S_DIRECTORY_NAME, orig_dn, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* put originator into message */
status = X400MsgAddRecip(x400_mp, X400_ORIGINATOR, rp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400MsgAddRecip returned error: %s\n", X400msError(status));
exit(status);
}
printf("Put %s in as originator\n", orig_orn);
/* add a recipient */
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipNew returned error: %s\n", X400msError(status));
exit(status);
}
status = X400RecipAddStrParam(rp, X400_S_OR_ADDRESS, recip, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400RecipAddStrParam(rp, X400_S_DIRECTORY_NAME, "CN=recipient;c=gb", -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400MsgAddRecip(x400_mp, X400_RECIP_STANDARD, rp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400MsgAddRecip returned error: %s\n", X400msError(status));
exit(status);
}
printf("Put %s in as reipient\n", recip);
/* Add 2nd recipient */
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipNew returned error: %s\n", X400msError(status));
exit(status);
}
status = X400RecipAddStrParam(rp, X400_S_OR_ADDRESS, recip, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400RecipAddStrParam(rp, X400_S_DIRECTORY_NAME, "CN=second recipient;c=gb", -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* put recipient into message */
status = X400MsgAddRecip(x400_mp, X400_RECIP_STANDARD, rp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400MsgAddRecip returned error: %s\n", X400msError(status));
exit(status);
}
printf("Put %s in as reipient\n", recip);
/* envelope */
/* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
printf("message priority is %d ( 0 - normal, 1 - non-urgent, 2 - urgent)\n", x400_default_priority);
status = X400MsgAddIntParam(x400_mp, X400_N_PRIORITY, x400_default_priority);
if (status != X400_E_NOERROR) {
return (status);
}
/* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
printf("military message priority is %d ( 0 - low, 1 - high)\n", x400_default_priority);
if (status != X400_E_NOERROR) {
return (status);
}
/* content */
/* subject */
status = X400MsgAddStrParam(x400_mp, X400_S_SUBJECT, fwd_subject, (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* now an IA5 body part using the bodypart func */
status = X400MsgAddAttachment(x400_mp, X400_T_IA5TEXT, text, strlen(text));
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_IA5TEXT BP\n");
return (status);
}
num_atts++;
/* 8859-1 attachment */
status = X400MsgAddStrParam(x400_mp, X400_T_ISO8859_1, text, (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400ms returned error: %s\n", X400msError(status));
exit(status);
}
num_atts++;
status = X400MsgAddIntParam(x400_mp, X400_N_NUM_ATTACHMENTS, num_atts);
if (status != X400_E_NOERROR) {
return (status);
}
status = X400msMsgAddMessageBody(mp, x400_mp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400msMsgAddMessageBody returned error: %s\n", X400msError(status));
return (status);
}
}
static int add_ftbp(struct X400msMessage *mp) {
FILE *fp = NULL;
int fs = 0;
char *binary_data;
int status;
struct X400Bodypart *bp;
/* Add FTBP using the bodypart func */
if (filename_to_send == NULL) {
printf("no file set - not sending X400_T_FTBP\n");
}
fp = fopen(filename_to_send, "rb");
if (fp == (FILE *)NULL) {
printf("Cannot open binary file\n");
return (X400_E_SYSERROR);
}
binary_data = (char *)malloc(bin_bp_size);
if (binary_data == NULL) {
}
if ((fs = fread(binary_data, sizeof(char), bin_bp_size / sizeof(char), fp)) == -1) {
printf("Cannot read from binary file\n");
free(binary_data);
fclose(fp);
return (X400_E_SYSERROR);
}
fclose(fp);
if (fs < bin_bp_size) {
printf("Cannot read %d bytes from binary file (got %d)\n", bin_bp_size, fs);
free(binary_data);
return (X400_E_SYSERROR);
}
/* NB this value should have the filename, but not the full path */
/* And on Windows backslashes must be escaped with a second backslash */
X400BodypartAddStrParam(bp, X400_S_FTBP_FILENAME, filename_to_send, -1);
X400BodypartAddStrParam(bp, X400_S_FTBP_CREATION_DATE, "20230801060101.0Z", -1);
status = X400msMsgAddBodypart(mp, bp);
free(binary_data);
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_FTBP BP\n");
return (status);
}
printf("Sent %d bytes as X400_T_FTBP BP\n", fs);
}
static void usage(void) {
printf("usage: %s\n", optstr);
printf("\t where:\n");
printf("\t -u : Don't prompt to override defaults \n");
printf("\t -3 : Use P3 connection \n");
printf("\t -7 : Use P7 connection \n");
printf("\t -1 : Use Marben-compatibility mode for P7 connection \n");
printf("\t -m : OR Address in P7 bind arg \n");
printf("\t -d : DN in P7 bind arg \n");
printf("\t -p : Presentation Address of P7 Store \n");
printf("\t -w : P7 password of P7 user for simple auth \n");
printf("\t -H : 'MTA name;GDI' for the MTA for P3 strong auth \n");
printf("\t -M : OR Address in P3 bind arg \n");
printf("\t -D : DN in P3 bind arg \n");
printf("\t -P : Presentation Address of P3 server\n");
printf("\t -W : for simple auth this is the P3 password of the P3 user \n");
printf("\t -o : Originator \n");
printf("\t -O : Originator Return Address \n");
printf("\t -r : Recipient\n");
printf("\t -l : Logline\n");
printf("\t -R : Report setting: 0=none, 1=-ve, 2=+ve\n");
printf("\t -y : Military Priority \n");
printf("\t\t 0 - deferred, 1 - routine, 2 - priority \n");
printf("\t\t 3 - immediate, 4 - flash, 5 - override \n");
printf("\t -C : Content Type (2/22/772/OID) \n");
printf("\t -i : Implicit conversion prohibited = TRUE \n");
printf("\t -a : Alternate Recipient Prohibited = TRUE \n");
printf("\t -q : Content Return Request = TRUE \n");
printf("\t -s : Disclosure of Recipient = FALSE \n");
printf("\t -A : Recipient Reassignment Prohibited = FALSE \n");
printf("\t -v : Conversion with Loss Prohibited = FALSE \n");
printf("\t -f : Filename to transfer as binary bp\n");
printf("\t -k : Request Delivery Report\n");
printf("\t -K : Request Read Notification ( 1 - RN, 2 - NRN, 4 - return of IPM with NRN )\n");
printf("\t -B : Set alternative subject line \n");
printf("\t -U : Directory containing trust anchors (required for strong authentication)\n");
printf("\t -b : Passphrase for private key in PKCS12 file (required for strong authentication)\n");
printf("\t -Y : Filename of PKCS12 file containing Digital Identity (required for strong authentication)\n");
return;
}
int X400RecipNew(int type, struct X400Recipient **rpp)
Create a new recipient object.
int X400MsgAddRecip(struct X400Message *mp, int reciptype, struct X400Recipient *recip)
Add a recipient object to the message.
int X400RecipAddStrParam(struct X400Recipient *rp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the recipient.
int X400MsgAddIntParam(struct X400Message *mp, int paramtype, int value)
Add integer-valued parameter to the message.
int X400BodypartAddStrParam(struct X400Bodypart *bp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the body part.
int X400BodypartAddIntParam(struct X400Bodypart *bp, int paramtype, int value)
Add integer-valued parameter to the body part.
int X400MsgNew(int type, struct X400Message **mpp)
Creates new message.
int X400MsgAddAttachment(struct X400Message *mp, int type, const char *string, size_t length)
Add an attachment to the message.
int X400MsgAddStrParam(struct X400Message *mp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
int X400BodypartNew(int type, struct X400Bodypart **bpp)
Create a new body part object.
int X400msMsgAddStrParam(struct X400msMessage *mp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
int X400msMsgFromRaw(struct X400msSession *sp, char *buffer, size_t buflen, struct X400msMessage **mpp, int *typep)
Reconstruct a message from a binary representation.
int X400msMsgAddBodypart(struct X400msMessage *mp, struct X400Bodypart *bp)
int X400msRecipGet(struct X400msMessage *mp, int type, int number, struct X400Recipient **rpp)
Get recipient object from message.
int X400msRecipAddIntParam(struct X400Recipient *rp, int paramtype, int value)
Add integer-valued parameter to the message.
int X400msMsgAddIntParam(struct X400msMessage *mp, int paramtype, int value)
Add integer-valued parameter to the message.
int X400msMsgGetStrParam(struct X400msMessage *mp, int paramtype, char *buffer, size_t buflen, size_t *paramlenp)
Return a string-valued parameter from the message object.
int X400msMsgGetRaw(struct X400msSession *sp, struct X400msMessage *mp, char *buffer, size_t buflen, size_t *buflenp)
Get a binary representation of a message which can be subsequently be used to reconstruct the message...
char * X400msBuildCredentials(int auth_type, const char *pass, const char *mtaPassword, const char *filename, const char *trustedCACertificatesDirectory, const char *orAddress, const char *mtaName, const char *gdi)
Build X.400 credentials of the type: For simple authentication. &#160;&#160;'SIMPLE\n<password>\n<MTA passw...
int X400msRecipGetStrParam(struct X400Recipient *rp, int paramtype, char *buffer, size_t buflen, size_t *paramlenp)
Return a string-valued parameter from the recipient object.
int X400msRecipNew(struct X400msMessage *mp, int type, struct X400Recipient **rpp)
Add new recipient to a message.
const char * X400msError(int error)
Obtain a string describing the meaning of the given error code.
int X400msRecipAddStrParam(struct X400Recipient *rp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
int X400msSetIntDefault(struct X400msSession *sp, int paramtype, int value)
Set a default integer parameter value in a session.
int X400msMsgSend(struct X400msMessage *mp)
Send message object.
int X400msMsgAddMessageBody(struct X400msMessage *mp, struct X400Message *mbp)
int X400msMsgDelete(struct X400msMessage *mp, int retain)
Delete message object.
int X400msMsgAddAttachment(struct X400msMessage *mp, int type, const char *string, size_t length)
Add attachment to the message.
void X400msSetConfigRequest(int val)
Disable and enable configuration requests in MS Bind operations.
int X400msMsgNew(struct X400msSession *sp, int type, struct X400msMessage **mpp)
Creates new message.
int X400msClose(struct X400msSession *sp)
Close a X400 Session.
int X400msSetStrDefault(struct X400msSession *sp, int paramtype, const char *value, size_t length)
Set a default string parameter value in a session.
int X400msOpen(int type, const char *oraddr, const char *dirname, const char *credentials, const char *pa, int *messages, struct X400msSession **spp)
Open a session to a Message Store (P7) or MTA (P3) in synchronous mode.
#define X400_S_DIRECTORY_NAME
Definition x400_att.h:397
#define X400_S_OR_ADDRESS
Definition x400_att.h:349
#define MS_BIND_STRONG_P7
Definition x400_msapi.h:358
#define MS_BIND_STRONG_P3
Definition x400_msapi.h:355
#define X400_N_FTBP_OBJECT_SIZE
Definition x400_att.h:1239
#define X400_S_FTBP_FILENAME
Definition x400_att.h:1227
#define X400_S_BODY_DATA
Definition x400_att.h:1194
#define X400_S_FTBP_MODIFICATION_DATE
Definition x400_att.h:1233
#define X400_S_FTBP_CREATION_DATE
Definition x400_att.h:1230
#define X400_S_FTBP_CONTENT_DESCRIPTION
Definition x400_att.h:1224
#define X400_S_SUBJECT
Definition x400_att.h:749
#define X400_T_BINARY
Definition x400_att.h:851
#define X400_T_IA5TEXT
Definition x400_att.h:825
#define X400_N_NUM_ATTACHMENTS
Definition x400_att.h:822
#define X400_T_ISO8859_1
Definition x400_att.h:835
#define X400_T_FTBP
Definition x400_att.h:860
#define X400_S_GRAPHIC_CHARSETS
Definition x400_att.h:1168
#define X400_S_TELETEX_CHARSETS
Definition x400_att.h:1175
#define X400_S_LOG_CONFIGURATION_FILE
Definition x400_att.h:1116
#define X400_N_PRIORITY
Definition x400_att.h:433
#define X400_S_MESSAGE_DELIVERY_TIME
Definition x400_att.h:451
#define X400_N_MMTS_PRIORITY_QUALIFIER
Definition x400_att.h:482
#define X400_S_CONTENT_IDENTIFIER
Definition x400_att.h:425
#define X400_N_CONTENT_RETURN_REQUEST
Definition x400_att.h:445
#define X400_S_MESSAGE_SUBMISSION_TIME
Definition x400_att.h:448
#define X400_S_EXTERNAL_CONTENT_TYPE
Definition x400_att.h:456
#define X400_S_MESSAGE_IDENTIFIER
Definition x400_att.h:416
#define X400_S_SECURITY_LABEL
Definition x400_att.h:1370
#define X400_E_BADPARAM
Definition x400_att.h:55
#define X400_E_SYSERROR
Definition x400_att.h:49
#define X400_E_RECIPIENT_ERROR
Definition x400_att.h:157
#define X400_E_NOMEMORY
Definition x400_att.h:52
#define X400_E_NOERROR
Definition x400_att.h:46
#define X400_E_NOSPACE
Definition x400_att.h:112
#define X400_N_ERROR_DUPLICATE_ATTRIBUTE
Definition x400_att.h:1306
#define X400_N_STRICT_P7_1988
Definition x400_att.h:1293
#define X400_N_USE_EXTENDED_SUBJECT
Definition x400_att.h:1299
#define X400_MSG_MESSAGE
Definition x400_att.h:29
#define X400_N_REPORT_REQUEST
Definition x400_att.h:680
#define X400_N_NOTIFICATION_REQUEST
Definition x400_att.h:702
#define X400_RECIP_STANDARD
Definition x400_att.h:341
#define X400_ORIGINATOR
Definition x400_att.h:305
#define X400_RECIP_INVALID
Definition x400_att.h:338
X400 MA/MS (P3/P7) Interface.

All rights reserved © 2002 - 2024 Isode Ltd.