From: Alberto Leiva Popper Date: Thu, 20 Dec 2018 19:10:20 +0000 (-0600) Subject: Merge branch 'rsync' X-Git-Tag: v0.0.2~114 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f94901c31ab5dfc97cf445c367256e04a9b3ce77;p=thirdparty%2FFORT-validator.git Merge branch 'rsync' --- f94901c31ab5dfc97cf445c367256e04a9b3ce77 diff --cc src/main.c index b91aa4c4,3d44138b..e12ab697 --- a/src/main.c +++ b/src/main.c @@@ -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(); diff --cc src/object/certificate.c index c9dfe3ee,d6671754..9016b0d0 --- a/src/object/certificate.c +++ b/src/object/certificate.c @@@ -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; + + 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 nid; 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; } } diff --cc src/rsync/rsync.c index 00000000,c5e41196..a9598bf0 mode 000000,100644..100644 --- a/src/rsync/rsync.c +++ b/src/rsync/rsync.c @@@ -1,0 -1,433 +1,436 @@@ + #include "rsync.h" + + #include + #include + #include + #include + #include + #include + #include + #include + + #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, &local_uri); ++ ++ 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; + - error = uri_g2l(rsync_uri_path, &localuri); ++ 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, "cer")) ++ size_t path_len = strlen(path); ++ ++ if (file_has_extension(path, path_len, "cer")) + return true; - if (file_has_extension(path, "gbr")) ++ if (file_has_extension(path, path_len, "gbr")) + return true; - if (file_has_extension(path, "mft")) ++ 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; + } diff --cc src/rsync/rsync.h index 00000000,3287ebe9..5005908b mode 000000,100644..100644 --- a/src/rsync/rsync.h +++ b/src/rsync/rsync.h @@@ -1,0 -1,11 +1,11 @@@ + #ifndef SRC_RSYNC_RSYNC_H_ + #define SRC_RSYNC_RSYNC_H_ + + #include + + int download_files(const char *); + int rsync_init(bool); -void rsync_destroy(); ++void rsync_destroy(void); + + + #endif /* SRC_RSYNC_RSYNC_H_ */