From 3252c2851905e85aa976882e38ab0b7338148ccf Mon Sep 17 00:00:00 2001 From: pcarana Date: Fri, 7 Feb 2020 11:48:29 -0600 Subject: [PATCH] Update docs, add rsync timeout, verify mft existence. +Add missing dependency at some distros (libcurl) and update 'libxml' package (the '*-devel' package is required). +Add '--timeout' parameter to rsync command, the default value is the same as 'http.idle-timeout' (15 secs). Update docs where this value is referred. +Verify that the manifest file exists locally after downloading a repo, if the file doesn't exist, then the repo is discarded and (possibly) another repository will be utilized (eg. rrdp or rsync repo). --- docs/installation.md | 22 +++++++++++++++++----- docs/usage.md | 6 ++++-- examples/config.json | 2 ++ man/fort.8 | 7 +++++-- src/common.c | 20 +++++++++++++------- src/common.h | 2 +- src/config.c | 7 +++++-- src/object/certificate.c | 30 ++++++++++++++++++++++++++++-- 8 files changed, 75 insertions(+), 21 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index c099b396..6b2ff8b6 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -120,7 +120,7 @@ This OS requires additional steps due to its GCC supported version (currently 4. OpenSSL devel (openssl-devel) package isn't necessary, if it's previously installed remove it to avoid future conflicts with newer OpenSSL versions. {% highlight bash %} -sudo yum install autoconf automake git jansson-devel pkgconfig rsync libxml2 +sudo yum install autoconf automake git jansson-devel pkgconfig rsync libcurl-devel libxml2-devel # Install supported GCC to compile OpenSSL sudo yum groupinstall "Development Tools" {% endhighlight %} @@ -169,7 +169,7 @@ exit The following steps are for Fedora 30. {% highlight bash %} -sudo yum install autoconf automake gcc make openssl-devel jansson-devel libxml2 +sudo yum install autoconf automake gcc make openssl-devel jansson-devel libcurl-devel libxml2-devel wget https://github.com/NICMx/FORT-validator/releases/download/v{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz tar xvzf fort-{{ site.fort-latest-version }}.tar.gz @@ -184,7 +184,7 @@ sudo make install The following steps are for openSUSE Leap 15.1. {% highlight bash %} -sudo zypper install autoconf automake gcc libopenssl-devel libjansson-devel libxml2 +sudo zypper install autoconf automake gcc libopenssl-devel libjansson-devel libcurl-devel libxml2-devel wget https://github.com/NICMx/FORT-validator/releases/download/v{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz tar xvzf fort-{{ site.fort-latest-version }}.tar.gz @@ -198,6 +198,18 @@ sudo make install The following steps are for FreeBSD 12.0. +`curl` library is needed, so in case it isn't already installed there's a port to install it: + +{% highlight bash %} +cd /usr/ports/ftp/curl +make config +su +make install clean +exit +{% endhighlight %} + +From there on, the installation steps are: + {% highlight bash %} su pkg install autoconf automake gcc jansson pkgconf rsync libxml2 @@ -215,7 +227,7 @@ exit ### Slackware version -The following steps are for Slackware "current" release (as of 2019-08-12). +The following steps are for Slackware "current" release (as of 2020-01-31). All dependencies are included in the current release, so there's no need to install any dependency. @@ -232,7 +244,7 @@ sudo make install In case you wan't a fresh version of Fort validator, there's this third option. The steps are mostly the same as in [Option 2](#option-2-compiling-and-installing-the-release-tarball), just another dependency (as minimum) must be installed: "git"; and a few steps are included in order to get the source code and generate configuration scripts. -The following example is the processo to clone, compile and install in Debian OS. +The following example is the process to clone, compile and install in Debian OS. {% highlight bash %} sudo apt install autoconf automake build-essential git libjansson-dev libssl-dev pkg-config rsync libcurl4-openssl-dev libxml2-dev diff --git a/docs/usage.md b/docs/usage.md index e8e45836..c5bf1b44 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -634,12 +634,14 @@ The configuration options are mostly the same as the ones from the `argv` interf "--delete", "--times", "--contimeout=20", + "--timeout=15", "$REMOTE", "$LOCAL" ], "arguments-flat": [ "--times", "--contimeout=20", + "--timeout=15", "--dirs", "$REMOTE", "$LOCAL" @@ -857,7 +859,7 @@ Name of the program needed to invoke an rsync file transfer. - **Type:** String array - **Availability:** JSON only -- **Default:** `[ "--recursive", "--delete", "--times", "--contimeout=20", "$REMOTE", "$LOCAL" ]` +- **Default:** `[ "--recursive", "--delete", "--times", "--contimeout=20", "--timeout=15", "$REMOTE", "$LOCAL" ]` Arguments needed by [`rsync.program`](#rsyncprogram) to perform a recursive rsync. @@ -867,7 +869,7 @@ Fort will replace `"$REMOTE"` with the remote URL it needs to download, and `"$L - **Type:** String array - **Availability:** JSON only -- **Default:** `[ "--times", "--contimeout=20", "--dirs", "$REMOTE", "$LOCAL" ]` +- **Default:** `[ "--times", "--contimeout=20", "--timeout=15", "--dirs", "$REMOTE", "$LOCAL" ]` Arguments needed by [`rsync.program`](#rsyncprogram) to perform a single-file rsync. diff --git a/examples/config.json b/examples/config.json index c18e1b40..75e27500 100644 --- a/examples/config.json +++ b/examples/config.json @@ -52,12 +52,14 @@ "--delete", "--times", "--contimeout=20", + "--timeout=15", "$REMOTE", "$LOCAL" ], "arguments-flat": [ "--times", "--contimeout=20", + "--timeout=15", "--dirs", "$REMOTE", "$LOCAL" diff --git a/man/fort.8 b/man/fort.8 index de1143cb..bb8cee31 100644 --- a/man/fort.8 +++ b/man/fort.8 @@ -81,7 +81,8 @@ Arguments needed by .B rsync.program to perform a recursive rsync. The arguments are specified as a JSON string array; its default value is: -[ "--recursive", "--delete", "--times", "--contimeout=20", "$REMOTE", "$LOCAL" ] +[ "--recursive", "--delete", "--times", "--contimeout=20", "--timeout=15", +"$REMOTE", "$LOCAL" ] .P FORT will replace "$REMOTE" with the remote URL it needs to download, and "$LOCAL" with the target local directory where the file is supposed to be @@ -97,7 +98,7 @@ Arguments needed by .B rsync.program to perform a single-file rsync. The arguments are specified as a JSON string array; its default value is: -[ "--times", "--contimeout=20", "--dirs", "$REMOTE", "$LOCAL" ] +[ "--times", "--contimeout=20", "--timeout=15", "--dirs", "$REMOTE", "$LOCAL" ] .P FORT will replace "$REMOTE" with the remote URL it needs to download, and "$LOCAL" with the target local directory where the file is supposed to be @@ -907,12 +908,14 @@ to a specific value: "--delete", "--times", "--contimeout=20", + "--timeout=15", "$REMOTE", "$LOCAL" ], "arguments-flat": [ "--times", "--contimeout=20", + "--timeout=15", "--dirs", "$REMOTE", "$LOCAL" diff --git a/src/common.c b/src/common.c index 21c62931..0888e12e 100644 --- a/src/common.c +++ b/src/common.c @@ -187,12 +187,16 @@ process_file_or_dir(char const *location, char const *file_ext, bool -valid_file_or_dir(char const *location) +valid_file_or_dir(char const *location, bool check_file, bool check_dir) { FILE *file; struct stat attr; + bool is_file, is_dir; bool result; + if (!check_file && !check_dir) + pr_crit("Wrong usage, at least one check must be 'true'."); + result = false; file = fopen(location, "rb"); if (file == NULL) { @@ -206,13 +210,15 @@ valid_file_or_dir(char const *location) goto end; } - if (!S_ISREG(attr.st_mode) && !S_ISDIR(attr.st_mode)) { - pr_err("'%s' does not seem to be a file or directory", - location); - goto end; - } + is_file = check_file && S_ISREG(attr.st_mode); + is_dir = check_dir && S_ISDIR(attr.st_mode); + + result = is_file || is_dir; + if (!result) + pr_err("'%s' does not seem to be a %s", location, + (check_file && check_dir) ? "file or directory" : + (check_file) ? "file" : "directory"); - result = true; end: if (fclose(file) == -1) pr_errno(errno, "fclose() failed"); diff --git a/src/common.h b/src/common.h index f925f2dd..7c07ac64 100644 --- a/src/common.h +++ b/src/common.h @@ -46,7 +46,7 @@ void close_thread(pthread_t thread, char const *); typedef int (*process_file_cb)(char const *, void *); int process_file_or_dir(char const *, char const *, process_file_cb, void *); -bool valid_file_or_dir(char const *); +bool valid_file_or_dir(char const *, bool, bool); char const *addr2str4(struct in_addr const *, char *); char const *addr2str6(struct in6_addr const *, char *); diff --git a/src/config.c b/src/config.c index 453c2091..e9b95dc4 100644 --- a/src/config.c +++ b/src/config.c @@ -696,6 +696,7 @@ set_default_values(void) "--delete", "--times", "--contimeout=20", + "--timeout=15", "$REMOTE", "$LOCAL", }; @@ -703,6 +704,7 @@ set_default_values(void) static char const *flat_rsync_args[] = { "--times", "--contimeout=20", + "--timeout=15", "--dirs", "$REMOTE", "$LOCAL", @@ -813,7 +815,7 @@ validate_config(void) if (rpki_config.tal == NULL) return pr_err("The TAL file/directory (--tal) is mandatory."); - if (!valid_file_or_dir(rpki_config.tal)) + if (!valid_file_or_dir(rpki_config.tal, true, true)) return pr_err("Invalid TAL file/directory."); if (rpki_config.server.interval.expire < @@ -830,7 +832,8 @@ validate_config(void) !valid_output_file(rpki_config.output.bgpsec)) return pr_err("Invalid output.bgpsec file."); - if (rpki_config.slurm != NULL && !valid_file_or_dir(rpki_config.slurm)) + if (rpki_config.slurm != NULL && + !valid_file_or_dir(rpki_config.slurm, true, true)) return pr_err("Invalid slurm location."); /* FIXME (later) Remove when sync-strategy is fully deprecated */ diff --git a/src/object/certificate.c b/src/object/certificate.c index 1fbf3259..b9bf206c 100644 --- a/src/object/certificate.c +++ b/src/object/certificate.c @@ -1876,16 +1876,42 @@ certificate_validate_aia(struct rpki_uri *caIssuers, X509 *cert) return force_aia_validation(caIssuers, cert); } +/* + * Verify that the manifest file actually exists at the local repository, if it + * doesn't exist then discard the repository (which can result in a attempt + * to fetch data from another repository). + */ +static int +verify_mft_loc(struct rpki_uri *mft_uri) +{ + if (!valid_file_or_dir(uri_get_local(mft_uri), true, false)) + return -EINVAL; /* Error already logged */ + + return 0; +} + static int exec_rrdp_method(struct sia_ca_uris *sia_uris) { - return rrdp_load(sia_uris->rpkiNotify.uri); + int error; + + error = rrdp_load(sia_uris->rpkiNotify.uri); + if (error) + return error; + + return verify_mft_loc(sia_uris->mft.uri); } static int exec_rsync_method(struct sia_ca_uris *sia_uris) { - return download_files(sia_uris->caRepository.uri, false, false); + int error; + + error = download_files(sia_uris->caRepository.uri, false, false); + if (error) + return error; + + return verify_mft_loc(sia_uris->mft.uri); } /* -- 2.47.3