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