1 | /***************************************
2 | $Revision: 1.16 $
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 int num_sources;
69 | extern char *countries[];
70 | extern char *nicsuffixes[];
71 | extern ca_updDbSource_t **upd_source_hdl;
72 |
73 |
74 | /* void up_check_source_attr
75 | checks for a valid source in the 'source' attributes */
76 | void up_check_source_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
77 | {
78 | int valid,i ;
79 | char *source_name;
80 | char *temp;
81 | GList *source_list;
82 |
83 | if (tracing)
84 | {
85 | printf("TRACING: up_check_source_attr running\n");
86 | }
87 |
88 | source_list = rpsl_object_get_attr(external_syntax_obj, "source");
89 |
90 | valid = i = 0 ;
91 | if ( source_list )
92 | {
93 | source_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(source_list->data) );
94 | for ( i=0; i<num_sources; i++ )
95 | {
96 | if ( ! strcasecmp( source_name, upd_source_hdl[i]->name) )
97 | {
98 | valid = 1;
99 | break;
100 | }
101 | }
102 |
103 | /* while(sources[i])
104 | {
105 | if(strcasecmp(sources[i++],source_name) == 0)
106 | {
107 | valid = 1;
108 | break;
109 | }
110 | } */
111 |
112 | g_list_free(source_list);
113 | }
114 |
115 | if (!valid)
116 | {
117 | /* the source is not recognised */
118 |
119 | if (tracing)
120 | {
121 | printf("TRACING: invalid source [%s]\n", source_name );
122 | }
123 |
124 | if (result->error_str == NULL)
125 | {
126 | result->error_str = strdup("***Error: No such source");
127 | }
128 | else
129 | {
130 | temp = (char *)malloc(strlen(result->error_str)
131 | + strlen("***Error: No such source") + 2);
132 | sprintf(temp, "%s\n%s", result->error_str,
133 | "***Error: No such source");
134 | free(result->error_str);
135 | result->error_str = temp;
136 | }
137 | /* and here we have to change the result code of "result" here ... */
138 | switch (result->result)
139 | {
140 | case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
141 | case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
142 | case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
143 | case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
144 | default: result->result = UP_EXTSYN_ERR; break;
145 | }
146 | }
147 |
148 | free(source_name);
149 | }
150 |
151 |
152 | /* void up_check_country_attr
153 | checks for a valid country in the 'country' attributes */
154 | void up_check_country_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
155 | {
156 | int valid,i, matched ;
157 | char *country_name;
158 | char *temp;
159 | GList *country_list = NULL;
160 | GList *country_item = NULL;
161 |
162 | country_list = rpsl_object_get_attr(external_syntax_obj, "country");
163 | rpsl_attr_split_multiple(&country_list);
164 |
165 | if ( country_list == NULL )
166 | return; /* only check if there is one */
167 |
168 | valid = 1 ;
169 | for ( country_item = country_list; country_item != NULL ; country_item = g_list_next(country_item) )
170 | {
171 | country_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(country_item->data) );
172 | matched = 0 ;
173 | i = 0 ;
174 | while(countries[i])
175 | {
176 | if(strcasecmp(countries[i++],country_name) == 0)
177 | {
178 | matched = 1;
179 | break;
180 | }
181 | }
182 |
183 | if ( ! matched )
184 | {
185 | valid = 0 ;
186 | break;
187 | }
188 | free(country_name);
189 | }
190 | g_list_free(country_list);
191 |
192 | if (!valid)
193 | {
194 | /* the country is not recognised */
195 | if (result->error_str == NULL)
196 | {
197 | result->error_str = malloc(strlen("***Error: No such country []") + strlen(country_name) +2);
198 | sprintf(result->error_str, "***Error: No such country [%s]", country_name);
199 | }
200 | else
201 | {
202 | temp = (char *)malloc(strlen(result->error_str)
203 | + strlen("***Error: No such country []") + strlen(country_name) + 2);
204 | sprintf(temp, "%s\n***Error: No such country [%s]", result->error_str,
205 | country_name);
206 | free(result->error_str);
207 | result->error_str = temp;
208 | }
209 |
210 | free(country_name);
211 |
212 | /* and here we have to change the result code of "result" here ... */
213 | switch (result->result)
214 | {
215 | case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
216 | case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
217 | case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
218 | case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
219 | default: ;
220 | }
221 | }
222 | }
223 |
224 | /* void up_check_nicsuffixes
225 | checks for a valid suffix at the end of a 'nic-hdl' attributes */
226 | void up_check_nicsuffixes(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
227 | {
228 | int valid,i ;
229 | char *name;
230 | char *temp;
231 | GList *list;
232 |
233 | if (tracing)
234 | {
235 | printf("TRACING: up_check_nicsuffixes running\n");
236 | }
237 |
238 | list = rpsl_object_get_attr(external_syntax_obj, "nic-hdl");
239 |
240 | valid = i = 0 ;
241 | if ( list )
242 | {
243 | name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(list->data) );
244 | if ( !strchr(name,'-') || strncasecmp(name,"AUTO-",strlen("AUTO-")) == 0 )
245 | {
246 | valid = 1;
247 | }
248 | else
249 | {
250 | while (nicsuffixes[i])
251 | {
252 | if ( strcasecmp(nicsuffixes[i++],strchr(name,'-')+1) == 0 )
253 | {
254 | valid = 1;
255 | break;
256 | }
257 | }
258 | if ( ! valid )
259 | {
260 | i = 0;
261 | for ( i=0; i<num_sources; i++ )
262 | {
263 | if ( ! strcasecmp( upd_source_hdl[i]->name, strchr(name,'-')+1) )
264 | {
265 | valid = 1;
266 | break;
267 | }
268 | }
269 |
270 | /* while (sources[i])
271 | {
272 | if (strcasecmp(sources[i++],strchr(name,'-')+1) == 0 )
273 | {
274 | valid = 1;
275 | break;
276 | }
277 | } */
278 |
279 | if ( ! valid )
280 | {
281 | i = 0;
282 | while (countries[i])
283 | {
284 | if ( strcasecmp(countries[i++],strchr(name,'-')+1) == 0 )
285 | {
286 | valid = 1;
287 | break;
288 | }
289 | }
290 | }
291 | }
292 | }
293 | free(name);
294 | g_list_free(list);
295 |
296 | if (!valid)
297 | {
298 | /* the nicsuffix is not recognised */
299 | if (result->error_str == NULL)
300 | {
301 | result->error_str = strdup("***Error: Invalid nic-hdl suffix");
302 | }
303 | else
304 | {
305 | temp = (char *)malloc(strlen(result->error_str)
306 | + strlen("***Error: Invalid nic-hdl suffix") + 2);
307 | sprintf(temp, "%s\n%s", result->error_str,
308 | "***Error: Invalid nic-hdl suffix");
309 | free(result->error_str);
310 | result->error_str = temp;
311 | }
312 | /* and here we have to change the result code of "result" here ... */
313 | switch (result->result)
314 | {
315 | case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
316 | case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
317 | case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
318 | case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
319 | default: ;
320 | }
321 | }
322 | }
323 | }
324 |
325 |
326 | /* obtains a list of dates in the given
327 | list of attributes */
328 | GList * up_get_dates(GList * attribute_list)
329 | {
330 | GList * item;
331 | char * str, *temp;
332 | GList * list = NULL;
333 |
334 | for ( item = attribute_list; item != NULL ; item = g_list_next(item) )
335 | {
336 | /* is this a 'changed' attribute? */
337 | if ( strcmp(rpsl_attr_get_name((rpsl_attr_t *)(item->data)), "changed") == 0 )
338 | {
339 | str = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
340 |
341 |
342 | /* now, we have the 'changed' attribute's content in "normalized" form
343 | We are sure it contains a date. So, it must be the second (and last)
344 | word in the attrib. */
345 | assert(index(str,' ') != NULL);
346 | temp = (char *)malloc(strlen(str) - (index(str,' ') - str ));
347 | temp = strncpy(temp, index(str,' ') + 1, strlen(str) - (index(str,' ') - str ) - 1);
348 | temp[strlen(str) - (index(str,' ') - str ) - 1] = '\0'; /* NULL terminate it */
349 | list = g_list_append (list, temp);
350 | }
351 | }
352 |
353 | return list;
354 | }
355 |
356 |
357 |
358 |
359 | /* Does the 'changed' attribute we got have a date already?
360 | Returns 1 if it does, 0 if not. */
361 | int up_changed_has_date(char * value)
362 | {
363 | /* now, if there is still a white space, then we have a date in the string
364 | (it has to be something like "ripe-dbm@ripe.net 20001210") */
365 | if (index(value, ' ') != NULL)
366 | {
367 | return 1;
368 | }
369 | else
370 | {
371 | return 0;
372 | }
373 | }
374 |
375 |
376 |
377 |
378 | /* supplies the current date in YYYYMMDD format (for example 20011010) */
379 | char * UP_get_current_date()
380 | {
381 | /* We will use Glib's functions here */
382 |
383 | char * date;
384 | struct tm * time_struct;
385 |
386 | time_t * time_loc;
387 |
388 | time_loc = (time_t *)malloc(sizeof(time_t));
389 | time(time_loc);
390 |
391 | time_struct = localtime(time_loc);
392 |
393 |
394 | date = (char *)malloc(9);
395 | sprintf(date, "%04i%02i%02i",
396 | time_struct->tm_year + 1900,
397 | time_struct->tm_mon + 1,
398 | time_struct->tm_mday);
399 | return date;
400 | }
401 |
402 |
403 |
404 |
405 | /* int up_add_dates: adds dates to 'changed' attributes which
406 | are missing one.
407 | Returns 1 if no problems encountered
408 | Returns 0 if a problem encountered, and the error string is set */
409 | int up_add_dates(rpsl_object_t *external_syntax_obj, GList *attribute_list, char ** warning_str, char ** error_str)
410 | {
411 | GList * item;
412 | char * current_date;
413 | int count_no_date = 0;
414 | char * temp;
415 | rpsl_attr_t *changed;
416 | char *value;
417 | int pos;
418 |
419 | *warning_str = NULL;
420 | *error_str = NULL;
421 |
422 | /* get the current date in YYYYMMDD format (for example 20011010) */
423 | current_date = UP_get_current_date();
424 |
425 | for ( item = attribute_list; item != NULL ; item = g_list_next(item) )
426 | {
427 | /* is this a 'changed' attribute? */
428 | if (strcmp(rpsl_attr_get_name((rpsl_attr_t *)(item->data)), "changed") == 0)
429 | {
430 | /* if this attribute does not have a date in it, add it. Also add
431 | a warning message about this */
432 | value = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
433 | if ( !up_changed_has_date(value) )
434 | {
435 | count_no_date++;
436 | /* create a copy of this changed attribute and add the date to the value */
437 | changed = rpsl_attr_copy((rpsl_attr_t *)(item->data));
438 | temp = (char *)malloc(strlen(value) + strlen(current_date) + 2 );
439 | sprintf(temp, "%s %s", value, current_date);
440 | rpsl_attr_replace_value(changed, temp);
441 | free(temp);
442 | /* delete the original attribute from the object */
443 | pos = rpsl_attr_get_ofs(changed);
444 | rpsl_object_remove_attr(external_syntax_obj, pos, NULL);
445 | /* add the new changed attribute in the same position */
446 | rpsl_object_add_attr(external_syntax_obj, changed, pos, NULL);
447 | /* add a warning message */
448 | if ( *warning_str == NULL)
449 | {
450 | *warning_str = (char *)malloc(strlen("WARNING date '' added to 'changed' attribute") + 9 );
451 | sprintf(*warning_str, "WARNING date '%s' added to 'changed' attribute", current_date);
452 | }
453 | else
454 | {
455 | temp = (char *)malloc(strlen(*warning_str) + 1
456 | + strlen("WARNING date '' added to 'changed' attribute") + 9 );
457 | sprintf(temp, "%s\nWARNING date '%s' added to 'changed' attribute",
458 | *warning_str, current_date);
459 | free(*warning_str);
460 | *warning_str = temp;
461 | }
462 | }
463 | free(value);
464 | }
465 | }
466 |
467 | if (count_no_date > 1)
468 | {
469 | *error_str = strdup("***Error: More than one 'changed' attributes without dates");
470 | return 0;
471 | }
472 | else
473 | {
474 | return 1;
475 | }
476 | }
477 |
478 |
479 |
480 |
481 | /* Checks the order of dates in the given list.
482 | If they are in order, returns 1,
483 | if not, returns 0 */
484 | int up_check_date_order(GList * list)
485 | {
486 | GList * item;
487 | char * previous;
488 | char *value;
489 |
490 | /* if list is empty, return 1 immediately */
491 | if (list == NULL)
492 | {
493 | return 1;
494 | }
495 |
496 | /* initialize the 'previous' date */
497 | previous = strdup("00000000");
498 |
499 | for ( item = list; item != NULL ; item = g_list_next(item))
500 | {
501 | assert((item->data) != NULL);
502 | /* if the new date is smaller than the previous */
503 | value = (char *)(item->data);
504 | if ( strcmp(value, previous) < 0 )
505 | {
506 | free(previous);
507 | return 0;
508 | }
509 | free(previous);
510 | previous = strdup(value);
511 | }
512 |
513 | free(previous);
514 | /* Reached the end, without finding out-of-order date. Return 1, then */
515 | return 1;
516 | }
517 |
518 |
519 |
520 |
521 |
522 | /* up_check_date: checks the syntax of the date, given as the only
523 | argument (char *). The argument is checked if it is in YYYYMMDD
524 | format, and returns an error code accordingly */
525 | int up_check_date(const char * arg)
526 | {
527 | int date_int; /* integer representation of the date (arg) */
528 | char * current_date;
529 | int year, month, day; /* integers for the components of the date */
530 |
531 | errno = 0;
532 | date_int = atoi(arg);
533 |
534 | if (errno != 0)
535 | { /* there was an error in the conversion, syntax error */
536 | return UP_DATE_SYNERR;
537 | }
538 |
539 | /* wrong format */
540 | if (date_int <= 10000000 )
541 | { /* the date is not in YYYYMMDD format */
542 | return UP_DATE_WRONGFORMAT;
543 | }
544 |
545 | /* check if it is too small */
546 | if (date_int <= 19840000 )
547 | { /* the date is older than the DB itself! */
548 | return UP_DATE_TOOSMALL;
549 | }
550 |
551 | /* check if it is too big */
552 | if (date_int >= 100000000 )
553 | {/* too big: syntax error */
554 | return UP_DATE_SYNERR;
555 | }
556 |
557 | /* and now check year, month and day components */
558 | year = date_int / 10000;
559 | month = (date_int - (year * 10000) ) / 100;
560 | day = (date_int % 100);
561 |
562 | /* check year */
563 | if (year < 1984 )
564 | {
565 | return UP_DATE_TOOSMALL;
566 | }
567 |
568 | /* check month */
569 | if (month < 1 || month > 12)
570 | {
571 | return UP_DATE_INVMONTH;
572 | }
573 |
574 | /* check day */
575 | if (day < 1 || day > 31)
576 | {
577 | return UP_DATE_INVDAY;
578 | }
579 |
580 | switch ( month )
581 | {
582 | case 1: case 3: case 5: case 7:
583 | case 8: case 10: case 12:
584 | if (day > 31)
585 | {
586 | return UP_DATE_INVDAY;
587 | };
588 | break;
589 | case 2:
590 | if ( (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) && (day > 29 ))
591 | { /* leap year */
592 | return UP_DATE_INVDAY;
593 | }
594 | else if( (!(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) && (day > 28) )
595 | { /* non-leap year */
596 | return UP_DATE_INVDAY;
597 | };
598 | break;
599 | case 4: case 6: case 9: case 11:
600 | if (day > 30)
601 | {
602 | return UP_DATE_INVDAY;
603 | };
604 | break;
605 | default: return UP_DATE_INVMONTH;
606 | }
607 |
608 | /* check if the arg is in the future or not */
609 | current_date = UP_get_current_date();
610 | if (strcmp(current_date, arg) < 0 )
611 | { /* arg is in the future */
612 | free(current_date);
613 | return UP_DATE_FUTURE;
614 | }
615 | free(current_date);
616 |
617 | return UP_DATE_OK;
618 | }
619 |
620 |
621 |
622 | /* Checks the syntax of the dates in the list */
623 | date_syntax_struct * up_check_dates_syntax(GList * list)
624 | {
625 | GList * item;
626 | date_syntax_struct * result;
627 | int res;
628 |
629 | /* initialize the result struct */
630 | result = (date_syntax_struct *)malloc(sizeof(date_syntax_struct));
631 | result->result = UP_DATE_OK;
632 | result->error_str = NULL;
633 |
634 | /* if list is empty, return immediately */
635 | if (list == NULL)
636 | {
637 | return result;
638 | }
639 |
640 | /* loop through the members of the list, check each of them */
641 | for ( item = list; item != NULL ; item = g_list_next(item))
642 | {
643 | assert((item->data) != NULL);
644 |
645 | /* check the date */
646 | res = up_check_date((char *)(item->data));
647 | switch (res)
648 | {
649 | case UP_DATE_OK: break;
650 |
651 | case UP_DATE_FUTURE:
652 | case UP_DATE_TOOSMALL:
653 | case UP_DATE_INVDAY:
654 | case UP_DATE_INVMONTH:
655 | case UP_DATE_WRONGFORMAT:
656 |
657 | if (result->error_str == NULL)
658 | {
659 | result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[res])
660 | + strlen(": ") + strlen((char *)(item->data)) + 1);
661 | sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[res],
662 | (char *)(item->data));
663 | }
664 | else
665 | {
666 | result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1
667 | + strlen("***Error: ") + strlen(up_date_errmsgs[res])
668 | + strlen(": ") + strlen((char *)(item->data)) + 1);
669 | sprintf(result->error_str, "%s\n***Error: %s: %s",
670 | result->error_str, up_date_errmsgs[res], (char *)(item->data));
671 | }
672 | result->result = UP_DATE_NOK; /* Not OK */
673 |
674 | break;
675 |
676 |
677 | case UP_DATE_SYNERR: /* syntax error in the date */
678 |
679 | default:
680 | if (result->error_str == NULL)
681 | {
682 | result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR])
683 | + strlen(": ") + strlen((char *)(item->data)) + 1);
684 | sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[UP_DATE_SYNERR],
685 | (char *)(item->data));
686 | }
687 | else
688 | {
689 | result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1
690 | + strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR])
691 | + strlen(": ") + strlen((char *)(item->data)) + 1);
692 | sprintf(result->error_str, "%s\n***Error: %s: %s",
693 | result->error_str, up_date_errmsgs[UP_DATE_SYNERR], (char *)(item->data));
694 | }
695 | result->result = UP_DATE_NOK; /* Not OK */
696 | break;
697 | }
698 | }
699 |
700 | return result;
701 | }
702 |
703 |
704 |
705 | /* void up_check_changed_attr
706 | checks the order of dates in the 'changed' attributes */
707 | void up_check_changed_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
708 | {
709 | GList * date_list;
710 | int res;
711 | char ** warning, **error;
712 | char * temp;
713 | date_syntax_struct * date_check_res;
714 | GList *changed_list;
715 |
716 | warning = (char **)malloc(sizeof(char **));
717 | error = (char **)malloc(sizeof(char **));
718 | changed_list = rpsl_object_get_attr(external_syntax_obj, "changed");
719 |
720 | /* Now, add dates to the "changed" attributes */
721 | res = up_add_dates(external_syntax_obj, changed_list, warning, error);
722 | if (!res)
723 | {
724 | /* so, add the error string to result's error string */
725 | if (result->error_str == NULL)
726 | {
727 | result->error_str = strdup(*error);
728 | }
729 | else
730 | {
731 | temp = (char *)malloc(strlen(result->error_str) + strlen(*error) + 2);
732 | sprintf(temp, "%s\n%s", result->error_str, *error);
733 | free(result->error_str);
734 | result->error_str = temp;
735 | }
736 | }
737 |
738 | /* and get the list of dates, we must check their order */
739 | /* we may have added a date to one of the changed attrs so get the list again */
740 | rpsl_attr_delete_list(changed_list);
741 | changed_list = rpsl_object_get_attr(external_syntax_obj, "changed");
742 | date_list = up_get_dates(changed_list);
743 | /* and check the order */
744 | res = up_check_date_order(date_list);
745 | if (!res)
746 | {
747 | /* so, add the error string to result's error string */
748 | if (result->error_str == NULL)
749 | {
750 | result->error_str = strdup("***Error: The dates in the 'changed' attributes should be in order");
751 | }
752 | else
753 | {
754 | temp = (char *)malloc(strlen(result->error_str)
755 | + strlen("***Error: The dates in the 'changed' attributes should be in order") + 2);
756 | sprintf(temp, "%s\n%s", result->error_str,
757 | "***Error: The dates in the 'changed' attributes should be in order");
758 | free(result->error_str);
759 | result->error_str = temp;
760 | }
761 | /* and here we have to change the result code of "result" here ... */
762 | switch (result->result)
763 | {
764 | case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
765 | case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
766 | case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
767 | case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
768 | default: ;
769 | }
770 | }
771 |
772 | /* check the syntax of dates */
773 | date_check_res = up_check_dates_syntax(date_list);
774 | if (date_check_res->result != UP_DATE_OK)
775 | {
776 | /* so, add the error string to result's error string */
777 | if (result->error_str == NULL)
778 | {
779 | result->error_str = strdup(date_check_res->error_str);
780 | }
781 | else
782 | {
783 | temp = (char *)malloc(strlen(result->error_str)
784 | + strlen(date_check_res->error_str) + 2);
785 | sprintf(temp, "%s\n%s", result->error_str,
786 | date_check_res->error_str);
787 | free(result->error_str);
788 | result->error_str = temp;
789 | }
790 | /* and here we have to change the result code of "result" here ... */
791 | switch (result->result)
792 | {
793 | case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
794 | case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
795 | case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
796 | case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
797 | default: ;
798 | }
799 | }
800 | }
801 |
802 |
803 | /* performs a simple check on a inetnum attribute. Assumes that
804 | the RPSL parser has already checked it. Tries to see if the attr
805 | is a range or not */
806 | int up_check_an_inetnum_attr(const char * arg){
807 |
808 |
809 | char * str;
810 | char * pos;
811 |
812 | str = strdup(arg);
813 |
814 | while((pos = index(str, '\n')) != NULL){
815 | *pos = ' ';
816 | }
817 |
818 | /* strip off the comment */
819 | if((pos = index(str, '#')) != NULL){
820 | *pos = '\0';
821 | }
822 |
823 |
824 | /* Most of the syntax check is done by RPSL parser. We only need to check
825 | that the argument is a _range_ of IPv4 addresses. So it suffices to
826 | check the existence of '-' in the arg */
827 | if(index(str, '-') != NULL){
828 |
829 | free(str);
830 | return 1;
831 |
832 | }else{
833 |
834 | free(str);
835 | return 0;
836 |
837 | }
838 | }
839 |
840 |
841 | /* void up_add_keycert_attrs
842 | adds the generated attrs of key-cert objects */
843 | void up_add_keycert_attrs(rpsl_object_t *generated_obj)
844 | {
845 | const char *type;
846 | char *attr_str;
847 | rpsl_attr_t *method_attr;
848 | rpsl_attr_t *owner_attr;
849 | rpsl_attr_t *fingerpr_attr;
850 |
851 | if (tracing)
852 | {
853 | printf("TRACING: UP_add_keycert_attrs: is running\n");
854 | }
855 |
856 | /* if this is a key-cert object */
857 | type = rpsl_object_get_class(generated_obj);
858 | if ( strcmp(type, "key-cert") == 0 )
859 | {
860 | method_attr = rpsl_attr_init("method: PGP", type);
861 | if ( method_attr )
862 | {
863 | rpsl_object_add_attr(generated_obj, method_attr, 1, NULL);
864 | }
865 |
866 | attr_str = (char *)malloc( sizeof("owner: ") + strlen(keyowner) +1 );
867 | strcpy(attr_str, "owner: ");
868 | strcat(attr_str, keyowner);
869 | if (tracing)
870 | {
871 | printf("TRACING: UP_add_keycert_attrs: owner attr_str [%s]\n", attr_str);
872 | }
873 | owner_attr = rpsl_attr_init(attr_str, "key-cert");
874 | if ( owner_attr )
875 | {
876 | rpsl_object_add_attr(generated_obj, owner_attr, 2, NULL);
877 | }
878 | free(attr_str);
879 |
880 | attr_str = (char *)malloc( sizeof("fingerpr: ") + strlen(fingerprint) +1 );
881 | strcpy(attr_str, "fingerpr: ");
882 | strcat(attr_str, fingerprint);
883 | if (tracing)
884 | {
885 | printf("TRACING: UP_add_keycert_attrs: fingerprint attr_str [%s]\n", attr_str);
886 | }
887 | fingerpr_attr = rpsl_attr_init(attr_str, "key-cert");
888 | if ( fingerpr_attr )
889 | {
890 | rpsl_object_add_attr(generated_obj, fingerpr_attr, 3, NULL);
891 | }
892 | free(attr_str);
893 | }
894 | }
895 |
896 |
897 | /* up_reconstruct_object: Reconstructs the object's text representation
898 | using the parsed object */
899 | void up_reconstruct_object(rpsl_object_t *external_syntax_obj, external_syntax_struct *result)
900 | {
901 | char * recons_obj = NULL;
902 |
903 | recons_obj = rpsl_object_get_text(external_syntax_obj,RPSL_STD_COLUMN);
904 |
905 | result->new_obj = recons_obj;
906 | }
907 |
908 |
909 |
910 | /* UP_check_external_syntax: Checks the syntax of attributes which are not checked
911 | by the api parser module. */
912 | external_syntax_struct * UP_check_external_syntax(rpsl_object_t *external_syntax_obj)
913 | {
914 | external_syntax_struct *result;
915 |
916 | if (tracing)
917 | {
918 | printf("TRACING: UP_check_external_syntax running\n");
919 | }
920 |
921 | result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
922 |
923 | /* initialize the struct */
924 | result->result = 0;
925 | result->error_str = strdup("");
926 | result->warning_str = strdup("");
927 |
928 | up_check_source_attr(external_syntax_obj, result);
929 |
930 | up_check_country_attr(external_syntax_obj, result);
931 |
932 | up_check_nicsuffixes(external_syntax_obj, result);
933 |
934 | up_check_changed_attr(external_syntax_obj, result);
935 |
936 | up_reconstruct_object(external_syntax_obj, result);
937 |
938 | if (tracing)
939 | {
940 | printf("TRACING: UP_check_external_syntax: the reconstructed object is=[%s]\n", result->new_obj);
941 | printf("TRACING: UP_check_external_syntax: ... and the result code is=[%i]\n", result->result);
942 | }
943 |
944 | return result;
945 | }
946 |
947 |
948 |
949 | /* generates the "generated" attributes of a key-cert object. Returns the
950 | new object string*/
951 | char *UP_generate_kc_attrs(rpsl_object_t *generated_obj)
952 | {
953 | external_syntax_struct *result;
954 | char *obj_str;
955 |
956 | if (tracing)
957 | {
958 | printf("TRACING: UP_generate_kc_attrs: is running\n");
959 | }
960 |
961 | result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
962 |
963 | /* initialize the struct */
964 | result->result = 0;
965 | result->error_str = strdup("");
966 | result->warning_str = strdup("");
967 |
968 | up_check_changed_attr(generated_obj, result);
969 | up_add_keycert_attrs(generated_obj);
970 |
971 | up_reconstruct_object(generated_obj, result);
972 |
973 | if (tracing)
974 | {
975 | printf("TRACING: UP_generate_kc_attrs: the reconstructed object is=[%s]\n", result->new_obj);
976 | printf("TRACING: UP_generate_kc_attrs: ... and the result code is=[%i]\n", result->result);
977 | }
978 |
979 | obj_str = strdup(result->new_obj);
980 | free(result);
981 | return obj_str;
982 | }
983 |
984 |
985 |
986 | /* char * up_assign_i6_status: Determines the status attribute of
987 | an inet6num object. It takes the inet6num attribute of the
988 | object as its only argument. If prefix length is less than
989 | 4, then returns NULL */
990 | char * up_assign_i6_status(const char * inet6num_attr)
991 | {
992 |
993 | char ** split_str;
994 | int prefix_length;
995 | int result;
996 |
997 | /* we need the prefix length here.*/
998 | split_str = g_strsplit(inet6num_attr, "/", 0);
999 | if(split_str[1] != NULL){
1000 |
1001 | result = sscanf(split_str[1], "%i", &prefix_length);
1002 | if(result != 0 && result != EOF){
1003 |
1004 | if(prefix_length >= 0 && prefix_length <= 3){
1005 |
1006 | g_strfreev(split_str);
1007 | return NULL;
1008 |
1009 | }else if(prefix_length >= 4 && prefix_length <= 15){
1010 |
1011 | g_strfreev(split_str);
1012 | return strdup("TLA");
1013 |
1014 | }else if(prefix_length >= 16 && prefix_length <= 35){
1015 |
1016 | g_strfreev(split_str);
1017 | return strdup("SUBTLA");
1018 |
1019 | }else if(prefix_length >= 36 && prefix_length <= 48){
1020 |
1021 | g_strfreev(split_str);
1022 | return strdup("NLA");
1023 |
1024 | }else if(prefix_length >= 48 && prefix_length <= 64){
1025 |
1026 | g_strfreev(split_str);
1027 | return strdup("SLA");
1028 |
1029 | }else{
1030 |
1031 | /* "default" status */
1032 | g_strfreev(split_str);
1033 | return strdup("SLA");
1034 |
1035 | }
1036 |
1037 | }else{
1038 |
1039 | /* return "default" status */
1040 | g_strfreev(split_str);
1041 | return strdup("SLA");
1042 |
1043 | }
1044 | }else{
1045 |
1046 | /* return "default" status */
1047 | g_strfreev(split_str);
1048 | return strdup("SLA");
1049 |
1050 | }
1051 |
1052 | }
1053 |
1054 |
1055 |
1056 | /* GSList * up_add_inet6num_attrs
1057 | adds the generated attrs of inet6num objects */
1058 | /*GSList * up_add_inet6num_attrs(Object * obj, char * obj_text, GSList * attribute_list,
1059 | external_syntax_struct * result)*/
1060 | void up_add_inet6num_attrs(rpsl_object_t *generated_obj)
1061 | {
1062 |
1063 | int attribute_no;
1064 | char *status_value;
1065 | rpsl_attr_t * status_attr;
1066 | char *inet6num_attr_str, *status_attr_str;
1067 | const char *type;
1068 | GList *attributes_changed;
1069 |
1070 |
1071 |
1072 | /* if this is an inet6num object */
1073 | type = rpsl_object_get_class(generated_obj);
1074 | if( ! strcmp(type, "inet6num") )
1075 | {
1076 | inet6num_attr_str = get_search_key(generated_obj, "inet6num");
1077 | status_value = up_assign_i6_status(inet6num_attr_str);
1078 | status_attr_str = (char *)UT_malloc(strlen("status: ") + strlen(status_value) + 1);
1079 | strcpy(status_attr_str, "status: ");
1080 | strcat(status_attr_str, status_value);
1081 | status_attr = rpsl_attr_init(status_attr_str, type);
1082 | free(status_attr_str);
1083 | if ( status_attr )
1084 | {
1085 | /* we will put the status attribute before the first 'changed' attribute */
1086 | attribute_no = 1; /* a default position (the second attribute) in case we cannot find
1087 | a 'changed' attribute */
1088 | attributes_changed = rpsl_object_get_attr(generated_obj, "changed");
1089 | if ( attributes_changed != NULL )
1090 | {
1091 | attribute_no = ((rpsl_attr_t *)(attributes_changed->data))->num;
1092 | }
1093 | rpsl_object_add_attr(generated_obj, status_attr, attribute_no, NULL);
1094 | }
1095 | }
1096 | }
1097 |