diff options
Diffstat (limited to 'src/libstrongswan')
37 files changed, 775 insertions, 2150 deletions
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 6fddda20a..a7deeef70 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -30,12 +30,9 @@ crypto/diffie_hellman.c crypto/diffie_hellman.h \ utils/identification.c utils/identification.h \ utils/linked_list.c utils/linked_list.h utils/iterator.h\ utils/randomizer.c utils/randomizer.h \ -utils/logger.c utils/logger.h \ -utils/logger_manager.c utils/logger_manager.h \ utils/host.c utils/host.h \ utils/lexparser.c utils/lexparser.h \ -utils/leak_detective.c utils/leak_detective.h \ -utils/tester.c utils/tester.h +utils/leak_detective.c utils/leak_detective.h libstrongswan_la_LIBADD = -lgmp -lpthread diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c index 0523b8ae8..e9a229d1e 100644 --- a/src/libstrongswan/asn1/asn1.c +++ b/src/libstrongswan/asn1/asn1.c @@ -13,14 +13,14 @@ * for more details. */ -#include <stdlib.h> +#include <stdio.h> #include <string.h> #include <time.h> -#include "types.h" #include "asn1.h" -#include <utils/logger_manager.h> +#include <types.h> +#include <library.h> /* some common prefabricated ASN.1 constants */ static u_char ASN1_INTEGER_0_str[] = { 0x02, 0x00 }; @@ -80,17 +80,6 @@ static const asn1Object_t algorithmIdentifierObjects[] = { #define ALGORITHM_ID_PARAMETERS 2 #define ALGORITHM_ID_ROOF 3 -static logger_t *logger = NULL; - -/** - * initializes the ASN.1 logger - */ -static void asn1_init_logger(void) -{ - if (logger == NULL) - logger = logger_manager->get_logger(logger_manager, ASN1); -} - /** * return the ASN.1 encoded algorithm identifier */ @@ -171,14 +160,14 @@ u_int asn1_length(chunk_t *blob) if (n > blob->len) { - logger->log(logger, ERROR|LEVEL1, "number of length octets is larger than ASN.1 object"); + DBG2("number of length octets is larger than ASN.1 object"); return ASN1_INVALID_LENGTH; } if (n > sizeof(len)) { - logger->log(logger, ERROR|LEVEL1, "number of length octets is larger than limit of %d octets", - (int)sizeof(len)); + DBG2("number of length octets is larger than limit of %d octets", + (int)sizeof(len)); return ASN1_INVALID_LENGTH; } @@ -289,8 +278,6 @@ time_t asn1totime(const chunk_t *utctime, asn1_t type) */ void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit) { - asn1_init_logger(); - ctx->blobs[0] = blob; ctx->level0 = level0; ctx->implicit = implicit; @@ -310,7 +297,7 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type) oid = known_oid(object); if (oid != OID_UNKNOWN) { - logger->log(logger, CONTROL|LEVEL2, " '%s'", oid_names[oid].name); + DBG2(" '%s'", oid_names[oid].name); return; } break; @@ -319,22 +306,18 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type) case ASN1_PRINTABLESTRING: case ASN1_T61STRING: case ASN1_VISIBLESTRING: - logger->log(logger, CONTROL|LEVEL2, " '%.*s'", (int)object.len, object.ptr); + DBG2(" '%.*s'", (int)object.len, object.ptr); return; case ASN1_UTCTIME: case ASN1_GENERALIZEDTIME: { - char buf[TIMETOA_BUF]; - time_t time = asn1totime(&object, type); - - timetoa(buf, TIMETOA_BUF, &time, TRUE); - logger->log(logger, CONTROL|LEVEL2, " '%s'", buf); + DBG2(" '%T'", asn1totime(&object, type)); } return; default: break; } - logger->log_chunk(logger, RAW|LEVEL1, "", object); + DBG3("%B", &object); } /** @@ -372,7 +355,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec if ((obj.flags & ASN1_DEF) && (blob->len == 0 || *start_ptr != obj.type) ) { /* field is missing */ - logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", *level, obj.name); + DBG2("L%d - %s:", *level, obj.name); if (obj.type & ASN1_CONSTRUCTED) { (*objectID)++ ; /* skip context-specific tag */ @@ -397,7 +380,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec if (blob->len < 2) { - logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN.1 object smaller than 2 octets", + DBG2("L%d - %s: ASN.1 object smaller than 2 octets", *level, obj.name); return FALSE; } @@ -406,7 +389,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len) { - logger->log(logger, ERROR|LEVEL1, "L%d - %s: length of ASN.1 object invalid or too large", + DBG2("L%d - %s: length of ASN.1 object invalid or too large", *level, obj.name); return FALSE; } @@ -419,7 +402,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec if (obj.flags & ASN1_RAW) { - logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", *level, obj.name); + DBG2("L%d - %s:", *level, obj.name); object->ptr = start_ptr; object->len = (size_t)(blob->ptr - start_ptr); return TRUE; @@ -427,13 +410,13 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec if (*start_ptr != obj.type && !(ctx->implicit && *objectID == 0)) { - logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x", + DBG1("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x", *level, obj.name, obj.type, *start_ptr); - logger->log_bytes(logger, RAW|LEVEL1, "", start_ptr, (u_int)(blob->ptr - start_ptr)); + DBG3("%b", start_ptr, (u_int)(blob->ptr - start_ptr)); return FALSE; } - logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", ctx->level0+obj.level, obj.name); + DBG2("L%d - %s:", ctx->level0+obj.level, obj.name); /* In case of "SEQUENCE OF" or "SET OF" start a loop */ if (obj.flags & ASN1_LOOP) @@ -458,7 +441,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec { object->ptr = start_ptr; object->len = (size_t)(blob->ptr - start_ptr); - logger->log_chunk(logger, RAW|LEVEL2, "", *object); + DBG3("%B", object); } else if (obj.flags & ASN1_BODY) { @@ -478,15 +461,14 @@ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const c /* an ASN.1 object must possess at least a tag and length field */ if (object->len < 2) { - logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN.1 object smaller than 2 octets", - level, name); + DBG2("L%d - %s: ASN.1 object smaller than 2 octets", level, name); return FALSE; } if (*object->ptr != type) { - logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x", - level, name, type, *object->ptr); + DBG2("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x", + level, name, type, *object->ptr); return FALSE; } @@ -494,12 +476,12 @@ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const c if (len == ASN1_INVALID_LENGTH || object->len < len) { - logger->log(logger, ERROR|LEVEL1, "L%d - %s: length of ASN.1 object invalid or too large", - level, name); + DBG2("L%d - %s: length of ASN.1 object invalid or too large", + level, name); return FALSE; } - logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", level, name); + DBG2("L%d - %s:", level, name); debug_asn1_simple_object(*object, type); return TRUE; } @@ -546,18 +528,16 @@ bool is_asn1(chunk_t blob) { u_int len; u_char tag = *blob.ptr; - - asn1_init_logger(); if (tag != ASN1_SEQUENCE && tag != ASN1_SET) { - logger->log(logger, ERROR|LEVEL2, " file content is not binary ASN.1"); + DBG2(" file content is not binary ASN.1"); return FALSE; } len = asn1_length(&blob); if (len != blob.len) { - logger->log(logger, ERROR|LEVEL2, " file size does not match ASN.1 coded length"); + DBG2(" file size does not match ASN.1 coded length"); return FALSE; } return TRUE; @@ -708,7 +688,7 @@ chunk_t timetoasn1(const time_t *time, asn1_t type) { int offset; const char *format; - char buf[TIMETOA_BUF]; + char buf[32]; chunk_t formatted_time; struct tm *t = gmtime(time); @@ -722,8 +702,8 @@ chunk_t timetoasn1(const time_t *time, asn1_t type) format = "%02d%02d%02d%02d%02d%02dZ"; offset = (t->tm_year < 100)? 0 : -100; } - sprintf(buf, format, t->tm_year + offset, t->tm_mon + 1, t->tm_mday - , t->tm_hour, t->tm_min, t->tm_sec); + snprintf(buf, sizeof(buf), format, t->tm_year + offset, + t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); formatted_time.ptr = buf; formatted_time.len = strlen(buf); return asn1_simple_object(type, formatted_time); diff --git a/src/libstrongswan/asn1/pem.c b/src/libstrongswan/asn1/pem.c index 1cba08fbf..97683e580 100755 --- a/src/libstrongswan/asn1/pem.c +++ b/src/libstrongswan/asn1/pem.c @@ -20,28 +20,18 @@ #include <stddef.h> #include <sys/types.h> -#include "asn1.h" #include "pem.h" -#include "ttodata.h" + +#include <library.h> +#include <asn1/asn1.h> +#include <asn1/ttodata.h> #include <utils/lexparser.h> -#include <utils/logger_manager.h> #include <crypto/hashers/hasher.h> #include <crypto/crypters/crypter.h> #define PKCS5_SALT_LEN 8 /* bytes */ -static logger_t *logger = NULL; - -/** - * initializes the PEM logger - */ -static void pem_init_logger(void) -{ - if (logger == NULL) - logger = logger_manager->get_logger(logger_manager, ASN1); -} - /** * check the presence of a pattern in a character string */ @@ -79,8 +69,7 @@ static bool find_boundary(const char* tag, chunk_t *line) { if (present("-----", line)) { - logger->log(logger, CONTROL|LEVEL2, - " -----%s %.*s-----", tag, (int)name.len, name.ptr); + DBG2(" -----%s %.*s-----", tag, (int)name.len, name.ptr); return TRUE; } line->ptr++; line->len--; name.len++; @@ -185,8 +174,6 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp) iv.ptr = iv_buf; iv.len = 0; - pem_init_logger(); - while (fetchline(&src, &line)) { if (state == PEM_PRE) @@ -222,7 +209,7 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp) } /* we are looking for a parameter: value pair */ - logger->log(logger, CONTROL|LEVEL2, " %.*s", (int)line.len, line.ptr); + DBG2(" %.*s", (int)line.len, line.ptr); ugh = extract_parameter_value(&name, &value, &line); if (ugh != NULL) continue; @@ -289,8 +276,7 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp) *pgp = TRUE; data.ptr++; data.len--; - logger->log(logger, CONTROL|LEVEL2, " Armor checksum: %.*s", - (int)data.len, data.ptr); + DBG2(" Armor checksum: %.*s", (int)data.len, data.ptr); continue; } @@ -327,8 +313,6 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase, FILE *fd = fopen(filename, "r"); - pem_init_logger(); - if (fd) { int bytes; @@ -338,19 +322,19 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase, blob->ptr = malloc(blob->len); bytes = fread(blob->ptr, 1, blob->len, fd); fclose(fd); - logger->log(logger, CONTROL, " loading %s file '%s' (%d bytes)", type, filename, bytes); + DBG1(" loading %s file '%s' (%d bytes)", type, filename, bytes); *pgp = FALSE; /* try DER format */ if (is_asn1(*blob)) { - logger->log(logger, CONTROL|LEVEL1, " file coded in DER format"); + DBG2(" file coded in DER format"); return TRUE; } if (passphrase != NULL) - logger->log_bytes(logger, PRIVATE, " passphrase:", passphrase->ptr, passphrase->len); + DBG4(" passphrase:", passphrase->ptr, passphrase->len); /* try PEM format */ ugh = pem_to_bin(blob, passphrase, pgp); @@ -359,24 +343,24 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase, { if (*pgp) { - logger->log(logger, CONTROL|LEVEL1, " file coded in armored PGP format"); + DBG2(" file coded in armored PGP format"); return TRUE; } if (is_asn1(*blob)) { - logger->log(logger, CONTROL|LEVEL1, " file coded in PEM format"); + DBG2(" file coded in PEM format"); return TRUE; } ugh = "file coded in unknown format, discarded"; } /* a conversion error has occured */ - logger->log(logger, ERROR, " %s", ugh); + DBG1(" %s", ugh); chunk_free(blob); } else { - logger->log(logger, ERROR, " could not open %s file '%s'", type, filename); + DBG1(" could not open %s file '%s'", type, filename); } return FALSE; } diff --git a/src/libstrongswan/crypto/certinfo.c b/src/libstrongswan/crypto/certinfo.c index a289d6562..20a695753 100644 --- a/src/libstrongswan/crypto/certinfo.c +++ b/src/libstrongswan/crypto/certinfo.c @@ -69,24 +69,15 @@ struct private_certinfo_t { crl_reason_t revocationReason; }; -/** - * RFC 2560 OCSP - certificate status - */ -static const char *const cert_status_name[] = { +ENUM(cert_status_names, CERT_GOOD, CERT_UNTRUSTED, "good", "revoked", "unknown", "unknown", - "untrusted" - }; - -enum_names cert_status_names = - { CERT_GOOD, CERT_UNTRUSTED, cert_status_name, NULL}; + "untrusted", +); -/** - * RFC 2459 CRL reason codes - */ -static const char *const crl_reason_name[] = { +ENUM(crl_reason_names, REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL, "unspecified", "key compromise", "ca compromise", @@ -95,11 +86,8 @@ static const char *const crl_reason_name[] = { "cessation of operation", "certificate hold", "reason #7", - "remove from crl" - }; - -enum_names crl_reason_names = - { REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL, crl_reason_name, NULL}; + "remove from crl", +); /** * Implements certinfo_t.get_serialNumber @@ -168,9 +156,9 @@ static void set_revocationReason(private_certinfo_t *this, crl_reason_t reason) /** * Implements certinfo_t.get_revocationReason */ -static const char *get_revocationReason(const private_certinfo_t *this) +static crl_reason_t get_revocationReason(const private_certinfo_t *this) { - return enum_name(&crl_reason_names, this->revocationReason); + return this->revocationReason; } /** @@ -205,7 +193,7 @@ certinfo_t *certinfo_create(chunk_t serial) this->public.set_revocationTime = (void (*) (certinfo_t*,time_t))set_revocationTime; this->public.get_revocationTime = (time_t (*) (const certinfo_t*))get_revocationTime; this->public.set_revocationReason = (void (*) (certinfo_t*, crl_reason_t))set_revocationReason; - this->public.get_revocationReason = (const char *(*) (const certinfo_t*))get_revocationReason; + this->public.get_revocationReason = (crl_reason_t(*) (const certinfo_t*))get_revocationReason; this->public.destroy = (void (*) (certinfo_t*))destroy; return &this->public; diff --git a/src/libstrongswan/crypto/certinfo.h b/src/libstrongswan/crypto/certinfo.h index 45090eafc..6561462a7 100644 --- a/src/libstrongswan/crypto/certinfo.h +++ b/src/libstrongswan/crypto/certinfo.h @@ -29,8 +29,6 @@ /** * RFC 2560 OCSP - certificate status */ -extern enum_names cert_status_names; - typedef enum { CERT_GOOD = 0, CERT_REVOKED = 1, @@ -39,12 +37,11 @@ typedef enum { CERT_UNTRUSTED = 4 /* private use */ } cert_status_t; +extern enum_name_t *cert_status_names; + /** * RFC 2459 CRL reason codes */ - -extern enum_names crl_reason_names; - typedef enum { REASON_UNSPECIFIED = 0, REASON_KEY_COMPROMISE = 1, @@ -56,6 +53,8 @@ typedef enum { REASON_REMOVE_FROM_CRL = 8 } crl_reason_t; +extern enum_name_t *crl_reason_names; + typedef struct certinfo_t certinfo_t; /** @@ -67,85 +66,76 @@ typedef struct certinfo_t certinfo_t; struct certinfo_t { /** - * @brief Get serial number - * - * + * @brief Get serial number. + * * @param this calling object * @return serialNumber */ chunk_t (*get_serialNumber) (const certinfo_t *this); /** - * @brief Set certificate status - * - * + * @brief Set certificate status. + * * @param this calling object * @param status status */ void (*set_status) (certinfo_t *this, cert_status_t status); /** - * @brief Get certificate status - * - * + * @brief Get certificate status. + * * @param this calling object * @return status */ cert_status_t (*get_status) (const certinfo_t *this); /** - * @brief Set nextUpdate - * - * + * @brief Set nextUpdate. + * * @param this calling object * @return nextUpdate */ void (*set_nextUpdate) (certinfo_t *this, time_t nextUpdate); /** - * @brief Get nextUpdate - * - * + * @brief Get nextUpdate. + * * @param this calling object * @return nextUpdate */ time_t (*get_nextUpdate) (const certinfo_t *this); /** - * @brief Set revocationTime - * - * + * @brief Set revocationTime. + * * @param this calling object * @param revocationTime revocationTime */ void (*set_revocationTime) (certinfo_t *this, time_t revocationTime); /** - * @brief Get revocationTime - * - * + * @brief Get revocationTime. + * * @param this calling object * @return revocationTime */ time_t (*get_revocationTime) (const certinfo_t *this); /** - * @brief Set revocationReason - * - * + * @brief Set revocationReason. + * * @param this calling object * @param reason revocationReason */ void (*set_revocationReason) (certinfo_t *this, crl_reason_t reason); /** - * @brief Get revocationReason - * - * + * @brief Get revocationReason. + * * @param this calling object * @return revocationReason */ - const char *(*get_revocationReason) (const certinfo_t *this); + crl_reason_t (*get_revocationReason) (const certinfo_t *this); /** * @brief Destroys the certinfo_t object. diff --git a/src/libstrongswan/crypto/crl.c b/src/libstrongswan/crypto/crl.c index 1f41c0a76..b2c24b80b 100755 --- a/src/libstrongswan/crypto/crl.c +++ b/src/libstrongswan/crypto/crl.c @@ -23,13 +23,14 @@ #include <sys/stat.h> #include <unistd.h> #include <string.h> +#include <printf.h> #include <types.h> +#include <library.h> #include <definitions.h> #include <asn1/oid.h> #include <asn1/asn1.h> #include <asn1/pem.h> -#include <utils/logger_manager.h> #include <utils/linked_list.h> #include <utils/identification.h> @@ -39,7 +40,6 @@ #define CRL_WARNING_INTERVAL 7 /* days */ -static logger_t *logger; extern char* check_expiry(time_t expiration_date, int warning_interval, bool strict); extern time_t parse_time(chunk_t blob, int level0); extern void parse_authorityKeyIdentifier(chunk_t blob, int level0 , chunk_t *authKeyID, chunk_t *authKeySerialNumber); @@ -206,9 +206,9 @@ static crl_reason_t parse_crl_reasonCode(chunk_t object) { reason = *object.ptr; } - logger->log(logger, CONTROL|LEVEL2, " '%s'", enum_name(&crl_reason_names, reason)); + DBG2(" '%N'", crl_reason_names, reason); - return reason; + return reason; } /** @@ -219,7 +219,7 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl) asn1_ctx_t ctx; bool critical; chunk_t extnID; - chunk_t userCertificate; + chunk_t userCertificate = CHUNK_INITIALIZER; revokedCert_t *revokedCert = NULL; chunk_t object; u_int level; @@ -245,14 +245,14 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl) break; case CRL_OBJ_VERSION: crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1; - logger->log(logger, CONTROL|LEVEL2, " v%d", crl->version); + DBG2(" v%d", crl->version); break; case CRL_OBJ_SIG_ALG: crl->sigAlg = parse_algorithmIdentifier(object, level, NULL); break; case CRL_OBJ_ISSUER: crl->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); - logger->log(logger, CONTROL|LEVEL1, " '%D'", crl->issuer); + DBG2(" '%D'", crl->issuer); break; case CRL_OBJ_THIS_UPDATE: crl->thisUpdate = parse_time(object, level); @@ -277,7 +277,7 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl) case CRL_OBJ_CRL_ENTRY_CRITICAL: case CRL_OBJ_CRITICAL: critical = object.len && *object.ptr; - logger->log(logger, CONTROL|LEVEL2, " %s",(critical)?"TRUE":"FALSE"); + DBG2(" %s",(critical)?"TRUE":"FALSE"); break; case CRL_OBJ_CRL_ENTRY_EXTN_VALUE: case CRL_OBJ_EXTN_VALUE: @@ -314,25 +314,22 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl) */ static err_t is_valid(const private_crl_t *this, time_t *until, bool strict) { - char buf[TIMETOA_BUF]; - time_t current_time = time(NULL); - timetoa(buf, BUF_LEN, &this->thisUpdate, TRUE); - logger->log(logger, CONTROL|LEVEL1, " this update : %s", buf); - timetoa(buf, BUF_LEN, ¤t_time, TRUE); - logger->log(logger, CONTROL|LEVEL1, " current time: %s", buf); - timetoa(buf, BUF_LEN, &this->nextUpdate, TRUE); - logger->log(logger, CONTROL|LEVEL1, " next update: %s", buf); - - if (strict && until != NULL - && (*until == UNDEFINED_TIME || this->nextUpdate < *until)) + DBG2(" this update : %T", this->thisUpdate); + DBG2(" current time: %T", current_time); + DBG2(" next update: %T", this->nextUpdate); + + if (strict && until != NULL && + (*until == UNDEFINED_TIME || this->nextUpdate < *until)) { *until = this->nextUpdate; } if (current_time > this->nextUpdate) + { return "has expired"; - logger->log(logger, CONTROL|LEVEL1, " crl is valid", buf); + } + DBG2(" crl is valid"); return NULL; } @@ -437,38 +434,88 @@ static void destroy(private_crl_t *this) } /** - * log crl + * output handler in printf() */ -static void log_crl(const private_crl_t *this, logger_t *logger, bool utc, bool strict) +static int print(FILE *stream, const struct printf_info *info, + const void *const *args) { - identification_t *issuer = this->issuer; - linked_list_t *revokedCertificates = this->revokedCertificates; - - char buf[BUF_LEN]; - - timetoa(buf, BUF_LEN, &this->installed, utc); - logger->log(logger, CONTROL, "%s, revoked certs: %d", - buf, revokedCertificates->get_count(revokedCertificates)); - - logger->log(logger, CONTROL, " issuer: '%D'", issuer); + private_crl_t *this = *((private_crl_t**)(args[0])); + bool utc = TRUE; + int written = 0; + time_t now; - timetoa(buf, BUF_LEN, &this->thisUpdate, utc); - logger->log(logger, CONTROL, " updates: this %s", buf); + if (info->alt) + { + utc = *((bool*)(args[1])); + } - timetoa(buf, BUF_LEN, &this->nextUpdate, utc); - logger->log(logger, CONTROL, " next %s %s", buf, - check_expiry(this->nextUpdate, CRL_WARNING_INTERVAL, strict)); + if (this == NULL) + { + return fprintf(stream, "(null)"); + } + + now = time(NULL); + + written += fprintf(stream, " issuer: %D\n", this->issuer); + written += fprintf(stream, " installed: %#T, revoked certs: %d\n", this->installed, utc, + this->revokedCertificates->get_count(this->revokedCertificates)); + written += fprintf(stream, " updates: this %#T\n", this->thisUpdate, utc); + written += fprintf(stream, " next %#T "); + if (this->nextUpdate == UNDEFINED_TIME) + { + written += fprintf(stream, "ok (expires never)"); + } + else if (now > this->nextUpdate) + { + written += fprintf(stream, "expired (since %V)", now, this->nextUpdate); + } + else if (now > this->nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24) + { + written += fprintf(stream, "ok (expires in %V)", now, this->nextUpdate); + } + else + { + written += fprintf(stream, "ok"); + } + if (this->authKeyID.ptr) + { + written += fprintf(stream, "\n authkey: %#B", &this->authKeyID); + } + if (this->authKeySerialNumber.ptr) + { + written += fprintf(stream, "\n aserial: %#B", &this->authKeySerialNumber); + } + return written; +} - if (this->authKeyID.ptr != NULL) +/** + * arginfo handler in printf() + */ +static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (info->alt) { - chunk_to_hex(buf, BUF_LEN, this->authKeyID); - logger->log(logger, CONTROL, " authkey: %s", buf); + if (n > 1) + { + argtypes[0] = PA_INT; + argtypes[1] = PA_INT; + } + return 2; } - if (this->authKeySerialNumber.ptr != NULL) + + if (n > 0) { - chunk_to_hex(buf, BUF_LEN, this->authKeySerialNumber); - logger->log(logger, CONTROL, " aserial: %s", buf); + argtypes[0] = PA_INT; } + return 1; +} + +/** + * register printf() handlers + */ +static void __attribute__ ((constructor))print_register() +{ + register_printf_function(CRL_PRINTF_SPEC, print, print_arginfo); } /* @@ -494,11 +541,7 @@ crl_t *crl_create_from_chunk(chunk_t chunk) this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer; this->public.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify; this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status; - this->public.log_crl = (void (*) (const crl_t*,logger_t*,bool,bool))log_crl; this->public.destroy = (void (*) (crl_t*))destroy; - - /* we do not use a per-instance logger right now, since its not always accessible */ - logger = logger_manager->get_logger(logger_manager, ASN1); if (!parse_x509crl(chunk, 0, this)) { diff --git a/src/libstrongswan/crypto/crl.h b/src/libstrongswan/crypto/crl.h index e4739fc29..ee9292818 100755 --- a/src/libstrongswan/crypto/crl.h +++ b/src/libstrongswan/crypto/crl.h @@ -29,7 +29,13 @@ #include <crypto/certinfo.h> #include <utils/identification.h> #include <utils/iterator.h> -#include <utils/logger.h> + +/** + * printf specifier for printing crls. When using the + * #-modifier, an additional bool argument defines if times + * are printed in UTC. + */ +#define CRL_PRINTF_SPEC 'U' typedef struct crl_t crl_t; @@ -115,16 +121,6 @@ struct crl_t { * @param this crl to destroy */ void (*destroy) (crl_t *this); - - /** - * @brief Log x509 crl info. - * - * @param this crl to log - * @param logger logger to be used - * @param utc log dates either in UTC or local time - * @param strict expiry of nextUpdate is fatal with strict == TRUE - */ - void (*log_crl) (const crl_t *this, logger_t *logger, bool utc, bool strict); }; /** diff --git a/src/libstrongswan/crypto/crypters/crypter.c b/src/libstrongswan/crypto/crypters/crypter.c index 145138d49..7f62741a7 100644 --- a/src/libstrongswan/crypto/crypters/crypter.c +++ b/src/libstrongswan/crypto/crypters/crypter.c @@ -28,27 +28,25 @@ #include <crypto/crypters/des_crypter.h> -/** - * String mappings for encryption_algorithm_t. - */ -mapping_t encryption_algorithm_m[] = { - {ENCR_UNDEFINED, "UNDEFINED"}, - {ENCR_DES_IV64, "DES_IV64"}, - {ENCR_DES, "DES"}, - {ENCR_3DES, "3DES"}, - {ENCR_RC5, "RC5"}, - {ENCR_IDEA, "IDEA"}, - {ENCR_CAST, "CAST"}, - {ENCR_BLOWFISH, "BLOWFISH"}, - {ENCR_3IDEA, "3IDEA"}, - {ENCR_DES_IV32, "DES_IV32"}, - {ENCR_NULL, "NULL"}, - {ENCR_AES_CBC, "AES_CBC"}, - {ENCR_AES_CTR, "AES_CTR"}, - {MAPPING_END, NULL} -}; +ENUM_BEGIN(encryption_algorithm_names, ENCR_UNDEFINED, ENCR_UNDEFINED, + "UNDEFINED"); +ENUM_NEXT(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32, ENCR_UNDEFINED, + "DES_IV64", + "DES", + "3DES", + "RC5", + "IDEA", + "CAST", + "BLOWFISH", + "3IDEA", + "DES_IV32"); +ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CTR, ENCR_DES_IV32, + "NULL", + "AES_CBC", + "AES_CTR"); +ENUM_END(encryption_algorithm_names, ENCR_AES_CTR); -/* +/* * Described in header. */ crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size) diff --git a/src/libstrongswan/crypto/crypters/crypter.h b/src/libstrongswan/crypto/crypters/crypter.h index ea14157f9..cb7f9b139 100644 --- a/src/libstrongswan/crypto/crypters/crypter.h +++ b/src/libstrongswan/crypto/crypters/crypter.h @@ -57,10 +57,10 @@ enum encryption_algorithm_t { ENCR_AES_CTR = 13 }; -/** - * String mappings for encryption_algorithm_t. +/** + * enum name for encryption_algorithm_t. */ -extern mapping_t encryption_algorithm_m[]; +extern enum_name_t *encryption_algorithm_names; typedef struct crypter_t crypter_t; diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/diffie_hellman.c index fdb508ee9..e4062066c 100644 --- a/src/libstrongswan/crypto/diffie_hellman.c +++ b/src/libstrongswan/crypto/diffie_hellman.c @@ -23,29 +23,26 @@ * for more details. */ -#include <gmp.h> -#include <stdio.h> +#include <gmp.h> +#include <stdio.h> #include "diffie_hellman.h" #include <utils/randomizer.h> - -/** - * String mappings for diffie_hellman_group_t. - */ -mapping_t diffie_hellman_group_m[] = { - {MODP_NONE, "MODP_NONE"}, - {MODP_768_BIT, "MODP_768_BIT"}, - {MODP_1024_BIT, "MODP_1024_BIT"}, - {MODP_1536_BIT, "MODP_1536_BIT"}, - {MODP_2048_BIT, "MODP_2048_BIT"}, - {MODP_3072_BIT, "MODP_3072_BIT"}, - {MODP_4096_BIT, "MODP_4096_BIT"}, - {MODP_6144_BIT, "MODP_6144_BIT"}, - {MODP_8192_BIT, "MODP_8192_BIT"}, - {MAPPING_END, NULL} -}; +ENUM_BEGIN(diffie_hellman_group_names, MODP_NONE, MODP_1024_BIT, + "MODP_NONE", + "MODP_768_BIT", + "MODP_1024_BIT"); +ENUM_NEXT(diffie_hellman_group_names, MODP_1536_BIT, MODP_1536_BIT, MODP_1024_BIT, + "MODP_1536_BIT"); +ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, MODP_8192_BIT, MODP_1536_BIT, + "MODP_2048_BIT", + "MODP_3072_BIT", + "MODP_4096_BIT", + "MODP_6144_BIT", + "MODP_8192_BIT"); +ENUM_END(diffie_hellman_group_names, MODP_8192_BIT); /** diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/diffie_hellman.h index 8edf9e40a..4659c7fee 100644 --- a/src/libstrongswan/crypto/diffie_hellman.h +++ b/src/libstrongswan/crypto/diffie_hellman.h @@ -50,10 +50,10 @@ enum diffie_hellman_group_t { MODP_8192_BIT = 18 }; -/** - * String mappings for diffie_hellman_group_t. +/** + * enum name for diffie_hellman_group_t. */ -extern mapping_t diffie_hellman_group_m[]; +extern enum_name_t *diffie_hellman_group_names; typedef struct diffie_hellman_t diffie_hellman_t; diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c index 444486f9f..7fa6346d6 100644 --- a/src/libstrongswan/crypto/hashers/hasher.c +++ b/src/libstrongswan/crypto/hashers/hasher.c @@ -28,18 +28,15 @@ #include <crypto/hashers/sha2_hasher.h> #include <crypto/hashers/md5_hasher.h> -/** - * String mappings for hash_algorithm_t. - */ -mapping_t hash_algorithm_m[] = { - {HASH_MD2,"HASH_MD2"}, - {HASH_MD5,"HASH_MD5"}, - {HASH_SHA1,"HASH_SHA1"}, - {HASH_SHA256,"HASH_SHA256"}, - {HASH_SHA384,"HASH_SHA384"}, - {HASH_SHA512,"HASH_SHA512"}, - {MAPPING_END, NULL} -}; + +ENUM(hash_algorithm_names, HASH_MD2, HASH_SHA512, + "HASH_MD2", + "HASH_MD5", + "HASH_SHA1", + "HASH_SHA256", + "HASH_SHA384", + "HASH_SHA512" +); /* * Described in header. diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h index ccc8d3eca..ed3defb05 100644 --- a/src/libstrongswan/crypto/hashers/hasher.h +++ b/src/libstrongswan/crypto/hashers/hasher.h @@ -43,17 +43,17 @@ typedef enum hash_algorithm_t hash_algorithm_t; * @ingroup hashers */ enum hash_algorithm_t { - HASH_MD2, + HASH_MD2 = 0, /** Implemented in class md5_hasher_t */ - HASH_MD5, + HASH_MD5 = 1, /** Implemented in class sha1_hasher_t */ - HASH_SHA1, + HASH_SHA1 = 2, /** Implemented in class sha2_hasher_t */ - HASH_SHA256, + HASH_SHA256 = 3, /** Implemented in class sha2_hasher_t */ - HASH_SHA384, + HASH_SHA384 = 4, /** Implemented in class sha2_hasher_t */ - HASH_SHA512, + HASH_SHA512 = 5, }; #define HASH_SIZE_MD2 16 @@ -65,9 +65,9 @@ enum hash_algorithm_t { #define HASH_SIZE_MAX 64 /** - * String mappings for hash_algorithm_t. + * enum names for hash_algorithm_t. */ -extern mapping_t hash_algorithm_m[]; +extern enum_name_t *hash_algorithm_names; typedef struct hasher_t hasher_t; diff --git a/src/libstrongswan/crypto/prfs/prf.c b/src/libstrongswan/crypto/prfs/prf.c index 31b220a84..aa5d1d2b7 100644 --- a/src/libstrongswan/crypto/prfs/prf.c +++ b/src/libstrongswan/crypto/prfs/prf.c @@ -27,18 +27,14 @@ #include <crypto/hashers/hasher.h> #include <crypto/prfs/hmac_prf.h> - -/** - * String mappings for encryption_algorithm_t. - */ -mapping_t pseudo_random_function_m[] = { - {PRF_UNDEFINED, "PRF_UNDEFINED"}, - {PRF_HMAC_MD5, "PRF_HMAC_MD5"}, - {PRF_HMAC_SHA1, "PRF_HMAC_SHA1"}, - {PRF_HMAC_TIGER, "PRF_HMAC_TIGER"}, - {PRF_AES128_CBC, "PRF_AES128_CBC"}, - {MAPPING_END, NULL} -}; +ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_UNDEFINED, + "PRF_UNDEFINED"); +ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_AES128_CBC, PRF_UNDEFINED, + "PRF_HMAC_MD5", + "PRF_HMAC_SHA1", + "PRF_HMAC_TIGER", + "PRF_AES128_CBC"); +ENUM_END(pseudo_random_function_names, PRF_AES128_CBC); /* * Described in header. diff --git a/src/libstrongswan/crypto/prfs/prf.h b/src/libstrongswan/crypto/prfs/prf.h index 2d30cc22e..0a0e0fa5c 100644 --- a/src/libstrongswan/crypto/prfs/prf.h +++ b/src/libstrongswan/crypto/prfs/prf.h @@ -47,10 +47,10 @@ enum pseudo_random_function_t { PRF_AES128_CBC = 4, }; -/** - * String mappings for encryption_algorithm_t. +/** + * enum name for encryption_algorithm_t. */ -extern mapping_t pseudo_random_function_m[]; +extern enum_name_t *pseudo_random_function_names; typedef struct prf_t prf_t; diff --git a/src/libstrongswan/crypto/signers/signer.c b/src/libstrongswan/crypto/signers/signer.c index 67fbbd69a..d6037c545 100644 --- a/src/libstrongswan/crypto/signers/signer.c +++ b/src/libstrongswan/crypto/signers/signer.c @@ -25,19 +25,15 @@ #include <crypto/signers/hmac_signer.h> -/** - * String mappings for integrity_algorithm_t. - */ -mapping_t integrity_algorithm_m[] = { - {AUTH_UNDEFINED, "UNDEFINED"}, - {AUTH_HMAC_MD5_96, "HMAC_MD5_96"}, - {AUTH_HMAC_SHA1_96, "HMAC_SHA1_96"}, - {AUTH_DES_MAC, "DES_MAC"}, - {AUTH_KPDK_MD5, "KPDK_MD5"}, - {AUTH_AES_XCBC_96, "AES_XCBC_96"}, - {MAPPING_END, NULL} -}; - +ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_UNDEFINED, + "UNDEFINED"); +ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_MD5_96, AUTH_AES_XCBC_96, AUTH_UNDEFINED, + "HMAC_MD5_96", + "HMAC_SHA1_96", + "DES_MAC", + "KPDK_MD5", + "AES_XCBC_96"); +ENUM_END(integrity_algorithm_names, AUTH_AES_XCBC_96); /* * Described in header. diff --git a/src/libstrongswan/crypto/signers/signer.h b/src/libstrongswan/crypto/signers/signer.h index 585183998..b7c7af55d 100644 --- a/src/libstrongswan/crypto/signers/signer.h +++ b/src/libstrongswan/crypto/signers/signer.h @@ -49,10 +49,10 @@ enum integrity_algorithm_t { AUTH_AES_XCBC_96 = 5 }; -/** - * String mappings for integrity_algorithm_t. +/** + * enum names for integrity_algorithm_t. */ -extern mapping_t integrity_algorithm_m[]; +extern enum_name_t *integrity_algorithm_names; typedef struct signer_t signer_t; diff --git a/src/libstrongswan/crypto/x509.c b/src/libstrongswan/crypto/x509.c index dd82a493c..4c5e014c8 100755 --- a/src/libstrongswan/crypto/x509.c +++ b/src/libstrongswan/crypto/x509.c @@ -24,22 +24,21 @@ #include <sys/stat.h> #include <unistd.h> #include <string.h> +#include <printf.h> #include "x509.h" #include <types.h> +#include <library.h> #include <definitions.h> #include <asn1/oid.h> #include <asn1/asn1.h> #include <asn1/pem.h> -#include <utils/logger_manager.h> #include <utils/linked_list.h> #include <utils/identification.h> #define CERT_WARNING_INTERVAL 30 /* days */ -static logger_t *logger; - /** * Different kinds of generalNames */ @@ -422,7 +421,7 @@ static bool parse_basicConstraints(chunk_t blob, int level0) if (objectID == BASIC_CONSTRAINTS_CA) { isCA = object.len && *object.ptr; - logger->log(logger, CONTROL|LEVEL2, " %s", isCA ? "TRUE" : "FALSE"); + DBG2(" %s", isCA ? "TRUE" : "FALSE"); } objectID++; } @@ -519,7 +518,7 @@ static identification_t *parse_generalName(chunk_t blob, int level0) if (id_type != ID_ANY) { identification_t *gn = identification_create_from_encoding(id_type, object); - logger->log(logger, CONTROL|LEVEL2, " '%D'", gn); + DBG2(" '%D'", gn); return gn; } objectID++; @@ -670,7 +669,7 @@ static void parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessL { if (asn1_length(&object) == ASN1_INVALID_LENGTH) return; - logger->log(logger, CONTROL|LEVEL2, " '%.*s'",(int)object.len, object.ptr); + DBG2(" '%.*s'",(int)object.len, object.ptr); /* only HTTP(S) URIs accepted */ if (strncasecmp(object.ptr, "http", 4) == 0) { @@ -678,7 +677,7 @@ static void parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessL return; } } - logger->log(logger, ERROR|LEVEL2, "ignoring OCSP InfoAccessLocation with unkown protocol"); + DBG2("ignoring OCSP InfoAccessLocation with unkown protocol"); break; default: /* unkown accessMethod, ignoring */ @@ -779,7 +778,7 @@ bool parse_x509cert(chunk_t blob, u_int level0, private_x509_t *cert) break; case X509_OBJ_VERSION: cert->version = (object.len) ? (1+(u_int)*object.ptr) : 1; - logger->log(logger, CONTROL|LEVEL2, " v%d", cert->version); + DBG2(" v%d", cert->version); break; case X509_OBJ_SERIAL_NUMBER: cert->serialNumber = object; @@ -789,7 +788,7 @@ bool parse_x509cert(chunk_t blob, u_int level0, private_x509_t *cert) break; case X509_OBJ_ISSUER: cert->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); - logger->log(logger, CONTROL|LEVEL1, " '%D'", cert->issuer); + DBG2(" '%D'", cert->issuer); break; case X509_OBJ_NOT_BEFORE: cert->notBefore = parse_time(object, level); @@ -799,12 +798,12 @@ bool parse_x509cert(chunk_t blob, u_int level0, private_x509_t *cert) break; case X509_OBJ_SUBJECT: cert->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object); - logger->log(logger, CONTROL|LEVEL1, " '%D'", cert->subject); + DBG2(" '%D'", cert->subject); break; case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM: if (parse_algorithmIdentifier(object, level, NULL) != OID_RSA_ENCRYPTION) { - logger->log(logger, ERROR|LEVEL1, " unsupported public key algorithm"); + DBG2(" unsupported public key algorithm"); return FALSE; } break; @@ -816,7 +815,7 @@ bool parse_x509cert(chunk_t blob, u_int level0, private_x509_t *cert) } else { - logger->log(logger, ERROR|LEVEL1, " invalid RSA public key format"); + DBG2(" invalid RSA public key format"); return FALSE; } break; @@ -828,7 +827,7 @@ bool parse_x509cert(chunk_t blob, u_int level0, private_x509_t *cert) break; case X509_OBJ_CRITICAL: critical = object.len && *object.ptr; - logger->log(logger, ERROR|LEVEL2, " %s", critical ? "TRUE" : "FALSE"); + DBG2(" %s", critical ? "TRUE" : "FALSE"); break; case X509_OBJ_EXTN_VALUE: { @@ -886,27 +885,26 @@ bool parse_x509cert(chunk_t blob, u_int level0, private_x509_t *cert) */ static err_t is_valid(const private_x509_t *this, time_t *until) { - char buf[TIMETOA_BUF]; - time_t current_time = time(NULL); - timetoa(buf, BUF_LEN, &this->notBefore, TRUE); - logger->log(logger, CONTROL|LEVEL1, " not before : %s", buf); - timetoa(buf, BUF_LEN, ¤t_time, TRUE); - logger->log(logger, CONTROL|LEVEL1, " current time: %s", buf); - timetoa(buf, BUF_LEN, &this->notAfter, TRUE); - logger->log(logger, CONTROL|LEVEL1, " not after : %s", buf); - - if (until != NULL - && (*until == UNDEFINED_TIME || this->notAfter < *until)) + DBG2(" not before : %T", this->notBefore); + DBG2(" current time: %T", current_time); + DBG2(" not after : %T", this->notAfter); + + if (until != NULL && + (*until == UNDEFINED_TIME || this->notAfter < *until)) { *until = this->notAfter; } if (current_time < this->notBefore) + { return "is not valid yet"; + } if (current_time > this->notAfter) + { return "has expired"; - logger->log(logger, CONTROL|LEVEL1, " certificate is valid", buf); + } + DBG2(" certificate is valid"); return NULL; } @@ -1049,153 +1047,165 @@ static bool verify(const private_x509_t *this, const rsa_public_key_t *signer) } /** - * destroy + * output handler in printf() */ -static void destroy(private_x509_t *this) +static int print(FILE *stream, const struct printf_info *info, + const void *const *args) { - identification_t *id; - while (this->subjectAltNames->remove_last(this->subjectAltNames, (void**)&id) == SUCCESS) + private_x509_t *this = *((private_x509_t**)(args[0])); + iterator_t *iterator; + identification_t *san; + chunk_t chunk; + bool utc = TRUE; + int written = 0; + + if (info->alt) { - id->destroy(id); + utc = *((bool*)(args[1])); } - this->subjectAltNames->destroy(this->subjectAltNames); - - while (this->crlDistributionPoints->remove_last(this->crlDistributionPoints, (void**)&id) == SUCCESS) + + if (this == NULL) { - id->destroy(id); + return fprintf(stream, "(null)"); } - this->crlDistributionPoints->destroy(this->crlDistributionPoints); - - if (this->issuer) - this->issuer->destroy(this->issuer); - - if (this->subject) - this->subject->destroy(this->subject); - - if (this->public_key) - this->public_key->destroy(this->public_key); - - free(this->certificate.ptr); - free(this); -} - -/** - * checks if the expiration date has been reached and warns during the - * warning_interval of the imminent expiration. - * strict=TRUE declares a fatal error, strict=FALSE issues a warning upon expiry. - */ -char* check_expiry(time_t expiration_date, int warning_interval, bool strict) -{ - int time_left; + + /* determine the current time */ + time_t now = time(NULL); - if (expiration_date == UNDEFINED_TIME) + written += fprintf(stream, " subject: %D\n", this->subject); + if (this->subjectAltNames->get_count(this->subjectAltNames) > 0) { - return "ok (expires never)"; + written += fprintf(stream, " altNames: "); + iterator = this->subjectAltNames->create_iterator(this->subjectAltNames, TRUE); + while (iterator->iterate(iterator, (void**)&san)) + { + written += fprintf(stream, "%D, ", san); + } + iterator->destroy(iterator); + written += fprintf(stream, "\n"); + } + written += fprintf(stream, " issuer: '%D'\n", this->issuer); + written += fprintf(stream, " serial: '%#B'\n", &this->serialNumber); + written += fprintf(stream, " installed: %#T\n", this->installed, utc); + + written += fprintf(stream, " validity: not before %#T, ", + this->notBefore, utc); + if (now < this->notBefore) + { + written += fprintf(stream, "not valid yet (valid in %V)\n", + now, this->notBefore); } - time_left = (expiration_date - time(NULL)); - if (time_left < 0) + else { - return strict? "fatal (expired)" : "warning (expired)"; + written += fprintf(stream, "ok\n"); } + written += fprintf(stream, " not after %#T, ", + this->notAfter, utc); + if (now > this->notAfter) { - static char buf[35]; - const char* unit = "second"; - - if (time_left > 86400*warning_interval) - return "ok"; - - if (time_left > 172800) - { - time_left /= 86400; - unit = "day"; - } - else if (time_left > 7200) - { - time_left /= 3600; - unit = "hour"; - } - else if (time_left > 120) + written += fprintf(stream, "expired (since %V)\n", now, this->notAfter); + } + else + { + written += fprintf(stream, "ok"); + if (now > this->notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24) { - time_left /= 60; - unit = "minute"; + written += fprintf(stream, " (expires in %V)", now, this->notAfter); } - snprintf(buf, sizeof(buf), "warning (expires in %d %s%s)", time_left, unit, (time_left == 1)?"":"s"); - - /* TODO: This is not thread save and may result in corrupted strings. Rewrite this! */ - return buf; + written += fprintf(stream, " \n"); } -} - -/** - * log certificate - */ -static void log_certificate(const private_x509_t *this, logger_t *logger, bool utc, bool has_key) -{ - identification_t *subject = this->subject; - identification_t *issuer = this->issuer; - rsa_public_key_t *pubkey = this->public_key; - - char buf[BUF_LEN]; - char time_buf[TIMETOA_BUF]; - - /* determine the current time */ - time_t now = time(NULL); - - timetoa(time_buf, TIMETOA_BUF, &this->installed, utc); - logger->log(logger, CONTROL, "%s", time_buf); - logger->log(logger, CONTROL, " subject: '%D'", subject); - logger->log(logger, CONTROL, " issuer: '%D'", issuer); - chunk_to_hex(buf, BUF_LEN, this->serialNumber); - logger->log(logger, CONTROL, " serial: %s", buf); + chunk = this->public_key->get_keyid(this->public_key); + written += fprintf(stream, " keyid: %#B\n", &chunk); + if (this->subjectKeyID.ptr) + { + written += fprintf(stream, " subjkey: %#B\n", &this->subjectKeyID); + } + if (this->authKeyID.ptr) + { + written += fprintf(stream, " authkey: %#B\n", &this->authKeyID); + } + if (this->authKeySerialNumber.ptr) + { + written += fprintf(stream, " aserial: %#B\n", &this->authKeySerialNumber); + } - timetoa(time_buf, TIMETOA_BUF, &this->notBefore, utc); - logger->log(logger, CONTROL, " validity: not before %s %s", time_buf, - (this->notBefore < now)? "ok":"fatal (not valid yet)"); + written += fprintf(stream, " pubkey: RSA %d bits", BITS_PER_BYTE * + this->public_key->get_keysize(this->public_key)); + written += fprintf(stream, ", status %N", + cert_status_names, this->status); - timetoa(time_buf, TIMETOA_BUF, &this->notAfter, utc); - logger->log(logger, CONTROL, " not after %s %s", time_buf, - check_expiry(this->notAfter, CERT_WARNING_INTERVAL, TRUE)); - - timetoa(time_buf, TIMETOA_BUF, &this->until, utc); switch (this->status) { case CERT_GOOD: - snprintf(buf, BUF_LEN, " until %s", time_buf); + written += fprintf(stream, " until %#T", this->until, utc); break; case CERT_REVOKED: - snprintf(buf, BUF_LEN, " on %s", time_buf); + written += fprintf(stream, " on %#T", this->until, utc); break; case CERT_UNKNOWN: case CERT_UNDEFINED: case CERT_UNTRUSTED: default: - *buf = '\0'; + break; } - logger->log(logger, CONTROL, " pubkey: RSA %d bits%s, status %s%s", - BITS_PER_BYTE * pubkey->get_keysize(pubkey), - has_key? ", has private key":"", - enum_name(&cert_status_names, this->status), buf); - - chunk_to_hex(buf, BUF_LEN, pubkey->get_keyid(pubkey)); - logger->log(logger, CONTROL, " keyid: %s", buf); + return written; +} - if (this->subjectKeyID.ptr != NULL) +/** + * arginfo handler in printf() + */ +static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (info->alt) + { + if (n > 1) + { + argtypes[0] = PA_INT; + argtypes[1] = PA_INT; + } + return 2; + } + + if (n > 0) { - chunk_to_hex(buf, BUF_LEN, this->subjectKeyID); - logger->log(logger, CONTROL, " subjkey: %s", buf); + argtypes[0] = PA_INT; } - if (this->authKeyID.ptr != NULL) + return 1; +} + +/** + * register printf() handlers + */ +static void __attribute__ ((constructor))print_register() +{ + register_printf_function(X509_PRINTF_SPEC, print, print_arginfo); +} + +/** + * Implements x509_t.destroy + */ +static void destroy(private_x509_t *this) +{ + identification_t *id; + while (this->subjectAltNames->remove_last(this->subjectAltNames, (void**)&id) == SUCCESS) { - chunk_to_hex(buf, BUF_LEN, this->authKeyID); - logger->log(logger, CONTROL, " authkey: %s", buf); + id->destroy(id); } - if (this->authKeySerialNumber.ptr != NULL) + this->subjectAltNames->destroy(this->subjectAltNames); + + while (this->crlDistributionPoints->remove_last(this->crlDistributionPoints, (void**)&id) == SUCCESS) { - chunk_to_hex(buf, BUF_LEN, this->authKeySerialNumber); - logger->log(logger, CONTROL, " aserial: %s", buf); + id->destroy(id); } + this->crlDistributionPoints->destroy(this->crlDistributionPoints); + + DESTROY_IF(this->issuer); + DESTROY_IF(this->subject); + DESTROY_IF(this->public_key); + free(this->certificate.ptr); + free(this); } /* @@ -1235,10 +1245,6 @@ x509_t *x509_create_from_chunk(chunk_t chunk) this->public.get_status = (cert_status_t (*) (const x509_t*))get_status; this->public.verify = (bool (*) (const x509_t*,const rsa_public_key_t*))verify; this->public.destroy = (void (*) (x509_t*))destroy; - this->public.log_certificate = (void (*) (const x509_t*,logger_t*,bool,bool))log_certificate; - - /* we do not use a per-instance logger right now, since its not always accessible */ - logger = logger_manager->get_logger(logger_manager, ASN1); if (!parse_x509cert(chunk, 0, this)) { diff --git a/src/libstrongswan/crypto/x509.h b/src/libstrongswan/crypto/x509.h index 866659e3b..6c533215b 100755 --- a/src/libstrongswan/crypto/x509.h +++ b/src/libstrongswan/crypto/x509.h @@ -29,8 +29,13 @@ #include <crypto/certinfo.h> #include <utils/identification.h> #include <utils/iterator.h> -#include <utils/logger.h> +/** + * printf specifier for printing certificates. When using the + * #-modifier, an additional bool argument defines if times + * are printed in UTC. + */ +#define X509_PRINTF_SPEC 'Q' typedef struct x509_t x509_t; @@ -203,16 +208,6 @@ struct x509_t { * @param this certificate to destroy */ void (*destroy) (x509_t *this); - - /** - * @brief Log x509 certificate info. - * - * @param this certificate to log - * @param logger logger to be used - * @param utc log dates either in UTC or local time - * @param has_key a matching private key is available - */ - void (*log_certificate) (const x509_t *this, logger_t *logger, bool utc, bool has_key); }; /** diff --git a/src/libstrongswan/definitions.c b/src/libstrongswan/definitions.c index 04db34949..087476838 100644 --- a/src/libstrongswan/definitions.c +++ b/src/libstrongswan/definitions.c @@ -21,39 +21,65 @@ * for more details. */ -#include <stdlib.h> +#include <printf.h> +#include <stdio.h> #include "definitions.h" /* - * Described in header. + * Described in header */ -char *mapping_find(mapping_t * maps, int value) +static char *enum_name(enum_name_t *e, long val) { - int i = 0; - while (maps[i].value != MAPPING_END) + do { - if (maps[i].value == value) + if (val >= e->first && val <= e->last) { - return maps[i].string; + return e->names[val - e->first]; } - i++; } - return "INVALID MAPPING"; + while ((e = e->next)); + return NULL; } -/* - * Described in header + +/** + * output handler in printf() for enum names */ -const char *enum_name(enum_names *ed, unsigned long val) +static int print_enum(FILE *stream, const struct printf_info *info, + const void *const *args) { - enum_names *p; + enum_name_t *ed = *((void**)(args[0])); + long val = *((size_t*)(args[1])); + char *name; + + name = enum_name(ed, val); + if (name == NULL) + { + return fprintf(stream, "(unknown enum value: %ld)", val); + } + return fprintf(stream, "%s", name); +} - for (p = ed; p != NULL; p = p->en_next_range) +/** + * arginfo handler in printf() for enum names + */ +static int print_enum_arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (n > 1) { - if (p->en_first <= val && val <= p->en_last) - return p->en_names[val - p->en_first]; + /* enum_names ptr */ + argtypes[0] = PA_POINTER; + /* value */ + argtypes[1] = PA_INT; } - return NULL; + return 2; } +/** + * register printf() handlers for enum names + */ +static void __attribute__ ((constructor))print_register() +{ + register_printf_function(ENUM_PRINTF_SPEC, print_enum, print_enum_arginfo); +} diff --git a/src/libstrongswan/definitions.h b/src/libstrongswan/definitions.h index 102358438..b02e8092d 100644 --- a/src/libstrongswan/definitions.h +++ b/src/libstrongswan/definitions.h @@ -27,16 +27,12 @@ #include <stddef.h> -#define BITS_PER_BYTE 8 -#define RSA_MIN_OCTETS (1024 / BITS_PER_BYTE) -#define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 1024 bits" -#define RSA_MAX_OCTETS (8192 / BITS_PER_BYTE) -#define RSA_MAX_OCTETS_UGH "RSA modulus too large: more than 8192 bits" +#define BITS_PER_BYTE 8 /** * Default length for various auxiliary text buffers */ -#define BUF_LEN 512 +#define BUF_LEN 512 /** * Macro compares two strings for equality @@ -78,55 +74,35 @@ */ #define ASSIGN(method, function) (method = (typeof(method))function) - /** - * Mapping entry which defines the end of a mapping_t array. + * printf() specifier to resolf enum names, see enum_names */ -#define MAPPING_END (-1) - -typedef struct mapping_t mapping_t; +#define ENUM_PRINTF_SPEC 'N' -/** - * @brief Mapping entry, where enum-to-string mappings are stored. - */ -struct mapping_t -{ - /** - * Enumeration value. - */ - int value; - - /** - * Mapped string. - */ - char *string; -}; - -/** - * @brief Find a mapping_string in the mapping[]. - * - * @param mappings mappings array - * @param value enum-value to get the string from - * - */ -char *mapping_find(mapping_t *mappings, int value); +typedef struct enum_name_t enum_name_t; /** - * @brief Describes an enumeration - * enum_name() returns the name of an enum value, or NULL if invalid. + * Struct to store names for enums. Use the convenience macros + * to define these. + * For a single range, use: + * ENUM(name, first, last, string1, string2, ...) + * + * For multiple ranges, use: + * ENUM_BEGIN(name, first, last, string1, string2, ...) + * ENUM_NEXT(name, first, last, last_from_previous, string3, ...) + * ENUM_NEXT(name, first, last, last_from_previous, string4, ...) + * ENUM_END(name, last_from_previous) */ -typedef const struct enum_names enum_names; - -struct enum_names { - unsigned long en_first; /* first value in range */ - unsigned long en_last; /* last value in range (inclusive) */ - const char *const *en_names; - enum_names *en_next_range; /* descriptor of next range */ +struct enum_name_t { + long first; + long last; + enum_name_t *next; + char *names[]; }; -/** - * @brief Returns the name of an enum value, or NULL if invalid - */ -const char *enum_name(enum_names *ed, unsigned long val); +#define ENUM_BEGIN(name, first, last, ...) static enum_name_t name##last = {first, last, NULL, { __VA_ARGS__ }} +#define ENUM_NEXT(name, first, last, prev, ...) static enum_name_t name##last = {first, last, &name##prev, { __VA_ARGS__ }} +#define ENUM_END(name, prev) enum_name_t *name = &name##prev; +#define ENUM(name, first, last, ...) ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last) #endif /*DEFINITIONS_H_*/ diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c index f561f2451..0394f32d7 100644 --- a/src/libstrongswan/library.c +++ b/src/libstrongswan/library.c @@ -1,8 +1,8 @@ /** * @file library.c - * + * * @brief Library (de-)initialization. - * + * */ /* @@ -21,23 +21,22 @@ * for more details. */ -#include <utils/logger_manager.h> -#include <utils/leak_detective.h> +#include <stdarg.h> +#include <stdio.h> -/** - * Called whenever the library is linked from a process - */ -void __attribute__ ((constructor)) library_init(void) -{ - logger_manager_init(); - leak_detective_init(); -} +#include "library.h" /** - * Called whenever the library is unlinked from a process + * default dbg function which printf all to stderr */ -void __attribute__ ((destructor)) library_cleanup(void) +static void dbg_stderr(int level, char *fmt, ...) { - leak_detective_cleanup(); - logger_manager_cleanup(); + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); } + +void (*dbg) (int level, char *fmt, ...) = dbg_stderr; diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h index 00472bde9..58cd4bb33 100644 --- a/src/libstrongswan/library.h +++ b/src/libstrongswan/library.h @@ -84,17 +84,25 @@ * * Symmetric signing algorithms, * used to ensure message integrity. - * + * * @ingroup crypto */ - + /** * @defgroup utils utils - * + * * Generic helper classes. - * + * * @ingroup libstrongswan */ +/** debug macros, they call the dbg function hook */ +#define DBG1(fmt, ...) dbg(1, fmt, ##__VA_ARGS__) +#define DBG2(fmt, ...) dbg(2, fmt, ##__VA_ARGS__) +#define DBG3(fmt, ...) dbg(3, fmt, ##__VA_ARGS__) +#define DBG4(fmt, ...) dbg(4, fmt, ##__VA_ARGS__) + +/** dbg function hook, uses stderr logger by default */ +extern void (*dbg) (int level, char *fmt, ...); #endif /* LIBRARY_H_ */ diff --git a/src/libstrongswan/types.c b/src/libstrongswan/types.c index 5f6b0b5f7..70cedfbfc 100644 --- a/src/libstrongswan/types.c +++ b/src/libstrongswan/types.c @@ -30,24 +30,20 @@ #include "types.h" +ENUM(status_names, SUCCESS, DESTROY_ME, + "SUCCESS", + "FAILED", + "OUT_OF_RES", + "ALREADY_DONE", + "NOT_SUPPORTED", + "INVALID_ARG", + "NOT_FOUND", + "PARSE_ERROR", + "VERIFY_ERROR", + "INVALID_STATE", + "DESTROY_ME", +); -/** - * String mappings for type status_t. - */ -mapping_t status_m[] = { - {SUCCESS, "SUCCESS"}, - {FAILED, "FAILED"}, - {OUT_OF_RES, "OUT_OF_RES"}, - {ALREADY_DONE, "ALREADY_DONE"}, - {NOT_SUPPORTED, "NOT_SUPPORTED"}, - {INVALID_ARG, "INVALID_ARG"}, - {NOT_FOUND, "NOT_FOUND"}, - {PARSE_ERROR, "PARSE_ERROR"}, - {VERIFY_ERROR, "VERIFY_ERROR"}, - {INVALID_STATE, "INVALID_STATE"}, - {DESTROY_ME, "DESTROY_ME"}, - {MAPPING_END, NULL} -}; /** * Empty chunk. @@ -162,29 +158,51 @@ bool chunk_equals_or_null(chunk_t a, chunk_t b) /** * Described in header. */ -void chunk_to_hex(char *buf, size_t buflen, chunk_t chunk) +void *clalloc(void * pointer, size_t size) { - bool first = TRUE; + void *data; + data = malloc(size); + + memcpy(data, pointer,size); + + return (data); +} - buflen--; /* reserve space for null termination */ +/** + * We use a single mutex for all refcount variables. This + * is not optimal for performance, but the critical section + * is not that long... + * TODO: Consider to include a mutex in each refcount_t variable. + */ +static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER; - while (chunk.len > 0 && buflen > 2) - { - static char hexdig[] = "0123456789abcdef"; +/** + * Described in header. + * + * TODO: May be implemented with atomic CPU instructions + * instead of a mutex. + */ +void ref_get(refcount_t *ref) +{ + pthread_mutex_lock(&ref_mutex); + (*ref)++; + pthread_mutex_unlock(&ref_mutex); +} - if (first) - { - first = FALSE; - } - else - { - *buf++ = ':'; buflen--; - } - *buf++ = hexdig[(*chunk.ptr >> 4) & 0x0f]; - *buf++ = hexdig[ *chunk.ptr++ & 0x0f]; - buflen -= 2; chunk.len--; - } - *buf = '\0'; +/** + * Described in header. + * + * TODO: May be implemented with atomic CPU instructions + * instead of a mutex. + */ +bool ref_put(refcount_t *ref) +{ + bool more_refs; + + pthread_mutex_lock(&ref_mutex); + more_refs = --(*ref); + pthread_mutex_unlock(&ref_mutex); + return !more_refs; } /** @@ -208,13 +226,9 @@ static int print_bytes(FILE *stream, const struct printf_info *info, char *bytes_roof = bytes + len; int line_start = 0; int i = 0; - int total_written = 0; + int written = 0; - total_written = fprintf(stream, "=> %d bytes @ %p", len, bytes); - if (total_written < 0) - { - return total_written; - } + written += fprintf(stream, "=> %d bytes @ %p", len, bytes); while (bytes_pos < bytes_roof) { @@ -238,13 +252,9 @@ static int print_bytes(FILE *stream, const struct printf_info *info, *buffer_pos++ = '\0'; ascii_buffer[i] = '\0'; - written = fprintf(stream, "\n%4d: %s %s", + written += fprintf(stream, "\n%4d: %s %s", line_start, buffer, ascii_buffer); - if (written < 0) - { - return written; - } - total_written += written; + buffer_pos = buffer; line_start += BYTES_PER_LINE; @@ -255,7 +265,7 @@ static int print_bytes(FILE *stream, const struct printf_info *info, *buffer_pos++ = ' '; } } - return total_written; + return written; } /** @@ -265,21 +275,98 @@ static int print_chunk(FILE *stream, const struct printf_info *info, const void *const *args) { chunk_t *chunk = *((chunk_t**)(args[0])); + bool first = TRUE; + chunk_t copy = *chunk; + int written = 0; - const void *new_args[] = {&chunk->ptr, &chunk->len}; - return print_bytes(stream, info, new_args); + if (!info->alt) + { + const void *new_args[] = {&chunk->ptr, &chunk->len}; + return print_bytes(stream, info, new_args); + } + + while (copy.len > 0) + { + static char hexdig[] = "0123456789abcdef"; + if (first) + { + first = FALSE; + } + else + { + written += fprintf(stream, ":"); + } + written += fprintf(stream, "%c%c", + hexdig[(*copy.ptr >> 4) & 0x0f], + hexdig[ *copy.ptr++ & 0x0f]); + copy.len--; + } + return written; } /** - * arginfo handler in printf() for chunks + * output handler in printf() for time_t */ -static int print_chunk_arginfo(const struct printf_info *info, size_t n, int *argtypes) +static int print_time(FILE *stream, const struct printf_info *info, + const void *const *args) { - if (n > 0) + static const char* months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + time_t time = *((time_t*)(args[0])); + bool utc = TRUE; + struct tm t; + + if (info->alt) { - argtypes[0] = PA_POINTER; + utc = *((bool*)(args[1])); } - return 1; + if (time == UNDEFINED_TIME) + { + return fprintf(stream, "--- -- --:--:--%s----", + info->alt ? " UTC " : " "); + } + if (utc) + { + gmtime_r(&time, &t); + } + else + { + localtime_r(&time, &t); + } + return fprintf(stream, "%s %02d %02d:%02d:%02d%s%04d", + months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec, info->alt ? " UTC " : " ", t.tm_year + 1900); +} + +/** + * output handler in printf() for time deltas + */ +static int print_time_delta(FILE *stream, const struct printf_info *info, + const void *const *args) +{ + time_t start = *((time_t*)(args[0])); + time_t end = *((time_t*)(args[1])); + u_int delta = abs(end - start); + char* unit = "second"; + + if (delta > 2 * 60 * 60 * 24) + { + delta /= 60 * 60 * 24; + unit = "days"; + } + else if (delta > 2 * 60 * 60) + { + delta /= 60 * 60; + unit = "hours"; + } + else if (delta > 2 * 60) + { + delta /= 60; + unit = "minutes"; + } + return fprintf(stream, "%d %s", delta, unit); } /** @@ -296,85 +383,59 @@ static int print_bytes_arginfo(const struct printf_info *info, size_t n, int *ar } /** - * register printf() handlers for chunk and byte ranges + * arginfo handler in printf() for time deltas */ -static void __attribute__ ((constructor))print_register() +static int print_time_delta_arginfo(const struct printf_info *info, size_t n, int *argtypes) { - register_printf_function(CHUNK_PRINTF_SPEC, print_chunk, print_chunk_arginfo); - register_printf_function(BYTES_PRINTF_SPEC, print_bytes, print_bytes_arginfo); + if (n > 1) + { + argtypes[0] = PA_INT; + argtypes[1] = PA_INT; + } + return 2; } /** - * Described in header. + * arginfo handler in printf() for time_t */ -void *clalloc(void * pointer, size_t size) +static int print_time_arginfo(const struct printf_info *info, size_t n, int *argtypes) { - void *data; - data = malloc(size); - - memcpy(data, pointer,size); + if (info->alt) + { + if (n > 1) + { + argtypes[0] = PA_INT; + argtypes[1] = PA_INT; + } + return 2; + } - return (data); + if (n > 0) + { + argtypes[0] = PA_INT; + } + return 1; } /** - * We use a single mutex for all refcount variables. This - * is not optimal for performance, but the critical section - * is not that long... - * TODO: Consider to include a mutex in each refcount_t variable. - */ -static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER; - -/** - * Described in header. - * - * TODO: May be implemented with atomic CPU instructions - * instead of a mutex. + * arginfo handler in printf() for chunks */ -void ref_get(refcount_t *ref) +static int print_chunk_arginfo(const struct printf_info *info, size_t n, int *argtypes) { - pthread_mutex_lock(&ref_mutex); - (*ref)++; - pthread_mutex_unlock(&ref_mutex); + if (n > 0) + { + argtypes[0] = PA_POINTER; + } + return 1; } /** - * Described in header. - * - * TODO: May be implemented with atomic CPU instructions - * instead of a mutex. - */ -bool ref_put(refcount_t *ref) -{ - bool more_refs; - - pthread_mutex_lock(&ref_mutex); - more_refs = --(*ref); - pthread_mutex_unlock(&ref_mutex); - return !more_refs; -} - -/* - * Names of the months used by timetoa() + * register printf() handlers for time_t */ -static const char* months[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -/* - * Described in header file - */ -void timetoa(char *buf, size_t buflen, const time_t *time, bool utc) +static void __attribute__ ((constructor))print_register() { - if (*time == UNDEFINED_TIME) - snprintf(buf, buflen, "--- -- --:--:--%s----", (utc)?" UTC ":" "); - else - { - struct tm *t = (utc)? gmtime(time) : localtime(time); - - snprintf(buf, buflen, "%s %02d %02d:%02d:%02d%s%04d", - months[t->tm_mon], t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, - (utc)?" UTC ":" ", t->tm_year + 1900); - } + register_printf_function(CHUNK_PRINTF_SPEC, print_chunk, print_chunk_arginfo); + register_printf_function(BYTES_PRINTF_SPEC, print_bytes, print_bytes_arginfo); + register_printf_function(TIME_PRINTF_SPEC, print_time, print_time_arginfo); + register_printf_function(TIME_DELTA_PRINTF_SPEC, print_time_delta, print_time_delta_arginfo); } diff --git a/src/libstrongswan/types.h b/src/libstrongswan/types.h index 1f28d3844..6561fb208 100644 --- a/src/libstrongswan/types.h +++ b/src/libstrongswan/types.h @@ -106,9 +106,9 @@ enum status_t { }; /** - * String mappings for type status_t. + * enum_names for type status_t. */ -extern mapping_t status_m[]; +extern enum_name_t *status_names; /** * Handle struct timeval like an own type. @@ -150,6 +150,8 @@ struct chunk_t { */ extern chunk_t CHUNK_INITIALIZER; + + /** * Printf() hook character to dump a chunk using printf. * The argument supplied to printf() is a pointer to a chunk. @@ -166,6 +168,22 @@ extern chunk_t CHUNK_INITIALIZER; #define BYTES_PRINTF_SPEC 'b' /** + * printf specifier for time_t, use #-modifier to print time as UTC + */ +#define TIME_PRINTF_SPEC 'T' + +/** + * printf specifier for time_t deltas, uses two arguments + * E.g. printf("%V", begin, end); + */ +#define TIME_DELTA_PRINTF_SPEC 'V' + +/** + * time_t for a not defined time + */ +#define UNDEFINED_TIME 0 + +/** * Initialize a chunk to a static buffer */ #define chunk_from_buf(str) { str, sizeof(str) } @@ -241,18 +259,4 @@ void ref_get(refcount_t *ref); bool ref_put(refcount_t *ref); -#define UNDEFINED_TIME 0 -#define TIMETOA_BUF 30 - -/** - * @brief Display a date either in local or UTC time - * - * @param buf buffer where displayed time will be written to - * @param buflen buffer length - * @param time time to be displayed - * @param utc UTC (TRUE) or local time (FALSE) - * - */ -void timetoa(char *buf, size_t buflen, const time_t *time, bool utc); - #endif /*TYPES_H_*/ diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c index 4932a1e94..6dbd376a3 100644 --- a/src/libstrongswan/utils/identification.c +++ b/src/libstrongswan/utils/identification.c @@ -35,11 +35,7 @@ #include <asn1/asn1.h> -/** - * String mappings for id_type_t. - */ - -static const char *const id_type_name[] = { +ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID, "ID_ANY", "ID_IPV4_ADDR", "ID_FQDN", @@ -51,11 +47,11 @@ static const char *const id_type_name[] = { "ID_IPV6_ADDR_RANGE", "ID_DER_ASN1_DN", "ID_DER_ASN1_GN", - "ID_KEY_ID", -}; + "ID_KEY_ID"); +ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_DER_ASN1_GN_URI, ID_KEY_ID, + "ID_DER_ASN1_GN_URI"); +ENUM_END(id_type_names, ID_DER_ASN1_GN_URI); -enum_names id_type_names = - { ID_ANY, ID_KEY_ID, id_type_name, NULL }; /** * X.501 acronyms for well known object identifiers (OIDs) diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h index 3df710c7c..0d2bc794e 100644 --- a/src/libstrongswan/utils/identification.h +++ b/src/libstrongswan/utils/identification.h @@ -116,9 +116,9 @@ enum id_type_t { }; /** - * String mappings for id_type_t. + * enum names for id_type_t. */ -extern enum_names id_type_names; +extern enum_name_t *id_type_names; typedef struct identification_t identification_t; diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index 9b4219e18..7cf036eea 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -38,6 +38,7 @@ #include "leak_detective.h" #include <types.h> +#include <library.h> #ifdef LEAK_DETECTIVE @@ -117,11 +118,6 @@ static memory_header_t first_header = { }; /** - * logger for the leak detective - */ -static logger_t *logger; - -/** * standard hooks, used to temparily remove hooking */ static void *old_malloc_hook, *old_realloc_hook, *old_free_hook; @@ -149,11 +145,11 @@ static void log_stack_frames(void **stack_frames, int stack_frame_count) strings = backtrace_symbols (stack_frames, stack_frame_count); - logger->log(logger, ERROR, " dumping %d stack frame addresses", stack_frame_count); + DBG1(" dumping %d stack frame addresses", stack_frame_count); for (i = 0; i < stack_frame_count; i++) { - logger->log(logger, ERROR, " %s", strings[i]); + DBG1(" %s", strings[i]); } free (strings); } @@ -166,7 +162,7 @@ static void log_stack_frames(void **stack_frames, int stack_frame_count) * * The range_size is calculated using the readelf utility, e.g.: * readelf -s /lib/glibc.so.6 - * These values may or may not be acceptable for another system. + * The values are for glibc-2.4 and may or may not be correct on other systems. */ typedef struct whitelist_t whitelist_t; @@ -176,15 +172,16 @@ struct whitelist_t { }; whitelist_t whitelist[] = { - {pthread_create, 381}, - {pthread_setspecific, 256}, - {mktime, 60}, - {tzset, 126}, - {inet_ntoa, 256}, - {strerror, 173}, - {getprotobynumber, 294}, - {getservbyport, 309}, - {register_printf_function, 150}, + {pthread_create, 2542}, + {pthread_setspecific, 217}, + {mktime, 60}, + {tzset, 123}, + {inet_ntoa, 249}, + {strerror, 180}, + {getprotobynumber, 291}, + {getservbyport, 311}, + {register_printf_function, 159}, + {syslog, 45}, }; /** @@ -220,7 +217,7 @@ void report_leaks() { if (!is_whitelisted(hdr->stack_frames, hdr->stack_frame_count)) { - logger->log(logger, ERROR, "Leak (%d bytes at %p):", hdr->bytes, hdr + 1); + DBG1("Leak (%d bytes at %p):", hdr->bytes, hdr + 1); log_stack_frames(hdr->stack_frames, hdr->stack_frame_count); leaks++; } @@ -229,13 +226,13 @@ void report_leaks() switch (leaks) { case 0: - logger->log(logger, CONTROL, "No leaks detected"); + DBG1("No leaks detected"); break; case 1: - logger->log(logger, ERROR, "One leak detected"); + DBG1("One leak detected"); break; default: - logger->log(logger, ERROR, "%d leaks detected", leaks); + DBG1("%d leaks detected", leaks); break; } } @@ -322,8 +319,8 @@ void free_hook(void *ptr, const void *caller) uninstall_hooks(); if (hdr->magic != MEMORY_HEADER_MAGIC) { - logger->log(logger, ERROR, "freeing of invalid memory (%p, MAGIC 0x%x != 0x%x):", - ptr, hdr->magic, MEMORY_HEADER_MAGIC); + DBG1("freeing of invalid memory (%p, MAGIC 0x%x != 0x%x):", + ptr, hdr->magic, MEMORY_HEADER_MAGIC); stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT); log_stack_frames(stack_frames, stack_frame_count); install_hooks(); @@ -368,7 +365,7 @@ void *realloc_hook(void *old, size_t bytes, const void *caller) uninstall_hooks(); if (hdr->magic != MEMORY_HEADER_MAGIC) { - logger->log(logger, ERROR, "reallocation of invalid memory (%p):", old); + DBG1("reallocation of invalid memory (%p):", old); stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT); log_stack_frames(stack_frames, stack_frame_count); install_hooks(); @@ -397,16 +394,15 @@ void *realloc_hook(void *old, size_t bytes, const void *caller) /** * Setup leak detective */ -void leak_detective_init() +void __attribute__ ((constructor)) leak_detective_init() { - logger = logger_manager->get_logger(logger_manager, LEAK_DETECT); install_hooks(); } /** * Clean up leak detective */ -void leak_detective_cleanup() +void __attribute__ ((destructor)) leak_detective_cleanup() { uninstall_hooks(); report_leaks(); @@ -415,7 +411,7 @@ void leak_detective_cleanup() /** * Log memory allocation statistics */ -void leak_detective_status(logger_t *logger) +void leak_detective_status(FILE *stream) { u_int blocks = 0; size_t bytes = 0; @@ -429,10 +425,10 @@ void leak_detective_status(logger_t *logger) } pthread_mutex_unlock(&mutex); - logger->log(logger, CONTROL|LEVEL1, "allocation statistics:"); - logger->log(logger, CONTROL|LEVEL1, " call stats: malloc: %d, free: %d, realloc: %d", + fprintf(stream, "allocation statistics:\n"); + fprintf(stream, " call stats: malloc: %d, free: %d, realloc: %d\n", count_malloc, count_free, count_realloc); - logger->log(logger, CONTROL|LEVEL1, " allocated %d blocks, total size %d bytes (avg. %d bytes)", + fprintf(stream, " allocated %d blocks, total size %d bytes (avg. %d bytes)\n", blocks, bytes, bytes/blocks); } @@ -441,7 +437,7 @@ void leak_detective_status(logger_t *logger) /** * Dummy when !using LEAK_DETECTIVE */ -void leak_detective_status(logger_t *logger) +void leak_detective_status(FILE *stream) { } diff --git a/src/libstrongswan/utils/leak_detective.h b/src/libstrongswan/utils/leak_detective.h index 07b2f6543..d4016b06e 100644 --- a/src/libstrongswan/utils/leak_detective.h +++ b/src/libstrongswan/utils/leak_detective.h @@ -22,36 +22,14 @@ #ifndef LEAK_DETECTIVE_H_ #define LEAK_DETECTIVE_H_ - -#include <utils/logger_manager.h> - /** * Log status information about allocation */ -void leak_detective_status(logger_t *logger); - -#ifdef LEAK_DETECTIVE +void leak_detective_status(FILE *stream); /** * Max number of stack frames to include in a backtrace. */ #define STACK_FRAMES_COUNT 30 -/** - * Initialize leak detective, activates it - */ -void leak_detective_init(); - -/** - * Cleanup leak detective, deactivates it - */ -void leak_detective_cleanup(); - -#else /* !LEAK_DETECTIVE */ - -#define leak_detective_init() {} -#define leak_detective_cleanup() {} - -#endif /* LEAK_DETECTIVE */ - #endif /* LEAK_DETECTIVE_H_ */ diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c index 0149afd69..83371018f 100644 --- a/src/libstrongswan/utils/linked_list.c +++ b/src/libstrongswan/utils/linked_list.c @@ -127,6 +127,11 @@ struct private_iterator_t { * Direction of iterator. */ bool forward; + + /** + * Mutex to use to synchronize access + */ + pthread_mutex_t *mutex; }; /** @@ -361,6 +366,10 @@ static void insert_after(private_iterator_t * iterator, void *item) */ static void iterator_destroy(private_iterator_t *this) { + if (this->mutex) + { + pthread_mutex_unlock(this->mutex); + } free(this); } @@ -373,24 +382,6 @@ static int get_count(private_linked_list_t *this) } /** - * Implementation of linked_list_t.call_on_items. - */ -static void call_on_items(private_linked_list_t *this, void(*func)(void*)) -{ - iterator_t *iterator; - void *item; - - iterator = this->public.create_iterator(&this->public,TRUE); - - while (iterator->has_next(iterator)) - { - iterator->current(iterator, &item); - (*func)(item); - } - iterator->destroy(iterator); -} - -/** * Implementation of linked_list_t.insert_first. */ static void insert_first(private_linked_list_t *this, void *item) @@ -629,7 +620,7 @@ static status_t get_last(private_linked_list_t *this, void **item) static iterator_t *create_iterator (private_linked_list_t *linked_list, bool forward) { private_iterator_t *this = malloc_thing(private_iterator_t); - + this->public.get_count = (bool (*) (iterator_t *this)) get_list_count; this->public.iterate = (bool (*) (iterator_t *this, void **value)) iterate; this->public.has_next = (bool (*) (iterator_t *this)) iterator_has_next; @@ -640,11 +631,26 @@ static iterator_t *create_iterator (private_linked_list_t *linked_list, bool for this->public.remove = (status_t (*) (iterator_t *this)) remove; this->public.reset = (void (*) (iterator_t *this)) iterator_reset; this->public.destroy = (void (*) (iterator_t *this)) iterator_destroy; - + this->forward = forward; this->current = NULL; this->list = linked_list; + this->mutex = NULL; + + return &this->public; +} +/** + * Implementation of linked_list_t.create_iterator_locked. + */ +static iterator_t *create_iterator_locked(private_linked_list_t *linked_list, + pthread_mutex_t *mutex) +{ + private_iterator_t *this = (private_iterator_t*)create_iterator(linked_list, TRUE); + this->mutex = mutex; + + pthread_mutex_lock(mutex); + return &this->public; } @@ -672,7 +678,7 @@ linked_list_t *linked_list_create() this->public.get_count = (int (*) (linked_list_t *)) get_count; this->public.create_iterator = (iterator_t * (*) (linked_list_t *,bool))create_iterator; - this->public.call_on_items = (void (*) (linked_list_t *, void(*func)(void*)))call_on_items; + this->public.create_iterator_locked = (iterator_t * (*) (linked_list_t *,pthread_mutex_t*))create_iterator_locked; this->public.get_first = (status_t (*) (linked_list_t *, void **item))get_first; this->public.get_last = (status_t (*) (linked_list_t *, void **item))get_last; this->public.insert_first = (void (*) (linked_list_t *, void *item))insert_first; diff --git a/src/libstrongswan/utils/linked_list.h b/src/libstrongswan/utils/linked_list.h index b5f982f20..9c824177e 100644 --- a/src/libstrongswan/utils/linked_list.h +++ b/src/libstrongswan/utils/linked_list.h @@ -24,6 +24,8 @@ #ifndef LINKED_LIST_H_ #define LINKED_LIST_H_ +#include <pthread.h> + #include <types.h> #include <utils/iterator.h> @@ -31,18 +33,13 @@ typedef struct linked_list_t linked_list_t; /** - * @brief Class implementing a double linked list (named only as linked list). + * @brief Class implementing a double linked list. * - * @warning Access to an object of this type is not thread-save. + * General purpose linked list. This list is not synchronized. * * @b Costructors: * - linked_list_create() - * - * @see - * - job_queue_t - * - event_queue_t - * - send_queue_t - * + * * @ingroup utils */ struct linked_list_t { @@ -64,27 +61,24 @@ struct linked_list_t { * @param forward iterator direction (TRUE: front to end) * @return new iterator_t object */ - iterator_t * (*create_iterator) (linked_list_t *linked_list, bool forward); + iterator_t *(*create_iterator) (linked_list_t *linked_list, bool forward); /** - * @brief Call a function with list element as argument. - * - * This method accepts a function, which will be called for - * each list element once. The function must accept the list - * element as the first argument. Handy for destruction of - * list elements. - * - * @todo Additional vararg which are passed to the - * function would be nice... + * @brief Creates a iterator, locking a mutex. + * + * The supplied mutex is acquired immediately, and released + * when the iterator gets destroyed. * * @param linked_list calling object - * @param func function to call + * @param mutex mutex to use for exclusive access + * @return new iterator_t object */ - void (*call_on_items) (linked_list_t *linked_list, void(*func)(void*)); + iterator_t *(*create_iterator_locked) (linked_list_t *linked_list, + pthread_mutex_t *mutex); /** * @brief Inserts a new item at the beginning of the list. - * + * * @param linked_list calling object * @param[in] item item value to insert in list */ diff --git a/src/libstrongswan/utils/logger.c b/src/libstrongswan/utils/logger.c deleted file mode 100644 index 26f42535e..000000000 --- a/src/libstrongswan/utils/logger.c +++ /dev/null @@ -1,384 +0,0 @@ -/** - * @file logger.c - * - * @brief Implementation of logger_t. - * - */ - -/* - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include <syslog.h> -#include <string.h> -#include <stdio.h> -#include <time.h> -#include <pthread.h> - -#include "logger.h" - -/** - * Maximum length of a log entry (only used for logger_s.log). - */ -#define MAX_LOG 8192 - -/** - * Maximum number of logged bytes per line - */ -#define MAX_BYTES 16 - -typedef struct private_logger_t private_logger_t; - -/** - * @brief Private data of a logger_t object. - */ -struct private_logger_t { - /** - * Public data. - */ - logger_t public; - /** - * Detail-level of logger. - */ - log_level_t level; - /** - * Name of logger. - */ - char *name; - /** - * File to write log output to. - * NULL for syslog. - */ - FILE *output; - - /** - * Should a thread_id be included in the log? - */ - bool log_thread_id; -}; - -/** - * thread local storage for get_thread_number - */ -static pthread_key_t thread_ids; -static void make_key(void) -{ - pthread_key_create(&thread_ids, NULL); -} - -/** - * Get a unique thread number for a calling thread. Since - * pthread_self returns large and ugly numbers, use this function - * for logging; these numbers are incremental starting at 1 - */ -static int get_thread_number(void) -{ - static int current_num = 0; - static pthread_once_t key_once = PTHREAD_ONCE_INIT; - int stored_num; - - pthread_once(&key_once, make_key); - stored_num = (int)pthread_getspecific(thread_ids); - if (stored_num == 0) - { - pthread_setspecific(thread_ids, (void*)++current_num); - return current_num; - } - else - { - return stored_num; - } -} - -/** - * prepend the logging prefix to string and store it in buffer - */ -static void prepend_prefix(private_logger_t *this, log_level_t loglevel, const char *string, char *buffer) -{ - char thread_id[3] = ""; - char log_type, log_details; - char *separator = (strlen(this->name) == 0)? "" : ":"; - - if (loglevel & CONTROL) - { - log_type = 'C'; - } - else if (loglevel & ERROR) - { - log_type = 'E'; - } - else if (loglevel & RAW) - { - log_type = 'R'; - } - else if (loglevel & PRIVATE) - { - log_type = 'P'; - } - else if (loglevel & AUDIT) - { - log_type = 'A'; - } - else - { - log_type = '-'; - } - - if (loglevel & (LEVEL3 - LEVEL2)) - { - log_details = '3'; - } - else if (loglevel & (LEVEL2 - LEVEL1)) - { - log_details = '2'; - } - else if (loglevel & LEVEL1) - { - log_details = '1'; - } - else - { - log_details = '0'; - } - - if (this->log_thread_id) - { - snprintf(thread_id, sizeof(thread_id), "%02d", get_thread_number()); - } - snprintf(buffer, MAX_LOG, "%s[%c%c%s%s] %s", - thread_id, log_type, log_details, separator, this->name, string); -} - -/** - * Convert a charon-loglevel to a syslog priority - */ -static int get_priority(log_level_t loglevel) -{ - if (loglevel & ERROR) - { - return LOG_AUTHPRIV|LOG_ERR; - } - if (loglevel & AUDIT) - { - return LOG_AUTHPRIV|LOG_INFO; - } - return LOG_AUTHPRIV|LOG_DEBUG; -} - -/** - * Implementation of logger_t.logv. - */ -static void logv(private_logger_t *this, log_level_t loglevel, const char *format, va_list args) -{ - if ((this->level & loglevel) == loglevel) - { - char buffer[MAX_LOG]; - - if (this->output == NULL) - { - /* syslog */ - prepend_prefix(this, loglevel, format, buffer); - vsyslog(get_priority(loglevel), buffer, args); - } - else - { - /* File output */ - prepend_prefix(this, loglevel, format, buffer); - vfprintf(this->output, buffer, args); - fprintf(this->output, "\n"); - } - } -} - -/** - * Implementation of logger_t.log. - */ -static void logg(private_logger_t *this, log_level_t loglevel, const char *format, ...) -{ - va_list args; - - va_start(args, format); - logv(this, loglevel, format, args); - va_end(args); -} - -/** - * Implementation of logger_t.log_bytes. - */ -static void log_bytes(private_logger_t *this, log_level_t loglevel, const char *label, const char *bytes, size_t len) -{ - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - - if ((this->level & loglevel) == loglevel) - { - char thread_id[3] = ""; - char buffer[MAX_LOG]; - char ascii_buffer[MAX_BYTES+1]; - - char *buffer_pos = buffer; - const char format[] = "%s %d bytes @ %p"; - const char *bytes_pos = bytes; - const char *bytes_roof = bytes + len; - - int line_start = 0; - int i = 0; - - /* since me can't do multi-line output to syslog, - * we must do multiple syslogs. To avoid - * problems in output order, lock this by a mutex. - */ - pthread_mutex_lock(&mutex); - - prepend_prefix(this, loglevel, format, buffer); - - if (this->log_thread_id) - { - snprintf(thread_id, sizeof(thread_id), "%02d", get_thread_number()); - } - - if (this->output == NULL) - { - syslog(get_priority(loglevel), buffer, label, len, bytes); - } - else - { - fprintf(this->output, buffer, label, len, bytes); - fprintf(this->output, "\n"); - } - - while (bytes_pos < bytes_roof) - { - static char hexdig[] = "0123456789ABCDEF"; - - *buffer_pos++ = hexdig[(*bytes_pos >> 4) & 0xF]; - *buffer_pos++ = hexdig[ *bytes_pos & 0xF]; - - ascii_buffer[i++] = (*bytes_pos > 31 && *bytes_pos < 127) - ? *bytes_pos : '.'; - - if (++bytes_pos == bytes_roof || i == MAX_BYTES) - { - int padding = 3 * (MAX_BYTES - i); - - while (padding--) - { - *buffer_pos++ = ' '; - } - *buffer_pos++ = '\0'; - ascii_buffer[i] = '\0'; - - if (this->output == NULL) - { - syslog(get_priority(loglevel), "%s[ :%5d] %s %s", thread_id, line_start, buffer, ascii_buffer); - } - else - { - fprintf(this->output, "%s[ :%5d] %s %s\n", thread_id, line_start, buffer, ascii_buffer); - } - buffer_pos = buffer; - line_start += MAX_BYTES; - i = 0; - } - else - { - *buffer_pos++ = ' '; - } - } - pthread_mutex_unlock(&mutex); - } -} - -/** - * Implementation of logger_t.log_chunk. - */ -static void log_chunk(logger_t *this, log_level_t loglevel, const char *label, chunk_t chunk) -{ - this->log_bytes(this, loglevel, label, chunk.ptr, chunk.len); -} - -/** - * Implementation of logger_t.enable_level. - */ -static void enable_level(private_logger_t *this, log_level_t log_level) -{ - this->level |= log_level; -} - -/** - * Implementation of logger_t.disable_level. - */ -static void disable_level(private_logger_t *this, log_level_t log_level) -{ - this->level &= ~log_level; -} - -/** - * Implementation of logger_t.set_output. - */ -static void set_output(private_logger_t *this, FILE * output) -{ - this->output = output; -} - -/** - * Implementation of logger_t.get_level. - */ -static log_level_t get_level(private_logger_t *this) -{ - return this->level; -} - -/** - * Implementation of logger_t.destroy. - */ -static void destroy(private_logger_t *this) -{ - free(this->name); - free(this); -} - -/* - * Described in header. - */ -logger_t *logger_create(char *logger_name, log_level_t log_level, bool log_thread_id, FILE * output) -{ - private_logger_t *this = malloc_thing(private_logger_t); - - /* public functions */ - this->public.log = (void(*)(logger_t*,log_level_t,const char*,...))logg; - this->public.logv = (void(*)(logger_t*,log_level_t,const char*,va_list))logv; - this->public.log_bytes = (void(*)(logger_t*, log_level_t, const char*, const char*,size_t))log_bytes; - this->public.log_chunk = log_chunk; - this->public.enable_level = (void(*)(logger_t*,log_level_t))enable_level; - this->public.disable_level = (void(*)(logger_t*,log_level_t))disable_level; - this->public.get_level = (log_level_t(*)(logger_t*))get_level; - this->public.set_output = (void(*)(logger_t*,FILE*))set_output; - this->public.destroy = (void(*)(logger_t*))destroy; - - if (logger_name == NULL) - { - logger_name = ""; - } - - /* private variables */ - this->level = log_level; - this->log_thread_id = log_thread_id; - this->name = malloc(strlen(logger_name) + 1); - - strcpy(this->name,logger_name); - this->output = output; - - return (logger_t*)this; -} diff --git a/src/libstrongswan/utils/logger.h b/src/libstrongswan/utils/logger.h deleted file mode 100644 index b24940d70..000000000 --- a/src/libstrongswan/utils/logger.h +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @file logger.h - * - * @brief Interface of logger_t. - * - */ - -/* - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#ifndef LOGGER_H_ -#define LOGGER_H_ - -#include <stdio.h> -#include <stdarg.h> - -#include <types.h> - -typedef enum log_level_t log_level_t; - -/** - * @brief Log Levels supported by the logger object. - * - * Logleves are devided in two different kinds: - * - levels to specify the type of the log - * - levels to specify the detail-level of the log - * - * Use combinations of these to build detailed loglevels, such - * as CONTROL|LEVEL2 fore a detailed cotrol level, or - * use RAW to see all raw data dumps (except private). - * - * @ingroup utils - */ -enum log_level_t { - /** - * Control flow. - */ - CONTROL = 1, - /** - * Error reporting. - */ - ERROR = 2, - /** - * Logs important for the sysadmin. - */ - AUDIT = 4, - /** - * Raw data dumps. - */ - RAW = 8, - /** - * Private data dumps. - */ - PRIVATE = 16, - - /** - * Log most important output, can be omitted. - */ - LEVEL0 = 0, - /** - * Log more detailed output. - */ - LEVEL1 = 32, - /** - * Log even more detailed output. - */ - LEVEL2 = LEVEL1 + 64, - /** - * Use maximum detailed output. - */ - LEVEL3 = LEVEL2 + 128, - - /** - * Summary for all types with all detail-levels. - */ - FULL = LEVEL3 + CONTROL + ERROR + RAW + PRIVATE + AUDIT -}; - -typedef struct logger_t logger_t; - -/** - * @brief Class to simplify logging. - * - * @b Constructors: - * - logger_create() - * - * @ingroup utils - */ -struct logger_t { - - /** - * @brief Log an entry, using printf()-like params. - * - * All specified loglevels must be activated that - * the log is done. - * - * @param this logger_t object - * @param loglevel or'ed set of log_level_t's - * @param format printf like format string - * @param ... printf like parameters - */ - void (*log) (logger_t *this, log_level_t log_level, const char *format, ...); - - /** - * @brief Log an entry, using vprintf() style va_list parameters. - * - * All specified loglevels must be activated that - * the log is done. - * - * @param this logger_t object - * @param loglevel or'ed set of log_level_t's - * @param format printf like format string - * @param args va_list argument list - */ - void (*logv) (logger_t *this, log_level_t log_level, const char *format, va_list args); - - /** - * @brief Log some bytes, useful for debugging. - * - * All specified loglevels must be activated that - * the log is done. - * - * @param this logger_t object - * @param loglevel or'ed set of log_level_t's - * @param label a labeling name, logged with the bytes - * @param bytes pointer to the bytes to dump - * @param len number of bytes to dump - */ - void (*log_bytes) (logger_t *this, log_level_t loglevel, const char *label, const char *bytes, size_t len); - - /** - * @brief Log a chunk, useful for debugging. - * - * All specified loglevels must be activated that - * the log is done. - * - * @param this logger_t object - * @param loglevel or'ed set of log_level_t's - * @param label a labeling name, logged with the bytes - * @param chunk chunk to log - */ - void (*log_chunk) (logger_t *this, log_level_t loglevel, const char *label, chunk_t chunk); - - /** - * @brief Enables a loglevel for the current logger_t object. - * - * @param this logger_t object - * @param log_level loglevel to enable - */ - void (*enable_level) (logger_t *this, log_level_t log_level); - - /** - * @brief Disables a loglevel for the current logger_t object. - * - * @param this logger_t object - * @param log_level loglevel to enable - */ - void (*disable_level) (logger_t *this, log_level_t log_level); - - /** - * @brief Set the output of the logger. - * - * Use NULL for syslog. - * - * @param this logger_t object - * @param output file, where log output should be written - */ - void (*set_output) (logger_t *this, FILE *output); - - /** - * @brief Get the currently used loglevel. - * - * @param this logger_t object - * @return currently used loglevel - */ - log_level_t (*get_level) (logger_t *this); - - /** - * @brief Destroys a logger_t object. - * - * @param this logger_t object - */ - void (*destroy) (logger_t *this); -}; - -/** - * @brief Constructor to create a logger_t object. - * - * @param logger_name name for the logger_t object - * @param log_level or'ed set of log_levels to assign to the new logger_t object - * @param log_thread_id TRUE if thread id should also be logged - * @param output FILE * if log has to go on a file output, NULL for syslog - * @return logger_t object - * - * @ingroup utils - */ -logger_t *logger_create(char *logger_name, log_level_t log_level, bool log_thread_id, FILE * output); - - -#endif /*LOGGER_H_*/ diff --git a/src/libstrongswan/utils/logger_manager.c b/src/libstrongswan/utils/logger_manager.c deleted file mode 100644 index ff79c62b9..000000000 --- a/src/libstrongswan/utils/logger_manager.c +++ /dev/null @@ -1,220 +0,0 @@ -/** - * @file logger_manager.c - * - * @brief Implementation of logger_manager_t. - * - */ - -/* - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - - -#include "logger_manager.h" - -#include <definitions.h> -#include <utils/linked_list.h> - -/** - * String mappings for logger_context_t - */ -mapping_t logger_context_t_mappings[] = { - {PARSER, "PARSER"}, - {GENERATOR, "GENERATOR"}, - {IKE_SA, "IKE_SA"}, - {IKE_SA_MANAGER, "IKE_SA_MANAGER"}, - {CHILD_SA, "CHILD_SA"}, - {MESSAGE, "MESSAGE"}, - {THREAD_POOL, "THREAD_POOL"}, - {WORKER, "WORKER"}, - {SCHEDULER, "SCHEDULER"}, - {SENDER, "SENDER"}, - {RECEIVER, "RECEIVER"}, - {SOCKET, "SOCKET"}, - {TESTER, "TESTER"}, - {DAEMON, "DAEMON"}, - {CONFIG, "CONFIG"}, - {ENCRYPTION_PAYLOAD, "ENCRYPTION_PAYLOAD"}, - {PAYLOAD, "PAYLOAD"}, - {DER_DECODER, "DER_DECODER"}, - {DER_ENCODER, "DER_ENCODER"}, - {ASN1, "ASN1"}, - {XFRM, "XFRM"}, - {LEAK_DETECT, "LEAK_DETECT"}, - {MAPPING_END, NULL}, -}; - -struct { - char *name; - log_level_t level; - bool log_thread_ids; -} logger_defaults[] = { - { "PARSR", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* PARSER */ - { "GNRAT", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* GENERATOR */ - { "IKESA", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* IKE_SA */ - { "SAMGR", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* IKE_SA_MANAGER */ - { "CHDSA", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* CHILD_SA */ - { "MESSG", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* MESSAGE */ - { "TPOOL", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* THREAD_POOL */ - { "WORKR", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* WORKER */ - { "SCHED", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* SCHEDULER */ - { "SENDR", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* SENDER */ - { "RECVR", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* RECEIVER */ - { "SOCKT", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* SOCKET */ - { "TESTR", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* TESTER */ - { "DAEMN", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* DAEMON */ - { "CONFG", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* CONFIG */ - { "ENCPL", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* ENCRYPTION_PAYLOAD */ - { "PAYLD", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* PAYLOAD */ - { "DERDC", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* DER_DECODER */ - { "DEREC", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* DER_ENCODER */ - { "ASN_1", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* ASN1 */ - { "XFRM ", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* XFRM */ - { "LEAKD", ERROR|CONTROL|AUDIT|LEVEL0, TRUE }, /* LEAK_DETECT */ -}; - - -typedef struct private_logger_manager_t private_logger_manager_t; - -/** - * Private data of logger_manager_t object. - */ -struct private_logger_manager_t { - /** - * Public data. - */ - logger_manager_t public; - - /** - * Array of loggers, one for each context - */ - logger_t *loggers[LOGGER_CONTEXT_ROOF]; -}; - -/** - * The one and only instance of the logger manager - */ -static private_logger_manager_t private_logger_manager; - -/** - * Exported pointer for the logger manager - */ -logger_manager_t *logger_manager = (logger_manager_t *)&private_logger_manager; - -/** - * Implementation of logger_manager_t.get_logger. - */ -static logger_t *get_logger(private_logger_manager_t *this, logger_context_t context) -{ - return this->loggers[context]; -} - -/** - * Implementation of logger_manager_t.get_log_level. - */ -static log_level_t get_log_level (private_logger_manager_t *this, logger_context_t context) -{ - return this->loggers[context]->get_level(this->loggers[context]); -} - -/** - * Implementation of private_logger_manager_t.enable_log_level. - */ -static void enable_log_level(private_logger_manager_t *this, logger_context_t context, log_level_t level) -{ - if (context == ALL_LOGGERS) - { - for (context = 0; context < LOGGER_CONTEXT_ROOF; context++) - { - this->loggers[context]->enable_level(this->loggers[context], level); - } - } - else - { - this->loggers[context]->enable_level(this->loggers[context], level); - } -} - -/** - * Implementation of private_logger_manager_t.disable_log_level. - */ -static void disable_log_level(private_logger_manager_t *this, logger_context_t context, log_level_t level) -{ - if (context == ALL_LOGGERS) - { - for (context = 0; context < LOGGER_CONTEXT_ROOF; context++) - { - this->loggers[context]->disable_level(this->loggers[context], level); - } - } - else - { - this->loggers[context]->disable_level(this->loggers[context], level); - } -} - -/** - * Implementation of private_logger_manager_t.set_output. - */ -static void set_output(private_logger_manager_t *this, logger_context_t context, FILE *output) -{ - if (context == ALL_LOGGERS) - { - for (context = 0; context < LOGGER_CONTEXT_ROOF; context++) - { - this->loggers[context]->set_output(this->loggers[context], output); - } - } - else - { - this->loggers[context]->set_output(this->loggers[context], output); - } -} - - -/** - * Creates the instance of the logger manager at library startup - */ -void logger_manager_init() -{ - int i; - - logger_manager->get_logger = (logger_t *(*)(logger_manager_t*,logger_context_t context))get_logger; - logger_manager->get_log_level = (log_level_t (*)(logger_manager_t *, logger_context_t)) get_log_level; - logger_manager->enable_log_level = (void (*)(logger_manager_t *, logger_context_t, log_level_t)) enable_log_level; - logger_manager->disable_log_level = (void (*)(logger_manager_t *, logger_context_t, log_level_t)) disable_log_level; - logger_manager->set_output = (void (*)(logger_manager_t *, logger_context_t, FILE*)) set_output; - - for (i = 0; i < LOGGER_CONTEXT_ROOF; i++) - { - private_logger_manager.loggers[i] = logger_create(logger_defaults[i].name, - logger_defaults[i].level, - logger_defaults[i].log_thread_ids, - INITIAL_LOG_OUTPUT); - } - -} - -/** - * Destroy the logger manager at library exit - */ -void logger_manager_cleanup() -{ - int i; - for (i = 0; i < LOGGER_CONTEXT_ROOF; i++) - { - private_logger_manager.loggers[i]->destroy(private_logger_manager.loggers[i]); - } -} diff --git a/src/libstrongswan/utils/logger_manager.h b/src/libstrongswan/utils/logger_manager.h deleted file mode 100644 index fa11cbd97..000000000 --- a/src/libstrongswan/utils/logger_manager.h +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @file logger_manager.h - * - * @brief Interface of logger_manager_t. - * - */ - -/* - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#ifndef LOGGER_MANAGER_H_ -#define LOGGER_MANAGER_H_ - -#include <pthread.h> - -#include <utils/logger.h> - -#define INITIAL_LOG_OUTPUT stdout - -typedef enum logger_context_t logger_context_t; - -/** - * @brief Context of a specific logger. - * - * @ingroup utils - */ -enum logger_context_t { - ALL_LOGGERS = -1, - PARSER = 0, - GENERATOR, - IKE_SA, - IKE_SA_MANAGER, - CHILD_SA, - MESSAGE, - THREAD_POOL, - WORKER, - SCHEDULER, - SENDER, - RECEIVER, - SOCKET, - TESTER, - DAEMON, - CONFIG, - ENCRYPTION_PAYLOAD, - PAYLOAD, - DER_DECODER, - DER_ENCODER, - ASN1, - XFRM, - LEAK_DETECT, - LOGGER_CONTEXT_ROOF, -}; - - -typedef struct logger_manager_t logger_manager_t; - -/** - * @brief Class to manage logger_t objects. - * - * The logger manager manages all logger_t object in a list and - * allows their manipulation. Via a logger_context_t, the loglevel - * of a specific logging type can be adjusted at runtime. - * This class differs from others, as it has no constructor or destroy - * function. The one and only instance "logger_manager" is created at - * library start and destroyed at exit. - * - * @b Constructors: - * - none, logger_manager is the single instance - * use logger_manager_init/logger_manager_cleanup - * - * @see logger_t - * - * @ingroup utils - */ -struct logger_manager_t { - - /** - * @brief Gets a logger_t object for a specific logger context. - * - * @param this logger_manager_t object - * @param context logger_context to use the logger for - * @param name name for the new logger. Context name is already included - * and has not to be specified (so NULL is allowed) - * @return logger_t object - */ - logger_t *(*get_logger) (logger_manager_t *this, logger_context_t context); - - /** - * @brief Returns the set log_level of a specific context. - * - * @param this calling object - * @param context context to check level - * @return log_level for the given logger_context - */ - log_level_t (*get_log_level) (logger_manager_t *this, logger_context_t context); - - /** - * @brief Enables a logger level of a specific context. - * - * Use context ALL_LOGGERS to manipulate all loggers. - * - * @param this calling object - * @param context context to set level - * @param log_level logger level to eanble - */ - void (*enable_log_level) (logger_manager_t *this, logger_context_t context,log_level_t log_level); - - /** - * @brief Disables a logger level of a specific context. - * - * Use context ALL_LOGGERS to manipulate all loggers. - * - * @param this calling object - * @param context context to set level - * @param log_level logger level to disable - */ - void (*disable_log_level) (logger_manager_t *this, logger_context_t context,log_level_t log_level); - - /** - * @brief Sets the output of a logger. - * - * Use context ALL_LOGGERS to redirect all loggers. - * - * @param this calling object - * @param context context to set output - * @param log_level logger level to disable - */ - void (*set_output) (logger_manager_t *this, logger_context_t context, FILE *output); -}; - -/** - * The single and global instance of the logger_manager - */ -extern logger_manager_t *logger_manager; - -/** - * Initialize the logger manager with all its logger. - * Has to be called before logger_manager is accessed. - */ -void logger_manager_init(void); - -/** - * Free any resources hold by the logger manager. Do - * not access logger_manager after this call. - */ -void logger_manager_cleanup(void); - -#endif /*LOGGER_MANAGER_H_*/ diff --git a/src/libstrongswan/utils/tester.c b/src/libstrongswan/utils/tester.c deleted file mode 100644 index fcc6b4c4c..000000000 --- a/src/libstrongswan/utils/tester.c +++ /dev/null @@ -1,255 +0,0 @@ -/** - * @file tester.c - * - * @brief Implementation of tester_t. - * - */ - -/* - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - - -#include <stdlib.h> -#include <string.h> -#include <pthread.h> -#include <sys/time.h> - -#include "tester.h" - - - -typedef struct private_tester_t private_tester_t; - -/** - * @brief Private Data of tester_t class. - * - */ -struct private_tester_t { - - /** - * Protected interface of tester_t. - */ - protected_tester_t protected; - - /** - * Runs a specific test. - * - * @param tester associated tester object - * @param test_function test function to perform - * @param test_name name for the given test - */ - void (*run_test) (private_tester_t *tester, void (*test_function) (protected_tester_t * tester), char * test_name); - - /** - * Returns the difference of to timeval structs in microseconds. - * - * @warning this function is also defined in the event queue - * in later improvements, this function can be added to a general - * class type! - * - * @param end_time end time - * @param start_time start time - * - * @TODO make object function or move to utils! - * - * @return difference in microseconds - */ - long (*time_difference) (private_tester_t *tester,struct timeval *end_time, struct timeval *start_time); - - /** - * Output is written into this file. - */ - FILE* output; - - /** - * Number of already performed tests. - */ - int tests_count; - - /** - * Number of failed tests. - */ - int failed_tests_count; - - /** - * Number of failed asserts in current test. - */ - int failed_asserts_count; - - /** - * TRUE if also succeeded asserts should be written to output. - */ - bool display_succeeded_asserts; - - /** - * Mutex to make this class thread-save. - */ - pthread_mutex_t mutex; -}; - -/** - * Implementation of tester_t.perform_tests. - */ -static void perform_tests(private_tester_t *this,test_t **tests) -{ - int current_test = 0; - fprintf(this->output,"\nStart testing...\n\n"); - fprintf(this->output,"_____________________________________________________________________\n"); - fprintf(this->output,"Testname | running time\n"); - fprintf(this->output,"_______________________________________________________|_____________\n"); - - while (tests[current_test] != NULL) - { - this->run_test(this,tests[current_test]->test_function,tests[current_test]->test_name); - current_test++; - } - fprintf(this->output,"=====================================================================\n"); - fprintf(this->output,"End testing. %d of %d tests succeeded\n",this->tests_count - this->failed_tests_count,this->tests_count); - fprintf(this->output,"=====================================================================\n"); -} - -/** - * Implementation of tester_t.perform_test. - */ -static void perform_test(private_tester_t *this, test_t *test) -{ - test_t *tests[] = {test, NULL}; - return (perform_tests(this,tests)); -} - -/** - * Returns the difference of to timeval structs in microseconds. - * - * @warning this function is also defined in the event queue - * in later improvements, this function can be added to a general - * class type! - * - * @param end_time end time - * @param start_time start time - * - * @TODO make object function or move to utils! - * - * @return difference in microseconds - */ -static long time_difference(private_tester_t *this,struct timeval *end_time, struct timeval *start_time) -{ - long seconds, microseconds; - - seconds = (end_time->tv_sec - start_time->tv_sec); - microseconds = (end_time->tv_usec - start_time->tv_usec); - return ((seconds * 1000000) + microseconds); -} - - -/** - * Implementation of private_tester_t.run_test. - */ -static void run_test(private_tester_t *this, void (*test_function) (protected_tester_t * tester), char * test_name) -{ - struct timeval start_time, end_time; - long timediff; - this->tests_count++; - this->failed_asserts_count = 0; - fprintf(this->output,"%-55s\n", test_name); - gettimeofday(&start_time,NULL); - test_function(&(this->protected)); - gettimeofday(&end_time,NULL); - timediff = this->time_difference(this,&end_time, &start_time); - - if (this->failed_asserts_count > 0) - { - fprintf(this->output," => Test failed: %-37s|%10ld us\n",test_name,timediff); - }else - { - fprintf(this->output,"\033[1A\033[55C|%10ld us\033[1B\033[80D",timediff); - } - if (this->failed_asserts_count > 0) - { - this->failed_tests_count++; - } -} - - -/** - * Implementation of tester_t.assert_true. - */ -static void assert_true(private_tester_t *this, bool to_be_true,char * assert_name) -{ - if (assert_name == NULL) - { - assert_name = "unknown"; - } - - pthread_mutex_lock(&(this->mutex)); - if (!to_be_true) - { - this->failed_asserts_count++; - fprintf(this->output," check '%s' failed!\n", assert_name); - }else - { - if (this->display_succeeded_asserts) - { - fprintf(this->output," check '%s' succeeded\n", assert_name); - } - } - pthread_mutex_unlock(&(this->mutex)); -} - -/** - * Implementation of tester_t.assert_false. - */ -static void assert_false(private_tester_t *this, bool to_be_false,char * assert_name) -{ - this->protected.assert_true(&(this->protected),(!to_be_false),assert_name); -} - -/** - * Implementation of tester_t.destroy. - */ -static void destroy(private_tester_t *tester) -{ - private_tester_t *this = (private_tester_t*) tester; - pthread_mutex_destroy(&(this->mutex)); - free(this); -} - -/* - * Described in header. - */ -tester_t *tester_create(FILE *output, bool display_succeeded_asserts) -{ - private_tester_t *this = malloc_thing(private_tester_t); - - /* public functions */ - this->protected.public.destroy = (void (*) (tester_t *))destroy; - this->protected.public.perform_tests = (void (*) (tester_t *, test_t**)) perform_tests; - this->protected.public.perform_test = (void (*) (tester_t *, test_t*))perform_test; - this->protected.assert_true = (void (*) (protected_tester_t *, bool, char*)) assert_true; - this->protected.assert_false = (void (*) (protected_tester_t *, bool, char*)) assert_false; - - /* private functions */ - this->run_test = run_test; - this->time_difference = time_difference; - - /* private data */ - this->display_succeeded_asserts = display_succeeded_asserts; - this->failed_tests_count = 0; - this->tests_count = 0; - this->output = output; - pthread_mutex_init(&(this->mutex),NULL); - - return &(this->protected.public); -} diff --git a/src/libstrongswan/utils/tester.h b/src/libstrongswan/utils/tester.h deleted file mode 100644 index 21e678c59..000000000 --- a/src/libstrongswan/utils/tester.h +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file tester.h - * - * @brief Interface of tester_t. - * - */ - -/* - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#ifndef TESTER_H_ -#define TESTER_H_ - -#include <stdio.h> - -#include <types.h> - - -/* must be defined here cause it is used in test_t */ -typedef struct protected_tester_t protected_tester_t; - -typedef struct test_t test_t; - -/** - * @brief Representing a specified test. - * - * @ingroup utils - */ -struct test_t { - /** - * Testfunction called for this test. - * - * @param tester associated tester_t object - */ - void (*test_function) (protected_tester_t * tester); - - /** - * Name of the test. - */ - char * test_name; -}; - - -typedef struct tester_t tester_t; - -/** - * @brief A class to perform tests. - * - * @b Constructors: - * - tester_create() - * - * @ingroup utils - */ -struct tester_t { - /** - * @brief Test all testcases in array tests with specific tester_t object. - * - * @param tester tester_t object - * @param tests pointer to an array of test_t-pointers. - * The last item has to be NULL to mark end of array. - */ - void (*perform_tests) (tester_t *tester,test_t **tests); - - /** - * @brief Run a specific test case. - * - * @param this tester_t object - * @param test pointer to a test_t object which will be performed - */ - void (*perform_test) (tester_t *tester, test_t *test); - - /** - * @brief Destroys a tester_t object. - * - * @param tester tester_t object - */ - void (*destroy) (tester_t *tester); -}; - - -/** - * @brief A class used in a specific testcase. - * - * For each testcase an object of this type is passed to the testfunction. The testfunction uses this - * object to check specific asserts with protected_tester_t.assert_true and protected_tester_t.assert_false. - * - * @b Constructors: - * - tester_create() - * - * @ingroup utils - */ -struct protected_tester_t { - - /** - * Public functions of a tester_t object - */ - tester_t public; - - /** - * @brief Is called in a testcase to check a specific situation for TRUE. - * - * Log-Values to the tester output are protected from multiple access. - * - * @param this tester_t object - * @param to_be_true assert which has to be TRUE - * @param assert_name name of the assertion - */ - void (*assert_true) (protected_tester_t *tester, bool to_be_true, char *assert_name); - - /** - * @brief Is called in a testcase to check a specific situation for FALSE. - * - * Log-Values to the tester output are protected from multiple access. - * - * @param this tester_t object - * @param to_be_false assert which has to be FALSE - * @param assert_name name of the assertion - */ - void (*assert_false) (protected_tester_t *tester, bool to_be_false, char *assert_name); -}; - - -/** - * @brief Creates a tester_t object used to perform tests with. - * - * @param output test output is written to this output. - * @param display_succeeded_asserts has to be TRUE, if all asserts should be displayed, - * FALSE otherwise - * - * @return tester_t object - * - * @ingroup utils - */ -tester_t *tester_create(FILE *output, bool display_succeeded_asserts); - -#endif /*TESTER_H_*/ |