]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Merge branch 'rsync'
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Thu, 20 Dec 2018 19:10:20 +0000 (13:10 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Thu, 20 Dec 2018 19:10:20 +0000 (13:10 -0600)
1  2 
src/Makefile.am
src/main.c
src/object/certificate.c
src/rsync/rsync.c
src/rsync/rsync.h

diff --cc src/Makefile.am
Simple merge
diff --cc src/main.c
index b91aa4c43a582dfb189a163da0e61b0b40e416a1,3d44138b225cd2c01bc7df238d43fd5186c6a9d1..e12ab69785e99b30319f3cf7c8cbc047bdbb6d5a
@@@ -6,9 -6,9 +6,10 @@@
  #include "debug.h"
  #include "log.h"
  #include "thread_var.h"
 +#include "crypto/hash.h"
  #include "object/certificate.h"
  #include "object/tal.h"
+ #include "rsync/rsync.h"
  
  /**
   * Registers the RPKI-specific OIDs in the SSL library.
@@@ -56,13 -33,17 +57,18 @@@ end
   * have been extracted from a TAL.
   */
  static int
 -handle_tal_uri(char const *uri)
 +handle_tal_uri(struct tal *tal, char const *guri)
  {
        struct validation *state;
 -      char *cert_file;
 +      char *luri;
        int error;
  
 -      error = uri_g2l(uri, &cert_file);
++      /* TODO this probably needs the state... */
++      error = download_files(guri);
+       if (error)
+               return error;
 -      error = download_files(uri);
 +      error = validation_prepare(&state, tal);
        if (error)
                return error;
  
@@@ -96,13 -81,18 +103,20 @@@ main(int argc, char **argv
  
        print_stack_trace_on_segfault();
  
 -      if (argc < 3) {
 -              pr_err("Repository path as first argument and TAL file as second argument, please.");
 -              return -EINVAL;
 -      }
 +      if (argc < 3)
 +              return pr_err("Repository path as first argument and TAL file as second argument, please.");
  
-       error = hash_init();
+       if (argc >= 4)
+               is_rsync_active = false;
+       error = rsync_init(is_rsync_active);
        if (error)
                return error;
  
++      error = hash_init();
++      if (error)
++              return error; /* TODO revert rsync? */
++
        add_rpki_oids();
        thvar_init();
        fnstack_store();
index c9dfe3eeb78b4c038bd3ddbcd19d7d9ea09d4883,d667175481344a42938df770858ffd715bc5f741..9016b0d0b14d5a66a8d5a025159f2c5f3fc2d825
@@@ -10,7 -9,7 +10,8 @@@
  #include "manifest.h"
  #include "thread_var.h"
  #include "asn1/decode.h"
 -#include "../rsync/rsync.h"
 +#include "asn1/oid.h"
++#include "rsync/rsync.h"
  
  /*
   * The X509V3_EXT_METHOD that references NID_sinfo_access uses the AIA item.
@@@ -573,77 -383,40 +574,81 @@@ handle_rpkiManifest(ACCESS_DESCRIPTION 
  }
  
  static int
 -_certificate_traverse(X509 *cert, SIGNATURE_INFO_ACCESS *sia, int sia_len)
 +handle_caRepository(ACCESS_DESCRIPTION *ad)
  {
 -      ACCESS_DESCRIPTION *ad;
 -      ACCESS_DESCRIPTION *list[sia_len];
        char *uri;
        int error;
-       int nid;
 +
 +      error = gn_g2l(ad->location, &uri);
 +      if (error)
 +              return error;
 +
 +      pr_debug("caRepository: %s", uri);
++      error = download_files(uri);
 +
 +      free(uri);
 +      return error;
 +}
 +
 +static int
 +handle_signedObject(ACCESS_DESCRIPTION *ad)
 +{
 +      char *uri;
 +      int error;
 +
 +      error = gn_g2l(ad->location, &uri);
 +      if (error)
 +              return error;
 +
 +      pr_debug("signedObject: %s", uri);
 +
 +      free(uri);
 +      return error;
 +}
 +
 +int
 +certificate_traverse_ca(X509 *cert, STACK_OF(X509_CRL) *crls)
 +{
 +      struct validation *state;
 +      SIGNATURE_INFO_ACCESS *sia;
 +      ACCESS_DESCRIPTION *ad;
 +      bool manifest_found = false;
        int i;
 -      int count;
 +      int error;
  
 -      for (i = 0, count = 0; i < sia_len; i++) {
 +      sia = X509_get_ext_d2i(cert, NID_sinfo_access, NULL, NULL);
 +      if (sia == NULL) {
 +              pr_err("Certificate lacks a Subject Information Access extension.");
 +              return -ESRCH;
 +      }
 +
 +      state = state_retrieve();
 +      if (state == NULL) {
 +              error = -EINVAL;
 +              goto end2;
 +      }
 +      error = validation_push_cert(state, cert);
 +      if (error)
 +              goto end2;
 +
++      /* rsync */
 +      for (i = 0; i < sk_ACCESS_DESCRIPTION_num(sia); i++) {
                ad = sk_ACCESS_DESCRIPTION_value(sia, i);
-               nid = OBJ_obj2nid(ad->method);
-               if (nid == NID_rpkiManifest) {
-                       error = handle_rpkiManifest(ad, crls);
+               if (OBJ_obj2nid(ad->method) == NID_caRepository) {
 -                      error = gn2uri(ad->location, (char const **)&uri);
++                      error = handle_caRepository(ad);
                        if (error)
 -                              goto end;
 -                      error = download_files(uri);
 -                      if (error)
 -                              goto end;
 -              } else {
 -                      list[count] = ad;
 -                      count++;
 +                              goto end1;
-                       manifest_found = true;
+               }
+       }
  
-               } else if (nid == NID_caRepository) {
-                       error = handle_caRepository(ad);
 -      for (i = 0; i < count; i++) {
 -              ad = list[i];
++      /* validate */
++      for (i = 0; i < sk_ACCESS_DESCRIPTION_num(sia); i++) {
++              ad = sk_ACCESS_DESCRIPTION_value(sia, i);
+               if (OBJ_obj2nid(ad->method) == NID_rpkiManifest) {
 -                      error = gn_g2l(ad->location, &uri);
 -                      if (error)
 -                              goto end;
 -                      error = handle_manifest(uri);
 -                      free(uri);
++                      error = handle_rpkiManifest(ad, crls);
                        if (error)
 -                              goto end;
 +                              goto end1;
++                      manifest_found = true;
                }
        }
  
index 0000000000000000000000000000000000000000,c5e41196ad1243423b0ba5f38b1760967d24ca85..a9598bf0b30caf7f59ed1b569d6d35308be8a65c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,433 +1,436 @@@
 -      error = uri_g2l(rsync_uri, &local_uri);
+ #include "rsync.h"
+ #include <sys/queue.h>
+ #include <sys/stat.h>
+ #include <err.h>
+ #include <errno.h>
+ #include <limits.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include "../common.h"
+ struct uri {
+       char *string;
+       size_t len;
+       SLIST_ENTRY(uri) next;
+ };
+ SLIST_HEAD(uri_list, uri);
+ static struct uri_list *rsync_uris;
+ static bool execute_rsync = true;
+ //static const char *rsync_command[] = {"rsync", "--recursive", "--delete", "--times", NULL};
+ static int create_dir_recursive(char *);
+ static int create_dir(char *);
+ static int do_rsync(char const *);
+ static int get_dest_path(char const *, char **);
+ static bool is_file(char const *);
+ static bool dir_exist(char *);
+ int
+ rsync_init(bool is_rsync_active)
+ {
+       // TODO remove the next 2 lines
+       if (!is_rsync_active) {
+               execute_rsync = is_rsync_active;
+               return 0;
+       }
+       rsync_uris = malloc(sizeof(struct uri_list));
+       if (!rsync_uris)
+               return -ENOMEM;
+       SLIST_INIT(rsync_uris);
+       return 0;
+ }
+ void
+ rsync_destroy()
+ {
+       struct uri *uri;
+       // TODO remove the next 2 lines
+       if (!execute_rsync)
+               return;
+       while (!SLIST_EMPTY(rsync_uris)) {
+               uri = SLIST_FIRST(rsync_uris);
+               SLIST_REMOVE_HEAD(rsync_uris, next);
+               free(uri->string);
+               free(uri);
+       }
+       free(rsync_uris);
+ }
+ static int
+ do_rsync(char const *rsync_uri)
+ {
+       int error;
+       char *command;
+       char *dest;
+       char const *rsync_command = "rsync --recursive --delete --times --contimeout=20 "; /* space char at end*/
+       error = get_dest_path(rsync_uri, &dest);
+       if (error)
+               return error;
+       command = malloc(strlen(rsync_command) + 1 + strlen(rsync_uri) + 1 + strlen(dest) + 1);
+       if (command == NULL)
+               return -ENOMEM;
+       strcpy(command, rsync_command);
+       strcat(command, rsync_uri);
+       strcat(command, " ");
+       strcat(command, dest);
+       free(dest);
+       printf("(%s) command = %s \n", __func__, command);
+       error = system(command);
+       if (error) {
+               printf("result rsync %d\n", error);
+               perror("rsync");
+       }
+       free(command);
+       return error;
+ }
+ static int
+ get_dest_path(char const *rsync_uri, char **result)
+ {
+       char *local_uri, *temp_str;
+       unsigned int result_size;
+       int error;
 -      error = uri_g2l(rsync_uri_path, &localuri);
++
++      error = uri_g2l(rsync_uri, strlen(rsync_uri), &local_uri);
+       if (error)
+               return error;
+       if (!is_file(local_uri)) {
+               *result = local_uri;
+               return 0;
+       }
+       temp_str = strrchr(local_uri, '/');
+       if (temp_str == NULL) {
+               // TODO warning msg
+               return -EINVAL;
+       }
+       result_size = temp_str - local_uri + 1; /* add slash (+1) */
+       temp_str = malloc(result_size + 1); /* null char (+1) */
+       if (temp_str == NULL) {
+               return -ENOMEM;
+       }
+       temp_str[result_size] = '\0'; /*Set null char*/
+       strncpy(temp_str, local_uri, result_size);
+       free(local_uri);
+       *result = temp_str;
+       return 0;
+ }
+ //static int
+ //do_rsync(char *rsync_uri)
+ //{
+ //    int temp, result;
+ //
+ //    char *temp_char;
+ //    char *rsync_command[] = {"rsync", "--recursive", "--delete", "--times", NULL, NULL, NULL};
+ //    char *src = "rsync://rpki.afrinic.net/repository/AfriNIC.cer";
+ //    char *dest = "/home/dhf/Desktop/rpkitest/rpki.afrinic.net/repository/";
+ //
+ //    rsync_command[4] = src;
+ //    rsync_command[5] = dest;
+ //    temp = 0;
+ //    while (temp < 7) {
+ //            temp_char = rsync_command[temp];
+ //            printf("[%d] ", temp);
+ //            if (temp_char == NULL) {
+ //                    printf("NULL\n");
+ //            } else {
+ //                    printf("%s\n", temp_char);
+ //            }
+ //            temp++;
+ //    }
+ //    printf("pre execv \n");
+ ////  result = execve(rsync_command[0], rsync_command, NULL);
+ //
+ //    result = system("rsync --recursive --delete --times rsync://rpki.afrinic.net/repository/AfriNIC.cer /home/dhf/Desktop/rpkitest/rpki.afrinic.net/repository/");
+ ////  printf("result execv %d\n", result);
+ //    printf("result rsync %d\n", result);
+ //    perror("rsync");
+ //    return 0;
+ //}
+ static bool
+ rsync_uri_prefix_equals(struct uri *rsync_uri, char const *new_uri)
+ {
+       size_t uri_len;
+       uri_len = strlen(new_uri);
+       if (rsync_uri->len > uri_len)
+               return false;
+       return !strncasecmp(rsync_uri->string, new_uri, rsync_uri->len);
+ }
+ static bool
+ is_uri_in_list(char const *rsync_uri)
+ {
+       struct uri *cursor;
+       bool found;
+       if (SLIST_EMPTY(rsync_uris)) {
+               return false;
+       }
+       found = false;
+       SLIST_FOREACH(cursor, rsync_uris, next) {
+               if (rsync_uri_prefix_equals(cursor, rsync_uri)) {
+                       found = true;
+                       break;
+               }
+       }
+       return found;
+ }
+ static int
+ add_uri_to_list(char const *rsync_uri_path)
+ {
+       struct uri *rsync_uri;
+       size_t urilen;
+       rsync_uri = malloc(sizeof(struct uri));
+       if (rsync_uri == NULL) {
+               warnx("Out of memory");
+               return -ENOMEM;
+       }
+       urilen = strlen(rsync_uri_path);
+       rsync_uri->string = malloc(urilen + 1);
+       if (!rsync_uri->string) {
+               free(rsync_uri);
+               warnx("Out of memory");
+               return -ENOMEM;
+       }
+       strcpy(rsync_uri->string, rsync_uri_path);
+       rsync_uri->len = urilen;
+       SLIST_INSERT_HEAD(rsync_uris, rsync_uri, next);
+       return 0;
+ }
+ static int
+ short_uri(char const *rsync_uri, char **result)
+ {
+       char const *const PREFIX = "rsync://";
+       char const *tmp;
+       char *short_uri;
+       size_t result_len;
+       size_t prefix_len;
+       prefix_len = strlen(PREFIX);
+       if (strncmp(PREFIX, rsync_uri, prefix_len) != 0) {
+ //            pr_err("Global URI %s does not begin with '%s'.", rsync_uri,
+ //                PREFIX);
+               return -EINVAL;
+       }
+       do {
+               tmp = rsync_uri + prefix_len;
+               tmp = strchr(tmp, '/');
+               if (tmp == NULL) {
+                       result_len = strlen(rsync_uri);
+                       break;
+               }
+               tmp = tmp + 1;
+               tmp = strchr(tmp, '/');
+               if (tmp != NULL)
+                       result_len = strlen(rsync_uri) - strlen(tmp);
+               else
+                       result_len = strlen(rsync_uri);
+       } while (0);
+       short_uri = malloc(result_len + 1 + 1); /* slash + null chara */
+       if (!short_uri)
+               return -ENOMEM;
+       strncpy(short_uri, rsync_uri, result_len);
+       short_uri[result_len] = '/';
+       short_uri[result_len + 1] = '\0';
+       *result = short_uri;
+       return 0;
+ }
+ int
+ download_files(char const *rsync_uri)
+ {
+       int error;
+       char *rsync_uri_path, *localuri;
+       // TODO remove the next 2 lines
+       if (!execute_rsync)
+               return 0;
+       if (is_uri_in_list(rsync_uri)){
+               printf("(%s) ON LIST: %s\n", __func__, rsync_uri);
+               error = 0;
+               goto end;
+       } else {
+               printf("(%s) DOWNLOAD: %s\n",__func__,  rsync_uri);
+       }
+       error = short_uri(rsync_uri, &rsync_uri_path);
+       if (error)
+               return error;
 -      if (file_has_extension(path, "cer"))
++      error = uri_g2l(rsync_uri_path, strlen(rsync_uri_path), &localuri);
+       if (error)
+               goto free_uri_path;
+       error = create_dir_recursive(localuri);
+       free(localuri);
+       if (error)
+               goto free_uri_path;
+       error = do_rsync(rsync_uri_path);
+       if (error)
+               goto free_uri_path;
+       error = add_uri_to_list(rsync_uri_path);
+ free_uri_path:
+       free(rsync_uri_path);
+ end:
+       return error;
+ }
+ static int
+ create_dir_recursive(char *localuri)
+ {
+       char *temp_luri;
+       char path[PATH_MAX];
+       char *slash;
+       size_t localuri_len;
+       size_t repository_len;
+       unsigned int offset;
+       if (dir_exist(localuri))
+               return 0;
+       localuri_len = strlen(localuri);
+       repository_len = strlen(repository);
+       temp_luri = localuri + repository_len ;
+       strcpy(path, repository);
+       offset = repository_len;
+       slash = strchr(temp_luri, '/');
+       while (slash != NULL) {
+               if (slash == temp_luri) {
+                       temp_luri++;
+                       localuri_len--;
+                       slash = strchr(temp_luri, '/');
+                       continue;
+               }
+               strcpy(path + offset, "/");
+               offset += 1;
+               strncpy(path + offset, temp_luri, slash - temp_luri);
+               offset += slash - temp_luri;
+               if (offset > localuri_len) {
+                       break;
+               }
+               path[offset] = '\0';
+               if (create_dir(path) == -1) {
+                       perror("Error while creating Dir");
+                       return -1;
+               }
+               temp_luri += slash - temp_luri + 1;
+               slash = strchr(temp_luri, '/');
+       }
+       if (offset < localuri_len) {
+               strcpy(path + offset, "/");
+               offset += 1;
+               strcpy(path + offset, temp_luri);
+               offset = localuri + localuri_len - temp_luri + offset + 1;
+               path[offset] = '\0';
+       }
+       if (create_dir(path) == -1) {
+               perror("Error while creating Dir");
+               return -1;
+       }
+       return 0;
+ }
+ static bool
+ is_file(char const *path)
+ {
 -      if (file_has_extension(path, "gbr"))
++      size_t path_len = strlen(path);
++
++      if (file_has_extension(path, path_len, "cer"))
+               return true;
 -      if (file_has_extension(path, "mft"))
++      if (file_has_extension(path, path_len, "gbr"))
+               return true;
++      if (file_has_extension(path, path_len, "mft"))
+               return true;
+       return false;
+ }
+ static bool
+ dir_exist(char *path)
+ {
+       int error;
+       struct stat _stat;
+       error = stat(path, &_stat);
+       if (error == -1)
+               return false; /* a dir or file not exist*/
+       return true;
+ }
+ static int
+ create_dir(char *path)
+ {
+       struct stat _stat;
+       int error;
+       mode_t mode = 0777;
+       if (is_file(path))
+               return 0;
+       error = stat(path, &_stat);
+       if (error != -1) {
+               /* a dir or file exist*/
+               return 0;
+       }
+       if (errno != ENOENT) {
+               perror("stat");
+               return -1; /* another error occurs*/
+       }
+       error = mkdir(path, mode);
+       return error;
+ }
index 0000000000000000000000000000000000000000,3287ebe9524da01b1f283b0bce65424647d6f083..5005908b2480a6b79b39a919fd9f9f69ae633d2d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,11 +1,11 @@@
 -void rsync_destroy();
+ #ifndef SRC_RSYNC_RSYNC_H_
+ #define SRC_RSYNC_RSYNC_H_
+ #include <stdbool.h>
+ int download_files(const char *);
+ int rsync_init(bool);
++void rsync_destroy(void);
+ #endif /* SRC_RSYNC_RSYNC_H_ */