bin/dbupdate/dbupdate.cc

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. error_init
  2. import_key
  3. process_object
  4. scan_for_PGP
  5. process_file
  6. generate_upd_file
  7. main

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

/* [<][>][^][v][top][bottom][index][help] */