aboutsummaryrefslogtreecommitdiff
path: root/rcynic
diff options
context:
space:
mode:
Diffstat (limited to 'rcynic')
-rw-r--r--rcynic/Makefile.in22
-rw-r--r--rcynic/defasn1.h140
-rw-r--r--rcynic/defstack.awk71
-rw-r--r--rcynic/defstack.h134
-rw-r--r--rcynic/rcynic-svn.py190
-rw-r--r--rcynic/rcynic.c332
-rwxr-xr-xrcynic/validation_status.awk32
7 files changed, 598 insertions, 323 deletions
diff --git a/rcynic/Makefile.in b/rcynic/Makefile.in
index eba83f39..0370f33a 100644
--- a/rcynic/Makefile.in
+++ b/rcynic/Makefile.in
@@ -6,7 +6,6 @@ BIN = ${NAME}
SRC = ${NAME}.c
OBJ = ${NAME}.o
-HDR = defasn1.h
GEN = defstack.h
OBJS = ${OBJ} bio_f_linebreak.o
@@ -24,21 +23,22 @@ abs_top_builddir = @abs_top_builddir@
host_os = @host_os@
-SCRIPTS = rcynic-text rcynic-html
+SCRIPTS = rcynic-text rcynic-html rcynic-svn validation_status
all: ${BIN} ${SCRIPTS}
clean:
cd static-rsync; ${MAKE} $@
- rm -f ${BIN} ${OBJS} ${GEN} ${SCRIPTS}
+ rm -f ${BIN} ${OBJS} ${SCRIPTS}
-${OBJ}: ${SRC} ${HDR} ${GEN}
+${OBJ}: ${SRC} ${GEN}
${BIN}: ${OBJS}
${CC} ${CFLAGS} -o $@ ${OBJS} ${LDFLAGS} ${LIBS}
-defstack.h: defstack.awk ${SRC} ${HDR}
- ${AWK} -f >$@ defstack.awk ${SRC} ${HDR}
+${GEN}: ${SRC}
+ ${PYTHON} ${abs_top_srcdir}/buildtools/defstack.py ${SRC} >$@.tmp
+ mv $@.tmp $@
test: ${BIN}
if test -r rcynic.conf; \
@@ -73,7 +73,13 @@ rcynic-text: rcynic-text.py
rcynic-html: rcynic-html.py
${COMPILE_PYTHON}
+rcynic-svn: rcynic-svn.py
+ ${COMPILE_PYTHON}
+
+validation_status: validation_status.py
+ ${COMPILE_PYTHON}
+
tags: TAGS
-TAGS: ${SRC} ${HDR} ${GEN}
- etags ${SRC} ${HDR} ${GEN}
+TAGS: ${SRC} ${GEN}
+ etags ${SRC} ${GEN}
diff --git a/rcynic/defasn1.h b/rcynic/defasn1.h
deleted file mode 100644
index c14e0ce5..00000000
--- a/rcynic/defasn1.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2009--2011 Internet Systems Consortium ("ISC")
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Portions copyright (C) 2006--2008 American Registry for Internet Numbers ("ARIN")
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef __DEFASN1_H__
-#define __DEFASN1_H__
-
-#include <openssl/bio.h>
-#include <openssl/pem.h>
-#include <openssl/err.h>
-#include <openssl/x509.h>
-#include <openssl/x509v3.h>
-#include <openssl/safestack.h>
-#include <openssl/conf.h>
-#include <openssl/rand.h>
-#include <openssl/asn1t.h>
-#include <openssl/cms.h>
-
-/*
- * ASN.1 templates. Not sure that ASN1_EXP_OPT() is the right macro
- * for these defaulted "version" fields, but it's what the examples
- * for this construction use. Probably doesn't matter since this
- * program only decodes manifests, never encodes them.
- *
- * Putting this section under conditional compilation is a hack to
- * keep Doxygen's parser from becoming hopelessly confused by the
- * weird OpenSSL ASN.1 macros. Someday perhaps I'll have time to
- * track down the problem in Doxygen's parser, but this works for now.
- */
-
-#ifndef DOXYGEN_GETS_HOPELESSLY_CONFUSED_BY_THIS_SECTION
-
-typedef struct FileAndHash_st {
- ASN1_IA5STRING *file;
- ASN1_BIT_STRING *hash;
-} FileAndHash;
-
-DECLARE_STACK_OF(FileAndHash)
-
-ASN1_SEQUENCE(FileAndHash) = {
- ASN1_SIMPLE(FileAndHash, file, ASN1_IA5STRING),
- ASN1_SIMPLE(FileAndHash, hash, ASN1_BIT_STRING)
-} ASN1_SEQUENCE_END(FileAndHash)
-
-typedef struct Manifest_st {
- ASN1_INTEGER *version, *manifestNumber;
- ASN1_GENERALIZEDTIME *thisUpdate, *nextUpdate;
- ASN1_OBJECT *fileHashAlg;
- STACK_OF(FileAndHash) *fileList;
-} Manifest;
-
-ASN1_SEQUENCE(Manifest) = {
- ASN1_EXP_OPT(Manifest, version, ASN1_INTEGER, 0),
- ASN1_SIMPLE(Manifest, manifestNumber, ASN1_INTEGER),
- ASN1_SIMPLE(Manifest, thisUpdate, ASN1_GENERALIZEDTIME),
- ASN1_SIMPLE(Manifest, nextUpdate, ASN1_GENERALIZEDTIME),
- ASN1_SIMPLE(Manifest, fileHashAlg, ASN1_OBJECT),
- ASN1_SEQUENCE_OF(Manifest, fileList, FileAndHash)
-} ASN1_SEQUENCE_END(Manifest)
-
-DECLARE_ASN1_FUNCTIONS(FileAndHash)
-DECLARE_ASN1_FUNCTIONS(Manifest)
-
-IMPLEMENT_ASN1_FUNCTIONS(FileAndHash)
-IMPLEMENT_ASN1_FUNCTIONS(Manifest)
-
-typedef struct ROAIPAddress_st {
- ASN1_BIT_STRING *IPAddress;
- ASN1_INTEGER *maxLength;
-} ROAIPAddress;
-
-DECLARE_STACK_OF(ROAIPAddress)
-
-ASN1_SEQUENCE(ROAIPAddress) = {
- ASN1_SIMPLE(ROAIPAddress, IPAddress, ASN1_BIT_STRING),
- ASN1_OPT(ROAIPAddress, maxLength, ASN1_INTEGER)
-} ASN1_SEQUENCE_END(ROAIPAddress)
-
-typedef struct ROAIPAddressFamily_st {
- ASN1_OCTET_STRING *addressFamily;
- STACK_OF(ROAIPAddress) *addresses;
-} ROAIPAddressFamily;
-
-DECLARE_STACK_OF(ROAIPAddressFamily)
-
-ASN1_SEQUENCE(ROAIPAddressFamily) = {
- ASN1_SIMPLE(ROAIPAddressFamily, addressFamily, ASN1_OCTET_STRING),
- ASN1_SEQUENCE_OF(ROAIPAddressFamily, addresses, ROAIPAddress)
-} ASN1_SEQUENCE_END(ROAIPAddressFamily)
-
-typedef struct ROA_st {
- ASN1_INTEGER *version, *asID;
- STACK_OF(ROAIPAddressFamily) *ipAddrBlocks;
-} ROA;
-
-ASN1_SEQUENCE(ROA) = {
- ASN1_EXP_OPT(ROA, version, ASN1_INTEGER, 0),
- ASN1_SIMPLE(ROA, asID, ASN1_INTEGER),
- ASN1_SEQUENCE_OF(ROA, ipAddrBlocks, ROAIPAddressFamily)
-} ASN1_SEQUENCE_END(ROA)
-
-DECLARE_ASN1_FUNCTIONS(ROAIPAddress)
-DECLARE_ASN1_FUNCTIONS(ROAIPAddressFamily)
-DECLARE_ASN1_FUNCTIONS(ROA)
-
-IMPLEMENT_ASN1_FUNCTIONS(ROAIPAddress)
-IMPLEMENT_ASN1_FUNCTIONS(ROAIPAddressFamily)
-IMPLEMENT_ASN1_FUNCTIONS(ROA)
-
-#endif /* DOXYGEN_GETS_HOPELESSLY_CONFUSED_BY_THIS_SECTION */
-
-#endif /* __DEFASN1_H__ */
diff --git a/rcynic/defstack.awk b/rcynic/defstack.awk
deleted file mode 100644
index 4593cb33..00000000
--- a/rcynic/defstack.awk
+++ /dev/null
@@ -1,71 +0,0 @@
-# $Id$
-#
-# Copyright (C) 2011 Internet Systems Consortium ("ISC")
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-function print_line(name, line)
-{
- gsub(/%/, name, line);
- print line;
-}
-
-function define_stack(name)
-{
- print_line(name, "/*");
- print_line(name, " * Safestack macros for %.");
- print_line(name, " */");
- print_line(name, "#define sk_%_new(st) SKM_sk_new(%, (st))");
- print_line(name, "#define sk_%_new_null() SKM_sk_new_null(%)");
- print_line(name, "#define sk_%_free(st) SKM_sk_free(%, (st))");
- print_line(name, "#define sk_%_num(st) SKM_sk_num(%, (st))");
- print_line(name, "#define sk_%_value(st, i) SKM_sk_value(%, (st), (i))");
- print_line(name, "#define sk_%_set(st, i, val) SKM_sk_set(%, (st), (i), (val))");
- print_line(name, "#define sk_%_zero(st) SKM_sk_zero(%, (st))");
- print_line(name, "#define sk_%_push(st, val) SKM_sk_push(%, (st), (val))");
- print_line(name, "#define sk_%_unshift(st, val) SKM_sk_unshift(%, (st), (val))");
- print_line(name, "#define sk_%_find(st, val) SKM_sk_find(%, (st), (val))");
- print_line(name, "#define sk_%_find_ex(st, val) SKM_sk_find_ex(%, (st), (val))");
- print_line(name, "#define sk_%_delete(st, i) SKM_sk_delete(%, (st), (i))");
- print_line(name, "#define sk_%_delete_ptr(st, ptr) SKM_sk_delete_ptr(%, (st), (ptr))");
- print_line(name, "#define sk_%_insert(st, val, i) SKM_sk_insert(%, (st), (val), (i))");
- print_line(name, "#define sk_%_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(%, (st), (cmp))");
- print_line(name, "#define sk_%_dup(st) SKM_sk_dup(%, st)");
- print_line(name, "#define sk_%_pop_free(st, free_func) SKM_sk_pop_free(%, (st), (free_func))");
- print_line(name, "#define sk_%_shift(st) SKM_sk_shift(%, (st))");
- print_line(name, "#define sk_%_pop(st) SKM_sk_pop(%, (st))");
- print_line(name, "#define sk_%_sort(st) SKM_sk_sort(%, (st))");
- print_line(name, "#define sk_%_is_sorted(st) SKM_sk_is_sorted(%, (st))");
- print_line(name, "");
-}
-
-BEGIN {
- print "/*";
- print " * Automatically generated, do not edit.";
- print " * Generator $Id$";
- print " */";
- print "";
- print "#ifndef __DEFSTACK_H__";
- print "#define __DEFSTACK_H__";
- print "";
-}
-
-/DECLARE_STACK_OF/ {
- sub(/^[ \t]+/, "");
- if (split($0, a, /[() \t]+/) > 1 && a[1] == "DECLARE_STACK_OF")
- define_stack(a[2]);
-}
-
-END {
- print "#endif /* __DEFSTACK_H__ */";
-}
diff --git a/rcynic/defstack.h b/rcynic/defstack.h
new file mode 100644
index 00000000..97490878
--- /dev/null
+++ b/rcynic/defstack.h
@@ -0,0 +1,134 @@
+/*
+ * Automatically generated, do not edit.
+ * Generator $Id: defstack.py 4725 2012-09-19 21:28:34Z sra $
+ */
+
+#ifndef __RCYNIC_C__DEFSTACK_H__
+#define __RCYNIC_C__DEFSTACK_H__
+
+/*
+ * Safestack macros for validation_status_t.
+ */
+#define sk_validation_status_t_new(st) SKM_sk_new(validation_status_t, (st))
+#define sk_validation_status_t_new_null() SKM_sk_new_null(validation_status_t)
+#define sk_validation_status_t_free(st) SKM_sk_free(validation_status_t, (st))
+#define sk_validation_status_t_num(st) SKM_sk_num(validation_status_t, (st))
+#define sk_validation_status_t_value(st, i) SKM_sk_value(validation_status_t, (st), (i))
+#define sk_validation_status_t_set(st, i, val) SKM_sk_set(validation_status_t, (st), (i), (val))
+#define sk_validation_status_t_zero(st) SKM_sk_zero(validation_status_t, (st))
+#define sk_validation_status_t_push(st, val) SKM_sk_push(validation_status_t, (st), (val))
+#define sk_validation_status_t_unshift(st, val) SKM_sk_unshift(validation_status_t, (st), (val))
+#define sk_validation_status_t_find(st, val) SKM_sk_find(validation_status_t, (st), (val))
+#define sk_validation_status_t_find_ex(st, val) SKM_sk_find_ex(validation_status_t, (st), (val))
+#define sk_validation_status_t_delete(st, i) SKM_sk_delete(validation_status_t, (st), (i))
+#define sk_validation_status_t_delete_ptr(st, ptr) SKM_sk_delete_ptr(validation_status_t, (st), (ptr))
+#define sk_validation_status_t_insert(st, val, i) SKM_sk_insert(validation_status_t, (st), (val), (i))
+#define sk_validation_status_t_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(validation_status_t, (st), (cmp))
+#define sk_validation_status_t_dup(st) SKM_sk_dup(validation_status_t, st)
+#define sk_validation_status_t_pop_free(st, free_func) SKM_sk_pop_free(validation_status_t, (st), (free_func))
+#define sk_validation_status_t_shift(st) SKM_sk_shift(validation_status_t, (st))
+#define sk_validation_status_t_pop(st) SKM_sk_pop(validation_status_t, (st))
+#define sk_validation_status_t_sort(st) SKM_sk_sort(validation_status_t, (st))
+#define sk_validation_status_t_is_sorted(st) SKM_sk_is_sorted(validation_status_t, (st))
+
+/*
+ * Safestack macros for walk_ctx_t.
+ */
+#define sk_walk_ctx_t_new(st) SKM_sk_new(walk_ctx_t, (st))
+#define sk_walk_ctx_t_new_null() SKM_sk_new_null(walk_ctx_t)
+#define sk_walk_ctx_t_free(st) SKM_sk_free(walk_ctx_t, (st))
+#define sk_walk_ctx_t_num(st) SKM_sk_num(walk_ctx_t, (st))
+#define sk_walk_ctx_t_value(st, i) SKM_sk_value(walk_ctx_t, (st), (i))
+#define sk_walk_ctx_t_set(st, i, val) SKM_sk_set(walk_ctx_t, (st), (i), (val))
+#define sk_walk_ctx_t_zero(st) SKM_sk_zero(walk_ctx_t, (st))
+#define sk_walk_ctx_t_push(st, val) SKM_sk_push(walk_ctx_t, (st), (val))
+#define sk_walk_ctx_t_unshift(st, val) SKM_sk_unshift(walk_ctx_t, (st), (val))
+#define sk_walk_ctx_t_find(st, val) SKM_sk_find(walk_ctx_t, (st), (val))
+#define sk_walk_ctx_t_find_ex(st, val) SKM_sk_find_ex(walk_ctx_t, (st), (val))
+#define sk_walk_ctx_t_delete(st, i) SKM_sk_delete(walk_ctx_t, (st), (i))
+#define sk_walk_ctx_t_delete_ptr(st, ptr) SKM_sk_delete_ptr(walk_ctx_t, (st), (ptr))
+#define sk_walk_ctx_t_insert(st, val, i) SKM_sk_insert(walk_ctx_t, (st), (val), (i))
+#define sk_walk_ctx_t_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(walk_ctx_t, (st), (cmp))
+#define sk_walk_ctx_t_dup(st) SKM_sk_dup(walk_ctx_t, st)
+#define sk_walk_ctx_t_pop_free(st, free_func) SKM_sk_pop_free(walk_ctx_t, (st), (free_func))
+#define sk_walk_ctx_t_shift(st) SKM_sk_shift(walk_ctx_t, (st))
+#define sk_walk_ctx_t_pop(st) SKM_sk_pop(walk_ctx_t, (st))
+#define sk_walk_ctx_t_sort(st) SKM_sk_sort(walk_ctx_t, (st))
+#define sk_walk_ctx_t_is_sorted(st) SKM_sk_is_sorted(walk_ctx_t, (st))
+
+/*
+ * Safestack macros for rsync_ctx_t.
+ */
+#define sk_rsync_ctx_t_new(st) SKM_sk_new(rsync_ctx_t, (st))
+#define sk_rsync_ctx_t_new_null() SKM_sk_new_null(rsync_ctx_t)
+#define sk_rsync_ctx_t_free(st) SKM_sk_free(rsync_ctx_t, (st))
+#define sk_rsync_ctx_t_num(st) SKM_sk_num(rsync_ctx_t, (st))
+#define sk_rsync_ctx_t_value(st, i) SKM_sk_value(rsync_ctx_t, (st), (i))
+#define sk_rsync_ctx_t_set(st, i, val) SKM_sk_set(rsync_ctx_t, (st), (i), (val))
+#define sk_rsync_ctx_t_zero(st) SKM_sk_zero(rsync_ctx_t, (st))
+#define sk_rsync_ctx_t_push(st, val) SKM_sk_push(rsync_ctx_t, (st), (val))
+#define sk_rsync_ctx_t_unshift(st, val) SKM_sk_unshift(rsync_ctx_t, (st), (val))
+#define sk_rsync_ctx_t_find(st, val) SKM_sk_find(rsync_ctx_t, (st), (val))
+#define sk_rsync_ctx_t_find_ex(st, val) SKM_sk_find_ex(rsync_ctx_t, (st), (val))
+#define sk_rsync_ctx_t_delete(st, i) SKM_sk_delete(rsync_ctx_t, (st), (i))
+#define sk_rsync_ctx_t_delete_ptr(st, ptr) SKM_sk_delete_ptr(rsync_ctx_t, (st), (ptr))
+#define sk_rsync_ctx_t_insert(st, val, i) SKM_sk_insert(rsync_ctx_t, (st), (val), (i))
+#define sk_rsync_ctx_t_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(rsync_ctx_t, (st), (cmp))
+#define sk_rsync_ctx_t_dup(st) SKM_sk_dup(rsync_ctx_t, st)
+#define sk_rsync_ctx_t_pop_free(st, free_func) SKM_sk_pop_free(rsync_ctx_t, (st), (free_func))
+#define sk_rsync_ctx_t_shift(st) SKM_sk_shift(rsync_ctx_t, (st))
+#define sk_rsync_ctx_t_pop(st) SKM_sk_pop(rsync_ctx_t, (st))
+#define sk_rsync_ctx_t_sort(st) SKM_sk_sort(rsync_ctx_t, (st))
+#define sk_rsync_ctx_t_is_sorted(st) SKM_sk_is_sorted(rsync_ctx_t, (st))
+
+/*
+ * Safestack macros for rsync_history_t.
+ */
+#define sk_rsync_history_t_new(st) SKM_sk_new(rsync_history_t, (st))
+#define sk_rsync_history_t_new_null() SKM_sk_new_null(rsync_history_t)
+#define sk_rsync_history_t_free(st) SKM_sk_free(rsync_history_t, (st))
+#define sk_rsync_history_t_num(st) SKM_sk_num(rsync_history_t, (st))
+#define sk_rsync_history_t_value(st, i) SKM_sk_value(rsync_history_t, (st), (i))
+#define sk_rsync_history_t_set(st, i, val) SKM_sk_set(rsync_history_t, (st), (i), (val))
+#define sk_rsync_history_t_zero(st) SKM_sk_zero(rsync_history_t, (st))
+#define sk_rsync_history_t_push(st, val) SKM_sk_push(rsync_history_t, (st), (val))
+#define sk_rsync_history_t_unshift(st, val) SKM_sk_unshift(rsync_history_t, (st), (val))
+#define sk_rsync_history_t_find(st, val) SKM_sk_find(rsync_history_t, (st), (val))
+#define sk_rsync_history_t_find_ex(st, val) SKM_sk_find_ex(rsync_history_t, (st), (val))
+#define sk_rsync_history_t_delete(st, i) SKM_sk_delete(rsync_history_t, (st), (i))
+#define sk_rsync_history_t_delete_ptr(st, ptr) SKM_sk_delete_ptr(rsync_history_t, (st), (ptr))
+#define sk_rsync_history_t_insert(st, val, i) SKM_sk_insert(rsync_history_t, (st), (val), (i))
+#define sk_rsync_history_t_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(rsync_history_t, (st), (cmp))
+#define sk_rsync_history_t_dup(st) SKM_sk_dup(rsync_history_t, st)
+#define sk_rsync_history_t_pop_free(st, free_func) SKM_sk_pop_free(rsync_history_t, (st), (free_func))
+#define sk_rsync_history_t_shift(st) SKM_sk_shift(rsync_history_t, (st))
+#define sk_rsync_history_t_pop(st) SKM_sk_pop(rsync_history_t, (st))
+#define sk_rsync_history_t_sort(st) SKM_sk_sort(rsync_history_t, (st))
+#define sk_rsync_history_t_is_sorted(st) SKM_sk_is_sorted(rsync_history_t, (st))
+
+/*
+ * Safestack macros for task_t.
+ */
+#define sk_task_t_new(st) SKM_sk_new(task_t, (st))
+#define sk_task_t_new_null() SKM_sk_new_null(task_t)
+#define sk_task_t_free(st) SKM_sk_free(task_t, (st))
+#define sk_task_t_num(st) SKM_sk_num(task_t, (st))
+#define sk_task_t_value(st, i) SKM_sk_value(task_t, (st), (i))
+#define sk_task_t_set(st, i, val) SKM_sk_set(task_t, (st), (i), (val))
+#define sk_task_t_zero(st) SKM_sk_zero(task_t, (st))
+#define sk_task_t_push(st, val) SKM_sk_push(task_t, (st), (val))
+#define sk_task_t_unshift(st, val) SKM_sk_unshift(task_t, (st), (val))
+#define sk_task_t_find(st, val) SKM_sk_find(task_t, (st), (val))
+#define sk_task_t_find_ex(st, val) SKM_sk_find_ex(task_t, (st), (val))
+#define sk_task_t_delete(st, i) SKM_sk_delete(task_t, (st), (i))
+#define sk_task_t_delete_ptr(st, ptr) SKM_sk_delete_ptr(task_t, (st), (ptr))
+#define sk_task_t_insert(st, val, i) SKM_sk_insert(task_t, (st), (val), (i))
+#define sk_task_t_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(task_t, (st), (cmp))
+#define sk_task_t_dup(st) SKM_sk_dup(task_t, st)
+#define sk_task_t_pop_free(st, free_func) SKM_sk_pop_free(task_t, (st), (free_func))
+#define sk_task_t_shift(st) SKM_sk_shift(task_t, (st))
+#define sk_task_t_pop(st) SKM_sk_pop(task_t, (st))
+#define sk_task_t_sort(st) SKM_sk_sort(task_t, (st))
+#define sk_task_t_is_sorted(st) SKM_sk_is_sorted(task_t, (st))
+
+#endif /* __RCYNIC_C__DEFSTACK_H__ */
diff --git a/rcynic/rcynic-svn.py b/rcynic/rcynic-svn.py
new file mode 100644
index 00000000..d17e20e1
--- /dev/null
+++ b/rcynic/rcynic-svn.py
@@ -0,0 +1,190 @@
+"""
+Archive rcynic output in a Subversion repository.
+"""
+
+# $Id$
+#
+# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+import subprocess
+import argparse
+import datetime
+import fcntl
+import glob
+import os
+
+try:
+ from lxml.etree import ElementTree
+except ImportError:
+ from xml.etree.ElementTree import ElementTree
+
+
+mime_types = (
+ ("html", "application/xhtml+xml"),
+ ("cer", "application/pkix-cert"),
+ ("crl", "application/pkix-crl"),
+ ("mft", "application/rpki-manifest"),
+ ("mnf", "application/rpki-manifest"),
+ ("roa", "application/rpki-roa"),
+ ("gbr", "application/rpki-ghostbusters"))
+
+
+def run(*cmd, **kwargs):
+ """
+ Run a program, displaying timing data when appropriate.
+ """
+
+ t = datetime.datetime.utcnow()
+ subprocess.check_call(cmd, **kwargs)
+ if args.show_timing:
+ now = datetime.datetime.utcnow()
+ print now, (now - t), " ".join(cmd)
+
+
+def runxml(*cmd):
+ """
+
+ Run a program which produces XML output, displaying timing data when
+ appropriate and returning an ElementTree constructed from the
+ program's output.
+ """
+ t = datetime.datetime.utcnow()
+ p = subprocess.Popen(cmd, stdout = subprocess.PIPE)
+ x = ElementTree(file = p.stdout)
+ s = p.wait()
+ if s:
+ raise subprocess.CalledProcessError(s, cmd[0])
+ if args.show_timing:
+ now = datetime.datetime.utcnow()
+ print now, (now - t), " ".join(cmd)
+ return x
+
+
+# Main program.
+
+parser = argparse.ArgumentParser(description = __doc__)
+
+parser.add_argument("--show_timing", action = "store_true", help = \
+ """
+ Show timing data on programs we run.
+ """)
+
+parser.add_argument("--verbatim", action = "store_true", help = \
+ """
+ Whether to archive rcynic's data output exactly as
+ rcynic writes it or map it into a directory
+ structure which makes more sense when used with
+ Subversion. True means archive exactly as rcynic
+ writes it, interpreting file and directory names
+ as rsync would, transient directories and all.
+ False means map the current authenticated/ tree in
+ rcynic's output to a stable authenticated/ subtree
+ in the subversion repository, with file and
+ directory anmes from the command line shorted to
+ their last component.
+ """)
+
+parser.add_argument("--lockfile", default = "rcynic-svn.lock", help = \
+ """
+ Lock file to to prevent multiple copies of this
+ program (eg, running under cron) from stepping on
+ each other while modifying the working directory.
+ """)
+
+parser.add_argument("files_to_archive", nargs = "*", help = \
+ """
+ Files to archive using Subversion. If omitted, we
+ assume that some other process has already
+ modified the Subversion working directory.
+ """)
+
+parser.add_argument("working_directory", help = \
+ """
+ Subversion working directory to use (must already
+ exist).
+ """)
+
+args = parser.parse_args()
+
+if args.show_timing:
+ t0 = datetime.datetime.utcnow()
+ print t0, "Starting"
+
+# Lock out other instances of this program. We may want some more
+# sophsiticated approach when combining this with other programs, but
+# this should minimize the risk of multiple copies of this program
+# trying to modify the same subversion working directory at the same
+# time and messing each other up. We leave the lock file in place
+# because doing so removes a potential race condition.
+
+lock = os.open("cronjob.lock", os.O_RDONLY | os.O_CREAT | os.O_NONBLOCK, 0666)
+fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
+
+# Make sure working tree is up to date.
+
+run("svn", "update", "--quiet", args.working_directory)
+
+# Copy rcynic's output as appropriate.
+
+if args.files_to_archive:
+
+ if args.verbatim:
+ cmd = ["rsync", "--archive", "--quiet", "--delete"]
+ cmd.extend(args.files_to_archive)
+ cmd.append(args.working_directory)
+ run(*cmd)
+
+ else:
+ for src in args.files_to_archive:
+ cmd = ["rsync", "--archive", "--quiet", "--delete", "--copy-links"]
+ cmd.append(src.rstrip("/"))
+ cmd.append(args.working_directory.rstrip("/") + "/")
+ run(*cmd)
+
+# Ask Subversion to add any new files, trying hard to get the MIME
+# types right.
+
+cmd = ["svn", "add", "--quiet", "--force", "--auto-props"]
+
+for fn2, mime_type in mime_types:
+ cmd.append("--config-option")
+ cmd.append("config:auto-props:*.%s=svn:mime-type=%s" % (fn2, mime_type))
+
+cmd.append(".")
+
+run(*cmd, cwd = args.working_directory)
+
+# Parse XML version of Subversion's status output to figure out what
+# files have been deleted, and tell Subversion that we deleted them
+# intentionally.
+
+missing = sorted(entry.get("path")
+ for entry in runxml("svn", "status", "--xml", args.working_directory).find("target").findall("entry")
+ if entry.find("wc-status").get("item") == "missing")
+deleted = []
+
+for path in missing:
+ if not any(path.startswith(r) for r in deleted):
+ run("svn", "delete", "--quiet", path)
+ deleted.append(path + "/")
+
+# Commit our changes and update the working tree.
+
+run("svn", "commit", "--quiet", "--message", "Auto update.", args.working_directory)
+run("svn", "update", "--quiet", args.working_directory)
+
+if args.show_timing:
+ now = datetime.datetime.utcnow()
+ print now, now - t0, "total runtime"
diff --git a/rcynic/rcynic.c b/rcynic/rcynic.c
index f06eacec..fd1f7c11 100644
--- a/rcynic/rcynic.c
+++ b/rcynic/rcynic.c
@@ -77,10 +77,12 @@
#include <openssl/asn1t.h>
#include <openssl/cms.h>
+#include <rpki/roa.h>
+#include <rpki/manifest.h>
+
#include "bio_f_linebreak.h"
#include "defstack.h"
-#include "defasn1.h"
#if !defined(FILENAME_MAX) && defined(PATH_MAX) && PATH_MAX > 1024
#define FILENAME_MAX PATH_MAX
@@ -389,8 +391,10 @@ typedef struct validation_status {
uri_t uri;
object_generation_t generation;
time_t timestamp;
- unsigned creation_order;
unsigned char events[(MIB_COUNTER_T_MAX + 7) / 8];
+ short balance;
+ struct validation_status *left_child;
+ struct validation_status *right_child;
} validation_status_t;
DECLARE_STACK_OF(validation_status_t)
@@ -547,7 +551,9 @@ struct rcynic_ctx {
int allow_digest_mismatch, allow_crl_digest_mismatch;
int allow_nonconformant_name, allow_ee_without_signedObject;
int allow_1024_bit_ee_key, allow_wrong_cms_si_attributes;
- unsigned max_select_time, validation_status_creation_order;
+ unsigned max_select_time;
+ validation_status_t *validation_status_in_waiting;
+ validation_status_t *validation_status_root;
log_level_t log_level;
X509_STORE *x509_store;
};
@@ -1056,6 +1062,207 @@ static void validation_status_set_code(validation_status_t *v,
}
/**
+ * validation_status object comparison, for AVL tree rather than
+ * OpenSSL stacks.
+ */
+static int
+validation_status_cmp(const validation_status_t *node,
+ const uri_t *uri,
+ const object_generation_t generation)
+{
+ int cmp = ((int) node->generation) - ((int) generation);
+ if (cmp)
+ return cmp;
+ else
+ return strcmp(uri->s, node->uri.s);
+}
+
+/**
+ * validation_status AVL tree insertion. Adapted from code written by
+ * Paul Vixie and explictly placed in the public domain using examples
+ * from the book: "Algorithms & Data Structures," Niklaus Wirth,
+ * Prentice-Hall, 1986, ISBN 0-13-022005-1. Thanks, Paul!
+ */
+static validation_status_t *
+validation_status_sprout(validation_status_t **node,
+ int *needs_balancing,
+ validation_status_t *new_node)
+{
+#ifdef AVL_DEBUG
+#define AVL_MSG(msg) sprintf(stderr, "AVL_DEBUG: '%s'\n", msg)
+#else
+#define AVL_MSG(msg)
+#endif
+
+ validation_status_t *p1, *p2, *result;
+ int cmp;
+
+ /*
+ * Are we grounded? If so, add the node "here" and set the
+ * rebalance flag, then exit.
+ */
+ if (*node == NULL) {
+ AVL_MSG("Grounded, adding new node");
+ new_node->left_child = NULL;
+ new_node->right_child = NULL;
+ new_node->balance = 0;
+ *node = new_node;
+ *needs_balancing = 1;
+ return *node;
+ }
+
+ /*
+ * Compare the data.
+ */
+ cmp = validation_status_cmp(*node, &new_node->uri, new_node->generation);
+
+ /*
+ * If LESS, prepare to move to the left.
+ */
+ if (cmp < 0) {
+
+ AVL_MSG("LESS. sprouting left.");
+ result = validation_status_sprout(&(*node)->left_child, needs_balancing, new_node);
+
+ if (*needs_balancing) {
+ AVL_MSG("LESS: left branch has grown longer");
+
+ switch ((*node)->balance) {
+
+ case 1:
+ /*
+ * Right branch WAS longer; balance is ok now.
+ */
+ AVL_MSG("LESS: case 1.. balance restored implicitly");
+ (*node)->balance = 0;
+ *needs_balancing = 0;
+ break;
+
+ case 0:
+ /*
+ * Balance WAS okay; now left branch longer.
+ */
+ AVL_MSG("LESS: case 0.. balnce bad but still ok");
+ (*node)->balance = -1;
+ break;
+
+ case -1:
+ /*
+ * Left branch was already too long. Rebalance.
+ */
+ AVL_MSG("LESS: case -1: rebalancing");
+ p1 = (*node)->left_child;
+
+ if (p1->balance == -1) {
+ AVL_MSG("LESS: single LL");
+ (*node)->left_child = p1->right_child;
+ p1->right_child = *node;
+ (*node)->balance = 0;
+ *node = p1;
+ }
+
+ else {
+ AVL_MSG("LESS: double LR");
+
+ p2 = p1->right_child;
+ p1->right_child = p2->left_child;
+ p2->left_child = p1;
+
+ (*node)->left_child = p2->right_child;
+ p2->right_child = *node;
+
+ if (p2->balance == -1)
+ (*node)->balance = 1;
+ else
+ (*node)->balance = 0;
+
+ if (p2->balance == 1)
+ p1->balance = -1;
+ else
+ p1->balance = 0;
+ *node = p2;
+ }
+
+ (*node)->balance = 0;
+ *needs_balancing = 0;
+ }
+ }
+ return result;
+ }
+
+ /*
+ * If MORE, prepare to move to the right.
+ */
+ if (cmp > 0) {
+
+ AVL_MSG("MORE: sprouting to the right");
+ result = validation_status_sprout(&(*node)->right_child, needs_balancing, new_node);
+
+ if (*needs_balancing) {
+ AVL_MSG("MORE: right branch has grown longer");
+
+ switch ((*node)->balance) {
+
+ case -1:AVL_MSG("MORE: balance was off, fixed implicitly");
+ (*node)->balance = 0;
+ *needs_balancing = 0;
+ break;
+
+ case 0: AVL_MSG("MORE: balance was okay, now off but ok");
+ (*node)->balance = 1;
+ break;
+
+ case 1: AVL_MSG("MORE: balance was off, need to rebalance");
+ p1 = (*node)->right_child;
+
+ if (p1->balance == 1) {
+ AVL_MSG("MORE: single RR");
+ (*node)->right_child = p1->left_child;
+ p1->left_child = *node;
+ (*node)->balance = 0;
+ *node = p1;
+ }
+
+ else {
+ AVL_MSG("MORE: double RL");
+
+ p2 = p1->left_child;
+ p1->left_child = p2->right_child;
+ p2->right_child = p1;
+
+ (*node)->right_child = p2->left_child;
+ p2->left_child = *node;
+
+ if (p2->balance == 1)
+ (*node)->balance = -1;
+ else
+ (*node)->balance = 0;
+
+ if (p2->balance == -1)
+ p1->balance = 1;
+ else
+ p1->balance = 0;
+
+ *node = p2;
+ } /*else*/
+ (*node)->balance = 0;
+ *needs_balancing = 0;
+ }
+ }
+ return result;
+ }
+
+ /*
+ * Neither more nor less, found existing node matching key, return it.
+ */
+ AVL_MSG("I found it!");
+ *needs_balancing = 0;
+ return *node;
+
+#undef AVL_DEBUG
+}
+
+/**
* Add a validation status entry to internal log.
*/
static void log_validation_status(rcynic_ctx_t *rc,
@@ -1063,8 +1270,8 @@ static void log_validation_status(rcynic_ctx_t *rc,
const mib_counter_t code,
const object_generation_t generation)
{
- validation_status_t v_, *v = NULL;
- int was_set;
+ validation_status_t *v = NULL;
+ int needs_balancing = 0;
assert(rc && uri && code < MIB_COUNTER_T_MAX && generation < OBJECT_GENERATION_MAX);
@@ -1074,68 +1281,41 @@ static void log_validation_status(rcynic_ctx_t *rc,
if (code == rsync_transfer_skipped && !rc->run_rsync)
return;
- memset(&v_, 0, sizeof(v_));
- v_.uri = *uri;
- v_.generation = generation;
-
- v = sk_validation_status_t_value(rc->validation_status, sk_validation_status_t_find(rc->validation_status, &v_));
- if (v == NULL) {
- if ((v = validation_status_t_new()) == NULL) {
- logmsg(rc, log_sys_err, "Couldn't allocate validation status entry for %s", uri->s);
- return;
- }
- *v = v_;
- v->creation_order = rc->validation_status_creation_order++;
- assert(rc->validation_status_creation_order != 0);
- if (!sk_validation_status_t_push(rc->validation_status, v)) {
- logmsg(rc, log_sys_err, "Couldn't store validation status entry for %s", uri->s);
- free(v);
- return;
- }
+ if (rc->validation_status_in_waiting == NULL &&
+ (rc->validation_status_in_waiting = validation_status_t_new()) == NULL) {
+ logmsg(rc, log_sys_err, "Couldn't allocate validation status entry for %s", uri->s);
+ return;
}
- was_set = validation_status_get_code(v, code);
+ v = rc->validation_status_in_waiting;
+ memset(v, 0, sizeof(*v));
+ v->uri = *uri;
+ v->generation = generation;
+
+ v = validation_status_sprout(&rc->validation_status_root, &needs_balancing, v);
+ if (v == rc->validation_status_in_waiting)
+ rc->validation_status_in_waiting = NULL;
+
+ if (rc->validation_status_in_waiting == NULL &&
+ !sk_validation_status_t_push(rc->validation_status, v)) {
+ logmsg(rc, log_sys_err, "Couldn't store validation status entry for %s", uri->s);
+ return;
+ }
v->timestamp = time(0);
- validation_status_set_code(v, code, 1);
- if (!was_set)
- logmsg(rc, log_verbose, "Recording \"%s\" for %s%s%s",
- (mib_counter_desc[code]
- ? mib_counter_desc[code]
- : X509_verify_cert_error_string(mib_counter_openssl[code])),
- (generation != object_generation_null ? object_generation_label[generation] : ""),
- (generation != object_generation_null ? " " : ""),
- uri->s);
-}
+ if (validation_status_get_code(v, code))
+ return;
-/**
- * Validation status object comparision. While building up the
- * database, we want to do lookups based on URI and generation number.
- */
-static int validation_status_cmp_uri(const validation_status_t * const *a, const validation_status_t * const *b)
-{
- int cmp = strcmp((*a)->uri.s, (*b)->uri.s);
- if (cmp)
- return cmp;
- cmp = (int) ((*a)->generation) - (int) ((*b)->generation);
- if (cmp)
- return cmp;
- return 0;
-}
+ validation_status_set_code(v, code, 1);
-/**
- * Validation status object comparision. When writing out the
- * database, one of our primary consumers has respectfully requested
- * that we write in something approximating the order we traversed, so
- * we regenerate that order using the "order" field added for just
- * that purpose when creating these objects.
- */
-static int validation_status_cmp_creation_order(const validation_status_t * const *a, const validation_status_t * const *b)
-{
- int cmp = (*a)->creation_order - (*b)->creation_order;
- assert(cmp != 0 || a == b);
- return cmp;
+ logmsg(rc, log_verbose, "Recording \"%s\" for %s%s%s",
+ (mib_counter_desc[code]
+ ? mib_counter_desc[code]
+ : X509_verify_cert_error_string(mib_counter_openssl[code])),
+ (generation != object_generation_null ? object_generation_label[generation] : ""),
+ (generation != object_generation_null ? " " : ""),
+ uri->s);
}
/**
@@ -1220,6 +1400,22 @@ static int install_object(rcynic_ctx_t *rc,
}
/**
+ * AVL tree lookup for validation status objects.
+ */
+static validation_status_t *
+validation_status_find(validation_status_t *node,
+ const uri_t *uri,
+ const object_generation_t generation)
+{
+ int cmp;
+
+ while (node != NULL && (cmp = validation_status_cmp(node, uri, generation)) != 0)
+ node = cmp < 0 ? node->left_child : node->right_child;
+
+ return node;
+}
+
+/**
* Figure out whether we already have a good copy of an object. This
* is a little more complicated than it sounds, because we might have
* failed the current generation and accepted the backup due to having
@@ -1235,9 +1431,8 @@ static int skip_checking_this_object(rcynic_ctx_t *rc,
const uri_t *uri,
const object_generation_t generation)
{
- validation_status_t v_, *v = NULL;
+ validation_status_t *v = NULL;
path_t path;
- int i;
assert(rc && uri && rc->validation_status);
@@ -1252,12 +1447,7 @@ static int skip_checking_this_object(rcynic_ctx_t *rc,
if (generation != object_generation_current)
return 1;
- memset(&v_, 0, sizeof(v_));
- v_.uri = *uri;
- v_.generation = generation;
-
- i = sk_validation_status_t_find(rc->validation_status, &v_);
- v = sk_validation_status_t_value(rc->validation_status, i);
+ v = validation_status_find(rc->validation_status_root, uri, generation);
if (v != NULL && validation_status_get_code(v, object_accepted))
return 1;
@@ -4800,9 +4990,6 @@ static int write_xml_file(const rcynic_ctx_t *rc,
if (ok)
ok &= fprintf(f, " </labels>\n") != EOF;
- (void) sk_validation_status_t_set_cmp_func(rc->validation_status, validation_status_cmp_creation_order);
- sk_validation_status_t_sort(rc->validation_status);
-
for (i = 0; ok && i < sk_validation_status_t_num(rc->validation_status); i++) {
validation_status_t *v = sk_validation_status_t_value(rc->validation_status, i);
assert(v);
@@ -5142,7 +5329,7 @@ int main(int argc, char *argv[])
goto done;
}
- if ((rc.validation_status = sk_validation_status_t_new(validation_status_cmp_uri)) == NULL) {
+ if ((rc.validation_status = sk_validation_status_t_new_null()) == NULL) {
logmsg(&rc, log_sys_err, "Couldn't allocate validation_status stack");
goto done;
}
@@ -5360,6 +5547,7 @@ int main(int argc, char *argv[])
*/
sk_validation_status_t_pop_free(rc.validation_status, validation_status_t_free);
sk_rsync_history_t_pop_free(rc.rsync_history, rsync_history_t_free);
+ validation_status_t_free(rc.validation_status_in_waiting);
X509_STORE_free(rc.x509_store);
NCONF_free(cfg_handle);
CONF_modules_free();
diff --git a/rcynic/validation_status.awk b/rcynic/validation_status.awk
deleted file mode 100755
index 92012595..00000000
--- a/rcynic/validation_status.awk
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/awk -f
-
-# $Id$
-#
-# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-# Prettyprint output of validation_status.xsl
-
-BEGIN {
- FS = "\t";
- cmd = "xsltproc validation_status.xsl";
- if (ARGC == 1)
- cmd = cmd " -";
- else
- for (i = 1; i < ARGC; ++i)
- cmd = cmd " " ARGV[i];
- while ((cmd | getline) > 0)
- printf "%s %8s %-40s %s\n", $1, $4, $2, $3;
- close(cmd);
-}