modules/up/UP_extrnl_syntax.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- up_check_source_attr
- up_check_country_attr
- up_check_nicsuffixes
- up_get_dates
- up_changed_has_date
- UP_get_current_date
- up_add_dates
- up_check_date_order
- up_check_date
- up_check_dates_syntax
- up_check_changed_attr
- up_check_an_inetnum_attr
- up_check_a_status_attr
- up_check_status_attr
- up_add_keycert_attrs
- up_reconstruct_object
- UP_check_external_syntax
- UP_generate_kc_attrs
- up_assign_i6_status
- up_add_inet6num_attrs
- UP_generate_i6_attrs
1 /***************************************
2 $Revision: 1.12 $
3
4 UP external syntax checks
5
6 Status: REVIEWED, NOT TESTED
7
8 Author(s): Engin Gunduz
9
10 ******************/ /******************
11 Modification History:
12 engin (15/12/2000) Created.
13 denis (31/08/2001) Modified for new API
14 ******************/ /******************
15 Copyright (c) 2001,2002 RIPE NCC
16
17 All Rights Reserved
18
19 Permission to use, copy, modify, and distribute this software and its
20 documentation for any purpose and without fee is hereby granted,
21 provided that the above copyright notice appear in all copies and that
22 both that copyright notice and this permission notice appear in
23 supporting documentation, and that the name of the author not be
24 used in advertising or publicity pertaining to distribution of the
25 software without specific, written prior permission.
26
27 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
28 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
29 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
30 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
31 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
32 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
33 ***************************************/
34
35
36 /*#include "rpsl/object.hh"*/
37 #include "UP_extrnl_syntax.h"
38 #include "dbupdate.h"
39
40 #define UP_DATE_OK 0
41 #define UP_DATE_SYNERR 1
42 #define UP_DATE_FUTURE 2
43 #define UP_DATE_TOOSMALL 3
44 #define UP_DATE_INVMONTH 4
45 #define UP_DATE_INVDAY 5
46 #define UP_DATE_WRONGFORMAT 6
47 #define UP_DATE_NOK 7
48
49 char * up_date_errmsgs[]=
50 {
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 extern char * allocmnt;
69
70 extern char *sources[];
71 extern char *countries[];
72 extern char *nicsuffixes[];
73
74
75 /* void up_check_source_attr
76 checks for a valid source in the 'source' attributes */
77 void up_check_source_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
/* [<][>][^][v][top][bottom][index][help] */
78 {
79 int valid,i ;
80 char *source_name;
81 char *temp;
82 GList *source_list;
83
84 source_list = rpsl_object_get_attr(external_syntax_obj, "source");
85
86 valid = i = 0 ;
87 if ( source_list )
88 {
89 source_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(source_list->data) );
90 while(sources[i])
91 {
92 if(strcasecmp(sources[i++],source_name) == 0)
93 {
94 valid = 1;
95 break;
96 }
97 }
98 free(source_name);
99 g_list_free(source_list);
100 }
101
102 if (!valid)
103 {
104 /* the source is not recognised */
105 if (result->error_str == NULL)
106 {
107 result->error_str = strdup("***Error: No such source");
108 }
109 else
110 {
111 temp = (char *)malloc(strlen(result->error_str)
112 + strlen("***Error: No such source") + 2);
113 sprintf(temp, "%s\n%s", result->error_str,
114 "***Error: No such source");
115 free(result->error_str);
116 result->error_str = temp;
117 }
118 /* and here we have to change the result code of "result" here ... */
119 switch (result->result)
120 {
121 case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
122 case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
123 case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
124 case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
125 default: ;
126 }
127 }
128 }
129
130
131 /* void up_check_country_attr
132 checks for a valid country in the 'country' attributes */
133 void up_check_country_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
/* [<][>][^][v][top][bottom][index][help] */
134 {
135 int valid,i, matched ;
136 char *country_name;
137 char *temp;
138 GList *country_list = NULL;
139 GList *country_item = NULL;
140
141 country_list = rpsl_object_get_attr(external_syntax_obj, "country");
142
143 if ( country_list == NULL )
144 return; /* only check if there is one */
145
146 valid = 1 ;
147 for ( country_item = country_list; country_item != NULL ; country_item = g_list_next(country_item) )
148 {
149 country_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(country_item->data) );
150 matched = 0 ;
151 i = 0 ;
152 while(countries[i])
153 {
154 if(strcasecmp(countries[i++],country_name) == 0)
155 {
156 matched = 1;
157 break;
158 }
159 }
160
161 if ( ! matched )
162 {
163 valid = 0 ;
164 break;
165 }
166 free(country_name);
167 }
168 g_list_free(country_list);
169
170 if (!valid)
171 {
172 /* the country is not recognised */
173 if (result->error_str == NULL)
174 {
175 result->error_str = malloc(strlen("***Error: No such country []") + strlen(country_name) +2);
176 sprintf(result->error_str, "***Error: No such country [%s]", country_name);
177 }
178 else
179 {
180 temp = (char *)malloc(strlen(result->error_str)
181 + strlen("***Error: No such country []") + strlen(country_name) + 2);
182 sprintf(temp, "%s\n***Error: No such country [%s]", result->error_str,
183 country_name);
184 free(result->error_str);
185 result->error_str = temp;
186 }
187
188 free(country_name);
189
190 /* and here we have to change the result code of "result" here ... */
191 switch (result->result)
192 {
193 case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
194 case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
195 case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
196 case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
197 default: ;
198 }
199 }
200 }
201
202 /* void up_check_nicsuffixes
203 checks for a valid suffix at the end of a 'nic-hdl' attributes */
204 void up_check_nicsuffixes(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
/* [<][>][^][v][top][bottom][index][help] */
205 {
206 int valid,i ;
207 char *name;
208 char *temp;
209 GList *list;
210
211 list = rpsl_object_get_attr(external_syntax_obj, "nic-hdl");
212
213 valid = i = 0 ;
214 if ( list )
215 {
216 name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(list->data) );
217 if ( !strchr(name,'-') || strncasecmp(name,"AUTO-",strlen("AUTO-")) == 0 )
218 {
219 valid = 1;
220 }
221 else
222 {
223 while (nicsuffixes[i])
224 {
225 if ( strcasecmp(nicsuffixes[i++],strchr(name,'-')+1) == 0 )
226 {
227 valid = 1;
228 break;
229 }
230 }
231 if ( ! valid )
232 {
233 i = 0;
234 while (sources[i])
235 {
236 if (strcasecmp(sources[i++],strchr(name,'-')+1) == 0 )
237 {
238 valid = 1;
239 break;
240 }
241 }
242 if ( ! valid )
243 {
244 i = 0;
245 while (countries[i])
246 {
247 if ( strcasecmp(countries[i++],strchr(name,'-')+1) == 0 )
248 {
249 valid = 1;
250 break;
251 }
252 }
253 }
254 }
255 }
256 free(name);
257 g_list_free(list);
258
259 if (!valid)
260 {
261 /* the nicsuffix is not recognised */
262 if (result->error_str == NULL)
263 {
264 result->error_str = strdup("***Error: Invalid nic-hdl suffix");
265 }
266 else
267 {
268 temp = (char *)malloc(strlen(result->error_str)
269 + strlen("***Error: Invalid nic-hdl suffix") + 2);
270 sprintf(temp, "%s\n%s", result->error_str,
271 "***Error: Invalid nic-hdl suffix");
272 free(result->error_str);
273 result->error_str = temp;
274 }
275 /* and here we have to change the result code of "result" here ... */
276 switch (result->result)
277 {
278 case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
279 case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
280 case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
281 case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
282 default: ;
283 }
284 }
285 }
286 }
287
288
289 /* obtains a list of dates in the given
290 list of attributes */
291 GList * up_get_dates(GList * attribute_list)
/* [<][>][^][v][top][bottom][index][help] */
292 {
293 GList * item;
294 char * str, *temp;
295 GList * list = NULL;
296
297 for ( item = attribute_list; item != NULL ; item = g_list_next(item) )
298 {
299 /* is this a 'changed' attribute? */
300 if ( strcmp(rpsl_attr_get_name((rpsl_attr_t *)(item->data)), "changed") == 0 )
301 {
302 str = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
303
304
305 /* now, we have the 'changed' attribute's content in "normalized" form
306 We are sure it contains a date. So, it must be the second (and last)
307 word in the attrib. */
308 assert(index(str,' ') != NULL);
309 temp = (char *)malloc(strlen(str) - (index(str,' ') - str ));
310 temp = strncpy(temp, index(str,' ') + 1, strlen(str) - (index(str,' ') - str ) - 1);
311 temp[strlen(str) - (index(str,' ') - str ) - 1] = '\0'; /* NULL terminate it */
312 list = g_list_append (list, temp);
313 }
314 }
315
316 return list;
317 }
318
319
320
321
322 /* Does the 'changed' attribute we got have a date already?
323 Returns 1 if it does, 0 if not. */
324 int up_changed_has_date(char * value)
/* [<][>][^][v][top][bottom][index][help] */
325 {
326 /* now, if there is still a white space, then we have a date in the string
327 (it has to be something like "ripe-dbm@ripe.net 20001210") */
328 if (index(value, ' ') != NULL)
329 {
330 return 1;
331 }
332 else
333 {
334 return 0;
335 }
336 }
337
338
339
340
341 /* supplies the current date in YYYYMMDD format (for example 20011010) */
342 char * UP_get_current_date()
/* [<][>][^][v][top][bottom][index][help] */
343 {
344 /* We will use Glib's functions here */
345
346 char * date;
347 struct tm * time_struct;
348
349 time_t * time_loc;
350
351 time_loc = (time_t *)malloc(sizeof(time_t));
352 time(time_loc);
353
354 time_struct = localtime(time_loc);
355
356
357 date = (char *)malloc(9);
358 sprintf(date, "%04i%02i%02i",
359 time_struct->tm_year + 1900,
360 time_struct->tm_mon + 1,
361 time_struct->tm_mday);
362 return date;
363 }
364
365
366
367
368 /* int up_add_dates: adds dates to 'changed' attributes which
369 are missing one.
370 Returns 1 if no problems encountered
371 Returns 0 if a problem encountered, and the error string is set */
372 int up_add_dates(rpsl_object_t *external_syntax_obj, GList *attribute_list, char ** warning_str, char ** error_str)
/* [<][>][^][v][top][bottom][index][help] */
373 {
374 GList * item;
375 char * current_date;
376 int count_no_date = 0;
377 char * temp;
378 rpsl_attr_t *changed;
379 char *value;
380 int pos;
381
382 *warning_str = NULL;
383 *error_str = NULL;
384
385 /* get the current date in YYYYMMDD format (for example 20011010) */
386 current_date = UP_get_current_date();
387
388 for ( item = attribute_list; item != NULL ; item = g_list_next(item) )
389 {
390 /* is this a 'changed' attribute? */
391 if (strcmp(rpsl_attr_get_name((rpsl_attr_t *)(item->data)), "changed") == 0)
392 {
393 /* if this attribute does not have a date in it, add it. Also add
394 a warning message about this */
395 value = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
396 if ( !up_changed_has_date(value) )
397 {
398 count_no_date++;
399 /* create a copy of this changed attribute and add the date to the value */
400 changed = rpsl_attr_copy((rpsl_attr_t *)(item->data));
401 temp = (char *)malloc(strlen(value) + strlen(current_date) + 2 );
402 sprintf(temp, "%s %s", value, current_date);
403 rpsl_attr_replace_value(changed, temp);
404 free(temp);
405 /* delete the original attribute from the object */
406 pos = rpsl_attr_get_ofs(changed);
407 rpsl_object_remove_attr(external_syntax_obj, pos, NULL);
408 /* add the new changed attribute in the same position */
409 rpsl_object_add_attr(external_syntax_obj, changed, pos, NULL);
410 /* add a warning message */
411 if ( *warning_str == NULL)
412 {
413 *warning_str = (char *)malloc(strlen("WARNING date '' added to 'changed' attribute") + 9 );
414 sprintf(*warning_str, "WARNING date '%s' added to 'changed' attribute", current_date);
415 }
416 else
417 {
418 temp = (char *)malloc(strlen(*warning_str) + 1
419 + strlen("WARNING date '' added to 'changed' attribute") + 9 );
420 sprintf(temp, "%s\nWARNING date '%s' added to 'changed' attribute",
421 *warning_str, current_date);
422 free(*warning_str);
423 *warning_str = temp;
424 }
425 }
426 free(value);
427 }
428 }
429
430 if (count_no_date > 1)
431 {
432 *error_str = strdup("***Error: More than one 'changed' attributes without dates");
433 return 0;
434 }
435 else
436 {
437 return 1;
438 }
439 }
440
441
442
443
444 /* Checks the order of dates in the given list.
445 If they are in order, returns 1,
446 if not, returns 0 */
447 int up_check_date_order(GList * list)
/* [<][>][^][v][top][bottom][index][help] */
448 {
449 GList * item;
450 char * previous;
451 char *value;
452
453 /* if list is empty, return 1 immediately */
454 if (list == NULL)
455 {
456 return 1;
457 }
458
459 /* initialize the 'previous' date */
460 previous = strdup("00000000");
461
462 for ( item = list; item != NULL ; item = g_list_next(item))
463 {
464 assert((item->data) != NULL);
465 /* if the new date is smaller than the previous */
466 value = (char *)(item->data);
467 if ( strcmp(value, previous) < 0 )
468 {
469 free(previous);
470 return 0;
471 }
472 free(previous);
473 previous = strdup(value);
474 }
475
476 free(previous);
477 /* Reached the end, without finding out-of-order date. Return 1, then */
478 return 1;
479 }
480
481
482
483
484
485 /* up_check_date: checks the syntax of the date, given as the only
486 argument (char *). The argument is checked if it is in YYYYMMDD
487 format, and returns an error code accordingly */
488 int up_check_date(const char * arg)
/* [<][>][^][v][top][bottom][index][help] */
489 {
490 int date_int; /* integer representation of the date (arg) */
491 char * current_date;
492 int year, month, day; /* integers for the components of the date */
493
494 errno = 0;
495 date_int = atoi(arg);
496
497 if (errno != 0)
498 { /* there was an error in the conversion, syntax error */
499 return UP_DATE_SYNERR;
500 }
501
502 /* wrong format */
503 if (date_int <= 10000000 )
504 { /* the date is not in YYYYMMDD format */
505 return UP_DATE_WRONGFORMAT;
506 }
507
508 /* check if it is too small */
509 if (date_int <= 19880000 )
510 { /* the date is older than the DB itself! */
511 return UP_DATE_TOOSMALL;
512 }
513
514 /* check if it is too big */
515 if (date_int >= 100000000 )
516 {/* too big: syntax error */
517 return UP_DATE_SYNERR;
518 }
519
520 /* and now check year, month and day components */
521 year = date_int / 10000;
522 month = (date_int - (year * 10000) ) / 100;
523 day = (date_int % 100);
524
525 /* check year */
526 if (year < 1988 )
527 {
528 return UP_DATE_TOOSMALL;
529 }
530
531 /* check month */
532 if (month < 1 || month > 12)
533 {
534 return UP_DATE_INVMONTH;
535 }
536
537 /* check day */
538 if (day < 1 || day > 31)
539 {
540 return UP_DATE_INVDAY;
541 }
542
543 switch ( month )
544 {
545 case 1: case 3: case 5: case 7:
546 case 8: case 10: case 12:
547 if (day > 31)
548 {
549 return UP_DATE_INVDAY;
550 };
551 break;
552 case 2:
553 if ( (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) && (day > 29 ))
554 { /* leap year */
555 return UP_DATE_INVDAY;
556 }
557 else if( (!(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) && (day > 28) )
558 { /* non-leap year */
559 return UP_DATE_INVDAY;
560 };
561 break;
562 case 4: case 6: case 9: case 11:
563 if (day > 30)
564 {
565 return UP_DATE_INVDAY;
566 };
567 break;
568 default: return UP_DATE_INVMONTH;
569 }
570
571 /* check if the arg is in the future or not */
572 current_date = UP_get_current_date();
573 if (strcmp(current_date, arg) < 0 )
574 { /* arg is in the future */
575 free(current_date);
576 return UP_DATE_FUTURE;
577 }
578 free(current_date);
579
580 return UP_DATE_OK;
581 }
582
583
584
585 /* Checks the syntax of the dates in the list */
586 date_syntax_struct * up_check_dates_syntax(GList * list)
/* [<][>][^][v][top][bottom][index][help] */
587 {
588 GList * item;
589 date_syntax_struct * result;
590 int res;
591
592 /* initialize the result struct */
593 result = (date_syntax_struct *)malloc(sizeof(date_syntax_struct));
594 result->result = UP_DATE_OK;
595 result->error_str = NULL;
596
597 /* if list is empty, return immediately */
598 if (list == NULL)
599 {
600 return result;
601 }
602
603 /* loop through the members of the list, check each of them */
604 for ( item = list; item != NULL ; item = g_list_next(item))
605 {
606 assert((item->data) != NULL);
607
608 /* check the date */
609 res = up_check_date((char *)(item->data));
610 switch (res)
611 {
612 case UP_DATE_OK: break;
613
614 case UP_DATE_FUTURE:
615 case UP_DATE_TOOSMALL:
616 case UP_DATE_INVDAY:
617 case UP_DATE_INVMONTH:
618 case UP_DATE_WRONGFORMAT:
619
620 if (result->error_str == NULL)
621 {
622 result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[res])
623 + strlen(": ") + strlen((char *)(item->data)) + 1);
624 sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[res],
625 (char *)(item->data));
626 }
627 else
628 {
629 result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1
630 + strlen("***Error: ") + strlen(up_date_errmsgs[res])
631 + strlen(": ") + strlen((char *)(item->data)) + 1);
632 sprintf(result->error_str, "%s\n***Error: %s: %s",
633 result->error_str, up_date_errmsgs[res], (char *)(item->data));
634 }
635 result->result = UP_DATE_NOK; /* Not OK */
636
637 break;
638
639
640 case UP_DATE_SYNERR: /* syntax error in the date */
641
642 default:
643 if (result->error_str == NULL)
644 {
645 result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR])
646 + strlen(": ") + strlen((char *)(item->data)) + 1);
647 sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[UP_DATE_SYNERR],
648 (char *)(item->data));
649 }
650 else
651 {
652 result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1
653 + strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR])
654 + strlen(": ") + strlen((char *)(item->data)) + 1);
655 sprintf(result->error_str, "%s\n***Error: %s: %s",
656 result->error_str, up_date_errmsgs[UP_DATE_SYNERR], (char *)(item->data));
657 }
658 result->result = UP_DATE_NOK; /* Not OK */
659 break;
660 }
661 }
662
663 return result;
664 }
665
666
667
668 /* void up_check_changed_attr
669 checks the order of dates in the 'changed' attributes */
670 void up_check_changed_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
/* [<][>][^][v][top][bottom][index][help] */
671 {
672 GList * date_list;
673 int res;
674 char ** warning, **error;
675 char * temp;
676 date_syntax_struct * date_check_res;
677 GList *changed_list;
678
679 warning = (char **)malloc(sizeof(char **));
680 error = (char **)malloc(sizeof(char **));
681 changed_list = rpsl_object_get_attr(external_syntax_obj, "changed");
682
683 /* Now, add dates to the "changed" attributes */
684 res = up_add_dates(external_syntax_obj, changed_list, warning, error);
685 if (!res)
686 {
687 /* so, add the error string to result's error string */
688 if (result->error_str == NULL)
689 {
690 result->error_str = strdup(*error);
691 }
692 else
693 {
694 temp = (char *)malloc(strlen(result->error_str) + strlen(*error) + 2);
695 sprintf(temp, "%s\n%s", result->error_str, *error);
696 free(result->error_str);
697 result->error_str = temp;
698 }
699 }
700
701 /* and get the list of dates, we must check their order */
702 /* we may have added a date to one of the changed attrs so get the list again */
703 rpsl_attr_delete_list(changed_list);
704 changed_list = rpsl_object_get_attr(external_syntax_obj, "changed");
705 date_list = up_get_dates(changed_list);
706 /* and check the order */
707 res = up_check_date_order(date_list);
708 if (!res)
709 {
710 /* so, add the error string to result's error string */
711 if (result->error_str == NULL)
712 {
713 result->error_str = strdup("***Error: The dates in the 'changed' attributes should be in order");
714 }
715 else
716 {
717 temp = (char *)malloc(strlen(result->error_str)
718 + strlen("***Error: The dates in the 'changed' attributes should be in order") + 2);
719 sprintf(temp, "%s\n%s", result->error_str,
720 "***Error: The dates in the 'changed' attributes should be in order");
721 free(result->error_str);
722 result->error_str = temp;
723 }
724 /* and here we have to change the result code of "result" here ... */
725 switch (result->result)
726 {
727 case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
728 case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
729 case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
730 case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
731 default: ;
732 }
733 }
734
735 /* check the syntax of dates */
736 date_check_res = up_check_dates_syntax(date_list);
737 if (date_check_res->result != UP_DATE_OK)
738 {
739 /* so, add the error string to result's error string */
740 if (result->error_str == NULL)
741 {
742 result->error_str = strdup(date_check_res->error_str);
743 }
744 else
745 {
746 temp = (char *)malloc(strlen(result->error_str)
747 + strlen(date_check_res->error_str) + 2);
748 sprintf(temp, "%s\n%s", result->error_str,
749 date_check_res->error_str);
750 free(result->error_str);
751 result->error_str = temp;
752 }
753 /* and here we have to change the result code of "result" here ... */
754 switch (result->result)
755 {
756 case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
757 case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
758 case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
759 case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
760 default: ;
761 }
762 }
763 }
764
765
766 /* performs a simple check on a inetnum attribute. Assumes that
767 the RPSL parser has already checked it. Tries to see if the attr
768 is a range or not */
769 int up_check_an_inetnum_attr(const char * arg){
/* [<][>][^][v][top][bottom][index][help] */
770
771
772 char * str;
773 char * pos;
774
775 str = strdup(arg);
776
777 while((pos = index(str, '\n')) != NULL){
778 *pos = ' ';
779 }
780
781 /* strip off the comment */
782 if((pos = index(str, '#')) != NULL){
783 *pos = '\0';
784 }
785
786
787 /* Most of the syntax check is done by RPSL parser. We only need to check
788 that the argument is a _range_ of IPv4 addresses. So it suffices to
789 check the existence of '-' in the arg */
790 if(index(str, '-') != NULL){
791
792 free(str);
793 return 1;
794
795 }else{
796
797 free(str);
798 return 0;
799
800 }
801 }
802
803
804
805 /* Performs a check on status attribute. It can be
806 ALLOCATED PI or ALLOCATED PA only if the maintainers in the
807 mnt-by attribute contain at least one of the names mentioned in
808 ALLOCMNT config variable.
809 */
810 int up_check_a_status_attr(const char * arg, GList * mnt_by_list)
/* [<][>][^][v][top][bottom][index][help] */
811 {
812 GList * item;
813 int result;
814 char * status, * mnt_by_attrib;
815 char ** allocmnt_list;
816 int i;
817
818 status = strdup(arg);
819 g_strdown(status);
820
821 /* construct a list of mntners that are in allocmnt */
822 allocmnt_list = g_strsplit(allocmnt, " ", 0); /* delimited by " " */
823
824 if (strstr(status, "allocated") != NULL)
825 {
826 result = 1; /* initialize */
827
828 for ( item = mnt_by_list; item != NULL ; item = g_list_next(item) )
829 {
830 mnt_by_attrib = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
831 for (i=0; allocmnt_list[i] != NULL; i++)
832 { /* loop thru the list of allocmnt maintainers */
833 if ((strlen(allocmnt_list[i]) != 0) && strcasecmp(mnt_by_attrib, allocmnt_list[i]) == 0)
834 {
835 result = 0;
836 }
837 }
838 free(mnt_by_attrib);
839 }
840
841 free(status);
842 g_strfreev(allocmnt_list);
843 return result;
844
845 }
846 else
847 { /* the status attribute is not allocated */
848 free(status);
849 g_strfreev(allocmnt_list);
850 return 0; /* so there is no problem */
851
852 }
853
854 }
855
856
857
858
859
860 /* check for status attribute here: The status attribute can be
861 ALLOCATED PI or ALLOCATED PA only if the maintainers in the
862 mnt-by attribute contain at least one of the names mentioned in
863 ALLOCMNT config variable.
864 */
865 void up_check_status_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
/* [<][>][^][v][top][bottom][index][help] */
866 {
867 int res;
868 char * temp;
869 char *value;
870 GList * item;
871 GList * mnt_by_list = NULL;
872 GList *status_list = NULL;
873
874 /* Gather a list of mnt-by attributes */
875 mnt_by_list = rpsl_object_get_attr(external_syntax_obj, "mnt-by");
876 status_list = rpsl_object_get_attr(external_syntax_obj, "status");
877
878 /* check the syntax */
879 for ( item = status_list; item != NULL ; item = g_list_next(item) )
880 {
881 value = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
882 res = up_check_a_status_attr(value, mnt_by_list);
883 if (res != 0)
884 { /* there was a problem */
885 /* so, add the error string to result's error string */
886 if (result->error_str == NULL)
887 {
888 result->error_str = (char *)UT_malloc(strlen("***Error: Status ALLOCATED can be set only by the following mntner(s):\n")
889 +strlen("***Error: ") + strlen(allocmnt) + 2);
890 sprintf(result->error_str, "%s%s%s", "***Error: Status ALLOCATED can be set only by the following mntner(s):\n",
891 "***Error: ", allocmnt);
892 }
893 else
894 {
895 temp = (char *)malloc(strlen(result->error_str)
896 + strlen("***Error: Status ALLOCATED can be set only by the following mntner(s):\n")
897 + strlen("***Error: ") + strlen(allocmnt) + 2);
898 sprintf(temp, "%s\n%s%s%s", result->error_str,
899 "***Error: Status ALLOCATED can be set only by the following mntner(s):\n",
900 "***Error: ", allocmnt);
901 free(result->error_str);
902 result->error_str = temp;
903 }
904 /* and here we have to change the result code of "result" here ... */
905 switch (result->result)
906 {
907 case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
908 case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
909 case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
910 case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
911 default: ;
912 }
913 }
914 free(value);
915 }
916 rpsl_attr_delete_list(mnt_by_list);
917 rpsl_attr_delete_list(status_list);
918 }
919
920
921
922
923 /* void up_add_keycert_attrs
924 adds the generated attrs of key-cert objects */
925 void up_add_keycert_attrs(rpsl_object_t *generated_obj)
/* [<][>][^][v][top][bottom][index][help] */
926 {
927 const char *type;
928 char *attr_str;
929 rpsl_attr_t *method_attr;
930 rpsl_attr_t *owner_attr;
931 rpsl_attr_t *fingerpr_attr;
932
933 if (tracing)
934 {
935 printf("TRACING: UP_add_keycert_attrs: is running\n");
936 }
937
938 /* if this is a key-cert object */
939 type = rpsl_object_get_class(generated_obj);
940 if ( strcmp(type, "key-cert") == 0 )
941 {
942 method_attr = rpsl_attr_init("method: PGP", type);
943 if ( method_attr )
944 {
945 rpsl_object_add_attr(generated_obj, method_attr, 1, NULL);
946 }
947
948 attr_str = (char *)malloc( sizeof("owner: ") + strlen(keyowner) +1 );
949 strcpy(attr_str, "owner: ");
950 strcat(attr_str, keyowner);
951 if (tracing)
952 {
953 printf("TRACING: UP_add_keycert_attrs: owner attr_str [%s]\n", attr_str);
954 }
955 owner_attr = rpsl_attr_init(attr_str, "key-cert");
956 if ( owner_attr )
957 {
958 rpsl_object_add_attr(generated_obj, owner_attr, 2, NULL);
959 }
960 free(attr_str);
961
962 attr_str = (char *)malloc( sizeof("fingerpr: ") + strlen(fingerprint) +1 );
963 strcpy(attr_str, "fingerpr: ");
964 strcat(attr_str, fingerprint);
965 if (tracing)
966 {
967 printf("TRACING: UP_add_keycert_attrs: fingerprint attr_str [%s]\n", attr_str);
968 }
969 fingerpr_attr = rpsl_attr_init(attr_str, "key-cert");
970 if ( fingerpr_attr )
971 {
972 rpsl_object_add_attr(generated_obj, fingerpr_attr, 3, NULL);
973 }
974 free(attr_str);
975 }
976 }
977
978
979
980 /* Constructs a list of all attributes of an object, and returns it
981 as a list of attribute_struct */
982 /*GSList * up_get_attribute_list(Object * o, char * text){
983
984 char * value = NULL;
985 char * type = NULL;
986 Attr *attr;
987 GSList *list_of_attributes = NULL;
988 attribute_struct * attribute;
989
990 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
991 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
992 strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
993 attr->len - strlen(attr->type->name()) -2 );
994 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
995 if(tracing) {
996 cout << "TRACING: up_get_attributes: adding " << g_strstrip(value) << endl;
997 }
998 attribute = (attribute_struct *)malloc(sizeof(attribute_struct));
999 attribute->content = value;
1000 type = strdup(attr->type->name());
1001 g_strdown(type);
1002 attribute->type = type;
1003 list_of_attributes = g_slist_append(list_of_attributes, attribute);
1004 }
1005
1006
1007 return list_of_attributes;
1008
1009 }
1010 */
1011
1012
1013 /* up_reconstruct_object: Reconstructs the object's text representation
1014 using the parsed object */
1015 void up_reconstruct_object(rpsl_object_t *external_syntax_obj, external_syntax_struct *result)
/* [<][>][^][v][top][bottom][index][help] */
1016 {
1017 char * recons_obj = NULL;
1018
1019 recons_obj = rpsl_object_get_text(external_syntax_obj,RPSL_STD_COLUMN);
1020
1021 result->new_obj = recons_obj;
1022 }
1023
1024
1025
1026 /* UP_check_external_syntax: Checks the syntax of attributes which are not checked
1027 by RAToolSet syntax checker. */
1028 external_syntax_struct * UP_check_external_syntax(rpsl_object_t *external_syntax_obj)
/* [<][>][^][v][top][bottom][index][help] */
1029 {
1030 external_syntax_struct *result;
1031
1032 if (tracing)
1033 {
1034 printf("TRACING: UP_check_external_syntax running\n");
1035 }
1036
1037 result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
1038
1039 /* initialize the struct */
1040 result->result = 0;
1041 result->error_str = strdup("");
1042 result->warning_str = strdup("");
1043
1044 up_check_source_attr(external_syntax_obj, result);
1045
1046 up_check_country_attr(external_syntax_obj, result);
1047
1048 up_check_nicsuffixes(external_syntax_obj, result);
1049
1050 up_check_changed_attr(external_syntax_obj, result);
1051
1052 /* this will be done by the new API parser */
1053 /* up_check_auth_attr (arg, obj_text, attribute_list, result); */
1054
1055 /* this will be done by the new API parser */
1056 /* up_check_inetnum_attr(arg, obj_text, attribute_list, result); */
1057
1058 up_check_status_attr(external_syntax_obj, result);
1059
1060
1061 up_reconstruct_object(external_syntax_obj, result);
1062
1063 if (tracing)
1064 {
1065 printf("TRACING: UP_check_external_syntax: the reconstructed object is=[%s]\n", result->new_obj);
1066 printf("TRACING: UP_check_external_syntax: ... and the result code is=[%i]\n", result->result);
1067 }
1068
1069 return result;
1070 }
1071
1072
1073
1074 /* generates the "generated" attributes of a key-cert object. Returns the
1075 new object string*/
1076 char *UP_generate_kc_attrs(rpsl_object_t *generated_obj)
/* [<][>][^][v][top][bottom][index][help] */
1077 {
1078 external_syntax_struct *result;
1079 char *obj_str;
1080
1081 if (tracing)
1082 {
1083 printf("TRACING: UP_generate_kc_attrs: is running\n");
1084 }
1085
1086 result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
1087
1088 /* initialize the struct */
1089 result->result = 0;
1090 result->error_str = strdup("");
1091 result->warning_str = strdup("");
1092
1093 up_check_changed_attr(generated_obj, result);
1094 up_add_keycert_attrs(generated_obj);
1095
1096 up_reconstruct_object(generated_obj, result);
1097
1098 if (tracing)
1099 {
1100 printf("TRACING: UP_generate_kc_attrs: the reconstructed object is=[%s]\n", result->new_obj);
1101 printf("TRACING: UP_generate_kc_attrs: ... and the result code is=[%i]\n", result->result);
1102 }
1103
1104 obj_str = strdup(result->new_obj);
1105 free(result);
1106 return obj_str;
1107 }
1108
1109
1110
1111 /* char * up_assign_i6_status: Determines the status attribute of
1112 an inet6num object. It takes the inet6num attribute of the
1113 object as its only argument. If prefix length is less than
1114 4, then returns NULL */
1115 char * up_assign_i6_status(const char * inet6num_attr)
/* [<][>][^][v][top][bottom][index][help] */
1116 {
1117
1118 char ** split_str;
1119 int prefix_length;
1120 int result;
1121
1122 /* we need the prefix length here.*/
1123 split_str = g_strsplit(inet6num_attr, "/", 0);
1124 if(split_str[1] != NULL){
1125
1126 result = sscanf(split_str[1], "%i", &prefix_length);
1127 if(result != 0 && result != EOF){
1128
1129 if(prefix_length >= 0 && prefix_length <= 3){
1130
1131 g_strfreev(split_str);
1132 return NULL;
1133
1134 }else if(prefix_length >= 4 && prefix_length <= 15){
1135
1136 g_strfreev(split_str);
1137 return strdup("TLA");
1138
1139 }else if(prefix_length >= 16 && prefix_length <= 35){
1140
1141 g_strfreev(split_str);
1142 return strdup("SUBTLA");
1143
1144 }else if(prefix_length >= 36 && prefix_length <= 48){
1145
1146 g_strfreev(split_str);
1147 return strdup("NLA");
1148
1149 }else if(prefix_length >= 48 && prefix_length <= 64){
1150
1151 g_strfreev(split_str);
1152 return strdup("SLA");
1153
1154 }else{
1155
1156 /* "default" status */
1157 g_strfreev(split_str);
1158 return strdup("SLA");
1159
1160 }
1161
1162 }else{
1163
1164 /* return "default" status */
1165 g_strfreev(split_str);
1166 return strdup("SLA");
1167
1168 }
1169 }else{
1170
1171 /* return "default" status */
1172 g_strfreev(split_str);
1173 return strdup("SLA");
1174
1175 }
1176
1177 }
1178
1179
1180
1181 /* GSList * up_add_inet6num_attrs
1182 adds the generated attrs of inet6num objects */
1183 /*GSList * up_add_inet6num_attrs(Object * obj, char * obj_text, GSList * attribute_list,
1184 external_syntax_struct * result)*/
1185 void up_add_inet6num_attrs(rpsl_object_t *generated_obj)
/* [<][>][^][v][top][bottom][index][help] */
1186 {
1187
1188 int attribute_no;
1189 char *status_value;
1190 rpsl_attr_t * status_attr;
1191 char *inet6num_attr_str, *status_attr_str;
1192 const char *type;
1193 GList *attributes_changed;
1194
1195
1196
1197 /* if this is an inet6num object */
1198 type = rpsl_object_get_class(generated_obj);
1199 if( ! strcmp(type, "inet6num") )
1200 {
1201 inet6num_attr_str = get_search_key(generated_obj, "inet6num");
1202 status_value = up_assign_i6_status(inet6num_attr_str);
1203 status_attr_str = (char *)UT_malloc(strlen("status: ") + strlen(status_value) + 1);
1204 strcpy(status_attr_str, "status: ");
1205 strcat(status_attr_str, status_value);
1206 status_attr = rpsl_attr_init(status_attr_str, type);
1207 free(status_attr_str);
1208 if ( status_attr )
1209 {
1210 /* we will put the status attribute before the first 'changed' attribute */
1211 attribute_no = 1; /* a default position (the second attribute) in case we cannot find
1212 a 'changed' attribute */
1213 attributes_changed = rpsl_object_get_attr(generated_obj, "changed");
1214 if ( attributes_changed != NULL )
1215 {
1216 attribute_no = ((rpsl_attr_t *)(attributes_changed->data))->num;
1217 }
1218 rpsl_object_add_attr(generated_obj, status_attr, attribute_no, NULL);
1219 }
1220 }
1221 }
1222
1223
1224
1225 /* generates the "generated" attribute (status) of an inet6num object. Returns the
1226 new object as a char * */
1227 char *UP_generate_i6_attrs(rpsl_object_t *generated_obj)
/* [<][>][^][v][top][bottom][index][help] */
1228 {
1229
1230 external_syntax_struct *result;
1231 char *obj_str;
1232
1233 result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
1234
1235 /* initialize the struct */
1236 result->result = 0;
1237 result->error_str = strdup("");
1238 result->warning_str = strdup("");
1239
1240
1241 up_check_changed_attr(generated_obj, result);
1242 up_add_inet6num_attrs(generated_obj);
1243
1244 up_reconstruct_object(generated_obj, result);
1245
1246 if (tracing)
1247 {
1248 printf("TRACING: UP_generate_i6_attrs: the reconstructed object is=[%s]\n", result->new_obj);
1249 printf("TRACING: UP_generate_i6_attrs: ... and the result code is=[%i]\n", result->result);
1250 }
1251
1252 obj_str = strdup(result->new_obj);
1253 free(result->error_str);
1254 free(result->warning_str);
1255 free(result->new_obj);
1256 free(result);
1257 return obj_str;
1258 }
1259