modules/up/src/rpslcheck/separateobjects.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- start_tracing
- start_debugging
- init_and_set_options
- send_object_db
- get_type
- get_search_key
- send_and_get
- count_objects
- take_object
- get_as_block
- get_less_specific_domain
- get_less_specific_set
- get_less_specific
- get_mntners
- get_auths
- get_mnt_lowers
- get_override
- check_override
- add_to_auth_vector
- get_auth_vector
- check_auth
- get_old_version
- process_object
- main
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <glib.h>
5 #include <iostream.h>
6
7 #include <netdb.h>
8 #include <sys/types.h>
9 #include <netinet/in.h>
10 #include <sys/socket.h>
11 #include <errno.h>
12
13 #include <config.h>
14 #include <istream.h>
15 #include "rpsl/object.hh"
16 #include "util/rusage.hh"
17 #include "util/debug.hh"
18 #include "util/trace.hh"
19 #include "util/Argv.hh"
20 #include "util/version.hh"
21 #ifdef IRR_NEEDED
22 #include "irr/irr.hh"
23 #include "irr/rawhoisc.hh"
24 #endif // IRR_NEEDED
25 #include "rpsl/schema.hh"
26
27 Rusage ru;
28 bool opt_stats = false;
29 bool opt_rusage = false;
30 char *opt_prompt = "RtConfig> ";
31 bool opt_echo = false;
32 #ifdef DEBUG
33 bool opt_debug_rpsl = false;
34 #endif // DEBUG
35
36 int start_tracing(char *dst, char *key, char *nextArg) {
/* [<][>][^][v][top][bottom][index][help] */
37 if (nextArg) {
38 trace.enable(nextArg);
39 return 1; // return 1 to signify nextArg is used by us
40 }
41 return 0;
42 }
43
44 int start_debugging(char *dst, char *key, char *nextArg) {
/* [<][>][^][v][top][bottom][index][help] */
45 if (nextArg) {
46 Debug(dbg.enable(atoi(nextArg)));
47 return 1; // return 1 to signify nextArg is used by us
48 }
49 return 0;
50 }
51
52 void init_and_set_options (int argc, char **argv, char **envp) {
/* [<][>][^][v][top][bottom][index][help] */
53 ArgvInfo argTable[] = {
54 // RAToolSet common arguments
55 // key, type, src, dst, help
56 {"-T", ARGV_FUNC, (char *) &start_tracing, (char *) NULL,
57 "Start tracing the next argument"},
58 {"-D", ARGV_FUNC, (char *) &start_debugging, (char *) NULL,
59 "Start debugging the next argument"},
60 {"-version", ARGV_FUNC, (char *) &version, (char *) NULL,
61 "Show version"},
62 #ifdef IRR_NEEDED
63 {"-h", ARGV_FUNC, (char *) &IRR::ArgvHost, (char *) NULL,
64 "Host name of the RAWhoisd server"},
65 {"-p", ARGV_FUNC, (char *) &IRR::ArgvPort, (char *) NULL,
66 "Port number of the RAWhoisd server"},
67 {"-s", ARGV_FUNC, (char *) &IRR::ArgvSources, (char *) NULL,
68 "Order of databases"},
69 {"-ignore_errors", ARGV_FUNC, (char *)&IRR::IgnoreErrors, (char *)NULL,
70 "Ignore IRR error and warning messages"},
71 {"-report_errors", ARGV_FUNC, (char *)&IRR::ReportErrors, (char *)NULL,
72 "Print IRR error and warning messages"},
73 #endif // IRR_NEEDED
74 {"-rusage", ARGV_BOOL, (char *) NULL, (char *) &opt_rusage,
75 "On termination print resource usage"},
76 {"-stats", ARGV_BOOL, (char *) NULL, (char *) &opt_stats,
77 "On termination print class statistics"},
78 {"-prompt", ARGV_STRING, (char *) NULL, (char *) &opt_prompt,
79 "Prompt"},
80
81 {"-echo", ARGV_BOOL, (char *) NULL, (char *) &opt_echo,
82 "Echo each object parsed"},
83 #ifdef DEBUG
84 {"-debug_rpsl", ARGV_BOOL, (char *) NULL, (char *) &opt_debug_rpsl,
85 "Turn on bison debugging. Intended for developers."},
86 #endif // DEBUG
87 {(char *) NULL, ARGV_END, (char *) NULL, (char *) NULL,
88 (char *) NULL}
89 };
90
91 #ifdef IRR_NEEDED
92 IRR::handleEnvironmentVariables(envp);
93 #endif // IRR_NEEDED
94
95 if (ParseArgv(&argc, argv, argTable, ARGV_NO_LEFTOVERS) != ARGV_OK) {
96 cerr << endl;
97 exit(1);
98 }
99
100 #ifdef IRR_NEEDED
101 irr = IRR::newClient();
102 #endif // IRR_NEEDED
103
104 // have a prompt only if the input is coming from a tty
105 if (!isatty(fileno(stdin)) || !isatty(fileno(stdout)))
106 opt_prompt = NULL;
107 }
108
109 #define MAXDATASIZE 100 /* max number of bytes we can get at once */
110 #define PORT 11111
111
112 #define UP_AUTH_OK 0 /* Authorisation succeeded */
113 #define ERROR_UP_MOR 1 /* Got more than one objects from the db, error */
114 #define ERROR_UP_NSO 2 /* so such object */
115 #define ERROR_UP_AUF 3 /* auth failed */
116 #define ERROR_UP_NIY 4 /* not implemented yet */
117 #define ERROR_UP_ABN 5 /* As-block does not exist */
118 #define ERROR_UP_HOF 6 /* Hierarchical authorisation failed */
119 #define ERROR_UP_OVF 7 /* override failed */
120 #define ERROR_UP_OVS 8 /* override syntax error */
121 #define ERROR_UP_INT 9 /* internal error */
122
123 #define OVR_OK 0 /* override succeded */
124
125
126 #define AU_MAIL_FROM 1
127 #define AU_CRYPT_PW 2
128 #define AU_PGP 3
129 #define AU_NONE 4
130
131 struct credentials{
132 char * password;
133 char * from;
134 char * pgp_struct;
135 };
136
137
138 typedef struct _auth_struct{
139 int type;
140 char * auth;
141 char * mntner_name;
142 int index;
143 char * pgp_struct;
144 } auth_struct;
145
146 int error = 0; // a global variable to store the errors
147 char * error_msg = NULL; // a global variable to store the error messages
148
149
150 /* sends the object to the database. char * operation is either 'ADD' or 'DEL' */
151 void send_object_db(char * arg, char * operation){
/* [<][>][^][v][top][bottom][index][help] */
152
153 int sockfd, numbytes;
154 char buf[MAXDATASIZE];
155 struct hostent *he;
156 struct sockaddr_in their_addr; /* connector's address information */
157
158 if ((he=gethostbyname("rowan")) == NULL) { /* get the host info */
159 perror("gethostbyname");
160 exit(1);
161 }
162
163 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
164 perror("socket");
165 exit(1);
166 }
167
168 their_addr.sin_family = AF_INET; /* host byte order */
169 their_addr.sin_port = htons(PORT); /* short, network byte order */
170 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
171 bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
172
173
174 if (connect(sockfd, (struct sockaddr *)&their_addr,
175 sizeof(struct sockaddr)) == -1) {
176 perror("connect");
177 exit(1);
178 }
179 if (send(sockfd, operation , strlen(operation), 0) == -1)
180 perror("send");
181 if (send(sockfd, "\n\n" , strlen("\n\n"), 0) == -1)
182 perror("send");
183 if (send(sockfd, arg , strlen(arg), 0) == -1)
184 perror("send");
185 if (send(sockfd, "\n",1,0) == -1)
186 perror("send");
187
188
189 while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
190 buf[numbytes] = '\0';
191 printf("%s",buf);
192 /*perror("recv");
193 exit(1);*/
194 }
195
196 /*buf[numbytes] = '\0';
197 printf("Received: %s",buf);*/
198
199 close(sockfd);
200 }
201
202
203
204
205
206
207 /* takes a pre-parsed object, and returns its type */
208 char * get_type(Object *arg){
/* [<][>][^][v][top][bottom][index][help] */
209
210 char * be_returned = NULL;
211 if(arg == NULL) return NULL;
212 be_returned = strdup(arg->type->getName());
213 return g_strstrip(be_returned);
214 }
215
216
217
218
219
220
221 /* takes an object (pre-parsed) and returns its first attrib if it is not
222 a person, and returns the nic-hdl if it is a person object */
223 char * get_search_key(Object *arg, char * type, char * text){
/* [<][>][^][v][top][bottom][index][help] */
224
225
226 Attr *attr;
227 char *primary_key = NULL, *value = NULL;
228
229 if(arg == NULL) return NULL;
230
231 for(attr = arg->attrs.head(); attr; attr = arg->attrs.next(attr)){
232 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
233 strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
234 attr->len - strlen(attr->type->name()) -2 );
235 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
236 //cout << "value: #" << value << "#" << endl;
237 if(strcmp(attr->type->name(),type) == 0 &&
238 strcmp(type,"person") != 0){
239 primary_key = strdup(value);
240 }
241 if(strcmp(attr->type->name(),"nic-hdl") == 0 &&
242 strcmp(type,"person") == 0){
243 primary_key = strdup(value);
244 }
245 }
246
247 return g_strstrip(primary_key);
248 }
249
250
251
252
253 /* sends char * arg to the specified host's specified port, and
254 returns the reply as a string */
255 char * send_and_get(char * host, int port, char * arg){
/* [<][>][^][v][top][bottom][index][help] */
256
257 int sockfd, numbytes;
258 char * result = NULL;
259 char buf[MAXDATASIZE];
260 struct hostent *he;
261 struct sockaddr_in their_addr; /* connector's address information */
262
263 if ((he=gethostbyname(host)) == NULL) { /* get the host info */
264 perror("gethostbyname");
265 exit(1);
266 }
267
268 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
269 perror("socket");
270 exit(1);
271 }
272
273 their_addr.sin_family = AF_INET; /* host byte order */
274 their_addr.sin_port = htons(port); /* short, network byte order */
275 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
276 bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
277
278
279 if (connect(sockfd, (struct sockaddr *)&their_addr,
280 sizeof(struct sockaddr)) == -1) {
281 perror("connect");
282 exit(1);
283 }
284 if (send(sockfd, arg , strlen(arg), 0) == -1)
285 perror("send");
286 if (send(sockfd, "\n",1,0) == -1)
287 perror("send");
288
289
290 while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
291 buf[numbytes] = '\0';
292 if(result == NULL){
293 result = strdup(buf);
294 }else{
295 result = (char *)realloc(result, strlen(result) + strlen(buf));
296 result = strcat(result, buf);
297 }
298 }
299
300 close(sockfd);
301 return result;
302
303
304 }
305
306 /* counts the number of objects in a string */
307 int count_objects(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
308 int count = 0;
309 char *pos = NULL;
310 char *temp = strdup(arg);
311
312 if(isalpha(arg[0])){
313 count++;
314 }else if(arg[0] == '\n' && isalpha(arg[1])){
315 count++;
316 }
317 while(pos = strstr(temp,"\n\n")){
318 pos[0] = 'a'; // something non-EOL so that it won't be caught in the next loop
319 if(isalpha(pos[2])){
320 count++;
321 }
322 }
323 cout << "DEBUG: count_objects returning " << count << endl;
324 return count;
325 }
326
327
328
329
330 /* */
331 char * take_object(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
332 char * returned;
333 char * object = NULL, * pos = NULL;
334 char * temp = strdup(arg);
335
336 if(isalpha(temp[0])){
337 if(strstr(temp,"\n\n") == NULL){
338 return temp;
339 }else{
340 pos = strstr(temp,"\n\n");
341 pos[0] = '\0';
342 return temp;
343 }
344 }else if(temp[0] == '\n' && isalpha(temp[1])){
345 if(strstr(temp,"\n\n") == NULL){
346 return (char *)temp[1];
347 }else{
348 pos = strstr(temp,"\n\n");
349 pos[0] = '\0';
350 return (char *)temp[1];
351 }
352 }else{
353 temp = strstr(temp,"\n\n");
354 temp = temp + 2;
355 if(strstr(temp,"\n\n") == NULL){
356 return temp;
357 }else{
358 pos = strstr(temp,"\n\n");
359 pos[0] = '\0';
360 return temp;
361 }
362 }
363 }
364
365
366
367
368
369 /* Takes an autnum_object, and returns the as-block containing this aut-num */
370 char * get_as_block(char *autnum_object){
/* [<][>][^][v][top][bottom][index][help] */
371 bool code;
372 char * search_key = NULL, * query_string = NULL;
373 char * result = NULL;
374 Object * o = new Object();
375
376 code = o->scan(autnum_object, strlen(autnum_object));
377 search_key = get_search_key(o,"aut-num",autnum_object);
378
379 query_string = (char *)malloc(strlen("-Tas-block -r ")+strlen(search_key)+1);
380 sprintf(query_string, "-Tas-block -r %s",search_key);
381 result = send_and_get("reimp", 43, query_string);
382 if(count_objects(result) == 0){
383 cout << "No such as-block" << endl;
384 return NULL;
385 }else if(count_objects(result) > 1){
386 cout << "More than one as-block returned" << endl;
387 return NULL;
388 }else{ // count_objects(result) == 1
389 return take_object(result);
390 }
391
392 }
393
394
395
396
397
398 /* Takes a domain_object, and returns the less specific domain of it */
399 char * get_less_specific_domain(char *domain_object){
/* [<][>][^][v][top][bottom][index][help] */
400 bool code;
401 char * search_key = NULL, * query_string = NULL;
402 char * result = NULL, * domain = NULL;
403 Object * o = new Object();
404 int i,j, length;
405 char * temp = NULL;
406 char ** splitted;
407
408 code = o->scan(domain_object, strlen(domain_object));
409 domain = get_search_key(o,"domain",domain_object);
410
411 /* split the domain from its dots ('50' is the max # of pieces, this number is just arbitrary) */
412 splitted = g_strsplit((char *)strdup(domain), ".", 50);
413
414 for(i=1; splitted[i] != NULL; i++){
415 /* in the following for loop, we will construct the 'less spec' domains
416 to be looked up in the DB */
417 for(j=i; splitted[j] !=NULL; j++){
418 length = 0;
419 if(temp!=NULL){
420 length = strlen(temp);
421 }
422 temp = (char *)realloc(temp, length + strlen(splitted[j]) + 2);
423 if(j==i){
424 temp = (char *)strdup(splitted[j]);
425 }else{
426 sprintf(temp, "%s.%s", temp, splitted[j]);
427 }
428 }
429 query_string = (char *)malloc(strlen("-Tdomain -r -R ")+strlen(temp)+1);
430 sprintf(query_string, "-Tdomain -r -R %s", temp);
431 result = send_and_get("reimp", 43, query_string);
432 if(count_objects(result) == 0){
433 }else if(count_objects(result) > 1){
434 cout << "DEBUG: get_less_specific_domain: More than one domains returned" << endl;
435 return NULL; /* error condition */
436 }else{ /* count_objects(result) == 1 */
437 return take_object(result);
438 }
439
440 }
441 /* release the memory allocated to **splitted */
442 for(i=0; splitted[i] != NULL; i++){
443 free(splitted[i]);
444 }
445 /* so, we couldn't find any 'less specific' domain */
446 return NULL;
447 }
448
449
450
451
452
453 /* Takes a hierarchical set_object, and returns the less specific set or auth-num of it
454 by striping down the object's name ( eg, for as35:rs-trial:rs-myset,
455 as35:rs-trial is tried ) */
456 char * get_less_specific_set(char *set_object, char *type){
/* [<][>][^][v][top][bottom][index][help] */
457 bool code;
458 char * search_key = NULL, * query_string = NULL;
459 char * result = NULL;
460 Object * o = new Object();
461 int i;
462
463 code = o->scan(set_object, strlen(set_object));
464 search_key = get_search_key(o, type, set_object);
465 delete(o);
466
467 for(i = strlen(search_key) -1; i > -1; i--){
468 if(search_key[i] == ':'){
469 search_key[i] = '\0'; /* truncate the string */
470 break;
471 }
472 if(i == 0){/* if we've reached the beginning of the string
473 (this means there wasn't any ';' in the string) */
474 free(search_key);
475 search_key = NULL;
476 }
477 }
478 if( search_key == NULL || strlen(search_key) == 0){/* this mustn't happen in fact, since
479 we make sure that the name of the
480 set_object contains a ':' in a proper place */
481 return NULL;
482 }
483
484
485 query_string = (char *)malloc(strlen("-Taut-num,as-set,rtr-set,peering-set,filter-set -r ")+strlen(search_key)+1);
486 sprintf(query_string, "-Taut-num,as-set,rtr-set,peering-set,filter-set -r %s", search_key);
487 result = send_and_get("reimp", 43, query_string);
488 if(count_objects(result) == 0){
489 cout << "No such object" << endl;
490 return NULL;
491 }else if(count_objects(result) > 1){
492 cout << "More than one objects returned" << endl;
493 return NULL;
494 }else{ // count_objects(result) == 1
495 return take_object(result);
496 }
497
498 }
499
500
501
502
503
504
505
506 /* Takes an inetnum or inet6num object and returnes one less specific of it */
507 char * get_less_specific(char *inetnum_object, char *type){
/* [<][>][^][v][top][bottom][index][help] */
508 bool code;
509 char * search_key = NULL, * query_string = NULL;
510 char * result = NULL;
511 Object * o = new Object();
512
513 code = o->scan(inetnum_object, strlen(inetnum_object));
514 search_key = get_search_key(o, type, inetnum_object);
515
516 query_string = (char *)malloc(strlen("-Tinet6num -r -l")+strlen(search_key)+1);
517 sprintf(query_string, "-T%s -r -l %s",type, search_key);
518 result = send_and_get("reimp", 43, query_string);
519 if(count_objects(result) == 0){
520 cout << "No such " << type << endl;
521 return NULL;
522 }else if(count_objects(result) > 1){
523 cout << "More than one " << type << " returned" << endl;
524 return NULL;
525 }else{ // count_objects(result) == 1
526 return take_object(result);
527 }
528
529 }
530
531
532
533
534 /* Gets an object as a string and returns its 'mnt-by' attributes as a
535 GSList (linked list) */
536
537 GSList *get_mntners(char * object){
/* [<][>][^][v][top][bottom][index][help] */
538 bool code;
539 Object * o;
540 Attr *attr;
541 char *value = NULL;
542 GSList *list_of_mntners = NULL;
543
544
545 cout << "DEBUG: get_mntners is running" << endl;
546 o = new Object;
547 code = o->scan(object,strlen(object));
548
549 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
550 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
551 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
552 attr->len - strlen(attr->type->name()) -2 );
553 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
554 //cout << "value: #" << value << "#" << endl;
555 if(strcmp(attr->type->name(),"mnt-by") == 0){
556 cout << "DEBUG: get_mntners: adding " << g_strstrip(value) << endl;
557 list_of_mntners = g_slist_append(list_of_mntners, strdup(g_strstrip(value)));
558 }
559 }
560
561
562 return list_of_mntners;
563 }
564
565
566
567
568
569 /* Gets a (maintainer) object as a string and returns its 'auth' attributes
570 as a GSList (linked list) */
571
572 GSList *get_auths(char * object){
/* [<][>][^][v][top][bottom][index][help] */
573 bool code;
574 Object * o;
575 Attr *attr;
576 char *value = NULL;
577 GSList *list_of_auths = NULL;
578
579
580 cout << "DEBUG: get_auths is running" << endl;
581 o = new Object;
582 code = o->scan(object,strlen(object));
583
584 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
585 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
586 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
587 attr->len - strlen(attr->type->name()) -2 );
588 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
589 //cout << "value: #" << value << "#" << endl;
590 if(strcmp(attr->type->name(),"auth") == 0){
591 cout << "DEBUG: get_auths: adding " << g_strstrip(value) << endl;
592 list_of_auths = g_slist_append(list_of_auths, strdup(g_strstrip(value)));
593 cout << "DEBUG: get_auths: # of nodes in list_of_auths is now " << g_slist_length(list_of_auths) << endl;
594 }
595 }
596
597 cout << "DEBUG: get_auths: returning" << endl;
598 return list_of_auths;
599 }
600
601
602
603
604
605 /* Gets an object as a string an returns its mnt_lower attributes as a
606 GSList (linked list) */
607
608 GSList *get_mnt_lowers(char * object){
/* [<][>][^][v][top][bottom][index][help] */
609 bool code;
610 Object * o;
611 Attr *attr;
612 char *value = NULL;
613 GSList *list_of_mnt_lowers = NULL;
614
615
616 cout << "DEBUG: get_mnt_lowers is running" << endl;
617 o = new Object;
618 code = o->scan(object,strlen(object));
619
620 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
621 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
622 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
623 attr->len - strlen(attr->type->name()) -2 );
624 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
625 //cout << "value: #" << value << "#" << endl;
626 if(strcmp(attr->type->name(),"mnt-lower") == 0){
627 cout << "DEBUG: get_mnt_lowers: adding " << g_strstrip(value) << endl;
628 list_of_mnt_lowers = g_slist_append(list_of_mnt_lowers, strdup(g_strstrip(value)));
629 }
630 }
631
632
633 return list_of_mnt_lowers;
634 }
635
636
637
638
639
640 /* retrieves the override password from the 'override' attribute
641 of the object. If none, it returns NULL */
642 char *get_override(char * object){
/* [<][>][^][v][top][bottom][index][help] */
643 bool code;
644 Object * o;
645 Attr *attr;
646 char *value = NULL;
647
648
649 cout << "DEBUG: get_override is running" << endl;
650 o = new Object;
651 code = o->scan(object,strlen(object));
652
653 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
654 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
655 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
656 attr->len - strlen(attr->type->name()) -2 );
657 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
658 //cout << "value: #" << value << "#" << endl;
659 if(strcmp(attr->type->name(),"override") == 0){
660 cout << "DEBUG: get_override: returning " << g_strstrip(value) << endl;
661 return strdup(g_strstrip(value));
662 }
663 }
664 /* there was no 'override' attrib, so return NULL */
665 return NULL;
666 }
667
668
669
670
671
672
673 /* checks override string (password)
674 returns OVR_OK if it is correct password */
675 int check_override(char * string){
/* [<][>][^][v][top][bottom][index][help] */
676 return OVR_OK; // for now
677 }
678
679
680
681
682
683
684
685 /* takes a GSList of struct auth_struct and a GSList of auths, and a mntner name,
686 add new elements to GSList of struct auth_struct and returns the new
687 GSList of struct auth_struct */
688
689 GSList * add_to_auth_vector(GSList * list_of_auth_struct, GSList * auths, char * mntner_name){
/* [<][>][^][v][top][bottom][index][help] */
690 //GSList * to_be_returned = NULL;
691 GSList * next;
692 char * auth_attrib = NULL;
693 char * auth_attrib_uppercase = NULL, * argument = NULL;
694 struct auth_struct * temp = NULL;
695 int index = 1;
696
697 for(next = auths; next != NULL; next = g_slist_next(next)){
698 auth_attrib = strdup((char *)next->data);
699 auth_attrib = g_strstrip(auth_attrib);
700 cout << "DEBUG: add_to_auth_vector: " << auth_attrib << endl;
701 /* Take the auth attribute and convert it into uppercase for comparisons */
702 auth_attrib_uppercase = strdup(auth_attrib);
703 g_strup(auth_attrib_uppercase);
704
705 if(strstr(auth_attrib_uppercase,"CRYPT-PW") == auth_attrib_uppercase){
706 /* take the argument of the auth attribute */
707 argument = strdup(auth_attrib + strlen("CRYPT-PW"));
708 g_strstrip(argument);
709 cout << "DEBUG: add_to_auth_vector: adding new argument: " << argument << endl;
710 temp = (struct auth_struct *)malloc(sizeof(auth_struct));
711 temp->type = AU_CRYPT_PW;
712 temp->auth = argument;
713 temp->mntner_name = mntner_name;
714 temp->index = index++;
715 list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
716 }else if(strstr(auth_attrib_uppercase,"MAIL-FROM") == auth_attrib_uppercase){
717 /* take the argument of the auth attribute */
718 argument = strdup(auth_attrib + strlen("MAIL-FROM"));
719 g_strstrip(argument);
720 cout << "DEBUG: add_to_auth_vector: adding new argument: " << argument << endl;
721 temp = (struct auth_struct *)malloc(sizeof(auth_struct));
722 temp->type = AU_MAIL_FROM;
723 temp->auth = argument;
724 temp->mntner_name = mntner_name;
725 temp->index = index++;
726 list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
727 }else if(strstr(auth_attrib_uppercase,"PGP-") == auth_attrib_uppercase){
728 temp = (struct auth_struct *)malloc(sizeof(auth_struct));
729 temp->type = AU_PGP;
730 temp->mntner_name = mntner_name;
731 temp->index = index++;
732 /* temp->pgp_struct must be assigned, not yet implemented */
733 cout << "Not implemented totally (PGP)" << endl;
734 }else{
735 cout << "Error: invalid auth attrib: " << auth_attrib << endl;
736 return NULL;
737 }
738 }
739 free(auth_attrib_uppercase);
740 free(auth_attrib);
741 return list_of_auth_struct;
742
743 }
744
745
746
747
748
749
750
751
752
753
754 /* constructs the authorisation vector, which is a GSList of
755 struct auth_struct */
756
757 GSList * get_auth_vector(GSList * mntners){
/* [<][>][^][v][top][bottom][index][help] */
758 GSList * list_of_auths = NULL;
759 GSList * next = NULL;
760 GSList * to_be_returned = NULL;
761 char * query_string = NULL, * result = NULL, * object = NULL;
762 GSList * temp;
763
764 for( next = mntners; next != NULL ; next = g_slist_next(next) ){
765 cout << "=====" << endl << "Got a mntner" << endl;
766 cout << (char *)next->data << endl;
767 query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
768 sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
769 result = send_and_get("reimp", 43, query_string);
770 if(count_objects(result) == 0){
771 cout << "No such maintainer, exiting" << endl;
772 exit(1);
773 }else if(count_objects(result) > 1){
774 cout << "More than one objects returned" << endl;
775 }else{ /* count_objects(result) == 1 */
776 object = take_object(result);
777 cout << "DEBUG: get_auth_vector: Calling get_auths(char *)" << endl;
778 temp = get_auths(object);
779 cout << "DEBUG: get_auth_vector: get_auths(char *) returned" << endl;
780 list_of_auths = g_slist_concat(list_of_auths, temp);
781 to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)next->data);
782 }
783 }
784
785 return to_be_returned;
786 }
787
788
789
790
791
792
793
794
795 /* Check authorisation
796 Applies authorisation rules according to the object type */
797
798 int check_auth(char *new_object, char *old_object, char *type){
/* [<][>][^][v][top][bottom][index][help] */
799
800 GSList *old_mntners = NULL, *new_mntners = NULL;
801 GSList *old_auths = NULL, *new_auths = NULL;
802 GSList *as_block_mnt_lowers = NULL;
803 GSList *old_auth_vector = NULL, *new_auth_vector = NULL, *as_block_auth_vector = NULL;
804 GSList *less_specific_auth_vector = NULL, *less_specific_mnt_lowers = NULL;
805 GSList *less_specific_mntners = NULL;
806
807 char *as_block_object = NULL, *less_specific_object = NULL;
808 char *less_specific_domain = NULL;
809 char *less_specific_object_type = NULL;
810 int overriden = 0;
811 char *override_string = NULL;
812 char *set_name = NULL;
813 Object *set_object = new Object();
814 Object *temp_obj;
815 bool code;
816
817 /* first check if it is overriden or not. if overriden, check the override
818 password. If it is correct, continue, setting "overriden" to 1. If not,
819 immediately exit returning ERR_UP_OVF */
820 override_string = get_override((new_object == NULL) ? old_object : new_object );
821 if(override_string == NULL){
822 overriden = 0;
823 }else if(check_override(override_string) == OVR_OK){
824 overriden = 1; // authorisation is overriden
825 }else if(check_override(override_string) == ERROR_UP_OVS){
826 return ERROR_UP_OVS; // override syntax error --it must have at least two words
827 }else{
828 return ERROR_UP_OVF; // override failed!
829 }
830
831
832 /*
833 * Handle the "person", "role", "limerick", "inet-rtr" types
834 */
835 if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0 ||
836 strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ){
837 if( new_object == NULL && old_object != NULL ){ // the object is to be deleted
838 old_mntners = get_mntners(old_object);
839 old_auth_vector = get_auth_vector(old_mntners);
840 //return authorise(old_auth_vector, overriden, ...);
841 }else if( new_object != NULL && old_object == NULL ){ // the object is to be created
842 new_mntners = get_mntners(new_object);
843 new_auth_vector = get_auth_vector(new_mntners);
844 //return authorise(new_auth_vector, overriden, ...);
845 }else if( new_object != NULL && old_object != NULL ){ // this is an update
846 old_mntners = get_mntners(old_object);
847 old_auth_vector = get_auth_vector(old_mntners);
848 if(old_auth_vector){ // if we have mntners in the old object, use them
849 //return authorise(old_auths_vector, overriden, ...);
850 }else{
851 new_mntners = get_mntners(new_object);
852 new_auth_vector = get_auth_vector(new_mntners);
853 //return authorise(new_auth_vector, overriden, ...);
854 }
855 }else{ // both are NULL, mustn't happen
856 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
857 return ERROR_UP_INT; /* internal error */
858 }
859 }
860
861 /*
862 * Handle the "auth-num" type
863 */
864 else if(strcmp(type,"aut-num") == 0 ){
865 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
866 old_mntners = get_mntners(old_object);
867 old_auth_vector = get_auth_vector(old_mntners);
868 //return authorise(old_auth_vector, overriden, ...);
869 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
870 as_block_object = get_as_block(new_object);
871 if(as_block_object == NULL ){
872 return ERROR_UP_ABN; /* As-block does not exist */
873 }else{
874 as_block_mnt_lowers = get_mnt_lowers(as_block_object);
875 as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
876 if(1/* authorise(as_block_auth_vector, overriden, ...) == UP_AUTH_OK */){
877 new_mntners = get_mntners(new_object);
878 new_auth_vector = get_auth_vector(new_mntners);
879 //return authorise(new_auth_vector, overriden, ...);
880 }else{
881 return ERROR_UP_HOF; /* hierarchical auth failed */
882 }
883 }
884 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
885 old_mntners = get_mntners(old_object);
886 old_auth_vector = get_auth_vector(old_mntners);
887 if(old_auth_vector){ /* if we have mntners in the old object, use them */
888 //return authorise(old_auth_vector, overriden, ...);
889 }else{
890 new_mntners = get_mntners(new_object);
891 new_auth_vector = get_auth_vector(new_mntners);
892 //return authorise(new_auth_vector, overriden, ...);
893 }
894 }else{ /* both are NULL, mustn't happen */
895 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
896 return ERROR_UP_INT; /* internal error */
897 }
898 }
899
900 /*
901 * Handle the "mntner/as-block" types
902 */
903 else if(strcmp(type,"mntner") == 0 || strcmp(type,"as-block") == 0 ){
904 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
905 old_mntners = get_mntners(old_object);
906 old_auth_vector = get_auth_vector(old_mntners);
907 //return authorise(old_auth_vector, overriden, ...);
908 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
909 if(overriden){
910 return UP_AUTH_OK;
911 }else{/* If not overriden, and if not coming from ripe-dbm, must be forwarded to ripe-dbm */
912 cout << "DEBUG: check_auth: '" << type << "' creation requested" << endl;
913 }
914 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
915 old_mntners = get_mntners(old_object);
916 old_auth_vector = get_auth_vector(old_mntners);
917 if(old_auth_vector){ /* if we have mntners in the old object, use them */
918 //return authorise(old_auth_vector, overriden, ...);
919 }else{
920 new_mntners = get_mntners(new_object);
921 new_auth_vector = get_auth_vector(new_mntners);
922 //return authorise(new_auth_vector, overriden, ...);
923 }
924 }else{ // both are NULL, mustn't happen
925 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
926 return ERROR_UP_INT; /* internal error */
927 }
928 }
929
930 /*
931 * Handle the "inetnum/inet6num" types
932 */
933 else if(strcmp(type,"inetnum") == 0 || strcmp(type,"inet6num") == 0 ){
934 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
935 old_mntners = get_mntners(old_object);
936 old_auth_vector = get_auth_vector(old_mntners);
937 //return authorise(old_auth_vector, overriden, ...);
938 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
939 less_specific_object = get_less_specific(new_object, type);
940 if(less_specific_object == NULL){
941 if(overriden){
942 return UP_AUTH_OK;
943 }else{
944 return ERROR_UP_HOF; /* hierarchical authorisation failed */
945 }
946 }else{ /* if we got an inet(6)num object */
947 less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
948 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
949 if(1/* authorise(less_specific_auth_vector, overriden, ...) == UP_AUTH_OK */){
950 new_mntners = get_mntners(new_object);
951 new_auth_vector = get_auth_vector(new_mntners);
952 //return authorise(new_auth_vector, overriden, ...);
953 }else{
954 return ERROR_UP_HOF; /* hierarchical authorisation failed */
955 }
956 }
957 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
958 old_mntners = get_mntners(old_object);
959 old_auth_vector = get_auth_vector(old_mntners);
960 if(old_auth_vector){ // if we have mntners in the old object, use them
961 //return authorise(old_auth_vector, overriden, ...);
962 }else{
963 new_mntners = get_mntners(new_object);
964 new_auth_vector = get_auth_vector(new_mntners);
965 //return authorise(new_auth_vector, overriden, ...);
966 }
967 }else{ // both are NULL, mustn't happen
968 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
969 return ERROR_UP_INT; /* internal error */
970 }
971 }
972
973
974
975 /*
976 * Handle the "domain" type
977 */
978 else if(strcmp(type,"domain") == 0){
979 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
980 old_mntners = get_mntners(old_object);
981 old_auth_vector = get_auth_vector(old_mntners);
982 //return authorise(old_auth_vector, overriden, ...);
983 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
984 /* now, we have to find a 'less specific domain object' for this.
985 If there is no less specific object, then creation is possible
986 only with overriding. */
987 less_specific_domain = get_less_specific_domain(new_object);
988 if(less_specific_domain == NULL){
989 if(overriden){/* we didn't get a 'less specific' domain object */
990 return UP_AUTH_OK;
991 }else{
992 return ERROR_UP_HOF; /* hierarchical authorisation failed */
993 }
994 }else{ /* we get a 'less specific' domain object */
995 less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain);
996 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
997 if(1/* authorise(less_specific_auth_vector, overriden, ...) == UP_AUTH_OK */){
998 new_mntners = get_mntners(new_object);
999 new_auth_vector = get_auth_vector(new_mntners);
1000 //return authorise(new_auth_vector, overriden, ...);
1001 }else{
1002 return ERROR_UP_HOF; /* hierarchical authorisation failed */
1003 }
1004
1005 }
1006 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1007 old_mntners = get_mntners(old_object);
1008 old_auth_vector = get_auth_vector(old_mntners);
1009 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1010 //return authorise(old_auth_vector, overriden, ...);
1011 }else{
1012 new_mntners = get_mntners(new_object);
1013 new_auth_vector = get_auth_vector(new_mntners);
1014 //return authorise(new_auth_vector, overriden, ...);
1015 }
1016 }else{ // both are NULL, mustn't happen
1017 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1018 return ERROR_UP_INT; /* internal error */
1019 }
1020 }
1021
1022
1023 /*
1024 * Handle the set objects ("as-set","rtr-set","peering-set" and "filter-set" types
1025 */
1026 else if(strcmp(type,"as-set") == 0 || strcmp(type,"rtr-set") == 0 ||
1027 strcmp(type,"peering-set") == 0 || strcmp(type,"filter-set") == 0 ){
1028 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1029 old_mntners = get_mntners(old_object);
1030 old_auth_vector = get_auth_vector(old_mntners);
1031 //return authorise(old_auth_vector, overriden, ...);
1032 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1033 code = set_object->scan(new_object, strlen(new_object));
1034 set_name = get_search_key(set_object, type, new_object);
1035 if(strstr(set_name,":") == NULL ){/* if the name is _not_ hierarchical */
1036 new_mntners = get_mntners(new_object);
1037 new_auth_vector = get_auth_vector(new_mntners);
1038 //return authorise(new_auth_vector, overriden, ...);
1039 }else{/* the name is hierarchical */
1040 less_specific_object = get_less_specific_set(new_object, type);
1041 if(less_specific_object != NULL){/* such an object exists */
1042 temp_obj = new Object();
1043 code = temp_obj->scan(less_specific_object, strlen(less_specific_object));
1044 less_specific_object_type = get_type(temp_obj);
1045 delete(temp_obj);
1046 if(strcmp(less_specific_object_type, "aut-num") == 0){/* if this is an aut-num object */
1047 less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
1048 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1049 if(less_specific_auth_vector != NULL){
1050 //return authorise((less_specific_auth_vector, overriden, ...);
1051 }else{/* the less specific object doesn't contain any mnt-lower */
1052 less_specific_mntners = get_mntners(less_specific_object);
1053 less_specific_auth_vector = get_auth_vector(less_specific_mntners);
1054 if(less_specific_auth_vector != NULL){/* less spec object has some mnt-by attribs,
1055 use them */
1056 //return authorise((less_specific_auth_vector, overriden, ...);
1057 }else{/* the less specific object doesn't contain any mnt-by either */
1058 if(overriden){
1059 return UP_AUTH_OK;
1060 }else{
1061 return ERROR_UP_HOF; /* hierarchical authorisation failed */
1062 }
1063 }
1064 }
1065 }else{ /* this is _not_ an aut-num object*/
1066 less_specific_mntners = get_mntners(less_specific_object);
1067 less_specific_auth_vector = get_auth_vector(less_specific_mntners);
1068 if(less_specific_auth_vector != NULL ){/* the set obj has some mnt-by attribs */
1069 //return authorise((less_specific_auth_vector, overriden, ...);
1070 }else{
1071 if(overriden){
1072 return UP_AUTH_OK;
1073 }else{
1074 return ERROR_UP_HOF; /* hierarchical authorisation failed */
1075 }
1076 }
1077 }
1078
1079 }else{/* we don't have a less specific of this set object in the DB */
1080 return ERROR_UP_HOF; /* hierarchical authorisation failed */
1081 }
1082 }
1083 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1084 old_mntners = get_mntners(old_object);
1085 old_auth_vector = get_auth_vector(old_mntners);
1086 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1087 //return authorise(old_auth_vector, overriden, ...);
1088 }else{
1089 new_mntners = get_mntners(new_object);
1090 new_auth_vector = get_auth_vector(new_mntners);
1091 //return authorise(new_auth_vector, overriden, ...);
1092 }
1093 }else{ /* both are NULL, mustn't happen */
1094 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1095 return ERROR_UP_INT; /* internal error */
1096 }
1097
1098
1099
1100
1101
1102 }else{ /* other types are not implemented yet */
1103 cout << "check_auth: This type '" << type << "' is not implemented yet" << endl;
1104 return ERROR_UP_NIY; /* not implemented yet */
1105 }
1106 return UP_AUTH_OK; // for now
1107 }
1108
1109
1110
1111
1112
1113
1114 /* Gets the old version of the given "arg" object, which is in char * format
1115 and returns the old version again in char * format */
1116
1117 char * get_old_version(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
1118
1119 bool code = true;
1120 char *type=NULL, *primary_search_key = NULL, *search_string = NULL;
1121 Object *o;
1122 o = new Object;
1123 char *result = NULL;
1124
1125
1126 code = o->scan(arg,strlen(arg));
1127 type = get_type(o);
1128 primary_search_key = get_search_key(o,type, arg);
1129 cout << "type=" << type << endl;
1130 cout << "primary_search_key=" << primary_search_key << endl;
1131 // prepare the search string
1132 search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
1133 + strlen(type) + 1);
1134 sprintf(search_string, "-x -R -r -T%s %s",type, primary_search_key);
1135 result = send_and_get("reimp", 43, search_string);
1136 cout << "send_and_get returned (with search '"<< search_string <<"'): " << endl
1137 << result << endl;
1138 // count the objects
1139 if(count_objects(result) == 0){
1140 result = NULL; // we don't have any object
1141 }else if(count_objects(result) == 1){
1142 result = take_object(result);
1143 cout << "DEBUG: Take_object returned ***\n" << result << "***" << endl;
1144 }else{ // we have more than one objects, error!
1145 error = ERROR_UP_MOR;
1146 return NULL;
1147 }
1148 return result;
1149 }
1150
1151
1152
1153
1154
1155
1156 int process_object(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
1157 bool code = true;
1158 Object *o;
1159 char * old_version = NULL;
1160 o = new Object;
1161 code = o->scan(arg,strlen(arg));
1162 if(code){
1163 if(o->isDeleted){
1164 old_version = get_old_version(arg);
1165 if(old_version == NULL){ // the object doesn't exist in the db!
1166 return ERROR_UP_NSO; /* no such object */
1167 }else
1168 if(check_auth(NULL, old_version, o->type->getName()) == UP_AUTH_OK){ // check_auth will know that this is a deletion
1169 cout << "DEBUG: Will send the obj to be deleted" << endl;
1170 //send_object_db(arg,"DEL");
1171 }else{
1172 //auth failed !
1173 cout << error_msg << endl;
1174 return ERROR_UP_AUF; /* Auth failed */
1175 }
1176 }else{
1177 old_version = get_old_version(arg);
1178 if(check_auth(arg, old_version,o->type->getName() ) == UP_AUTH_OK){ // note: if the obj is to-be-created,
1179 // old_version becomes NULL
1180 cout << "DEBUG: Will send the obj to be added/updated" << endl;
1181 //send_object_db(arg,"ADD");
1182 }else{
1183 // auth failed !
1184 cout << error_msg << endl;
1185 return ERROR_UP_AUF; /* Auth failed */
1186 }
1187 }
1188 }else{// even if obj doesn't parse properly, it may be a legacy object
1189 // which the user wants to delete...
1190 return ERROR_UP_NIY; /* Not implemented yet */
1191 }
1192 }
1193
1194
1195
1196
1197
1198
1199 void main(int argc, char **argv, char **envp){
/* [<][>][^][v][top][bottom][index][help] */
1200 schema.initialize();
1201 //init_and_set_options(argc, argv, envp);
1202
1203 int count = 0;
1204
1205
1206 char *line;
1207 char *object = NULL;
1208 char *password = NULL;
1209 GSList *list_of_objects = NULL, *next = NULL;
1210
1211 object = NULL;
1212
1213 line = (char *)malloc(1024);
1214
1215 while(fgets(line, 1024,stdin ) != NULL){
1216 /* first, if it is a pasword, save it, but do not regard it as an attrib */
1217 if(strstr(line, "password:") == line){
1218 cout << "This is a password" << endl;
1219 free(password);
1220 password = strdup(line + strlen("password:"));
1221 continue;
1222 }
1223 if(strlen(line) == 1){
1224 cout << endl;
1225 if(object != NULL){
1226 cout << "The object was" << endl << object << endl;
1227 list_of_objects = g_slist_append(list_of_objects, object);
1228 //free(object);
1229 object = NULL;
1230 }
1231 }else{
1232 /* if the line contains only the EOL char */
1233 if(object == NULL && strlen(line) != 1){
1234 object = (char *)malloc(strlen(line));
1235 object = strdup(line);
1236 }
1237 else{
1238 object = (char *)realloc(object, strlen(object) + strlen(line));
1239 object = strcat(object, line);
1240 }
1241 }
1242
1243 }
1244
1245 if(password != NULL){
1246 password = g_strstrip(password);
1247 cout << "This was the password: " << password << endl;
1248 }
1249
1250 cout << "Now, printing out the objects in the list " << endl;
1251 next = list_of_objects;
1252 for( next = list_of_objects; next != NULL ; next = g_slist_next(next) ){
1253 cout << "=====" << endl << "Got a member" << endl;
1254 cout << (char *)next->data << endl;
1255 process_object((char *)next->data);
1256 cout << "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << endl;
1257 }
1258
1259
1260 }