/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- error_init
- lockfilestruct
- delete_key
- import_key
- get_keyowner_fingerpr
- deprecated_mail_from
- write_errors_to_ack
- set_default_source_data
- set_current_source_data
- process_object
- process_file
- generate_upd_file
- create_lock_file
- remove_lock_file
- write_checkpoint
- remove_checkpoint
- main
1 /***************************************
2 $Revision: 1.33 $
3
4 DBupdate
5
6 Status: PARTIALLY REVIEWED, NOT TESTED
7
8 Author(s): Engin Gunduz
9
10 ******************/ /******************
11 Modification History:
12 engin (01/03/2000) Created.
13 denis (31/08/2001) Modified for new API
14 ******************/ /******************
15 Copyright (c) 2001,2002 RIPE NCC
16
17 All Rights Reserved
18
19 Permission to use, copy, modify, and distribute this software and its
20 documentation for any purpose and without fee is hereby granted,
21 provided that the above copyright notice appear in all copies and that
22 both that copyright notice and this permission notice appear in
23 supporting documentation, and that the name of the author not be
24 used in advertising or publicity pertaining to distribution of the
25 software without specific, written prior permission.
26
27 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
28 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
29 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
30 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
31 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
32 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
33 ***************************************/
34
35
36
37
38 #include <config.h>
39 #include "dbupdate.h"
40 #include "UP_extrnl_syntax.h"
41 #include "UP_subject.h"
42 #include "er_yacc_helper.h"
43 #include "erroutines.h"
44 #include "ca_configFns.h"
45 #include "ca_dictionary.h"
46 #include "ca_macros.h"
47 #include "ca_srcAttribs.h"
48 #include "notification.h"
49 #include "gpg.h"
50 #include "mail_parser.h"
51 #include "process.h"
52
53 #ifdef HAVE_SYS_PARAM_H
54 #include <sys/param.h>
55 #endif
56
57 extern int num_sources;
58
59 int tracing = 0;
60 int test_mode = 0;
61 int supress_ack_notif = 0;
62 int print_out_ack = 0;
63
64 /* do we process a mail */
65 int reading_from_mail = 0;
66
67 /* sync update flags */
68 int webupdate = 0;
69 int help_requested = 0;
70 int enforced_new = 0;
71 int origin_string = 0;
72
73 /* are we processing networkupdate? */
74 int networkupdate = 0;
75
76 /* IP of the networkupdate client */
77 char * netupdclientIP = NULL;
78
79 /* two global variables to tally the processed objects */
80 int count_successful = 0;
81 int count_unsuccessful = 0;
82
83
84 /* sender of the mail, in case of a mail update */
85 char *update_mail_sender = NULL;
86 char *update_mail_subject = NULL;
87 char *update_mail_date = NULL;
88 char *update_mail_ID = NULL;
89 char *update_mail_cc = NULL;
90
91 /* re-direct to humail message */
92 char *header_type = NULL;
93 char *text_type = NULL;
94
95 /* required configuration variables */
96 char *tmpdir = NULL;
97 char *lockdir = NULL;
98 char *mailcmd = NULL;
99 char *notitxt = NULL;
100 char *notihdr = NULL;
101 char *successtxt = NULL;
102 char *failuretxt = NULL;
103 char *helpheader = NULL;
104 char *notimailtxt = NULL;
105 char *notinetworktxt = NULL;
106 char *fwtxt = NULL;
107 char *fwhdr = NULL;
108 char *fwmailtxt = NULL;
109 char *mtfwheader = NULL;
110 char *mtfwtxt = NULL;
111 char *mailtxt = NULL;
112 char *acksig = NULL;
113 char *defmail = NULL;
114 char *updlog = NULL;
115 char *notiflog = NULL;
116 char *crosslog = NULL;
117 char *acklog = NULL;
118 char *forwlog = NULL;
119 char *humailbox = NULL;
120 char *autobox = NULL;
121 char *copyright_notice = NULL;
122 char *overridecryptedpw = NULL;
123 char *country = NULL;
124 char *countries[400];
125 char *authmethod = NULL;
126 char *authmethods[20];
127 char *nicsuffixes[7];
128 char *current_source = NULL;
129 char *pgppath = NULL;
130 char *gpgcmd = NULL;
131 char *pgp_public_key_ring = NULL;
132 char *autodbmhelp = NULL;
133 char *update_host = NULL;
134 int update_port;
135 char *query_host = NULL;
136 int query_port;
137 char *cn_subject_add = NULL;
138 char *cn_subject_del = NULL;
139 char *cn_explain_add = NULL;
140 char *cn_explain_del = NULL;
141 char *cn_overlap_add = NULL;
142 char *cn_overlap_del = NULL;
143 char *cno_subject_add = NULL;
144 char *cno_subject_del = NULL;
145 char *cno_explain_add = NULL;
146 char *cno_explain_del = NULL;
147 char *cno_overlap_add = NULL;
148 char *cno_overlap_del = NULL;
149 char *allocmnt = NULL;
150 char *mheader = NULL;
151 char *DBhost = NULL;
152 int DBport;
153 char *DBuser = NULL;
154 char *DBname = NULL;
155 char *DBpasswd = NULL;
156 ca_updDbSource_t **upd_source_hdl;
157 /* end of config variables */
158
159 char * fingerprint = NULL;
160 char * keyowner = NULL;
161
162 /* result of subject line processing is kept in the following struct. */
163 up_subject_struct subject_result;
164
165
166 /* hostname and pid are used all over the program, so we save them into these variables */
167 char hostname[MAXHOSTNAMELEN];
168 /* char * hostname; */
169 int pid;
170
171 /* name of the lock file, which is used for the crash recovery mechanism */
172 char * lock_file_name;
173
174 void error_init(int argc, char ** argv) {
/* [<][>][^][v][top][bottom][index][help] */
175
176 ER_init("dbupdate", 1);
177
178
179 } /* error_init() */
180
181
182
183
184
185
186 /* 'lockfile' struct is for keeping both the name of the lock file and the file descriptor
187 of it, which is open during the execution of dbupdate. We need the filedes to close it,
188 when dbupdate finishes, and the name to delete the file. */
189 typedef struct {
190 char * lockname;
191 int filedes;
192 } lockfilestruct;
/* [<][>][^][v][top][bottom][index][help] */
193
194
195 lockfilestruct lockfile;
196
197
198
199 /* Deletes the key defined in the incoming object (a key-cert object)
200 from the public keyring. Returns NULL if there was no error,
201 returns an error message if there is an error */
202 char *delete_key(rpsl_object_t * obj)
/* [<][>][^][v][top][bottom][index][help] */
203 {
204 struct ImportKeyObject iKO;
205 char * obj_keyID;
206 char * key_cert_attr;
207 GList * templist;
208 GList * certiflist, * next;
209 u32 keyID;
210 char * key_file_name;
211 char ** lines;
212 char *value;
213 int i;
214 FILE * key_file;
215 char * temp, * temp2;
216 char * error_string;
217 rpsl_attr_t *attr;
218
219 /* templist = get_attr_list(obj, "key-cert"); */
220 templist = rpsl_object_get_attr(obj, "key-cert");
221 attr = (rpsl_attr_t *)(templist->data);
222 key_cert_attr = strdup((char *)(attr->value));
223 /* key_cert_attr = strdup( (char *)( ((rpsl_attr_t *)(templist->data))->value ) ); */
224 rpsl_attr_delete_list(templist);
225
226 key_file_name = (char *)malloc(strlen(tmpdir) + strlen("tmp-key.") + 32);
227 sprintf(key_file_name, "%s/tmp-key.%i", tmpdir, pid);
228
229 /* now we must write certif attribute(s) of this key-certif into the key_file_name */
230 /* get the certif first */
231 /* certiflist = get_attr_list(obj, "certif"); */
232 certiflist = rpsl_object_get_attr(obj, "certif");
233 if (( key_file = fopen(key_file_name, "w")) == NULL)
234 {
235 ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temporary file, %s", key_file_name);
236 exit(1);
237 }
238 for ( next = certiflist; next != NULL ; next = g_list_next(next) )
239 {
240 value = rpsl_attr_get_clean_lines( (rpsl_attr_t *)(next->data) );
241 if (value == NULL)
242 { /* if this was an empty attribute, just print an empty line */
243 fprintf(key_file, "\n");
244 }
245 else
246 {
247 fprintf(key_file, "%s\n", value);
248 free(value);
249 }
250
251 /* attr = (rpsl_attr_t *)(next->data);
252 lines = g_strsplit((char *)(attr->value), "\n", 0);
253 if (lines[0] == NULL)
254 { /* if this was an empty attribute, just print an empty line */
255 /* fprintf(key_file, "\n");
256 }
257 for (i = 0; lines[i] != NULL; i++)
258 {
259 temp = strdup(lines[i]);
260 if (i != 0 && temp[0] == '+')
261 { /* if it begins with a plus */
262 /* temp2 = strdup(temp + 1);
263 g_strstrip(temp2);
264 fprintf(key_file, "%s\n", temp2);
265 free(temp);free(temp2);
266 }
267 else
268 {
269 g_strstrip(temp);
270 fprintf(key_file, "%s\n", temp);
271 free(temp);
272 }
273 }
274 g_strfreev(lines);
275 */
276 }
277 fclose(key_file);
278 rpsl_attr_delete_list(certiflist);
279
280 strcpy(iKO.iFilename, key_file_name);
281
282 if (tracing)
283 {
284 printf("TRACING: delete_key: key_cert_attr: [%s]\n", key_cert_attr);
285 }
286
287 obj_keyID = strdup(key_cert_attr + strlen("PGPKEY-"));
288
289 if (tracing)
290 {
291 printf("TRACING: delete_key: obj_keyID: [%s]\n", obj_keyID);
292 }
293
294 keyID = strtoul(obj_keyID, NULL, 16);
295
296 if (tracing)
297 {
298 printf("TRACING: delete_key: keyID is: %u, %X\n", keyID, keyID);
299 }
300
301 strcpy(iKO.keyRing, pgp_public_key_ring);
302 PA_RemoveKey(&iKO);
303
304 if (tracing)
305 {
306 printf("TRACING: importKeyObj status:\n");
307 printf("TRACING: isValid: %d\n", iKO.rc);
308 }
309
310 /* clean-up: delete the file, free the char * */
311 unlink(key_file_name);
312 free(key_file_name);
313
314 if (iKO.rc == iKO_OK)
315 { /* if PA_RemoveKey returned OK */
316 return NULL;
317 }
318 else
319 { /* if PA_RemoveKey returned not OK */
320 switch (iKO.rc)
321 {
322 case iKO_UNCHANGED: error_string = strdup("the key is already in the keyring");break;
323 case iKO_NOUSERID: error_string = strdup("no user ID could be extracted");break;
324 case iKO_GENERAL: error_string = strdup("general PGP error");break;
325 case iKO_NOTVALIDUSERID: error_string = strdup("no valid user ID ");break;
326 case iKO_NOPUBLICKEY: error_string = strdup("no public key in the object");break;
327 case iKO_NODEFAULTPUBLICKEYRING: error_string = strdup("general PGP error");break;
328 case iKO_CRC_ERROR: error_string = strdup("CRC error in the certificate");break;
329 case iKO_NO_OPENPGP_DATA:error_string = strdup("no OpenPGP data in the object");break;
330 case iKO_NO_IN_FILES: error_string = strdup("general PGP error");break;
331 case iKO_GENERALFAILURE: error_string = strdup("general PGP error");break;
332 default: error_string = strdup("general PGP error");
333 }
334 return error_string;
335 }
336 }
337
338
339
340
341
342 /* Takes a key-certif object, extracts its 'certif' attribute and adds
343 the key into public keyring
344 If there is no problem, it returns NULL
345 If there is a problem, then it returns a string which contains an error
346 message */
347 char * import_key(rpsl_object_t *object)
/* [<][>][^][v][top][bottom][index][help] */
348 {
349 char * key_file_name;
350 char *value;
351 struct ImportKeyObject iKO;
352 GList * certiflist, * item, * templist;
353 FILE * key_file;
354 char keyID[9];
355 char * obj_keyID, * key_cert_attr;
356 char * error_string = NULL;
357
358 key_file_name = (char *)malloc(strlen(tmpdir) + strlen("tmp-key.") + 32);
359 sprintf(key_file_name, "%s/tmp-key.%i", tmpdir, pid );
360
361 /* now we must write certif attribute(s) of this key-certif into the key_file_name */
362 /* get the certif first */
363 certiflist = rpsl_object_get_attr(object, "certif");
364 if (( key_file = fopen(key_file_name, "w")) == NULL)
365 {
366 ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temporary file, %s", key_file_name);
367 exit(1);
368 }
369 for( item = certiflist; item != NULL ; item = g_list_next(item) )
370 {
371 value = rpsl_attr_get_clean_lines( (rpsl_attr_t *)(item->data) );
372 if (value == NULL)
373 { /* if this was an empty attribute, just print an empty line */
374 fprintf(key_file, "\n");
375 }
376 else
377 {
378 fprintf(key_file, "%s\n", value);
379 free(value);
380 }
381 }
382 fclose(key_file);
383 rpsl_attr_delete_list(certiflist);
384
385 strcpy(iKO.iFilename, key_file_name);
386 strcpy(iKO.keyRing, pgp_public_key_ring);
387 PA_ImportKey(&iKO);
388
389 if (tracing)
390 {
391 printf("importKeyObj status:\n");
392
393 printf("isValid: %d\n", iKO.rc);
394 printf("keyID: %08lX\n", (long)(iKO.keyID) );
395 }
396 snprintf(keyID, 9, "%08lX", iKO.keyID);
397
398 if (tracing)
399 {
400 printf("keyID: [%s]\n", keyID);
401 }
402
403 templist = rpsl_object_get_attr(object, "key-cert");
404 key_cert_attr = rpsl_attr_get_clean_value((rpsl_attr_t *)(templist->data));
405 rpsl_attr_delete_list(templist);
406
407 if (tracing)
408 {
409 printf("key_cert_attr: [%s]\n", key_cert_attr);
410 }
411 obj_keyID = strdup(key_cert_attr + strlen("PGPKEY-"));
412 free(key_cert_attr);
413 if (tracing)
414 {
415 printf("obj_keyID: [%s]\n", obj_keyID);
416 }
417
418 if (iKO.rc == iKO_OK && (strcasecmp(obj_keyID, keyID) == 0))
419 { /* if PA_ImportKey returned OK
420 and the real keyID is equal to the
421 keyID in the 'key-cert' attribute */
422 fingerprint = strdup(iKO.fingerPrint);
423 keyowner = strdup(iKO.keyOwner);
424
425 /* clean-up: delete the file, free the variable */
426 unlink(key_file_name);
427 free(key_file_name);
428
429 return NULL;
430 }
431 else
432 {
433 /* if PA_ImportKey returned not OK or obj_keyID, keyID didn't match */
434 if (iKO.rc != iKO_OK)
435 {
436 switch (iKO.rc)
437 {
438 case iKO_UNCHANGED: error_string = strdup("the key is already in the keyring");break;
439 case iKO_NOUSERID: error_string = strdup("no user ID could be extracted");break;
440 case iKO_GENERAL: error_string = strdup("general PGP error");break;
441 case iKO_NOTVALIDUSERID: error_string = strdup("no valid user ID ");break;
442 case iKO_NOPUBLICKEY: error_string = strdup("no public key in the object");break;
443 case iKO_NODEFAULTPUBLICKEYRING: error_string = strdup("general PGP error");break;
444 case iKO_CRC_ERROR: error_string = strdup("CRC error in the certificate");break;
445 case iKO_NO_OPENPGP_DATA:error_string = strdup("no OpenPGP data in the object");break;
446 case iKO_NO_IN_FILES: error_string = strdup("general PGP error");break;
447 case iKO_INVALID_ARMOR_HEADER: error_string = strdup("invalid armor header");break;
448 case iKO_MULTIPLE_KEYS: error_string = strdup("multiple keys in key-cert object");break;
449 case iKO_GENERALFAILURE: error_string = strdup("general PGP error");break;
450 default: error_string = strdup("general PGP error");
451 }
452
453 /* clean-up: delete the file, free the variable */
454 unlink(key_file_name);
455 free(key_file_name);
456 return error_string;
457
458 }
459 else
460 {
461 error_string = (char *)malloc(1024);/* this should be enough */
462 sprintf(error_string, "Keyid for this certificate (%s) is not the same as the PGPKEY field (%s)",
463 keyID, obj_keyID);
464 /* roll-back: we encountered a problem, so we have to remove the key that
465 we've added */
466 PA_RemoveKey(&iKO);
467
468 /* clean-up: delete the file, free the variable */
469 unlink(key_file_name);
470 free(key_file_name);
471
472 free(obj_keyID);
473 return error_string;
474 }
475 }
476 }
477
478
479
480 /* Gets the keyowner and fingerprint of a PGP key
481 from the keycert object. The keycert object must already
482 be in the database (thus, in the keyring)
483 The fingerprint and keyowner will be saved in global variables */
484
485 void get_keyowner_fingerpr(rpsl_object_t *obj)
/* [<][>][^][v][top][bottom][index][help] */
486 {
487 GList * templist = NULL;
488 char * obj_keyID = NULL;
489 struct ImportKeyObject iKO;
490 u32 keyID;
491 char * key_cert_value;
492
493
494 templist = rpsl_object_get_attr(obj, "key-cert");
495 key_cert_value = rpsl_attr_get_clean_value((rpsl_attr_t *)(templist->data));
496 rpsl_attr_delete_list(templist);
497
498 if (tracing)
499 {
500 printf("get_keyowner_fingerpr: key_cert_attr is [%s]\n", key_cert_value);
501 }
502
503 obj_keyID = strdup(key_cert_value + strlen("PGPKEY-"));
504 if (tracing)
505 {
506 printf("get_keyowner_fingerpr: obj_keyID is [%s]\n", obj_keyID);
507 }
508
509 sscanf(obj_keyID, "%8X", &keyID);
510 if (tracing)
511 {
512 printf("get_keyowner_fingerpr: keyID is [%u]\n", keyID);
513 }
514
515 /* set appropriate fields of iKO */
516 iKO.keyID = keyID;
517 strcpy(iKO.keyRing, pgp_public_key_ring);
518
519 GetFingerPrint(&iKO);
520 fingerprint = strdup(iKO.fingerPrint);
521
522 GetKeyOwner(&iKO);
523 keyowner = strdup(iKO.keyOwner);
524
525 free(key_cert_value);
526 free(obj_keyID);
527
528 if(tracing)
529 {
530 if (fingerprint != NULL)
531 {
532 printf("get_keyowner_fingerpr: fingerprint is [%s]\n", fingerprint);
533 }
534 if (keyowner)
535 {
536 printf("get_keyowner_fingerpr: keyowner is [%s]\n", keyowner);
537 }
538 }
539 }
540
541
542
543 /* Adds an information message to the ack message if a deprecated MAIL-FROM was found in
544 any of the mntner objects checked by the check_auth routine. */
545 void deprecated_mail_from(char * ack_file_name, int result)
/* [<][>][^][v][top][bottom][index][help] */
546 {
547 /* auth passed OK but a MAIL-FROM was still found */
548
549 /* an early idea that was not implemented - so do nothing */
550
551 /* remove completely during re-structuring */
552 }
553
554
555 /* writes the object and any attribute and object level error
556 messages to the ack file.
557 */
558
559 void write_errors_to_ack(rpsl_object_t *object, char *arg, char * ack_file_name, char *errmsg)
/* [<][>][^][v][top][bottom][index][help] */
560 {
561 const GList * attr_list = NULL;
562 const GList * attr_list_item = NULL;
563 const GList * error_list = NULL;
564 const GList * error_list_item = NULL;
565 const GList * attr_error_list = NULL;
566 const GList * attr_error_list_item = NULL;
567 char * arg2;
568 const char * value = NULL;
569 const char * name = NULL;
570 char * attribute = NULL;
571
572 /* syntax error AND not deletion */
573 /*
574 noclass = 0;
575 for ( error_list_item = error_list; error_list_item != NULL; error_list_item = g_list_next(error_list_item) )
576 {
577 ecode = ((rpsl_error_t *)(error_list_item->data))->code;
578 if ( ecode == RPSL_ERR_ONLYCOMMENTS || ecode == RPSL_ERR_BADCLASS
579 || ecode == RPSL_ERR_BADCLASS )
580 {
581 noclass = 1;
582 break;
583 }
584 }
585 */
586 if ( UP_remove_override_attr(object) )
587 {
588 arg2 = rpsl_object_get_text(object,0);
589 if ( ! arg2 )
590 {
591 /* if we are processing garbage with a : in the first line, arg2 may be null */
592 arg2 = (char *)malloc(2);
593 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
594 }
595 }
596 else
597 {
598 /* there was an override attr in this object and it has not been removed */
599 arg2 = (char *)malloc(2);
600 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
601 }
602
603 /* if ( ! noclass )
604 {
605 type = rpsl_object_get_class(object);
606 key = get_search_key(object, type);
607 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s \n***Error: Syntax error in object\n",
608 type, key ? key : "" );
609 }
610 else
611 */
612 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: Syntax error in object\n");
613
614 if ( rpsl_object_has_error(object, RPSL_ERRLVL_CRIT) )
615 {
616 /* object not parsed so print out text version of object rather than attributes */
617 AK_add_to_ack(ack_file_name, "%s\n", arg2);
618 }
619 else
620 {
621 /* add attributes along with any attribute error messages */
622 attr_list = rpsl_object_get_all_attr(object);
623 for ( attr_list_item = attr_list; attr_list_item != NULL; attr_list_item = g_list_next(attr_list_item) )
624 {
625 name = rpsl_attr_get_name( (rpsl_attr_t *)(attr_list_item->data) );
626 if ( strcasecmp(name, "override") != 0 )
627 {
628 /* don't include the override attibute, but still include override error messages */
629 value = rpsl_attr_get_value( (rpsl_attr_t *)(attr_list_item->data) );
630 attribute = (char *)malloc( strlen(name) + strlen(value) + 3);
631 sprintf(attribute, "%s: %s", name, value);
632 AK_add_to_ack(ack_file_name, "%s\n", attribute);
633 free(attribute);
634 }
635 attr_error_list = rpsl_attr_errors( (rpsl_attr_t *)(attr_list_item->data) );
636 for ( attr_error_list_item = attr_error_list; attr_error_list_item != NULL; attr_error_list_item = g_list_next(attr_error_list_item) )
637 {
638 if ( ((rpsl_error_t *)(attr_error_list_item->data))->level > RPSL_ERRLVL_DEBUG )
639 AK_add_to_ack(ack_file_name, "***Error: %s\n", ((rpsl_error_t *)(attr_error_list_item->data))->descr);
640 }
641 }
642 }
643
644 /* now add any object level error messages */
645 error_list = rpsl_object_errors(object);
646 for ( error_list_item = error_list; error_list_item != NULL; error_list_item = g_list_next(error_list_item) )
647 {
648 if ( ((rpsl_error_t *)(error_list_item->data))->level > RPSL_ERRLVL_DEBUG &&
649 ((rpsl_error_t *)(error_list_item->data))->code != RPSL_ERR_BADATTR )
650 {
651 AK_add_to_ack(ack_file_name, "***Error: %s\n", ((rpsl_error_t *)(error_list_item->data))->descr);
652 }
653 }
654
655 if ( errmsg )
656 AK_add_to_ack(ack_file_name, "\n%s\n", errmsg);
657
658 AK_add_to_ack(ack_file_name, "\n");
659 free(arg2);
660 }
661
662
663 /* sets up the current source data from the first entry in the
664 list of config data for multiple sources.
665 Needed for networkupdate.
666 */
667
668 void set_default_source_data()
/* [<][>][^][v][top][bottom][index][help] */
669 {
670 if (tracing)
671 {
672 printf("TRACING: set_default_source_data running\n");
673 }
674
675 if ( current_source )
676 free(current_source);
677 current_source = strdup(upd_source_hdl[0]->name);
678 update_host = upd_source_hdl[0]->whoisd_host;
679 if ( query_host )
680 free(query_host);
681 query_host = strdup(update_host);
682 update_port = upd_source_hdl[0]->updPort;
683 query_port = upd_source_hdl[0]->qryPort;
684 DBhost = upd_source_hdl[0]->updDb.host;
685 DBport = upd_source_hdl[0]->updDb.port;
686 DBname = upd_source_hdl[0]->updDb.dbName;
687 DBuser = upd_source_hdl[0]->updDb.user;
688 DBpasswd = upd_source_hdl[0]->updDb.password;
689
690 if (tracing)
691 {
692 /* print out the config variables for debugging */
693 printf("CURRENT SOURCE is: [%s]\n", current_source);
694 printf("UPDATE_HOST is: [%s]\n", update_host);
695 printf("UPDATE_PORT is: [%i]\n", update_port);
696 printf("QUERY_HOST is: [%s]\n", query_host);
697 printf("QUERY_PORT is: [%i]\n", query_port);
698 printf("DBhost is: [%s]\n", DBhost);
699 printf("DBport is: [%i]\n", DBport);
700 printf("DBname is: [%s]\n", DBname);
701 printf("DBuser is: [%s]\n", DBuser);
702 printf("DBpasswd is: [%s]\n", DBpasswd);
703 }
704 }
705
706
707 /* takes the source string from an object and sets up the current source
708 data from the list of config data for multiple sources
709
710 returns 1 for success and 0 for source not found */
711
712 int set_current_source_data(char *obj_source)
/* [<][>][^][v][top][bottom][index][help] */
713 {
714 int i;
715 int found = 0;
716
717 if (tracing)
718 {
719 printf("TRACING: set_current_source_data running\n");
720 }
721
722 for ( i=0; i<num_sources; i++ )
723 {
724 if ( ! strcasecmp( obj_source, upd_source_hdl[i]->name) )
725 {
726 /* found the source in the list */
727 found = 1;
728
729 if ( current_source )
730 free(current_source);
731 current_source = strdup(upd_source_hdl[i]->name);
732 update_host = upd_source_hdl[i]->whoisd_host;
733 if ( query_host )
734 free(query_host);
735 query_host = strdup(update_host);
736 update_port = upd_source_hdl[i]->updPort;
737 query_port = upd_source_hdl[i]->qryPort;
738 DBhost = upd_source_hdl[i]->updDb.host;
739 DBport = upd_source_hdl[i]->updDb.port;
740 DBname = upd_source_hdl[i]->updDb.dbName;
741 DBuser = upd_source_hdl[i]->updDb.user;
742 DBpasswd = upd_source_hdl[i]->updDb.password;
743
744 if (tracing)
745 {
746 /* print out the config variables for debugging */
747 printf("CURRENT SOURCE is: [%s]\n", current_source);
748 printf("UPDATE_HOST is: [%s]\n", update_host);
749 printf("UPDATE_PORT is: [%i]\n", update_port);
750 printf("QUERY_HOST is: [%s]\n", query_host);
751 printf("QUERY_PORT is: [%i]\n", query_port);
752 printf("DBhost is: [%s]\n", DBhost);
753 printf("DBport is: [%i]\n", DBport);
754 printf("DBname is: [%s]\n", DBname);
755 printf("DBuser is: [%s]\n", DBuser);
756 printf("DBpasswd is: [%s]\n", DBpasswd);
757 }
758
759 break;
760 }
761 }
762
763 if ( ! found && tracing )
764 {
765 printf("TRACING: invalid source [%s]\n", obj_source);
766 }
767
768 return found;
769 }
770
771
772
773 /* Checks the object's syntax, retrives the old version of it from the db,
774 and checks auth2. If everything is OK, then sends it to RIPdb, where referential
775 integrity is checked, and the object is really committed to the db.
776 Also now determines which source to update for each object.
777
778 Arguments:
779 char * incoming: The object,
780 credentials_struct credentials: The struct containing the credentials, such as
781 'From:' field of the e-mail update,
782 GHashTable * NIC_hdl_hash: A hash containing
783 char * ack_file_name: The file name, to be used to store ACK message
784 GHashTable * ntfy_hash,
785 GHashTable * forw_hash,
786 GHashTable * cross_hash: hashes that contain files that have notifications.
787 */
788
789
790
791 int process_object(char * incoming, credentials_struct credentials,
/* [<][>][^][v][top][bottom][index][help] */
792 GHashTable * NIC_hdl_hash, char * ack_file_name,
793 GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash)
794 {
795 rpsl_object_t *object = NULL;
796 rpsl_object_t *old_obj = NULL;
797 rpsl_object_t *external_syntax_obj = NULL;
798 rpsl_object_t *obj_with_AUTO_NIC_hdl = NULL;
799 rpsl_object_t *formatted_object = NULL;
800 rpsl_object_t *generated_obj = NULL;
801 const GList * error_list = NULL;
802 const GList * error_list_item = NULL;
803 const GList * attr_list = NULL;
804 const GList * attr_list_item = NULL;
805 const GList * attr_error_list = NULL;
806 const GList * attr_error_list_item = NULL;
807 char * old_version = NULL;
808 int result = 0;
809 char * result_from_import_key = NULL;
810 char * result_from_delete_key = NULL;
811 char * auto_nic = NULL;
812 char * changed_obj_str = NULL;
813 char *obj_with_AUTO_NIC_hdl_str;
814 char * assigned_NIC;
815 char * formatted_object_str;
816 const char * type;
817 char *lctype;
818 char * arg;
819 char * arg2;
820 char * generated_obj_str;
821 const char * value = NULL;
822 const char * name = NULL;
823 char * attribute = NULL;
824 char *key;
825 char *obj_source = NULL;
826 up_ripupd_result_struct * result_from_RIPupd;
827 external_syntax_struct * external_syntax_results;
828 gint elevel, ecode;
829 gchar *edescr = NULL;
830
831 arg = strdup(incoming);
832
833 object = rpsl_object_init(arg);
834 error_list = rpsl_object_errors(object);
835 if (tracing && error_list)
836 {
837 printf("TRACING: errors found on initial object parse\n");
838 for ( error_list_item = error_list; error_list_item != NULL; error_list_item = g_list_next(error_list_item) )
839 {
840 elevel = ((rpsl_error_t *)(error_list_item->data))->level;
841 ecode = ((rpsl_error_t *)(error_list_item->data))->code;
842 edescr = strdup(((rpsl_error_t *)(error_list_item->data))->descr);
843
844 printf("TRACING: level [%d] code [%d] [%s]\n", elevel, ecode, edescr);
845 free(edescr);
846 }
847 }
848 if ( error_list )
849 {
850 if ( ((rpsl_error_t *)(error_list->data))->code == RPSL_ERR_ONLYCOMMENTS )
851 return UP_NOOBJECT;
852 }
853
854 /* find source from object and set current source data */
855 attr_list = rpsl_object_get_attr(object, "source");
856 if ( attr_list )
857 {
858 obj_source = rpsl_attr_get_clean_value((rpsl_attr_t *)(attr_list->data));
859 result = set_current_source_data(obj_source);
860 if ( ! result )
861 {
862 /* source in object not recognised */
863 write_errors_to_ack(object, arg, ack_file_name, "***Error: No such source");
864 rpsl_object_delete(object);
865 free(arg);
866 return UP_INT; /* need a new return code here for object source not found in config list */
867 /* return UP_SNF; */
868 }
869 }
870 else
871 {
872 /* should only happen if the object has no source: attribute */
873 write_errors_to_ack(object, arg, ack_file_name, NULL);
874 rpsl_object_delete(object);
875 free(arg);
876 return UP_SYN;
877 }
878
879 if ( !rpsl_object_has_error(object, RPSL_ERRLVL_ERROR)
880 && has_ref_to_AUTO_nic_hdl(object) )
881 { /* parsed with no systax errors */
882 if (tracing)
883 {
884 printf("TRACING: the object has ref to AUTO nic-hdl\n");
885 }
886
887 /* if this object has refs to AUTO NIC hdls*/
888 /* then first replace AUTO NIC hdls with assigned NIC hdls (in NIC_hdl_hash) */
889 if ((changed_obj_str = replace_refs_to_AUTO_NIC_hdl(object, NIC_hdl_hash, arg)) == NULL)
890 {
891 type = rpsl_object_get_class(object);
892
893 free(arg);
894 if ( UP_remove_override_attr(object) )
895 {
896 arg = rpsl_object_get_text(object,0);
897 if ( ! arg )
898 {
899 /* if we are processing garbage with a : in the first line, arg will be null */
900 arg = (char *)malloc(2);
901 strcpy(arg, ""); /* Don't include object in ack/notif msgs */
902 }
903 }
904 else
905 {
906 /* there was an override attr in this object and it has not been removed */
907 arg = (char *)malloc(2);
908 strcpy(arg, ""); /* Don't include object in ack/notif msgs */
909 }
910
911 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] Unknown AUTO NIC handle referenced\n%s\n",
912 type ? type : "unknown-type", arg);
913
914 rpsl_object_delete(object);
915 free(arg);
916 return UP_ANE; /* AUTO NIC hdl error */
917 }
918 else
919 { /* in this case, we must use changed_obj_str instead of arg */
920
921 free(arg);
922 arg = changed_obj_str;
923 };
924 }
925
926
927 if ( !rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
928 {
929 /* parsed with no systax errors */
930
931 /* find source from object and set current source data */
932 attr_list = rpsl_object_get_attr(object, "source");
933 if ( attr_list )
934 {
935 obj_source = rpsl_attr_get_clean_value((rpsl_attr_t *)(attr_list->data));
936 result = set_current_source_data(obj_source);
937 if ( ! result )
938 {
939 write_errors_to_ack(object, arg, ack_file_name, "***Error: No such source");
940 rpsl_object_delete(object);
941 free(arg);
942 return UP_INT; /* need a new return code here for object source not found in config list */
943 /* return UP_SNF; */
944 }
945 }
946 else
947 {
948 /* should only happen if the object has no source: attribute */
949 write_errors_to_ack(object, arg, ack_file_name, NULL);
950 rpsl_object_delete(object);
951 free(arg);
952 return UP_SYN;
953 }
954
955 type = rpsl_object_get_class(object);
956 /* is the object to be deleted? */
957 if ( rpsl_object_is_deleted(object) )
958 {
959 old_version = get_old_version(object, arg);
960
961 if(old_version == NULL)
962 { /* the object doesn't exist in the db! */
963
964 if (tracing)
965 {
966 printf("TRACING: the object doesn't exist in the db\n");
967 }
968
969 free(arg);
970 if ( UP_remove_override_attr(object) )
971 {
972 arg = rpsl_object_get_text(object,0);
973 if ( ! arg )
974 {
975 /* if we are processing garbage with a : in the first line, arg will be null */
976 arg = (char *)malloc(2);
977 strcpy(arg, ""); /* Don't include object in ack/notif msgs */
978 }
979 }
980 else
981 {
982 /* there was an override attr in this object and it has not been removed */
983 arg = (char *)malloc(2);
984 strcpy(arg, ""); /* Don't include object in ack/notif msgs */
985 }
986
987 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n***Error: Entry not found\n\n",
988 type, get_search_key(object, type), arg);
989
990 rpsl_object_delete(object);
991 free(arg);
992 return UP_NSO; /* no such object */
993 }
994 else
995 { /* the object is in the db */
996
997 if (tracing)
998 {
999 printf("TRACING: the object is in the db\n");
1000 }
1001
1002 lctype = strdup(type);
1003 g_strdown(lctype);
1004 if ( identical(old_version, object) /* if the old & new versions are identical */
1005 || (strcmp(lctype, "key-cert") == 0) /* or it is a key-cert object */
1006 || (strcmp(lctype, "inet6num") == 0) ) /* or it is an inet6num object */
1007 {
1008 result = check_auth(NULL, object, type, credentials);
1009 if(result == UP_AUTH_OK || result == UP_OKM)
1010 {
1011 if (tracing)
1012 {
1013 printf("TRACING: Will send the obj to be deleted\n");
1014 }
1015 if(strcmp(type, "key-cert") == 0)
1016 {
1017 result_from_delete_key = delete_key(object);
1018 }
1019 else
1020 {
1021 result_from_delete_key = NULL;
1022 }
1023 /* if there was no problem with key deletion from the key-ring */
1024 if (result_from_delete_key == NULL)
1025 {
1026 result_from_RIPupd = send_object_db(object, NULL, "DEL");
1027 if (result_from_RIPupd->result == 0)
1028 {
1029 AK_add_to_ack(ack_file_name, "\nDelete OK: [%s] %s\n",
1030 type, get_search_key(object, type));
1031 deprecated_mail_from( ack_file_name, result );
1032 NT_write_all_ntfs(old_version, NULL, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash,
1033 credentials.from);
1034
1035 rpsl_object_delete(object);
1036 free(result_from_RIPupd);
1037 free(arg);
1038 free(old_version);
1039 return UP_OK;
1040 }
1041 else
1042 {
1043 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
1044 type, get_search_key(object, type),
1045 result_from_RIPupd->error_str);
1046 deprecated_mail_from( ack_file_name, result );
1047
1048 rpsl_object_delete(object);
1049 free(result_from_RIPupd->error_str);
1050 free(result_from_RIPupd);
1051 free(arg);
1052 free(old_version);
1053 return UP_INT;
1054 }
1055 }
1056 else
1057 {
1058 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
1059 type, get_search_key(object, type),
1060 result_from_delete_key);
1061 deprecated_mail_from( ack_file_name, result );
1062
1063 rpsl_object_delete(object);
1064 free(arg);
1065 free(old_version);
1066 free(result_from_delete_key);
1067 return UP_INT;
1068 }
1069 }
1070 else
1071 { /* auth failed */
1072 if (tracing)
1073 {
1074 printf("TRACING: Auth failed\n");
1075 }
1076
1077 free(arg);
1078 if ( UP_remove_override_attr(object) )
1079 {
1080 arg = rpsl_object_get_text(object,0);
1081 if ( ! arg )
1082 {
1083 /* if we are processing garbage with a : in the first line, arg may be null */
1084 arg = (char *)malloc(2);
1085 strcpy(arg, ""); /* Don't include object in ack/notif msgs */
1086 }
1087 }
1088 else
1089 {
1090 /* there was an override attr in this object and it has not been removed */
1091 arg = (char *)malloc(2);
1092 strcpy(arg, ""); /* Don't include object in ack/notif msgs */
1093 }
1094
1095 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
1096 type, get_search_key(object, type), arg);
1097 deprecated_mail_from( ack_file_name, result );
1098 NT_write_all_frwds(old_version, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
1099
1100 rpsl_object_delete(object);
1101 free(arg);
1102 free(old_version);
1103 return UP_AUF; /* Auth failed */
1104 }
1105 } /* end of identical match */
1106 else
1107 { /* the new & old versions do not match */
1108 free(arg);
1109 if ( UP_remove_override_attr(object) )
1110 {
1111 arg = rpsl_object_get_text(object,0);
1112 if ( ! arg )
1113 {
1114 /* if we are processing garbage with a : in the first line, arg may be null */
1115 arg = (char *)malloc(2);
1116 strcpy(arg, ""); /* Don't include object in ack/notif msgs */
1117 }
1118 }
1119 else
1120 {
1121 /* there was an override attr in this object and it has not been removed */
1122 arg = (char *)malloc(2);
1123 strcpy(arg, ""); /* Don't include object in ack/notif msgs */
1124 }
1125
1126 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n***Error: new & old versions do not match\n",
1127 type, get_search_key(object, type), arg);
1128
1129 rpsl_object_delete(object);
1130 free(arg);
1131 free(old_version);
1132 return UP_NOM; /* new & old versions do not match */
1133 }
1134 } /* end of the object is in the db */
1135 } /* end of the object is to be deleted */
1136 else
1137 { /* the object is _NOT_ to be deleted */
1138
1139 if (has_AUTO_NIC_hdl(object))
1140 { /* if the object has an AUTO NIC hdl */
1141 external_syntax_obj = rpsl_object_copy(object);
1142 external_syntax_results = UP_check_external_syntax(external_syntax_obj);
1143 if ( external_syntax_results->result != UP_EXTSYN_ERR
1144 && external_syntax_results->result != UP_EXTSYN_ERR_WARN)
1145 { /* if there is no error */
1146 /* then its nic-hdl attribute must be modified so that RIPupdate
1147 would understand that it must assign a NIC handle to it */
1148 /* but first check the auth */
1149 result = check_auth(external_syntax_obj, NULL, type, credentials);
1150 if (result == UP_AUTH_OK || result == UP_OKM)
1151 {
1152 if (tracing)
1153 {
1154 printf("TRACING: Will send the obj to be created with AUTO NIC hdl\n");
1155 }
1156 auto_nic = (char *)malloc(1024); /* should be enough for a NIC hdl */
1157 obj_with_AUTO_NIC_hdl = replace_AUTO_NIC_hdl(external_syntax_obj, auto_nic);
1158 if (tracing)
1159 {
1160 obj_with_AUTO_NIC_hdl_str = rpsl_object_get_text(obj_with_AUTO_NIC_hdl,0);
1161 printf("TRACING: Called replace_AUTO_NIC_hdl, get [%s]\n", obj_with_AUTO_NIC_hdl_str);
1162 printf("TRACING: Will send the obj to be added\n");
1163 free(obj_with_AUTO_NIC_hdl_str);
1164 obj_with_AUTO_NIC_hdl_str = NULL;
1165 }
1166 assigned_NIC = (char *)malloc(128); /* this should be enough for a NIC hdl */
1167 result_from_RIPupd = send_object_db(obj_with_AUTO_NIC_hdl, assigned_NIC, "ADD");
1168 if (result_from_RIPupd->result == 0)
1169 {
1170 AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n", type, assigned_NIC);
1171 deprecated_mail_from( ack_file_name, result );
1172
1173 /* replace the AUTO nic hdl with the assigned one (for reporting purposes, in the notif mesg) */
1174 formatted_object = UP_put_assigned_NIC(external_syntax_obj, assigned_NIC);
1175
1176 formatted_object_str = rpsl_object_get_text(formatted_object,0);
1177 NT_write_all_ntfs(NULL, arg, formatted_object_str, tmpdir, ntfy_hash, forw_hash, cross_hash,
1178 credentials.from);
1179
1180 result_from_RIPupd->result = 0;
1181 if (tracing && assigned_NIC != NULL)
1182 {
1183 printf("TRACING: send_object_db returned [%s] as assigned NIC hdl\n", assigned_NIC);
1184 }
1185 if (assigned_NIC != NULL)
1186 {
1187 if (tracing)
1188 {
1189 printf("TRACING: auto_nic=[%s], assigned_NIC=[%s]\n", auto_nic, assigned_NIC);
1190 }
1191 g_hash_table_insert(NIC_hdl_hash, auto_nic, assigned_NIC);
1192 if (tracing)
1193 {
1194 printf("TRACING: NIC_hdl_hash has %i pairs\n",g_hash_table_size(NIC_hdl_hash));
1195 }
1196 }
1197
1198 rpsl_object_delete(formatted_object);
1199 rpsl_object_delete(obj_with_AUTO_NIC_hdl);
1200 rpsl_object_delete(external_syntax_obj);
1201 rpsl_object_delete(object);
1202 free(result_from_RIPupd);
1203 free(formatted_object_str);
1204 free(external_syntax_results->new_obj);
1205 /* free(external_syntax_results->error_str);*/
1206 /* free(external_syntax_results->warning_str);*/
1207 free(external_syntax_results);
1208 free(arg);
1209 return UP_OK;
1210 }
1211 else
1212 {
1213 if ( UP_remove_override_attr(object) )
1214 {
1215 arg2 = rpsl_object_get_text(object,0);
1216 if ( ! arg2 )
1217 {
1218 /* if we are processing garbage with a : in the first line, arg2 may be null */
1219 arg2 = (char *)malloc(2);
1220 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1221 }
1222 }
1223 else
1224 {
1225 /* there was an override attr in this object and it has not been removed */
1226 arg2 = (char *)malloc(2);
1227 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1228 }
1229
1230 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s]\n%s\n%s\n",
1231 type, arg2, result_from_RIPupd->error_str);
1232 deprecated_mail_from( ack_file_name, result );
1233
1234 rpsl_object_delete(obj_with_AUTO_NIC_hdl);
1235 rpsl_object_delete(external_syntax_obj);
1236 rpsl_object_delete(object);
1237 free(result_from_RIPupd);
1238 free(external_syntax_results->new_obj);
1239 free(external_syntax_results);
1240 free(arg2);
1241 free(arg);
1242 return UP_INT;
1243 }
1244 }
1245 else
1246 {
1247 /* auth failed ! */
1248 if (tracing)
1249 {
1250 printf("TRACING: Auth failed\n");
1251 }
1252
1253 if ( UP_remove_override_attr(object) )
1254 {
1255 arg2 = rpsl_object_get_text(object,0);
1256 if ( ! arg2 )
1257 {
1258 /* if we are processing garbage with a : in the first line, arg2 may be null */
1259 arg2= (char *)malloc(2);
1260 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1261 }
1262 }
1263 else
1264 {
1265 /* there was an override attr in this object and it has not been removed */
1266 arg2 = (char *)malloc(2);
1267 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1268 }
1269
1270 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
1271 type, get_search_key(object, type), arg2);
1272 deprecated_mail_from( ack_file_name, result );
1273 NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
1274
1275 rpsl_object_delete(external_syntax_obj);
1276 rpsl_object_delete(object);
1277 free(external_syntax_results->new_obj);
1278 free(external_syntax_results);
1279 free(arg2);
1280 free(arg);
1281 return UP_AUF; /* Auth failed */
1282 }
1283 }
1284 else
1285 { /* external syntax check failed */
1286 if ( UP_remove_override_attr(object) )
1287 {
1288 arg2 = rpsl_object_get_text(object,0);
1289 if ( ! arg2 )
1290 {
1291 /* if we are processing garbage with a : in the first line, arg2 may be null */
1292 arg2= (char *)malloc(2);
1293 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1294 }
1295 }
1296 else
1297 {
1298 /* there was an override attr in this object and it has not been removed */
1299 arg2 = (char *)malloc(2);
1300 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1301 }
1302
1303 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s%s\n",
1304 type, get_search_key(object, type),
1305 arg2, external_syntax_results->error_str);
1306
1307 rpsl_object_delete(external_syntax_obj);
1308 rpsl_object_delete(object);
1309 free(external_syntax_results->new_obj);
1310 free(external_syntax_results);
1311 free(arg2);
1312 free(arg);
1313 return UP_SYN;
1314 }
1315 } /* end of the object has an AUTO NIC hdl */
1316 else
1317 { /* process object without an AUTO NIC hdl */
1318 old_version = get_old_version(object, arg);
1319 if (old_version != NULL)
1320 {
1321 /* so, this is an update operation */
1322 if (tracing)
1323 printf("TRACING: this is an UPDATE\n");
1324
1325 if ( (!reading_from_mail && !webupdate) ||
1326 (subject_result.result != UP_SUBJ_NEW_ENFORCED))
1327 {
1328 /* If the user didn't enforce creation in the subject line */
1329 external_syntax_obj = rpsl_object_copy(object);
1330 external_syntax_results = UP_check_external_syntax(external_syntax_obj);
1331 if ( external_syntax_results->result != UP_EXTSYN_ERR
1332 && external_syntax_results->result != UP_EXTSYN_ERR_WARN)
1333 {
1334 /* if there is no error */
1335 if ( identical(old_version, external_syntax_obj) != 1 )
1336 {
1337 /* if the old version & the new one are not identical */
1338 old_obj = rpsl_object_init(old_version);
1339 error_list = rpsl_object_errors(old_obj);
1340 /***************************** DO SOME ERROR CHECKING / REPORTING HERE ***************/
1341
1342 result = check_auth(object, old_obj, type, credentials);
1343 if (result == UP_AUTH_OK || result == UP_OKM)
1344 {
1345 if (tracing)
1346 {
1347 printf("TRACING: Will send the obj to be updated\n");
1348 }
1349
1350 generated_obj = rpsl_object_copy(external_syntax_obj);
1351 if (strcasecmp(type, "key-cert") == 0)
1352 {
1353 get_keyowner_fingerpr(object);/* get keyowner and fingerprint,
1354 save them into global vars */
1355 generated_obj_str = UP_generate_kc_attrs(generated_obj);
1356 free(external_syntax_results->new_obj);
1357 external_syntax_results->new_obj = generated_obj_str;
1358 }
1359
1360 result_from_RIPupd = send_object_db(generated_obj, NULL, "UPD");
1361
1362 if ( UP_remove_override_attr(object) )
1363 {
1364 arg2 = rpsl_object_get_text(object,0);
1365 if ( ! arg2 )
1366 {
1367 /* if we are processing garbage with a : in the first line, arg2 may be null */
1368 arg2= (char *)malloc(2);
1369 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1370 }
1371 }
1372 else
1373 {
1374 /* there was an override attr in this object and it has not been removed */
1375 arg2 = (char *)malloc(2);
1376 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1377 }
1378
1379 if (result_from_RIPupd->result == 0)
1380 {
1381 AK_add_to_ack(ack_file_name, "\nUpdate OK: [%s] %s\n",
1382 type, get_search_key(object, type));
1383 deprecated_mail_from( ack_file_name, result );
1384
1385 NT_write_all_ntfs(old_version, arg, external_syntax_results->new_obj, tmpdir, ntfy_hash, forw_hash, cross_hash,
1386 credentials.from);
1387
1388 rpsl_object_delete(generated_obj);
1389 rpsl_object_delete(old_obj);
1390 rpsl_object_delete(external_syntax_obj);
1391 rpsl_object_delete(object);
1392 free(result_from_RIPupd);
1393 free(old_version);
1394 free(external_syntax_results->new_obj);
1395 free(external_syntax_results);
1396 free(arg2);
1397 free(arg);
1398 return UP_OK;
1399 }
1400 else
1401 {
1402 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s\n%s\n",
1403 type, get_search_key(object, type),
1404 arg2, result_from_RIPupd->error_str);
1405 deprecated_mail_from( ack_file_name, result );
1406
1407 rpsl_object_delete(generated_obj);
1408 rpsl_object_delete(old_obj);
1409 rpsl_object_delete(external_syntax_obj);
1410 rpsl_object_delete(object);
1411 free(result_from_RIPupd->error_str);
1412 free(result_from_RIPupd);
1413 free(old_version);
1414 free(external_syntax_results->new_obj);
1415 free(external_syntax_results);
1416 free(arg2);
1417 free(arg);
1418 return UP_INT;
1419 }
1420 }
1421 else if (result == UP_NAM)
1422 {
1423 /* name of a person/role object cannot be changed */
1424 if (tracing)
1425 {
1426 printf("TRACING: name of a person/role object cannot be changed\n");
1427 }
1428
1429 if ( UP_remove_override_attr(object) )
1430 {
1431 arg2 = rpsl_object_get_text(object,0);
1432 if ( ! arg2 )
1433 {
1434 /* if we are processing garbage with a : in the first line, arg2 may be null */
1435 arg2= (char *)malloc(2);
1436 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1437 }
1438 }
1439 else
1440 {
1441 /* there was an override attr in this object and it has not been removed */
1442 arg2 = (char *)malloc(2);
1443 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1444 }
1445
1446 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s\n***Error: Name of a person or role object cannot be changed.\n",
1447 type, get_search_key(object, type), arg2);
1448
1449 rpsl_object_delete(old_obj);
1450 rpsl_object_delete(external_syntax_obj);
1451 rpsl_object_delete(object);
1452 free(old_version);
1453 free(external_syntax_results->new_obj);
1454 free(external_syntax_results);
1455 free(arg2);
1456 free(arg);
1457 return UP_NAM; /* name of a person/role object cannot be changed */
1458
1459
1460 }
1461 else
1462 {
1463 /* auth failed ! */
1464 if (tracing)
1465 {
1466 printf("TRACING: Auth failed\n");
1467 }
1468
1469 if ( UP_remove_override_attr(object) )
1470 {
1471 arg2 = rpsl_object_get_text(object,0);
1472 if ( ! arg2 )
1473 {
1474 /* if we are processing garbage with a : in the first line, arg2 may be null */
1475 arg2= (char *)malloc(2);
1476 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1477 }
1478 }
1479 else
1480 {
1481 /* there was an override attr in this object and it has not been removed */
1482 arg2 = (char *)malloc(2);
1483 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1484 }
1485
1486 /* we can now have a hierarchical authorisation failure in an update
1487 if an inet6num status is set to ASSIGNED when there are more specific objects */
1488 if (result == UP_HOF)
1489 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\nHierarchical Authorisation failed, request forwarded to maintainer.\n%s\n",
1490 type, get_search_key(object, type), arg2);
1491 else
1492 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
1493 type, get_search_key(object, type), arg2);
1494 deprecated_mail_from( ack_file_name, result );
1495
1496 NT_write_all_frwds(old_version, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
1497
1498 rpsl_object_delete(old_obj);
1499 rpsl_object_delete(external_syntax_obj);
1500 rpsl_object_delete(object);
1501 free(old_version);
1502 free(external_syntax_results->new_obj);
1503 free(external_syntax_results);
1504 free(arg2);
1505 free(arg);
1506 return UP_AUF; /* Auth failed */
1507 }
1508
1509 }
1510 else
1511 { /* if the old and new versions of the object are the same */
1512 if (tracing)
1513 {
1514 printf("TRACING: The obj sent is identical to the one in the DB (NOOP)\n");
1515 }
1516
1517 AK_add_to_ack(ack_file_name, "\nUpdate NOOP: [%s] %s\n",
1518 type, get_search_key(object, type));
1519
1520 rpsl_object_delete(external_syntax_obj);
1521 rpsl_object_delete(object);
1522 free(old_version);
1523 free(external_syntax_results->new_obj);
1524 free(external_syntax_results);
1525 free(arg);
1526 return UP_OK;
1527 }
1528 }
1529 else
1530 { /* if there is an error in external syntax checks */
1531 if ( UP_remove_override_attr(object) )
1532 {
1533 arg2 = rpsl_object_get_text(object,0);
1534 if ( ! arg2 )
1535 {
1536 /* if we are processing garbage with a : in the first line, arg2 may be null */
1537 arg2= (char *)malloc(2);
1538 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1539 }
1540 }
1541 else
1542 {
1543 /* there was an override attr in this object and it has not been removed */
1544 arg2 = (char *)malloc(2);
1545 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1546 }
1547
1548 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s%s\n",
1549 type, get_search_key(object, type),
1550 arg2, external_syntax_results->error_str);
1551
1552 rpsl_object_delete(external_syntax_obj);
1553 rpsl_object_delete(object);
1554 free(old_version);
1555 free(external_syntax_results->new_obj);
1556 free(external_syntax_results);
1557 free(arg2);
1558 free(arg);
1559 return UP_SYN;
1560 }
1561 }
1562 else
1563 { /* if the user enforced creation (using NEW keyword) in the subject line */
1564 if ( UP_remove_override_attr(object) )
1565 {
1566 arg2 = rpsl_object_get_text(object,0);
1567 if ( ! arg2 )
1568 {
1569 /* if we are processing garbage with a : in the first line, arg2 may be null */
1570 arg2= (char *)malloc(2);
1571 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1572 }
1573 }
1574 else
1575 {
1576 /* there was an override attr in this object and it has not been removed */
1577 arg2 = (char *)malloc(2);
1578 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1579 }
1580
1581 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s\n"
1582 "***Error: Object already exists\n",
1583 type, get_search_key(object, type), arg2),
1584
1585 rpsl_object_delete(object);
1586 free(old_version);
1587 free(arg2);
1588 free(arg);
1589 return UP_INT;
1590
1591 }
1592 } /* end of this is an update operation */
1593 else
1594 { /* old_version == NULL, so, creation */
1595 if (tracing)
1596 printf("TRACING: this is a CREATION\n");
1597
1598 external_syntax_obj = rpsl_object_copy(object);
1599 external_syntax_results = UP_check_external_syntax(external_syntax_obj);
1600 if ( external_syntax_results->result != UP_EXTSYN_ERR
1601 && external_syntax_results->result != UP_EXTSYN_ERR_WARN)
1602 {
1603 /* if there is no error */
1604 result = check_auth(object, NULL, type, credentials);
1605 if (result == UP_AUTH_OK || result == UP_OKM)
1606 {
1607 if (tracing)
1608 {
1609 printf("TRACING: Will send the obj to be added\n");
1610 }
1611 /* if the object is a key-cert object, then we must import the PGP key */
1612 if ( strcmp(type, "key-cert") == 0 )
1613 {
1614 result_from_import_key = import_key(object);
1615 }
1616 else
1617 {
1618 result_from_import_key = NULL;
1619 }
1620 if (result_from_import_key == NULL)
1621 {
1622 /* no PGP problem */
1623 generated_obj = rpsl_object_copy(external_syntax_obj);
1624 if (strcasecmp(type, "key-cert") == 0)
1625 {
1626 /* if the object is a key-cert object */
1627 generated_obj_str = UP_generate_kc_attrs(generated_obj);
1628 free(external_syntax_results->new_obj);
1629 external_syntax_results->new_obj = generated_obj_str;
1630 }
1631 result_from_RIPupd = send_object_db(generated_obj, NULL, "ADD");
1632
1633 if (result_from_RIPupd->result == 0)
1634 {
1635 /* if there was no problem */
1636 AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n",
1637 type, get_search_key(object, type));
1638 deprecated_mail_from( ack_file_name, result );
1639
1640 NT_write_all_ntfs(NULL, arg, external_syntax_results->new_obj, tmpdir,
1641 ntfy_hash, forw_hash, cross_hash, credentials.from);
1642
1643 rpsl_object_delete(generated_obj);
1644 rpsl_object_delete(external_syntax_obj);
1645 rpsl_object_delete(object);
1646 free(result_from_RIPupd);
1647 free(external_syntax_results->new_obj);
1648 free(external_syntax_results);
1649 free(arg);
1650 return UP_OK;
1651
1652 }
1653 else
1654 {
1655 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s\n",
1656 type, get_search_key(object, type),
1657 result_from_RIPupd->error_str);
1658 deprecated_mail_from( ack_file_name, result );
1659
1660 rpsl_object_delete(generated_obj);
1661 rpsl_object_delete(external_syntax_obj);
1662 rpsl_object_delete(object);
1663 free(result_from_RIPupd->error_str);
1664 free(result_from_RIPupd);
1665 free(external_syntax_results->new_obj);
1666 free(external_syntax_results);
1667 free(arg);
1668 return UP_INT;
1669 }
1670 }
1671 else
1672 {
1673 /* there was a problem with PGP key import */
1674 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s\n",
1675 type, get_search_key(object, type),
1676 result_from_import_key);
1677
1678 rpsl_object_delete(external_syntax_obj);
1679 rpsl_object_delete(object);
1680 free(result_from_import_key);
1681 free(external_syntax_results->new_obj);
1682 free(external_syntax_results);
1683 free(arg);
1684 return UP_INT;
1685 }
1686 }
1687 else if (result == UP_FWD)
1688 {
1689 /* this was a maintainer or as-block creation request, so
1690 forward it to <HUMAILBOX> */
1691 if (tracing)
1692 {
1693 printf("TRACING: Maintainer or as-block or irt request will be forwarded to <HUMAILBOX>\n");
1694 }
1695
1696 if ( UP_remove_override_attr(object) )
1697 {
1698 arg2 = rpsl_object_get_text(object,0);
1699 if ( ! arg2 )
1700 {
1701 /* if we are processing garbage with a : in the first line, arg2 may be null */
1702 arg2= (char *)malloc(2);
1703 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1704 }
1705 }
1706 else
1707 {
1708 /* there was an override attr in this object and it has not been removed */
1709 arg2 = (char *)malloc(2);
1710 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1711 }
1712
1713 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s\n"
1714 "***Error: %s objects cannot be created automatically\n"
1715 "***Error: This object has been forwarded to %s\n"
1716 "***Error: for authorisation.\n"
1717 "***Error: No further action from your part is required\n",
1718 type, get_search_key(object, type),
1719 arg2, type, humailbox);
1720
1721 if ( ! strcmp(type, "mntner") )
1722 {
1723 header_type = strdup("Maintainer");
1724 text_type = strdup("maintainer");
1725 }
1726 else if ( ! strcmp(type, "as-block") )
1727 {
1728 header_type = strdup("as-block");
1729 text_type = strdup("as-block");
1730 }
1731 else if ( ! strcmp(type, "irt") )
1732 {
1733 header_type = strdup("irt");
1734 text_type = strdup("irt");
1735 }
1736 else
1737 {
1738 header_type = strdup("");
1739 text_type = strdup("");
1740 }
1741
1742 /* and forward this creation request to <HUMAILBOX> */
1743 NT_forw_create_req(external_syntax_results->new_obj);
1744
1745 rpsl_object_delete(external_syntax_obj);
1746 rpsl_object_delete(object);
1747 free(external_syntax_results->new_obj);
1748 free(external_syntax_results);
1749 free(arg2);
1750 free(arg);
1751 free(header_type);
1752 free(text_type);
1753 return UP_AUF;
1754 }
1755 else if (result == UP_HOF)
1756 {
1757 /* hierarchical authorisation failed */
1758 if (tracing)
1759 {
1760 printf("TRACING: Auth failed\n");
1761 }
1762
1763 if ( UP_remove_override_attr(object) )
1764 {
1765 arg2 = rpsl_object_get_text(object,0);
1766 if ( ! arg2 )
1767 {
1768 /* if we are processing garbage with a : in the first line, arg2 may be null */
1769 arg2= (char *)malloc(2);
1770 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1771 }
1772 }
1773 else
1774 {
1775 /* there was an override attr in this object and it has not been removed */
1776 arg2 = (char *)malloc(2);
1777 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1778 }
1779
1780 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nHierarchical authorisation failed, request forwarded to maintainer.\n%s\n",
1781 type, get_search_key(object, type), arg2);
1782
1783 NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
1784
1785 rpsl_object_delete(external_syntax_obj);
1786 rpsl_object_delete(object);
1787 free(external_syntax_results->new_obj);
1788 free(external_syntax_results);
1789 free(arg2);
1790 free(arg);
1791 return UP_AUF;
1792 }
1793 else
1794 {
1795 /* auth failed ! */
1796 if (tracing)
1797 {
1798 printf("TRACING: Auth failed\n");
1799 }
1800
1801 if ( UP_remove_override_attr(object) )
1802 {
1803 arg2 = rpsl_object_get_text(object,0);
1804 if ( ! arg2 )
1805 {
1806 /* if we are processing garbage with a : in the first line, arg2 may be null */
1807 arg2= (char *)malloc(2);
1808 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1809 }
1810 }
1811 else
1812 {
1813 /* there was an override attr in this object and it has not been removed */
1814 arg2 = (char *)malloc(2);
1815 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1816 }
1817
1818 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
1819 type, get_search_key(object, type), arg2);
1820 deprecated_mail_from( ack_file_name, result );
1821
1822 NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
1823
1824 rpsl_object_delete(external_syntax_obj);
1825 rpsl_object_delete(object);
1826 free(external_syntax_results->new_obj);
1827 free(external_syntax_results);
1828 free(arg2);
1829 free(arg);
1830 return UP_AUF; /* Auth failed */
1831 }
1832 }
1833 else
1834 {
1835 if ( UP_remove_override_attr(object) )
1836 {
1837 arg2 = rpsl_object_get_text(object,0);
1838 if ( ! arg2 )
1839 {
1840 /* if we are processing garbage with a : in the first line, arg2 may be null */
1841 arg2= (char *)malloc(2);
1842 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1843 }
1844 }
1845 else
1846 {
1847 /* there was an override attr in this object and it has not been removed */
1848 arg2 = (char *)malloc(2);
1849 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
1850 }
1851
1852 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s%s\n",
1853 type, get_search_key(object, type),
1854 arg2, external_syntax_results->error_str);
1855
1856 rpsl_object_delete(external_syntax_obj);
1857 rpsl_object_delete(object);
1858 free(external_syntax_results->new_obj);
1859 free(external_syntax_results);
1860 free(arg2);
1861 free(arg);
1862 return UP_SYN;
1863 }
1864 } /* end of creation */
1865 } /* end of process object without an AUTO NIC hdl */
1866 } /* end of the object is _not_ to be deleted */
1867 } /* end of parsed with no systax errors */
1868 else
1869 {
1870 /* even if obj doesn't parse properly, it may be a legacy object
1871 which the user wants to delete... */
1872 if (tracing)
1873 {
1874 printf("TRACING: Object didn't parse, check for legacy object deletion\n");
1875 }
1876 /* if it is for deletion */
1877 if (rpsl_object_is_deleted(object))
1878 {
1879 /* here delete it */
1880 type = rpsl_object_get_class(object);
1881 old_version = get_old_version(object, arg);
1882
1883 if (tracing)
1884 {
1885 printf("TRACING: old_version: [\n%s]\n arg: [\n%s]\n", old_version, arg);
1886 }
1887
1888 if (old_version == NULL)
1889 {
1890 /* the object doesn't exist in the db! */
1891 free(arg);
1892 if ( UP_remove_override_attr(object) )
1893 {
1894 arg = rpsl_object_get_text(object,0);
1895 if ( ! arg )
1896 {
1897 /* if we are processing garbage with a : in the first line, arg may be null */
1898 arg = (char *)malloc(2);
1899 strcpy(arg, ""); /* Don't include object in ack/notif msgs */
1900 }
1901 }
1902 else
1903 {
1904 /* there was an override attr in this object and it has not been removed */
1905 arg = (char *)malloc(2);
1906 strcpy(arg, ""); /* Don't include object in ack/notif msgs */
1907 }
1908
1909 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n***Error: Entry not found\n\n%s\n",
1910 type, get_search_key(object, type), arg);
1911
1912 rpsl_object_delete(object);
1913 free(arg);
1914 return UP_NSO; /* no such object */
1915 }
1916 else
1917 {
1918
1919 if (tracing)
1920 {
1921 printf("TRACING: legacy object is in the database\n");
1922 }
1923
1924 /* the object is in the db */
1925 if ( identical(old_version, object) )
1926 {
1927 /* if the old & new versions are identical */
1928
1929 if (tracing)
1930 {
1931 printf("TRACING: old & new versions are identical\n");
1932 }
1933 result = check_auth(NULL, object, type, credentials);
1934 if (result == UP_AUTH_OK || result == UP_OKM)
1935 {
1936 if (tracing)
1937 {
1938 printf("TRACING: Will send the obj to be deleted\n");
1939 }
1940 if (strcmp(type, "key-cert") == 0)
1941 {
1942 result_from_delete_key = delete_key(object);
1943 }
1944 else
1945 {
1946 result_from_delete_key = NULL;
1947 }
1948 /* if there was no problem with key deletion from the key-ring */
1949 if (result_from_delete_key == NULL)
1950 {
1951 result_from_RIPupd = send_object_db(object, NULL, "DEL");
1952 if (result_from_RIPupd->result == 0)
1953 {
1954 AK_add_to_ack(ack_file_name, "\nDelete OK: [%s] %s\n",
1955 type, get_search_key(object, type));
1956 deprecated_mail_from( ack_file_name, result );
1957 NT_write_all_ntfs(old_version, NULL, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash,
1958 credentials.from);
1959
1960 rpsl_object_delete(object);
1961 free(result_from_RIPupd);
1962 free(arg);
1963 free(old_version);
1964 return UP_OK;
1965 }
1966 else
1967 {
1968 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
1969 type, get_search_key(object, type),
1970 result_from_RIPupd->error_str);
1971 deprecated_mail_from( ack_file_name, result );
1972
1973 rpsl_object_delete(object);
1974 free(result_from_RIPupd->error_str);
1975 free(result_from_RIPupd);
1976 free(arg);
1977 free(old_version);
1978 return UP_INT;
1979 }
1980 }
1981 else
1982 {
1983 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
1984 type, get_search_key(object, type), result_from_delete_key);
1985
1986 rpsl_object_delete(object);
1987 free(arg);
1988 free(old_version);
1989 free(result_from_delete_key);
1990 return UP_INT;
1991 }
1992 }
1993 else
1994 { /* auth failed */
1995 if (tracing)
1996 {
1997 printf("TRACING: Auth failed\n");
1998 }
1999
2000 if ( UP_remove_override_attr(object) )
2001 {
2002 arg2 = rpsl_object_get_text(object,0);
2003 if ( ! arg2 )
2004 {
2005 /* if we are processing garbage with a : in the first line, arg2 may be null */
2006 arg2= (char *)malloc(2);
2007 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
2008 }
2009 }
2010 else
2011 {
2012 /* there was an override attr in this object and it has not been removed */
2013 arg2 = (char *)malloc(2);
2014 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
2015 }
2016
2017 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
2018 type, get_search_key(object, type), arg2);
2019 deprecated_mail_from( ack_file_name, result );
2020 NT_write_all_frwds(arg, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
2021
2022 rpsl_object_delete(object);
2023 free(arg2);
2024 free(arg);
2025 free(old_version);
2026 return UP_AUF; /* Auth failed */
2027 }
2028 } /* end of identical match */
2029 else
2030 {
2031 /* the new & old versions do not match */
2032 if ( UP_remove_override_attr(object) )
2033 {
2034 arg2 = rpsl_object_get_text(object,0);
2035 if ( ! arg2 )
2036 {
2037 /* if we are processing garbage with a : in the first line, arg2 may be null */
2038 arg2= (char *)malloc(2);
2039 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
2040 }
2041 }
2042 else
2043 {
2044 /* there was an override attr in this object and it has not been removed */
2045 arg2 = (char *)malloc(2);
2046 strcpy(arg2, ""); /* Don't include object in ack/notif msgs */
2047 }
2048
2049 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s \n***Error: new & old versions do not match\n%s\n",
2050 type, get_search_key(object, type), arg2);
2051
2052 rpsl_object_delete(object);
2053 free(arg2);
2054 free(arg);
2055 free(old_version);
2056 return UP_NOM; /* new & old versions do not match */
2057 }
2058 } /* end of the object is in the db */
2059 } /* end of the object is to be deleted */
2060 else
2061 {
2062 /* syntax error AND not deletion */
2063
2064 write_errors_to_ack(object, arg, ack_file_name, NULL);
2065 rpsl_object_delete(object);
2066 free(arg);
2067 return UP_SYN; /* syntax error */
2068 }
2069 }
2070 }
2071
2072
2073
2074
2075
2076 /* processes the objects in the given file */
2077 void process_file(char * filename, credentials_struct credentials,
/* [<][>][^][v][top][bottom][index][help] */
2078 GHashTable * AUTO_NIC_hdl_hash, char * ack_file_name,
2079 GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash)
2080 {
2081 FILE * input_file;
2082 GSList *list_of_objects = NULL, *list_of_objects2 = NULL;
2083 GSList *next = NULL;
2084 int object_count = 0;
2085 char *object = NULL;
2086 char * line;
2087 char * lwrcase_line;
2088 int result = 0;
2089 rpsl_object_t *obj = NULL;
2090 const GList * error_list = NULL;
2091
2092 if (tracing)
2093 {
2094 printf("TRACING: process_file running\n");
2095 }
2096
2097 line = (char *)malloc(1024);
2098
2099 if ((input_file = fopen(filename, "r")) == NULL)
2100 {
2101 if (tracing)
2102 {
2103 printf("TRACING: Couldn't open the file %s: %s\n", filename, strerror(errno));
2104 }
2105 ER_perror(FAC_UP, UP_CANTOPEN, "Couldn't open the file %s: %s\n", filename, strerror(errno));
2106 exit(1);
2107 }
2108
2109 while (fgets(line, 1024, input_file) != NULL)
2110 {
2111 /* first, if it is a pasword, save it, but do not regard it as an attrib */
2112 lwrcase_line = strdup(line);
2113 g_strdown(lwrcase_line);
2114 if (strstr(lwrcase_line, "password:") == lwrcase_line)
2115 {
2116 if (tracing)
2117 {
2118 printf("TRACING: This is a password\n");
2119 }
2120 credentials.password_list = g_slist_append(credentials.password_list,
2121 g_strstrip(strdup(line + strlen("password:"))));
2122 free(lwrcase_line);
2123 continue;
2124 }
2125 free(lwrcase_line);
2126
2127 line = UP_remove_EOLs(line); /* remove '\n's and '\r' first */
2128 /* remove trailing white space */
2129 line = g_strchomp(line);
2130 if (strlen(line) == 0)
2131 {
2132 /* then, this was an empty line */
2133 if (object != NULL)
2134 {
2135 list_of_objects = g_slist_append(list_of_objects, object);
2136 if (tracing)
2137 {
2138 printf("TRACING: added an object: [%s]\n", object);
2139 }
2140 object = NULL;
2141 }
2142 }
2143 else
2144 {
2145 if (object == NULL && strlen(line) != 0)
2146 {
2147 object = (char *)malloc(strlen(line) + 2);
2148 object = strcpy(object, line);
2149 object = strcat(object, "\n"); /* add EOL again (we removed it before) */
2150 }
2151 else
2152 {
2153 object = (char *)realloc(object, strlen(object) + strlen(line) + 2);
2154 object = strcat(object, line);
2155 object = strcat(object, "\n");
2156 }
2157 }
2158
2159 }
2160 fclose(input_file);
2161 free(line);
2162
2163 /* now, if at the very and of the input file there wasn't an
2164 empty line, we have to add the remaining object in the 'object'
2165 variable */
2166 if (object != NULL)
2167 {
2168 list_of_objects = g_slist_append(list_of_objects, object);
2169 object = NULL;
2170 }
2171
2172
2173 if (tracing)
2174 {
2175 printf("TRACING: Will process the objects in the list\n");
2176 }
2177 next = list_of_objects;
2178 object_count = 0;
2179 for ( next = list_of_objects; next != NULL ; next = g_slist_next(next) )
2180 {
2181 if (UP_is_object((char *)next->data))
2182 {
2183 /* if this looks like an object */
2184
2185 object_count++;
2186 if(tracing)
2187 {
2188 printf("TRACING: Got an object from the list\n");
2189 printf("[%s]\n", (char *)next->data );
2190 }
2191
2192 obj = rpsl_object_init( (char *)next->data );
2193 error_list = rpsl_object_errors(obj);
2194
2195 if ( ! rpsl_object_has_error(obj, RPSL_ERRLVL_ERROR) && has_ref_to_AUTO_nic_hdl(obj) )
2196 {
2197 /* if object has a reference to an auto- nichdl and no syntax errors
2198 then defer the processing to allow the auto- nichdl to be created first */
2199 if(tracing)
2200 {
2201 printf("TRACING: this object has a ref to an AUTO NIC hdl\n");
2202 }
2203 list_of_objects2 = g_slist_append(list_of_objects2, strdup((char *)next->data));
2204 }
2205 else
2206 {
2207 result = 0;
2208 result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
2209 ntfy_hash, forw_hash, cross_hash);
2210 /* keep a tally */
2211 if (result == UP_NOOBJECT)
2212 {
2213 /* do nothing and don't increment any counts */
2214 }
2215 else if (result == UP_OK)
2216 {
2217 count_successful++;
2218 }
2219 else
2220 {
2221 count_unsuccessful++;
2222 }
2223 }
2224
2225 rpsl_object_delete(obj);
2226 }
2227 else
2228 {
2229 /* this does not look like an object (a signature? some other text?) */
2230
2231 AK_add_to_ack(ack_file_name, "\nThe following paragraph does not look like an object,\n"
2232 "so ignoring it:\n%s\n", (char *)next->data);
2233 }
2234 }
2235
2236
2237 if (tracing)
2238 {
2239 printf("TRACING: list_of_objects2 has %d entries\n", g_slist_length(list_of_objects2));
2240 printf("TRACING: will start to process the second list\n");
2241 }
2242
2243 for ( next = list_of_objects2; next != NULL ; next = g_slist_next(next) )
2244 {
2245 if (tracing)
2246 {
2247 printf("TRACING: Will process object: %s\n", (char *)next->data);
2248 }
2249 result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
2250 ntfy_hash, forw_hash, cross_hash);
2251 /* keep a tally */
2252 if (result == UP_NOOBJECT)
2253 {
2254 /* do nothing and don't increment any counts */
2255 }
2256 else if (result == UP_OK)
2257 {
2258 count_successful++;
2259 }
2260 else
2261 {
2262 count_unsuccessful++;
2263 }
2264 }
2265 }/* process_file */
2266
2267
2268
2269
2270 /* Generates a unique file name and returns the full path of the filename
2271 for storing notification message. */
2272
2273 char * generate_upd_file()
/* [<][>][^][v][top][bottom][index][help] */
2274 {
2275 char * name;
2276
2277 /* allocate space for name. 32 should be enough for PID */
2278 name = (char*)malloc(strlen(tmpdir) + strlen("/dbupdate-tmp.") + 34 );
2279
2280 sprintf(name, "%s/dbupdate-tmp.%i", tmpdir, pid /*getpid()*/);
2281
2282 return name;
2283 }
2284
2285
2286 /* create_lock_file: creates a lock file in lockdir and locks it. This is a
2287 part of crash recovery. Must be called in the beginning of the run. At the
2288 end, the file must be removed. */
2289 /* The idea: Create the "lock" file, and lock it. When another process starts
2290 running, it checks the existing lock files. If some exists, then it checks
2291 if it is locked or not. It not locked, then assumes that the corresponding
2292 dbupdate is alredy running. If not locked, assumes that it has crashed.
2293 (note: when a process crashes, the kernel releases all the files locked by
2294 this process [by the OS])
2295 Problem: locking doesn't work properly on some NFS implementations. */
2296
2297 lockfilestruct create_lock_file(){
/* [<][>][^][v][top][bottom][index][help] */
2298
2299 lockfilestruct lock;
2300 int file;
2301 int length;
2302
2303 /* allocate space for file name */
2304 length = strlen(lockdir) + strlen(hostname) + 32;
2305 lock.lockname = (char *)malloc(length + 1);
2306
2307 snprintf(lock.lockname, length, "%s/dbupdate.%s.%ld", lockdir, hostname, pid /*getpid()*/);
2308
2309 /* we will lock the file, so we have to use open(), but not fopen() (see man
2310 page of lockf(3C)) */
2311 if(( file = open(lock.lockname, O_RDWR|O_CREAT)) == -1){
2312 ER_perror(FAC_UP, UP_CANTOPEN, "Can't open lock file, %s", lock.lockname);
2313 exit(1);
2314 }
2315
2316 if(lockf(file, F_LOCK, 0) == -1){
2317 ER_perror(FAC_UP, UP_CANTLOCK, "Can't lock the file, %s", lock.lockname);
2318 exit(1);
2319 };
2320
2321 lock.filedes = file;
2322
2323 return lock;
2324
2325 }
2326
2327
2328
2329
2330
2331 /* remove_lock_file(): unlocks and removes the file */
2332 void remove_lock_file(lockfilestruct lockfile){
/* [<][>][^][v][top][bottom][index][help] */
2333
2334 close(lockfile.filedes); /* this will remove the lock at the same time */
2335 unlink(lockfile.lockname);
2336
2337 }
2338
2339
2340
2341 /* writes the checkpoint file with the specified state */
2342 void write_checkpoint(int state){
/* [<][>][^][v][top][bottom][index][help] */
2343
2344 char * filename;
2345 char * tmpfilename;
2346 int length;
2347 FILE * file;
2348
2349 if(tracing){
2350 printf("TRACING: write_checkpoint, state=[%i]\n", state);
2351 }
2352 length = strlen(lockdir) + strlen(hostname) + 64;
2353 filename = (char *)malloc(length + 1);
2354 tmpfilename = (char *)malloc(length + 5);
2355
2356 snprintf(filename, length, "%s/dbupdate.checkpoint.%s.%ld", lockdir, hostname, pid );
2357 snprintf(tmpfilename, length, "%s/dbupdate.checkpoint.%s.%ld.tmp", lockdir, hostname, pid );
2358
2359 if(( file = fopen(tmpfilename, "w")) == NULL){
2360 /* fprintf(stderr, "Can't open temp checkpoint file, %s", tmpfilename); */
2361 ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temp checkpoint file, %s", tmpfilename);
2362 exit(1);
2363 }
2364
2365 fprintf(file, "[STATE]\n%i\n", state);
2366
2367 fprintf(file, "[FLAGS]\n");
2368 /* should print the flags here */
2369
2370 fprintf(file, "[PARTS]\n");
2371 /* should print the parts (filenames) here */
2372
2373 fprintf(file, "[OBJECTS1]\n");
2374
2375 fprintf(file, "[OBJECTS2]\n");
2376
2377 fprintf(file, "[ACKFILE]\n");
2378
2379 fprintf(file, "[NOTIFFILES]\n");
2380
2381 fprintf(file, "[TIDS1]\n");
2382
2383 fprintf(file, "[TIDS2]\n");
2384
2385 fprintf(file, "[NICHDLHASH]\n");
2386
2387 fprintf(file, "[CURRENTOBJECT]\n");
2388
2389 fprintf(file, "[CURRENTPART]\n");
2390
2391
2392 fclose(file);
2393
2394 rename(tmpfilename, filename);
2395
2396 /* free the char *'s */
2397 free(tmpfilename);
2398 free(filename);
2399
2400 }
2401
2402
2403
2404
2405 /* removes check point file */
2406 void remove_checkpoint(){
/* [<][>][^][v][top][bottom][index][help] */
2407
2408 char * filename;
2409 int length;
2410
2411 if(tracing){
2412 printf("TRACING: remove_checkpoint\n");
2413 }
2414
2415 length = strlen(lockdir) + strlen(hostname) + 64;
2416 filename = (char *)malloc(length + 1);
2417
2418 snprintf(filename, length, "%s/dbupdate.checkpoint.%s.%ld", lockdir, hostname, pid );
2419
2420 unlink(filename);
2421
2422 /* free the char * */
2423 free(filename);
2424
2425 }
2426
2427
2428
2429
2430 /* main */
2431 int main(int argc, char **argv, char **envp){
/* [<][>][^][v][top][bottom][index][help] */
2432 /* init_and_set_options(argc, argv, envp); */
2433
2434 int i,j;
2435 char ** temp_vector;
2436 char * temp;
2437 char * temp_upd_file = NULL;
2438 char *input_file_name = NULL;
2439 GHashTable *AUTO_NIC_hdl_hash;
2440 credentials_struct credentials;
2441 FILE * upd_file;
2442 char c;
2443 char * mheader_replaced = NULL;
2444 char * mailtxt_replaced = NULL;
2445
2446 GHashTable *ntfy_hash, *forw_hash, *cross_hash;
2447
2448
2449 char * ack_file_name;
2450 char *config_file_name = NULL;
2451
2452
2453 /* to use EP module */
2454 EP_Mail_DescrPtr p;
2455 EPTokenPtr pt;
2456 EPTokenPtr list_item;
2457 EPTokenKeysPtr ptk;
2458
2459 char * temp_keyid;
2460 char * dummy_keyid;
2461
2462 /* a variable to be used to know if the part is pgp_signed or not */
2463 int pgp_signed = 0;
2464
2465 int ch;
2466 char * to_address = NULL;
2467 char * subject = NULL;
2468 char * reply_to = NULL;
2469
2470
2471 /* create notification hashes */
2472 ntfy_hash = g_hash_table_new(g_str_hash, g_str_equal);
2473 forw_hash = g_hash_table_new(g_str_hash, g_str_equal);
2474 cross_hash = g_hash_table_new(g_str_hash, g_str_equal);
2475
2476 credentials.password_list = NULL;
2477 credentials.from = NULL;
2478
2479 AUTO_NIC_hdl_hash = g_hash_table_new(g_str_hash, g_str_equal);
2480
2481 /* initialise the rpsl dictionary */
2482 rpsl_load_dictionary(RPSL_DICT_FRONT_END);
2483
2484 while ((ch = getopt(argc, argv, "MtSTf:c:snwheo:")) != -1){
2485 switch(ch) {
2486 case 'M':
2487 reading_from_mail = 1;
2488 break;
2489 case 'f':
2490 input_file_name = strdup(optarg);
2491 break;
2492 case 'c':
2493 config_file_name = strdup(optarg);
2494 break;
2495 case 't':
2496 tracing = 1;
2497 break;
2498 /* Test mode? In test mode, creation of mntners and as-blocks is possible, without overriding */
2499 case 'T':
2500 test_mode = 1;
2501 break;
2502 /* Supress acks and notifications? If yes, the acks and notifs will go to DEFMAIL config var */
2503 case 'S':
2504 supress_ack_notif = 1;
2505 break;
2506 /* Print out the ack to stdout? */
2507 case 's':
2508 print_out_ack = 1;
2509 break;
2510 /* are we processing networkupdate? (invoked via inetd) */
2511 case 'n':
2512 networkupdate = 1;
2513 break;
2514 case 'w':
2515 webupdate = 1;
2516 break;
2517 case 'h':
2518 /* help request from sync updates */
2519 help_requested = 1;
2520 break;
2521 case 'e':
2522 /* enforced new from sync updates */
2523 enforced_new = 1;
2524 break;
2525 case 'o':
2526 /* log a string from sync updates containing the origin IP address*/
2527 netupdclientIP = strdup(optarg);
2528 break;
2529 case '?':
2530 default:
2531 printf("Unknown option\n"); exit(1);
2532 }
2533 }
2534
2535 if (tracing)
2536 {
2537 printf("TRACING: options set\n");
2538 printf("TRACING: reading_from_mail [%d]\n", reading_from_mail);
2539 printf("TRACING: networkupdate [%d]\n", networkupdate);
2540 printf("TRACING: webupdate [%d]\n", webupdate);
2541 printf("TRACING: help_requested [%d]\n", help_requested);
2542 printf("TRACING: enforced_new [%d]\n", enforced_new);
2543 printf("TRACING: netupdclientIP [%s]\n", netupdclientIP ? netupdclientIP : "NULL");
2544 }
2545
2546 /* config stuff */
2547 /* if -c flag is given, use the named file as config file, otherwise use
2548 default filename */
2549 if ( config_file_name != NULL)
2550 {
2551 /*ca_readConfig(config_file_name, confVars, VARS);*/
2552 ca_init(config_file_name);
2553 free(config_file_name);
2554 }
2555 else
2556 {
2557 /*ca_readConfig("dbupdate.conf", confVars, VARS);*/
2558 ca_init("dbupdate.conf");
2559 }
2560
2561 error_init(argc, argv);
2562
2563
2564 tmpdir = ca_get_tmpdir;
2565 PA_SetTmpDir(tmpdir);
2566 tmpdir = g_strstrip(tmpdir);
2567 lockdir = ca_get_lockdir;
2568 mailcmd = ca_get_mailcmd;
2569 mailcmd = g_strstrip(mailcmd);
2570 notitxt = ca_get_notitxt;
2571 notihdr = ca_get_nheader;
2572 mailtxt = ca_get_mailtxt;
2573 successtxt = ca_get_successtxt;
2574 failuretxt = ca_get_failuretxt;
2575 helpheader = ca_get_helpheader;
2576 defmail = ca_get_defmail; defmail = UP_remove_EOLs(defmail);
2577 crosslog = ca_get_crosslog;
2578 fwtxt = ca_get_fwtxt;
2579 fwhdr = ca_get_fwheader;
2580 acksig = ca_get_acksig;
2581 humailbox = ca_get_humailbox;
2582 humailbox = g_strstrip(humailbox);
2583 autobox = ca_get_autobox;
2584 overridecryptedpw = ca_get_overridecryptedpw;
2585 overridecryptedpw = g_strstrip(overridecryptedpw);
2586 updlog = ca_get_updlog;
2587 acklog = ca_get_acklog;
2588 notiflog = ca_get_notiflog;
2589 notimailtxt = ca_get_notimailtxt;
2590 notinetworktxt = ca_get_notinetworktxt;
2591 forwlog = ca_get_forwlog;
2592 fwmailtxt = ca_get_fwmailtxt;
2593 mtfwheader = ca_get_mtfwheader;
2594 mtfwtxt = ca_get_mtfwtxt;
2595 country = ca_get_country;
2596 authmethod = ca_get_authmethod;
2597 pgppath = ca_get_pgppath;
2598 gpgcmd = ca_get_gpgcmd;
2599 PA_SetGPGCmd(gpgcmd);
2600 autodbmhelp = ca_get_autodbmhelp;
2601 allocmnt = ca_get_allocmnt; allocmnt = UP_remove_EOLs(allocmnt);
2602 /* convert all '\t's, '\n's and '\r's in allocmnt to white spaces */
2603 for(i=0;i<strlen(allocmnt);i++){
2604 if(allocmnt[i] == '\r' || allocmnt[i] == '\n' || allocmnt[i] == '\t'){
2605 allocmnt[i] = ' ';
2606 }
2607 }
2608 cn_subject_add = ca_get_cn_subject_add; cn_subject_add = UP_remove_EOLs(cn_subject_add);
2609 cn_subject_del = ca_get_cn_subject_del; cn_subject_del = UP_remove_EOLs(cn_subject_del);
2610 cn_explain_add = ca_get_cn_explain_add;
2611 cn_explain_del = ca_get_cn_explain_del;
2612 cn_overlap_add = ca_get_cn_overlap_add;
2613 cn_overlap_del = ca_get_cn_overlap_del;
2614 cno_subject_add = ca_get_cno_subject_add; cno_subject_add = UP_remove_EOLs(cno_subject_add);
2615 cno_subject_del = ca_get_cno_subject_del; cno_subject_del = UP_remove_EOLs(cno_subject_del);
2616 cno_explain_add = ca_get_cno_explain_add;
2617 cno_explain_del = ca_get_cno_explain_del;
2618 cno_overlap_add = ca_get_cno_overlap_add;
2619 cno_overlap_del = ca_get_cno_overlap_del;
2620 copyright_notice = ca_get_pw_resp_header;
2621 mheader = ca_get_mheader;
2622 pgp_public_key_ring = (char *)malloc(strlen(pgppath) + strlen("/pubring.gpg") + 2);
2623 sprintf(pgp_public_key_ring ,"%s/pubring.gpg", pgppath);
2624 PA_SetKeyRing(pgp_public_key_ring);
2625 if(test_mode != 1){/* if it is not already set to 1 (from command line), read from config */
2626
2627 test_mode = ca_get_testmode;
2628 }
2629 /* retrieve source variables */
2630 /* we now allow multiple sources */
2631 /* upd_source_hdl is a pointer to an array of pointers to source data */
2632 upd_source_hdl = ca_get_UpdSourceHandle(CA_UPDSOURCE);
2633
2634 if (upd_source_hdl[0] == NULL)
2635 {
2636 printf("There must be at least one updateable source in the config file. Exiting.\n");
2637 ER_perror(FAC_UP, UP_CONFERR, "There must be at least one updateable source in"
2638 " the config file. Exiting.");
2639 exit(1);
2640 }
2641 /* now using multiple sources,
2642 this data set up for each object in update message
2643 else{
2644 if(tracing){
2645 printf("\nTRACING: The upd_source_hdl is: %s\n", upd_source_hdl->name);
2646 }
2647 sources[0] = strdup(upd_source_hdl->name);
2648 update_host = upd_source_hdl->whoisd_host;
2649 query_host = strdup(update_host);
2650 update_port = upd_source_hdl->updPort;
2651 query_port = upd_source_hdl->qryPort;
2652 DBhost = upd_source_hdl->updDb.host;
2653 DBport = upd_source_hdl->updDb.port;
2654 DBname = upd_source_hdl->updDb.dbName;
2655 DBuser = upd_source_hdl->updDb.user;
2656 DBpasswd = upd_source_hdl->updDb.password;
2657 }
2658 */
2659
2660 /* construct country array from country string variable */
2661
2662 temp_vector = g_strsplit(country, "\n", 0);
2663 for (i=0, j=0; temp_vector[i] != NULL; i++)
2664 {
2665 temp_vector[i] == g_strstrip(temp_vector[i]);
2666 if (strlen(temp_vector[i]) > 0)
2667 {
2668 countries[j] = strdup(temp_vector[i]);
2669 g_strup(countries[j++]);
2670 }
2671 }
2672 countries[j] = NULL; /* mark the end of array */
2673 g_strfreev(temp_vector);
2674 if (tracing)
2675 {
2676 printf("TRACING: number of countries [%i]\n", j);
2677 }
2678
2679 /* construct authmethods array from authmethod string variable */
2680
2681 temp_vector = g_strsplit(authmethod, "\n", 0);
2682 for (i=0, j=0; temp_vector[i] != NULL; i++)
2683 {
2684 temp_vector[i] == g_strstrip(temp_vector[i]);
2685 if (strlen(temp_vector[i]) > 0)
2686 {
2687 authmethods[j] = strdup(temp_vector[i]);
2688 g_strup(authmethods[j++]);
2689 }
2690 }
2691 authmethods[j] = NULL; /* mark the end of array */
2692 g_strfreev(temp_vector);
2693
2694 /* hard code the nicsuffixes for now, but should be a configurable variable */
2695
2696 nicsuffixes[0] = strdup("RIPE");
2697 nicsuffixes[1] = strdup("ORG");
2698 nicsuffixes[2] = strdup("ARIN");
2699 nicsuffixes[3] = strdup("RADB");
2700 nicsuffixes[4] = strdup("APNIC");
2701 nicsuffixes[5] = strdup("RIPN");
2702 nicsuffixes[6] = NULL;
2703
2704 if (tracing)
2705 {
2706 /* print out the config variables for debugging */
2707 printf("TMPDIR is: [%s]\n", tmpdir);
2708 printf("MAILCMD is: [%s]\n", mailcmd);
2709 printf("NOTITXT is: [%s]\n", notitxt);
2710 printf("NOTIHDR is: [%s]\n", notihdr);
2711 printf("CROSSLOG is: [%s]\n", crosslog);
2712 printf("FWTXT is: [%s]\n", fwtxt);
2713 printf("FWHDR is: [%s]\n", fwhdr);
2714 printf("HUMAILBOX is: [%s]\n", humailbox);
2715 printf("AUTOBOX is: [%s]\n", autobox);
2716 printf("OVERRIDECRYPTEDPW is: [%s]\n", overridecryptedpw);
2717 printf("ACKLOG is: [%s]\n", acklog);
2718 printf("NOTIFLOG is: [%s]\n", notiflog);
2719 printf("FORWLOG is: [%s]\n", forwlog);
2720 printf("NOTIMAILTXT is: [%s]\n", notimailtxt);
2721 printf("FWMAILTXT is: [%s]\n", fwmailtxt);
2722 /* printf("COUNTRY is: [%s]\n", country); */
2723 printf("PGPPATH is: [%s]\n", pgppath);
2724 printf("LOCKDIR is: [%s]\n", lockdir);
2725 printf("TESTMODE is: [%i]\n", test_mode);
2726 printf("CNO_SUBJECT_ADD is: [%s]\n", cno_subject_add);
2727 printf("CNO_SUBJECT_DEL is: [%s]\n", cno_subject_del);
2728 }
2729 /* end of config stuff */
2730
2731
2732 /* set hostname global variable */
2733 gethostname(hostname, MAXHOSTNAMELEN);
2734
2735 /* set pid global variable */
2736 pid = getpid();
2737
2738 /* create the lock file and lock it */
2739 /* lockfile = create_lock_file(); */
2740
2741 /* Generate a name for temporary file for storing acks (AK_ack_file_name_generate
2742 also creates it) */
2743 ack_file_name = AK_ack_file_name_generate(tmpdir, ACK_FILE_PREFIX);
2744
2745 /* initialize credentials.pgp_key_list */
2746 credentials.pgp_key_list = NULL;
2747
2748
2749
2750 if (reading_from_mail || networkupdate || webupdate)
2751 {
2752 if (networkupdate)
2753 {
2754 set_default_source_data();
2755 process_networkupdate(credentials, AUTO_NIC_hdl_hash, ack_file_name,
2756 ntfy_hash, forw_hash, cross_hash);
2757 }
2758 if (input_file_name != NULL)
2759 {
2760 temp_upd_file = generate_upd_file();
2761 if (tracing)
2762 {
2763 printf("TRACING: temp_upd_file is [%s]\n", temp_upd_file);
2764 }
2765
2766 /* first log the input in the upd log file */
2767 UP_add_to_upd_log(input_file_name);
2768
2769
2770 MM_store(input_file_name, temp_upd_file, 0, networkupdate | webupdate);
2771 /*
2772 PA_SetGPGCmd(gpgcmd);
2773 PA_SetKeyRing(pgp_public_key_ring);
2774 */
2775 p = EP_ParseMail(temp_upd_file, tmpdir);
2776
2777 }
2778 else
2779 { /* input_file_name == NULL */
2780 temp_upd_file = generate_upd_file();
2781 MM_store("-", temp_upd_file, 0, networkupdate | webupdate);
2782
2783 /* first log the input in the upd log file */
2784 UP_add_to_upd_log(temp_upd_file);
2785
2786 /*
2787 PA_SetGPGCmd(gpgcmd);
2788 PA_SetKeyRing(pgp_public_key_ring);
2789 */
2790 p = EP_ParseMail(temp_upd_file, tmpdir);
2791
2792 }
2793
2794 /* write off the checkpoint file */
2795 write_checkpoint(1);
2796
2797 /* the new stuff using the EP module's interface */
2798
2799 if(p->from != NULL && p->from->field != NULL)
2800 {
2801 credentials.from = (char *)malloc(strlen(p->from->field) + strlen("From:") + 1);
2802 sprintf(credentials.from, "From:%s", p->from->field);
2803 credentials.from_email = strdup(p->from->field); /* This doesn't contain "From:" */
2804 /* cut off the '\n's and '\r's at the end */
2805 UP_remove_EOLs(credentials.from);
2806 UP_remove_EOLs(credentials.from_email);
2807
2808 /* now, there is a problem with EP module (or c-client): the p->from->field
2809 would contain only the first line if the "From" field has multiple lines.
2810 As a temp solution, we will add the second line (if it exists) explicitely */
2811 /* This is not a problem, it is the way the imap is written.
2812 It returns multiple lines as a linked list, so loop for all the lines */
2813 while ( (p->from = p->from->next) != NULL && p->from->field != NULL)
2814 { /* there is another line */
2815 credentials.from = (char *)realloc(credentials.from, strlen(credentials.from) + strlen(p->from->field) + 1);
2816 strcat(credentials.from, p->from->field);
2817 credentials.from_email = (char *)realloc(credentials.from_email, strlen(credentials.from_email) + strlen(p->from->field) + 1);
2818 strcat(credentials.from_email, p->from->field);
2819 UP_remove_EOLs(credentials.from);
2820 UP_remove_EOLs(credentials.from_email);
2821 }
2822 }
2823 else
2824 {
2825 credentials.from = strdup("");
2826 credentials.from_email = strdup("");
2827 }
2828
2829 update_mail_sender = strdup(credentials.from_email);
2830
2831 if (tracing)
2832 {
2833 printf("TRACING: From field is: [%s]\n", credentials.from);
2834 printf("TRACING: update_mail_sender is: [%s]\n", update_mail_sender);
2835 }
2836
2837
2838 if(p->cc != NULL && p->cc->field != NULL)
2839 {
2840 update_mail_cc = strdup(p->cc->field);
2841 /* cut off the '\n's and '\r's at the end */
2842 UP_remove_EOLs(update_mail_cc);
2843
2844 /* loop for all multiple lines */
2845 while ( (p->cc = p->cc->next) != NULL && p->cc->field != NULL)
2846 { /* there is another line */
2847 update_mail_cc = (char *)realloc(update_mail_cc, strlen(update_mail_cc) + strlen(p->cc->field) + 1);
2848 strcat(update_mail_cc, p->cc->field);
2849 UP_remove_EOLs(update_mail_cc);
2850 }
2851 }
2852 else
2853 update_mail_cc = strdup("");
2854
2855 if (tracing)
2856 {
2857 printf("TRACING: Cc field is: [%s]\n", update_mail_cc);
2858 }
2859
2860
2861 if(p->subject != NULL && p->subject->field != NULL)
2862 {
2863 subject = strdup(p->subject->field);
2864 /* cut off the '\n' and '\r' from the end */
2865 UP_remove_EOLs(subject);
2866
2867 /* loop for all multiple lines */
2868 while ( (p->subject = p->subject->next) != NULL && p->subject->field != NULL)
2869 { /* there is another line */
2870 subject = (char *)realloc(subject, strlen(subject) + strlen(p->subject->field) + 1);
2871 strcat(subject, p->subject->field);
2872 UP_remove_EOLs(subject);
2873 }
2874 }
2875 else
2876 subject = strdup("");
2877
2878 update_mail_subject = strdup(subject);
2879
2880 if (reading_from_mail)
2881 {
2882 /* parse the subject line */
2883 subject_result = UP_subject_process(update_mail_subject);
2884 if (tracing)
2885 printf("TRACING: subject processing result [%d]\n", subject_result.result);
2886 }
2887 else
2888 {
2889 /* web update (or networkupdate) */
2890 /* process the flags */
2891 subject_result = UP_subject_flags();
2892 if (tracing)
2893 printf("TRACING: subject flags result [%d]\n", subject_result.result);
2894 }
2895
2896 if(p->reply_to != NULL && p->reply_to->field != NULL)
2897 {
2898 reply_to = strdup(p->reply_to->field);
2899 /* cut off the '\n' and '\r' from the end */
2900 UP_remove_EOLs(reply_to);
2901
2902 /* loop for all multiple lines */
2903 while ( (p->reply_to = p->reply_to->next) != NULL && p->reply_to->field != NULL)
2904 { /* there is another line */
2905 reply_to = (char *)realloc(reply_to, strlen(reply_to) + strlen(p->reply_to->field) + 1);
2906 strcat(reply_to, p->reply_to->field);
2907 UP_remove_EOLs(reply_to);
2908 }
2909 }
2910 else
2911 reply_to = strdup("");
2912
2913
2914 to_address = find_email_address(credentials.from);
2915
2916 /* if Reply_To was available in the incoming header, then use it */
2917 if (strlen(reply_to) > 0)
2918 {
2919 to_address = (char *)realloc(to_address, strlen(reply_to) + 1);
2920 to_address = strcpy(to_address, reply_to);
2921 to_address = find_email_address(to_address); /* so that we take only the email address */
2922 }
2923
2924 if (p->message_id != NULL && p->message_id->field != NULL)
2925 {
2926 update_mail_ID = strdup(p->message_id->field);
2927 /* cut off the '\n' and '\r' from the end */
2928 UP_remove_EOLs(update_mail_ID);
2929
2930 /* loop for all multiple lines */
2931 while ( (p->message_id = p->message_id->next) != NULL && p->message_id->field != NULL)
2932 { /* there is another line */
2933 update_mail_ID = (char *)realloc(update_mail_ID, strlen(update_mail_ID) + strlen(p->message_id->field) + 1);
2934 strcat(update_mail_ID, p->message_id->field);
2935 UP_remove_EOLs(update_mail_ID);
2936 }
2937 }
2938 else
2939 update_mail_ID = strdup("");
2940
2941
2942 if(p->date != NULL && p->date->field != NULL)
2943 {
2944 update_mail_date = strdup(p->date->field);
2945 /* cut off the '\n' and '\r' from the end */
2946 UP_remove_EOLs(update_mail_date);
2947
2948 /* loop for all multiple lines */
2949 while ( (p->date = p->date->next) != NULL && p->date->field != NULL)
2950 { /* there is another line */
2951 update_mail_date = (char *)realloc(update_mail_date, strlen(update_mail_date) + strlen(p->date->field) + 1);
2952 strcat(update_mail_date, p->date->field);
2953 UP_remove_EOLs(update_mail_date);
2954 }
2955 }
2956 else
2957 update_mail_date = strdup("");
2958
2959 if (tracing)
2960 {
2961 printf("\nEP_ShowTree outputs:\n");
2962 EP_ShowTree(p->tree);
2963 }
2964
2965 pt = EP_GetTokens(p->tree, NULL, NULL, NULL);
2966
2967 if(tracing)
2968 {
2969 /* Print the list out (debugging) */
2970 printf("\nEP_PrintTokens outputs:\n");
2971 EP_PrintTokens(pt);
2972 }
2973
2974 /* replace the global variables in mheader */
2975 mheader_replaced = UP_replace_globals(mheader);
2976 /* replace the global variables in mailtxt */
2977 mailtxt_replaced = UP_replace_globals(mailtxt);
2978
2979 /* If this wasn't only a help request, then we need to process the input */
2980 if(subject_result.result != UP_SUBJ_HELP_REQ)
2981 {
2982 /* ... and now process the items in the list */
2983 list_item = pt;
2984 while (list_item != NULL)
2985 {
2986 if(tracing)
2987 {
2988 printf("\n\nWill process: %s, MIMEtype: %d\n", list_item->file, list_item->MIMEContentType);
2989 }
2990
2991 /* Start with passwords from pieces of mail up in the structure*/
2992 credentials.password_list = list_item->passwords;
2993 /* initialize pgp_key_list (XXX This should be a proper freeing of the list) */
2994 credentials.pgp_key_list = NULL;
2995 ptk = list_item->keys;
2996 if(ptk != NULL)
2997 {
2998 AK_add_to_ack(ack_file_name, "==== BEGIN PGP SIGNED PART (keyID(s):");
2999 pgp_signed = 1;
3000 while (ptk != NULL)
3001 {
3002 if(tracing)
3003 {
3004 printf("TRACING: key: %.8X, isValid: %i\n",
3005 ptk->keyID, ptk->isValidPGPSignature);
3006 }
3007 temp_keyid = (char *)malloc(10);
3008 sprintf(temp_keyid, "%.8X", ptk->keyID);
3009 dummy_keyid = strdup("00000000");
3010 if(tracing)
3011 {
3012 printf("TRACING: This key will be added to the list: [%s]\n", temp_keyid);
3013 }
3014
3015 if((ptk->isValidPGPSignature) == vS_IS_VALID)
3016 {
3017
3018 AK_add_to_ack(ack_file_name, " %s", temp_keyid);
3019 credentials.pgp_key_list = g_slist_append (credentials.pgp_key_list, temp_keyid);
3020 }
3021 else
3022 {
3023 /* if the signature was bad, just add a dummy key ID, '00000000' */
3024 if(tracing)
3025 {
3026 printf("TRACING: bad signature, adding a dummy key ID\n");
3027 }
3028
3029 AK_add_to_ack(ack_file_name, " %s", dummy_keyid);
3030 credentials.pgp_key_list = g_slist_append (credentials.pgp_key_list, dummy_keyid);
3031 }
3032
3033 free(dummy_keyid);
3034 ptk = ptk->next;
3035 if(ptk != NULL)
3036 {
3037 AK_add_to_ack(ack_file_name, ",");
3038 }
3039 else
3040 {
3041 AK_add_to_ack(ack_file_name, ") ====\n");
3042 }
3043 }
3044 }
3045 process_file(list_item->file, credentials,
3046 AUTO_NIC_hdl_hash, ack_file_name,
3047 ntfy_hash, forw_hash, cross_hash);
3048 if(pgp_signed)
3049 {
3050 AK_add_to_ack(ack_file_name, "==== END PGP SIGNED PART ====\n\n");
3051 pgp_signed = 0;
3052 }
3053 list_item = list_item->next;
3054 }
3055
3056 }
3057 else
3058 {
3059 /* this was only a help request (inferred from the "Subject" line of the upd message) */
3060
3061 /* Print out the header of the acknowledgement */
3062 /* AK_add_to_ack(ack_file_name, "To: %s\n%s\n\nHelp file requested so body of message ignored.\n\n\n"
3063 "============================================================\n\n",
3064 to_address, mheader_replaced); */
3065 AK_add_to_ack(ack_file_name, "\n============================================================\n\n");
3066
3067 AK_add_file_to_ack(ack_file_name, autodbmhelp);
3068 AK_add_to_ack(ack_file_name, "\n============================================================\n\n");
3069 }
3070
3071 EP_CleanTokens(pt);
3072
3073 EP_MailDescrCleanUp(p);
3074
3075 /* if we have created a temporary file for update, delete it */
3076 if (temp_upd_file != NULL)
3077 {
3078 unlink(temp_upd_file);
3079 }
3080
3081 }
3082 else
3083 { /* not reading from the mail message or from network */
3084 if (input_file_name != NULL)
3085 {
3086 /* first log the input in the upd log file */
3087 UP_add_to_upd_log(input_file_name);
3088
3089 write_checkpoint(1);
3090 process_file(input_file_name, credentials,
3091 AUTO_NIC_hdl_hash, ack_file_name,
3092 ntfy_hash, forw_hash, cross_hash);
3093 }
3094 else
3095 { /* the filename is not given, so we have to write
3096 stdin to a temp file, and give it to process_file */
3097 temp_upd_file = generate_upd_file();
3098 if (tracing)
3099 {
3100 printf("TRACING: main: temp_upd_file=%s\n", temp_upd_file);
3101 }
3102 if (( upd_file = fopen(temp_upd_file, "a")) == NULL)
3103 {
3104 ER_perror(FAC_UP, UP_CANTOPENW, "Can't open ack file, %s", temp_upd_file);
3105 }
3106
3107 while ((c = getchar()) != EOF)
3108 {
3109 fprintf(upd_file, "%c",c);
3110 }
3111 fclose(upd_file);
3112
3113 /* now log the input in the upd log file */
3114 UP_add_to_upd_log(temp_upd_file);
3115
3116 write_checkpoint(1);
3117 process_file(temp_upd_file, credentials,
3118 AUTO_NIC_hdl_hash, ack_file_name,
3119 ntfy_hash, forw_hash, cross_hash);
3120 unlink(temp_upd_file);
3121 }
3122 }
3123
3124
3125 /* post-process and send the ack */
3126 if(reading_from_mail && to_address != NULL){
3127 AK_send_ack(ack_file_name, to_address, mailcmd);
3128 }
3129
3130 /* if our update wasn't a mail update OR we have been asked explicitely
3131 to print out the ack to the stdout, print it */
3132 if((!reading_from_mail && !networkupdate)|| print_out_ack){
3133 AK_print_ack(ack_file_name);
3134 }
3135
3136 AK_log_ack(ack_file_name, acklog);
3137 AK_delete_ack(ack_file_name);
3138
3139 NT_send_ntfy_list(ntfy_hash, mailcmd);
3140 NT_log_ntfy_list(ntfy_hash, notiflog);
3141 NT_delete_ntfy_list(ntfy_hash);
3142
3143 NT_send_ntfy_list(forw_hash, mailcmd);
3144 NT_log_ntfy_list(forw_hash, forwlog);
3145 NT_delete_ntfy_list(forw_hash);
3146
3147
3148 NT_send_ntfy_list(cross_hash, mailcmd);
3149 NT_log_ntfy_list(cross_hash, crosslog);
3150 NT_delete_ntfy_list(cross_hash);
3151
3152 /* remove the lock file */
3153 /* remove_lock_file(lockfile); */
3154
3155
3156 /* remove checkpoint file */
3157 remove_checkpoint();
3158
3159 free(ack_file_name);
3160
3161 if (tracing)
3162 {
3163 printf("TRACING: END\n");
3164 }
3165
3166 return 0 ;
3167 }