aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2011-05-24 16:46:49 +0000
committerRob Austein <sra@hactrn.net>2011-05-24 16:46:49 +0000
commit8ac101f7e8d2c03b6cbf134ab80560811161d2ed (patch)
tree2a6370c6a41debba4230f53ad835e14873001f20
parentea2e37754ba2d256026fc874126f83f791ceda63 (diff)
Checkpoint
svn path=/rcynic-ng/rcynic.c; revision=3829
-rw-r--r--rcynic-ng/rcynic.c136
1 files changed, 94 insertions, 42 deletions
diff --git a/rcynic-ng/rcynic.c b/rcynic-ng/rcynic.c
index 6846a85f..a20fee85 100644
--- a/rcynic-ng/rcynic.c
+++ b/rcynic-ng/rcynic.c
@@ -1519,6 +1519,46 @@ static int prune_unauthenticated(const rcynic_ctx_t *rc,
/**
+ * Read non-directory filenames from a directory, so we can check to
+ * see what's missing from a manifest.
+ */
+static STACK_OF(OPENSSL_STRING) *directory_filenames(const rcynic_ctx_t *rc,
+ const char *prefix,
+ const char *uri)
+{
+ STACK_OF(OPENSSL_STRING) *result = NULL;
+ char path[FILENAME_MAX];
+ DIR *dir = NULL;
+ struct dirent *d;
+ int ok = 0;
+
+ assert(rc && prefix && uri);
+
+ if (!uri_to_filename(rc, uri, path, sizeof(path), prefix) ||
+ (dir = opendir(path)) == NULL ||
+ (result = sk_OPENSSL_STRING_new(uri_cmp)) == NULL)
+ goto done;
+
+ while ((d = readdir(dir)) != NULL)
+ if (d->d_type != DT_DIR && !sk_OPENSSL_STRING_push_strdup(result, d->d_name))
+ goto done;
+
+ ok = 1;
+
+ done:
+ if (dir != NULL)
+ closedir(dir);
+
+ if (ok)
+ return result;
+
+ sk_OPENSSL_STRING_pop_free(result, OPENSSL_STRING_free);
+ return NULL;
+}
+
+
+
+/**
* Read a DER object using a BIO pipeline that hashes the file content
* as we read it. Returns the internal form of the parsed DER object,
* sets the hash buffer (if specified) as a side effect. The default
@@ -3007,12 +3047,10 @@ static void walk_cert_3(rcynic_ctx_t *rc,
const int backup,
Manifest *manifest)
{
- char uri[URI_MAX], path[FILENAME_MAX];
+ char uri[URI_MAX];
FileAndHash *fah;
STACK_OF(OPENSSL_STRING) *stray_ducks = NULL;
const certinfo_t *issuer;
- DIR *dir = NULL;
- struct dirent *d;
walk_ctx_t *w;
int i;
@@ -3025,17 +3063,7 @@ static void walk_cert_3(rcynic_ctx_t *rc,
/*
* Pull all non-directory filenames from the publication point directory.
*/
- if ((stray_ducks = sk_OPENSSL_STRING_new(uri_cmp)) == NULL)
- logmsg(rc, log_sys_err, "Couldn't allocate stray_ducks stack");
- else if (!uri_to_filename(rc, issuer->sia, path, sizeof(path), prefix) || (dir = opendir(path)) == NULL)
- logmsg(rc, log_data_err, "Couldn't list directory %s, skipping check for out-of-manifest data", path);
- else
- while ((d = readdir(dir)) != NULL)
- if (d->d_type != DT_DIR && !sk_OPENSSL_STRING_push_strdup(stray_ducks, d->d_name))
- logmsg(rc, log_sys_err, "Couldn't strdup() string \"%s\", blundering onwards", d->d_name);
-
- if (dir != NULL)
- closedir(dir);
+ stray_ducks = directory_filenames(rc, prefix, issuer->sia);
/*
* Loop over manifest, checking everything it lists. Remove any
@@ -3083,56 +3111,80 @@ static void walk_cert_3(rcynic_ctx_t *rc,
* daisy chain recursion is to avoid having to duplicate the stack
* manipulation and error handling.
*/
-static void walk_cert(rcynic_ctx_t *rc, STACK_OF(walk_ctx_t) *walk)
+static void walk_cert_cb(rcynic_ctx_t *rc, STACK_OF(walk_ctx_t) *walk)
{
- const certinfo_t *issuer;
+ STACK_OF(X509) *certs;
+ Manifest *manifest = NULL;
walk_ctx_t *w;
assert(rc && walk);
w = sk_walk_ctx_t_value(walk, sk_walk_ctx_t_num(walk) - 1);
assert(w);
- issuer = &w->certinfo;
- if (issuer->sia[0] && issuer->ca) {
- int n_walk = sk_walk_ctx_t_num(walk);
- Manifest *manifest = NULL;
+ certs = walk_ctx_stack_certs(walk);
+ assert(certs);
- rc->indent++;
+ if ((manifest = check_manifest(rc, w->certinfo.manifest, certs)) == NULL)
+ logmsg(rc, log_data_err, "Couldn't get manifest %s, blundering onward", w->certinfo.manifest);
- rsync_tree(rc, issuer->sia);
+ sk_X509_free(certs);
+ certs = NULL;
- if (!issuer->manifest[0]) {
+ logmsg(rc, log_debug, "Walking unauthenticated store");
+ walk_cert_3(rc, walk, rc->unauthenticated, 0, manifest);
+ logmsg(rc, log_debug, "Done walking unauthenticated store");
- logmsg(rc, log_data_err, "Issuer's certificate does not specify a manifest, skipping collection");
+ logmsg(rc, log_debug, "Walking old authenticated store");
+ walk_cert_3(rc, walk, rc->old_authenticated, 1, manifest);
+ logmsg(rc, log_debug, "Done walking old authenticated store");
- } else {
+ Manifest_free(manifest);
+}
- STACK_OF(X509) *certs = walk_ctx_stack_certs(walk);
+/**
+ * Recursive walk of certificate hierarchy (core of the program). The
+ * daisy chain recursion is to avoid having to duplicate the stack
+ * manipulation and error handling.
+ */
+static void walk_cert(rcynic_ctx_t *rc, STACK_OF(walk_ctx_t) *walk)
+{
+ const certinfo_t *issuer;
+ walk_ctx_t *w;
+ int n_walk;
- assert(certs != NULL);
+ assert(rc && walk);
- if ((manifest = check_manifest(rc, issuer->manifest, certs)) == NULL)
- logmsg(rc, log_data_err, "Couldn't get manifest %s, blundering onward", issuer->manifest);
+ w = sk_walk_ctx_t_value(walk, sk_walk_ctx_t_num(walk) - 1);
+ assert(w);
+ issuer = &w->certinfo;
- sk_X509_free(certs);
- certs = NULL;
+ if (!issuer->sia[0] || !issuer->ca)
+ return;
- logmsg(rc, log_debug, "Walking unauthenticated store");
- walk_cert_3(rc, walk, rc->unauthenticated, 0, manifest);
- logmsg(rc, log_debug, "Done walking unauthenticated store");
+ if (!issuer->manifest[0]) {
+ logmsg(rc, log_data_err, "Issuer's certificate does not specify a manifest, skipping collection");
+ return;
+ }
- logmsg(rc, log_debug, "Walking old authenticated store");
- walk_cert_3(rc, walk, rc->old_authenticated, 1, manifest);
- logmsg(rc, log_debug, "Done walking old authenticated store");
+ /*
+ * Both the log indentation hack and the assertions to track call
+ * stack against data stack are probably doomed, but leave here
+ * until they stop being useful.
+ */
- Manifest_free(manifest);
- }
+ rc->indent++;
+ n_walk = sk_walk_ctx_t_num(walk);
- assert(sk_walk_ctx_t_num(walk) == n_walk);
+ /*
+ * rsync() doesn't take callbacks yet, but pretend it does, so we
+ * can start sorting out which bits of code go where.
+ */
+ rsync_tree(rc, issuer->sia);
+ walk_cert_cb(rc, walk);
- rc->indent--;
- }
+ assert(sk_walk_ctx_t_num(walk) == n_walk);
+ rc->indent--;
}