x400_mssend_sign.c
1 /* Copyright (c) 2003-2014, Isode Limited, London, England.
2  * All rights reserved.
3  *
4  * Acquisition and use of this software and related materials for any
5  * purpose requires a written licence agreement from Isode Limited,
6  * or a written licence from an organisation licenced by Isode Limited
7  * to grant such a licence.
8  *
9  */
10 
11 /*
12  *
13  * @VERSION@
14  * Simple example program for submitting a message via a message store.
15  * The security environment is set up so that messages are signed.
16  */
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <errno.h>
22 
23 #include <x400_msapi.h>
24 #include <seclabel_api.h> /* For security labels */
25 
26 #include "example.h"
27 #include "ms_example.h"
28 #include "time.h"
29 
30 #define PCT_OID "1.2.840.113549.1.9.16.1.6"
31 
32 static char *optstr = "u37m:d:p:w:M:D:P:W:r:o:O:r:g:G:c:l:R:y:C:iaqsAve:x:b:f:S:Y:Z4B:F:N:";
33 
34 /* These are the data items used to construct the message for submission */
35 static char *default_recip = "/CN=lppt1/OU=lppt/O=attlee/PRMD=TestPRMD/ADMD=TestADMD/C=GB/";
36 char *recip;
37 static char *content_id = "030924.140212";
38 
39 static const char text[] = "First line\r\nSecond line\r\n";
40 
41 static char *binary_data;
42 
43 static int setup_msg_sec_env = 0;
44 
45 /* set this to non zero to cause the IA5 body part to be an attachment */
46 int send_ia5_as_att = 0;
47 
48 /* local functions */
49 
50 static void usage(void) ;
51 static int send_msg(
52  int contype,
53  char *orn,
54  char *def_dn,
55  char *pa,
56  char *password);
57 
58 static int submit_msg(
59  char *orn,
60  struct X400msSession *sp /* session object */
61 );
62 
63 static int setup_default_new_sec_env(
64  struct X400msSession *sp,
65  char *identity_filename,
66  char *pw
67 );
68 
69 static int setup_default_old_sec_env(
70  struct X400msSession *sp,
71  char *id,
72  char *dn,
73  char *pw
74 );
75 
76 static int setup_msg_new_sec_env(
77  struct X400msMessage *mp, /* message object */
78  char *identity_filename,
79  char *pw
80 );
81 
82 static int setup_msg_old_sec_env(
83  struct X400msMessage *mp, /* message object */
84  char *id,
85  char *dn,
86  char *pw
87 );
88 
89 static int add_sec_label(
90  struct X400msMessage *mp /* message object */
91 );
92 
93 
94 static int add_content(
95  struct X400msMessage *mp /* message object */
96 );
97 
98 /* start here */
99 int main (
100  int argc,
101  char **argv
102 )
103 {
104  char pa[BUFSIZ];
105  char orn[BUFSIZ];
106  char *def_oraddr;
107  char *def_dn;
108  char *def_pa;
109  int contype;
110  int status;
111  char password[BUFSIZ];
112 
113  if (get_args(argc, argv, optstr)) {
114  usage();
115  exit(-1);
116  }
117 
118  printf("Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [%d]: ", x400_contype);
119  contype = ic_fgetc(x400_contype, stdin);
120  if (contype != 10)
121  ic_fgetc(x400_contype, stdin);
122 
123  if ( contype < '0' || '2' < contype )
124  contype = x400_contype;
125  else
126  contype -= '0';
127 
128  if (contype == 0) {
129  def_oraddr = x400_ms_user_addr;
130  def_dn = x400_ms_user_dn;
131  def_pa = x400_ms_presentation_address;
132  } else {
133  def_oraddr = x400_mta_user_addr;
134  def_dn = x400_mta_user_dn;
135  def_pa = x400_mta_presentation_address;
136  }
137 
138  printf("Your ORAddress [%s] > ", def_oraddr);
139  ic_fgets (orn, sizeof orn, stdin);
140 
141  if ( orn[strlen(orn)-1] == '\n' )
142  orn[strlen(orn)-1] = '\0';
143 
144  if (orn[0] == '\0')
145  strcpy(orn, def_oraddr);
146 
147  /* Prompt for password; note: reflected. */
148  printf ("Password [%s]: ",
149  contype == 0 ? x400_p7_password : x400_p3_password);
150  if ( ic_fgets (password, sizeof password, stdin) == NULL )
151  exit (1);
152 
153  if (password[strlen(password)-1] == '\n' )
154  password[strlen(password)-1] = '\0';
155  if (password[0] == '\0')
156  strcpy(password, contype == 0 ? x400_p7_password : x400_p3_password);
157 
158  /* Presentation Address */
159  printf("Presentation Address [%s] > ", def_pa);
160  ic_fgets (pa, sizeof pa, stdin);
161 
162  if ( pa[strlen(pa)-1] == '\n' )
163  pa[strlen(pa)-1] = '\0';
164 
165  if (pa[0] == '\0')
166  strcpy(pa, def_pa);
167 
168  printf("sending message using session 1\n");
169  if ((status = send_msg(contype, orn, def_dn, pa, password))
170  != X400_E_NOERROR ) {
171  fprintf (stderr, "Error in sending message\n");
172  exit (status);
173  }
174  /*
175  printf("sending message using session 2\n");
176  if ((status = send_msg(contype, orn, def_dn, pa, password))
177  != X400_E_NOERROR ) {
178  fprintf (stderr, "Error sending message\n");
179  exit (status);
180  }
181  */
182  return (status);
183 }
184 
185 static int send_msg(
186  int contype,
187  char *orn,
188  char *def_dn,
189  char *pa,
190  char *password
191 )
192 {
193  struct X400msSession *sp; /* session object */
194 
195  int status;
196 
197 
198  /* we've got what we need - now open an API session */
199  status = X400msOpen (contype, orn, def_dn, password, pa, NULL, &sp);
200  if ( status != X400_E_NOERROR ) {
201  fprintf (stderr, "Error in Open: %s\n", X400msError (status));
202  fprintf (stderr, "%s %s %s\n", orn, def_dn, pa);
203  return (status);
204  }
205 
206  /* setup logging */
207  X400msSetStrDefault(sp, X400_S_LOG_CONFIGURATION_FILE, "x400api.xml", 0);
208 
209  /* Set up the security environment.
210  *
211  * The security env can be specified the new way (recommended) using
212  * a PKCS12 filename and passphrase, or as a directory (deprecated and
213  * obsolete).
214  *
215  * If the ID is specified as a directory, in which the subdirectory
216  * "x509" is expected to contain one or more PKCS12 files.
217  * The appropriate Digital Identity is determined from the
218  * DN of the subject, and the passphrase is used to decrypt
219  * the private key.
220  */
221  if (use_new_sec_env) {
222  status = setup_default_new_sec_env(sp, identity_filename, passphrase);
223  } else {
224  status = setup_default_old_sec_env(sp, security_id, identity_dn,
225  passphrase);
226  }
227 
228  if ( status != X400_E_NOERROR ) {
229  fprintf (stderr, "Can't setup security environment\n");
230  return (status);
231  }
232 
233  printf("sending message 1\n");
234  status = submit_msg(orn, sp);
235  if ( status != X400_E_NOERROR ) {
236  fprintf (stderr, "Can't submit\n");
237  return (status);
238  }
239 
240  status = X400msClose (sp);
241  if ( status != X400_E_NOERROR ) {
242  fprintf (stderr, "X400msClose returned error: %s\n", X400msError (status));
243  return (status);
244  }
245  return status;
246 }
247 
248 static int submit_msg(
249  char *orn,
250  struct X400msSession *sp /* session object */
251 )
252 {
253  struct X400msMessage *mp; /* message object */
254  struct X400Recipient *rp; /* recipient object */
255  char tmp[BUFSIZ];
256  FILE *fp = NULL;
257  int fs=0;
258  int status;
259 
260  if (x400_default_recipient != NULL)
261  recip = x400_default_recipient;
262  else
263  recip = default_recip;
264 
265  printf("Message recipient [%s]: ", recip);
266  ic_fgets (tmp, sizeof tmp, stdin);
267 
268  if ( tmp[strlen(tmp)-1] == '\n' )
269  tmp[strlen(tmp)-1] = '\0';
270  if (strlen(tmp) != 0)
271  recip = strdup(tmp);
272 
273  printf("Subject [%s]: ", subject);
274  ic_fgets (tmp, sizeof tmp, stdin);
275 
276  if ( tmp[strlen(tmp)-1] == '\n' )
277  tmp[strlen(tmp)-1] = '\0';
278  if (strlen(tmp) != 0)
279  subject = strdup(tmp);
280 
281  status = X400msMsgNew (sp, X400_MSG_MESSAGE, &mp);
282  if ( status != X400_E_NOERROR ) {
283  fprintf (stderr, "x400msMsgNew returned error: %s\n", X400msError (status));
284  return (status);
285  }
286 
287  printf("\n\nPreparing Message\n");
288 
289  /* set content type */
290  if (x400_default_external_content_type != NULL) {
291  printf("Sending external content type %s\n",
292  x400_default_external_content_type);
294  x400_default_external_content_type, -1);
295  } else {
296  printf("Sending content type %d\n", x400_default_content_type);
298  x400_default_content_type);
299  }
300  if ( status != X400_E_NOERROR ) {
301  fprintf (stderr, "X400msMsgAddIntParam returned error: %s\n",
302  X400msError (status));
303  return (status);
304  }
305 
306  /* Set up the security environment for this message overriding the
307  * default security env.
308  *
309  * The security env can be specified the new way (recommended) using
310  * a PKCS12 filename and passphrase, or as a directory (deprecated and
311  * obsolete).
312  *
313  * If the ID is specified as a pathname, in which the subdirectory
314  * "x509" is expected to contain one or more PKCS12 files.
315  * The appropriate Digital Identity is determined from the
316  * DN of the subject, and the passphrase is used to decrypt
317  * the private key.
318  */
319  if (setup_msg_sec_env) {
320  if (use_new_sec_env) {
321  status = setup_msg_new_sec_env(mp, identity_filename, passphrase);
322  if ( status != X400_E_NOERROR ) {
323  fprintf (stderr, "Can't setup new security environment\n");
324  return (status);
325  }
326  } else {
327  status = setup_msg_old_sec_env(mp, security_id, identity_dn2,
328  passphrase);
329  if ( status != X400_E_NOERROR ) {
330  fprintf (stderr, "Can't setup old security environment\n");
331  return (status);
332  }
333  }
334  }
335 
336  /* Instruct the X400msMsgSend() function to generate a MOAC (signature) for
337  * the message.
338  *
339  * The default attributes will be used unless the attributes are
340  * also included in the message eg by calling setup_msg_sec_env() above
341  */
342  if (gen_moac) {
343  status = X400msMsgAddIntParam (mp, X400_B_SEC_GEN_MOAC, 1);
344  if ( status != X400_E_NOERROR ) {
345  fprintf (stderr, "x400msMsgAddIntParam returned error: %s\n",
346  X400msError (status));
347  return (status);
348  }
349  }
350 
351  if (gen_4406_sig) {
352  /* Instruct the X400msMsgSend() function to generate a STANAG 4406
353  * signature for the message
354  *
355  * The default attributes will be used unless the attributes are
356  * also included in the message
357  * e.g. by calling setup_msg_sec_env() above
358  */
359  printf("\nRequesting 4406 signature\n");
360  status = X400msMsgAddIntParam (mp, X400_N_S4406, 1);
361  if ( status != X400_E_NOERROR ) {
362  fprintf (stderr, "x400msMsgAddIntParam returned error: %s\n",
363  X400msError (status));
364  return (status);
365  }
366  /* set the external content type correctly to PCT */
368  PCT_OID, -1);
369  printf("Sending external content type %s\n", PCT_OID);
370  } else {
371  printf("\nNot requesting 4406 signature\n");
372  }
373 
374  status = add_sec_label (mp);
375  if ( status != X400_E_NOERROR ) {
376  fprintf (stderr, "Failed to add 4406 Security Label: %s\n",
377  X400msError (status));
378  return (status);
379  }
380 
381  status = X400msRecipNew (mp, X400_RECIP_STANDARD, &rp);
382  if ( status != X400_E_NOERROR ) {
383  fprintf (stderr, "x400msRecipNew returned error: %s\n", X400msError (status));
384  return (status);
385  }
386 
387  /* put precedence extension into primary recipient */
388  status = X400msRecipAddIntParam (rp, X400_N_PRECEDENCE, 2);
389  if ( status != X400_E_NOERROR ) {
390  fprintf (stderr, "x400msRecipAddIntParam returned error: %s\n",
391  X400msError (status));
392  return (status);
393  }
394 
395  status = X400msRecipAddStrParam (rp, X400_S_OR_ADDRESS, recip, -1);
396  if ( status != X400_E_NOERROR ) {
397  fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
398  return (status);
399  }
400 
401  status = X400msRecipAddStrParam (rp, X400_S_DIRECTORY_NAME, "CN=recipient;c=gb", -1);
402  if ( status != X400_E_NOERROR ) {
403  fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
404  return (status);
405  }
406 
407  status = X400msMsgAddStrParam (mp, X400_S_OR_ADDRESS, orn, -1);
408  if ( status != X400_E_NOERROR ) {
409  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
410  return (status);
411  }
412 
413  status = X400msMsgAddStrParam (mp, X400_S_DIRECTORY_NAME, "CN=originator;c=gb", -1);
414  if ( status != X400_E_NOERROR ) {
415  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
416  return (status);
417  }
418 
419  /* Ask for +ve and -ve delivery reports */
421  if ( status != X400_E_NOERROR ) {
422  fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
423  return (status);
424  }
425 
426  /* Ask for +ve and -ve read receipts */
428  if ( status != X400_E_NOERROR ) {
429  fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
430  return (status);
431  }
432 
434  content_id, -1);
435  if ( status != X400_E_NOERROR ) {
436  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
437  return (status);
438  }
439 
440  /* subject */
441  {
442  time_t t;
443  time(&t);
444  char tmp_buffer[255];
445  // NB strip newline from ctime result
446  snprintf(tmp_buffer, 244, "%s '%s' '%.19s'",
447  subject, get_x400_pty_str_from_4406(x400_default_priority), ctime(&t));
448  printf("Subject is '%s'\n", tmp_buffer);
449  status = X400msMsgAddStrParam (mp, X400_S_SUBJECT, tmp_buffer, -1);
450  if ( status != X400_E_NOERROR ) {
451  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
452  X400msError (status));
453  exit (status);
454  }
455  }
456 
457  /* put FLOT into IA5 BP */
458  if (flot_string != NULL) {
459  status = X400msMsgAddStrParam (mp, X400_T_IA5TEXT, flot_string, -1);
460  if ( status != X400_E_NOERROR ) {
461  fprintf (stderr, "x400ms returned error: %s\n",
462  X400msError (status));
463  return (status);
464  }
465  printf("Sent IA5 FLOT:\n%s\n", flot_string);
466  }
467 
468  if (add_content(mp) != X400_E_NOERROR) {
469  fprintf (stderr, "add_content() returned error: %s\n",
470  X400msError (status));
471  return (status);
472  }
473 
474  status = X400msMsgAddStrParam (mp, X400_T_ISO8859_1, text, -1);
475  if ( status != X400_E_NOERROR ) {
476  fprintf (stderr, "x400ms returned error: %s\n", X400msError (status));
477  return (status);
478  }
479  printf("Sent 8859 content:\n%s\n", text);
480 
481  /* now an IA5 body part using the bodypart func */
482  status = X400msMsgAddAttachment (mp, X400_T_IA5TEXT, text, strlen(text));
483  if ( status != X400_E_NOERROR ) {
484  printf("failed to add X400_T_IA5TEXT BP\n");
485  return (status);
486  }
487  printf("Sent IA5 content:\n%s\n", text);
488 
489  /* or a Binary body part using the bodypart func */
490  if (filename_to_send != NULL) {
491  binary_data = (char *) malloc(100000);
492  if ( binary_data == NULL )
493  return X400_E_NOMEMORY;
494  fp = fopen(filename_to_send, "r");
495  if (fp == (FILE *)NULL) {
496  printf("Cannot open binary file\n");
497  return (X400_E_SYSERROR);
498  }
499  if ((fs = fread (binary_data, sizeof(char), 100000/sizeof(char), fp) ) == -1) {
500  printf("Cannot read from binary file\n");
501  return (X400_E_SYSERROR);
502  }
503  fclose(fp);
504 
505  status = X400msMsgAddAttachment (mp, X400_T_BINARY, binary_data, fs);
506  if ( status != X400_E_NOERROR ) {
507  printf("failed to add X400_T_BINARY BP\n");
508  return (status);
509  }
510  } else {
511  printf("no binary file set - not sending X400_T_BINARY\n");
512  }
513 
514  status = X400msMsgSend (mp);
515  if ( status != X400_E_NOERROR ) {
516  fprintf (stderr, "x400msMsgSend returned error: %s\n", X400msError (status));
517  return (status);
518  } else {
519  printf("Message submitted successfully\n");
520  }
521 
522  status = X400msMsgDelete (mp, 0);
523  if ( status != X400_E_NOERROR ) {
524  fprintf (stderr, "x400msMsgDelete returned error: %s\n", X400msError (status));
525  return (status);
526  }
527 
528  mp = NULL;
529  rp = NULL;
530 
531  return (status);
532 }
533 
534 
535 static int setup_default_new_sec_env(
536  struct X400msSession *sp,
537  char *identity,
538  char *pw
539 )
540 {
541  int status;
542 
543  /* Filename of the Digital Identity (PKCS12 file) */
545  identity, -1);
546  if ( status != X400_E_NOERROR ) {
547  fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
548  X400msError (status));
549  return (status);
550  }
551 
552  /* Passphrase of the private key in the above Digital Identity */
554  if ( status != X400_E_NOERROR ) {
555  fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
556  X400msError (status));
557  return (status);
558  }
559 
560  /* test the sec env */
561  status = X400msTestSecurityEnv (sp);
562  if ( status != X400_E_NOERROR ) {
563  fprintf (stderr, "X400msTestSecurityEnv returned error: %s\n",
564  X400msError (status));
565  return (status);
566  }
567 
568  printf ("X400msTestSecurityEnv returned success\n");
569 
570  return status;
571 }
572 
573 static int setup_default_old_sec_env(
574  struct X400msSession *sp,
575  char *id,
576  char *dn,
577  char *pw
578 )
579 {
580  int status;
581 
582  /* first set a default security identity. This passes in the name of a
583  * directory, which contains an x509 subdirectory in which all Identities
584  * are held */
586 
587  /* select by DN which Identity is to be used (if there are several)
588  * Currently these must be PKCS12 files */
589  status = X400msSetStrDefault (sp, X400_S_SEC_IDENTITY_DN, dn, -1);
590  if ( status != X400_E_NOERROR ) {
591  fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
592  X400msError (status));
593  return (status);
594  }
595 
596  /* Passphrase of the private key in the above Digital Identity */
598  if ( status != X400_E_NOERROR ) {
599  fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
600  X400msError (status));
601  return (status);
602  }
603 
604  return status;
605 }
606 
607 static int setup_msg_new_sec_env(
608  struct X400msMessage *mp, /* message object */
609  char *identity,
610  char *pw
611 )
612 {
613  int status;
614 
615  /* Filename of the Digital Identity (PKCS12 file) */
617  identity, -1);
618  if ( status != X400_E_NOERROR ) {
619  fprintf (stderr, "X400msMsgAddStrParam returned error: %s\n",
620  X400msError (status));
621  return (status);
622  }
623 
624  /* Passphrase of the private key in the above Digital Identity */
626  if ( status != X400_E_NOERROR ) {
627  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
628  X400msError (status));
629  return (status);
630  }
631  return (status);
632 }
633 
634 static int setup_msg_old_sec_env(
635  struct X400msMessage *mp, /* message object */
636  char *id,
637  char *dn,
638  char *pw
639 )
640 {
641  int status;
642 
643  /* overide the default security environment by specifying a new set of
644  * attibutes, and put them into the message */
645  /* security additions */
646  status = X400msMsgAddStrParam (mp, X400_S_SEC_IDENTITY, id, -1);
647  /* status = X400msMsgAddStrParam (mp, X400_S_SEC_IDENTITY, "/var/isode/dsa-db", -1); */
648  if ( status != X400_E_NOERROR ) {
649  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
650  X400msError (status));
651  return (status);
652  }
653 
654  /* security additions */
655  status = X400msMsgAddStrParam (mp, X400_S_SEC_IDENTITY_DN, dn, -1);
656  if ( status != X400_E_NOERROR ) {
657  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
658  X400msError (status));
659  return (status);
660  }
661 
662  /* security additions */
664  if ( status != X400_E_NOERROR ) {
665  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
666  X400msError (status));
667  return (status);
668  }
669  return (status);
670 }
671 
672 static int add_sec_label(
673  struct X400msMessage *mp /* message object */
674 )
675 {
676 #define XML_BUFSIZE 1024
677 #define STRING_BUFSIZE 1024
678 
679  const char* xml_filename = "seclabel.xml";
680  char xml_content[XML_BUFSIZE];
681  char xml_content_inserted[XML_BUFSIZE];
682  char str_content[STRING_BUFSIZE];
683  int str_len = STRING_BUFSIZE;
684  FILE *fd = NULL;
685  int status;
686 
687  /* Read in the security label XML file */
688  fd = fopen(xml_filename,"r");
689  if(fd == NULL) {
690  fprintf(stderr,"Failed to open %s : %s\n",
691  xml_filename,strerror(errno));
692  return X400_E_INT_ERROR;
693  }
694 
695  fread(&xml_content,XML_BUFSIZE,1,fd);
696 
697  fclose(fd);
698 
699  status = SecLabelInit("Example program");
700  if (status != SECLABEL_E_NOERROR) {
701  fprintf(stderr, "SecLabelInit returned error %d\n", status);
702  return(X400_E_INT_ERROR);
703  }
704 
705  /* Use SecLabelParse to turn the XML into an octect string */
706  status = SecLabelParse(xml_content,
707  str_content,
708  STRING_BUFSIZE,
709  &str_len);
710 
711  if (status != SECLABEL_E_NOERROR) {
712  fprintf(stderr, "SecLabelParse returned error %d\n", status);
713  return(X400_E_INT_ERROR);
714  }
715 
716 
717  if ((gen_4406_sig) && (send_4406_label)) {
718  /* Insert into the CMS signature */
719  /* Add the octet string to the message pointer */
721  str_content,str_len);
722  if ( status != X400_E_NOERROR ) {
723  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
724  X400msError (status));
725  return (status);
726  }
727  }
728 
729  if (send_x411_label) {
730  /* Insert into the envelope */
731  /* Add the octet string to the message pointer */
733  str_content,str_len);
734  if ( status != X400_E_NOERROR ) {
735  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
736  X400msError (status));
737  return (status);
738  }
739  } else {
740  printf("\nNot requesting X.411 Label\n");
741  }
742 
743  /* check what we inserted */
744  (void) SecLabelPrint((const unsigned char *)str_content,
745  str_len,
746  xml_content_inserted,
747  XML_BUFSIZE);
748 
749  /* write out the XML we read from file and inserted ..*/
750  if (send_x411_label) {
751  printf("Added this X.411 security label:%s\n", xml_content);
752  } else {
753  printf("Not adding X.411 security label\n");
754  }
755  if ((gen_4406_sig) && (send_4406_label)) {
756  printf("Added this 4406 security label:%s\n", xml_content_inserted);
757  } else {
758  printf("Not adding 4406 security label\n");
759  }
760 
761  return X400_E_NOERROR;
762 }
763 
764 static int add_content(
765  struct X400msMessage *mp /* message object */
766 )
767 {
768  FILE *fp = NULL;
769  int fs = 0;
770  int status;
771 
772  /* add some attachments/body parts
773  * Strictly a message simply has a sequence of body parts.
774  * However in human terms, it can be useful to treat the Body Parts
775  * as
776  * - text, i.e. an IA5 or general text attachment
777  * - followed by 0 or more attachments (e.g. documents, images etc)
778  *
779  * The API allows for either style.
780  *
781  * Use the AddStrParam() function to add a text attachment
782  * Use the X400msMsgAddAttachment() function to add a Body Part
783  * Use the X400msMsgAddMessageBodyWType() function to add structured
784  * Body Part (e.g. message, FTBP)
785  */
786 
787  status = X400msMsgAddStrParam (mp, X400_T_ISO8859_1, text, -1);
788  if ( status != X400_E_NOERROR ) {
789  fprintf (stderr, "x400ms returned error: %s\n", X400msError (status));
790  return (status);
791  }
792  printf("Sent 8859 attachment as string:\n%s\n", text);
793 
794  if (send_ia5_as_att) {
795  /* now an IA5 body attachment using the attachment func */
796  status = X400msMsgAddAttachment (mp, X400_T_IA5TEXT,
797  text, strlen(text));
798  if ( status != X400_E_NOERROR ) {
799  printf("failed to add X400_T_IA5TEXT attachment\n");
800  return (status);
801  }
802  printf("Sent IA5 as first attachment:\n%s\n", text);
803  } else {
804  /* now an IA5 attachment using the str func */
805  status = X400msMsgAddStrParam (mp, X400_T_IA5TEXT, text, -1);
806  if ( status != X400_E_NOERROR ) {
807  printf("failed to add X400_T_IA5TEXT BP\n");
808  return (status);
809  }
810  printf("Sent IA5 as string in message \n%s\n", text);
811  }
812 
813  /* now an 8859-1 body attachment using the attachment func */
814  status = X400msMsgAddAttachment (mp, X400_T_ISO8859_1, text, strlen(text));
815  if ( status != X400_E_NOERROR ) {
816  printf("failed to add X400_T_ISO8859_1, attachment\n");
817  return (status);
818  }
819  printf("Sent 8859-1 as attachment:\n%s\n", text);
820 
821  /* or a Binary body part using the bodypart func */
822  if (filename_to_send != NULL) {
823  binary_data = (char *) malloc(100000);
824  if ( binary_data == NULL )
825  return X400_E_NOMEMORY;
826  fp = fopen(filename_to_send, "r");
827  if (fp == (FILE *)NULL) {
828  printf("Cannot open binary file\n");
829  return (X400_E_SYSERROR);
830  }
831  if ((fs = fread (binary_data, sizeof(char), 100000/sizeof(char), fp))
832  == -1) {
833  printf("Cannot read from binary file\n");
834  return (X400_E_SYSERROR);
835  }
836  fclose(fp);
837 
838  status = X400msMsgAddAttachment (mp, X400_T_BINARY, binary_data, fs);
839  if ( status != X400_E_NOERROR ) {
840  printf("failed to add X400_T_BINARY BP\n");
841  return (status);
842  }
843 
844  free (binary_data);
845 
846  } else {
847  printf("no binary file set - not sending X400_T_BINARY\n");
848  }
849  return status;
850 }
851 
852 static void usage(void) {
853  printf("usage: %s\n", optstr);
854  printf("\t where:\n");
855  printf("\t -u : Don't prompt to override defaults \n");
856  printf("\t -3 : Use P3 connection \n");
857  printf("\t -7 : Use P7 connection \n");
858  printf("\t -m : OR Address in P7 bind arg \n");
859  printf("\t -d : DN in P7 bind arg \n");
860  printf("\t -p : Presentation Address of P7 Store \n");
861  printf("\t -w : P7 password of P7 user \n");
862  printf("\t -M : OR Address in P3 bind arg \n");
863  printf("\t -D : DN in P3 bind arg \n");
864  printf("\t -P : Presentation Address of P3 server\n");
865  printf("\t -W : P3 password of P3 user \n");
866  printf("\t -o : Originator \n");
867  printf("\t -O : Originator Return Address \n");
868  printf("\t -r : Recipient\n");
869  printf("\t -l : Logline\n");
870  printf("\t -y : Military Priority \n");
871  printf("\t\t 0 - deferred, 1 - routine, 2 - priority \n");
872  printf("\t\t 3 - immediate, 4 - flash, 5 - override \n");
873  printf("\t -C : Content Type (2/22/772/OID) \n");
874  printf("\t -i : Implicit conversion prohibited = TRUE \n");
875  printf("\t -a : Alternate Recipient Prohibited = TRUE \n");
876  printf("\t -q : Content Return Request = TRUE \n");
877  printf("\t -s : Disclosure of Recipient = FALSE \n");
878  printf("\t -A : Recipient Reassignment Prohibited = FALSE \n");
879  printf("\t -v : Conversion with Loss Prohibited = FALSE \n");
880  printf("\t -e : Security Environment (dir with x509 subdir): obsolete, use -Y <p12file>\n");
881  printf("\t -x : DN of X.509 Digital Identity\n");
882  printf("\t -b : Passphrase for private key in PKCS12 file\n");
883  printf("\t -f : Filename to transfer as binary bp\n");
884  printf("\t -Y : Filename of PKCS12 file containing Digital Identity\n");
885  printf("\t -Z : Generate MOAC Signature\n");
886  printf("\t -4 : Generate STANAG 4406 PCT Signatures\n");
887  printf("\t -B : Subject of message\n");
888  printf("\t -F : String to insert in first line of text (e.g. as FLOT)\n");
889  printf("\t -N : Insert Security Label in (e)nvelope or (4)406 signature\n");
890  return;
891 }
892 
893 
#define X400_S_DIRECTORY_NAME
Definition: x400_att.h:397
#define X400_MSG_MESSAGE
Definition: x400_att.h:29
#define X400_S_EXTERNAL_CONTENT_TYPE
Definition: x400_att.h:447
#define X400_E_SYSERROR
Definition: x400_att.h:49
#define X400_S_LOG_CONFIGURATION_FILE
Definition: x400_att.h:1091
int X400msSetStrDefault(struct X400msSession *sp, int paramtype, const char *value, size_t length)
Set a default string parameter value in a session.
#define X400_S_CONTENT_IDENTIFIER
Definition: x400_att.h:414
int X400msMsgAddStrParam(struct X400msMessage *mp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
#define X400_S_SEC_IDENTITY
Definition: x400_att.h:554
int X400msTestSecurityEnv(struct X400msSession *sp)
Test the default Security Environment.
int X400msRecipAddIntParam(struct X400Recipient *rp, int paramtype, int value)
Add integer-valued parameter to the message.
#define X400_N_PRECEDENCE
Definition: x400_att.h:685
const char * X400msError(int error)
Obtain a string describing the meaning of the given error code.
#define X400_S_S4406_SECURITY_LABEL
Definition: x400_att.h:618
int X400msMsgNew(struct X400msSession *sp, int type, struct X400msMessage **mpp)
Creates new message.
int X400msClose(struct X400msSession *sp)
Close a X400 Session.
#define X400_T_ISO8859_1
Definition: x400_att.h:808
#define X400_N_NOTIFICATION_REQUEST
Definition: x400_att.h:675
int X400msMsgAddAttachment(struct X400msMessage *mp, int type, const char *string, size_t length)
Add attachment to the message.
int X400msRecipAddStrParam(struct X400Recipient *rp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
#define X400_T_IA5TEXT
Definition: x400_att.h:798
#define X400_E_NOERROR
Definition: x400_att.h:46
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_OR_ADDRESS
Definition: x400_att.h:349
#define X400_N_CONTENT_TYPE
Definition: x400_att.h:408
#define X400_S_SEC_IDENTITY_PASSPHRASE
Definition: x400_att.h:560
#define X400_RECIP_STANDARD
Definition: x400_att.h:341
#define X400_T_BINARY
Definition: x400_att.h:824
#define X400_S_SECURITY_LABEL
Definition: x400_att.h:1338
#define X400_S_SEC_IDENTITY_DN
Definition: x400_att.h:563
#define X400_N_REPORT_REQUEST
Definition: x400_att.h:653
int X400msMsgSend(struct X400msMessage *mp)
Send message object.
X400 MA/MS (P3/P7) Interface.
#define X400_S_SEC_IDENTITY_FILE
Definition: x400_att.h:578
int X400msRecipNew(struct X400msMessage *mp, int type, struct X400Recipient **rpp)
Add new recipient to a message.
#define X400_E_NOMEMORY
Definition: x400_att.h:52
#define X400_N_S4406
Definition: x400_att.h:598
#define X400_S_SUBJECT
Definition: x400_att.h:722
#define X400_E_INT_ERROR
Definition: x400_att.h:58
#define X400_B_SEC_GEN_MOAC
Definition: x400_att.h:557
int X400msMsgAddIntParam(struct X400msMessage *mp, int paramtype, int value)
Add integer-valued parameter to the message.
int X400msMsgDelete(struct X400msMessage *mp, int retain)
Delete message object.