]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Create CACHEDIR.TAG during cache initialization
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Tue, 12 Dec 2023 21:16:39 +0000 (15:16 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Tue, 12 Dec 2023 22:04:21 +0000 (16:04 -0600)
To hint backup software not to copy the cache.
https://bford.info/cachedir/

Fixes #104.

src/Makefile.am
src/cache/local_cache.c
src/cache/local_cache.h
src/cache/tmp.c [deleted file]
src/cache/tmp.h [deleted file]
src/http/http.c
src/object/tal.c

index 9aa7d768e60742370a7ed9eef9d3929fc3c25212..25ee95af6cea9129796a6aa43a319cf51ff1ba1e 100644 (file)
@@ -45,7 +45,6 @@ fort_SOURCES += types/uri.h types/uri.c
 fort_SOURCES += types/vrp.c types/vrp.h
 
 fort_SOURCES += cache/local_cache.c cache/local_cache.h
-fort_SOURCES += cache/tmp.c cache/tmp.h
 
 fort_SOURCES += config/boolean.c config/boolean.h
 fort_SOURCES += config/filename_format.h config/filename_format.c
index ae1e9d1d012f0b8f273ab55f9fc6d1919df37dc3..38b46cdf3c47c566613e320409c7fda8aa39e60b 100644 (file)
@@ -1,6 +1,7 @@
 #include "cache/local_cache.h"
 
 #include <ftw.h>
+#include <stdatomic.h>
 #include <time.h>
 
 #include "alloc.h"
@@ -44,6 +45,9 @@ struct rpki_cache {
 #define CACHE_METAFILE "cache.json"
 #define TAGNAME_VERSION "fort-version"
 
+#define CACHEDIR_TAG "CACHEDIR.TAG"
+#define TMPDIR "tmp"
+
 #define TAL_METAFILE "tal.json"
 #define TAGNAME_URL "url"
 #define TAGNAME_ATTEMPT_TS "attempt-timestamp"
@@ -51,24 +55,55 @@ struct rpki_cache {
 #define TAGNAME_SUCCESS_TS "success-timestamp"
 #define TAGNAME_IS_NOTIF "is-rrdp-notification"
 
+static atomic_uint file_counter;
+
 static char *
-get_cache_metafile_name(void)
+get_cache_filename(char const *name, bool fatal)
 {
        struct path_builder pb;
        int error;
 
-       error = pb_init_cache(&pb, NULL, CACHE_METAFILE);
+       error = pb_init_cache(&pb, NULL, name);
        if (error) {
-               pr_op_err("Cannot create path to " CACHE_METAFILE ": %s",
-                   strerror(error));
-               return NULL;
+               if (fatal) {
+                       pr_crit("Cannot create path to %s: %s", name,
+                           strerror(error));
+               } else {
+                       pr_op_err("Cannot create path to %s: %s", name,
+                           strerror(error));
+                       return NULL;
+               }
        }
 
        return pb.string;
 }
 
-void
-cache_setup(void)
+static int
+write_simple_file(char const *filename, char const *content)
+{
+       FILE *file;
+       int error;
+
+       file = fopen(filename, "w");
+       if (file == NULL)
+               goto fail;
+
+       if (fprintf(file, "%s", content) < 0)
+               goto fail;
+
+       fclose(file);
+       return 0;
+
+fail:
+       error = errno;
+       pr_op_err("Cannot write %s: %s", filename, strerror(error));
+       if (file != NULL)
+               fclose(file);
+       return error;
+}
+
+static void
+init_cache_metafile(void)
 {
        char *filename;
        json_t *root;
@@ -76,10 +111,7 @@ cache_setup(void)
        char const *file_version;
        int error;
 
-       filename = get_cache_metafile_name();
-       if (filename == NULL)
-               return;
-
+       filename = get_cache_filename(CACHE_METAFILE, true);
        root = json_load_file(filename, 0, &jerror);
 
        if (root == NULL) {
@@ -114,41 +146,93 @@ end:      json_decref(root);
        free(filename);
 }
 
+static void
+init_cachedir_tag(void)
+{
+       char *filename;
+
+       filename = get_cache_filename(CACHEDIR_TAG, false);
+       if (filename == NULL)
+               return;
+
+       if (file_exists(filename) == ENOENT)
+               write_simple_file(filename,
+                  "Signature: 8a477f597d28d172789f06886806bc55\n"
+                  "# This file is a cache directory tag created by Fort.\n"
+                  "# For information about cache directory tags, see:\n"
+                  "#   https://bford.info/cachedir/\n");
+
+       free(filename);
+}
+
+static void
+init_tmp_dir(void)
+{
+       char *dirname;
+       int error;
+
+       dirname = get_cache_filename(TMPDIR, true);
+
+       error = mkdir_p(dirname, true);
+       if (error)
+               pr_crit("Cannot create %s: %s", dirname, strerror(error));
+
+       free(dirname);
+}
+
 void
-cache_teardown(void)
+cache_setup(void)
 {
-       static char const * const CONTENT = "{ \"" TAGNAME_VERSION "\": \""
-           PACKAGE_VERSION "\" }\n";
+       init_cache_metafile();
+       init_cachedir_tag();
+       init_tmp_dir();
+}
 
+void
+cache_teardown(void)
+{
        char *filename;
-       FILE *file = NULL;
-       int error;
 
-       filename = get_cache_metafile_name();
+       filename = get_cache_filename(CACHE_METAFILE, false);
        if (filename == NULL)
                return;
 
-       file = fopen(filename, "w");
-       if (file == NULL)
-               goto fail;
+       write_simple_file(filename, "{ \"" TAGNAME_VERSION "\": \""
+           PACKAGE_VERSION "\" }\n");
+       free(filename);
+}
 
-       if (fprintf(file, CONTENT) < 0)
-               goto fail;
+/*
+ * Returns a unique temporary file name in the local cache.
+ *
+ * The file will not be automatically deleted when it is closed or the program
+ * terminates.
+ *
+ * The name of the function is inherited from tmpfile(3).
+ *
+ * The resulting string needs to be released.
+ */
+int
+cache_tmpfile(char **filename)
+{
+       struct path_builder pb;
+       int error;
 
-       free(filename);
-       fclose(file);
-       return;
+       error = pb_init_cache(&pb, NULL, TMPDIR);
+       if (error)
+               return error;
+       error = pb_append_u32(&pb, atomic_fetch_add(&file_counter, 1u));
+       if (error) {
+               pb_cleanup(&pb);
+               return error;
+       }
 
-fail:
-       error = errno;
-       pr_op_err("Cannot write %s: %s", filename, strerror(error));
-       free(filename);
-       if (file != NULL)
-               fclose(file);
+       *filename = pb.string;
+       return 0;
 }
 
 static char *
-get_json_filename(struct rpki_cache *cache)
+get_tal_json_filename(struct rpki_cache *cache)
 {
        struct path_builder pb;
        return pb_init_cache(&pb, cache->tal, TAL_METAFILE)
@@ -248,7 +332,7 @@ load_tal_json(struct rpki_cache *cache)
         * without killing itself. It's just a cache of a cache.
         */
 
-       filename = get_json_filename(cache);
+       filename = get_tal_json_filename(cache);
        if (filename == NULL)
                return;
 
@@ -357,7 +441,7 @@ write_tal_json(struct rpki_cache *cache)
        if (json == NULL)
                return;
 
-       filename = get_json_filename(cache);
+       filename = get_tal_json_filename(cache);
        if (filename == NULL)
                goto end;
 
index d01932a5f79aff4e20295930c178fe2cd39b8ff0..93eb11f1a2dcffc1a058d1f49c0fc4b97916e68e 100644 (file)
@@ -8,6 +8,8 @@ struct rpki_cache;
 void cache_setup(void);
 void cache_teardown(void);
 
+int cache_tmpfile(char **);
+
 struct rpki_cache *cache_create(char const *);
 /* Will destroy the cache object, but not the cache directory itself, obv. */
 void cache_destroy(struct rpki_cache *);
diff --git a/src/cache/tmp.c b/src/cache/tmp.c
deleted file mode 100644 (file)
index 6d969d5..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "cache/tmp.h"
-
-#include <stdatomic.h>
-
-#include "common.h"
-#include "data_structure/path_builder.h"
-
-static atomic_uint file_counter;
-
-static int
-pb_init_tmp(struct path_builder *pb)
-{
-       return pb_init_cache(pb, NULL, "tmp");
-}
-
-int
-init_tmpdir(void)
-{
-       struct path_builder pb;
-       int error;
-
-       error = pb_init_tmp(&pb);
-       if (error)
-               return error;
-
-       error = mkdir_p(pb.string, true);
-
-       pb_cleanup(&pb);
-       return error;
-}
-
-/*
- * Returns a unique temporary file name in the local cache.
- *
- * The file will not be automatically deleted when it is closed or the program
- * terminates.
- *
- * The name of the function is inherited from tmpfile(3).
- *
- * The resulting string needs to be released.
- */
-int
-cache_tmpfile(char **filename)
-{
-       struct path_builder pb;
-       int error;
-
-       error = pb_init_tmp(&pb);
-       if (error)
-               return error;
-       error = pb_append_u32(&pb, atomic_fetch_add(&file_counter, 1u));
-       if (error)
-               return error;
-
-       *filename = pb.string;
-       return 0;
-}
diff --git a/src/cache/tmp.h b/src/cache/tmp.h
deleted file mode 100644 (file)
index 9d30a22..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef SRC_CACHE_TMP_H_
-#define SRC_CACHE_TMP_H_
-
-int init_tmpdir(void);
-int cache_tmpfile(char **filename);
-
-#endif /* SRC_CACHE_TMP_H_ */
index 7b356be97faf9de65350c7a3420e1ab4846fd574..27a10b9a8767c929a60791432c3868ccdc59a9c6 100644 (file)
@@ -7,8 +7,8 @@
 #include "config.h"
 #include "file.h"
 #include "log.h"
-#include "cache/tmp.h"
 #include "data_structure/uthash.h"
+#include "cache/local_cache.h"
 
 struct http_handler {
        CURL *curl;
index 0f5ad1e981886eb1690767303c5f24d9a02e2c98..ebc588f40f2c288d75711a116081fd4d1d1a8b55 100644 (file)
@@ -14,7 +14,6 @@
 #include "state.h"
 #include "thread_var.h"
 #include "validation_handler.h"
-#include "cache/tmp.h"
 #include "crypto/base64.h"
 #include "object/certificate.h"
 #include "rtr/db/vrps.h"
@@ -505,17 +504,11 @@ perform_standalone_validation(void)
        struct threads_list threads = SLIST_HEAD_INITIALIZER(threads);
        struct validation_thread *thread;
        struct db_table *db = NULL;
-       int error, tmperr;
+       int error = 0;
+       int tmperr;
 
        cache_setup();
 
-       error = init_tmpdir();
-       if (error) {
-               pr_val_err("Cannot initialize the cache's temporal directory: %s",
-                   strerror(error));
-               return NULL;
-       }
-
        /* TODO (fine) Maybe don't spawn threads if there's only one TAL */
        if (foreach_file(config_get_tal(), ".tal", true, spawn_tal_thread,
                         &threads) != 0) {