## modules/up/UP_extrnl_syntax.cc

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

## FUNCTIONS

This source file includes following functions.

1. up_get_dates
2. up_changed_has_date
3. UP_get_current_date
4. up_add_dates
5. up_check_date_order
6. up_check_date
7. up_check_dates_syntax
8. up_check_changed_attr
9. up_check_an_auth_attr
10. up_check_auth_attr
11. up_check_an_inetnum_attr
12. up_check_inetnum_attr
13. up_add_keycert_attrs
14. up_get_attribute_list
15. up_reconstruct_object
16. UP_check_external_syntax
17. UP_generate_kc_attrs

       1 /***************************************
       2   $Revision: 1.10 $
       3
       4   UP external syntax checks
       5
       6   Status: NOT REVIEWED, NOT TESTED
       7
       8   Author(s):       Engin Gunduz
       9
      10   ******************/ /******************
      11   Modification History:
      12         engin (15/12/2000) Created.
      13   ******************/ /******************
      14   Copyright (c) 2001                              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 #include "rpsl/object.hh"
      36 #include "UP_extrnl_syntax.h"
      37 #include "dbupdate.h"
      38
      39 #define UP_DATE_OK      0
      40 #define UP_DATE_SYNERR  1
      41 #define UP_DATE_FUTURE  2
      42 #define UP_DATE_TOOSMALL        3
      43 #define UP_DATE_INVMONTH        4
      44 #define UP_DATE_INVDAY  5
      45 #define UP_DATE_WRONGFORMAT 6
      46 #define UP_DATE_NOK    7
      47
      48
      49
      50 char * up_date_errmsgs[]={
      51
      52   "OK",
      53   "Syntax error in date of 'changed' attribute",
      54   "Date in the future in 'changed' attribute",
      55   "Date is older than the database itself in 'changed' attribute",
      56   "Invalid month in date in 'changed' attribute",
      57   "Invalid day in date in 'changed' attribute",
      58   "Date must be in YYYYMMDD format in 'change' attribute",
      59   "Syntax error in date of 'changed' attribute"
      60 };
      61
      62
      63 extern int tracing;
      64
      65 extern char * fingerprint;
      66 extern char * keyowner;
      67
      68
      69
      70 /* obtains a list of dates in the given
      71    list of attributes (GSList of attribute_struct) */
      72 GSList * up_get_dates(GSList * attribute_list){
         /* [<][>][^][v][top][bottom][index][help] */
      73
      74   GSList * next;
      75   char * temp, * str;
      76   int i;
      77   GSList * list = NULL;
      78
      79   for( next = attribute_list; next != NULL ; next = g_slist_next(next) ){
      80     /* is this a 'changed' attribute? */
      81     if(strcmp((char *)(((attribute_struct *)(next->data))->type), "changed") == 0){
      82       temp = strdup(((attribute_struct *)(next->data))->content);
      83
      84       /* delete the part after '#', inclusive */
      85       if(index(temp,'#') != NULL){
      86         temp[index(temp, '#') - temp] = '\0';
      87       }
      88       /* replace \n, \r & \t's with " " */
      89       for(i = 0; i < strlen(temp) ;i++){
      90         if(temp[i] == '\n' || temp[i] == '\r' || temp[i] == '\t' ){
      91           temp[i] = ' ';
      92         }
      93       }
      94       g_strstrip(temp);
      95       /* delete multiple spaces */
      96       str = (char *)malloc(strlen(temp) + 1);
      97       up_string_pack(str, temp);
      98       free(temp);
      99
     100       /* now, we have the 'changed' attribute's content in "normalized" form
     101          We are sure it contains a date. So, it must be the second (and last)
     102          word in the attrib. */
     103       assert(index(str,' ') != NULL);
     104       temp = (char *)malloc(strlen(str) - (index(str,' ') - str ));
     105       temp = strncpy(temp, index(str,' ') + 1, strlen(str) - (index(str,' ') - str ) - 1);
     106       temp[strlen(str) - (index(str,' ') - str ) - 1] = '\0'; /* NULL terminate it */
     107       list = g_slist_append (list, temp);
     108     }
     109   }
     110
     111   return list;
     112 }
     113
     114
     115
     116
     117 /* Does the 'changed' attribute we got have a date already?
     118    Returns 1 if it does, 0 if not. */
     119 int up_changed_has_date(char * arg){
         /* [<][>][^][v][top][bottom][index][help] */
     120
     121   int i;
     122   char * str;
     123   char * temp;
     124
     125   str = strdup(arg);
     126
     127   /* cut off the EOL comments */
     128   if(index(str, '#')){
     129     str[index(str, '#') - str - 1 ] = '\0';
     130   }
     131
     132   /* replace \n, \r & \t's with " " */
     133   for(i = 0; i < strlen(str) ;i++){
     134     if(str[i] == '\n' || str[i] == '\r' || str[i] == '\t' ){
     135       str[i] = ' ';
     136     }
     137   }
     138   g_strstrip(str);
     139   /* delete multiple spaces */
     140   temp = (char *)malloc(strlen(str) + 1);
     141   up_string_pack(temp, str);
     142
     143   free(str);
     144   str = temp;
     145
     146   /* now, if there is still a white space, then we have a date in the string
     147      (it has to be something like "ripe-dbm@ripe.net 20001210") */
     148   if(index(str, ' ') != NULL){
     149     return 1;
     150   }else{
     151     return 0;
     152   }
     153 }
     154
     155
     156
     157
     158 /* supplies the current date in YYYYMMDD format (for example 20011010) */
     159 char * UP_get_current_date(){
         /* [<][>][^][v][top][bottom][index][help] */
     160   /* We will use Glib's functions here */
     161
     162   char * date;
     163   struct tm * time_struct;
     164
     165   time_t * time_loc;
     166
     167   time_loc = (time_t *)malloc(sizeof(time_t));
     168   time(time_loc);
     169
     170   time_struct = localtime(time_loc);
     171
     172
     173   date = (char *)malloc(9);
     174   sprintf(date, "%04i%02i%02i",
     175           time_struct->tm_year + 1900,
     176           time_struct->tm_mon + 1,
     177           time_struct->tm_mday);
     178   return date;
     179 }
     180
     181
     182
     183
     184
     185
     186
     187
     188 /* int up_add_dates: adds dates to 'changed' attributes which
     189      are missing one.
     190      Returns 1 if no problems encountered
     191      Returns 0 if a problem encountered, and the error string is set */
     192 int up_add_dates(GSList * attribute_list, char ** warning_str, char ** error_str){
         /* [<][>][^][v][top][bottom][index][help] */
     193
     194   GSList * next;
     195   char * attribute, * current_date;
     196   int count_no_date = 0;
     197   char * temp;
     198
     199   *warning_str = NULL;
     200   *error_str   = NULL;
     201
     202   /* get the current date in YYYYMMDD format (for example 20011010) */
     203   current_date = UP_get_current_date();
     204
     205   for( next = attribute_list; next != NULL ; next = g_slist_next(next) ){
     206     /* is this a 'changed' attribute? */
     207     if(strcmp((char *)(((attribute_struct *)(next->data))->type), "changed") == 0){
     208       /* if this attribute does not have a date in it, add it. Also add
     209           a warning message about this */
     210       if( !up_changed_has_date((char *)(((attribute_struct *)(next->data))->content))){
     211         count_no_date++;
     212         attribute = (char *)(((attribute_struct *)(next->data))->content);
     213         temp = (char *)malloc(strlen(attribute) + strlen(current_date) + 2 );
     214         if(index(attribute, '#')){/* cut off the EOL comments */
     215           attribute[index(attribute, '#') - attribute - 1] = '\0';
     216         }
     217         sprintf(temp, "%s %s", attribute, current_date);
     218         ((attribute_struct *)(next->data))->content = temp;
     219         free(attribute);
     220         /* add a warning message */
     221         if( *warning_str == NULL){
     222           *warning_str = (char *)malloc(strlen("WARNING  date '' added to 'changed' attribute") + 9 );
     223           sprintf(*warning_str, "WARNING  date '%s' added to 'changed' attribute", current_date);
     224         }else{
     225           temp = (char *)malloc(strlen(*warning_str) + 1
     226                                        + strlen("WARNING  date '' added to 'changed' attribute") + 9 );
     227           sprintf(temp, "%s\nWARNING  date '%s' added to 'changed' attribute",
     228                               *warning_str, current_date);
     229           free(*warning_str);
     230           *warning_str = temp;
     231         }
     232       }
     233     }
     234   }
     235
     236   if(count_no_date > 1){
     237     *error_str = strdup("***Error: More than one 'changed' attributes without dates");
     238     return 0;
     239   }else{
     240     return 1;
     241   }
     242
     243
     244 }
     245
     246
     247
     248
     249
     250
     251 /* Checks the order of dates in the given list.
     252    If they are in order, returns 1,
     253    if not, returns 0 */
     254 int up_check_date_order(GSList * list){
         /* [<][>][^][v][top][bottom][index][help] */
     255
     256   GSList * next;
     257   char * previous;
     258
     259   /* if list is empty, return 1 immediately */
     260   if(list == NULL){
     261     return 1;
     262   }
     263
     264   /* initialize the 'previous' date */
     265   previous = strdup("00000000");
     266
     267   for( next = list; next != NULL ; next = g_slist_next(next)){
     268     assert((next->data) != NULL);
     269     /* if the new date is smaller than the previous */
     270     if(strcmp((char *)(next->data), previous) < 0 ){
     271       free(previous);
     272       return 0;
     273     }
     274     free(previous);
     275     previous = strdup((char *)(next->data));
     276   }
     277
     278   free(previous);
     279   /* Reached the end, without finding out-of-order date. Return 1, then */
     280   return 1;
     281
     282 }
     283
     284
     285
     286
     287
     288 /* up_check_date: checks the syntax of the date, given as the only
     289    argument (char *). The argument is checked if it is in YYYYMMDD
     290    format, and returns an error code accordingly */
     291 int up_check_date(const char * arg){
         /* [<][>][^][v][top][bottom][index][help] */
     292
     293   int date_int; /* integer representation of the date (arg) */
     294   char * current_date;
     295   int year, month, day; /* integers for the components of the date */
     296
     297
     298   errno = 0;
     299   date_int = atoi(arg);
     300
     301
     302   if(errno != 0){/* there was an error in the conversion, syntax error */
     303     return UP_DATE_SYNERR;
     304   }
     305
     306   /* wrong format */
     307   if(date_int <= 10000000 ){ /* the date is not in YYYYMMDD format */
     308     return UP_DATE_WRONGFORMAT;
     309   }
     310
     311
     312   /* check if it is too small */
     313   if(date_int <= 19880000 ){ /* the date is older than the DB itself! */
     314     return UP_DATE_TOOSMALL;
     315   }
     316
     317   /* check if it is too big */
     318   if(date_int >= 100000000 ){/* too big: syntax error */
     319     return UP_DATE_SYNERR;
     320   }
     321
     322   /* and now check year, month and day components */
     323   year = date_int / 10000;
     324   month = (date_int - (year * 10000) ) / 100;
     325   day = (date_int % 100);
     326
     327   /* check year */
     328   if(year < 1988 ){
     329     return UP_DATE_TOOSMALL;
     330   }
     331
     332   /* check month */
     333   if(month < 1 || month > 12){
     334     return UP_DATE_INVMONTH;
     335   }
     336
     337   /* check day */
     338   if(day < 1 || day > 31){
     339     return UP_DATE_INVDAY;
     340   }
     341
     342   switch( month ){
     343     case 1: case 3: case 5: case 7:
     344     case 8: case 10: case 12:
     345          if (day > 31){
     346            return UP_DATE_INVDAY;
     347          };
     348          break;
     349     case 2:
     350          if ( (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) && (day > 29 )){ /* leap year */
     351            return UP_DATE_INVDAY;
     352          }else if( (!(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) && (day > 28) ){/* non-leap year */
     353            return UP_DATE_INVDAY;
     354          };
     355          break;
     356     case 4: case 6: case 9: case 11:
     357          if (day > 30){
     358            return UP_DATE_INVDAY;
     359          };
     360          break;
     361     default: return UP_DATE_INVMONTH;
     362
     363   }
     364
     365   /* check if the arg is in the future or not */
     366   current_date = UP_get_current_date();
     367   if(strcmp(current_date, arg) < 0 ){/* arg is in the future */
     368     free(current_date);
     369     return UP_DATE_FUTURE;
     370   }
     371   free(current_date);
     372
     373
     374   return UP_DATE_OK;
     375
     376 }
     377
     378
     379
     380
     381
     382
     383
     384
     385
     386
     387 /* Checks the syntax of the dates in the list */
     388 date_syntax_struct * up_check_dates_syntax(GSList * list){
         /* [<][>][^][v][top][bottom][index][help] */
     389
     390   GSList * next;
     391   char * previous;
     392   date_syntax_struct * result;
     393   int res;
     394
     395   /* initialize the result struct */
     396   result = (date_syntax_struct *)malloc(sizeof(date_syntax_struct));
     397   result->result = UP_DATE_OK;
     398   result->error_str = NULL;
     399
     400   /* if list is empty, return immediately */
     401   if(list == NULL){
     402     return result;
     403   }
     404
     405   /* loop through the members of the list, check each of them */
     406   for( next = list; next != NULL ; next = g_slist_next(next)){
     407     assert((next->data) != NULL);
     408
     409     /* check the date */
     410     res = up_check_date((char *)next->data);
     411     switch (res){
     412       case UP_DATE_OK: break;
     413
     414       case UP_DATE_FUTURE:
     415       case UP_DATE_TOOSMALL:
     416       case UP_DATE_INVDAY:
     417       case UP_DATE_INVMONTH:
     418       case UP_DATE_WRONGFORMAT:
     419
     420              if(result->error_str == NULL){
     421                result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[res])
     422                                                   + strlen(": ") + strlen((char *)next->data) + 1);
     423                sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[res],
     424                        (char *)next->data);
     425              }else{
     426                result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1
     427                                                    + strlen("***Error: ") + strlen(up_date_errmsgs[res])
     428                                                    + strlen(": ") + strlen((char *)next->data) + 1);
     429                sprintf(result->error_str, "%s\n***Error: %s: %s",
     430                        result->error_str, up_date_errmsgs[res], (char *)next->data);
     431              }
     432              result->result = UP_DATE_NOK; /* Not OK */
     433
     434              break;
     435
     436
     437       case UP_DATE_SYNERR: /* syntax error in the date */
     438
     439       default:
     440              if(result->error_str == NULL){
     441                result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR])
     442                                                   + strlen(": ") + strlen((char *)next->data) + 1);
     443                sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[UP_DATE_SYNERR],
     444                        (char *)next->data);
     445              }else{
     446                result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1
     447                                                    + strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR])
     448                                                    + strlen(": ") + strlen((char *)next->data) + 1);
     449                sprintf(result->error_str, "%s\n***Error: %s: %s",
     450                        result->error_str, up_date_errmsgs[UP_DATE_SYNERR], (char *)next->data);
     451              }
     452              result->result = UP_DATE_NOK; /* Not OK */
     453              break;
     454     }
     455
     456   }
     457
     458
     459   return result;
     460
     461 }
     462
     463
     464
     465
     466
     467
     468
     469
     470
     471
     472 /* void up_check_changed_attr
     473    checks the order of dates in the 'changed' attributes */
     474 void up_check_changed_attr(Object * obj, char * obj_text, GSList * attribute_list,
         /* [<][>][^][v][top][bottom][index][help] */
     475                            external_syntax_struct * result){
     476
     477   GSList * date_list;
     478   int res;
     479   char ** warning, **error;
     480   char * temp;
     481   date_syntax_struct * date_check_res;
     482
     483
     484   warning = (char **)malloc(sizeof(char **));
     485   error   = (char **)malloc(sizeof(char **));
     486
     487
     488   /* Now, add dates to the "changed" attributes */
     489   res = up_add_dates(/*changed_list*/attribute_list, warning, error);
     490   if(!res){
     491     /* so, add the error string to result's error string */
     492     if(result->error_str == NULL){
     493       result->error_str = strdup(*error);
     494     }else{
     495       temp = (char *)malloc(strlen(result->error_str) + strlen(*error) + 2);
     496       sprintf(temp, "%s\n%s", result->error_str, *error);
     497       free(result->error_str);
     498       result->error_str = temp;
     499     }
     500   }
     501
     502   /* and get the list of dates, we must check their order */
     503   date_list = up_get_dates(attribute_list);
     504   /* and check the order */
     505   res = up_check_date_order(date_list);
     506   if(!res){
     507     /* so, add the error string to result's error string */
     508     if(result->error_str == NULL){
     509       result->error_str = strdup("***Error: The dates in the 'changed' attributes should be in order");
     510     }else{
     511       temp = (char *)malloc(strlen(result->error_str)
     512               + strlen("***Error: The dates in the 'changed' attributes should be in order") + 2);
     513       sprintf(temp, "%s\n%s", result->error_str,
     514               "***Error: The dates in the 'changed' attributes should be in order");
     515       free(result->error_str);
     516       result->error_str = temp;
     517     }
     518     /* and here we have to change the result code of "result" here ... */
     519     switch(result->result){
     520       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
     521       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
     522       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
     523       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
     524       default: ;
     525     }
     526   }
     527
     528   /* check the syntax of dates */
     529   date_check_res = up_check_dates_syntax(date_list);
     530   if(date_check_res->result != UP_DATE_OK){
     531     /* so, add the error string to result's error string */
     532     if(result->error_str == NULL){
     533       result->error_str = strdup(date_check_res->error_str);
     534     }else{
     535       temp = (char *)malloc(strlen(result->error_str)
     536               + strlen(date_check_res->error_str) + 2);
     537       sprintf(temp, "%s\n%s", result->error_str,
     538               date_check_res->error_str);
     539       free(result->error_str);
     540       result->error_str = temp;
     541     }
     542     /* and here we have to change the result code of "result" here ... */
     543     switch(result->result){
     544       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
     545       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
     546       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
     547       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
     548       default: ;
     549     }
     550
     551   }
     552
     553 }
     554
     555
     556
     557
     558
     559 int up_check_an_auth_attr(const char * arg, char ** error){
         /* [<][>][^][v][top][bottom][index][help] */
     560
     561   char * attr;
     562   int ret = 1;
     563   char * cryptpw, * key;
     564
     565
     566   attr = strdup(arg);
     567   /*  chop the whitespace in hte beginning and end */
     568   g_strstrip(attr);
     569
     570   /* Convert to uppercase  */
     571   g_strup(attr);
     572
     573   /* chop the EOL comment off */
     574   if(index(attr, '#') != NULL){
     575     attr[index(attr, '#') - attr ] = '\0';
     576   }
     577
     578   if(strstr(attr, "MAIL-FROM ") == attr){
     579     /* It must have somethings after "MAIL-FROM ", which are
     580       supposed to be a regexp */
     581     if(strlen(attr) <= strlen("MAIL-FROM ")){
     582       ret = 0;
     583     }
     584   }else if(strstr(attr, "NONE") == attr){
     585     /* We mustn't have anything after "NONE"  */
     586     if(strlen(attr) != strlen("NONE")){
     587       *error = strdup("***Error: There mustn't be anything after NONE in 'auth' attribute");
     588       ret = 0;
     589     }
     590   }else if(strstr(attr, "CRYPT-PW ") == attr){
     591     /* The string after CRYPT-PW must be of length 13 and must consist of certain
     592        characters */
     593     cryptpw = strdup(attr + strlen("CRYPT-PW "));
     594     g_strstrip(cryptpw);
     595     if(strlen(cryptpw) != 13){
     596       *error = strdup("***Error: The crypted password must be 13-character long in 'auth' attribute");
     597       free(cryptpw);
     598       ret = 0;
     599     }
     600   }else if(strstr(attr, "PGPKEY-") == attr){
     601     /* The string after CRYPT-PW must be of length 13 and must consist of certain
     602        characters */
     603     key = strdup(attr + strlen("PGPKEY-"));
     604     g_strchomp(key);
     605     if(strlen(key) != 8){
     606       *error = strdup("***Error: The PGP key must be 8-character long in 'auth' attribute");
     607
     608       free(key);
     609       ret = 0;
     610     }
     611
     612   }else{
     613     *error = strdup("***Error: 'auth' attribute must start with MAIL-FROM, NONE, PGPKEY- or CRYPT-PW");
     614     ret = 0;
     615   }
     616
     617   free(attr);
     618   return ret;
     619 }
     620
     621
     622
     623
     624
     625
     626
     627 /* void up_check_auth_attr
     628    checks the syntax of 'auth' attributes */
     629 void up_check_auth_attr(Object * obj, char * obj_text, GSList * attribute_list, external_syntax_struct * result){
         /* [<][>][^][v][top][bottom][index][help] */
     630
     631   int res;
     632   char **error;
     633   char * temp;
     634   GSList * next;
     635
     636   error   = (char **)malloc(sizeof(char **));
     637
     638   /* loop in the attribute_list, find the 'auth' attribs, and check their syntax */
     639   for( next = attribute_list; next != NULL ; next = g_slist_next(next) ){
     640     /* is this an 'auth' attribute? */
     641     if(strcmp((char *)(((attribute_struct *)(next->data))->type), "auth") == 0){
     642       /* chech its syntax */
     643       res = up_check_an_auth_attr((char *)(((attribute_struct *)(next->data))->content), error);
     644       if(!res){
     645         /* so, add the error string to result's error string */
     646         if(result->error_str == NULL){
     647           result->error_str = strdup(*error);
     648         }else{
     649           temp = (char *)malloc(strlen(result->error_str)
     650                   + strlen(*error) + 2);
     651           sprintf(temp, "%s\n%s", result->error_str,
     652                   *error);
     653           free(result->error_str);
     654           result->error_str = temp;
     655         }
     656         /* and here we have to change the result code of "result" here ... */
     657         switch(result->result){
     658           case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
     659           case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
     660           case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
     661           case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
     662           default: ;
     663         }
     664       }
     665     }
     666   }
     667 }
     668
     669
     670 /* performs a simple check on a inetnum attribute. Assumes that
     671    the RPSL parser has already checked it. Tries to see if the attr
     672    is a range or not  */
     673 int up_check_an_inetnum_attr(const char * arg){
         /* [<][>][^][v][top][bottom][index][help] */
     674
     675
     676   char * str;
     677   char * pos;
     678
     679   str = strdup(arg);
     680
     681   while((pos = index(str, '\n')) != NULL){
     682     *pos = ' ';
     683   }
     684
     685   /* strip off the comment */
     686   if((pos = index(str, '#')) != NULL){
     687     *pos = '\0';
     688   }
     689
     690
     691   /* Most of the syntax check is done by RPSL parser. We only need to check
     692      that the argument is a _range_ of IPv4 addresses. So it suffices to
     693      check the existence of '-' in the arg */
     694   if(index(str, '-') != NULL){
     695
     696     free(str);
     697     return 1;
     698
     699   }else{
     700
     701     free(str);
     702     return 0;
     703
     704   }
     705 }
     706
     707
     708
     709 /* void up_check_inetnum_attr
     710    checks the syntax of 'inetnum' attributes
     711    (this is required to reject inetnums in the form of
     712    "inetnum: 23.23.23.23". RPSL parser unfortunately
     713    passes them although we define them as a range of ipv4 addreses.) */
     714 void up_check_inetnum_attr(Object * obj, char * obj_text, GSList * attribute_list, external_syntax_struct * result){
         /* [<][>][^][v][top][bottom][index][help] */
     715
     716   int res;
     717   char * temp;
     718   GSList * next;
     719
     720
     721   /* loop in the attribute_list, find the 'inetnum' attribs, and check their syntax */
     722   for( next = attribute_list; next != NULL ; next = g_slist_next(next) ){
     723     /* is this an 'inetnum' attribute? */
     724     if(strcmp((char *)(((attribute_struct *)(next->data))->type), "inetnum") == 0){
     725       /* chech its syntax */
     726       res = up_check_an_inetnum_attr((char *)(((attribute_struct *)(next->data))->content));
     727       if(!res){
     728         /* so, add the error string to result's error string */
     729         if(result->error_str == NULL){
     730           result->error_str = strdup("***Error: inetnum must be a range of IPv4 address\n");
     731         }else{
     732           temp = (char *)malloc(strlen(result->error_str)
     733                   + strlen("***Error: inetnum must be a range of IPv4 address\n") + 2);
     734           sprintf(temp, "%s\n%s", result->error_str,
     735                   "***Error: inetnum must be a range of IPv4 address\n");
     736           free(result->error_str);
     737           result->error_str = temp;
     738         }
     739         /* and here we have to change the result code of "result" here ... */
     740         switch(result->result){
     741           case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
     742           case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
     743           case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
     744           case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
     745           default: ;
     746         }
     747       }
     748     }
     749   }
     750 }
     751
     752
     753
     754
     755
     756
     757
     758 /* GSList * up_add_keycert_attrs
     759    adds the generated attrs of key-cert objects */
     760 GSList * up_add_keycert_attrs(Object * obj, char * obj_text, GSList * attribute_list, external_syntax_struct * result){
         /* [<][>][^][v][top][bottom][index][help] */
     761
     762   int res;
     763   char * type, * content;
     764   char **error;
     765   char * temp;
     766   GSList * new_list;
     767   attribute_struct * attribute;
     768
     769   new_list = attribute_list;
     770
     771
     772   /* if this is a key-cert object */
     773   if(strcmp(obj->type->getName(), "key-cert") == 0){
     774       content = strdup("PGP");
     775       type = strdup("method");
     776       attribute = (attribute_struct *)malloc(sizeof(attribute_struct));
     777       attribute->content = content;
     778       attribute->type = type;
     779       new_list = g_slist_insert(new_list, attribute, 1);
     780
     781       content = strdup(keyowner);
     782       type = strdup("owner");
     783       attribute = (attribute_struct *)malloc(sizeof(attribute_struct));
     784       attribute->content = content;
     785       attribute->type = type;
     786       new_list = g_slist_insert(new_list, attribute, 2);
     787
     788       content = strdup(fingerprint);
     789       type = strdup("fingerpr");
     790       attribute = (attribute_struct *)malloc(sizeof(attribute_struct));
     791       attribute->content = content;
     792       attribute->type = type;
     793       new_list = g_slist_insert(new_list, attribute, 3);
     794
     795   }
     796
     797   return new_list;
     798
     799 }
     800
     801
     802
     803
     804
     805
     806
     807
     808
     809
     810 /* Constructs a list of all attributes of an object, and returns it
     811    as a list of attribute_struct */
     812 GSList * up_get_attribute_list(Object * o, char * text){
         /* [<][>][^][v][top][bottom][index][help] */
     813
     814   char * value = NULL;
     815   char * type = NULL;
     816   Attr *attr;
     817   GSList *list_of_attributes = NULL;
     818   attribute_struct * attribute;
     819
     820   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
     821     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
     822     strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
     823         attr->len - strlen(attr->type->name()) -2 );
     824     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
     825       if(tracing) {
     826         cout << "TRACING: up_get_attributes: adding " << g_strstrip(value) << endl;
     827       }
     828       attribute = (attribute_struct *)malloc(sizeof(attribute_struct));
     829       attribute->content = value;
     830       type = strdup(attr->type->name());
     831       g_strdown(type);
     832       attribute->type = type;
     833       list_of_attributes = g_slist_append(list_of_attributes, attribute);
     834   }
     835
     836
     837   return list_of_attributes;
     838
     839 }
     840
     841
     842
     843
     844 /* up_reconstruct_object: Reconstructs the object's text representation
     845      using the attribute list */
     846 void up_reconstruct_object(GSList * attr_list, external_syntax_struct *result){
         /* [<][>][^][v][top][bottom][index][help] */
     847
     848   char * recons_obj = NULL;
     849   char * temp;
     850   char * content, * type;
     851   GSList * next;
     852
     853
     854
     855
     856   for( next = attr_list; next != NULL ; next = g_slist_next(next) ){
     857
     858     content = strdup((char *)(((attribute_struct *)(next->data))->content));
     859     type = strdup((char *)(((attribute_struct *)(next->data))->type));
     860
     861     if(tracing){
     862       printf("TRACING: up_reconstruct_object:[%s:%s]\n", type, content);
     863     }
     864
     865     if(recons_obj == NULL){
     866       recons_obj = (char *)malloc(14 + strlen(content) + 1 );
     867       /* trim the white spaces in the beginning */
     868       g_strchug(content);
     869
     870       /* add ':' at the end of 'type' */
     871       temp = (char *)malloc(strlen(type) + 2);
     872       sprintf(temp, "%s:", type);
     873       free(type);
     874       type = temp;
     875
     876       sprintf(recons_obj, "%-14s%s", type, content);
     877     }else{
     878       /* trim the white spaces in the beginning */
     879       g_strchug(content);
     880
     881       /* add ':' at the end of 'type' */
     882       temp = (char *)malloc(strlen(type) + 2);
     883       sprintf(temp, "%s:", type);
     884       free(type);
     885       type = temp;
     886
     887       temp = (char *)malloc(strlen(recons_obj) + 14 + strlen(content) + 3 );
     888       sprintf(temp, "%s\n%-14s%s", recons_obj, type, content);
     889       free(recons_obj);
     890       recons_obj = temp;
     891     }
     892
     893   }
     894
     895   result->new_obj = recons_obj;
     896
     897 }
     898
     899
     900
     901
     902 /*  UP_check_external_syntax: Checks the syntax of attributes which are not checked
     903        by RAToolSet syntax checker. */
     904 external_syntax_struct * UP_check_external_syntax(Object * arg, char * obj_text){
         /* [<][>][^][v][top][bottom][index][help] */
     905
     906   external_syntax_struct *result;
     907   GSList * attribute_list;
     908
     909
     910
     911
     912   result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
     913
     914   /* initialize the struct */
     915   result->result = 0;
     916   result->error_str = strdup("");
     917   result->warning_str = strdup("");
     918
     919   /* get a list of all attributes */
     920   attribute_list = up_get_attribute_list(arg, obj_text);
     921
     922   up_check_changed_attr(arg, obj_text, attribute_list, result);
     923   up_check_auth_attr   (arg, obj_text, attribute_list, result);
     924   up_check_inetnum_attr(arg, obj_text, attribute_list, result);
     925
     926   up_reconstruct_object(attribute_list, result);
     927
     928   if(tracing){
     929     printf("TRACING: UP_check_external_syntax: the reconstructed object is=[%s]\n", result->new_obj);
     930     printf("TRACING: UP_check_external_syntax: ... and the result code is=[%i]\n", result->result);
     931   }
     932
     933   return result;
     934 }
     935
     936
     937
     938
     939
     940 /* generates the "generated" attributes of a key-cert object. Returns the
     941    new object as a char * */
     942 char * UP_generate_kc_attrs(Object * arg, char * obj_text){
         /* [<][>][^][v][top][bottom][index][help] */
     943
     944   external_syntax_struct *result;
     945   GSList * attribute_list;
     946
     947
     948
     949
     950   result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
     951
     952   /* initialize the struct */
     953   result->result = 0;
     954   result->error_str = strdup("");
     955   result->warning_str = strdup("");
     956
     957   /* get a list of all attributes */
     958   attribute_list = up_get_attribute_list(arg, obj_text);
     959
     960   up_check_changed_attr(arg, obj_text, attribute_list, result);
     961   //up_check_auth_attr   (arg, obj_text, attribute_list, result);
     962   attribute_list = up_add_keycert_attrs (arg, obj_text, attribute_list, result);
     963
     964
     965   up_reconstruct_object(attribute_list, result);
     966
     967   if(tracing){
     968     printf("TRACING: UP_check_external_syntax: the reconstructed object is=[%s]\n", result->new_obj);
     969     printf("TRACING: UP_check_external_syntax: ... and the result code is=[%i]\n", result->result);
     970   }
     971
     972   return result->new_obj;
     973 }
     974

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