bin/dbupdate/dbupdate.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- error_init
- process_object
- scan_for_PGP
- process_file
- generate_upd_file
- main
1 /***************************************
2 $Revision: 1.22 $
3
4 DBupdate
5
6 Status: NOT REVIEWED, NOT TESTED
7
8 Author(s): Engin Gunduz
9
10 ******************/ /******************
11 Modification History:
12 engin (01/03/2000) Created.
13 ******************/ /******************
14 Copyright (c) 2000 RIPE NCC
15
16 All Rights Reserved
17
18 Permission to use, copy, modify, and distribute this software and its
19 documentation for any purpose and without fee is hereby granted,
20 provided that the above copyright notice appear in all copies and that
21 both that copyright notice and this permission notice appear in
22 supporting documentation, and that the name of the author not be
23 used in advertising or publicity pertaining to distribution of the
24 software without specific, written prior permission.
25
26 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
27 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
28 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
29 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
30 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32 ***************************************/
33
34
35
36
37
38 #include "dbupdate.h"
39 #include "erroutines.h"
40 #include "ca_configFns.h"
41 #include "ca_dictSyms.h"
42 #include "ca_macros.h"
43 #include "ca_srcAttribs.h"
44 #include "notification.h"
45 #include "gpg.h"
46
47 int tracing = 0;
48 int test_mode = 0;
49 int reading_from_mail = 0;
50
51 /* required configuration variables */
52 char *tmpdir = NULL;
53 char *mailcmd = NULL;
54 char *notitxt = NULL;
55 char *notimailtxt = NULL;
56 char *fwtxt = NULL;
57 char *fwmailtxt = NULL;
58 char *mailtxt = NULL;
59 char *notiflog = NULL;
60 char *crosslog = NULL;
61 char *acklog = NULL;
62 char *forwlog = NULL;
63 char *humailbox = NULL;
64 char *overridecryptedpw = NULL;
65 int *testmode = NULL;
66 char *country = NULL;
67 char *countries[400];
68 char *pgppath = NULL;
69 char *pgp_public_key_ring = NULL;
70 /* end of config variables */
71
72 void error_init(int argc, char ** argv) {
/* [<][>][^][v][top][bottom][index][help] */
73 er_path_t erlogstr;
74
75 ER_init(argc, argv);
76
77 erlogstr.fdes = stderr;
78 erlogstr.asp = 0;
79 erlogstr.sev = ER_SEV_W;
80 erlogstr.mode = ER_M_SEVCHAR | ER_M_TEXTLONG;
81
82 ER_setpath(& erlogstr);
83
84 } /* error_init() */
85
86
87
88 /* Checks the object's syntax, retrives the old version of it from the db,
89 and checks auth2. If everything is OK, then sends it to RIPdb, where referential
90 integrity is checked, and the object is really committed to the db.
91
92 Arguments:
93 char * arg: The object,
94 credentials_struct credentials: The struct containing the credentials, such as
95 'From:' field of the e-mail update,
96 GHashTable * NIC_hdl_hash: A hash containing
97 char * ack_file_name: The file name, to be used to store ACK message
98 */
99
100
101
102 int process_object(char * arg, credentials_struct credentials, GHashTable * NIC_hdl_hash, char * ack_file_name,
/* [<][>][^][v][top][bottom][index][help] */
103 GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash){
104 bool code = true;
105 Object *o;
106 char * old_version = NULL;
107 o = new Object;
108 int result = 0;
109 int result_from_RIPupd = 0;
110 char * auto_nic = NULL;
111 char * changed_obj = NULL;
112 char * obj_with_AUTO_NIC_hdl;
113 char * assigned_NIC;
114
115 char * value = NULL;/* these two are for */
116 Attr * attr; /* ack messages only */
117
118 if(has_ref_to_AUTO_nic_hdl(arg)){/* if this object has refs to AUTO NIC hdls*/
119 /* then first replace AUTO NIC hdls with assigned NIC hdls (in NIC_hdl_hash) */
120 if((arg = replace_refs_to_AUTO_NIC_hdl(changed_obj, arg, NIC_hdl_hash)) == NULL){
121 return UP_ANE; /* AUTO NIC hdl error */
122 };
123 }
124
125 code = o->scan(arg,strlen(arg));
126 if(code){
127 /* is the object to be deleted? */
128 if(o->isDeleted){
129 //printf("DEBUG: This object is to be deleted\n");
130 old_version = get_old_version(arg);
131 if(old_version == NULL){ /* the object doesn't exist in the db! */
132 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nEntry not found\n\n%s\n",
133 o->type->getName(), get_search_key(o, o->type->getName(), arg), arg);
134 return UP_NSO; /* no such object */
135 }else {/* the object is in the db */
136 if(identical(old_version, arg)){/* if the old & new versions are identical */
137 result = check_auth(NULL, old_version, o->type->getName(), credentials);
138 if(result == UP_AUTH_OK){
139 if(tracing) {
140 printf("TRACING: Will send the obj to be deleted\n");
141 }
142 result_from_RIPupd = send_object_db(arg, NULL, "DEL");
143 if(result_from_RIPupd == 0){
144 AK_add_to_ack(ack_file_name, "\nDelete OK: [%s] %s\n",
145 o->type->getName(), get_search_key(o, o->type->getName(), arg));
146 NT_write_all_ntfs(arg, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
147 }else{
148 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nReferential integrity failure\n",
149 o->type->getName(), get_search_key(o, o->type->getName(), arg));
150 }
151 result_from_RIPupd = 0;
152 }else{ /* auth failed */
153 if(tracing) {
154 printf("TRACING: Auth failed\n");
155 }
156
157 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nAuth failed\n",
158 o->type->getName(), get_search_key(o, o->type->getName(), arg));
159 NT_write_all_frwds(arg, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
160 return UP_AUF; /* Auth failed */
161 }
162 }else{/* the new & old versions do not match */
163 AK_add_to_ack(ack_file_name, "\nDelete FAILED: new & old versions do not match\n");
164 return UP_NOM; /* new & old versions do not match */
165 }
166 }
167 }else {/* the object is _not_ to be deleted */
168 if(has_AUTO_NIC_hdl(arg)){/* it the object has an AUTO NIC hdl */
169 /* then its nic-hdl attribute must be modified so that RIPupdate
170 would understand that it must assign a NIC handle to it */
171 /* but first check the auth */
172 result = check_auth(arg, NULL, o->type->getName(), credentials);
173 if(result == UP_AUTH_OK){
174 if(tracing) {
175 printf("TRACING: Will send the obj to be created with AUTO NIC hdl\n");
176 }
177 auto_nic = (char *)malloc(1024); /* should be enough for a NIC hdl */
178 obj_with_AUTO_NIC_hdl = replace_AUTO_NIC_hdl(arg, auto_nic);
179 if(tracing) {
180 printf("TRACING: Called replace_AUTO_NIC_hdl, get [%s]\n", obj_with_AUTO_NIC_hdl);
181 printf("TRACING: Will send the obj to be added\n");
182 }
183 assigned_NIC = (char *)malloc(128); /* this should be enough for a NIC hdl */
184 result_from_RIPupd = send_object_db(obj_with_AUTO_NIC_hdl, assigned_NIC, "ADD");
185 if(result_from_RIPupd == 0){
186 AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n",
187 o->type->getName(), assigned_NIC);
188 NT_write_all_ntfs(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
189 }else{
190 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
191 o->type->getName(), arg);
192 }
193 result_from_RIPupd = 0;
194 if(tracing && assigned_NIC != NULL) {
195 printf("TRACING: send_object_db returned [%s] as assigned NIC hdl\n", assigned_NIC);
196 }
197 if(assigned_NIC != NULL){
198 printf("DEBUG: auto_nic=[%s], assigned_NIC=[%s]\n", auto_nic, assigned_NIC);
199 g_hash_table_insert(NIC_hdl_hash, auto_nic, assigned_NIC);
200 printf("DEBUG: NIC_hdl_hash has %i pairs\n",g_hash_table_size(NIC_hdl_hash));
201 }
202
203 }else{
204 /* auth failed ! */
205 if(tracing) {
206 printf("TRACING: Auth failed\n");
207 }
208
209 ER_perror(0, result, "");
210 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
211 o->type->getName(), get_search_key(o, o->type->getName(), arg));
212 NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
213 return UP_AUF; /* Auth failed */
214 }
215 }
216 else{
217 old_version = get_old_version(arg);
218 if(old_version != NULL){/* so, this is an update operation */
219 result = check_auth(arg, old_version, o->type->getName(), credentials);
220 if(result == UP_AUTH_OK){
221 if(tracing) {
222 printf("TRACING: Will send the obj to be updated\n");
223 }
224 result_from_RIPupd = send_object_db(arg, NULL, "UPD");
225 if(result_from_RIPupd == 0){
226 AK_add_to_ack(ack_file_name, "\nUpdate OK: [%s] %s\n",
227 o->type->getName(), get_search_key(o, o->type->getName(), arg));
228 NT_write_all_ntfs(old_version, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
229 }else{
230 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s]\n%s\nReferential integrity failure\n",
231 o->type->getName(), get_search_key(o, o->type->getName(), arg));
232 }
233 result_from_RIPupd = 0;
234 }else{
235 /* auth failed ! */
236 if(tracing) {
237 printf("TRACING: Auth failed\n");
238 }
239
240 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\nAuth failed\n",
241 o->type->getName(), get_search_key(o, o->type->getName(), arg));
242 NT_write_all_frwds(old_version, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
243 return UP_AUF; /* Auth failed */
244 }
245 }else { /* old_version == NULL, so, creation */
246 result = check_auth(arg, NULL, o->type->getName(), credentials);
247 if(result == UP_AUTH_OK){
248 if(tracing) {
249 printf("TRACING: Will send the obj to be added\n");
250 }
251 result_from_RIPupd = send_object_db(arg, NULL, "ADD");
252 if(result_from_RIPupd == 0){
253 AK_add_to_ack(ack_file_name, "\nNew OK [%s] %s\n",
254 o->type->getName(), get_search_key(o, o->type->getName(), arg));
255 NT_write_all_ntfs(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
256
257 }else{
258 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
259 o->type->getName(), get_search_key(o, o->type->getName(), arg));
260 }
261 result_from_RIPupd = 0;
262 }else{
263 /* auth failed ! */
264 if(tracing) {
265 printf("TRACING: Auth failed\n");
266 }
267
268 ER_perror(0, result, "");
269 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
270 o->type->getName(), get_search_key(o, o->type->getName(), arg));
271 NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
272 return UP_AUF; /* Auth failed */
273 }
274 }
275 }
276 }
277 }else{/* even if obj doesn't parse properly, it may be a legacy object
278 which the user wants to delete... */
279 if(tracing){
280 printf("TRACING: Object didn't parse\n");
281 }
282 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: Syntax error in object\n");
283 //////////////////////////////////
284 if(o->attrs.head() != NULL){
285 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
286 if(attr->len > 0){
287 value = (char*)malloc(attr->len);
288 strncpy(value, (char *)(arg+attr->offset) ,
289 attr->len - 1);
290 value[attr->len - 1] = '\0';
291 AK_add_to_ack(ack_file_name, "%s\n", value);
292 if(!attr->errors.empty()){
293 AK_add_to_ack_string(ack_file_name, attr->errors);
294 }
295 free(value);
296 }else{
297 if(!attr->errors.empty()){
298 AK_add_to_ack_string(ack_file_name, attr->errors);
299 }
300 }
301 }
302 }
303 if(o->has_error){
304 AK_add_to_ack_string(ack_file_name, o->errors);
305 }
306 AK_add_to_ack(ack_file_name, "\n");
307 //////////////////////////////////
308 return UP_NIY; /* Not implemented yet */
309 }
310 }
311
312
313 /* A temporary function to test if there is a PGP signed portion in the file */
314 int scan_for_PGP(const char * filename){
/* [<][>][^][v][top][bottom][index][help] */
315
316 FILE *file;
317 char *line;
318
319 line = (char *)malloc(1024);
320 if((file = fopen(filename, "r")) == NULL){
321 printf("Couldn't open the file %s: %s\n", filename, strerror(errno));
322 exit(1);
323 }
324 while(fgets(line, 1024, file) != NULL){
325 if(strstr(line, "-----BEGIN PGP") == line){/* yes, we have a PGP signed portion, so return true */
326 fclose(file);
327 free(line);
328 return 1;
329 }
330 }
331 fclose(file);
332 free(line);
333 return 0; /* no, we din't have any PGP signed portions */
334 }
335
336
337
338
339
340 /* processes the objects in the given file */
341 void process_file(char * filename, credentials_struct credentials,
/* [<][>][^][v][top][bottom][index][help] */
342 GHashTable * AUTO_NIC_hdl_hash, char * ack_file_name,
343 GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash){
344
345 FILE * input_file;
346 GSList *list_of_objects = NULL, *list_of_objects2 = NULL;
347 GSList *next = NULL;
348 int object_count = 0;
349 char *object = NULL;
350 char *line;
351 int result = 0;
352 struct VerifySignObject vSO, *pvSO;
353 //char keyring[100] = "/home/engin/.gnupg/pubring.gpg";
354
355
356 /* allocate space for pgp_struct, it will be set to pgp key ID when we encounter a pgp signed message */
357 credentials.pgp_struct == (char *)malloc(10);
358
359 line = (char *)malloc(1024);
360
361 /* if we have PGP signed portions in the message */
362 if(scan_for_PGP(filename)){
363 strcpy(vSO.outputPath, "/tmp");
364 strcpy(vSO.iDocSigFilename, filename);
365 strcpy(vSO.iSigFilename, "");
366 strcpy(vSO.keyRing, pgp_public_key_ring/*keyring*/);
367
368 PA_VerifySignature(&vSO);
369
370 pvSO = vSO.next;
371 while (pvSO != NULL) {
372 printf("isValid: %d\n", pvSO->isValid);
373 printf("key ID: %x\n", pvSO->keyID);
374 printf("oStream is %s\n", pvSO->oStream);
375
376
377 if(pvSO->isValid == 1){/* if this PGP signed portion is valid, read it */
378 if((input_file = fopen( pvSO->oStream/*filename*/, "r")) == NULL){
379 printf("Couldn't open the file %s: %s\n", filename, strerror(errno));
380 exit(1);
381 }
382 AK_add_to_ack(ack_file_name, "\n*** Beginning of PGP signed part from key ID %X\n", pvSO->keyID);
383 sprintf(credentials.pgp_struct, "%.8X", pvSO->keyID);
384 printf("DEBUG: credentials.pgp_struct=[%s]\n", credentials.pgp_struct);
385 while(fgets(line, 1024, input_file) != NULL){
386 /* first, if it is a pasword, save it, but do not regard it as an attrib */
387 if(strstr(line, "password:") == line){
388 if(tracing){
389 printf("DEBUG: This is a password\n");
390 }
391 credentials.password_list = g_slist_append(credentials.password_list,
392 g_strstrip(strdup(line + strlen("password:"))));
393 continue;
394 }
395 /* if the length of the line read is 2, then this is an empty line ("\n\r")*/
396 if(strlen(line) == 2){
397 if(object != NULL){
398 list_of_objects = g_slist_append(list_of_objects, object);
399 object = NULL;
400 }
401 }else{
402 /* if the line contains only the EOL sequence "\n\r" */
403 if(object == NULL && strlen(line) != 2){
404 object = (char *)malloc(strlen(line));
405 object = strdup(line);
406 }
407 else{
408 object = (char *)realloc(object, strlen(object) + strlen(line));
409 object = strcat(object, line);
410 }
411 }
412
413 }
414 fclose(input_file);
415
416 /* now, if at the very and of the input file there wasn't an
417 empty line, we have to add the remaining object in the 'object'
418 variable */
419 if(object != NULL){
420 //cout << "The object was" << endl << object << endl;
421 list_of_objects = g_slist_append(list_of_objects, object);
422 object = NULL;
423 }
424
425
426
427 if(tracing) {
428 printf("TRACING: Will process the objects in the list\n");
429 }
430 next = list_of_objects;
431 object_count = 0;
432 for( next = list_of_objects; next != NULL ; next = g_slist_next(next) ){
433 object_count++;
434
435 if(tracing) {
436 cout << "TRACING: Got an object from the list" << endl;
437 cout << (char *)next->data << endl;
438 }
439
440 if(has_ref_to_AUTO_nic_hdl((char *)next->data)){/* defer the processing */
441 if(tracing) {
442 printf("TRACING: this object has a ref to an AUTO NIC hdl\n");
443 }
444 list_of_objects2 = g_slist_append(list_of_objects2, strdup((char *)next->data));
445 }else{
446 result = 0;
447 result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
448 ntfy_hash, forw_hash, cross_hash);
449 }
450 }
451
452 if(tracing) {
453 printf("TRACING: list_of_objects2 has %d entries\n", g_slist_length(list_of_objects2));
454 }
455
456 if(tracing) {
457 printf("TRACING: will start to process the second list\n");
458 }
459
460 for( next = list_of_objects2; next != NULL ; next = g_slist_next(next) ){
461 if(tracing) {
462 printf("TRACING: Will process object: %s\n", (char *)next->data);
463 }
464 result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
465 ntfy_hash, forw_hash, cross_hash);
466 }
467 /* empty the object lists (this must be done by properly freeing the memory taken by them!) */
468 list_of_objects = NULL;
469 list_of_objects2 = NULL;
470 AK_add_to_ack(ack_file_name, "\n*** End of PGP signed part from key ID %X\n", pvSO->keyID);
471
472 }else{
473 AK_add_to_ack(ack_file_name, "\n*** Ignoring PGP signed part from key ID %X", pvSO->keyID);
474 AK_add_to_ack(ack_file_name, "\n*** Bad signature or key is not in public key ring or other error\n\n");
475 }
476
477 pvSO = pvSO->next;
478 /* empty out credentials.pgp_struct for the next loop */
479 strcpy(credentials.pgp_struct,"");
480 }
481
482 }
483 else{/* the file doesn't contain PGP signed portions */
484 if((input_file = fopen(filename, "r")) == NULL){
485 printf("Couldn't open the file %s: %s\n", filename, strerror(errno));
486 exit(1);
487 }
488
489
490 while(fgets(line, 1024, input_file) != NULL){
491 /* first, if it is a pasword, save it, but do not regard it as an attrib */
492 if(strstr(line, "password:") == line){
493 if(tracing){
494 printf("DEBUG: This is a password\n");
495 }
496 credentials.password_list = g_slist_append(credentials.password_list,
497 g_strstrip(strdup(line + strlen("password:"))));
498 continue;
499 }
500 /* if the length of the line read is 2, then this is an empty line ("\n\r")*/
501 if(strlen(line) == 2){
502 if(object != NULL){
503 list_of_objects = g_slist_append(list_of_objects, object);
504 object = NULL;
505 }
506 }else{
507 /* if the line contains only the EOL sequence "\n\r" */
508 if(object == NULL && strlen(line) != 2){
509 object = (char *)malloc(strlen(line));
510 object = strdup(line);
511 }
512 else{
513 object = (char *)realloc(object, strlen(object) + strlen(line));
514 object = strcat(object, line);
515 }
516 }
517
518 }
519 fclose(input_file);
520
521 /* now, if at the very and of the input file there wasn't an
522 empty line, we have to add the remaining object in the 'object'
523 variable */
524 if(object != NULL){
525 //cout << "The object was" << endl << object << endl;
526 list_of_objects = g_slist_append(list_of_objects, object);
527 object = NULL;
528 }
529
530
531
532 if(tracing) {
533 printf("TRACING: Will process the objects in the list\n");
534 }
535 next = list_of_objects;
536 object_count = 0;
537 for( next = list_of_objects; next != NULL ; next = g_slist_next(next) ){
538 object_count++;
539
540 if(tracing) {
541 cout << "TRACING: Got an object from the list" << endl;
542 cout << (char *)next->data << endl;
543 }
544
545 if(has_ref_to_AUTO_nic_hdl((char *)next->data)){/* defer the processing */
546 if(tracing) {
547 printf("TRACING: this object has a ref to an AUTO NIC hdl\n");
548 }
549 list_of_objects2 = g_slist_append(list_of_objects2, strdup((char *)next->data));
550 }else{
551 result = 0;
552 result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
553 ntfy_hash, forw_hash, cross_hash);
554 }
555 }
556
557 if(tracing) {
558 printf("TRACING: list_of_objects2 has %d entries\n", g_slist_length(list_of_objects2));
559 }
560
561 if(tracing) {
562 printf("TRACING: will start to process the second list\n");
563 }
564
565 for( next = list_of_objects2; next != NULL ; next = g_slist_next(next) ){
566 if(tracing) {
567 printf("TRACING: Will process object: %s\n", (char *)next->data);
568 }
569 result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
570 ntfy_hash, forw_hash, cross_hash);
571 }
572
573 }
574
575 }/* process_file */
576
577
578
579
580
581
582 /* Generates a unique file name and returns the full path of the filename
583 for storing notification message. */
584
585 char * generate_upd_file(){
/* [<][>][^][v][top][bottom][index][help] */
586
587 char * name;
588
589 /* allocate space for name. 32 should be enough for PID */
590 name = (char*)malloc(strlen("/tmp/dbupdate-tmp.") + strlen("notify") +32 );
591
592 sprintf(name, "/tmp/dbupdate-tmp.%i", getpid());
593
594
595 return name;
596
597 }
598
599
600
601
602
603 /* main */
604 void main(int argc, char **argv, char **envp){
/* [<][>][^][v][top][bottom][index][help] */
605 //init_and_set_options(argc, argv, envp);
606
607 int count = 0;
608 int i,j;
609
610 char ** temp_vector;
611 char * temp;
612 char * temp_upd_file = NULL;
613 char *input_file_name = NULL;
614 GHashTable *AUTO_NIC_hdl_hash;
615 credentials_struct credentials;
616
617
618 GHashTable *ntfy_hash, *forw_hash, *cross_hash;
619
620
621 char *mail_command_line, * ack_file_name;
622 char *config_file_name = NULL;
623
624
625 /* for using MM module */
626 int retcode;
627 MM_header *mail_header = NULL;
628 MM_xmp_list *part_list;
629 MM_xmp *partptr;
630 long debug = 0;
631
632 /* optarg & optind are necessary to use getopt(3C) */
633 extern char *optarg;
634 extern int optind;
635
636
637 /* create notification hashes */
638 ntfy_hash = g_hash_table_new(g_str_hash, g_str_equal);
639 forw_hash = g_hash_table_new(g_str_hash, g_str_equal);
640
641
642 credentials.password_list = NULL;
643 credentials.from = NULL;
644 int ch;
645 char * to_address = NULL;
646
647 AUTO_NIC_hdl_hash = g_hash_table_new(g_str_hash, g_str_equal);
648 error_init(argc, argv);
649
650
651 while ((ch = getopt(argc, argv, "MtTf:c:")) != -1){
652 switch(ch) {
653 case 'M':
654 reading_from_mail = 1;
655 break;
656 case 'f':
657 input_file_name = strdup(optarg);
658 break;
659 case 'c':
660 config_file_name = strdup(optarg);
661 break;
662 case 't':
663 tracing = 1;
664 break;
665 case 'T':
666 test_mode = 1;
667 break;
668 case '?':
669 default:
670 printf("Unknown option\n");exit(1);
671 }
672 }
673
674
675
676 /* config stuff */
677 ca_populateDictionary(dictionary, VARS);
678 /* if -c flag is given, use the named file as config file, otherwise use
679 default filename */
680 if( config_file_name != NULL){
681 ca_readConfig(config_file_name, confVars, VARS);
682 }else{
683 ca_readConfig("dbupdate.conf", confVars, VARS);
684 }
685 tmpdir = ca_get_tmpdir;
686 tmpdir = g_strstrip(tmpdir);
687 mailcmd = ca_get_mailcmd;
688 mailcmd = g_strstrip(mailcmd);
689 notitxt = ca_get_notitxt;
690 mailtxt = ca_get_mailtxt;
691 crosslog = ca_get_crosslog;
692 fwtxt = ca_get_fwtxt;
693 humailbox = ca_get_humailbox;
694 humailbox = g_strstrip(humailbox);
695 overridecryptedpw = ca_get_overridecryptedpw;
696 overridecryptedpw = g_strstrip(overridecryptedpw);
697 acklog = ca_get_acklog;
698 acklog = g_strstrip(acklog);
699 notiflog = ca_get_notiflog;
700 notiflog = g_strstrip(notiflog);
701 notimailtxt = ca_get_notimailtxt;
702 forwlog = ca_get_forwlog;
703 forwlog = g_strstrip(forwlog);
704 fwmailtxt = ca_get_fwmailtxt;
705 country = ca_get_country;
706 pgppath = ca_get_pgppath;
707 pgppath = g_strstrip(pgppath);
708 pgp_public_key_ring = (char *)malloc(strlen(pgppath) + strlen("/pubring.gpg") + 2);
709 sprintf(pgp_public_key_ring ,"%s/pubring.gpg", pgppath);
710 test_mode = ca_get_testmode;
711 /* construct country array from country string variable */
712
713 temp_vector = g_strsplit(country, "\n", 0);
714 for(i=0, j=0; temp_vector[i] != NULL; i++){
715 temp_vector[i] == g_strstrip(temp_vector[i]);
716 if(strlen(temp_vector[i]) > 0){
717 countries[j] = strdup(temp_vector[i]);
718 g_strup(countries[j]);
719 printf("DEBUG: got a country country[%i] =.%s.,\n", j, countries[j]);
720 j++;
721 }
722 }
723 countries[j] = NULL; /* mark the end of array */
724 printf("DEBUG: countries[%i] = NULL\n", j);
725
726
727 //test_mode = ca_get_testmode;
728
729 printf("TMPDIR is: [%s]\n", tmpdir);
730 printf("MAILCMD is: [%s]\n", mailcmd);
731 printf("NOTITXT is: [%s]\n", notitxt);
732 printf("CROSSLOG is: [%s]\n", crosslog);
733 printf("FWTXT is: [%s]\n", fwtxt);
734 printf("HUMAILBOX is: [%s]\n", humailbox);
735 printf("OVERRIDECRYPTEDPW is: [%s]\n", overridecryptedpw);
736 printf("ACKLOG is: [%s]\n", acklog);
737 printf("NOTIFLOG is: [%s]\n", notiflog);
738 printf("FORWLOG is: [%s]\n", forwlog);
739 printf("NOTIMAILTXT is: [%s]\n", notimailtxt);
740 printf("FWMAILTXT is: [%s]\n", fwmailtxt);
741 printf("COUNTRY is: [%s]\n", country);
742 printf("PGPPATH is: [%s]\n", pgppath);
743
744 printf("TESTMODE is: [%i]\n", test_mode);
745 /* end of config stuff */
746
747
748
749 /* initialize the parser */
750 schema.initialize();
751
752
753 /* Generate a name for temporary file for storing acks (AK_ack_file_name_generate
754 also creates it) */
755 ack_file_name = AK_ack_file_name_generate(tmpdir, ACK_FILE_PREFIX);
756
757
758 /* Allocate memory for the header */
759 mail_header = (MM_header *)malloc(sizeof(MM_header));
760
761 /* Initialize the list of extracted MIME parts */
762 part_list = (MM_xmp_list *)malloc(sizeof(MM_xmp_list));
763 MM_xmp_list_init (part_list);
764
765
766 if(reading_from_mail){
767 if(input_file_name != NULL){
768 if((retcode = MM_decode(input_file_name, mail_header, part_list, 1, 0)) != 0){
769 printf("DEBUG: MM_decode returned %i\n", retcode);
770 exit(retcode);
771 }
772
773 }else{/* input_file_name == NULL */
774 temp_upd_file = generate_upd_file();
775 MM_store("-", temp_upd_file, 0);
776 if((retcode = MM_decode(temp_upd_file, mail_header, part_list, 1, 0)) != 0){
777 printf("DEBUG: MM_decode returned %i\n", retcode);
778 exit(retcode);
779 }
780
781 }
782 unlink(temp_upd_file);
783 printf ("Mail headers:\n\n");
784 printf ("From - [%s]",mail_header->from);
785 /* some MAIL-FROM's in mntner auths contain "From: " string too,
786 so we have to have it in credential.from */
787 temp = (char *)malloc(strlen(mail_header->from) + strlen("From: ") + 1);
788 sprintf(temp, "From: %s", mail_header->from);
789 temp[strlen(temp) - 4] = '\0'; /* cut two '\r\n's at the end */
790 credentials.from = temp;
791 printf ("credentials.from = [%s]\n", credentials.from );
792 mail_header->subject[strlen(mail_header->subject) - 4] = '\0';
793 printf ("Subject - [%s]",mail_header->subject);
794 printf ("Date - [%s]",mail_header->date);
795 printf ("Message-ID - [%s]",mail_header->message_id);
796 printf ("Reply-To - [%s]",mail_header->reply_to);
797 printf ("Cc - [%s]",mail_header->cc);
798 to_address = find_to_address(credentials.from);
799 AK_add_to_ack(ack_file_name, "To: %s\nFrom: %s\nSubject: Re: %s \nReply-To: %s\n\nAcknowledgement message from database software, beta version\n", to_address, humailbox, mail_header->subject, humailbox);
800 if(credentials.from != NULL){
801 AK_add_to_ack(ack_file_name, "\n[%s]\n", credentials.from);
802 }
803
804 partptr = part_list->head;
805 while (partptr != NULL){
806
807 printf("-----------------------------------------\n");
808 printf ("Section: %s\n",partptr->number);
809 printf ("Content-type: %s\n",partptr->type);
810 if (partptr->supported){
811 printf ("Supported\n");
812 printf ("Filename is [%s]\n", partptr->file);
813 process_file(partptr->file, credentials,
814 AUTO_NIC_hdl_hash, ack_file_name,
815 ntfy_hash, forw_hash, cross_hash);
816 }
817 else
818 printf ("Unsupported\n");
819 printf ("\n\n");
820 partptr = partptr->next;
821 }
822
823
824 /* Clean up the temporary files */
825 MM_cleanup(part_list, 0);
826
827
828 }else{/* not reading from the mail message */
829 if(input_file_name != NULL){
830 process_file(input_file_name, credentials,
831 AUTO_NIC_hdl_hash, ack_file_name,
832 ntfy_hash, forw_hash, cross_hash);
833 }
834
835 }
836
837
838 if(reading_from_mail && to_address != NULL){
839 AK_send_ack(ack_file_name, to_address, mailcmd);
840 }
841 AK_log_ack(ack_file_name, acklog);
842 AK_delete_ack(ack_file_name);
843
844 NT_send_ntfy_list(ntfy_hash, mailcmd);
845 NT_log_ntfy_list(ntfy_hash, notiflog);
846 NT_delete_ntfy_list(ntfy_hash);
847
848 NT_send_ntfy_list(forw_hash, mailcmd);
849 NT_log_ntfy_list(forw_hash, forwlog);
850 //NT_delete_ntfy_list(forw_hash);
851
852
853
854 if(tracing) {
855 printf("TRACING: END\n");
856 }
857
858
859 }