x400_mssend_msg_tok_sign.c
1/* Copyright (c) 2009-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 *
15 *
16 * Simple example program for submitting a message via a message store.
17 * The security environment is set up so that messages are signed with
18 * a per recipient message token.
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#ifndef _WIN32
26#include <unistd.h>
27#endif
28#include <fcntl.h>
29#include <errno.h>
30
31#include <x400_msapi.h>
32#include <seclabel_api.h> /* For security labels */
33#include "example.h"
34#include "ms_example.h"
35#include "time.h"
36
37/* uncomment this if you want a second recipient.
38 * NB as the recipient name is the same, M-Switch
39 * removes the duplicate envelope recips */
40/*
41#define tworecips 1
42*/
43
44/* uncomment this to cause the API to generate msg_seq_nums which
45 * increment by 1 per message per session */
46#define FIRST_SEQ_NUM 2
47
48#ifdef FIRST_SEQ_NUM
49int seq_num_val_1 = FIRST_SEQ_NUM;
50int seq_num_val_2 = FIRST_SEQ_NUM + 100;
51#endif
52
53/* set this to non zero to cause the IA5 body part to be an attachment */
54int send_ia5_as_att = 0;
55
56/*
57#define ADD_MOAC
58*/
59
60static 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:Y:S:j:";
61
62/* These are the data items used to construct the message for submission */
63static char *default_recip = "/CN=P7User1/OU=sales/O=attlee/PRMD=TestPRMD/ADMD=TestADMD/C=GB/";
64char *recip;
65char *recip2;
66static char *content_id = "030924.140212";
67static const char text[] = "First line\r\nSecond line\r\n";
68
69int adding_sec_label = 1;
70
71/* local functions */
72
73static void usage(void) ;
74static int send_msg(
75 int contype,
76 char *orn,
77 char *def_dn,
78 char *pa,
79 char *password);
80
81static int submit_msg(
82 char *orn,
83 struct X400msSession *sp /* session object */
84);
85
86static int setup_default_new_sec_env(
87 struct X400msSession *sp,
88 char *identity_filename,
89 char *pw
90);
91
92
93static int setup_default_old_sec_env(
94 struct X400msSession *sp,
95 char *id,
96 char *dn,
97 char *pw
98);
99
100#ifdef notused
101static int setup_msg_new_sec_env(
102 struct X400msMessage *mp, /* message object */
103 char *identity_filename,
104 char *pw
105);
106
107
108static int setup_msg_old_sec_env(
109 struct X400msMessage *mp, /* message object */
110 char *id,
111 char *dn,
112 char *pw
113);
114
115static int setup_recip_new_sec_env(
116 struct X400Recipient *rp, /* recipient object */
117 char *identity_filename,
118 char *pw /* passphrase for private key in pkcs12 file */
119);
120
121static int setup_recip_old_sec_env(
122 struct X400Recipient *rp, /* recipient object */
123 char *id, /* x509 identity (directory with x509 subdir) */
124 char *dn, /* DN to use as subject of the X.509 identity */
125 char *pw /* passphrase for private key in pkcs12 file */
126);
127
128#endif
129
130
131static int add_recip(
132 struct X400msMessage *mp, /* message object */
133 char *recip
134);
135
136static int add_content(
137 struct X400msMessage *mp /* message object */
138);
139
140static int add_binary_bp(
141 struct X400msMessage *mp
142);
143
144static int add_ftbp(
145 struct X400msMessage *mp
146);
147
148static int add_ia5_str(
149 struct X400msMessage *mp
150);
151
152/* start here */
153int main (
154 int argc,
155 char **argv
156)
157{
158 char pa[BUFSIZ];
159 char orn[BUFSIZ];
160 char *def_oraddr;
161 char *def_dn;
162 char *def_pa;
163 int contype;
164 int status;
165 char password[BUFSIZ];
166
167 if (get_args(argc, argv, optstr)) {
168 usage();
169 exit(-1);
170 }
171
172 printf("Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [%d]: ", x400_contype);
173 contype = ic_fgetc(x400_contype, stdin);
174 if (contype != 10)
175 ic_fgetc(x400_contype, stdin);
176
177 if ( contype < '0' || '2' < contype )
178 contype = x400_contype;
179 else
180 contype -= '0';
181
182 if (contype == 0) {
183 def_oraddr = x400_ms_user_addr;
184 def_dn = x400_ms_user_dn;
185 def_pa = x400_ms_presentation_address;
186 } else {
187 def_oraddr = x400_mta_user_addr;
188 def_dn = x400_mta_user_dn;
189 def_pa = x400_mta_presentation_address;
190 }
191
192 printf("Your ORAddress [%s] > ", def_oraddr);
193 ic_fgets (orn, sizeof orn, stdin);
194
195 if ( orn[strlen(orn)-1] == '\n' )
196 orn[strlen(orn)-1] = '\0';
197
198 if (orn[0] == '\0')
199 strcpy(orn, def_oraddr);
200
201 /* Prompt for password; note: reflected. */
202 printf ("Password [%s]: ",
203 contype == 0 ? x400_p7_password : x400_p3_password);
204 if ( ic_fgets (password, sizeof password, stdin) == NULL )
205 exit (1);
206
207 if (password[strlen(password)-1] == '\n' )
208 password[strlen(password)-1] = '\0';
209 if (password[0] == '\0')
210 strcpy(password, contype == 0 ? x400_p7_password : x400_p3_password);
211
212 /* Presentation Address */
213 printf("Presentation Address [%s] > ", def_pa);
214 ic_fgets (pa, sizeof pa, stdin);
215
216 if ( pa[strlen(pa)-1] == '\n' )
217 pa[strlen(pa)-1] = '\0';
218
219 if (pa[0] == '\0')
220 strcpy(pa, def_pa);
221
222 printf("sending message using session 1\n");
223 if ((status = send_msg(contype, orn, def_dn, pa, password))
224 != X400_E_NOERROR ) {
225 fprintf (stderr, "Error in sending message\n");
226 exit (status);
227 }
228
229#ifdef notdef
230 printf("sending message using session 2\n");
231 if ((status = send_msg(contype, orn, def_dn, pa, password))
232 != X400_E_NOERROR ) {
233 fprintf (stderr, "Error sending message\n");
234 exit (status);
235 }
236#endif
237
238 return (status);
239}
240
241static int send_msg(
242 int contype,
243 char *orn,
244 char *def_dn,
245 char *pa,
246 char *password
247)
248{
249 struct X400msSession *sp; /* session object */
250
251 int status;
252 int nummsg;
253
254
255 /* Open an API session */
256 status = X400msOpen (contype, orn, def_dn, password, pa, &nummsg, &sp);
257 if ( status != X400_E_NOERROR ) {
258 fprintf (stderr, "Error in Open: %s\n", X400msError (status));
259 fprintf (stderr, "%s %s %s\n", orn, def_dn, pa);
260 return (status);
261 }
262
263 /* setup logging */
265
266 /* Set up the security environment.
267 *
268 * In R15.0 this need only be the name of a trusted certificate directory.
269 *
270 * Prior to R15.0, the ID is specified as a pathname, in which the
271 * subdirectory "x509" is expected to contain one or more PKCS12
272 * files. The appropriate Digital Identity is determined from the
273 * DN of the subject, and the passphrase is used to decrypt the
274 * private key. NB even though we're not going to use our cert,
275 * (as we're going to use the cert in the message to check the MOAC
276 * we need to do this due to a limitation in the underlying X.509
277 * layer.
278 */
279
280 if (use_new_sec_env) {
281 status = setup_default_new_sec_env(sp, identity_filename, passphrase);
282 } else {
283 status = setup_default_old_sec_env(sp, security_id,
284 identity_dn, passphrase);
285 }
286
287 if ( status != X400_E_NOERROR ) {
288 fprintf (stderr, "Can't setup security environment\n");
289 return (status);
290 }
291
292 printf("sending message 1\n");
293 status = submit_msg(orn, sp);
294 if ( status != X400_E_NOERROR ) {
295 fprintf (stderr, "Can't submit\n");
296 return (status);
297 }
298
299/*
300 printf("sending message 2\n");
301 status = submit_msg(orn, sp);
302 if ( status != X400_E_NOERROR ) {
303 fprintf (stderr, "Can't submit\n");
304 return (status);
305 }
306 printf("sending message 3\n");
307 status = submit_msg(orn, sp);
308 if ( status != X400_E_NOERROR ) {
309 fprintf (stderr, "Can't submit\n");
310 return (status);
311 }
312*/
313 status = X400msClose (sp);
314 if ( status != X400_E_NOERROR ) {
315 fprintf (stderr, "X400msClose returned error: %s\n", X400msError (status));
316 return (status);
317 }
318 return status;
319}
320
321static int submit_msg(
322 char *orn,
323 struct X400msSession *sp /* session object */
324)
325{
326 struct X400msMessage *mp; /* message object */
327#ifdef tworecips
328 struct X400Recipient *rp2; /* recipient object */
329#endif
330 char tmp[BUFSIZ];
331 static int msg_num = 0;
332 int status;
333
334 msg_num++;
335
336 if (x400_default_recipient != NULL) {
337 recip = x400_default_recipient;
338 recip2 = x400_default_recipient;
339 } else {
340 recip = default_recip;
341 recip2 = default_recip;
342 }
343
344 printf("Message recipient [%s]: ", recip);
345 ic_fgets (tmp, sizeof tmp, stdin);
346
347 if ( tmp[strlen(tmp)-1] == '\n' )
348 tmp[strlen(tmp)-1] = '\0';
349 if (strlen(tmp) != 0) {
350 recip = strdup(tmp);
351 recip2 = strdup(tmp);
352 }
353
354 printf("Subject [%s]: ", subject);
355 ic_fgets (tmp, sizeof tmp, stdin);
356
357 if ( tmp[strlen(tmp)-1] == '\n' )
358 tmp[strlen(tmp)-1] = '\0';
359 if (strlen(tmp) != 0)
360 subject = strdup(tmp);
361
362 printf("\n");
363 status = X400msMsgNew (sp, X400_MSG_MESSAGE, &mp);
364 if ( status != X400_E_NOERROR ) {
365 fprintf (stderr, "x400msMsgNew returned error: %s\n",
366 X400msError (status));
367 return (status);
368 }
369
370#ifdef use_diff_sec_env_second_msg
371 if (msg_num > 1) {
372 /* set up a security env for the message - this will be used in
373 * preference to the default security env */
374 status = setup_msg_sec_env(mp, "/root",
375 "cn=P7User1,o=Address Book,c=GB", "secret");
376 if ( status != X400_E_NOERROR ) {
377 fprintf (stderr, "setup_msg_sec_env returned error: %s\n",
378 X400msError (status));
379 /* ignore - let's see if the defaults work */
380 }
381 }
382#endif
383
384#define S4404_ENCRYPT
385#ifdef S4404_ENCRYPT
386 /* Instruct the X400msMsgSend() function to generate a
387 * an S4406 (PCT) encrypted message.
388 * The default attributes will be used unless the attributes are
389 * also included in the message eg by calling setup_msg_sec_env() above */
390 status = X400msMsgAddIntParam (mp, X400_N_S4406, 1);
391 if ( status != X400_E_NOERROR ) {
392 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
393 X400msError (status));
394 return (status);
395 } else {
396 fprintf (stderr, "encrypting message as S4406 (PCT) \n");
397 }
398#endif
399#ifdef ADD_MOAC
400 /* Instruct the X400msMsgSend() function to generate a
401 * MOAC (signature) for
402 * the message Instruct the X400msMsgSend() function to generate a MOAC
403 * (signature) for the message
404 * The default attributes will be used unless the attributes are
405 * also included in the message eg by calling setup_msg_sec_env() above */
407 if ( status != X400_E_NOERROR ) {
408 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
409 X400msError (status));
410 return (status);
411 } else {
412 fprintf (stderr, "Adding MOAC\n");
413 }
414#endif
415
416
417 /* originator */
418 status = X400msMsgAddStrParam (mp, X400_S_OR_ADDRESS, orn, -1);
419 if ( status != X400_E_NOERROR ) {
420 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
421 X400msError (status));
422 return (status);
423 }
424
426 "CN=originator;c=gb", -1);
427 if ( status != X400_E_NOERROR ) {
428 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
429 X400msError (status));
430 return (status);
431 }
432
433 if (adding_sec_label) {
434 status = add_sec_label (mp);
435 if ( status != X400_E_NOERROR ) {
436 fprintf (stderr, "Failed to add Security Label: %s\n",
437 X400msError (status));
438 return (status);
439 } else {
440 fprintf (stderr, "added Security Label\n");
441 }
442 }
444 content_id, -1);
445 if ( status != X400_E_NOERROR ) {
446 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
447 X400msError (status));
448 return (status);
449 }
450
451 /*
452 status = X400msMsgAddStrParam (mp, X400_S_SUBJECT, subject, -1);
453 if ( status != X400_E_NOERROR ) {
454 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
455 X400msError (status));
456 return (status);
457 }
458*/
459
460 /* Priority: X.400 0 - normal, 1 - non-urgent, 2 - urgent */
461 /* Military 0 - deferred, 1 - routine, 2 - priority \n"); */
462 /* 3 - immediate, 4 - flash, 5 - override \n"); */
463 printf("military message priority is %d (%s) \n",
464 x400_default_priority,
465 get_x400_pty_str_from_4406(x400_default_priority));
467 get_x400_pty_from_4406(x400_default_priority));
468 if ( status != X400_E_NOERROR ) return (status);
469
470 /* Priority qaulifier: 0 - low, 1 - high */
471 printf("military message priority qualifer is %d ( 0 - low, 1 - high)\n",
472 get_x400_pty_qual_from_4406(x400_default_priority));
474 get_x400_pty_qual_from_4406(x400_default_priority));
475 if ( status != X400_E_NOERROR ) return (status);
476
477 /* subject */
478 {
479 time_t t;
480 time(&t);
481 char tmp_buffer[255];
482 // NB strip newline from ctime result
483 snprintf(tmp_buffer, 244, "%s '%s' '%.19s'",
484 subject, get_x400_pty_str_from_4406(x400_default_priority), ctime(&t));
485 printf("Subject is '%s'\n", tmp_buffer);
486 status = X400msMsgAddStrParam (mp, X400_S_SUBJECT, tmp_buffer, -1);
487 if ( status != X400_E_NOERROR ) {
488 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
489 X400msError (status));
490 exit (status);
491 }
492 }
493
494 /* content type */
495 //status = X400msMsgAddStrParam (mp, X400_S_EXTERNAL_CONTENT_TYPE, "1.3.26.0.4406.0.4.1", -1);
496 status = X400msMsgAddStrParam (mp, X400_S_EXTERNAL_CONTENT_TYPE, "1.2.840.113549.1.9.16.1.6", -1);
497 if ( status != X400_E_NOERROR ) {
498 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
499 exit (status);
500 }
501
502 if (add_recip(mp, recip) != X400_E_NOERROR) {
503 fprintf (stderr, "add_recip() returned error: %s\n",
504 X400msError (status));
505 return (status);
506 }
507
508 /*
509 * Use this to add a second recip
510 *
511 if (add_recip(mp, "/G=P7/S=User2/ou=acp127/O=centos64-1/ADMD= /C=GB/") != X400_E_NOERROR) {
512 fprintf (stderr, "add_recip() returned error: %s\n",
513 X400msError (status));
514 return (status);
515 }
516 */
517
518 if (add_content(mp) != X400_E_NOERROR) {
519 fprintf (stderr, "add_content() returned error: %s\n",
520 X400msError (status));
521 return (status);
522 }
523
524 status = X400msMsgSend (mp);
525 if ( status != X400_E_NOERROR ) {
526 fprintf (stderr, "x400msMsgSend returned error: %s\n",
527 X400msError (status));
528 return (status);
529 } else {
530 printf("Message submitted successfully\n");
531 }
532
533 status = X400msMsgDelete (mp, 0);
534 if ( status != X400_E_NOERROR ) {
535 fprintf (stderr, "x400msMsgDelete returned error: %s\n",
536 X400msError (status));
537 return (status);
538 }
539
540 mp = NULL;
541 return (status);
542}
543
544
545static int add_recip(
546 struct X400msMessage *mp, /* message object */
547 char *local_recip
548)
549{
550 int status;
551 struct X400Recipient *rp; /* recipient object */
552
553 /* first recip */
554 status = X400msRecipNew (mp, X400_RECIP_STANDARD, &rp);
555 if ( status != X400_E_NOERROR ) {
556 fprintf (stderr, "x400msRecipNew returned error: %s\n",
557 X400msError (status));
558 return (status);
559 }
560
561 /* put precedence extension into primary recipient */
563 if ( status != X400_E_NOERROR ) {
564 fprintf (stderr, "x400msRecipAddIntParam returned error: %s\n",
565 X400msError (status));
566 return (status);
567 }
568
569
570 status = X400msRecipAddStrParam (rp, X400_S_OR_ADDRESS, local_recip, -1);
571 if ( status != X400_E_NOERROR ) {
572 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n",
573 X400msError (status));
574 return (status);
575 }
576
578 "CN=recipient;c=gb", -1);
579 if ( status != X400_E_NOERROR ) {
580 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n",
581 X400msError (status));
582 return (status);
583 }
584
585 /* cause a PODR to be added as a recip extension */
587 if ( status != X400_E_NOERROR ) {
588 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
589 X400msError (status));
590 return (status);
591 }
592
593 /* cause a Content Integrity Check to be added as a recip extension */
595 if ( status != X400_E_NOERROR ) {
596 fprintf (stderr, "X400msRecipAddIntParam returned error: %s\n",
597 X400msError (status));
598 return (status);
599 }
600
601 /* Ask for Message Token for this recip */
602 fprintf (stderr, "requesting token\n");
604 if ( status != X400_E_NOERROR ) {
605 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n",
606 X400msError (status));
607 return (status);
608 }
609
610#ifdef FIRST_SEQ_NUM
611 /* Add sequence num */
613 seq_num_val_1);
614 if ( status != X400_E_NOERROR ) {
615 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n",
616 X400msError (status));
617 return (status);
618 } else {
619 fprintf (stderr, "Added sequence number %d for token\n", seq_num_val_1);
620 }
621 seq_num_val_1++;
622#endif
623
624
625 /* Ask for +ve and -ve delivery reports */
626 /* status = X400msRecipAddIntParam (rp, X400_N_REPORT_REQUEST, 2); */
627 /* Ask for no +ve and -ve delivery reports */
629 if ( status != X400_E_NOERROR ) {
630 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n",
631 X400msError (status));
632 return (status);
633 }
634
635 /* Ask for +ve and -ve read receipts */
637 if ( status != X400_E_NOERROR ) {
638 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n",
639 X400msError (status));
640 return (status);
641 }
642 return X400_E_NOERROR;
643}
644
645
646static int setup_default_new_sec_env(
647 struct X400msSession *sp,
648 char *idf,
649 char *pw
650)
651{
652 int status;
653
654 fprintf (stderr, "using new_sec_nv %s\n", idf);
655 /* Filename of the Digital Identity (PKCS12 file)
656 * This supersedes the obsolescent X400_S_SEC_IDENTITY,
657 * X400_S_SEC_IDENTITY_DN attributes */
659 idf, -1);
660 if ( status != X400_E_NOERROR ) {
661 fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
662 X400msError (status));
663 return (status);
664 }
665
666 /* passphrase used to open the Identity */
668 if ( status != X400_E_NOERROR ) {
669 fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
670 X400msError (status));
671 return (status);
672 }
673
674 /* test the sec env */
675 status = X400msTestSecurityEnv (sp);
676 if ( status != X400_E_NOERROR ) {
677 fprintf (stderr, "X400msTestSecurityEnv returned error: %s\n",
678 X400msError (status));
679 return (status);
680 }
681
682 return status;
683}
684
685
686static int setup_default_old_sec_env(
687 struct X400msSession *sp,
688 char *id,
689 char *dn,
690 char *pw
691)
692{
693 int status;
694
695 fprintf (stderr, "using old_sec_nv\n");
696 /* first set a default security identity. This passes in the name of a
697 * directory, which contains an x509 subdirectory in which all Identities
698 * are held */
700
701 /* select by DN which Identity is to be used (if there are several)
702 * Currently these must be PKCS12 files */
703 status = X400msSetStrDefault (sp, X400_S_SEC_IDENTITY_DN, dn, -1);
704 if ( status != X400_E_NOERROR ) {
705 fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
706 X400msError (status));
707 return (status);
708 }
709
710 /* passphrase used to open the Identity */
712 if ( status != X400_E_NOERROR ) {
713 fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
714 X400msError (status));
715 return (status);
716 }
717 return status;
718}
719
720#ifdef notused
721static int setup_msg_new_sec_env(
722 struct X400msMessage *mp, /* message object */
723 char *identity_filename,
724 char *pw /* passphrase for private key in pkcs12 file */
725)
726{
727 int status;
728
729 /* Filename of the Digital Identity (PKCS12 file)
730 * This supersedes the obsolescent X400_S_SEC_IDENTITY,
731 * X400_S_SEC_IDENTITY_DN attributes */
733 identity_filename, -1);
734 if ( status != X400_E_NOERROR ) {
735 fprintf (stderr, "X400msMsgAddStrParam returned error: %s\n",
736 X400msError (status));
737 return (status);
738 }
739
740 printf("setting up new message security env %s\n", identity_filename);
741
742 /* security additions */
744 if ( status != X400_E_NOERROR ) {
745 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
746 X400msError (status));
747 return (status);
748 }
749 return (status);
750}
751
752static int setup_msg_old_sec_env(
753 struct X400msMessage *mp, /* message object */
754 char *id, /* x509 identity (directory with x509 subdir) */
755 char *dn, /* DN to use as subject of the X.509 identity */
756 char *pw /* passphrase for private key in pkcs12 file */
757)
758{
759 int status;
760
761 printf("setting up message security env %s\n", id);
762
763 /* overide the default security environment by specifying a new set of
764 * attibutes, and put them into the message */
765 /* security additions */
766 status = X400msMsgAddStrParam (mp, X400_S_SEC_IDENTITY, id, -1);
767 if ( status != X400_E_NOERROR ) {
768 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
769 X400msError (status));
770 return (status);
771 }
772
773 /* security additions */
774 status = X400msMsgAddStrParam (mp, X400_S_SEC_IDENTITY_DN, dn, -1);
775 if ( status != X400_E_NOERROR ) {
776 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
777 X400msError (status));
778 return (status);
779 }
780
781 printf("setting up new message security env %s\n", identity_filename);
782
783 /* security additions */
785 if ( status != X400_E_NOERROR ) {
786 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
787 X400msError (status));
788 return (status);
789 }
790 return (status);
791}
792
793static int setup_recip_new_sec_env(
794 struct X400Recipient *rp, /* recipient object */
795 char *identity_filename,
796 char *pw /* passphrase for private key in pkcs12 file */
797)
798{
799 int status;
800
801 printf("setting up recipient security env %s\n", identity_filename);
802
803 /* Filename of the Digital Identity (PKCS12 file)
804 * This supersedes the obsolescent X400_S_SEC_IDENTITY,
805 * X400_S_SEC_IDENTITY_DN attributes */
807 identity_filename, -1);
808 if ( status != X400_E_NOERROR ) {
809 fprintf (stderr, "X400msRecipAddStrParam returned error: %s\n",
810 X400msError (status));
811 return (status);
812 }
813
814 status = X400msRecipAddStrParam (rp,
816 if ( status != X400_E_NOERROR ) {
817 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n",
818 X400msError (status));
819 return (status);
820 }
821
822 return (status);
823}
824
825
826static int setup_recip_old_sec_env(
827 struct X400Recipient *rp, /* recipient object */
828 char *id, /* x509 identity (directory with x509 subdir) */
829 char *dn, /* DN to use as subject of the X.509 identity */
830 char *pw /* passphrase for private key in pkcs12 file */
831)
832{
833 int status;
834
835 printf("setting up recipient security env %s\n", id);
836
837 /* overide the default and message security environment
838 * by specifying a new set of attibutes, and put them
839 * into the recipient security attributes */
840 status = X400msRecipAddStrParam (rp, X400_S_SEC_IDENTITY, id, -1);
841 if ( status != X400_E_NOERROR ) {
842 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n",
843 X400msError (status));
844 return (status);
845 }
846
847 status = X400msRecipAddStrParam (rp, X400_S_SEC_IDENTITY_DN, dn, -1);
848 if ( status != X400_E_NOERROR ) {
849 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n",
850 X400msError (status));
851 return (status);
852 }
853
854 status = X400msRecipAddStrParam (rp,
856 if ( status != X400_E_NOERROR ) {
857 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n",
858 X400msError (status));
859 return (status);
860 }
861
862 return (status);
863}
864#endif
865
866static int add_content(
867 struct X400msMessage *mp /* message object */
868)
869{
870 FILE *fp = NULL;
871 int fs = 0;
872 int status;
873 char *binary_data;
874
875 /* add some attachments/body parts
876 * Strictly a message simply has a sequence of body parts.
877 * However in human terms, it can be useful to treat the Body Parts
878 * as
879 * - text, i.e. an IA5 or general text attachment
880 * - followed by 0 or more attachments (e.g. documents, images etc)
881 *
882 * The API allows for either style.
883 *
884 * Use the AddStrParam() function to add a text attachment
885 * Use the X400msMsgAddAttachment() function to add a Body Part
886 * Use the X400msMsgAddMessageBodyWType() function to add structured
887 * Body Part (e.g. message, FTBP)
888 */
889
890 status = X400msMsgAddStrParam (mp, X400_T_ISO8859_1, text, -1);
891 if ( status != X400_E_NOERROR ) {
892 fprintf (stderr, "x400ms returned error: %s\n", X400msError (status));
893 return (status);
894 }
895 printf("Sent 8859 attachment as string:\n%s\n", text);
896
897 if (send_ia5_as_att) {
898 /* now an IA5 body attachment using the attachment func */
900 text, strlen(text));
901 if ( status != X400_E_NOERROR ) {
902 printf("failed to add X400_T_IA5TEXT attachment\n");
903 return (status);
904 }
905 printf("Sent IA5 as first attachment:\n%s\n", text);
906 } else {
907 /* now an IA5 attachment using the str func */
908 if (num_of_ia5_bytes == 0) {
909 status = X400msMsgAddStrParam (mp, X400_T_IA5TEXT, text, -1);
910 if ( status != X400_E_NOERROR ){
911 printf("failed to add X400_T_IA5TEXT BP\n");
912 return (status);
913 }
914 printf("Sent IA5 as string in message \n%s\n", text);
915 } else {
916 status = add_ia5_str(mp);
917 if ( status != X400_E_NOERROR ) {
918 printf("failed to add IA5 str\n");
919 return (status);
920 }
921 }
922 }
923
924 /* now an 8859-1 body attachment using the attachment func */
925 status = X400msMsgAddAttachment (mp, X400_T_ISO8859_1, text, strlen(text));
926 if ( status != X400_E_NOERROR ) {
927 printf("failed to add X400_T_ISO8859_1, attachment\n");
928 return (status);
929 }
930 printf("Sent 8859-1 as attachment:\n%s\n", text);
931
932 /* or a Binary body part using the bodypart func */
933 status = add_binary_bp(mp);
934 if ( status != X400_E_NOERROR ) {
935 printf("failed to add X400_T_BINARY BP\n");
936 return (status);
937 }
938
939 /* File Transfer Body Part using the bodypart func */
940 status = add_ftbp(mp);
941 if ( status != X400_E_NOERROR ) {
942 printf("failed to add X400_T_BINARY BP\n");
943 return (status);
944 }
945
946 return status;
947
948 if (filename_to_send != NULL) {
949 binary_data = (char *) malloc(100000);
950 if ( binary_data == NULL )
951 return X400_E_NOMEMORY;
952 fp = fopen(filename_to_send, "r");
953 if (fp == (FILE *)NULL) {
954 printf("Cannot open binary file\n");
955 return (X400_E_SYSERROR);
956 }
957 if ((fs = fread (binary_data, sizeof(char), 100000/sizeof(char), fp))
958 == -1) {
959 printf("Cannot read from binary file\n");
960 return (X400_E_SYSERROR);
961 }
962 fclose(fp);
963
964 status = X400msMsgAddAttachment (mp, X400_T_BINARY, binary_data, fs);
965 if ( status != X400_E_NOERROR ) {
966 printf("failed to add X400_T_BINARY BP\n");
967 return (status);
968 }
969
970 status = X400msMsgAddStrParam (mp, X400_T_IA5TEXT, text, -1);
971 if ( status != X400_E_NOERROR ){
972 printf("failed to add X400_T_IA5TEXT BP\n");
973 return (status);
974 }
975 printf("Sent IA5 as string in message \n%s\n", text);
976
977 free (binary_data);
978
979 } else {
980 printf("no binary file set - not sending X400_T_BINARY\n");
981 }
982 return status;
983}
984
985
986static int add_ia5_str(
987 struct X400msMessage *mp
988)
989{
990 int status;
991 char *tmp;
992 int i;
993 char *sample_ia5 = {"Here is some sample text to put into the IA5 attachment."};
994
995 if ((tmp = malloc(num_of_ia5_bytes + 1)) == NULL) {
996 printf("failed to malloc %d bytes\n", num_of_ia5_bytes);
997 return (X400_E_SYSERROR);
998 }
999 strcpy(tmp, text);
1000 for (i = strlen(text) ; i < num_of_ia5_bytes ; i++)
1001 tmp[i] = sample_ia5[i%strlen(sample_ia5)];
1002 tmp[i] = '\0';
1003
1004 status = X400msMsgAddStrParam (mp, X400_T_IA5TEXT, tmp, strlen(tmp));
1005 if ( status != X400_E_NOERROR ) {
1006 printf("failed to add X400_T_IA5TEXT BP\n");
1007 return (status);
1008 }
1009 printf("Sent %d bytes IA5 as string in message \n%s\n", i, tmp);
1010 return X400_E_NOERROR;
1011}
1012
1013
1014static int add_binary_bp(
1015 struct X400msMessage *mp
1016)
1017{
1018 FILE *fp = NULL;
1019 int fs=0;
1020 char *binary_data;
1021 int status;
1022
1023 /* or a Binary body part using the bodypart func */
1024 if (filename_to_send != NULL) {
1025 fp = fopen(filename_to_send, "rb");
1026 if (fp == (FILE *)NULL) {
1027 printf("Cannot open binary file\n");
1028 return (X400_E_SYSERROR);
1029 }
1030 binary_data = (char *) malloc(bin_bp_size);
1031 if ( binary_data == NULL )
1032 return X400_E_NOMEMORY;
1033 if ((fs = fread (binary_data, sizeof(char),
1034 bin_bp_size/sizeof(char), fp) ) == -1) {
1035 printf("Cannot read from binary file\n");
1036 free (binary_data);
1037 fclose(fp);
1038 return (X400_E_SYSERROR);
1039 }
1040 fclose(fp);
1041 if (fs < bin_bp_size) {
1042 printf("Cannot read %d bytes from binary file (got %d)\n",
1043 bin_bp_size, fs);
1044 free (binary_data);
1045 return (X400_E_SYSERROR);
1046 }
1047
1048 status = X400msMsgAddAttachment (mp, X400_T_BINARY, binary_data, fs);
1049 free (binary_data);
1050 if ( status != X400_E_NOERROR ) {
1051 printf("failed to add X400_T_BINARY BP\n");
1052 return (status);
1053 }
1054 printf("Sent %d bytes as X400_T_BINARY BP\n", fs);
1055 } else {
1056 printf("no binary file set - not sending X400_T_BINARY\n");
1057 }
1058 return X400_E_NOERROR;
1059}
1060
1061
1062static int add_ftbp(
1063 struct X400msMessage *mp
1064)
1065{
1066 FILE *fp = NULL;
1067 int fs=0;
1068 char *binary_data;
1069 int status;
1070 struct X400Bodypart *bp;
1071
1072 /* or a Binary body part using the bodypart func */
1073 if (filename_to_send != NULL) {
1074 fp = fopen(filename_to_send, "rb");
1075 if (fp == (FILE *)NULL) {
1076 printf("Cannot open binary file\n");
1077 return (X400_E_SYSERROR);
1078 }
1079 binary_data = (char *) malloc(bin_bp_size);
1080 if ( binary_data == NULL )
1081 return X400_E_NOMEMORY;
1082 if ((fs = fread (binary_data, sizeof(char),
1083 bin_bp_size/sizeof(char), fp) ) == -1) {
1084 printf("Cannot read from binary file\n");
1085 free (binary_data);
1086 fclose(fp);
1087 return (X400_E_SYSERROR);
1088 }
1089 fclose(fp);
1090 if (fs < bin_bp_size) {
1091 printf("Cannot read %d bytes from binary file (got %d)\n",
1092 bin_bp_size, fs);
1093 free (binary_data);
1094 return (X400_E_SYSERROR);
1095 }
1096
1098 X400BodypartAddStrParam(bp, X400_S_BODY_DATA, binary_data, fs);
1100 "Test FTBP File", -1);
1101 /* NB this value should have the filename, but not the full path */
1102 /* Ad on Windows backslashes must be escaped with a second backslash */
1103 X400BodypartAddStrParam(bp, X400_S_FTBP_FILENAME, filename_to_send, -1);
1105 "20160801060101.0Z", -1);
1107 "20160801060202.0Z", -1);
1109 status = X400msMsgAddBodypart(mp, bp);
1110 free (binary_data);
1111
1112 if ( status != X400_E_NOERROR ) {
1113 printf("failed to add X400_T_FTBP BP\n");
1114 return (status);
1115 }
1116 printf("Sent %d bytes as X400_T_FTBP BP\n", fs);
1117 } else {
1118 printf("no binary file set - not sending X400_T_FTBP\n");
1119 }
1120 return X400_E_NOERROR;
1121}
1122
1123
1124static void usage(void) {
1125printf("usage: %s\n", optstr);
1126 printf("\t where:\n");
1127 printf("\t -u : Don't prompt to override defaults \n");
1128 printf("\t -3 : Use P3 connection \n");
1129 printf("\t -7 : Use P7 connection \n");
1130 printf("\t -m : OR Address in P7 bind arg \n");
1131 printf("\t -d : DN in P7 bind arg \n");
1132 printf("\t -p : Presentation Address of P7 Store \n");
1133 printf("\t -w : P7 password of P7 user \n");
1134 printf("\t -M : OR Address in P3 bind arg \n");
1135 printf("\t -D : DN in P3 bind arg \n");
1136 printf("\t -P : Presentation Address of P3 server\n");
1137 printf("\t -W : P3 password of P3 user \n");
1138 printf("\t -o : Originator \n");
1139 printf("\t -O : Originator Return Address \n");
1140 printf("\t -r : Recipient\n");
1141 printf("\t -l : Logline\n");
1142 printf("\t -R : Report requests\n");
1143 printf("\t\t : 0 - none, 1 - non-delivery, 2 - delivery (implies 1)\n");
1144 printf("\t -y : Military Priority \n");
1145 printf("\t\t 0 - deferred, 1 - routine, 2 - priority \n");
1146 printf("\t\t 3 - immediate, 4 - flash, 5 - override \n");
1147 printf("\t -C : Content Type (2/22/772/OID) \n");
1148 printf("\t -i : Implicit conversion prohibited = TRUE \n");
1149 printf("\t -a : Alternate Recipient Prohibited = TRUE \n");
1150 printf("\t -q : Content Return Request = TRUE \n");
1151 printf("\t -s : Disclosure of Recipient = FALSE \n");
1152 printf("\t -A : Recipient Reassignment Prohibited = FALSE \n");
1153 printf("\t -v : Conversion with Loss Prohibited = FALSE \n");
1154 printf("\t -e : Security Environment (dir with x509 subdir): obsolete, use -Y <p12file>\n");
1155 printf("\t -x : DN of X.509 Digital Identity\n");
1156 printf("\t -b : Passphrase for private key in PKCS12 file\n");
1157 printf("\t -f : Filename to transfer as binary bp\n");
1158 printf("\t -Y : Filename of PKCS12 file containing Digital Identity\n");
1159 printf("\t -S : Number of bytes to put into Binary BP and FTBP (default 100)\n");
1160 printf("\t -j : Number of bytes to put into IA5 BP (default 100)\n");
1161 return;
1162}
1163
1164
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 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 X400msMsgAddBodypart(struct X400msMessage *mp, struct X400Bodypart *bp)
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 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 X400msTestSecurityEnv(struct X400msSession *sp)
Test the default Security Environment.
int X400msMsgSend(struct X400msMessage *mp)
Send message object.
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.
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 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_N_PROOF_OF_DEL_REQ
Definition x400_att.h:1004
#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_T_ISO8859_1
Definition x400_att.h:835
#define X400_T_FTBP
Definition x400_att.h:860
#define X400_S_LOG_CONFIGURATION_FILE
Definition x400_att.h:1116
#define X400_N_PRIORITY
Definition x400_att.h:433
#define X400_N_MMTS_PRIORITY_QUALIFIER
Definition x400_att.h:482
#define X400_S_CONTENT_IDENTIFIER
Definition x400_att.h:425
#define X400_S_EXTERNAL_CONTENT_TYPE
Definition x400_att.h:456
#define X400_E_SYSERROR
Definition x400_att.h:49
#define X400_E_NOMEMORY
Definition x400_att.h:52
#define X400_E_NOERROR
Definition x400_att.h:46
#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_N_PRECEDENCE
Definition x400_att.h:712
#define X400_RECIP_STANDARD
Definition x400_att.h:341
#define X400_N_MSGTOK_SEQ_NUM
Definition x400_att.h:1469
#define X400_S_SEC_IDENTITY_DN
Definition x400_att.h:572
#define X400_B_SEC_GEN_MOAC
Definition x400_att.h:566
#define X400_N_S4406
Definition x400_att.h:626
#define X400_B_SEC_GEN_MESSAGE_TOKEN
Definition x400_att.h:1445
#define X400_B_SEC_CONTENT_INTEGRITY_CHECK
Definition x400_att.h:1451
#define X400_S_SEC_IDENTITY_FILE
Definition x400_att.h:600
#define X400_S_SEC_IDENTITY
Definition x400_att.h:563
#define X400_S_SEC_IDENTITY_PASSPHRASE
Definition x400_att.h:569
X400 MA/MS (P3/P7) Interface.

All rights reserved © 2002 - 2024 Isode Ltd.