(no commit message)
authorMartin Willi <martin@strongswan.org>
Wed, 27 Sep 2006 14:15:49 +0000 (14:15 -0000)
committerMartin Willi <martin@strongswan.org>
Wed, 27 Sep 2006 14:15:49 +0000 (14:15 -0000)
12 files changed:
src/libstrongswan/crypto/crl.c
src/libstrongswan/crypto/x509.c
src/libstrongswan/definitions.h
src/libstrongswan/types.c
src/libstrongswan/types.h
src/libstrongswan/utils/host.c
src/libstrongswan/utils/host.h
src/libstrongswan/utils/identification.c
src/libstrongswan/utils/identification.h
src/libstrongswan/utils/leak_detective.c
src/libstrongswan/utils/logger.c
src/libstrongswan/utils/logger.h

index 95b6b5b..1f41c0a 100755 (executable)
@@ -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);
index 07745ba..dd82a49 100755 (executable)
@@ -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);
index 9b8b52d..1023584 100644 (file)
 
 #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"
 
 /**
  * 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[].
  * 
index 2ca0e4c..5f6b0b5 100644 (file)
@@ -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)
index 9874d5b..1f28d38 100644 (file)
@@ -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) }
index 4492578..702d4bd 100644 (file)
@@ -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:
index b9a97b1..38bdc80 100644 (file)
 
 #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_*/
index 4fbda0a..4932a1e 100644 (file)
@@ -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);
 }
index 5b13d02..3df710c 100644 (file)
 #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_ */
index 86071a5..9b4219e 100644 (file)
@@ -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},
 };
 
 /**
index de323bb..26f4253 100644 (file)
@@ -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;
index 0bcd50d..b24940d 100644 (file)
@@ -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