## 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] */