diff options
Diffstat (limited to 'rcynic')
-rw-r--r-- | rcynic/Makefile.in | 22 | ||||
-rw-r--r-- | rcynic/defasn1.h | 140 | ||||
-rw-r--r-- | rcynic/defstack.awk | 71 | ||||
-rw-r--r-- | rcynic/defstack.h | 134 | ||||
-rw-r--r-- | rcynic/rcynic-svn.py | 190 | ||||
-rw-r--r-- | rcynic/rcynic.c | 332 | ||||
-rwxr-xr-x | rcynic/validation_status.awk | 32 |
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); -} |