Unclutters lots of argument lists.
Also delete the prefix*_contains functions. Weren't being used.
rpki_validator_SOURCES += common.h common.c
rpki_validator_SOURCES += debug.h debug.c
rpki_validator_SOURCES += file.h file.c
-rpki_validator_SOURCES += filename_stack.h filename_stack.c
rpki_validator_SOURCES += line_file.h line_file.c
rpki_validator_SOURCES += log.h log.c
rpki_validator_SOURCES += resource.h resource.c
rpki_validator_SOURCES += sorted_array.h sorted_array.c
rpki_validator_SOURCES += state.h state.c
+rpki_validator_SOURCES += thread_var.h thread_var.c
rpki_validator_SOURCES += asn1/content_info.h asn1/content_info.c
rpki_validator_SOURCES += asn1/decode.h asn1/decode.c
return 0;
}
-
-bool
-prefix4_contains(const struct ipv4_prefix *a, const struct ipv4_prefix *b)
-{
- uint32_t maskbits;
- uint32_t a_bits;
- uint32_t b_bits;
-
- if (a->len > b->len)
- return false;
-
- maskbits = ((uint64_t) 0xffffffffU) << (32 - a->len);
- a_bits = ntohl(a->addr.s_addr) & maskbits;
- b_bits = ntohl(b->addr.s_addr) & maskbits;
-
- return a_bits == b_bits;
-}
-
-bool
-prefix6_contains(const struct ipv6_prefix *a, const struct ipv6_prefix *b)
-{
- struct in6_addr a2;
- struct in6_addr b2;
- unsigned int quadrant;
- uint32_t mask;
- unsigned int i;
-
- if (a->len > b->len)
- return false;
-
- memcpy(&a2, &a->addr, sizeof(a2));
- memcpy(&b2, &b->addr, sizeof(b2));
-
- /* Zeroize the suffixes of a2 and b2 */
- quadrant = a->len >> 5; /* ">> 5" is the same as "/ 32" */
- if (quadrant > 3)
- quadrant = 3;
- mask = ((uint64_t) 0xffffffffU) << (32 - (a->len & 0x1f));
- a2.s6_addr32[quadrant] = htonl(ntohl(a2.s6_addr32[quadrant]) & mask);
- b2.s6_addr32[quadrant] = htonl(ntohl(b2.s6_addr32[quadrant]) & mask);
- for (i = quadrant + 1; i < 4; i++) {
- a2.s6_addr32[i] = 0;
- b2.s6_addr32[i] = 0;
- }
-
- /* Finally compare */
- return memcmp(&a2, &b2, sizeof(a2)) == 0;
-}
int range4_decode(IPAddressRange_t *, struct ipv4_range *);
int range6_decode(IPAddressRange_t *, struct ipv6_range *);
-bool prefix4_contains(const struct ipv4_prefix *, const struct ipv4_prefix *);
-bool prefix6_contains(const struct ipv6_prefix *, const struct ipv6_prefix *);
-
#endif /* SRC_ADDRESS_H_ */
}
static int
-handle_sdata_certificate(struct validation *state, ANY_t *any,
- struct resources *res)
+handle_sdata_certificate(ANY_t *any, struct resources *res)
{
const unsigned char *tmp;
X509 *cert;
cert = d2i_X509(NULL, &tmp, any->size);
if (cert == NULL) {
- error = crypto_err(state, "Signed object's 'certificate' element does not decode into a Certificate");
+ error = crypto_err("Signed object's 'certificate' element does not decode into a Certificate");
goto end1;
}
- error = certificate_validate(state, cert, NULL); /* TODO crls */
+ error = certificate_validate(cert, NULL); /* TODO crls */
if (error)
goto end2;
if (res != NULL) {
- error = certificate_get_resources(state, cert, res);
+ error = certificate_get_resources(cert, res);
if (error)
goto end2;
}
}
static int
-validate(struct validation *state, struct SignedData *sdata,
- struct resources *res)
+validate(struct SignedData *sdata, struct resources *res)
{
struct SignerInfo *sinfo;
bool is_digest;
return -EINVAL;
}
- error = handle_sdata_certificate(state,
- sdata->certificates->list.array[0], res);
+ error = handle_sdata_certificate(sdata->certificates->list.array[0],
+ res);
if (error)
return error;
}
int
-signed_data_decode(struct validation *state, ANY_t *coded,
- struct SignedData **result, struct resources *res)
+signed_data_decode(ANY_t *coded, struct SignedData **result,
+ struct resources *res)
{
struct SignedData *sdata;
int error;
if (error)
return error;
- error = validate(state, sdata, res);
+ error = validate(sdata, res);
if (error) {
signed_data_free(sdata);
return error;
#include <libcmscodec/SignedData.h>
#include "resource.h"
-#include "state.h"
-int signed_data_decode(struct validation *, ANY_t *, struct SignedData **,
- struct resources *);
+int signed_data_decode(ANY_t *, struct SignedData **, struct resources *);
void signed_data_free(struct SignedData *);
int get_content_type_attr(struct SignedData *, OBJECT_IDENTIFIER_t **);
#include "common.h"
#include <errno.h>
+#include <string.h>
#include "log.h"
char const *repository;
+++ /dev/null
-#ifndef SRC_FILENAME_STACK_H_
-#define SRC_FILENAME_STACK_H_
-
-void fnstack_init(void);
-void fnstack_store(void);
-
-void fnstack_push(char const *);
-char const *fnstack_peek(void);
-void fnstack_pop(void);
-
-#endif /* SRC_FILENAME_STACK_H_ */
#include <openssl/bio.h>
#include <openssl/err.h>
-#include "filename_stack.h"
+#include "thread_var.h"
#define STDOUT stdout
#define STDERR stderr
pr_indent(STDERR);
}
+#define PR_ERR(args) do { \
+ pr_err_prefix(); \
+ pr_file_name(STDERR); \
+ \
+ va_start(args, format); \
+ vfprintf(STDERR, format, args); \
+ va_end(args); \
+ fprintf(STDERR, "\n"); \
+} while (0)
+
/**
* Always appends a newline at the end.
*/
pr_err(const char *format, ...)
{
va_list args;
-
- pr_err_prefix();
- pr_file_name(STDERR);
-
- va_start(args, format);
- vfprintf(STDERR, format, args);
- va_end(args);
- fprintf(STDERR, "\n");
+ PR_ERR(args);
}
/**
* Always appends a newline at the end.
*/
int
-crypto_err(struct validation *state, const char *format, ...)
+crypto_err(const char *format, ...)
{
+ struct validation *state;
BIO *bio;
+ bool bio_needs_free;
char const *file;
va_list args;
int error;
- bio = validation_stderr(state);
+ error = ERR_GET_REASON(ERR_peek_last_error());
+ bio = NULL;
+ bio_needs_free = false;
+
+ state = state_retrieve();
+ if (state != NULL)
+ bio = validation_stderr(state);
+ if (bio == NULL) {
+ bio = BIO_new_fp(stderr, BIO_NOCLOSE);
+ if (bio == NULL)
+ goto trainwreck;
+ bio_needs_free = true;
+ }
file = fnstack_peek();
BIO_printf(bio, "%s: ", (file != NULL) ? file : "(Unknown file)");
- error = ERR_GET_REASON(ERR_peek_last_error());
-
va_start(args, format);
BIO_vprintf(bio, format, args);
va_end(args);
}
BIO_printf(bio, "\n");
+ if (bio_needs_free)
+ BIO_free_all(bio);
return error;
+
+trainwreck:
+ /* Fall back to behave just like pr_err(). */
+ PR_ERR(args);
+
+ pr_err_prefix();
+ pr_file_name(STDERR);
+ fprintf(STDERR, "(Cannot print libcrypto error: Failed to initialise standard error's BIO.)\n");
+
+ return error ? error : -EINVAL;
}
#ifndef SRC_LOG_H_
#define SRC_LOG_H_
-#include "state.h"
-
void pr_debug(const char *, ...);
void pr_debug_add(const char *, ...);
void pr_debug_rm(const char *, ...);
void pr_err(const char *, ...);
int pr_errno(int, const char *, ...);
-int crypto_err(struct validation *, const char *, ...);
+int crypto_err(const char *, ...);
#define PR_DEBUG printf("%s:%d (%s())\n", __FILE__, __LINE__, __func__)
#define PR_DEBUG_MSG(msg, ...) printf("%s:%d (%s()): " msg "\n", \
#include "common.h"
#include "debug.h"
#include "log.h"
-#include "filename_stack.h"
+#include "thread_var.h"
#include "object/certificate.h"
#include "object/tal.h"
}
fnstack_push(uri);
- error = certificate_traverse(state, validation_peek_cert(state));
+ error = certificate_traverse(validation_peek_cert(state));
fnstack_pop();
end2:
}
add_rpki_oids();
- fnstack_init();
+ thvar_init();
fnstack_store();
fnstack_push(argv[2]);
#include "common.h"
#include "log.h"
#include "manifest.h"
+#include "thread_var.h"
#include "asn1/decode.h"
/*
}
static int
-validate_public_key(struct validation *state, X509 *cert)
+validate_public_key(X509 *cert)
{
X509_PUBKEY *pubkey;
ASN1_OBJECT *algorithm;
pubkey = X509_get_X509_PUBKEY(cert);
if (pubkey == NULL) {
- crypto_err(state, "X509_get_X509_PUBKEY() returned NULL.");
+ crypto_err("X509_get_X509_PUBKEY() returned NULL.");
return -EINVAL;
}
ok = X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, pubkey);
if (!ok) {
- crypto_err(state, "X509_PUBKEY_get0_param() returned %d.", ok);
+ crypto_err("X509_PUBKEY_get0_param() returned %d.", ok);
return -EINVAL;
}
}
static int
-rfc6487_validate(struct validation *state, X509 *cert)
+rfc6487_validate(X509 *cert)
{
int error;
/* libcrypto already does this. */
/* rfc6487#section-4.7 */
- error = validate_public_key(state, cert);
+ error = validate_public_key(cert);
if (error)
return error;
}
int
-certificate_load(struct validation *state, const char *file, X509 **result)
+certificate_load(const char *file, X509 **result)
{
X509 *cert = NULL;
BIO *bio;
bio = BIO_new(BIO_s_file());
if (bio == NULL)
- return crypto_err(state, "BIO_new(BIO_s_file()) returned NULL");
+ return crypto_err("BIO_new(BIO_s_file()) returned NULL");
if (BIO_read_filename(bio, file) <= 0) {
- error = crypto_err(state, "Error reading certificate");
+ error = crypto_err("Error reading certificate");
goto abort1;
}
cert = d2i_X509_bio(bio, NULL);
if (cert == NULL) {
- error = crypto_err(state, "Error parsing certificate");
+ error = crypto_err("Error parsing certificate");
goto abort1;
}
- error = rfc6487_validate(state, cert);
+ error = rfc6487_validate(cert);
if (error)
goto abort2;
}
int
-certificate_validate(struct validation *state, X509 *cert,
- STACK_OF(X509_CRL) *crls)
+certificate_validate(X509 *cert, STACK_OF(X509_CRL) *crls)
{
/*
* TODO
* So, just in case, enable -no-CAfile and -no-CApath.
*/
+ struct validation *state;
X509_STORE_CTX *ctx;
int ok;
int error;
+ state = state_retrieve();
+ if (state == NULL)
+ return -EINVAL;
+
ctx = X509_STORE_CTX_new();
if (ctx == NULL) {
- crypto_err(state, "X509_STORE_CTX_new() returned NULL");
+ crypto_err("X509_STORE_CTX_new() returned NULL");
return -EINVAL;
}
/* Returns 0 or 1 , all callers test ! only. */
ok = X509_STORE_CTX_init(ctx, validation_store(state), cert, NULL);
if (!ok) {
- crypto_err(state, "X509_STORE_CTX_init() returned %d", ok);
+ crypto_err("X509_STORE_CTX_init() returned %d", ok);
goto abort;
}
* That said, there's not much to do about !error,
* so hope for the best.
*/
- crypto_err(state, "Certificate validation failed: %d",
- ok);
+ crypto_err("Certificate validation failed: %d", ok);
}
goto abort;
}
static int
-handle_ip_extension(struct validation *state, X509_EXTENSION *ext,
- struct resources *resources)
+handle_ip_extension(X509_EXTENSION *ext, struct resources *resources)
{
ASN1_OCTET_STRING *string;
struct IPAddrBlocks *blocks;
* Each SEQUENCE MUST be ordered by ascending addressFamily values.
*/
for (i = 0; i < blocks->list.count; i++) {
- error = resources_add_ip(resources, blocks->list.array[i],
- validation_peek_resource(state));
+ error = resources_add_ip(resources, blocks->list.array[i]);
if (error)
break;
}
}
static int
-handle_asn_extension(struct validation *state, X509_EXTENSION *ext,
- struct resources *resources)
+handle_asn_extension(X509_EXTENSION *ext, struct resources *resources)
{
ASN1_OCTET_STRING *string;
struct ASIdentifiers *ids;
if (error)
return error;
- error = resources_add_asn(resources, ids,
- validation_peek_resource(state));
+ error = resources_add_asn(resources, ids);
ASN_STRUCT_FREE(asn_DEF_ASIdentifiers, ids);
return error;
}
int
-certificate_get_resources(struct validation *state, X509 *cert,
- struct resources *resources)
+certificate_get_resources(X509 *cert, struct resources *resources)
{
X509_EXTENSION *ext;
int i;
switch (OBJ_obj2nid(X509_EXTENSION_get_object(ext))) {
case NID_sbgp_ipAddrBlock:
pr_debug_add("IP {");
- error = handle_ip_extension(state, ext, resources);
+ error = handle_ip_extension(ext, resources);
pr_debug_rm("}");
break;
case NID_sbgp_autonomousSysNum:
pr_debug_add("ASN {");
- error = handle_asn_extension(state, ext, resources);
+ error = handle_asn_extension(ext, resources);
pr_debug_rm("}");
break;
}
return error;
}
-int certificate_traverse(struct validation *state, X509 *cert)
+int certificate_traverse(X509 *cert)
{
SIGNATURE_INFO_ACCESS *sia;
ACCESS_DESCRIPTION *ad;
error = gn_g2l(ad->location, &uri);
if (error)
goto end;
- error = handle_manifest(state, uri);
+ error = handle_manifest(uri);
free(uri);
if (error)
goto end;
#include <stdbool.h>
#include <openssl/x509.h>
#include "resource.h"
-#include "state.h"
bool is_certificate(char const *);
-int certificate_load(struct validation *, const char *, X509 **);
+int certificate_load(const char *, X509 **);
/*
* Note: You actually need all three of these functions for a full validation;
* you will need certificate_traverse() to walk through the children.
*/
-int certificate_validate(struct validation *, X509 *, STACK_OF(X509_CRL) *);
-int certificate_get_resources(struct validation *, X509 *, struct resources *);
-int certificate_traverse(struct validation *, X509 *);
+int certificate_validate(X509 *, STACK_OF(X509_CRL) *);
+int certificate_get_resources(X509 *, struct resources *);
+int certificate_traverse(X509 *);
#endif /* SRC_OBJECT_CERTIFICATE_H_ */
#include "log.h"
static int
-__crl_load(struct validation *state, const char *file, X509_CRL **result)
+__crl_load(const char *file, X509_CRL **result)
{
X509_CRL *crl = NULL;
BIO *bio;
bio = BIO_new(BIO_s_file());
if (bio == NULL)
- return crypto_err(state, "BIO_new(BIO_s_file()) returned NULL");
+ return crypto_err("BIO_new(BIO_s_file()) returned NULL");
if (BIO_read_filename(bio, file) <= 0) {
- error = crypto_err(state, "Error reading CRL '%s'", file);
+ error = crypto_err("Error reading CRL '%s'", file);
goto end;
}
crl = d2i_X509_CRL_bio(bio, NULL);
if (crl == NULL) {
- error = crypto_err(state, "Error parsing CRL '%s'", file);
+ error = crypto_err("Error parsing CRL '%s'", file);
goto end;
}
}
int
-crl_load(struct validation *state, char const *file, X509_CRL **result)
+crl_load(char const *file, X509_CRL **result)
{
int error;
pr_debug_add("CRL {");
- error = __crl_load(state, file, result);
+ error = __crl_load(file, result);
pr_debug_rm("}");
return error;
#define SRC_OBJECT_CRL_H_
#include <openssl/x509.h>
-#include "state.h"
-int crl_load(struct validation *, char const *, X509_CRL **);
+int crl_load(char const *, X509_CRL **);
#endif /* SRC_OBJECT_CRL_H_ */
#include <libcmscodec/GeneralizedTime.h>
#include <libcmscodec/Manifest.h>
-#include "filename_stack.h"
#include "log.h"
#include "asn1/oid.h"
+#include "thread_var.h"
#include "object/certificate.h"
#include "object/crl.h"
#include "object/roa.h"
return 0;
}
-typedef int (*foreach_cb)(struct validation *, char *, void *);
+typedef int (*foreach_cb)(char *, void *);
struct foreach_args {
STACK_OF(X509_CRL) *crls;
};
static int
-foreach_file(struct validation *state, struct manifest *mft, char *extension,
- foreach_cb cb, void *arg)
+foreach_file(struct manifest *mft, char *extension, foreach_cb cb, void *arg)
{
char *uri;
char *luri; /* "Local URI". As in "URI that we can easily reference." */
error = get_relative_file(mft->file_path, uri, &luri);
if (error)
return error;
- error = cb(state, luri, arg);
+ error = cb(luri, arg);
free(luri);
if (error)
return error;
}
static int
-pile_crls(struct validation *state, char *file, void *crls)
+pile_crls(char *file, void *crls)
{
X509_CRL *crl;
int error;
fnstack_push(file);
- error = crl_load(state, file, &crl);
+ error = crl_load(file, &crl);
if (error)
goto end;
idx = sk_X509_CRL_push(crls, crl);
if (idx <= 0) {
- error = crypto_err(state, "Could not add CRL to a CRL stack");
+ error = crypto_err("Could not add CRL to a CRL stack");
X509_CRL_free(crl);
goto end;
}
}
static int
-pile_addr_ranges(struct validation *state, char *file, void *__args)
+pile_addr_ranges(char *file, void *__args)
{
struct foreach_args *args = __args;
struct resources *resources;
* (Error messages should have been printed in stderr.)
*/
- if (certificate_load(state, file, &cert))
+ if (certificate_load(file, &cert))
goto end; /* Fine */
- if (certificate_validate(state, cert, args->crls))
+ if (certificate_validate(cert, args->crls))
goto revert; /* Fine */
resources = resources_create();
goto revert;
}
- if (certificate_get_resources(state, cert, resources))
+ if (certificate_get_resources(cert, resources))
goto revert2; /* Fine */
- if (validation_push_cert(state, cert, resources)) {
+ if (validation_push_cert(cert, resources)) {
/*
* Validation_push_cert() only fails on OPENSSL_sk_push().
* The latter really only fails on memory allocation fault.
error = -EINVAL; /* Not fine */
goto revert2;
}
- certificate_traverse(state, cert); /* Error code is useless. */
- validation_pop_cert(state); /* Error code is useless. */
+ certificate_traverse(cert); /* Error code is useless. */
+ validation_pop_cert(); /* Error code is useless. */
error = resources_join(args->resources, resources); /* Not fine */
}
static int
-print_roa(struct validation *state, char *file, void *arg)
+print_roa(char *file, void *arg)
{
/*
* TODO to validate the ROA's cert, the parent cert must not have been
* popped at this point.
*/
- handle_roa(state, file);
+ handle_roa(file);
return 0;
}
static int
-__handle_manifest(struct validation *state, struct manifest *mft)
+__handle_manifest(struct manifest *mft)
{
struct foreach_args args;
int error;
}
/* Get CRLs as a stack. There will usually only be one. */
- error = foreach_file(state, mft, "crl", pile_crls, args.crls);
+ error = foreach_file(mft, "crl", pile_crls, args.crls);
if (error)
goto end;
* Use CRL stack to validate certificates.
* Pile up valid address ranges from the valid certificates.
*/
- error = foreach_file(state, mft, "cer", pile_addr_ranges, &args);
+ error = foreach_file(mft, "cer", pile_addr_ranges, &args);
if (error)
goto end;
/* Use valid address ranges to print ROAs that match them. */
- error = foreach_file(state, mft, "roa", print_roa, &args);
+ error = foreach_file(mft, "roa", print_roa, &args);
end:
resources_destroy(args.resources);
}
int
-handle_manifest(struct validation *state, char const *file_path)
+handle_manifest(char const *file_path)
{
static OID oid = OID_MANIFEST;
struct oid_arcs arcs = OID2ARCS(oid);
* TODO about those NULL resources: Maybe print a warning if the
* certificate contains some.
*/
- error = signed_object_decode(state, file_path, &asn_DEF_Manifest, &arcs,
+ error = signed_object_decode(file_path, &asn_DEF_Manifest, &arcs,
(void **) &mft.obj, NULL);
if (error)
goto end;
error = validate_manifest(mft.obj);
if (!error)
- error = __handle_manifest(state, &mft);
+ error = __handle_manifest(&mft);
ASN_STRUCT_FREE(asn_DEF_Manifest, mft.obj);
end:
#ifndef SRC_OBJECT_MANIFEST_H_
#define SRC_OBJECT_MANIFEST_H_
-#include "state.h"
-
-int handle_manifest(struct validation *, char const *);
+int handle_manifest(char const *);
#endif /* SRC_OBJECT_MANIFEST_H_ */
#include <arpa/inet.h>
#include <libcmscodec/RouteOriginAttestation.h>
-#include "filename_stack.h"
#include "log.h"
+#include "thread_var.h"
#include "asn1/oid.h"
#include "object/signed_object.h"
return -EINVAL;
}
-int handle_roa(struct validation *state, char const *file)
+int handle_roa(char const *file)
{
static OID oid = OID_ROA;
struct oid_arcs arcs = OID2ARCS(oid);
goto end1;
}
- error = signed_object_decode(state, file,
- &asn_DEF_RouteOriginAttestation, &arcs, (void **) &roa,
- cert_resources);
+ error = signed_object_decode(file, &asn_DEF_RouteOriginAttestation,
+ &arcs, (void **) &roa, cert_resources);
if (error)
goto end2;
error = __handle_roa(roa, cert_resources);
#ifndef SRC_OBJECT_ROA_H_
#define SRC_OBJECT_ROA_H_
-#include "state.h"
-
-int handle_roa(struct validation *, char const *);
+int handle_roa(char const *);
#endif /* SRC_OBJECT_ROA_H_ */
}
int
-signed_object_decode(struct validation *state,
- char const *file,
+signed_object_decode(char const *file,
asn_TYPE_descriptor_t const *descriptor,
struct oid_arcs const *oid,
void **result,
if (error)
goto end1;
- error = signed_data_decode(state, &cinfo->content, &sdata, res);
+ error = signed_data_decode(&cinfo->content, &sdata, res);
if (error)
goto end2;
#include "asn1/oid.h"
#include "resource.h"
-#include "state.h"
-int signed_object_decode(struct validation *, char const *,
- asn_TYPE_descriptor_t const *, struct oid_arcs const *, void **,
- struct resources *);
+int signed_object_decode(char const *, asn_TYPE_descriptor_t const *,
+ struct oid_arcs const *, void **, struct resources *);
#endif /* SRC_OBJECT_SIGNED_OBJECT_H_ */
#include "address.h"
#include "log.h"
#include "sorted_array.h"
+#include "thread_var.h"
#include "resource/ip4.h"
#include "resource/ip6.h"
#include "resource/asn.h"
return -1;
}
+static struct resources *
+get_parent_resources(void)
+{
+ struct validation *state = state_retrieve();
+ return (state != NULL) ? validation_peek_resource(state) : NULL;
+}
+
static void
pr_debug_prefix(int family, void *addr, unsigned int length)
{
}
static int
-inherit_aors(struct resources *resources, int family, struct resources *parent)
+inherit_aors(struct resources *resources, int family)
{
+ struct resources *parent;
+
+ parent = get_parent_resources();
+ if (!parent) {
+ pr_err("Certificate inherits IP resources, but parent does not define any resources.");
+ return -EINVAL;
+ }
+
switch (family) {
case AF_INET:
if (resources->ip4s != NULL) {
}
static int
-add_prefix4(struct resources *resources, IPAddress2_t *addr,
- struct resources *parent)
+add_prefix4(struct resources *resources, IPAddress2_t *addr)
{
+ struct resources *parent;
struct ipv4_prefix prefix;
int error;
+ parent = get_parent_resources();
+
if ((parent != NULL) && (resources->ip4s == parent->ip4s)) {
pr_err("Certificate defines IPv4 prefixes while also inheriting his parent's.");
return -EINVAL;
}
static int
-add_prefix6(struct resources *resources, IPAddress2_t *addr,
- struct resources *parent)
+add_prefix6(struct resources *resources, IPAddress2_t *addr)
{
+ struct resources *parent;
struct ipv6_prefix prefix;
int error;
+ parent = get_parent_resources();
+
if ((parent != NULL) && (resources->ip6s == parent->ip6s)) {
pr_err("Certificate defines IPv6 prefixes while also inheriting his parent's.");
return -EINVAL;
}
static int
-add_prefix(struct resources *resources, int family, IPAddress2_t *addr,
- struct resources *parent)
+add_prefix(struct resources *resources, int family, IPAddress2_t *addr)
{
switch (family) {
case AF_INET:
- return add_prefix4(resources, addr, parent);
+ return add_prefix4(resources, addr);
case AF_INET6:
- return add_prefix6(resources, addr, parent);
+ return add_prefix6(resources, addr);
}
pr_err("Programming error: Unknown address family '%d'", family);
}
static int
-add_range4(struct resources *resources, IPAddressRange_t *input,
- struct resources *parent)
+add_range4(struct resources *resources, IPAddressRange_t *input)
{
+ struct resources *parent;
struct ipv4_range range;
int error;
+ parent = get_parent_resources();
+
if ((parent != NULL) && (resources->ip4s == parent->ip4s)) {
pr_err("Certificate defines IPv4 ranges while also inheriting his parent's.");
return -EINVAL;
}
static int
-add_range6(struct resources *resources, IPAddressRange_t *input,
- struct resources *parent)
+add_range6(struct resources *resources, IPAddressRange_t *input)
{
+ struct resources *parent;
struct ipv6_range range;
int error;
+ parent = get_parent_resources();
+
if ((parent != NULL) && (resources->ip6s == parent->ip6s)) {
pr_err("Certificate defines IPv6 ranges while also inheriting his parent's.");
return -EINVAL;
}
static int
-add_range(struct resources *resources, int family, IPAddressRange_t *range,
- struct resources *parent)
+add_range(struct resources *resources, int family, IPAddressRange_t *range)
{
switch (family) {
case AF_INET:
- return add_range4(resources, range, parent);
+ return add_range4(resources, range);
case AF_INET6:
- return add_range6(resources, range, parent);
+ return add_range6(resources, range);
}
pr_err("Programming error: Unknown address family '%d'", family);
static int
add_aors(struct resources *resources, int family,
- struct IPAddressChoice__addressesOrRanges *aors, struct resources *parent)
+ struct IPAddressChoice__addressesOrRanges *aors)
{
struct IPAddressOrRange *aor;
int i;
switch (aor->present) {
case IPAddressOrRange_PR_addressPrefix:
error = add_prefix(resources, family,
- &aor->choice.addressPrefix, parent);
+ &aor->choice.addressPrefix);
if (error)
return error;
break;
case IPAddressOrRange_PR_addressRange:
error = add_range(resources, family,
- &aor->choice.addressRange, parent);
+ &aor->choice.addressRange);
if (error)
return error;
break;
}
int
-resources_add_ip(struct resources *resources, struct IPAddressFamily *obj,
- struct resources *parent)
+resources_add_ip(struct resources *resources, struct IPAddressFamily *obj)
{
int family;
case IPAddressChoice_PR_NOTHING:
break;
case IPAddressChoice_PR_inherit:
- return inherit_aors(resources, family, parent);
+ return inherit_aors(resources, family);
case IPAddressChoice_PR_addressesOrRanges:
return add_aors(resources, family,
- &obj->ipAddressChoice.choice.addressesOrRanges, parent);
+ &obj->ipAddressChoice.choice.addressesOrRanges);
}
/* rfc3779#section-2.2.3.4 */
}
static int
-inherit_asiors(struct resources *resources, struct resources *parent)
+inherit_asiors(struct resources *resources)
{
+ struct resources *parent;
+
+ parent = get_parent_resources();
+ if (!parent) {
+ pr_err("Certificate inherits ASN resources, but parent does not define any resources.");
+ return -EINVAL;
+ }
+
if (resources->asns != NULL) {
pr_err("Certificate inherits ASN resources while also defining others of its own.");
return -EINVAL;
}
static int
-add_asior(struct resources *resources, struct ASIdOrRange *obj,
- struct resources *parent)
+add_asior(struct resources *resources, struct ASIdOrRange *obj)
{
+ struct resources *parent;
+
+ parent = get_parent_resources();
+
if ((parent != NULL) && (resources->asns == parent->asns)) {
pr_err("Certificate defines ASN resources while also inheriting his parent's.");
return -EINVAL;
}
int
-resources_add_asn(struct resources *resources, struct ASIdentifiers *ids,
- struct resources *parent)
+resources_add_asn(struct resources *resources, struct ASIdentifiers *ids)
{
struct ASIdentifierChoice__asIdsOrRanges *iors;
int i;
switch (ids->asnum->present) {
case ASIdentifierChoice_PR_inherit:
- return inherit_asiors(resources, parent);
+ return inherit_asiors(resources);
case ASIdentifierChoice_PR_asIdsOrRanges:
iors = &ids->asnum->choice.asIdsOrRanges;
for (i = 0; i < iors->list.count; i++) {
- error = add_asior(resources, iors->list.array[i],
- parent);
+ error = add_asior(resources, iors->list.array[i]);
if (error)
return error;
}
struct resources *resources_create(void);
void resources_destroy(struct resources *);
-int resources_add_ip(struct resources *, struct IPAddressFamily *,
- struct resources *);
-int resources_add_asn(struct resources *, struct ASIdentifiers *,
- struct resources *);
+int resources_add_ip(struct resources *, struct IPAddressFamily *);
+int resources_add_asn(struct resources *, struct ASIdentifiers *);
bool resources_contains_asn(struct resources *, ASId_t);
bool resources_contains_ipv4(struct resources *, struct ipv4_prefix *);
#include <errno.h>
#include <stdlib.h>
+#include <string.h>
#include "log.h"
struct sorted_array {
#include <errno.h>
#include "log.h"
-#include "filename_stack.h"
+#include "thread_var.h"
#include "object/certificate.h"
/**
* uses it to traverse the tree and keep track of validated data.
*/
struct validation {
- /**
- * Encapsulated standard output.
- * Needed because the crypto library won't write to stdout directly.
- */
- BIO *out;
/**
* Encapsulated standard error.
* Needed because the crypto library won't write to stderr directly.
fnstack_push(root);
- error = certificate_load(result, root, &cert);
+ error = certificate_load(root, &cert);
if (error)
goto abort1;
ok = sk_X509_push(result->trusted, cert);
if (ok <= 0) {
- error = crypto_err(result,
+ error = crypto_err(
"Could not add certificate to trusted stack: %d", ok);
goto abort3;
}
{
struct validation *result;
struct resources *resources;
- int error = -ENOMEM;
+ int error;
result = malloc(sizeof(struct validation));
if (!result)
return -ENOMEM;
- result->out = BIO_new_fp(stdout, BIO_NOCLOSE);
- if (result->out == NULL) {
- fprintf(stderr, "Failed to initialise standard output's BIO.\n");
+ error = state_store(result);
+ if (error)
goto abort1;
- }
+
result->err = BIO_new_fp(stderr, BIO_NOCLOSE);
- if (result->out == NULL) {
+ if (result->err == NULL) {
fprintf(stderr, "Failed to initialise standard error's BIO.\n");
- goto abort2;
+ error = -ENOMEM;
+ goto abort1;
}
result->store = X509_STORE_new();
if (!result->store) {
- error = crypto_err(result, "X509_STORE_new() returned NULL");
- goto abort3;
+ error = crypto_err("X509_STORE_new() returned NULL");
+ goto abort2;
}
X509_STORE_set_verify_cb(result->store, cb);
error = init_trusted(result, root);
if (error)
- goto abort4;
+ goto abort3;
result->rsrcs = restack_create();
if (!result->rsrcs)
- goto abort5;
+ goto abort4;
resources = resources_create();
if (resources == NULL)
- goto abort6;
+ goto abort5;
fnstack_push(root);
- error = certificate_get_resources(result, validation_peek_cert(result),
+ error = certificate_get_resources(validation_peek_cert(result),
resources);
fnstack_pop();
if (error)
- goto abort7;
+ goto abort6;
restack_push(result->rsrcs, resources);
*out = result;
return 0;
-abort7:
- resources_destroy(resources);
abort6:
- restack_destroy(result->rsrcs);
+ resources_destroy(resources);
abort5:
- sk_X509_pop_free(result->trusted, X509_free);
+ restack_destroy(result->rsrcs);
abort4:
- X509_STORE_free(result->store);
+ sk_X509_pop_free(result->trusted, X509_free);
abort3:
- BIO_free_all(result->err);
+ X509_STORE_free(result->store);
abort2:
- BIO_free_all(result->out);
+ BIO_free_all(result->err);
abort1:
free(result);
return error;
sk_X509_pop_free(state->trusted, X509_free);
X509_STORE_free(state->store);
BIO_free_all(state->err);
- BIO_free_all(state->out);
free(state);
}
-BIO *
-validation_stdout(struct validation *state)
-{
- return state->out;
-}
-
BIO *
validation_stderr(struct validation *state)
{
}
int
-validation_push_cert(struct validation *state, X509 *cert,
- struct resources *resources)
+validation_push_cert(X509 *cert, struct resources *resources)
{
+ struct validation *state;
int ok;
+ state = state_retrieve();
+ if (state == NULL)
+ return -EINVAL;
+
ok = sk_X509_push(state->trusted, cert);
if (ok <= 0) {
- crypto_err(state,
- "Could not add certificate to trusted stack: %d", ok);
+ crypto_err("Couldn't add certificate to trusted stack: %d", ok);
return -ENOMEM; /* Presumably */
}
}
int
-validation_pop_cert(struct validation *state)
+validation_pop_cert(void)
{
+ struct validation *state;
+
+ state = state_retrieve();
+ if (state == NULL)
+ return -EINVAL;
+
if (sk_X509_pop(state->trusted) == NULL) {
- return crypto_err(state,
+ return crypto_err(
"Programming error: Attempted to pop empty cert stack");
}
if (restack_pop(state->rsrcs) == NULL) {
int validation_create(struct validation **, char *);
void validation_destroy(struct validation *);
-BIO *validation_stdout(struct validation *);
BIO *validation_stderr(struct validation *);
X509_STORE *validation_store(struct validation *);
STACK_OF(X509) *validation_certs(struct validation *);
struct restack *validation_resources(struct validation *);
-int validation_push_cert(struct validation *, X509 *, struct resources *);
-int validation_pop_cert(struct validation *);
+int validation_push_cert(X509 *, struct resources *);
+int validation_pop_cert(void);
X509 *validation_peek_cert(struct validation *);
struct resources *validation_peek_resource(struct validation *);
-#include "filename_stack.h"
+#include "thread_var.h"
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
+static pthread_key_t state_key;
static pthread_key_t filenames_key;
struct filename_stack {
free(files);
}
-/** Initializes this module. Call once per runtime lifetime. */
+/** Initializes this entire module. Call once per runtime lifetime. */
void
-fnstack_init(void)
+thvar_init(void)
{
int error;
+ error = pthread_key_create(&state_key, NULL);
+ if (error) {
+ fprintf(stderr,
+ "Fatal: Errcode %d while initializing the validation state thread variable.\n",
+ error);
+ exit(error);
+ }
+
error = pthread_key_create(&filenames_key, fnstack_discard);
if (error) {
fprintf(stderr,
- "Fatal: Errcode %d while attempting to initialize thread variable.\n",
+ "Fatal: Errcode %d while initializing the file name stack thread variable.\n",
error);
exit(error);
}
}
+/* Puts @state in the current thread's variable pool. Call once per thread. */
+int
+state_store(struct validation *state)
+{
+ int error;
+
+ error = pthread_setspecific(state_key, state);
+ if (error)
+ fprintf(stderr, "pthread_setspecific() returned %d.", error);
+
+ return error;
+}
+
+/* Returns the current thread's validation state. */
+struct validation *
+state_retrieve(void)
+{
+ struct validation *state;
+
+ state = pthread_getspecific(state_key);
+ if (state == NULL)
+ fprintf(stderr, "This thread lacks a validation state.\n");
+
+ return state;
+}
+
/** Initializes the current thread's fnstack. Call once per thread. */
void
fnstack_store(void)
files->filenames[files->len++] = get_filename(file_path);
}
+/* Returns the file name on the top of the file name stack. */
char const *
fnstack_peek(void)
{
return files->filenames[files->len - 1];
}
+/* Reverts the last fnstack_push(). */
void
fnstack_pop(void)
{
--- /dev/null
+#ifndef SRC_THREAD_VAR_H_
+#define SRC_THREAD_VAR_H_
+
+#include "state.h"
+
+void thvar_init(void);
+
+int state_store(struct validation *);
+struct validation *state_retrieve(void);
+
+void fnstack_store(void);
+void fnstack_push(char const *);
+char const *fnstack_peek(void);
+void fnstack_pop(void);
+
+#endif /* SRC_THREAD_VAR_H_ */
AM_CFLAGS = -pedantic -Wall -std=gnu11 -I../src ${CHECK_CFLAGS}
MY_LDADD = ${CHECK_LIBS}
-check_PROGRAMS = address.test line_file.test tal.test
+check_PROGRAMS = line_file.test tal.test
TESTS = ${check_PROGRAMS}
-address_test_SOURCES = address_test.c ../src/address.c ../src/address.h
-address_test_LDADD = ${MY_LDADD}
-
line_file_test_SOURCES = line_file_test.c ../src/line_file.c ../src/line_file.h
line_file_test_LDADD = ${MY_LDADD}
+++ /dev/null
-#include "address.h"
-
-#include <check.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-static bool
-p4test(uint32_t a1, unsigned int l1, uint32_t a2, unsigned int l2)
-{
- struct ipv4_prefix a, b;
-
- a.addr.s_addr = htonl(a1);
- a.len = l1;
- b.addr.s_addr = htonl(a2);
- b.len = l2;
-
- return prefix4_contains(&a, &b);
-}
-
-START_TEST(test_prefix4_contains)
-{
- unsigned int i;
-
- /* Prefix-only tests */
-
- ck_assert_int_eq(false, p4test(0x12345678u, 32, 0x12345677u, 32));
- ck_assert_int_eq(true, p4test(0x12345678u, 32, 0x12345678u, 32));
- ck_assert_int_eq(false, p4test(0x12345678u, 32, 0x12345679u, 32));
-
- ck_assert_int_eq(false, p4test(0x01020304u, 30, 0x01020303u, 32));
- ck_assert_int_eq(true, p4test(0x01020304u, 30, 0x01020304u, 32));
- ck_assert_int_eq(true, p4test(0x01020304u, 30, 0x01020305u, 32));
- ck_assert_int_eq(true, p4test(0x01020304u, 30, 0x01020306u, 32));
- ck_assert_int_eq(true, p4test(0x01020304u, 30, 0x01020307u, 32));
- ck_assert_int_eq(false, p4test(0x01020304u, 30, 0x01020308u, 32));
-
- ck_assert_int_eq(true, p4test(0x00000000u, 0, 0x00000000u, 32));
- ck_assert_int_eq(true, p4test(0x00000000u, 0, 0x12345678u, 32));
- ck_assert_int_eq(true, p4test(0x00000000u, 0, 0xFFFFFFFFu, 32));
-
- /* Length-only tests */
-
- for (i = 0; i < 33; i++)
- ck_assert_int_eq(true, p4test(0, i, 0, 32));
- for (i = 0; i < 32; i++)
- ck_assert_int_eq(false, p4test(0, 32, 0, i));
- for (i = 0; i < 33; i++)
- ck_assert_int_eq(true, p4test(0, 0, 0, i));
- for (i = 1; i < 33; i++)
- ck_assert_int_eq(false, p4test(0, i, 0, 0));
-}
-END_TEST
-
-static void
-p6init(struct ipv6_prefix *p, uint32_t q1, uint32_t q2, uint32_t q3,
- uint32_t q4, unsigned int len)
-{
- p->addr.s6_addr32[0] = htonl(q1);
- p->addr.s6_addr32[1] = htonl(q2);
- p->addr.s6_addr32[2] = htonl(q3);
- p->addr.s6_addr32[3] = htonl(q4);
- p->len = len;
-}
-
-START_TEST(test_prefix6_contains)
-{
- struct ipv6_prefix a, b;
-
- p6init(&a, 0, 0, 0, 0, 128);
- p6init(&b, 0, 0, 0, 0, 128);
-
- /* Length-only tests */
-
- for (a.len = 0; a.len < 129; a.len++)
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- a.len = 128;
- for (b.len = 0; b.len < 128; b.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- a.len = 0;
- for (b.len = 0; b.len < 129; b.len++)
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- b.len = 0;
- for (a.len = 1; a.len < 129; a.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- /* Full quadrants */
-
- /* pl = 0 */
- p6init(&a, 0, 0, 0, 0, 0);
- p6init(&b, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 128);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
- /* Others were already tested above. */
-
- /* pl = 32 */
- p6init(&a, 0x13131313u, 0, 0, 0, 32);
- p6init(&b, 0x13131313u, 0, 0, 0, 32);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x13131313u, 0xffffffffu, 0xffffffffu, 0xffffffffu, 128);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x13151313u, 0xffffffffu, 0xffffffffu, 0xffffffffu, 128);
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- /* pl = 64 */
- p6init(&a, 0x13131313u, 0x13131313u, 0, 0, 64);
- p6init(&b, 0x13131313u, 0x13131313u, 0, 0, 64);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x13131313u, 0x13131313u, 0xffffffffu, 0xffffffffu, 128);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x13151313u, 0x13131313u, 0, 0, 128);
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
- p6init(&b, 0x13131313u, 0x13151313u, 0xffffffffu, 0xffffffffu, 128);
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- /* pl = 96 */
- p6init(&a, 0x13131313u, 0x13131313u, 0x13131313u, 0, 96);
- p6init(&b, 0x13131313u, 0x13131313u, 0x13131313u, 0, 96);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x13131313u, 0x13131313u, 0x13131313u, 0xffffffffu, 128);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x13151313u, 0x13131313u, 0x13131313u, 0, 128);
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
- p6init(&b, 0x13131313u, 0x13151313u, 0x13131313u, 0x12345678u, 128);
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
- p6init(&b, 0x13131313u, 0x13131313u, 0x13151313u, 0xffffffffu, 128);
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- /* Try different prefixes in the same quadrant*/
-
- p6init(&a, 0x20010000u, 0, 0, 0, 16);
- p6init(&b, 0x20000000u, 0, 0, 0, 0);
- for (b.len = 0; b.len < 129; b.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- p6init(&a, 0, 0x20010000u, 0, 0, 48);
- p6init(&b, 0, 0x20000000u, 0, 0, 0);
- for (b.len = 0; b.len < 129; b.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- p6init(&a, 0, 0, 0x20010000u, 0, 80);
- p6init(&b, 0, 0, 0x20000000u, 0, 0);
- for (b.len = 0; b.len < 129; b.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- p6init(&a, 0, 0, 0, 0x20010000u, 112);
- p6init(&b, 0, 0, 0, 0x20000000u, 0);
- for (b.len = 0; b.len < 129; b.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- /* Try different prefixes in different quadrants */
-
- /* q2 */
- p6init(&a, 1, 0x20010000u, 0, 0, 48);
- p6init(&b, 0, 0x20010000u, 0, 0, 0);
- for (b.len = 0; b.len < 129; b.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- /* q3 */
- p6init(&a, 1, 0, 0x20010000u, 0, 80);
- p6init(&b, 0, 0, 0x20000000u, 0, 0);
- for (b.len = 0; b.len < 129; b.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- p6init(&a, 0, 1, 0x20010000u, 0, 80);
- for (b.len = 0; b.len < 129; b.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- /* q4 */
- p6init(&a, 1, 0, 0, 0x20010000u, 112);
- p6init(&b, 0, 0, 0, 0x20000000u, 0);
- for (b.len = 0; b.len < 129; b.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- p6init(&a, 0, 1, 0, 0x20010000u, 112);
- for (b.len = 0; b.len < 129; b.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- p6init(&a, 0, 0, 1, 0x20010000u, 112);
- for (b.len = 0; b.len < 129; b.len++)
- ck_assert_int_eq(false, prefix6_contains(&a, &b));
-
- /* Try actually containing prefixes */
-
- /* q1 */
- p6init(&a, 0x20010000u, 0, 0, 0, 16);
- p6init(&b, 0x20010000u, 0, 0, 0, 16);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x2001ffffu, 0, 0, 0, 32);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x2001ffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 128);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- /* q2 */
- p6init(&a, 0x20010000u, 0x20010000u, 0, 0, 48);
- p6init(&b, 0x20010000u, 0x20010000u, 0, 0, 48);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x20010000u, 0x2001ffffu, 0, 0, 64);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x20010000u, 0x2001ffffu, 0xffffffffu, 0xffffffffu, 128);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- /* q3 */
- p6init(&a, 0x20010000u, 0x20010000u, 0x20010000u, 0, 80);
- p6init(&b, 0x20010000u, 0x20010000u, 0x20010000u, 0, 80);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x20010000u, 0x20010000u, 0x2001ffffu, 0, 96);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x20010000u, 0x20010000u, 0x2001ffffu, 0xffffffff, 128);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- /* q4 */
- p6init(&a, 0x20010000u, 0x20010000u, 0x20010000u, 0x20010000, 112);
- p6init(&b, 0x20010000u, 0x20010000u, 0x20010000u, 0x20010000, 112);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-
- p6init(&b, 0x20010000u, 0x20010000u, 0x20010000u, 0x2001ffff, 128);
- ck_assert_int_eq(true, prefix6_contains(&a, &b));
-}
-END_TEST
-
-Suite *lfile_read_suite(void)
-{
- Suite *suite;
- TCase *core;
-
- core = tcase_create("Core");
- tcase_add_test(core, test_prefix6_contains);
- tcase_add_test(core, test_prefix4_contains);
-
- suite = suite_create("address");
- suite_add_tcase(suite, core);
- return suite;
-}
-
-int main(void)
-{
- Suite *suite;
- SRunner *runner;
- int tests_failed;
-
- suite = lfile_read_suite();
-
- runner = srunner_create(suite);
- srunner_run_all(runner, CK_NORMAL);
- tests_failed = srunner_ntests_failed(runner);
- srunner_free(runner);
-
- return (tests_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}