diff options
author | Martin Willi <martin@strongswan.org> | 2006-09-27 14:15:49 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2006-09-27 14:15:49 +0000 |
commit | 151168f6eaf58e99cd436dee0f9751bb6c03b3ec (patch) | |
tree | bf202b927391849d1b7ac40d630e2eea32ac642c | |
parent | 47f5027807c10d52d6122b9bba590e8ec6e02a95 (diff) | |
download | strongswan-151168f6eaf58e99cd436dee0f9751bb6c03b3ec.tar.bz2 strongswan-151168f6eaf58e99cd436dee0f9751bb6c03b3ec.tar.xz |
-rwxr-xr-x | src/libstrongswan/crypto/crl.c | 4 | ||||
-rwxr-xr-x | src/libstrongswan/crypto/x509.c | 10 | ||||
-rw-r--r-- | src/libstrongswan/definitions.h | 42 | ||||
-rw-r--r-- | src/libstrongswan/types.c | 118 | ||||
-rw-r--r-- | src/libstrongswan/types.h | 15 | ||||
-rw-r--r-- | src/libstrongswan/utils/host.c | 159 | ||||
-rw-r--r-- | src/libstrongswan/utils/host.h | 36 | ||||
-rw-r--r-- | src/libstrongswan/utils/identification.c | 235 | ||||
-rw-r--r-- | src/libstrongswan/utils/identification.h | 15 | ||||
-rw-r--r-- | src/libstrongswan/utils/leak_detective.c | 24 | ||||
-rw-r--r-- | src/libstrongswan/utils/logger.c | 28 | ||||
-rw-r--r-- | src/libstrongswan/utils/logger.h | 14 |
12 files changed, 392 insertions, 308 deletions
diff --git a/src/libstrongswan/crypto/crl.c b/src/libstrongswan/crypto/crl.c index 95b6b5b6e..1f41c0a76 100755 --- a/src/libstrongswan/crypto/crl.c +++ b/src/libstrongswan/crypto/crl.c @@ -252,7 +252,7 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl) break; case CRL_OBJ_ISSUER: crl->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); - logger->log(logger, CONTROL|LEVEL1, " '%s'", crl->issuer->get_string(crl->issuer)); + logger->log(logger, CONTROL|LEVEL1, " '%D'", crl->issuer); break; case CRL_OBJ_THIS_UPDATE: crl->thisUpdate = parse_time(object, level); @@ -450,7 +450,7 @@ static void log_crl(const private_crl_t *this, logger_t *logger, bool utc, bool logger->log(logger, CONTROL, "%s, revoked certs: %d", buf, revokedCertificates->get_count(revokedCertificates)); - logger->log(logger, CONTROL, " issuer: '%s'", issuer->get_string(issuer)); + logger->log(logger, CONTROL, " issuer: '%D'", issuer); timetoa(buf, BUF_LEN, &this->thisUpdate, utc); logger->log(logger, CONTROL, " updates: this %s", buf); diff --git a/src/libstrongswan/crypto/x509.c b/src/libstrongswan/crypto/x509.c index 07745ba00..dd82a493c 100755 --- a/src/libstrongswan/crypto/x509.c +++ b/src/libstrongswan/crypto/x509.c @@ -519,7 +519,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, " '%s'", gn->get_string(gn)); + logger->log(logger, CONTROL|LEVEL2, " '%D'", gn); return gn; } objectID++; @@ -789,7 +789,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, " '%s'", cert->issuer->get_string(cert->issuer)); + logger->log(logger, CONTROL|LEVEL1, " '%D'", cert->issuer); break; case X509_OBJ_NOT_BEFORE: cert->notBefore = parse_time(object, level); @@ -799,7 +799,7 @@ 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, " '%s'", cert->subject->get_string(cert->subject)); + logger->log(logger, CONTROL|LEVEL1, " '%D'", cert->subject); break; case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM: if (parse_algorithmIdentifier(object, level, NULL) != OID_RSA_ENCRYPTION) @@ -1144,8 +1144,8 @@ static void log_certificate(const private_x509_t *this, logger_t *logger, bool u timetoa(time_buf, TIMETOA_BUF, &this->installed, utc); logger->log(logger, CONTROL, "%s", time_buf); - logger->log(logger, CONTROL, " subject: '%s'", subject->get_string(subject)); - logger->log(logger, CONTROL, " issuer: '%s'", issuer->get_string(issuer)); + 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); diff --git a/src/libstrongswan/definitions.h b/src/libstrongswan/definitions.h index 9b8b52dd9..102358438 100644 --- a/src/libstrongswan/definitions.h +++ b/src/libstrongswan/definitions.h @@ -27,39 +27,6 @@ #include <stddef.h> -/* stolen from FreeS/WAN */ -#if linux -# if defined(i386) && !defined(__i386__) -# define __i386__ 1 -# define MYHACKFORTHIS 1 -# endif -# include <endian.h> -# ifdef MYHACKFORTHIS -# undef __i386__ -# undef MYHACKFORTHIS -# endif -#elif !(defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN) && defined(BYTE_ORDER)) - /* we don't know how to do this, so we require the macros to be defined - * with compiler flags: - * -DBIG_ENDIAN=4321 -DLITTLE_ENDIAN=1234 -DBYTE_ORDER=BIG_ENDIAN - * or -DBIG_ENDIAN=4321 -DLITTLE_ENDIAN=1234 -DBYTE_ORDER=LITTLE_ENDIAN - * Thse match the GNU definitions - */ -# include <sys/endian.h> -#endif - -#ifndef BIG_ENDIAN - #error "BIG_ENDIAN must be defined" -#endif - -#ifndef LITTLE_ENDIAN - #error "LITTLE_ENDIAN must be defined" -#endif - -#ifndef BYTE_ORDER - #error "BYTE_ORDER must be defined" -#endif - #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" @@ -103,12 +70,14 @@ /** * Macro to allocate a sized type. - * - * @param thing object on which a sizeof is performed - * @return poiner to allocated memory */ #define malloc_thing(thing) ((thing*)malloc(sizeof(thing))) +/** + * Assign a function as a class method + */ +#define ASSIGN(method, function) (method = (typeof(method))function) + /** * Mapping entry which defines the end of a mapping_t array. @@ -133,7 +102,6 @@ struct mapping_t char *string; }; - /** * @brief Find a mapping_string in the mapping[]. * diff --git a/src/libstrongswan/types.c b/src/libstrongswan/types.c index 2ca0e4c5c..5f6b0b5f7 100644 --- a/src/libstrongswan/types.c +++ b/src/libstrongswan/types.c @@ -26,6 +26,7 @@ #include <stdio.h> #include <stdarg.h> #include <pthread.h> +#include <printf.h> #include "types.h" @@ -187,6 +188,123 @@ void chunk_to_hex(char *buf, size_t buflen, chunk_t chunk) } /** + * Number of bytes per line to dump raw data + */ +#define BYTES_PER_LINE 16 + +/** + * output handler in printf() for byte ranges + */ +static int print_bytes(FILE *stream, const struct printf_info *info, + const void *const *args) +{ + char *bytes = *((void**)(args[0])); + int len = *((size_t*)(args[1])); + + char buffer[BYTES_PER_LINE * 3]; + char ascii_buffer[BYTES_PER_LINE + 1]; + char *buffer_pos = buffer; + char *bytes_pos = bytes; + char *bytes_roof = bytes + len; + int line_start = 0; + int i = 0; + int total_written = 0; + + total_written = fprintf(stream, "=> %d bytes @ %p", len, bytes); + if (total_written < 0) + { + return total_written; + } + + 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 == BYTES_PER_LINE) + { + int padding = 3 * (BYTES_PER_LINE - i); + int written; + + while (padding--) + { + *buffer_pos++ = ' '; + } + *buffer_pos++ = '\0'; + ascii_buffer[i] = '\0'; + + 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; + i = 0; + } + else + { + *buffer_pos++ = ' '; + } + } + return total_written; +} + +/** + * output handler in printf() for chunks + */ +static int print_chunk(FILE *stream, const struct printf_info *info, + const void *const *args) +{ + chunk_t *chunk = *((chunk_t**)(args[0])); + + const void *new_args[] = {&chunk->ptr, &chunk->len}; + return print_bytes(stream, info, new_args); +} + +/** + * arginfo handler in printf() for chunks + */ +static int print_chunk_arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (n > 0) + { + argtypes[0] = PA_POINTER; + } + return 1; +} + +/** + * arginfo handler in printf() for byte ranges + */ +static int print_bytes_arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (n > 1) + { + argtypes[0] = PA_POINTER; + argtypes[1] = PA_INT; + } + return 2; +} + +/** + * register printf() handlers for chunk and byte ranges + */ +static void __attribute__ ((constructor))print_register() +{ + register_printf_function(CHUNK_PRINTF_SPEC, print_chunk, print_chunk_arginfo); + register_printf_function(BYTES_PRINTF_SPEC, print_bytes, print_bytes_arginfo); +} + +/** * Described in header. */ void *clalloc(void * pointer, size_t size) diff --git a/src/libstrongswan/types.h b/src/libstrongswan/types.h index 9874d5bc0..1f28d3844 100644 --- a/src/libstrongswan/types.h +++ b/src/libstrongswan/types.h @@ -151,6 +151,21 @@ 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. + * E.g. printf("chunk xy is: %B", &xy); + */ +#define CHUNK_PRINTF_SPEC 'B' + +/** + * Printf() hook character to dump a chunk using printf. + * Two arguments are supplied for one format string charactar, + * first a pointer to the buffer, and as second the length of the buffer. + * E.g. printf("buffer xy is: %b", buffer, sizeof(buffer)); + */ +#define BYTES_PRINTF_SPEC 'b' + +/** * Initialize a chunk to a static buffer */ #define chunk_from_buf(str) { str, sizeof(str) } diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c index 44925784c..702d4bd4e 100644 --- a/src/libstrongswan/utils/host.c +++ b/src/libstrongswan/utils/host.c @@ -23,6 +23,7 @@ */ #include <string.h> +#include <printf.h> #include "host.h" @@ -39,11 +40,6 @@ struct private_host_t { host_t public; /** - * string representation of host - */ - char *string; - - /** * low-lewel structure, wich stores the address */ union { @@ -108,60 +104,77 @@ static bool is_anyaddr(private_host_t *this) } /** - * implements host_t.get_string - */ -static char *get_string(private_host_t *this) -{ - return this->string; -} - -/** - * Compute the string value + * output handler in printf() */ -static void set_string(private_host_t *this) +static int print(FILE *stream, const struct printf_info *info, + const void *const *args) { + private_host_t *this = *((private_host_t**)(args[0])); + char buffer[INET6_ADDRSTRLEN]; + void *address; + u_int16_t port; + + if (this == NULL) + { + return fprintf(stream, "(null)"); + } + if (is_anyaddr(this)) { - this->string = strdup("%any"); - return; + return fprintf(stream, "%%any"); } - switch (this->address.sa_family) + switch (this->address.sa_family) { case AF_INET: + address = &this->address4.sin_addr; + port = this->address4.sin_port; + break; case AF_INET6: - { - char buffer[INET6_ADDRSTRLEN]; - void *address; - - if (this->address.sa_family == AF_INET) - { - address = &this->address4.sin_addr; - } - else - { - address = &this->address6.sin6_addr; - } - - if (inet_ntop(this->address.sa_family, address, - buffer, sizeof(buffer)) != NULL) - { - this->string = strdup(buffer); - } - else - { - this->string = strdup("(address conversion failed)"); - } - return; - } + address = &this->address6.sin6_addr; + port = this->address6.sin6_port; + break; default: - { - this->string = strdup("(family not supported)"); - } + return fprintf(stream, "(family not supported)"); + } + + if (inet_ntop(this->address.sa_family, address, + buffer, sizeof(buffer)) == NULL) + { + return fprintf(stream, "(address conversion failed)"); + } + + if (info->alt) + { + return fprintf(stream, "%s[%d]", buffer, ntohs(port)); + } + else + { + return fprintf(stream, "%s", buffer); } } /** + * arginfo handler in printf() + */ +static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (n > 0) + { + argtypes[0] = PA_POINTER; + } + return 1; +} + +/** + * register printf() handlers + */ +static void __attribute__ ((constructor))print_register() +{ + register_printf_function(HOST_PRINTF_SPEC, print, print_arginfo); +} + +/** * Implementation of host_t.get_address. */ static chunk_t get_address(private_host_t *this) @@ -252,10 +265,6 @@ static private_host_t *clone(private_host_t *this) private_host_t *new = malloc_thing(private_host_t); memcpy(new, this, sizeof(private_host_t)); - if (this->string) - { - new->string = strdup(this->string); - } return new; } @@ -359,7 +368,6 @@ static bool equals(private_host_t *this, private_host_t *other) */ static void destroy(private_host_t *this) { - free(this->string); free(this); } @@ -374,7 +382,6 @@ static private_host_t *host_create_empty(void) this->public.get_sockaddr_len = (socklen_t*(*) (host_t*))get_sockaddr_len; this->public.clone = (host_t* (*) (host_t*))clone; this->public.get_family = (int (*) (host_t*))get_family; - this->public.get_string = (char* (*) (host_t *))get_string; this->public.get_address = (chunk_t (*) (host_t *)) get_address; this->public.get_port = (u_int16_t (*) (host_t *))get_port; this->public.set_port = (void (*) (host_t *,u_int16_t))set_port; @@ -384,56 +391,12 @@ static private_host_t *host_create_empty(void) this->public.is_anyaddr = (bool (*) (host_t *)) is_anyaddr; this->public.destroy = (void (*) (host_t*))destroy; - this->string = NULL; - return this; } /* * Described in header. */ -host_t *host_create(int family, char *address, u_int16_t port) -{ - private_host_t *this = host_create_empty(); - - this->address.sa_family = family; - - switch (family) - { - case AF_INET: - { - if (inet_pton(family, address, &this->address4.sin_addr) <=0) - { - break; - } - this->address4.sin_port = htons(port); - this->socklen = sizeof(struct sockaddr_in); - set_string(this); - return &this->public; - } - case AF_INET6: - { - if (inet_pton(family, address, &this->address6.sin6_addr) <=0) - { - break; - } - this->address6.sin6_port = htons(port); - this->socklen = sizeof(struct sockaddr_in6); - set_string(this); - return &this->public; - } - default: - { - break; - } - } - free(this); - return NULL; -} - -/* - * Described in header. - */ host_t *host_create_from_string(char *string, u_int16_t port) { private_host_t *this = host_create_empty(); @@ -457,7 +420,6 @@ host_t *host_create_from_string(char *string, u_int16_t port) } this->address4.sin_port = htons(port); this->socklen = sizeof(struct sockaddr_in); - set_string(this); return &this->public; } case AF_INET6: @@ -468,7 +430,6 @@ host_t *host_create_from_string(char *string, u_int16_t port) } this->address6.sin6_port = htons(port); this->socklen = sizeof(struct sockaddr_in6); - set_string(this); return &this->public; } default: @@ -499,7 +460,6 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port) memcpy(&(this->address4.sin_addr.s_addr), address.ptr,4); this->address4.sin_port = htons(port); this->socklen = sizeof(struct sockaddr_in); - set_string(this); return &(this->public); } case AF_INET6: @@ -511,7 +471,6 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port) memcpy(&(this->address6.sin6_addr.s6_addr), address.ptr, 16); this->address6.sin6_port = htons(port); this->socklen = sizeof(struct sockaddr_in6); - set_string(this); return &this->public; } default: @@ -534,14 +493,12 @@ host_t *host_create_from_sockaddr(sockaddr_t *sockaddr) { memcpy(&this->address4, sockaddr, sizeof(struct sockaddr_in)); this->socklen = sizeof(struct sockaddr_in); - set_string(this); return &this->public; } case AF_INET6: { memcpy(&this->address6, sockaddr, sizeof(struct sockaddr_in6)); this->socklen = sizeof(struct sockaddr_in6); - set_string(this); return &this->public; } default: diff --git a/src/libstrongswan/utils/host.h b/src/libstrongswan/utils/host.h index b9a97b1cb..38bdc809a 100644 --- a/src/libstrongswan/utils/host.h +++ b/src/libstrongswan/utils/host.h @@ -35,6 +35,14 @@ #include <types.h> + +/** + * printf() specifier to print a host. + * The specifier option '#' does include the port number, e.g.: + * printf("my host is %#H\n", my_host); + */ +#define HOST_PRINTF_SPEC 'H' + typedef enum host_diff_t host_diff_t; /** @@ -107,17 +115,6 @@ struct host_t { int (*get_family) (host_t *this); /** - * @brief Get the address of this host as a string - * - * Mostly used for debugging purposes. String - * points to internal data. - * - * @param this object - * @return address string, - */ - char* (*get_string) (host_t *this); - - /** * @brief Checks if the ip address of host is set to default route. * * @param this calling object @@ -190,21 +187,7 @@ struct host_t { }; /** - * @brief Constructor to create a host_t object from an address string - * - * @param family Address family to use for this object, such as AF_INET or AF_INET6 - * @param address string of an address, such as "152.96.193.130" - * @param port port number - * @return - * - host_t object - * - NULL, if family not supported/invalid string. - * - * @ingroup network - */ -host_t *host_create(int family, char *address, u_int16_t port); - -/** - * @brief Same as host_create(), but guesses the family. + * @brief Constructor to create a host_t object from an address string. * * @param string string of an address, such as "152.96.193.130" * @param port port number @@ -242,5 +225,4 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port); */ host_t *host_create_from_sockaddr(sockaddr_t *sockaddr); - #endif /*HOST_H_*/ diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c index 4fbda0afd..4932a1e94 100644 --- a/src/libstrongswan/utils/identification.c +++ b/src/libstrongswan/utils/identification.c @@ -28,6 +28,7 @@ #include <string.h> #include <stdio.h> #include <ctype.h> +#include <printf.h> #include "definitions.h" #include "identification.h" @@ -180,11 +181,6 @@ struct private_identification_t { identification_t public; /** - * String representation of this ID. - */ - char *string; - - /** * Encoded representation of this ID. */ chunk_t encoded; @@ -675,21 +671,25 @@ static id_type_t get_type(private_identification_t *this) { return this->type; } - -/** - * Implementation of identification_t.get_string. - */ -static char *get_string(private_identification_t *this) -{ - return this->string; -} /** * Implementation of identification_t.contains_wildcards. */ static bool contains_wildcards(private_identification_t *this) { - return this->type == ID_ANY || strchr(this->string, '*') != NULL; + switch (this->type) + { + case ID_ANY: + return TRUE; + case ID_FQDN: + case ID_RFC822_ADDR: + return memchr(this->encoded.ptr, '*', this->encoded.len) != NULL; + case ID_DER_ASN1_DN: + /* TODO */ + default: + return FALSE; + + } } /** @@ -698,13 +698,15 @@ static bool contains_wildcards(private_identification_t *this) */ static bool equals_binary(private_identification_t *this, private_identification_t *other) { - return this->type == other->type && chunk_equals(this->encoded, other->encoded); + return this->type == other->type && + chunk_equals(this->encoded, other->encoded); } /** * Special implementation of identification_t.equals for ID_DER_ASN1_DN. */ -static bool equals_dn(private_identification_t *this, private_identification_t *other) +static bool equals_dn(private_identification_t *this, + private_identification_t *other) { return same_dn(this->encoded, other->encoded); } @@ -712,24 +714,25 @@ static bool equals_dn(private_identification_t *this, private_identification_t * /** * Default implementation of identification_t.matches. */ -static bool matches_binary(private_identification_t *this, private_identification_t *other, - int *wildcards) -{ +static bool matches_binary(private_identification_t *this, + private_identification_t *other, int *wildcards) +{ if (other->type == ID_ANY) { *wildcards = MAX_WILDCARDS; return TRUE; } *wildcards = 0; - return this->type == other->type && chunk_equals(this->encoded, other->encoded); + return this->type == other->type && + chunk_equals(this->encoded, other->encoded); } /** * Special implementation of identification_t.matches for ID_RFC822_ADDR/ID_FQDN. * Checks for a wildcard in other-string, and compares it against this-string. */ -static bool matches_string(private_identification_t *this, private_identification_t *other, - int *wildcards) +static bool matches_string(private_identification_t *this, + private_identification_t *other, int *wildcards) { u_int len = other->encoded.len; @@ -772,9 +775,9 @@ static bool matches_string(private_identification_t *this, private_identificatio * Special implementation of identification_t.matches for ID_ANY. * ANY matches only another ANY, but nothing other */ -static bool matches_any(private_identification_t *this, private_identification_t *other, - int *wildcards) -{ +static bool matches_any(private_identification_t *this, + private_identification_t *other, int *wildcards) +{ *wildcards = 0; return other->type == ID_ANY; } @@ -783,8 +786,8 @@ static bool matches_any(private_identification_t *this, private_identification_t * Special implementation of identification_t.matches for ID_DER_ASN1_DN. * ANY matches any, even ANY, thats why its there... */ -static bool matches_dn(private_identification_t *this, private_identification_t *other, - int *wildcards) +static bool matches_dn(private_identification_t *this, + private_identification_t *other, int *wildcards) { if (other->type == ID_ANY) { @@ -800,6 +803,85 @@ static bool matches_dn(private_identification_t *this, private_identification_t } /** + * output handler in printf() + */ +static int print(FILE *stream, const struct printf_info *info, + const void *const *args) +{ + private_identification_t *this = *((private_identification_t**)(args[0])); + char buf[BUF_LEN]; + chunk_t buf_chunk = chunk_from_buf(buf); + + if (this == NULL) + { + return fprintf(stream, "(null)"); + } + + switch (this->type) + { + case ID_ANY: + return fprintf(stream, "%%any"); + case ID_IPV4_ADDR: + if (this->encoded.len < sizeof(struct in_addr) || + inet_ntop(AF_INET, this->encoded.ptr, buf, sizeof(buf)) == NULL) + { + return fprintf(stream, "(invalid ID_IPV4_ADDR)"); + } + else + { + return fprintf(stream, "%s", buf); + } + case ID_IPV6_ADDR: + if (this->encoded.len < sizeof(struct in6_addr) || + inet_ntop(AF_INET6, this->encoded.ptr, buf, INET6_ADDRSTRLEN) == NULL) + { + return fprintf(stream, "(invalid ID_IPV6_ADDR)"); + } + else + { + return fprintf(stream, "%s", buf); + } + case ID_FQDN: + return fprintf(stream, "@%.*s", this->encoded.len, this->encoded.ptr); + case ID_RFC822_ADDR: + return fprintf(stream, "%.*s", this->encoded.len, this->encoded.ptr); + case ID_DER_ASN1_DN: + snprintf(buf, sizeof(buf), "%.*s", this->encoded.len, this->encoded.ptr); + /* TODO: whats returned on failure?*/ + dntoa(this->encoded, &buf_chunk); + return fprintf(stream, "%s", buf); + case ID_DER_ASN1_GN: + return fprintf(stream, "(ASN.1 general Name"); + case ID_KEY_ID: + return fprintf(stream, "(KEY_ID)"); + case ID_DER_ASN1_GN_URI: + return fprintf(stream, "%.*s", this->encoded.len, this->encoded.ptr); + default: + return fprintf(stream, "(unknown ID type: %d)", this->type); + } +} + +/** + * arginfo handler in printf() + */ +static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (n > 0) + { + argtypes[0] = PA_POINTER; + } + return 1; +} + +/** + * register printf() handlers + */ +static void __attribute__ ((constructor))print_register() +{ + register_printf_function(IDENTIFICATION_PRINTF_SPEC, print, print_arginfo); +} + +/** * Implementation of identification_t.clone. */ static identification_t *clone(private_identification_t *this) @@ -808,9 +890,6 @@ static identification_t *clone(private_identification_t *this) clone->type = this->type; clone->encoded = chunk_clone(this->encoded); - clone->string = malloc(strlen(this->string) + 1); - strcpy(clone->string, this->string); - clone->public.equals = this->public.equals; clone->public.matches = this->public.matches; @@ -822,9 +901,8 @@ static identification_t *clone(private_identification_t *this) */ static void destroy(private_identification_t *this) { - free(this->string); - free(this->encoded.ptr); - free(this); + chunk_free(&this->encoded); + free(this); } /** @@ -836,7 +914,6 @@ static private_identification_t *identification_create(void) this->public.get_encoding = (chunk_t (*) (identification_t*))get_encoding; this->public.get_type = (id_type_t (*) (identification_t*))get_type; - this->public.get_string = (char* (*) (identification_t*))get_string; this->public.contains_wildcards = (bool (*) (identification_t *this))contains_wildcards; this->public.clone = (identification_t* (*) (identification_t*))clone; this->public.destroy = (void (*) (identification_t*))destroy; @@ -844,7 +921,6 @@ static private_identification_t *identification_create(void) this->public.equals = (bool (*) (identification_t*,identification_t*))equals_binary; this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_binary; - this->string = NULL; this->encoded = CHUNK_INITIALIZER; return this; @@ -858,8 +934,9 @@ identification_t *identification_create_from_string(char *string) private_identification_t *this = identification_create(); if (string == NULL) + { string = "%any"; - + } if (strchr(string, '=') != NULL) { /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN. @@ -870,7 +947,6 @@ identification_t *identification_create_from_string(char *string) free(this); return NULL; } - this->string = strdup(string); this->type = ID_DER_ASN1_DN; this->public.equals = (bool (*) (identification_t*,identification_t*))equals_dn; this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_dn; @@ -886,8 +962,8 @@ identification_t *identification_create_from_string(char *string) { /* any ID will be accepted */ this->type = ID_ANY; - this->string = strdup("%any"); - this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_any; + this->public.matches = (bool (*) + (identification_t*,identification_t*,int*))matches_any; return &this->public; } else @@ -904,7 +980,6 @@ identification_t *identification_create_from_string(char *string) return NULL; } this->encoded = chunk_clone(chunk); - this->string = strdup(string); this->type = ID_IPV4_ADDR; return &(this->public); } @@ -920,7 +995,6 @@ identification_t *identification_create_from_string(char *string) return NULL; } this->encoded = chunk_clone(chunk); - this->string = strdup(string); this->type = ID_IPV6_ADDR; return &(this->public); } @@ -939,20 +1013,20 @@ identification_t *identification_create_from_string(char *string) else { this->type = ID_FQDN; - this->string = strdup(string); this->encoded.ptr = strdup(string + 1); this->encoded.len = strlen(string + 1); - this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_string; + this->public.matches = (bool (*) + (identification_t*,identification_t*,int*))matches_string; return &(this->public); } } else { this->type = ID_RFC822_ADDR; - this->string = strdup(string); this->encoded.ptr = strdup(string); this->encoded.len = strlen(string); - this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_string; + this->public.matches = (bool (*) + (identification_t*,identification_t*,int*))matches_string; return &(this->public); } } @@ -963,72 +1037,34 @@ identification_t *identification_create_from_string(char *string) */ identification_t *identification_create_from_encoding(id_type_t type, chunk_t encoded) { - char *pos; - char buf[BUF_LEN]; - chunk_t buf_chunk = chunk_from_buf(buf); private_identification_t *this = identification_create(); - this->type = type; - switch (type) { case ID_ANY: - this->string = strdup("%any"); - this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_any; - break; - case ID_IPV4_ADDR: - if (encoded.len < sizeof(struct in_addr) || - inet_ntop(AF_INET, encoded.ptr, buf, sizeof(buf)) == NULL) - { - this->string = strdup("(invalid ID_IPV4_ADDR)"); - } - else - { - this->string = strdup(buf); - } - break; - case ID_IPV6_ADDR: - if (encoded.len < sizeof(struct in6_addr) || - inet_ntop(AF_INET6, encoded.ptr, buf, INET6_ADDRSTRLEN) == NULL) - { - this->string = strdup("(invalid ID_IPV6_ADDR)"); - } - else - { - this->string = strdup(buf); - } + this->public.matches = (bool (*) + (identification_t*,identification_t*,int*))matches_any; break; case ID_FQDN: - snprintf(buf, sizeof(buf), "@%.*s", encoded.len, encoded.ptr); - this->string = strdup(buf); - this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_string; + this->public.matches = (bool (*) + (identification_t*,identification_t*,int*))matches_string; break; case ID_RFC822_ADDR: - snprintf(buf, sizeof(buf), "%.*s", encoded.len, encoded.ptr); - this->string = strdup(buf); - this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_string; + this->public.matches = (bool (*) + (identification_t*,identification_t*,int*))matches_string; break; case ID_DER_ASN1_DN: - snprintf(buf, sizeof(buf), "%.*s", encoded.len, encoded.ptr); - /* TODO: whats returned on failure */ - dntoa(encoded, &buf_chunk); - this->string = strdup(buf); - this->public.equals = (bool (*) (identification_t*,identification_t*))equals_dn; - this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_dn; + this->public.equals = (bool (*) + (identification_t*,identification_t*))equals_dn; + this->public.matches = (bool (*) + (identification_t*,identification_t*,int*))matches_dn; break; + case ID_IPV4_ADDR: + case ID_IPV6_ADDR: case ID_DER_ASN1_GN: - this->string = strdup("ASN.1 coded generalName"); - break; case ID_KEY_ID: - this->string = strdup("(KEY_ID)"); - break; case ID_DER_ASN1_GN_URI: - snprintf(buf, sizeof(buf), "%.*s", encoded.len, encoded.ptr); - this->string = strdup(buf); - break; default: - snprintf(buf, sizeof(buf), "(invalid ID type: %d)", type); - this->string = strdup(buf); break; } @@ -1037,14 +1073,5 @@ identification_t *identification_create_from_encoding(id_type_t type, chunk_t en { this->encoded = chunk_clone(encoded); } - - /* remove unprintable chars in string */ - for (pos = this->string; *pos != '\0'; pos++) - { - if (!isprint(*pos)) - { - *pos = '?'; - } - } return &(this->public); } diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h index 5b13d02a0..3df710c7c 100644 --- a/src/libstrongswan/utils/identification.h +++ b/src/libstrongswan/utils/identification.h @@ -28,6 +28,10 @@ #include "types.h" #define MAX_WILDCARDS 14 +/** + * printf() specifier to print a identification. + */ +#define IDENTIFICATION_PRINTF_SPEC 'D' typedef enum id_type_t id_type_t; @@ -162,16 +166,6 @@ struct identification_t { id_type_t (*get_type) (identification_t *this); /** - * @brief Get a string representation of this id. - * - * @warning Result points to internal data, do NOT free! - * - * @param this the identification_t object - * @return string - */ - char *(*get_string) (identification_t *this); - - /** * @brief Check if two identification_t objects are equal. * * @param this the identification_t object @@ -269,5 +263,4 @@ identification_t * identification_create_from_string(char *string); */ identification_t * identification_create_from_encoding(id_type_t type, chunk_t encoded); - #endif /* IDENTIFICATION_H_ */ diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index 86071a505..9b4219e18 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -33,6 +33,7 @@ #include <syslog.h> #include <pthread.h> #include <netdb.h> +#include <printf.h> #include "leak_detective.h" @@ -138,7 +139,8 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /** * log stack frames queried by backtrace() - * TODO: Dump symbols of static functions!!! + * TODO: Dump symbols of static functions. This could be done with + * the addr2line utility or the GNU BFD Library... */ static void log_stack_frames(void **stack_frames, int stack_frame_count) { @@ -161,6 +163,10 @@ static void log_stack_frames(void **stack_frames, int stack_frame_count) * * This is necessary, as some function use allocation hacks (static buffers) * and so on, which we want to suppress on leak reports. + * + * 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. */ typedef struct whitelist_t whitelist_t; @@ -170,13 +176,15 @@ struct whitelist_t { }; whitelist_t whitelist[] = { - {pthread_create, 0x500}, - {pthread_setspecific, 0xFF}, - {mktime, 0xFF}, - {inet_ntoa, 0xFF}, - {strerror, 0xFF}, - {getprotobynumber, 0xFF}, - {getservbyport, 0xFF}, + {pthread_create, 381}, + {pthread_setspecific, 256}, + {mktime, 60}, + {tzset, 126}, + {inet_ntoa, 256}, + {strerror, 173}, + {getprotobynumber, 294}, + {getservbyport, 309}, + {register_printf_function, 150}, }; /** diff --git a/src/libstrongswan/utils/logger.c b/src/libstrongswan/utils/logger.c index de323bb9a..26f42535e 100644 --- a/src/libstrongswan/utils/logger.c +++ b/src/libstrongswan/utils/logger.c @@ -22,7 +22,6 @@ */ #include <syslog.h> -#include <stdarg.h> #include <string.h> #include <stdio.h> #include <time.h> @@ -30,7 +29,6 @@ #include "logger.h" - /** * Maximum length of a log entry (only used for logger_s.log). */ @@ -180,40 +178,43 @@ static int get_priority(log_level_t loglevel) } /** - * Implementation of logger_t.log. - * - * Yes, logg is written wrong :-). + * Implementation of logger_t.logv. */ -static void logg(private_logger_t *this, log_level_t loglevel, const char *format, ...) +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]; - va_list args; - if (this->output == NULL) { /* syslog */ prepend_prefix(this, loglevel, format, buffer); - va_start(args, format); vsyslog(get_priority(loglevel), buffer, args); - va_end(args); } else { /* File output */ prepend_prefix(this, loglevel, format, buffer); - va_start(args, format); vfprintf(this->output, buffer, args); - va_end(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) @@ -357,6 +358,7 @@ logger_t *logger_create(char *logger_name, log_level_t log_level, bool log_threa /* 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; diff --git a/src/libstrongswan/utils/logger.h b/src/libstrongswan/utils/logger.h index 0bcd50d34..b24940d70 100644 --- a/src/libstrongswan/utils/logger.h +++ b/src/libstrongswan/utils/logger.h @@ -25,6 +25,7 @@ #define LOGGER_H_ #include <stdio.h> +#include <stdarg.h> #include <types.h> @@ -114,6 +115,19 @@ struct logger_t { 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 |