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