x400_mssend_sign_multi_addr.c
1/* Copyright (c) 2003-2013, 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 * @VERSION@
13 * Simple example program for transferring a message into the gateway.
14 * The security environment is set up so that messages are signed.
15 */
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20
21#include <x400_msapi.h>
22#include "example.h"
23
24static 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:";
25
26/* These are the data items used to construct the message for submission */
27static char *default_recip = "/CN=lppt1/OU=lppt/O=attlee/PRMD=TestPRMD/ADMD=TestADMD/C=GB/";
28char *recip;
29/* static char *content_id = "030924.140212"; */
30static char *content_id = "030924.140212";
31static const char text[] = "First line\r\nSecond line\r\n";
32static char *binary_data;
33
34static int setup_msg_sec_env = 1;
35
36/* local functions */
37
38static void usage(void) ;
39static int send_msg(
40 int contype,
41 char *orn,
42 char *def_dn,
43 char *pa,
44 char *password);
45
46static int submit_msg(
47 char *orn,
48 struct X400msSession *sp /* session object */
49);
50
51static int setup_default_new_sec_env(
52 struct X400msSession *sp,
53 char *identity_filename,
54 char *pw
55);
56
57static int setup_default_old_sec_env(
58 struct X400msSession *sp,
59 char *id,
60 char *dn,
61 char *pw
62);
63
64static int setup_msg_new_sec_env(
65 struct X400msMessage *mp, /* message object */
66 char *identity_filename,
67 char *pw
68);
69
70static int setup_msg_old_sec_env(
71 struct X400msMessage *mp, /* message object */
72 char *id,
73 char *dn,
74 char *pw
75);
76
77/* start here */
78int main (
79 int argc,
80 char **argv
81)
82{
83 char pa[BUFSIZ];
84 char orn[BUFSIZ];
85 char *def_oraddr;
86 char *def_dn;
87 char *def_pa;
88 int contype;
89 int status = 0;
90 char password[BUFSIZ];
91 int num_msgs = 2;
92
93 if (get_args(argc, argv, optstr)) {
94 usage();
95 exit(-1);
96 }
97
98 printf("Connection type (0 = P7, 1 = P3) [%d]: ", x400_contype);
99 contype = ic_fgetc(x400_contype, stdin);
100 if (contype != 10)
101 ic_fgetc(x400_contype, stdin);
102
103 if ((contype != '0') && (contype != '1'))
104 contype = x400_contype;
105 else
106 contype -= '0';
107
108 if (contype == 0) {
109 def_oraddr = x400_ms_user_addr;
110 def_dn = x400_ms_user_dn;
111 def_pa = x400_ms_presentation_address;
112 } else {
113 def_oraddr = x400_mta_user_addr;
114 def_dn = x400_mta_user_dn;
115 def_pa = x400_mta_presentation_address;
116 }
117
118 printf("Your ORAddress [%s] > ", def_oraddr);
119 ic_fgets (orn, sizeof orn, stdin);
120
121 if ( orn[strlen(orn)-1] == '\n' )
122 orn[strlen(orn)-1] = '\0';
123
124 if (orn[0] == '\0')
125 strcpy(orn, def_oraddr);
126
127 /* Prompt for password; note: reflected. */
128 printf ("Password [%s]: ",
129 contype == 0 ? x400_p7_password : x400_p3_password);
130 if ( ic_fgets (password, sizeof password, stdin) == NULL )
131 exit (1);
132
133 if (password[strlen(password)-1] == '\n' )
134 password[strlen(password)-1] = '\0';
135 if (password[0] == '\0')
136 strcpy(password, contype == 0 ? x400_p7_password : x400_p3_password);
137
138 /* Presentation Address */
139 printf("Presentation Address [%s] > ", def_pa);
140 ic_fgets (pa, sizeof pa, stdin);
141
142 if ( pa[strlen(pa)-1] == '\n' )
143 pa[strlen(pa)-1] = '\0';
144
145 if (pa[0] == '\0')
146 strcpy(pa, def_pa);
147
148 while (num_msgs--) {
149 if ((status = send_msg(contype, orn, def_dn, pa, password))
150 != X400_E_NOERROR ) {
151 fprintf (stderr, "Error in sending message\n");
152 exit (status);
153 }
154 }
155 return (status);
156}
157
158static int send_msg(
159 int contype,
160 char *orn,
161 char *def_dn,
162 char *pa,
163 char *password
164)
165{
166 struct X400msSession *sp; /* session object */
167
168 int status;
169
170
171 /* we've got what we need - now open an API session */
172 status = X400msOpen (contype, orn, def_dn, password, pa, NULL, &sp);
173 if ( status != X400_E_NOERROR ) {
174 fprintf (stderr, "Error in Open: %s\n", X400msError (status));
175 fprintf (stderr, "%s %s %s\n", orn, def_dn, pa);
176 return (status);
177 }
178
179 /* setup logging */
181
182 /* Set up the security environment.
183 *
184 * The security env can be specified the new way (recommended) using
185 * a PKCS12 filename and passphrase, or as a directory (deprecated and
186 * obsolete).
187 *
188 * If the ID is specified as a directory, in which the subdirectory
189 * "x509" is expected to contain one or more PKCS12 files.
190 * The appropriate Digital Identity is determined from the
191 * DN of the subject, and the passphrase is used to decrypt
192 * the private key.
193 */
194 if (use_new_sec_env) {
195 status = setup_default_new_sec_env(sp, identity_filename, passphrase);
196 } else {
197 status = setup_default_old_sec_env(sp, security_id, identity_dn,
198 passphrase);
199 }
200 if ( status != X400_E_NOERROR ) {
201 fprintf (stderr, "Can't setup security environment\n");
202 return (status);
203 }
204
205 printf("sending message 1\n");
206 status = submit_msg(orn, sp);
207 if ( status != X400_E_NOERROR ) {
208 fprintf (stderr, "Can't submit\n");
209 return (status);
210 }
211
212 /* might want to test changing the default security env here */
213
214 printf("sending message 2\n");
215 status = submit_msg(orn, sp);
216 if ( status != X400_E_NOERROR ) {
217 fprintf (stderr, "Can't submit\n");
218 return (status);
219 }
220
221 printf("sending message 3\n");
222 status = submit_msg(orn, sp);
223 if ( status != X400_E_NOERROR ) {
224 fprintf (stderr, "Can't submit\n");
225 return (status);
226 }
227
228 status = X400msClose (sp);
229 if ( status != X400_E_NOERROR ) {
230 fprintf (stderr, "X400msClose returned error: %s\n", X400msError (status));
231 return (status);
232 }
233
234 return status;
235}
236
237static int submit_msg(
238 char *orn,
239 struct X400msSession *sp /* session object */
240)
241{
242 struct X400msMessage *mp; /* message object */
243 struct X400Recipient *rp; /* recipient object */
244 char tmp[BUFSIZ];
245 FILE *fp = NULL;
246 int fs=0;
247 int status;
248
249 if (x400_default_recipient != NULL)
250 recip = x400_default_recipient;
251 else
252 recip = default_recip;
253
254 printf("Message recipient [%s]: ", recip);
255 ic_fgets (tmp, sizeof tmp, stdin);
256
257 if ( tmp[strlen(tmp)-1] == '\n' )
258 tmp[strlen(tmp)-1] = '\0';
259 if (strlen(tmp) != 0)
260 recip = strdup(tmp);
261
262 printf("Subject [%s]: ", subject);
263 ic_fgets (tmp, sizeof tmp, stdin);
264
265 if ( tmp[strlen(tmp)-1] == '\n' )
266 tmp[strlen(tmp)-1] = '\0';
267 if (strlen(tmp) != 0)
268 subject = strdup(tmp);
269
270 status = X400msMsgNew (sp, X400_MSG_MESSAGE, &mp);
271 if ( status != X400_E_NOERROR ) {
272 fprintf (stderr, "x400msMsgNew returned error: %s\n", X400msError (status));
273 return (status);
274 }
275
276 /* Set up the security environment for this message overriding the
277 * default security env.
278 *
279 * The security env can be specified the new way (reccommened) using
280 * a PKCS12 filename and passphrase, or as a directory (deprecated and
281 * obsolete).
282 *
283 * If the ID is specified as a pathname, in which the subdirectory
284 * "x509" is expected to contain one or more PKCS12 files.
285 * The appropriate Digital Identity is determined from the
286 * DN of the subject, and the passphrase is used to decrypt
287 * the private key.
288 */
289 if (setup_msg_sec_env) {
290 if (use_new_sec_env) {
291 status = setup_msg_new_sec_env(mp, identity_filename, passphrase);
292 if ( status != X400_E_NOERROR ) {
293 fprintf (stderr, "Can't setup new security environment\n");
294 return (status);
295 }
296 } else {
297 status = setup_msg_old_sec_env(mp, security_id, identity_dn2,
298 passphrase);
299 if ( status != X400_E_NOERROR ) {
300 fprintf (stderr, "Can't setup old security environment\n");
301 return (status);
302 }
303 }
304 }
305
306 /* Instruct the X400msMsgSend() function to generate a MOAC (signature) for
307 * the message Instruct the X400msMsgSend() function to generate a MOAC
308 * (signature) for the message
309 * The default attributes will be used unless the attributes are
310 * also included in the message eg by calling setup_msg_sec_env() above
311 */
313 if ( status != X400_E_NOERROR ) {
314 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
315 return (status);
316 }
317
318 status = X400msRecipNew (mp, X400_RECIP_STANDARD, &rp);
319 if ( status != X400_E_NOERROR ) {
320 fprintf (stderr, "x400msRecipNew returned error: %s\n", X400msError (status));
321 return (status);
322 }
323
324 status = X400msRecipAddStrParam (rp, X400_S_OR_ADDRESS, recip, -1);
325 if ( status != X400_E_NOERROR ) {
326 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
327 return (status);
328 }
329
330 status = X400msRecipAddStrParam (rp, X400_S_DIRECTORY_NAME, "CN=recipient;c=gb", -1);
331 if ( status != X400_E_NOERROR ) {
332 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
333 return (status);
334 }
335
336 status = X400msMsgAddStrParam (mp, X400_S_OR_ADDRESS, orn, -1);
337 if ( status != X400_E_NOERROR ) {
338 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
339 return (status);
340 }
341
342 status = X400msMsgAddStrParam (mp, X400_S_DIRECTORY_NAME, "CN=originator;c=gb", -1);
343 if ( status != X400_E_NOERROR ) {
344 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
345 return (status);
346 }
347
348 /* Ask for +ve and -ve delivery reports */
350 if ( status != X400_E_NOERROR ) {
351 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
352 return (status);
353 }
354
355 /* Ask for +ve and -ve read receipts */
357 if ( status != X400_E_NOERROR ) {
358 fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
359 return (status);
360 }
361
363 content_id, -1);
364 if ( status != X400_E_NOERROR ) {
365 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
366 return (status);
367 }
368
369 status = X400msMsgAddStrParam (mp, X400_S_SUBJECT, subject, -1);
370 if ( status != X400_E_NOERROR ) {
371 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
372 return (status);
373 }
374
375 status = X400msMsgAddStrParam (mp, X400_T_ISO8859_1, text, -1);
376 if ( status != X400_E_NOERROR ) {
377 fprintf (stderr, "x400ms returned error: %s\n", X400msError (status));
378 return (status);
379 }
380
381 /* now an IA5 body part using the bodypart func */
382 status = X400msMsgAddAttachment (mp, X400_T_IA5TEXT, text, strlen(text));
383 if ( status != X400_E_NOERROR ) {
384 printf("failed to add X400_T_IA5TEXT BP\n");
385 return (status);
386 }
387
388 /* or a Binary body part using the bodypart func */
389 if (filename_to_send != NULL) {
390 binary_data = (char *) malloc(100000);
391 if ( binary_data == NULL )
392 return X400_E_NOMEMORY;
393 fp = fopen(filename_to_send, "r");
394 if (fp == (FILE *)NULL) {
395 printf("Cannot open binary file\n");
396 return (X400_E_SYSERROR);
397 }
398 if ((fs = fread (binary_data, sizeof(char), 100000/sizeof(char), fp) ) == -1) {
399 printf("Cannot read from binary file\n");
400 return (X400_E_SYSERROR);
401 }
402 fclose(fp);
403
404 status = X400msMsgAddAttachment (mp, X400_T_BINARY, binary_data, fs);
405 if ( status != X400_E_NOERROR ) {
406 printf("failed to add X400_T_BINARY BP\n");
407 return (status);
408 }
409 } else {
410 printf("no binary file set - not sending X400_T_BINARY\n");
411 }
412
413 status = X400msMsgSend (mp);
414 if ( status != X400_E_NOERROR ) {
415 fprintf (stderr, "x400msMsgSend returned error: %s\n", X400msError (status));
416 return (status);
417 } else {
418 printf("Message submitted successfully\n");
419 }
420
421 status = X400msMsgDelete (mp, 0);
422 if ( status != X400_E_NOERROR ) {
423 fprintf (stderr, "x400msMsgDelete returned error: %s\n", X400msError (status));
424 return (status);
425 }
426
427 mp = NULL;
428 rp = NULL;
429
430 return (status);
431}
432
433static int setup_default_new_sec_env(
434 struct X400msSession *sp,
435 char *identity,
436 char *pw
437)
438{
439 int status;
440
441 /* Filename of the Digital Identity (PKCS12 file) */
443 identity, -1);
444 if ( status != X400_E_NOERROR ) {
445 fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
446 X400msError (status));
447 return (status);
448 }
449
450 /* passphrase used to open the Identity */
452 if ( status != X400_E_NOERROR ) {
453 fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
454 X400msError (status));
455 return (status);
456 }
457
458 /* test the sec env */
459 status = X400msTestSecurityEnv (sp);
460 if ( status != X400_E_NOERROR ) {
461 fprintf (stderr, "X400msTestSecurityEnv returned error: %s\n",
462 X400msError (status));
463 return (status);
464 }
465
466 return status;
467}
468
469static int setup_default_old_sec_env(
470 struct X400msSession *sp,
471 char *id,
472 char *dn,
473 char *pw
474)
475{
476 int status;
477
478 /* first set a default security identity. This passes in the name of a
479 * directory, which contains an x509 subdirectory in which all Identities
480 * are held */
482
483 /* select by DN which Identity is to be used (if there are several)
484 * Currently these must be PKCS12 files */
485 status = X400msSetStrDefault (sp, X400_S_SEC_IDENTITY_DN, dn, -1);
486 if ( status != X400_E_NOERROR ) {
487 fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
488 X400msError (status));
489 return (status);
490 }
491
492 /* passphrase used to open the Identity */
494 if ( status != X400_E_NOERROR ) {
495 fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
496 X400msError (status));
497 return (status);
498 }
499
500 return status;
501}
502
503static int setup_msg_new_sec_env(
504 struct X400msMessage *mp, /* message object */
505 char *identity,
506 char *pw
507)
508{
509 int status;
510
511 /* Filename of the Digital Identity (PKCS12 file) */
513 identity, -1);
514 if ( status != X400_E_NOERROR ) {
515 fprintf (stderr, "X400msMsgAddStrParam returned error: %s\n",
516 X400msError (status));
517 return (status);
518 }
519
520 /* security additions */
522 if ( status != X400_E_NOERROR ) {
523 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
524 X400msError (status));
525 return (status);
526 }
527 return (status);
528}
529
530static int setup_msg_old_sec_env(
531 struct X400msMessage *mp, /* message object */
532 char *id,
533 char *dn,
534 char *pw
535)
536{
537 int status;
538
539 /* overide the default security environment by specifying a new set of
540 * attibutes, and put them into the message */
541 /* security additions */
542 status = X400msMsgAddStrParam (mp, X400_S_SEC_IDENTITY, id, -1);
543 /* status = X400msMsgAddStrParam (mp, X400_S_SEC_IDENTITY, "/var/isode/dsa-db", -1); */
544 if ( status != X400_E_NOERROR ) {
545 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
546 X400msError (status));
547 return (status);
548 }
549
550 /* security additions */
551 status = X400msMsgAddStrParam (mp, X400_S_SEC_IDENTITY_DN, dn, -1);
552 if ( status != X400_E_NOERROR ) {
553 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
554 X400msError (status));
555 return (status);
556 }
557
558 /* security additions */
560 if ( status != X400_E_NOERROR ) {
561 fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
562 X400msError (status));
563 return (status);
564 }
565 return (status);
566}
567
568static void usage(void) {
569 printf("usage: %s\n", optstr);
570 printf("\t where:\n");
571 printf("\t -u : Don't prompt to override defaults \n");
572 printf("\t -3 : Use P3 connection \n");
573 printf("\t -7 : Use P7 connection \n");
574 printf("\t -m : OR Address in P7 bind arg \n");
575 printf("\t -d : DN in P7 bind arg \n");
576 printf("\t -p : Presentation Address of P7 Store \n");
577 printf("\t -w : P7 password of P7 user \n");
578 printf("\t -M : OR Address in P3 bind arg \n");
579 printf("\t -D : DN in P3 bind arg \n");
580 printf("\t -P : Presentation Address of P3 server\n");
581 printf("\t -W : P3 password of P3 user \n");
582 printf("\t -o : Originator \n");
583 printf("\t -O : Originator Return Address \n");
584 printf("\t -r : Recipient\n");
585 printf("\t -l : Logline\n");
586 printf("\t -y : Priority (0 - normal, 1 - non-urgent, 2 - urgent \n");
587 printf("\t -C : Content Type (2/22/772/OID) \n");
588 printf("\t -i : Implicit conversion prohibited = TRUE \n");
589 printf("\t -a : Alternate Recipient Prohibited = TRUE \n");
590 printf("\t -q : Content Return Request = TRUE \n");
591 printf("\t -s : Disclosure of Recipient = FALSE \n");
592 printf("\t -A : Recipient Reassignment Prohibited = FALSE \n");
593 printf("\t -v : Conversion with Loss Prohibited = FALSE \n");
594 printf("\t -e : Security Environment (dir with x509 subdir): obsolete, use -Y <p12file>\n");
595 printf("\t -x : DN of X.509 Digital Identity\n");
596 printf("\t -b : Passphrase for private key in PKCS12 file\n");
597 printf("\t -f : Filename to transfer as binary bp\n");
598 printf("\t -Y : Filename of PKCS12 file containing Digital Identity\n");
599 return;
600}
601
602
int X400msMsgAddStrParam(struct X400msMessage *mp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the 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 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_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_S_LOG_CONFIGURATION_FILE
Definition x400_att.h:1116
#define X400_S_CONTENT_IDENTIFIER
Definition x400_att.h:425
#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_RECIP_STANDARD
Definition x400_att.h:341
#define X400_S_SEC_IDENTITY_DN
Definition x400_att.h:572
#define X400_B_SEC_GEN_MOAC
Definition x400_att.h:566
#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.