summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2008-07-09 21:02:41 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2008-07-09 21:02:41 +0000
commitdb67c87db3c9089ea8d2e14f617bf3d9e2af261f (patch)
tree665c0caea83d34c11c1517c4c57137bb58cba6fb /src/libstrongswan/utils
parent1c088a8b6237ec67f63c23f97a0f2dc4e99af869 (diff)
downloadvyos-strongswan-db67c87db3c9089ea8d2e14f617bf3d9e2af261f.tar.gz
vyos-strongswan-db67c87db3c9089ea8d2e14f617bf3d9e2af261f.zip
[svn-upgrade] Integrating new upstream version, strongswan (4.2.4)
Diffstat (limited to 'src/libstrongswan/utils')
-rw-r--r--src/libstrongswan/utils/enumerator.c364
-rw-r--r--src/libstrongswan/utils/enumerator.h118
-rw-r--r--src/libstrongswan/utils/fetcher.c424
-rw-r--r--src/libstrongswan/utils/fetcher.h95
-rw-r--r--src/libstrongswan/utils/host.c156
-rw-r--r--src/libstrongswan/utils/host.h150
-rw-r--r--src/libstrongswan/utils/identification.c376
-rw-r--r--src/libstrongswan/utils/identification.h142
-rw-r--r--src/libstrongswan/utils/iterator.h95
-rw-r--r--src/libstrongswan/utils/leak_detective.c418
-rw-r--r--src/libstrongswan/utils/leak_detective.h42
-rw-r--r--src/libstrongswan/utils/lexparser.c19
-rw-r--r--src/libstrongswan/utils/lexparser.h39
-rw-r--r--src/libstrongswan/utils/linked_list.c253
-rw-r--r--src/libstrongswan/utils/linked_list.h201
-rw-r--r--src/libstrongswan/utils/mutex.c267
-rw-r--r--src/libstrongswan/utils/mutex.h123
-rw-r--r--src/libstrongswan/utils/optionsfrom.c10
-rw-r--r--src/libstrongswan/utils/optionsfrom.h38
-rw-r--r--src/libstrongswan/utils/randomizer.c165
-rw-r--r--src/libstrongswan/utils/randomizer.h114
21 files changed, 1841 insertions, 1768 deletions
diff --git a/src/libstrongswan/utils/enumerator.c b/src/libstrongswan/utils/enumerator.c
index 842a2e997..cac5d73fa 100644
--- a/src/libstrongswan/utils/enumerator.c
+++ b/src/libstrongswan/utils/enumerator.c
@@ -1,10 +1,3 @@
-/**
- * @file enumerator.c
- *
- * @brief Implementation of enumerator_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,10 +11,20 @@
* 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.
+ *
+ * $Id: enumerator.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "enumerator.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include <debug.h>
/**
* Implementation of enumerator_create_empty().enumerate
@@ -42,3 +45,350 @@ enumerator_t* enumerator_create_empty()
return this;
}
+/**
+ * Enumerator implementation for directory enumerator
+ */
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** directory handle */
+ DIR *dir;
+ /** absolute path of current file */
+ char full[PATH_MAX];
+ /** where directory part of full ends and relative file gets written */
+ char *full_end;
+} dir_enum_t;
+
+/**
+ * Implementation of enumerator_create_directory().destroy
+ */
+static void destroy_dir_enum(dir_enum_t *this)
+{
+ closedir(this->dir);
+ free(this);
+}
+
+/**
+ * Implementation of enumerator_create_directory().enumerate
+ */
+static bool enumerate_dir_enum(dir_enum_t *this, char **relative,
+ char **absolute, struct stat *st)
+{
+ struct dirent *entry = readdir(this->dir);
+ size_t len, remaining;
+
+ if (!entry)
+ {
+ return FALSE;
+ }
+ if (streq(entry->d_name, ".") || streq(entry->d_name, ".."))
+ {
+ return enumerate_dir_enum(this, relative, absolute, st);
+ }
+ if (relative)
+ {
+ *relative = entry->d_name;
+ }
+ if (absolute || st)
+ {
+ remaining = sizeof(this->full) - (this->full_end - this->full);
+ len = snprintf(this->full_end, remaining, "%s", entry->d_name);
+ if (len < 0 || len >= remaining)
+ {
+ DBG1("buffer too small to enumerate file '%s'", entry->d_name);
+ return FALSE;
+ }
+ if (absolute)
+ {
+ *absolute = this->full;
+ }
+ if (st)
+ {
+ if (stat(this->full, st))
+ {
+ DBG1("stat() on '%s' failed: %s", this->full, strerror(errno));
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * See header
+ */
+enumerator_t* enumerator_create_directory(char *path)
+{
+ size_t len;
+ dir_enum_t *this = malloc_thing(dir_enum_t);
+ this->public.enumerate = (void*)enumerate_dir_enum;
+ this->public.destroy = (void*)destroy_dir_enum;
+
+ if (*path == '\0')
+ {
+ path = "./";
+ }
+ len = snprintf(this->full, sizeof(this->full)-1, "%s", path);
+ if (len < 0 || len >= sizeof(this->full)-1)
+ {
+ DBG1("path string %s too long", path);
+ free(this);
+ return NULL;
+ }
+ /* append a '/' if not already done */
+ if (this->full[len-1] != '/')
+ {
+ this->full[len++] = '/';
+ this->full[len] = '\0';
+ }
+ this->full_end = &this->full[len];
+
+ this->dir = opendir(path);
+ if (this->dir == NULL)
+ {
+ DBG1("opening directory %s failed: %s", path, strerror(errno));
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+/**
+ * enumerator for nested enumerations
+ */
+typedef struct {
+ /* implements enumerator_t */
+ enumerator_t public;
+ /* outer enumerator */
+ enumerator_t *outer;
+ /* inner enumerator */
+ enumerator_t *inner;
+ /* constructor for inner enumerator */
+ enumerator_t *(*create_inner)(void *outer, void *data);
+ /* data to pass to constructor above */
+ void *data;
+ /* destructor for data */
+ void (*destroy_data)(void *data);
+} nested_enumerator_t;
+
+
+/**
+ * Implementation of enumerator_create_nested().enumerate()
+ */
+static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2,
+ void *v3, void *v4, void *v5)
+{
+ while (TRUE)
+ {
+ while (this->inner == NULL)
+ {
+ void *outer;
+
+ if (!this->outer->enumerate(this->outer, &outer))
+ {
+ return FALSE;
+ }
+ this->inner = this->create_inner(outer, this->data);
+ }
+ if (this->inner->enumerate(this->inner, v1, v2, v3, v4, v5))
+ {
+ return TRUE;
+ }
+ this->inner->destroy(this->inner);
+ this->inner = NULL;
+ }
+}
+
+/**
+ * Implementation of enumerator_create_nested().destroy()
+ **/
+static void destroy_nested(nested_enumerator_t *this)
+{
+ if (this->destroy_data)
+ {
+ this->destroy_data(this->data);
+ }
+ DESTROY_IF(this->inner);
+ this->outer->destroy(this->outer);
+ free(this);
+}
+
+/**
+ * See header
+ */
+enumerator_t *enumerator_create_nested(enumerator_t *outer,
+ enumerator_t *(inner_constructor)(void *outer, void *data),
+ void *data, void (*destroy_data)(void *data))
+{
+ nested_enumerator_t *enumerator = malloc_thing(nested_enumerator_t);
+
+ enumerator->public.enumerate = (void*)enumerate_nested;
+ enumerator->public.destroy = (void*)destroy_nested;
+ enumerator->outer = outer;
+ enumerator->inner = NULL;
+ enumerator->create_inner = (void*)inner_constructor;
+ enumerator->data = data;
+ enumerator->destroy_data = destroy_data;
+
+ return &enumerator->public;
+}
+
+/**
+ * enumerator for filtered enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ enumerator_t *unfiltered;
+ void *data;
+ bool (*filter)(void *data, ...);
+ void (*destructor)(void *data);
+} filter_enumerator_t;
+
+/**
+ * Implementation of enumerator_create_filter().destroy
+ */
+void destroy_filter(filter_enumerator_t *this)
+{
+ if (this->destructor)
+ {
+ this->destructor(this->data);
+ }
+ this->unfiltered->destroy(this->unfiltered);
+ free(this);
+}
+
+/**
+ * Implementation of enumerator_create_filter().enumerate
+ */
+bool enumerate_filter(filter_enumerator_t *this, void *o1, void *o2,
+ void *o3, void *o4, void *o5)
+{
+ void *i1, *i2, *i3, *i4, *i5;
+
+ while (this->unfiltered->enumerate(this->unfiltered, &i1, &i2, &i3, &i4, &i5))
+ {
+ if (this->filter(this->data, &i1, o1, &i2, o2, &i3, o3, &i4, o4, &i5, o5))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * see header
+ */
+enumerator_t *enumerator_create_filter(enumerator_t *unfiltered,
+ bool (*filter)(void *data, ...),
+ void *data, void (*destructor)(void *data))
+{
+ filter_enumerator_t *this = malloc_thing(filter_enumerator_t);
+
+ this->public.enumerate = (void*)enumerate_filter;
+ this->public.destroy = (void*)destroy_filter;
+ this->unfiltered = unfiltered;
+ this->filter = filter;
+ this->data = data;
+ this->destructor = destructor;
+
+ return &this->public;
+}
+
+/**
+ * enumerator for cleaner enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ enumerator_t *wrapped;
+ void (*cleanup)(void *data);
+ void *data;
+} cleaner_enumerator_t;
+
+/**
+ * Implementation of enumerator_create_cleanup().destroy
+ */
+static void destroy_cleaner(cleaner_enumerator_t *this)
+{
+ this->cleanup(this->data);
+ this->wrapped->destroy(this->wrapped);
+ free(this);
+}
+
+/**
+ * Implementation of enumerator_create_cleaner().enumerate
+ */
+static bool enumerate_cleaner(cleaner_enumerator_t *this, void *v1, void *v2,
+ void *v3, void *v4, void *v5)
+{
+ return this->wrapped->enumerate(this->wrapped, v1, v2, v3, v4, v5);
+}
+
+/**
+ * see header
+ */
+enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped,
+ void (*cleanup)(void *data), void *data)
+{
+ cleaner_enumerator_t *this = malloc_thing(cleaner_enumerator_t);
+
+ this->public.enumerate = (void*)enumerate_cleaner;
+ this->public.destroy = (void*)destroy_cleaner;
+ this->wrapped = wrapped;
+ this->cleanup = cleanup;
+ this->data = data;
+
+ return &this->public;
+}
+
+/**
+ * enumerator for single enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ void *item;
+ void (*cleanup)(void *item);
+ bool done;
+} single_enumerator_t;
+
+/**
+ * Implementation of enumerator_create_single().destroy
+ */
+static void destroy_single(single_enumerator_t *this)
+{
+ if (this->cleanup)
+ {
+ this->cleanup(this->item);
+ }
+ free(this);
+}
+
+/**
+ * Implementation of enumerator_create_single().enumerate
+ */
+static bool enumerate_single(single_enumerator_t *this, void **item)
+{
+ if (this->done)
+ {
+ return FALSE;
+ }
+ *item = this->item;
+ this->done = TRUE;
+ return TRUE;
+}
+
+/**
+ * see header
+ */
+enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item))
+{
+ single_enumerator_t *this = malloc_thing(single_enumerator_t);
+
+ this->public.enumerate = (void*)enumerate_single;
+ this->public.destroy = (void*)destroy_single;
+ this->item = item;
+ this->cleanup = cleanup;
+ this->done = FALSE;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/utils/enumerator.h b/src/libstrongswan/utils/enumerator.h
index df1d78206..6b91fee72 100644
--- a/src/libstrongswan/utils/enumerator.h
+++ b/src/libstrongswan/utils/enumerator.h
@@ -1,10 +1,3 @@
-/**
- * @file enumerator.h
- *
- * @brief Interface of enumerator_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,22 +11,29 @@
* 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.
+ *
+ * $Id: enumerator.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup enumerator enumerator
+ * @{ @ingroup utils
*/
#ifndef ENUMERATOR_H_
#define ENUMERATOR_H_
-#include <library.h>
-
typedef struct enumerator_t enumerator_t;
+#include <library.h>
+
/**
- * @brief Enumerate is simpler, but more flexible than iterator.
+ * Enumerate is simpler, but more flexible than iterator.
*/
struct enumerator_t {
/**
- * @brief Enumerate collection.
+ * Enumerate collection.
*
* The enumerate function takes a variable argument list containing
* pointers where the enumerated values get written.
@@ -44,14 +44,104 @@ struct enumerator_t {
bool (*enumerate)(enumerator_t *this, ...);
/**
- * @brief Destroy a enumerator instance.
+ * Destroy a enumerator instance.
*/
void (*destroy)(enumerator_t *this);
};
/**
- * @brief Create an enumerator which enumerates over nothing
+ * Create an enumerator which enumerates over nothing
+ *
+ * @return an enumerator over no values
*/
enumerator_t* enumerator_create_empty();
-#endif /* ENUMERATOR_H_ */
+/**
+ * Create an enumerator which enumerates over a single item
+ *
+ * @param item item to enumerate
+ * @param cleanup cleanup function called on destroy with the item
+ * @return an enumerator over a single value
+ */
+enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item));
+
+/**
+ * Create an enumerator over files/subdirectories in a directory.
+ *
+ * This enumerator_t.enumerate() function returns a (to the directory) relative
+ * filename (as a char*), an absolute filename (as a char*) and a file status
+ * (to a struct stat), which all may be NULL. "." and ".." entries are
+ * skipped. Example:
+ *
+ * @code
+ char *rel, *abs;
+ struct stat st;
+ enumerator_t *e;
+
+ e = enumerator_create_directory("/tmp");
+ if (e)
+ {
+ while (e->enumerate(e, &rel, &abs, &st))
+ {
+ if (S_ISDIR(st.st_mode) && *rel != '.')
+ {
+ printf("%s\n", abs);
+ }
+ }
+ e->destroy(e);
+ }
+ @endcode
+ *
+ * @param path path of the directory
+ * @return the directory enumerator, NULL on failure
+ */
+enumerator_t* enumerator_create_directory(char *path);
+
+/**
+ * Creates an enumerator which enumerates over enumerated enumerators :-).
+ *
+ * The variable argument list of enumeration values is limit to 5.
+ *
+ * @param outer outer enumerator
+ * @param inner_constructor constructor to inner enumerator
+ * @param data data to pass to each inner_constructor call
+ * @param destroy_data destructor to pass to data
+ * @return the nested enumerator
+ */
+enumerator_t *enumerator_create_nested(enumerator_t *outer,
+ enumerator_t *(inner_constructor)(void *outer, void *data),
+ void *data, void (*destroy_data)(void *data));
+
+/**
+ * Creates an enumerator which filters output of another enumerator.
+ *
+ * The filter function receives the user supplied "data" followed by a
+ * unfiltered enumeration item, followed by an output pointer where to write
+ * the filtered data. Then the next input/output pair follows.
+ * It returns TRUE to deliver the
+ * values to the caller of enumerate(), FALSE to filter this enumeration.
+ *
+ * The variable argument list of enumeration values is limit to 5.
+ *
+ * @param unfiltered unfiltered enumerator to wrap, gets destroyed
+ * @param filter filter function
+ * @param data user data to supply to filter
+ * @param destructor destructor function to clean up data after use
+ * @return the filtered enumerator
+ */
+enumerator_t *enumerator_create_filter(enumerator_t *unfiltered,
+ bool (*filter)(void *data, ...),
+ void *data, void (*destructor)(void *data));
+
+/**
+ * Create an enumerator wrapper which does a cleanup on destroy.
+ *
+ * @param wrapped wrapped enumerator
+ * @param cleanup cleanup function called on destroy
+ * @param data user data to supply to cleanup
+ * @return the enumerator with cleanup
+ */
+enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped,
+ void (*cleanup)(void *data), void *data);
+
+#endif /* ENUMERATOR_H_ @} */
diff --git a/src/libstrongswan/utils/fetcher.c b/src/libstrongswan/utils/fetcher.c
deleted file mode 100644
index 7a06999aa..000000000
--- a/src/libstrongswan/utils/fetcher.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/**
- * @file fetcher.c
- *
- * @brief Implementation of fetcher_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Andreas Steffen
- * 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 <fetcher://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.
- */
-
-#ifdef LIBCURL
-#include <curl/curl.h>
-#endif /* LIBCURL */
-
-#ifdef LIBLDAP
-#ifndef LDAP_DEPRECATED
-#define LDAP_DEPRECATED 1
-#endif
-#include <ldap.h>
-#endif /* LIBLDAP */
-
-#include <library.h>
-#include <debug.h>
-
-#include "fetcher.h"
-
-typedef struct private_fetcher_t private_fetcher_t;
-
-/**
- * @brief Private Data of a fetcher_t object.
- */
-struct private_fetcher_t {
- /**
- * Public data
- */
- fetcher_t public;
-
- /**
- * URI of the information source
- */
- const char *uri;
-
-#ifdef LIBCURL
- /**
- * we use libcurl from http://curl.haxx.se/ as a fetcher
- */
- CURL* curl;
-#endif /* LIBCURL */
-
-#ifdef LIBLDAP
- /**
- * we use libldap from http://www.openssl.org/ as a fetcher
- */
- LDAP *ldap;
- LDAPURLDesc *lurl;
-#endif /* LIBLDAP */
-};
-
-/**
- * writes data into a dynamically resizeable chunk_t
- * needed for libcurl responses
- */
-static size_t curl_write_buffer(void *ptr, size_t size, size_t nmemb, void *data)
-{
- size_t realsize = size * nmemb;
- chunk_t *mem = (chunk_t*)data;
-
- mem->ptr = (u_char *)realloc(mem->ptr, mem->len + realsize);
- if (mem->ptr) {
- memcpy(&(mem->ptr[mem->len]), ptr, realsize);
- mem->len += realsize;
- }
- return realsize;
-}
-
-/**
- * Implements fetcher_t.get for curl methods
- */
-static chunk_t curl_get(private_fetcher_t *this)
-{
- chunk_t response = chunk_empty;
-
-#ifdef LIBCURL
- if (this->curl)
- {
- CURLcode res;
- chunk_t curl_response = chunk_empty;
- char curl_error_buffer[CURL_ERROR_SIZE];
-
- curl_easy_setopt(this->curl, CURLOPT_URL, this->uri);
- curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, curl_write_buffer);
- curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void *)&curl_response);
- curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, &curl_error_buffer);
- curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
- curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, FETCHER_TIMEOUT);
- curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
-
- DBG1("sending curl request to '%s'...", this->uri);
- res = curl_easy_perform(this->curl);
-
- if (res == CURLE_OK)
- {
- DBG1("received valid curl response");
- response = chunk_clone(curl_response);
- }
- else
- {
- DBG1("curl request failed: %s", curl_error_buffer);
- }
- curl_free(curl_response.ptr);
- }
-#else
- DBG1("warning: libcurl fetching not compiled in");
-#endif /* LIBCURL */
- return response;
-}
-
-/**
- * Implements fetcher_t.post.
- */
-static chunk_t http_post(private_fetcher_t *this, const char *request_type, chunk_t request)
-{
- chunk_t response = chunk_empty;
-
-#ifdef LIBCURL
- if (this->curl)
- {
- CURLcode res;
- struct curl_slist *headers = NULL;
- chunk_t curl_response = chunk_empty;
- char curl_error_buffer[CURL_ERROR_SIZE];
- char content_type[BUF_LEN];
-
- /* set content type header */
- snprintf(content_type, BUF_LEN, "Content-Type: %s", request_type);
- headers = curl_slist_append(headers, content_type);
-
- /* set options */
- curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(this->curl, CURLOPT_URL, this->uri);
- curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, curl_write_buffer);
- curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void *)&curl_response);
- curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, request.ptr);
- curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, request.len);
- curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, &curl_error_buffer);
- curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
- curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, FETCHER_TIMEOUT);
- curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
-
- DBG1("sending http post request to '%s'...", this->uri);
- res = curl_easy_perform(this->curl);
-
- if (res == CURLE_OK)
- {
- DBG1("received valid http response");
- response = chunk_clone(curl_response);
- }
- else
- {
- DBG1("http post request using libcurl failed: %s", curl_error_buffer);
- }
- curl_slist_free_all(headers);
- curl_free(curl_response.ptr);
- }
-#else
- DBG1("warning: libcurl fetching not compiled in");
-#endif /* LIBCURL */
- return response;
-}
-
-#ifdef LIBLDAP
-/**
- * Parses the result returned by an ldap query
- */
-static chunk_t ldap_parse(LDAP *ldap, LDAPMessage *result)
-{
- chunk_t response = chunk_empty;
- err_t ugh = NULL;
-
- LDAPMessage *entry = ldap_first_entry(ldap, result);
-
- if (entry != NULL)
- {
- BerElement *ber = NULL;
- char *attr;
-
- attr = ldap_first_attribute(ldap, entry, &ber);
-
- if (attr != NULL)
- {
- struct berval **values = ldap_get_values_len(ldap, entry, attr);
-
- if (values != NULL)
- {
- if (values[0] != NULL)
- {
- response.len = values[0]->bv_len;
- response.ptr = malloc(response.len);
- memcpy(response.ptr, values[0]->bv_val, response.len);
-
- if (values[1] != NULL)
- {
- ugh = "more than one value was fetched - first selected";
- }
- }
- else
- {
- ugh = "no values in attribute";
- }
- ldap_value_free_len(values);
- }
- else
- {
- ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
- }
- ldap_memfree(attr);
- }
- else
- {
- ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
- }
- ber_free(ber, 0);
- }
- else
- {
- ugh = ldap_err2string(ldap_result2error(ldap, result, 0));
- }
- if (ugh)
- {
- DBG1("ldap request failed: %s", ugh);
- }
- return response;
-}
-#endif /* LIBLDAP */
-
-/**
- * Implements fetcher_t.get for curl methods
- */
-static chunk_t ldap_get(private_fetcher_t *this)
-{
- chunk_t response = chunk_empty;
-
-#ifdef LIBLDAP
- if (this->ldap)
- {
- err_t ugh = NULL;
- int rc;
- int ldap_version = LDAP_VERSION3;
-
- struct timeval timeout;
-
- timeout.tv_sec = FETCHER_TIMEOUT;
- timeout.tv_usec = 0;
-
- ldap_set_option(this->ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
- ldap_set_option(this->ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
-
- DBG1("sending ldap request to '%s'...", this->uri);
-
- rc = ldap_simple_bind_s(this->ldap, NULL, NULL);
- if (rc == LDAP_SUCCESS)
- {
- LDAPMessage *result;
-
- timeout.tv_sec = FETCHER_TIMEOUT;
- timeout.tv_usec = 0;
-
- rc = ldap_search_st(this->ldap, this->lurl->lud_dn,
- this->lurl->lud_scope,
- this->lurl->lud_filter,
- this->lurl->lud_attrs,
- 0, &timeout, &result);
-
- if (rc == LDAP_SUCCESS)
- {
- response = ldap_parse(this->ldap, result);
- if (response.ptr)
- {
- DBG1("received valid ldap response");
- }
- ldap_msgfree(result);
- }
- else
- {
- ugh = ldap_err2string(rc);
- }
- }
- else
- {
- ugh = ldap_err2string(rc);
- }
- ldap_unbind_s(this->ldap);
-
- if (ugh)
- {
- DBG1("ldap request failed: %s", ugh);
- }
- }
-#else /* !LIBLDAP */
- DBG1("warning: libldap fetching not compiled in");
-#endif /* !LIBLDAP */
- return response;
-}
-
-/**
- * Implements fetcher_t.destroy
- */
-static void destroy(private_fetcher_t *this)
-{
-#ifdef LIBCURL
- if (this->curl)
- {
- curl_easy_cleanup(this->curl);
- }
-#endif /* LIBCURL */
-
-#ifdef LIBLDAP
- if (this->lurl)
- {
- ldap_free_urldesc(this->lurl);
- }
-#endif /* LIBLDAP */
-
- free(this);
-}
-
-/*
- * Described in header.
- */
-fetcher_t *fetcher_create(const char *uri)
-{
- private_fetcher_t *this = malloc_thing(private_fetcher_t);
-
- /* initialize */
- this->uri = uri;
-
-#ifdef LIBCURL
- this->curl = NULL;
-#endif /* LIBCURL */
-
-#ifdef LIBLDAP
- this->lurl = NULL;
- this->ldap = NULL;
-#endif /* LIBLDAP */
-
- if (strlen(uri) >= 4 && strncasecmp(uri, "ldap", 4) == 0)
- {
-#ifdef LIBLDAP
- int rc = ldap_url_parse(uri, &this->lurl);
-
- if (rc == LDAP_SUCCESS)
- {
- this->ldap = ldap_init(this->lurl->lud_host,
- this->lurl->lud_port);
- }
- else
- {
- DBG1("ldap: %s", ldap_err2string(rc));
- this->ldap = NULL;
- }
-#endif /* LIBLDAP */
- this->public.get = (chunk_t (*) (fetcher_t*))ldap_get;
- }
- else
- {
-#ifdef LIBCURL
- this->curl = curl_easy_init();
- if (this->curl == NULL)
- {
- DBG1("curl_easy_init_failed()");
- }
-#endif /* LIBCURL */
- this->public.get = (chunk_t (*) (fetcher_t*))curl_get;
- }
-
- /* public functions */
- this->public.post = (chunk_t (*) (fetcher_t*,const char*,chunk_t))http_post;
- this->public.destroy = (void (*) (fetcher_t*))destroy;
-
- return &this->public;
-}
-
-/**
- * Described in header.
- */
-void fetcher_initialize(void)
-{
-#ifdef LIBCURL
- CURLcode res;
-
- /* initialize libcurl */
- DBG1("initializing libcurl");
- res = curl_global_init(CURL_GLOBAL_NOTHING);
- if (res != CURLE_OK)
- {
- DBG1("libcurl could not be initialized: %s", curl_easy_strerror(res));
- }
-#endif /* LIBCURL */
-}
-
-/**
- * Described in header.
- */
-void fetcher_finalize(void)
-{
-#ifdef LIBCURL
- /* finalize libcurl */
- DBG1("finalizing libcurl");
- curl_global_cleanup();
-#endif /* LIBCURL */
-}
-
diff --git a/src/libstrongswan/utils/fetcher.h b/src/libstrongswan/utils/fetcher.h
deleted file mode 100644
index 47b43a0b7..000000000
--- a/src/libstrongswan/utils/fetcher.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file fetcher.h
- *
- * @brief Interface of fetcher_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Andreas Steffen
- * 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 <fetcher://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 FETCHER_H_
-#define FETCHER_H_
-
-typedef struct fetcher_t fetcher_t;
-
-#include <chunk.h>
-
-#define FETCHER_TIMEOUT 10 /* seconds */
-
-/**
- * @brief Fetches information from an URI (http, file, ftp, etc.)
- *
- * @ingroup utils
- */
-struct fetcher_t {
-
- /**
- * @brief Get information via a get request.
- *
- * @param this calling object
- * @param uri uri specifying the information source
- * @return chunk_t containing the information
- */
- chunk_t (*get) (fetcher_t *this);
-
- /**
- * @brief Get information via a get request.
- *
- * @param this calling object
- * @param uri uri specifying the information source
- * @param type content type of http post request
- * @param request binary data for http post request
- * @return chunk_t containing the information
- */
- chunk_t (*post) (fetcher_t *this, const char *type, chunk_t request);
-
- /**
- * @brief Destroys the fetcher_t object.
- *
- * @param this fetcher_t to destroy
- */
- void (*destroy) (fetcher_t *this);
-
-};
-
-/**
- * @brief Create a fetcher_t object.
- *
- * @return created fetcher_t object
- *
- * @ingroup utils
- */
-fetcher_t* fetcher_create(const char *uri);
-
-/**
- * @brief Initializes the fetcher_t class
- *
- * call this function only once in the main program
- *
- * @ingroup utils
- */
-void fetcher_initialize(void);
-
-/**
- * @brief Finalizes the fetcher_t class
- *
- * call this function only once befor exiting the main program
- *
- * @ingroup utils
- */
-void fetcher_finalize(void);
-
-#endif /*FETCHER_H_*/
diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c
index 68e9c9500..eb87f27bc 100644
--- a/src/libstrongswan/utils/host.c
+++ b/src/libstrongswan/utils/host.c
@@ -1,10 +1,3 @@
-/**
- * @file host.c
- *
- * @brief Implementation of host_t.
- *
- */
-
/*
* Copyright (C) 2006-2007 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
@@ -21,18 +14,23 @@
* 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.
+ *
+ * $Id: host.c 4056 2008-06-11 07:44:23Z martin $
*/
+#define _GNU_SOURCE
+#include <netdb.h>
#include <string.h>
#include <printf.h>
#include "host.h"
+#include <debug.h>
typedef struct private_host_t private_host_t;
/**
- * @brief Private Data of a host object.
+ * Private Data of a host object.
*/
struct private_host_t {
/**
@@ -111,56 +109,79 @@ 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;
+ char buffer[INET6_ADDRSTRLEN + 16];
if (this == NULL)
{
- return fprintf(stream, "(null)");
+ snprintf(buffer, sizeof(buffer), "(null)");
}
-
- if (is_anyaddr(this))
+ else if (is_anyaddr(this))
{
- return fprintf(stream, "%%any");
+ snprintf(buffer, sizeof(buffer), "%%any");
}
-
- switch (this->address.sa_family)
+ else
{
- case AF_INET:
- address = &this->address4.sin_addr;
- port = this->address4.sin_port;
- break;
- case AF_INET6:
- address = &this->address6.sin6_addr;
- port = this->address6.sin6_port;
- break;
- default:
- return fprintf(stream, "(family not supported)");
- }
+ void *address;
+ u_int16_t port;
+ int len;
+
+ address = &this->address6.sin6_addr;
+ port = this->address6.sin6_port;
+
+ switch (this->address.sa_family)
+ {
+ case AF_INET:
+ address = &this->address4.sin_addr;
+ port = this->address4.sin_port;
+ /* fall */
+ case AF_INET6:
- if (inet_ntop(this->address.sa_family, address,
- buffer, sizeof(buffer)) == NULL)
- {
- return fprintf(stream, "(address conversion failed)");
+ if (inet_ntop(this->address.sa_family, address,
+ buffer, sizeof(buffer)) == NULL)
+ {
+ snprintf(buffer, sizeof(buffer),
+ "(address conversion failed)");
+ }
+ else if (info->alt)
+ {
+ len = strlen(buffer);
+ snprintf(buffer + len, sizeof(buffer) - len,
+ "[%d]", ntohs(port));
+ }
+ break;
+ default:
+ snprintf(buffer, sizeof(buffer), "(family not supported)");
+ break;
+ }
}
-
- if (info->alt)
+ if (info->left)
{
- return fprintf(stream, "%s[%d]", buffer, ntohs(port));
+ return fprintf(stream, "%-*s", info->width, buffer);
}
- else
+ return fprintf(stream, "%*s", info->width, buffer);
+}
+
+
+/**
+ * arginfo handler for printf() hosts
+ */
+int arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (n > 0)
{
- return fprintf(stream, "%s", buffer);
+ argtypes[0] = PA_POINTER;
}
+ return 1;
}
/**
- * register printf() handlers
+ * return printf hook functions for a host
*/
-static void __attribute__ ((constructor))print_register()
+printf_hook_functions_t host_get_printf_hooks()
{
- register_printf_function(PRINTF_HOST, print, arginfo_ptr);
+ printf_hook_functions_t hooks = {print, arginfo};
+
+ return hooks;
}
/**
@@ -433,6 +454,61 @@ host_t *host_create_from_string(char *string, u_int16_t port)
/*
* Described in header.
*/
+host_t *host_create_from_dns(char *string, int af, u_int16_t port)
+{
+ private_host_t *this;
+ struct hostent host, *ptr;
+ char buf[512];
+ int err, ret;
+
+ if (strchr(string, ':'))
+ { /* gethostbyname does not like IPv6 addresses, fallback */
+ return host_create_from_string(string, port);
+ }
+
+ if (af)
+ {
+ ret = gethostbyname2_r(string, af, &host, buf, sizeof(buf), &ptr, &err);
+ }
+ else
+ {
+ ret = gethostbyname_r(string, &host, buf, sizeof(buf), &ptr, &err);
+ }
+ if (ret != 0)
+ {
+ DBG1("resolving '%s' failed: %s", string, hstrerror(err));
+ return NULL;
+ }
+ if (ptr == NULL)
+ {
+ DBG1("resolving '%s' failed", string);
+ }
+ this = host_create_empty();
+ this->address.sa_family = host.h_addrtype;
+ switch (this->address.sa_family)
+ {
+ case AF_INET:
+ memcpy(&this->address4.sin_addr.s_addr,
+ host.h_addr_list[0], host.h_length);
+ this->address4.sin_port = htons(port);
+ this->socklen = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ memcpy(&this->address6.sin6_addr.s6_addr,
+ host.h_addr_list[0], host.h_length);
+ this->address6.sin6_port = htons(port);
+ this->socklen = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+/*
+ * Described in header.
+ */
host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port)
{
private_host_t *this = host_create_empty();
diff --git a/src/libstrongswan/utils/host.h b/src/libstrongswan/utils/host.h
index ee9aa457f..6a1d824c6 100644
--- a/src/libstrongswan/utils/host.h
+++ b/src/libstrongswan/utils/host.h
@@ -1,14 +1,7 @@
-/**
- * @file host.h
- *
- * @brief Interface of host_t.
- *
- */
-
/*
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2006-2007 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -23,6 +16,11 @@
* for more details.
*/
+/**
+ * @defgroup host host
+ * @{ @ingroup utils
+ */
+
#ifndef HOST_H_
#define HOST_H_
@@ -49,42 +47,31 @@ enum host_diff_t {
};
/**
- * @brief Representates a Host
+ * Representates a Host
*
* Host object, identifies a address:port pair and defines some
* useful functions on it.
- *
- * @b Constructors:
- * - host_create()
- * - host_create_from_chunk()
- * - host_create_from_sockaddr()
- *
- * @todo Add IPv6 support
- *
- * @ingroup utils
*/
struct host_t {
/**
- * @brief Build a clone of this host object.
+ * Build a clone of this host object.
*
- * @param this object to clone
- * @return cloned host
+ * @return cloned host
*/
host_t *(*clone) (host_t *this);
/**
- * @brief Get a pointer to the internal sockaddr struct.
+ * Get a pointer to the internal sockaddr struct.
*
* This is used for sending and receiving via sockets.
*
- * @param this object to clone
- * @return pointer to the internal sockaddr structure
+ * @return pointer to the internal sockaddr structure
*/
sockaddr_t *(*get_sockaddr) (host_t *this);
/**
- * @brief Get the length of the sockaddr struct.
+ * Get the length of the sockaddr struct.
*
* Depending on the family, the length of the sockaddr struct
* is different. Use this function to get the length of the sockaddr
@@ -92,140 +79,129 @@ struct host_t {
*
* This is used for sending and receiving via sockets.
*
- * @param this object to clone
- * @return length of the sockaddr struct
+ * @return length of the sockaddr struct
*/
socklen_t *(*get_sockaddr_len) (host_t *this);
/**
- * @brief Gets the family of the address
+ * Gets the family of the address
*
- * @param this calling object
- * @return family
+ * @return family
*/
int (*get_family) (host_t *this);
/**
- * @brief Checks if the ip address of host is set to default route.
+ * Checks if the ip address of host is set to default route.
*
- * @param this calling object
- * @return
- * - TRUE if host has IP 0.0.0.0 for default route
- * - FALSE otherwise
+ * @return TRUE if host is 0.0.0.0 or 0::0, FALSE otherwise
*/
bool (*is_anyaddr) (host_t *this);
/**
- * @brief get the address of this host as chunk_t
+ * Get the address of this host as chunk_t
*
* Returned chunk points to internal data.
*
- * @param this object
- * @return address string,
+ * @return address string,
*/
chunk_t (*get_address) (host_t *this);
/**
- * @brief get the port of this host
+ * Get the port of this host
*
- * @param this object to clone
- * @return port number
+ * @return port number
*/
u_int16_t (*get_port) (host_t *this);
/**
- * @brief set the port of this host
+ * Set the port of this host
*
- * @param this object to clone
- * @param port port numer
+ * @param port port numer
*/
void (*set_port) (host_t *this, u_int16_t port);
/**
- * @brief Compare the ips of two hosts hosts.
+ * Compare the ips of two hosts hosts.
*
- * @param this object to compare
- * @param other the other to compare
- * @return TRUE if addresses are equal.
+ * @param other the other to compare
+ * @return TRUE if addresses are equal.
*/
bool (*ip_equals) (host_t *this, host_t *other);
/**
- * @brief Compare two hosts, with port.
+ * Compare two hosts, with port.
*
- * @param this object to compare
- * @param other the other to compare
- * @return TRUE if addresses and ports are equal.
+ * @param other the other to compare
+ * @return TRUE if addresses and ports are equal.
*/
bool (*equals) (host_t *this, host_t *other);
/**
- * @brief Compare two hosts and return the differences.
+ * Compare two hosts and return the differences.
*
- * @param this object to compare
- * @param other the other to compare
- * @return differences in a combination of host_diff_t's
+ * @param other the other to compare
+ * @return differences in a combination of host_diff_t's
*/
host_diff_t (*get_differences) (host_t *this, host_t *other);
/**
- * @brief Destroy this host object
- *
- * @param this calling
- * @return SUCCESS in any case
+ * Destroy this host object.
*/
void (*destroy) (host_t *this);
};
/**
- * @brief Constructor to create a host_t object from an address string.
+ * 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
- * @return
- * - host_t object
- * - NULL, if string not an address.
- *
- * @ingroup network
+ * @return host_t, NULL if string not an address.
*/
host_t *host_create_from_string(char *string, u_int16_t port);
/**
- * @brief Constructor to create a host_t object from an address chunk
+ * Constructor to create a host_t from a DNS name.
*
- * @param family Address family to use for this object, such as AF_INET or AF_INET6
- * @param address address as 4 byte chunk_t in networ order
+ * @param string hostname to resolve
+ * @param family family to prefer, 0 for first match
* @param port port number
- * @return
- * - host_t object
- * - NULL, if family not supported or chunk_t length not 4 bytes.
- *
- * @ingroup network
+ * @return host_t, NULL lookup failed
+ */
+host_t *host_create_from_dns(char *string, int family, u_int16_t port);
+
+/**
+ * Constructor to create a host_t object from an address chunk
+ *
+ * @param family Address family, such as AF_INET or AF_INET6
+ * @param address address as chunk_t in networ order
+ * @param port port number
+ * @return host_t, NULL if family not supported/chunk invalid
*/
host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port);
/**
- * @brief Constructor to create a host_t object from a sockaddr struct
+ * Constructor to create a host_t object from a sockaddr struct
*
* @param sockaddr sockaddr struct which contains family, address and port
- * @return
- * - host_t object
- * - NULL, if family not supported.
- *
- * @ingroup network
+ * @return host_t, NULL if family not supported
*/
host_t *host_create_from_sockaddr(sockaddr_t *sockaddr);
/**
- * @brief Create a host without an address, a "any" host.
+ * Create a host without an address, a "any" host.
*
* @param family family of the any host
- * @return
- * - host_t object
- * - NULL, if family not supported.
- *
- * @ingroup network
+ * @return host_t, NULL if family not supported
*/
host_t *host_create_any(int family);
-#endif /*HOST_H_*/
+/**
+ * Get printf hooks for a host.
+ *
+ * Arguments are:
+ * host_t *host
+ * Use #-modifier to include port number
+ */
+printf_hook_functions_t host_get_printf_hooks();
+
+#endif /* HOST_H_ @}*/
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index 18f6d6824..39d49bf6c 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -1,12 +1,5 @@
-/**
- * @file identification.c
- *
- * @brief Implementation of identification_t.
- *
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -20,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: identification.c 3256 2007-10-07 13:42:43Z andreas $
+ * $Id: identification.c 4064 2008-06-13 15:10:01Z martin $
*/
#define _GNU_SOURCE
@@ -34,8 +27,17 @@
#include "identification.h"
+#include <asn1/oid.h>
#include <asn1/asn1.h>
+ENUM_BEGIN(id_match_names, ID_MATCH_NONE, ID_MATCH_MAX_WILDCARDS,
+ "MATCH_NONE",
+ "MATCH_ANY",
+ "MATCH_MAX_WILDCARDS");
+ENUM_NEXT(id_match_names, ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_MAX_WILDCARDS,
+ "MATCH_PERFECT");
+ENUM_END(id_match_names, ID_MATCH_PERFECT);
+
ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID,
"ID_ANY",
"ID_IPV4_ADDR",
@@ -49,10 +51,12 @@ ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID,
"ID_DER_ASN1_DN",
"ID_DER_ASN1_GN",
"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_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_CERT_DER_SHA1, ID_KEY_ID,
+ "ID_DER_ASN1_GN_URI",
+ "ID_PUBKEY_INFO_SHA1",
+ "ID_PUBKEY_SHA1",
+ "ID_CERT_DER_SHA1");
+ENUM_END(id_type_names, ID_CERT_DER_SHA1);
/**
* X.501 acronyms for well known object identifiers (OIDs)
@@ -237,7 +241,7 @@ static chunk_t sanitize_chunk(chunk_t chunk)
/**
* Pointer is set to the first RDN in a DN
*/
-static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
+static bool init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
{
*rdn = chunk_empty;
*attribute = chunk_empty;
@@ -246,7 +250,7 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex
if (*dn.ptr != ASN1_SEQUENCE)
{
/* DN is not a SEQUENCE */
- return FAILED;
+ return FALSE;
}
rdn->len = asn1_length(&dn);
@@ -254,7 +258,7 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex
if (rdn->len == ASN1_INVALID_LENGTH)
{
/* Invalid RDN length */
- return FAILED;
+ return FALSE;
}
rdn->ptr = dn.ptr;
@@ -262,13 +266,13 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex
/* are there any RDNs ? */
*next = rdn->len > 0;
- return SUCCESS;
+ return TRUE;
}
/**
* Fetches the next RDN in a DN
*/
-static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value, asn1_t *type, bool *next)
+static bool get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value, asn1_t *type, bool *next)
{
chunk_t body;
@@ -283,13 +287,13 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (*rdn->ptr != ASN1_SET)
{
/* RDN is not a SET */
- return FAILED;
+ return FALSE;
}
attribute->len = asn1_length(rdn);
if (attribute->len == ASN1_INVALID_LENGTH)
{
/* Invalid attribute length */
- return FAILED;
+ return FALSE;
}
attribute->ptr = rdn->ptr;
/* advance to start of next RDN */
@@ -301,7 +305,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (*attribute->ptr != ASN1_SEQUENCE)
{
/* attributeTypeAndValue is not a SEQUENCE */
- return FAILED;
+ return FALSE;
}
/* extract the attribute body */
@@ -310,7 +314,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (body.len == ASN1_INVALID_LENGTH)
{
/* Invalid attribute body length */
- return FAILED;
+ return FALSE;
}
body.ptr = attribute->ptr;
@@ -323,7 +327,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (*body.ptr != ASN1_OID)
{
/* attributeType is not an OID */
- return FAILED;
+ return FALSE;
}
/* extract OID */
oid->len = asn1_length(&body);
@@ -331,7 +335,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (oid->len == ASN1_INVALID_LENGTH)
{
/* Invalid attribute OID length */
- return FAILED;
+ return FALSE;
}
oid->ptr = body.ptr;
@@ -348,19 +352,19 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (value->len == ASN1_INVALID_LENGTH)
{
/* Invalid attribute string length */
- return FAILED;
+ return FALSE;
}
value->ptr = body.ptr;
/* are there any RDNs left? */
*next = rdn->len > 0 || attribute->len > 0;
- return SUCCESS;
+ return TRUE;
}
/**
* Parses an ASN.1 distinguished name int its OID/value pairs
*/
-static status_t dntoa(chunk_t dn, chunk_t *str)
+static bool dntoa(chunk_t dn, chunk_t *str)
{
chunk_t rdn, oid, attribute, value, proper;
asn1_t type;
@@ -368,17 +372,17 @@ static status_t dntoa(chunk_t dn, chunk_t *str)
bool next;
bool first = TRUE;
- status_t status = init_rdn(dn, &rdn, &attribute, &next);
-
- if (status != SUCCESS)
- return status;
+ if (!init_rdn(dn, &rdn, &attribute, &next))
+ {
+ return FALSE;
+ }
while (next)
{
- status = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
-
- if (status != SUCCESS)
- return status;
+ if (!get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next))
+ {
+ return FALSE;
+ }
if (first)
{ /* first OID/value pair */
@@ -390,7 +394,7 @@ static status_t dntoa(chunk_t dn, chunk_t *str)
}
/* print OID */
- oid_code = known_oid(oid);
+ oid_code = asn1_known_oid(oid);
if (oid_code == OID_UNKNOWN)
{
update_chunk(str, snprintf(str->ptr,str->len,"0x#B", &oid));
@@ -404,7 +408,7 @@ static status_t dntoa(chunk_t dn, chunk_t *str)
update_chunk(str, snprintf(str->ptr,str->len,"=%.*s", (int)proper.len, proper.ptr));
chunk_free(&proper);
}
- return SUCCESS;
+ return TRUE;
}
/**
@@ -420,15 +424,17 @@ static bool same_dn(chunk_t a, chunk_t b)
/* same lengths for the DNs */
if (a.len != b.len)
+ {
return FALSE;
-
+ }
/* try a binary comparison first */
if (memeq(a.ptr, b.ptr, b.len))
+ {
return TRUE;
-
+ }
/* initialize DN parsing */
- if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != SUCCESS
- || init_rdn(b, &rdn_b, &attribute_b, &next_b) != SUCCESS)
+ if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) ||
+ !init_rdn(b, &rdn_b, &attribute_b, &next_b))
{
return FALSE;
}
@@ -437,23 +443,27 @@ static bool same_dn(chunk_t a, chunk_t b)
while (next_a && next_b)
{
/* parse next RDNs and check for errors */
- if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != SUCCESS
- || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != SUCCESS)
+ if (!get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) ||
+ !get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b))
{
return FALSE;
}
/* OIDs must agree */
- if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
+ if (oid_a.len != oid_b.len || !memeq(oid_a.ptr, oid_b.ptr, oid_b.len))
+ {
return FALSE;
+ }
/* same lengths for values */
if (value_a.len != value_b.len)
+ {
return FALSE;
+ }
/* printableStrings and email RDNs require uppercase comparison */
- if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING
- || (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
+ if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
+ (type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL)))
{
if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
{
@@ -470,8 +480,9 @@ static bool same_dn(chunk_t a, chunk_t b)
}
/* both DNs must have same number of RDNs */
if (next_a || next_b)
+ {
return FALSE;
-
+ }
/* the two DNs are equal! */
return TRUE;
}
@@ -490,14 +501,11 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
bool next_a, next_b;
/* initialize wildcard counter */
- if (wildcards)
- {
- *wildcards = 0;
- }
+ *wildcards = 0;
/* initialize DN parsing */
- if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != SUCCESS
- || init_rdn(b, &rdn_b, &attribute_b, &next_b) != SUCCESS)
+ if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) ||
+ !init_rdn(b, &rdn_b, &attribute_b, &next_b))
{
return FALSE;
}
@@ -506,31 +514,32 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
while (next_a && next_b)
{
/* parse next RDNs and check for errors */
- if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != SUCCESS
- || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != SUCCESS)
+ if (!get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) ||
+ !get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b))
{
return FALSE;
}
/* OIDs must agree */
if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
+ {
return FALSE;
+ }
/* does rdn_b contain a wildcard? */
if (value_b.len == 1 && *value_b.ptr == '*')
{
- if (wildcards)
- {
- (*wildcards)++;
- }
+ (*wildcards)++;
continue;
}
/* same lengths for values */
if (value_a.len != value_b.len)
+ {
return FALSE;
+ }
/* printableStrings and email RDNs require uppercase comparison */
- if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING
- || (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
+ if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
+ (type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL)))
{
if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
{
@@ -550,12 +559,8 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
{
return FALSE;
}
-
/* the two DNs match! */
- if (wildcards)
- {
- *wildcards = min(*wildcards, MAX_WILDCARDS);
- }
+ *wildcards = min(*wildcards, ID_MATCH_ONE_WILDCARD - ID_MATCH_MAX_WILDCARDS);
return TRUE;
}
@@ -645,7 +650,8 @@ static status_t atodn(char *src, chunk_t *dn)
{
name.len -= whitespace;
rdn_type = (x501rdns[i].type == ASN1_PRINTABLESTRING
- && !is_printablestring(name))? ASN1_T61STRING : x501rdns[i].type;
+ && !asn1_is_printablestring(name))
+ ? ASN1_T61STRING : x501rdns[i].type;
if (rdn_count < RDN_MAX)
{
@@ -675,7 +681,7 @@ static status_t atodn(char *src, chunk_t *dn)
/* build the distinguished name sequence */
{
int i;
- u_char *pos = build_asn1_object(dn, ASN1_SEQUENCE, dn_len);
+ u_char *pos = asn1_build_object(dn, ASN1_SEQUENCE, dn_len);
for (i = 0; i < rdn_count; i++)
{
@@ -776,198 +782,189 @@ static bool equals_strcasecmp(private_identification_t *this,
/**
* Default implementation of identification_t.matches.
*/
-static bool matches_binary(private_identification_t *this,
- private_identification_t *other, int *wildcards)
+static id_match_t matches_binary(private_identification_t *this,
+ private_identification_t *other)
{
if (other->type == ID_ANY)
{
- if (wildcards)
- {
- *wildcards = MAX_WILDCARDS;
- }
- return TRUE;
+ return ID_MATCH_ANY;
}
- if (wildcards)
+ if (this->type == other->type &&
+ chunk_equals(this->encoded, other->encoded))
{
- *wildcards = 0;
+ return ID_MATCH_PERFECT;
}
- return this->type == other->type &&
- chunk_equals(this->encoded, other->encoded);
+ return ID_MATCH_NONE;
}
/**
* 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 id_match_t matches_string(private_identification_t *this,
+ private_identification_t *other)
{
u_int len = other->encoded.len;
if (other->type == ID_ANY)
{
- if (wildcards)
- {
- *wildcards = MAX_WILDCARDS;
- }
- return TRUE;
+ return ID_MATCH_ANY;
}
-
if (this->type != other->type)
- return FALSE;
-
- /* try a binary comparison first */
- if (equals_binary(this, other))
{
- if (wildcards)
- {
- *wildcards = 0;
- }
- return TRUE;
+ return ID_MATCH_NONE;
+ }
+ /* try a equals check first */
+ if (equals_strcasecmp(this, other))
+ {
+ return ID_MATCH_PERFECT;
}
-
if (len == 0 || this->encoded.len < len)
- return FALSE;
+ {
+ return ID_MATCH_NONE;
+ }
/* check for single wildcard at the head of the string */
if (*other->encoded.ptr == '*')
{
- if (wildcards)
- {
- *wildcards = 1;
- }
-
/* single asterisk matches any string */
if (len-- == 1)
- return TRUE;
-
- if (memeq(this->encoded.ptr + this->encoded.len - len, other->encoded.ptr + 1, len))
- return TRUE;
+ { /* not better than ID_ANY */
+ return ID_MATCH_ANY;
+ }
+ if (strncasecmp(this->encoded.ptr + this->encoded.len - len,
+ other->encoded.ptr + 1, len) == 0)
+ {
+ return ID_MATCH_ONE_WILDCARD;
+ }
}
-
- return FALSE;
+ return ID_MATCH_NONE;
}
/**
* 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 id_match_t matches_any(private_identification_t *this,
+ private_identification_t *other)
{
- if (wildcards)
+ if (other->type == ID_ANY)
{
- *wildcards = 0;
+ return ID_MATCH_ANY;
}
- return other->type == ID_ANY;
+ return ID_MATCH_NONE;
}
/**
- * Special implementation of identification_t.matches for ID_DER_ASN1_DN.
- * ANY matches any, even ANY, thats why its there...
+ * Special implementation of identification_t.matches for ID_DER_ASN1_DN
*/
-static bool matches_dn(private_identification_t *this,
- private_identification_t *other, int *wildcards)
+static id_match_t matches_dn(private_identification_t *this,
+ private_identification_t *other)
{
+ int wc;
+
if (other->type == ID_ANY)
{
- if (wildcards)
- {
- *wildcards = MAX_WILDCARDS;
- }
- return TRUE;
+ return ID_MATCH_ANY;
}
if (this->type == other->type)
{
- return match_dn(this->encoded, other->encoded, wildcards);
+ if (match_dn(this->encoded, other->encoded, &wc))
+ {
+ return ID_MATCH_PERFECT - wc;
+ }
}
- return FALSE;
+ return ID_MATCH_NONE;
}
/**
* output handler in printf()
*/
static int print(FILE *stream, const struct printf_info *info,
- const void *const *args)
+ const void *const *args)
{
private_identification_t *this = *((private_identification_t**)(args[0]));
char buf[BUF_LEN];
chunk_t proper, buf_chunk = chunk_from_buf(buf);
- int written;
if (this == NULL)
{
- return fprintf(stream, "(null)");
+ return fprintf(stream, "%*s", info->width, "(null)");
}
switch (this->type)
{
case ID_ANY:
- return fprintf(stream, "%%any");
+ snprintf(buf, sizeof(buf), "%%any");
+ break;
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);
+ snprintf(buf, sizeof(buf), "(invalid ID_IPV4_ADDR)");
}
+ break;
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);
+ snprintf(buf, sizeof(buf), "(invalid ID_IPV6_ADDR)");
}
+ break;
case ID_FQDN:
- {
- proper = sanitize_chunk(this->encoded);
- written = fprintf(stream, "%.*s", proper.len, proper.ptr);
- chunk_free(&proper);
- return written;
- }
case ID_RFC822_ADDR:
- {
+ case ID_DER_ASN1_GN_URI:
proper = sanitize_chunk(this->encoded);
- written = fprintf(stream, "%.*s", proper.len, proper.ptr);
+ snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr);
chunk_free(&proper);
- return written;
- }
+ break;
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);
- }
+ if (!dntoa(this->encoded, &buf_chunk))
+ {
+ snprintf(buf, sizeof(buf), "(invalid ID_DER_ASN1_DN)");
+ }
+ break;
case ID_DER_ASN1_GN:
- return fprintf(stream, "(ASN.1 general Name");
+ snprintf(buf, sizeof(buf), "(ASN.1 general Name");
+ break;
case ID_KEY_ID:
- return fprintf(stream, "(KEY_ID)");
- case ID_DER_ASN1_GN_URI:
- {
- proper = sanitize_chunk(this->encoded);
- written = fprintf(stream, "%.*s", proper.len, proper.ptr);
- chunk_free(&proper);
- return written;
- }
+ case ID_PUBKEY_INFO_SHA1:
+ case ID_PUBKEY_SHA1:
+ case ID_CERT_DER_SHA1:
+ snprintf(buf, sizeof(buf), "%#B", &this->encoded);
+ break;
default:
- return fprintf(stream, "(unknown ID type: %d)", this->type);
+ snprintf(buf, sizeof(buf), "(unknown ID type: %d)", this->type);
+ break;
+ }
+ if (info->left)
+ {
+ return fprintf(stream, "%-*s", info->width, buf);
+ }
+ return fprintf(stream, "%*s", info->width, buf);
+}
+
+/**
+ * arginfo handler
+ */
+static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (n > 0)
+ {
+ argtypes[0] = PA_POINTER;
}
+ return 1;
}
/**
- * register printf() handlers
+ * Get printf hook functions
*/
-static void __attribute__ ((constructor))print_register()
+printf_hook_functions_t identification_get_printf_hooks()
{
- register_printf_function(PRINTF_IDENTIFICATION, print, arginfo_ptr);
+ printf_hook_functions_t hook = {print, arginfo};
+
+ return hook;
}
/**
@@ -1011,7 +1008,7 @@ static private_identification_t *identification_create(void)
this->public.destroy = (void (*) (identification_t*))destroy;
/* we use these as defaults, the may be overloaded for special ID types */
this->public.equals = (bool (*) (identification_t*,identification_t*))equals_binary;
- this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_binary;
+ this->public.matches = (id_match_t (*) (identification_t*,identification_t*))matches_binary;
this->encoded = chunk_empty;
@@ -1041,7 +1038,7 @@ identification_t *identification_create_from_string(char *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;
+ this->public.matches = (id_match_t (*) (identification_t*,identification_t*))matches_dn;
return &this->public;
}
else if (strchr(string, '@') == NULL)
@@ -1054,8 +1051,8 @@ identification_t *identification_create_from_string(char *string)
{
/* any ID will be accepted */
this->type = ID_ANY;
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_any;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_any;
return &this->public;
}
else
@@ -1072,8 +1069,8 @@ identification_t *identification_create_from_string(char *string)
this->type = ID_FQDN;
this->encoded.ptr = strdup(string);
this->encoded.len = strlen(string);
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_string;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_string;
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_strcasecmp;
return &(this->public);
@@ -1105,17 +1102,19 @@ identification_t *identification_create_from_string(char *string)
{
if (*(string + 1) == '#')
{
- /* TODO: Pluto handles '#' as hex encoded ID_KEY_ID. */
- free(this);
- return NULL;
+ string += 2;
+ this->type = ID_KEY_ID;
+ this->encoded = chunk_from_hex(
+ chunk_create(string, strlen(string)), NULL);
+ return &(this->public);
}
else
{
this->type = ID_FQDN;
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 = (id_match_t (*)
+ (identification_t*,identification_t*))matches_string;
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_strcasecmp;
return &(this->public);
@@ -1126,8 +1125,8 @@ identification_t *identification_create_from_string(char *string)
this->type = ID_RFC822_ADDR;
this->encoded.ptr = strdup(string);
this->encoded.len = strlen(string);
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_string;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_string;
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_strcasecmp;
return &(this->public);
@@ -1146,27 +1145,30 @@ identification_t *identification_create_from_encoding(id_type_t type, chunk_t en
switch (type)
{
case ID_ANY:
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_any;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_any;
break;
case ID_FQDN:
case ID_RFC822_ADDR:
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_string;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_string;
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_strcasecmp;
break;
case 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;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_dn;
break;
case ID_IPV4_ADDR:
case ID_IPV6_ADDR:
case ID_DER_ASN1_GN:
case ID_KEY_ID:
case ID_DER_ASN1_GN_URI:
+ case ID_PUBKEY_INFO_SHA1:
+ case ID_PUBKEY_SHA1:
+ case ID_CERT_DER_SHA1:
default:
break;
}
diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h
index 59c568eaf..591909411 100644
--- a/src/libstrongswan/utils/identification.h
+++ b/src/libstrongswan/utils/identification.h
@@ -1,10 +1,3 @@
-/**
- * @file identification.h
- *
- * @brief Interface of identification_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* 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.
+ *
+ * $Id: identification.h 3838 2008-04-18 11:24:45Z tobias $
+ */
+
+/**
+ * @defgroup identification identification
+ * @{ @ingroup utils
*/
@@ -27,15 +27,33 @@
typedef enum id_type_t id_type_t;
typedef struct identification_t identification_t;
+typedef enum id_match_t id_match_t;
#include <library.h>
-#define MAX_WILDCARDS 14
+/**
+ * Matches returned from identification_t.match
+ */
+enum id_match_t {
+ /* no match */
+ ID_MATCH_NONE = 0,
+ /* match to %any ID */
+ ID_MATCH_ANY = 1,
+ /* match with maximum allowed wildcards */
+ ID_MATCH_MAX_WILDCARDS = 2,
+ /* match with only one wildcard */
+ ID_MATCH_ONE_WILDCARD = 19,
+ /* perfect match, won't get better */
+ ID_MATCH_PERFECT = 20,
+};
/**
- * @brief ID Types in a ID payload.
- *
- * @ingroup utils
+ * enum names for id_match_t.
+ */
+extern enum_name_t *id_match_names;
+
+/**
+ * ID Types in a ID payload.
*/
enum id_type_t {
@@ -109,7 +127,21 @@ enum id_type_t {
* private type which represents a GeneralName of type URI
*/
ID_DER_ASN1_GN_URI = 201,
-
+
+ /**
+ * SHA1 hash over PKCS#1 subjectPublicKeyInfo
+ */
+ ID_PUBKEY_INFO_SHA1,
+
+ /**
+ * SHA1 hash over PKCS#1 subjectPublicKey
+ */
+ ID_PUBKEY_SHA1,
+
+ /**
+ * SHA1 hash of the binary DER encoding of a certificate
+ */
+ ID_CERT_DER_SHA1,
};
/**
@@ -118,110 +150,84 @@ enum id_type_t {
extern enum_name_t *id_type_names;
/**
- * @brief Generic identification, such as used in ID payload.
- *
- * The following types are possible:
- * - ID_IPV4_ADDR
- * - ID_FQDN
- * - ID_RFC822_ADDR
- * - ID_IPV6_ADDR
- * - ID_DER_ASN1_DN
- * - ID_DER_ASN1_GN
- * - ID_KEY_ID
- * - ID_DER_ASN1_GN_URI
- *
- * @b Constructors:
- * - identification_create_from_string()
- * - identification_create_from_encoding()
+ * Generic identification, such as used in ID payload.
*
* @todo Support for ID_DER_ASN1_GN is minimal right now. Comparison
* between them and ID_IPV4_ADDR/RFC822_ADDR would be nice.
- *
- * @ingroup utils
*/
struct identification_t {
/**
- * @brief Get the encoding of this id, to send over
+ * Get the encoding of this id, to send over
* the network.
*
- * @warning Result points to internal data, do NOT free!
+ * Result points to internal data, do not free.
*
- * @param this the identification_t object
* @return a chunk containing the encoded bytes
*/
chunk_t (*get_encoding) (identification_t *this);
/**
- * @brief Get the type of this identification.
+ * Get the type of this identification.
*
- * @param this the identification_t object
* @return id_type_t
*/
id_type_t (*get_type) (identification_t *this);
/**
- * @brief Check if two identification_t objects are equal.
+ * Check if two identification_t objects are equal.
*
- * @param this the identification_t object
* @param other other identification_t object
* @return TRUE if the IDs are equal
*/
bool (*equals) (identification_t *this, identification_t *other);
/**
- * @brief Check if an ID matches a wildcard ID.
+ * Check if an ID matches a wildcard ID.
*
* An identification_t may contain wildcards, such as
* *@strongswan.org. This call checks if a given ID
* (e.g. tester@strongswan.org) belongs to a such wildcard
- * ID. Returns TRUE if
+ * ID. Returns > 0 if
* - IDs are identical
* - other is of type ID_ANY
* - other contains a wildcard and matches this
+ *
+ * The larger the return value is, the better is the match. Zero means
+ * no match at all, 1 means a bad match, and 2 a slightly better match.
*
- * @param this the ID without wildcard
- * @param other the ID containing a wildcard
+ * @param other the ID containing one or more wildcards
* @param wildcards returns the number of wildcards, may be NULL
- * @return TRUE if match is found
+ * @return match value as described above
*/
- bool (*matches) (identification_t *this, identification_t *other, int *wildcards);
+ id_match_t (*matches) (identification_t *this, identification_t *other);
/**
- * @brief Check if an ID is a wildcard ID.
+ * Check if an ID is a wildcard ID.
*
* If the ID represents multiple IDs (with wildcards, or
* as the type ID_ANY), TRUE is returned. If it is unique,
* FALSE is returned.
*
- * @param this identification_t object
* @return TRUE if ID contains wildcards
*/
bool (*contains_wildcards) (identification_t *this);
/**
- * @brief Clone a identification_t instance.
+ * Clone a identification_t instance.
*
- * @param this the identification_t object to clone
* @return clone of this
*/
identification_t *(*clone) (identification_t *this);
/**
- * @brief Destroys a identification_t object.
- *
- * @param this identification_t object
+ * Destroys a identification_t object.
*/
void (*destroy) (identification_t *this);
};
/**
- * @brief Creates an identification_t object from a string.
- *
- * @param string input string, which will be converted
- * @return
- * - created identification_t object, or
- * - NULL if unsupported string supplied.
+ * Creates an identification_t object from a string.
*
* The input string may be e.g. one of the following:
* - ID_IPV4_ADDR: 192.168.0.1
@@ -239,23 +245,29 @@ struct identification_t {
* ND, UID, DC, CN, S, SN, serialNumber, C, L, ST, O, OU, T, D,
* N, G, I, ID, EN, EmployeeNumber, E, Email, emailAddress, UN,
* unstructuredName, TCGID.
- *
- * @ingroup utils
+ *
+ * @param string input string, which will be converted
+ * @return created identification_t, NULL if not supported.
*/
identification_t * identification_create_from_string(char *string);
/**
- * @brief Creates an identification_t object from an encoded chunk.
- *
- * @param type type of this id, such as ID_IPV4_ADDR
- * @param encoded encoded bytes, such as from identification_t.get_encoding
- * @return identification_t object
+ * Creates an identification_t object from an encoded chunk.
*
* In contrast to identification_create_from_string(), this constructor never
* returns NULL, even when the conversion to a string representation fails.
- *
- * @ingroup utils
+ *
+ * @param type type of this id, such as ID_IPV4_ADDR
+ * @param encoded encoded bytes, such as from identification_t.get_encoding
+ * @return identification_t
*/
identification_t * identification_create_from_encoding(id_type_t type, chunk_t encoded);
-#endif /* IDENTIFICATION_H_ */
+/**
+ * Get the printf hook functions.
+ *
+ * @return printf hook functions
+ */
+printf_hook_functions_t identification_get_printf_hooks();
+
+#endif /* IDENTIFICATION_H_ @} */
diff --git a/src/libstrongswan/utils/iterator.h b/src/libstrongswan/utils/iterator.h
index b4ff85bfb..a1bdad1d6 100644
--- a/src/libstrongswan/utils/iterator.h
+++ b/src/libstrongswan/utils/iterator.h
@@ -1,10 +1,3 @@
-/**
- * @file iterator.h
- *
- * @brief Interface iterator_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* 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.
+ *
+ * $Id: iterator.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup iterator iterator
+ * @{ @ingroup utils
*/
#ifndef ITERATOR_H_
@@ -29,13 +29,11 @@
typedef enum hook_result_t hook_result_t;
/**
- * @brief Return value of an iterator hook.
+ * Return value of an iterator hook.
*
* Returning HOOK_AGAIN is useful to "inject" additional elements in an
* iteration, HOOK_NEXT is the normal iterator behavior, and HOOK_SKIP may
* be used to filter elements out.
- *
- * @ingroup utils
*/
enum hook_result_t {
@@ -56,14 +54,12 @@ enum hook_result_t {
};
/**
- * @brief Iterator hook function prototype.
+ * Iterator hook function prototype.
*
* @param param user supplied parameter
* @param in the value the hook receives from the iterator
* @param out the value supplied as a result to the iterator
* @return a hook_result_t
- *
- * @ingroup utils
*/
typedef hook_result_t (iterator_hook_t)(void *param, void *in, void **out);
@@ -71,44 +67,34 @@ typedef hook_result_t (iterator_hook_t)(void *param, void *in, void **out);
typedef struct iterator_t iterator_t;
/**
- * @brief Iterator interface, allows iteration over collections.
+ * Iterator interface, allows iteration over collections.
*
* iterator_t defines an interface for iterating over collections.
* It allows searching, deleting, updating and inserting.
*
- * @b Constructors:
- * - via linked_list_t.create_iterator, or
- * - any other class which supports the iterator_t interface
- *
- * @see linked_list_t
- *
- * @ingroup utils
+ * @deprecated Use enumerator instead.
*/
struct iterator_t {
/**
- * @brief Return number of list items.
+ * Return number of list items.
*
- * @param this calling object
* @return number of list items
*/
int (*get_count) (iterator_t *this);
/**
- * @brief Iterate over all items.
+ * Iterate over all items.
*
* The easy way to iterate over items.
*
- * @param this calling object
- * @param[out] value item
- * @return
- * - TRUE, if there was an element available,
- * - FALSE otherwise
+ * @param value item
+ * @return TRUE, if there was an element available, FALSE otherwise
*/
bool (*iterate) (iterator_t *this, void** value);
/**
- * @brief Hook a function into the iterator.
+ * Hook a function into the iterator.
*
* Sometimes it is useful to hook in an iterator. The hook function is
* called before any successful return of iterate(). It takes the
@@ -119,80 +105,67 @@ struct iterator_t {
* If an iterator is hooked, only the iterate() method is valid,
* all other methods behave undefined.
*
- * @param this calling object
- * @param hook iterator hook which manipulates the iterated value
- * @param param user supplied parameter to pass back to the hook
+ * @param hook iterator hook which manipulates the iterated value
+ * @param param user supplied parameter to pass back to the hook
*/
void (*set_iterator_hook) (iterator_t *this, iterator_hook_t *hook,
void *param);
/**
- * @brief Inserts a new item before the given iterator position.
+ * Inserts a new item before the given iterator position.
*
* The iterator position is not changed after inserting
*
- * @param this calling iterator
- * @param[in] item value to insert in list
+ * @param item value to insert in list
*/
void (*insert_before) (iterator_t *this, void *item);
/**
- * @brief Inserts a new item after the given iterator position.
+ * Inserts a new item after the given iterator position.
*
* The iterator position is not changed after inserting.
*
- * @param this calling iterator
- * @param[in] item value to insert in list
+ * @param this calling iterator
+ * @param item value to insert in list
*/
void (*insert_after) (iterator_t *this, void *item);
/**
- * @brief Replace the current item at current iterator position.
+ * Replace the current item at current iterator position.
*
* The iterator position is not changed after replacing.
*
- * @param this calling iterator
- * @param[out] old_item old value will be written here(can be NULL)
- * @param[in] new_item new value
- *
- * @return
- * - SUCCESS
- * - FAILED if iterator is on an invalid position
+ * @param this calling iterator
+ * @param old old value will be written here(can be NULL)
+ * @param new new value
+ * @return SUCCESS, FAILED if iterator is on an invalid position
*/
- status_t (*replace) (iterator_t *this, void **old_item, void *new_item);
+ status_t (*replace) (iterator_t *this, void **old, void *new);
/**
- * @brief Removes an element from list at the given iterator position.
+ * Removes an element from list at the given iterator position.
*
* The iterator is set the the following position:
* - to the item before, if available
* - it gets reseted, otherwise
*
- * @param this calling object
- * @return
- * - SUCCESS
- * - FAILED if iterator is on an invalid position
+ * @return SUCCESS, FAILED if iterator is on an invalid position
*/
status_t (*remove) (iterator_t *this);
/**
- * @brief Resets the iterator position.
+ * Resets the iterator position.
*
* After reset, the iterator_t objects doesn't point to an element.
* A call to iterator_t.has_next is necessary to do any other operations
* with the resetted iterator.
- *
- * @param this calling object
*/
void (*reset) (iterator_t *this);
/**
- * @brief Destroys an iterator.
- *
- * @param this iterator to destroy
- *
+ * Destroys an iterator.
*/
void (*destroy) (iterator_t *this);
};
-#endif /*ITERATOR_H_*/
+#endif /*ITERATOR_H_ @} */
diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c
index dab18fd5c..cff5a1c81 100644
--- a/src/libstrongswan/utils/leak_detective.c
+++ b/src/libstrongswan/utils/leak_detective.c
@@ -1,11 +1,5 @@
-/**
- * @file leak_detective.c
- *
- * @brief Allocation hooks to find memory leaks.
- */
-
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -17,8 +11,15 @@
* 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.
+ *
+ * $Id: leak_detective.c 4044 2008-06-06 15:05:54Z martin $
*/
+#ifdef HAVE_DLADDR
+# define _GNU_SOURCE
+# include <dlfcn.h>
+#endif /* HAVE_DLADDR */
+
#include <stddef.h>
#include <string.h>
#include <stdio.h>
@@ -33,6 +34,7 @@
#include <pthread.h>
#include <netdb.h>
#include <printf.h>
+#include <locale.h>
#ifdef HAVE_BACKTRACE
# include <execinfo.h>
#endif /* HAVE_BACKTRACE */
@@ -42,7 +44,18 @@
#include <library.h>
#include <debug.h>
-#ifdef LEAK_DETECTIVE
+typedef struct private_leak_detective_t private_leak_detective_t;
+
+/**
+ * private data of leak_detective
+ */
+struct private_leak_detective_t {
+
+ /**
+ * public functions
+ */
+ leak_detective_t public;
+};
/**
* Magic value which helps to detect memory corruption. Yummy!
@@ -50,6 +63,11 @@
#define MEMORY_HEADER_MAGIC 0x7ac0be11
/**
+ * Magic written to tail of allocation
+ */
+#define MEMORY_TAIL_MAGIC 0xcafebabe
+
+/**
* Pattern which is filled in memory before freeing it
*/
#define MEMORY_FREE_PATTERN 0xFF
@@ -66,25 +84,26 @@ static void *malloc_hook(size_t, const void *);
static void *realloc_hook(void *, size_t, const void *);
static void free_hook(void*, const void *);
+void *(*old_malloc_hook)(size_t, const void *);
+void *(*old_realloc_hook)(void *, size_t, const void *);
+void (*old_free_hook)(void*, const void *);
+
static u_int count_malloc = 0;
static u_int count_free = 0;
static u_int count_realloc = 0;
typedef struct memory_header_t memory_header_t;
+typedef struct memory_tail_t memory_tail_t;
/**
* Header which is prepended to each allocated memory block
*/
struct memory_header_t {
- /**
- * Magci byte which must(!) hold MEMORY_HEADER_MAGIC
- */
- u_int32_t magic;
/**
* Number of bytes following after the header
*/
- size_t bytes;
+ u_int bytes;
/**
* Stack frames at the time of allocation
@@ -105,7 +124,25 @@ struct memory_header_t {
* Pointer to next entry in linked list
*/
memory_header_t *next;
-};
+
+ /**
+ * magic bytes to detect bad free or heap underflow, MEMORY_HEADER_MAGIC
+ */
+ u_int32_t magic;
+
+}__attribute__((__packed__));
+
+/**
+ * tail appended to each allocated memory block
+ */
+struct memory_tail_t {
+
+ /**
+ * Magic bytes to detect heap overflow, MEMORY_TAIL_MAGIC
+ */
+ u_int32_t magic;
+
+}__attribute__((__packed__));
/**
* first mem header is just a dummy to chain
@@ -120,22 +157,11 @@ static memory_header_t first_header = {
};
/**
- * standard hooks, used to temparily remove hooking
- */
-static void *old_malloc_hook, *old_realloc_hook, *old_free_hook;
-
-/**
* are the hooks currently installed?
*/
static bool installed = FALSE;
/**
- * Mutex to exclusivly uninstall hooks, access heap list
- */
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-
-/**
* log stack frames queried by backtrace()
* TODO: Dump symbols of static functions. This could be done with
* the addr2line utility or the GNU BFD Library...
@@ -143,80 +169,140 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static void log_stack_frames(void **stack_frames, int stack_frame_count)
{
#ifdef HAVE_BACKTRACE
- char **strings;
size_t i;
+ char **strings;
+
+ strings = backtrace_symbols(stack_frames, stack_frame_count);
- strings = backtrace_symbols (stack_frames, stack_frame_count);
-
- DBG1(" dumping %d stack frame addresses", stack_frame_count);
-
+ fprintf(stderr, " dumping %d stack frame addresses:\n", stack_frame_count);
for (i = 0; i < stack_frame_count; i++)
{
- DBG1(" %s", strings[i]);
+#ifdef HAVE_DLADDR
+ Dl_info info;
+
+ if (dladdr(stack_frames[i], &info))
+ {
+ char cmd[1024];
+ FILE *output;
+ char c;
+ void *ptr = stack_frames[i];
+
+ if (strstr(info.dli_fname, ".so"))
+ {
+ ptr = (void*)(stack_frames[i] - info.dli_fbase);
+ }
+ snprintf(cmd, sizeof(cmd), "addr2line -e %s %p", info.dli_fname, ptr);
+ if (info.dli_sname)
+ {
+ fprintf(stderr, " \e[33m%s\e[0m @ %p (\e[31m%s\e[0m+0x%x) [%p]\n",
+ info.dli_fname, info.dli_fbase, info.dli_sname,
+ stack_frames[i] - info.dli_saddr, stack_frames[i]);
+ }
+ else
+ {
+ fprintf(stderr, " \e[33m%s\e[0m @ %p [%p]\n", info.dli_fname,
+ info.dli_fbase, stack_frames[i]);
+ }
+ fprintf(stderr, " -> \e[32m");
+ output = popen(cmd, "r");
+ if (output)
+ {
+ while (TRUE)
+ {
+ c = getc(output);
+ if (c == '\n' || c == EOF)
+ {
+ break;
+ }
+ fputc(c, stderr);
+ }
+ }
+ else
+ {
+#endif /* HAVE_DLADDR */
+ fprintf(stderr, " %s\n", strings[i]);
+#ifdef HAVE_DLADDR
+ }
+ fprintf(stderr, "\n\e[0m");
+ }
+#endif /* HAVE_DLADDR */
}
free (strings);
#endif /* HAVE_BACKTRACE */
}
/**
- * Whitelist, which contains address ranges in stack frames ignored when leaking.
- *
- * This is necessary, as some function use allocation hacks (static buffers)
- * and so on, which we want to suppress on leak reports.
+ * Leak report white list
*
- * The range_size is calculated using the readelf utility, e.g.:
- * readelf -s /lib/glibc.so.6
- * The values are for glibc-2.4 and may or may not be correct on other systems.
+ * List of functions using static allocation buffers or should be suppressed
+ * otherwise on leak report.
*/
-typedef struct whitelist_t whitelist_t;
-
-struct whitelist_t {
- void* range_start;
- size_t range_size;
-};
-
-#ifdef LIBCURL
-/* dummy declaration for whitelisting */
-void *Curl_getaddrinfo(void);
-#endif /* LIBCURL */
-
-whitelist_t whitelist[] = {
- {pthread_create, 2542},
- {pthread_setspecific, 217},
- {mktime, 60},
- {tzset, 123},
- {inet_ntoa, 249},
- {strerror, 180},
- {getprotobynumber, 291},
- {getservbyport, 311},
- {register_printf_function, 159},
- {syslog, 44},
- {vsyslog, 41},
- {dlopen, 109},
-# ifdef LIBCURL
- /* from /usr/lib/libcurl.so.3 */
- {Curl_getaddrinfo, 480},
-# endif /* LIBCURL */
+char *whitelist[] = {
+ /* pthread stuff */
+ "pthread_create",
+ "pthread_setspecific",
+ /* glibc functions */
+ "mktime",
+ "__gmtime_r",
+ "tzset",
+ "inet_ntoa",
+ "strerror",
+ "getprotobynumber",
+ "getservbyport",
+ "getservbyname",
+ "gethostbyname_r",
+ "gethostbyname2_r",
+ "getpwnam_r",
+ "getgrnam_r",
+ "register_printf_function",
+ "syslog",
+ "vsyslog",
+ "getaddrinfo",
+ "setlocale",
+ /* ignore dlopen, as we do not dlclose to get proper leak reports */
+ "dlopen",
+ "dlerror",
+ /* mysql functions */
+ "mysql_init_character_set",
+ "init_client_errs",
+ "my_thread_init",
+ /* fastcgi library */
+ "FCGX_Init",
+ /* libxml */
+ "xmlInitCharEncodingHandlers",
+ "xmlInitParser",
+ "xmlInitParserCtxt",
+ /* ClearSilver */
+ "nerr_init",
+ /* OpenSSL */
+ "RSA_new_method",
+ "DH_new_method",
};
/**
- * Check if this stack frame is whitelisted.
+ * check if a stack frame contains functions listed above
*/
static bool is_whitelisted(void **stack_frames, int stack_frame_count)
{
int i, j;
+#ifdef HAVE_DLADDR
for (i=0; i< stack_frame_count; i++)
{
- for (j=0; j<sizeof(whitelist)/sizeof(whitelist_t); j++)
- {
- if (stack_frames[i] >= whitelist[j].range_start &&
- stack_frames[i] <= (whitelist[j].range_start + whitelist[j].range_size))
+ Dl_info info;
+
+ if (dladdr(stack_frames[i], &info) && info.dli_sname)
+ {
+ for (j = 0; j < sizeof(whitelist)/sizeof(char*); j++)
{
- return TRUE;
+ if (streq(info.dli_sname, whitelist[j]))
+ {
+ return TRUE;
+ }
}
}
}
+#endif /* HAVE_DLADDR */
return FALSE;
}
@@ -226,14 +312,19 @@ static bool is_whitelisted(void **stack_frames, int stack_frame_count)
void report_leaks()
{
memory_header_t *hdr;
- int leaks = 0;
+ int leaks = 0, whitelisted = 0;
for (hdr = first_header.next; hdr != NULL; hdr = hdr->next)
{
- if (!is_whitelisted(hdr->stack_frames, hdr->stack_frame_count))
+ if (is_whitelisted(hdr->stack_frames, hdr->stack_frame_count))
+ {
+ whitelisted++;
+ }
+ else
{
- DBG1("Leak (%d bytes at %p):", hdr->bytes, hdr + 1);
- log_stack_frames(hdr->stack_frames, hdr->stack_frame_count);
+ fprintf(stderr, "Leak (%d bytes at %p):\n", hdr->bytes, hdr + 1);
+ /* skip the first frame, contains leak detective logic */
+ log_stack_frames(hdr->stack_frames + 1, hdr->stack_frame_count - 1);
leaks++;
}
}
@@ -241,15 +332,16 @@ void report_leaks()
switch (leaks)
{
case 0:
- DBG1("No leaks detected");
+ fprintf(stderr, "No leaks detected");
break;
case 1:
- DBG1("One leak detected");
+ fprintf(stderr, "One leak detected");
break;
default:
- DBG1("%d leaks detected", leaks);
+ fprintf(stderr, "%d leaks detected", leaks);
break;
}
+ fprintf(stderr, ", %d suppressed by whitelist\n", whitelisted);
}
/**
@@ -289,17 +381,28 @@ static void uninstall_hooks()
void *malloc_hook(size_t bytes, const void *caller)
{
memory_header_t *hdr;
+ memory_tail_t *tail;
+ pthread_t thread_id = pthread_self();
+ int oldpolicy;
+ struct sched_param oldparams, params;
+
+ pthread_getschedparam(thread_id, &oldpolicy, &oldparams);
+
+ params.__sched_priority = sched_get_priority_max(SCHED_FIFO);
+ pthread_setschedparam(thread_id, SCHED_FIFO, &params);
- pthread_mutex_lock(&mutex);
count_malloc++;
uninstall_hooks();
- hdr = malloc(bytes + sizeof(memory_header_t));
+ hdr = malloc(sizeof(memory_header_t) + bytes + sizeof(memory_tail_t));
+ tail = ((void*)hdr) + bytes + sizeof(memory_header_t);
/* set to something which causes crashes */
- memset(hdr, MEMORY_ALLOC_PATTERN, bytes + sizeof(memory_header_t));
+ memset(hdr, MEMORY_ALLOC_PATTERN,
+ sizeof(memory_header_t) + bytes + sizeof(memory_tail_t));
hdr->magic = MEMORY_HEADER_MAGIC;
hdr->bytes = bytes;
hdr->stack_frame_count = backtrace(hdr->stack_frames, STACK_FRAMES_COUNT);
+ tail->magic = MEMORY_TAIL_MAGIC;
install_hooks();
/* insert at the beginning of the list */
@@ -310,7 +413,9 @@ void *malloc_hook(size_t bytes, const void *caller)
}
hdr->previous = &first_header;
first_header.next = hdr;
- pthread_mutex_unlock(&mutex);
+
+ pthread_setschedparam(thread_id, oldpolicy, &oldparams);
+
return hdr + 1;
}
@@ -321,41 +426,53 @@ void free_hook(void *ptr, const void *caller)
{
void *stack_frames[STACK_FRAMES_COUNT];
int stack_frame_count;
- memory_header_t *hdr = ptr - sizeof(memory_header_t);
-
+ memory_header_t *hdr;
+ memory_tail_t *tail;
+ pthread_t thread_id = pthread_self();
+ int oldpolicy;
+ struct sched_param oldparams, params;
+
/* allow freeing of NULL */
if (ptr == NULL)
{
return;
}
+ hdr = ptr - sizeof(memory_header_t);
+ tail = ptr + hdr->bytes;
+
+ pthread_getschedparam(thread_id, &oldpolicy, &oldparams);
+
+ params.__sched_priority = sched_get_priority_max(SCHED_FIFO);
+ pthread_setschedparam(thread_id, SCHED_FIFO, &params);
- pthread_mutex_lock(&mutex);
count_free++;
uninstall_hooks();
- if (hdr->magic != MEMORY_HEADER_MAGIC)
+ if (hdr->magic != MEMORY_HEADER_MAGIC ||
+ tail->magic != MEMORY_TAIL_MAGIC)
{
- DBG1("freeing of invalid memory (%p, MAGIC 0x%x != 0x%x):",
- ptr, hdr->magic, MEMORY_HEADER_MAGIC);
+ fprintf(stderr, "freeing invalid memory (%p): "
+ "header magic 0x%x, tail magic 0x%x:\n",
+ ptr, hdr->magic, tail->magic);
stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT);
log_stack_frames(stack_frames, stack_frame_count);
- install_hooks();
- pthread_mutex_unlock(&mutex);
- return;
}
-
- /* remove item from list */
- if (hdr->next)
+ else
{
- hdr->next->previous = hdr->previous;
- }
- hdr->previous->next = hdr->next;
+ /* remove item from list */
+ if (hdr->next)
+ {
+ hdr->next->previous = hdr->previous;
+ }
+ hdr->previous->next = hdr->next;
+
+ /* clear MAGIC, set mem to something remarkable */
+ memset(hdr, MEMORY_FREE_PATTERN, hdr->bytes + sizeof(memory_header_t));
- /* clear MAGIC, set mem to something remarkable */
- memset(hdr, MEMORY_FREE_PATTERN, hdr->bytes + sizeof(memory_header_t));
+ free(hdr);
+ }
- free(hdr);
install_hooks();
- pthread_mutex_unlock(&mutex);
+ pthread_setschedparam(thread_id, oldpolicy, &oldparams);
}
/**
@@ -366,7 +483,11 @@ void *realloc_hook(void *old, size_t bytes, const void *caller)
memory_header_t *hdr;
void *stack_frames[STACK_FRAMES_COUNT];
int stack_frame_count;
-
+ memory_tail_t *tail;
+ pthread_t thread_id = pthread_self();
+ int oldpolicy;
+ struct sched_param oldparams, params;
+
/* allow reallocation of NULL */
if (old == NULL)
{
@@ -374,27 +495,34 @@ void *realloc_hook(void *old, size_t bytes, const void *caller)
}
hdr = old - sizeof(memory_header_t);
+ tail = old + hdr->bytes;
+
+ pthread_getschedparam(thread_id, &oldpolicy, &oldparams);
+
+ params.__sched_priority = sched_get_priority_max(SCHED_FIFO);
+ pthread_setschedparam(thread_id, SCHED_FIFO, &params);
- pthread_mutex_lock(&mutex);
count_realloc++;
uninstall_hooks();
- if (hdr->magic != MEMORY_HEADER_MAGIC)
+ if (hdr->magic != MEMORY_HEADER_MAGIC ||
+ tail->magic != MEMORY_TAIL_MAGIC)
{
- DBG1("reallocation of invalid memory (%p):", old);
+ fprintf(stderr, "reallocating invalid memory (%p): "
+ "header magic 0x%x, tail magic 0x%x:\n",
+ old, hdr->magic, tail->magic);
stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT);
log_stack_frames(stack_frames, stack_frame_count);
- install_hooks();
- pthread_mutex_unlock(&mutex);
- raise(SIGKILL);
- return NULL;
}
-
- hdr = realloc(hdr, bytes + sizeof(memory_header_t));
-
+ /* clear tail magic, allocate, set tail magic */
+ memset(&tail->magic, MEMORY_ALLOC_PATTERN, sizeof(tail->magic));
+ hdr = realloc(hdr, sizeof(memory_header_t) + bytes + sizeof(memory_tail_t));
+ tail = ((void*)hdr) + bytes + sizeof(memory_header_t);
+ tail->magic = MEMORY_TAIL_MAGIC;
+
/* update statistics */
hdr->bytes = bytes;
hdr->stack_frame_count = backtrace(hdr->stack_frames, STACK_FRAMES_COUNT);
-
+
/* update header of linked list neighbours */
if (hdr->next)
{
@@ -402,70 +530,36 @@ void *realloc_hook(void *old, size_t bytes, const void *caller)
}
hdr->previous->next = hdr;
install_hooks();
- pthread_mutex_unlock(&mutex);
+ pthread_setschedparam(thread_id, oldpolicy, &oldparams);
return hdr + 1;
}
/**
- * Setup leak detective
- */
-void __attribute__ ((constructor)) leak_detective_init()
-{
- if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
- {
- install_hooks();
- }
-}
-
-/**
- * Clean up leak detective
+ * Implementation of leak_detective_t.destroy
*/
-void __attribute__ ((destructor)) leak_detective_cleanup()
+static void destroy(private_leak_detective_t *this)
{
- if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
+ if (installed)
{
uninstall_hooks();
report_leaks();
}
+ free(this);
}
-/**
- * Log memory allocation statistics
+/*
+ * see header file
*/
-void leak_detective_status(FILE *stream)
+leak_detective_t *leak_detective_create()
{
- u_int blocks = 0;
- size_t bytes = 0;
- memory_header_t *hdr = &first_header;
+ private_leak_detective_t *this = malloc_thing(private_leak_detective_t);
- if (getenv("LEAK_DETECTIVE_DISABLE"))
- {
- return;
- }
+ this->public.destroy = (void(*)(leak_detective_t*))destroy;
- pthread_mutex_lock(&mutex);
- while ((hdr = hdr->next))
+ if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
{
- blocks++;
- bytes += hdr->bytes;
+ install_hooks();
}
- pthread_mutex_unlock(&mutex);
-
- fprintf(stream, "allocation statistics:\n");
- fprintf(stream, " call stats: malloc: %d, free: %d, realloc: %d\n",
- count_malloc, count_free, count_realloc);
- fprintf(stream, " allocated %d blocks, total size %d bytes (avg. %d bytes)\n",
- blocks, bytes, bytes/blocks);
-}
-
-#else /* !LEAK_DETECTION */
-
-/**
- * Dummy when !using LEAK_DETECTIVE
- */
-void leak_detective_status(FILE *stream)
-{
-
+ return &this->public;
}
-#endif /* LEAK_DETECTION */
diff --git a/src/libstrongswan/utils/leak_detective.h b/src/libstrongswan/utils/leak_detective.h
index d4016b06e..763814726 100644
--- a/src/libstrongswan/utils/leak_detective.h
+++ b/src/libstrongswan/utils/leak_detective.h
@@ -1,11 +1,5 @@
-/**
- * @file leak_detective.h
- *
- * @brief malloc/free hooks to detect leaks.
- */
-
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -19,17 +13,41 @@
* for more details.
*/
+/**
+ * @defgroup leak_detective leak_detective
+ * @{ @ingroup utils
+ */
+
#ifndef LEAK_DETECTIVE_H_
#define LEAK_DETECTIVE_H_
/**
- * Log status information about allocation
+ * Maximum depth stack frames to register
*/
-void leak_detective_status(FILE *stream);
+#define STACK_FRAMES_COUNT 20
+
+typedef struct leak_detective_t leak_detective_t;
/**
- * Max number of stack frames to include in a backtrace.
+ * Leak detective finds leaks and bad frees using malloc hooks.
+ *
+ * Currently leaks are reported to stderr on destruction.
+ *
+ * @todo Build an API for leak detective, allowing leak enumeration, statistics
+ * and dynamic whitelisting.
+ */
+struct leak_detective_t {
+
+ /**
+ * Destroy a leak_detective instance.
+ */
+ void (*destroy)(leak_detective_t *this);
+};
+
+/**
+ * Create a leak_detective instance.
*/
-#define STACK_FRAMES_COUNT 30
+leak_detective_t *leak_detective_create();
+
+#endif /* LEAK_DETECTIVE_H_ @}*/
-#endif /* LEAK_DETECTIVE_H_ */
diff --git a/src/libstrongswan/utils/lexparser.c b/src/libstrongswan/utils/lexparser.c
index 7cc89fc90..8b7b3b547 100644
--- a/src/libstrongswan/utils/lexparser.c
+++ b/src/libstrongswan/utils/lexparser.c
@@ -1,12 +1,5 @@
-/**
- * @file lexparser.c
- *
- * @brief lexical parser for text-based configuration files
- *
- */
-
/*
- * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2001-2006 Andreas Steffen
*
* 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
@@ -18,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: lexparser.c 3353 2007-11-19 12:27:08Z martin $
+ * $Id: lexparser.c 3872 2008-04-25 07:04:59Z andreas $
*/
/* memrchr is a GNU extension */
@@ -55,6 +48,14 @@ bool extract_token(chunk_t *token, const char termination, chunk_t *src)
{
u_char *eot = memchr(src->ptr, termination, src->len);
+ if (termination == ' ')
+ {
+ u_char *eot_tab = memchr(src->ptr, '\t', src->len);
+
+ /* check if a tab instead of a space terminates the token */
+ eot = ( eot_tab == NULL || (eot && eot < eot_tab) ) ? eot : eot_tab;
+ }
+
/* initialize empty token */
*token = chunk_empty;
diff --git a/src/libstrongswan/utils/lexparser.h b/src/libstrongswan/utils/lexparser.h
index 775898139..7d54ca22e 100644
--- a/src/libstrongswan/utils/lexparser.h
+++ b/src/libstrongswan/utils/lexparser.h
@@ -1,12 +1,7 @@
-/**
- * @file lexparser.h
- *
- * @brief lexical parser for text-based configuration files
- *
- */
-
/*
- * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2001-2008 Andreas Steffen
+ *
+ * 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
@@ -18,47 +13,57 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: lexparser.h 3346 2007-11-16 20:23:29Z andreas $
+ * $Id: lexparser.h 3876 2008-04-26 09:24:14Z andreas $
+ */
+
+/**
+ * @defgroup lexparser lexparser
+ * @{ @ingroup utils
*/
+#ifndef LEXPARSER_H_
+#define LEXPARSER_H_
+
#include <library.h>
/**
- * @brief Eats whitespace
+ * Eats whitespace
*/
bool eat_whitespace(chunk_t *src);
/**
- * @brief Compare null-terminated pattern with chunk
+ * Compare null-terminated pattern with chunk
*/
bool match(const char *pattern, const chunk_t *ch);
/**
- * @brief Extracts a token ending with the first occurence a given termination symbol
+ * Extracts a token ending with the first occurence a given termination symbol
*/
bool extract_token(chunk_t *token, const char termination, chunk_t *src);
/**
- * @brief Extracts a token ending with the last occurence a given termination symbol
+ * Extracts a token ending with the last occurence a given termination symbol
*/
bool extract_last_token(chunk_t *token, const char termination, chunk_t *src);
/**
- * @brief Fetches a new text line terminated by \n or \r\n
+ * Fetches a new text line terminated by \n or \r\n
*/
bool fetchline(chunk_t *src, chunk_t *line);
/**
- * @brief Extracts a value that might be single or double quoted
+ * Extracts a value that might be single or double quoted
*/
err_t extract_value(chunk_t *value, chunk_t *line);
/**
- * @brief extracts a name: value pair from a text line
+ * extracts a name: value pair from a text line
*/
err_t extract_name_value(chunk_t *name, chunk_t *value, chunk_t *line);
/**
- * @brief extracts a parameter: value from a text line
+ * extracts a parameter: value from a text line
*/
err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line);
+
+#endif /* LEXPARSER_H_ @} */
diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c
index 63e1bcfbf..80c4e6f9f 100644
--- a/src/libstrongswan/utils/linked_list.c
+++ b/src/libstrongswan/utils/linked_list.c
@@ -1,12 +1,5 @@
-/**
- * @file linked_list.c
- *
- * @brief Implementation of linked_list_t.
- *
- */
-
/*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -20,6 +13,8 @@
* 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.
+ *
+ * $Id: linked_list.c 3841 2008-04-18 11:48:53Z tobias $
*/
#include <stdlib.h>
@@ -154,9 +149,14 @@ struct private_enumerator_t {
enumerator_t enumerator;
/**
- * next item to enumerate
+ * associated linked list
*/
- element_t *next;
+ private_linked_list_t *list;
+
+ /**
+ * current item
+ */
+ element_t *current;
};
/**
@@ -164,12 +164,23 @@ struct private_enumerator_t {
*/
static bool enumerate(private_enumerator_t *this, void **item)
{
- if (this->next == NULL)
+ if (!this->current)
{
- return FALSE;
+ if (!this->list->first)
+ {
+ return FALSE;
+ }
+ this->current = this->list->first;
}
- *item = this->next->value;
- this->next = this->next->next;
+ else
+ {
+ if (!this->current->next)
+ {
+ return FALSE;
+ }
+ this->current = this->current->next;
+ }
+ *item = this->current->value;
return TRUE;
}
@@ -182,7 +193,8 @@ static enumerator_t* create_enumerator(private_linked_list_t *this)
enumerator->enumerator.enumerate = (void*)enumerate;
enumerator->enumerator.destroy = (void*)free;
- enumerator->next = this->first;
+ enumerator->list = this;
+ enumerator->current = NULL;
return &enumerator->enumerator;
}
@@ -459,34 +471,37 @@ static void insert_first(private_linked_list_t *this, void *item)
}
/**
- * Implementation of linked_list_t.remove_first.
+ * unlink an element form the list, returns following element
*/
-static status_t remove_first(private_linked_list_t *this, void **item)
+static element_t* remove_element(private_linked_list_t *this, element_t *element)
{
- element_t *element = this->first;
-
- if (element == NULL)
+ element_t *next, *previous;
+
+ next = element->next;
+ previous = element->previous;
+ free(element);
+ if (next)
{
- return NOT_FOUND;
+ next->previous = previous;
}
- if (element->next != NULL)
+ else
{
- element->next->previous = NULL;
+ this->last = previous;
}
- this->first = element->next;
-
- if (item != NULL)
+ if (previous)
+ {
+ previous->next = next;
+ }
+ else
{
- *item = element->value;
+ this->first = next;
}
if (--this->count == 0)
{
+ this->first = NULL;
this->last = NULL;
}
-
- free(element);
-
- return SUCCESS;
+ return next;
}
/**
@@ -503,6 +518,19 @@ static status_t get_first(private_linked_list_t *this, void **item)
}
/**
+ * Implementation of linked_list_t.remove_first.
+ */
+static status_t remove_first(private_linked_list_t *this, void **item)
+{
+ if (get_first(this, item) == SUCCESS)
+ {
+ remove_element(this, this->first);
+ return SUCCESS;
+ }
+ return NOT_FOUND;
+}
+
+/**
* Implementation of linked_list_t.insert_last.
*/
static void insert_last(private_linked_list_t *this, void *item)
@@ -529,151 +557,69 @@ static void insert_last(private_linked_list_t *this, void *item)
}
/**
- * Implementation of linked_list_t.remove_last.
+ * Implementation of linked_list_t.get_last.
*/
-static status_t remove_last(private_linked_list_t *this, void **item)
+static status_t get_last(private_linked_list_t *this, void **item)
{
- element_t *element = this->last;
-
- if (element == NULL)
+ if (this->count == 0)
{
return NOT_FOUND;
}
- if (element->previous != NULL)
- {
- element->previous->next = NULL;
- }
- this->last = element->previous;
-
- if (item != NULL)
- {
- *item = element->value;
- }
- if (--this->count == 0)
- {
- this->first = NULL;
- }
-
- free(element);
-
+ *item = this->last->value;
return SUCCESS;
}
/**
- * Implementation of linked_list_t.insert_at_position.
+ * Implementation of linked_list_t.remove_last.
*/
-static status_t insert_at_position (private_linked_list_t *this,size_t position, void *item)
+static status_t remove_last(private_linked_list_t *this, void **item)
{
- element_t *current_element;
- int i;
-
- if (this->count <= position)
+ if (get_last(this, item) == SUCCESS)
{
- return INVALID_ARG;
- }
-
- current_element = this->first;
-
- for (i = 0; i < position;i++)
- {
- current_element = current_element->next;
- }
-
- if (current_element == NULL)
- {
- this->public.insert_last(&(this->public),item);
+ remove_element(this, this->last);
return SUCCESS;
}
-
- element_t *element = element_create(item);
- if (current_element->previous == NULL)
- {
- current_element->previous = element;
- element->next = current_element;
- this->first = element;
- }
- else
- {
- current_element->previous->next = element;
- element->previous = current_element->previous;
- current_element->previous = element;
- element->next = current_element;
- }
-
-
- this->count++;
- return SUCCESS;
+ return NOT_FOUND;
}
/**
- * Implementation of linked_list_t.remove_at_position.
+ * Implementation of linked_list_t.remove.
*/
-static status_t remove_at_position(private_linked_list_t *this,size_t position, void **item)
+static int remove(private_linked_list_t *this, void *item,
+ bool (*compare)(void *,void*))
{
- iterator_t *iterator;
- int i;
-
- if (this->count <= position)
- {
- return INVALID_ARG;
- }
+ element_t *current = this->first;
+ int removed = 0;
- iterator = this->public.create_iterator(&(this->public),TRUE);
- iterator->iterate(iterator, item);
- for (i = 0; i < position; i++)
+ while (current)
{
- if (!iterator->iterate(iterator, item))
+ if ((compare && compare(current->value, item)) ||
+ (!compare && current->value == item))
{
- iterator->destroy(iterator);
- return INVALID_ARG;
+ removed++;
+ current = remove_element(this, current);
}
- }
- iterator->remove(iterator);
- iterator->destroy(iterator);
-
- return SUCCESS;
-}
-
-/**
- * Implementation of linked_list_t.get_at_position.
- */
-static status_t get_at_position(private_linked_list_t *this,size_t position, void **item)
-{
- int i;
- iterator_t *iterator;
-
- if (this->count <= position)
- {
- return INVALID_ARG;
- }
-
- iterator = this->public.create_iterator(&(this->public),TRUE);
- iterator->iterate(iterator, item);
- for (i = 0; i < position; i++)
- {
- if (!iterator->iterate(iterator, item))
+ else
{
- iterator->destroy(iterator);
- return INVALID_ARG;
+ current = current->next;
}
}
- iterator->destroy(iterator);
- return SUCCESS;
+ return removed;
}
/**
- * Implementation of linked_list_t.get_last.
+ * Implementation of linked_list_t.remove_at.
*/
-static status_t get_last(private_linked_list_t *this, void **item)
+static void remove_at(private_linked_list_t *this, private_enumerator_t *enumerator)
{
- if (this->count == 0)
+ element_t *current;
+
+ if (enumerator->current)
{
- return NOT_FOUND;
+ current = enumerator->current;
+ enumerator->current = current->previous;
+ remove_element(this, current);
}
-
- *item = this->last->value;
-
- return SUCCESS;
}
/**
@@ -725,14 +671,15 @@ static status_t find_last(private_linked_list_t *this, linked_list_match_t match
/**
* Implementation of linked_list_t.invoke_offset.
*/
-static void invoke_offset(private_linked_list_t *this, size_t offset)
+static void invoke_offset(private_linked_list_t *this, size_t offset,
+ void *d1, void *d2, void *d3, void *d4, void *d5)
{
element_t *current = this->first;
while (current)
{
- void (**method)(void*) = current->value + offset;
- (*method)(current->value);
+ linked_list_invoke_t *method = current->value + offset;
+ (*method)(current->value, d1, d2, d3, d4, d5);
current = current->next;
}
}
@@ -740,13 +687,14 @@ static void invoke_offset(private_linked_list_t *this, size_t offset)
/**
* Implementation of linked_list_t.invoke_function.
*/
-static void invoke_function(private_linked_list_t *this, void(*fn)(void*))
+static void invoke_function(private_linked_list_t *this, linked_list_invoke_t fn,
+ void *d1, void *d2, void *d3, void *d4, void *d5)
{
element_t *current = this->first;
while (current)
{
- fn(current->value);
+ fn(current->value, d1, d2, d3, d4, d5);
current = current->next;
}
}
@@ -895,11 +843,10 @@ linked_list_t *linked_list_create()
this->public.insert_last = (void (*) (linked_list_t *, void *item))insert_last;
this->public.remove_first = (status_t (*) (linked_list_t *, void **item))remove_first;
this->public.remove_last = (status_t (*) (linked_list_t *, void **item))remove_last;
- this->public.insert_at_position = (status_t (*) (linked_list_t *,size_t, void *))insert_at_position;
- this->public.remove_at_position = (status_t (*) (linked_list_t *,size_t, void **))remove_at_position;
- this->public.get_at_position = (status_t (*) (linked_list_t *,size_t, void **))get_at_position;
- this->public.invoke_offset = (void (*)(linked_list_t*,size_t))invoke_offset;
- this->public.invoke_function = (void (*)(linked_list_t*,void(*)(void*)))invoke_function;
+ this->public.remove = (int(*)(linked_list_t*, void *item, bool (*compare)(void *,void*)))remove;
+ this->public.remove_at = (void(*)(linked_list_t*, enumerator_t *enumerator))remove_at;
+ this->public.invoke_offset = (void (*)(linked_list_t*,size_t,...))invoke_offset;
+ this->public.invoke_function = (void (*)(linked_list_t*,linked_list_invoke_t,...))invoke_function;
this->public.clone_offset = (linked_list_t * (*)(linked_list_t*,size_t))clone_offset;
this->public.clone_function = (linked_list_t * (*)(linked_list_t*,void*(*)(void*)))clone_function;
this->public.destroy = (void (*) (linked_list_t *))destroy;
diff --git a/src/libstrongswan/utils/linked_list.h b/src/libstrongswan/utils/linked_list.h
index ac36ef46d..310e91e3c 100644
--- a/src/libstrongswan/utils/linked_list.h
+++ b/src/libstrongswan/utils/linked_list.h
@@ -1,12 +1,5 @@
-/**
- * @file linked_list.h
- *
- * @brief Interface of linked_list_t.
- *
- */
-
/*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -20,6 +13,13 @@
* 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.
+ *
+ * $Id: linked_list.h 3841 2008-04-18 11:48:53Z tobias $
+ */
+
+/**
+ * @defgroup linked_list linked_list
+ * @{ @ingroup utils
*/
#ifndef LINKED_LIST_H_
@@ -42,51 +42,50 @@ typedef struct linked_list_t linked_list_t;
* @return
* - TRUE, if the item matched
* - FALSE, otherwise
- * @ingroup utils
*/
typedef bool (*linked_list_match_t)(void *item, ...);
/**
- * @brief Class implementing a double linked list.
- *
- * General purpose linked list. This list is not synchronized.
+ * Method to be invoked on elements in a linked list (used in invoke_* functions)
*
- * @b Costructors:
- * - linked_list_create()
+ * @param item current list item
+ * @param ... user supplied data (only pointers, at most 5)
+ */
+typedef void (*linked_list_invoke_t)(void *item, ...);
+
+/**
+ * Class implementing a double linked list.
*
- * @ingroup utils
+ * General purpose linked list. This list is not synchronized.
*/
struct linked_list_t {
/**
- * @brief Gets the count of items in the list.
+ * Gets the count of items in the list.
*
- * @param this calling object
* @return number of items in list
*/
int (*get_count) (linked_list_t *this);
/**
- * @brief Creates a iterator for the given list.
+ * Creates a iterator for the given list.
*
* @warning Created iterator_t object has to get destroyed by the caller.
*
* @deprecated Iterator is obsolete and will disappear, it is too
* complicated to implement. Use enumerator instead.
*
- * @param this calling object
* @param forward iterator direction (TRUE: front to end)
* @return new iterator_t object
*/
iterator_t *(*create_iterator) (linked_list_t *this, bool forward);
/**
- * @brief Creates a iterator, locking a mutex.
+ * Creates a iterator, locking a mutex.
*
* The supplied mutex is acquired immediately, and released
* when the iterator gets destroyed.
*
- * @param this calling object
* @param mutex mutex to use for exclusive access
* @return new iterator_t object
*/
@@ -94,113 +93,86 @@ struct linked_list_t {
pthread_mutex_t *mutex);
/**
- * @brief Create an enumerator over the list.
+ * Create an enumerator over the list.
*
* The enumerator is a "lightweight" iterator. It only has two methods
* and should therefore be much easier to implement.
*
- * @param this calling object
* @return enumerator over list items
*/
enumerator_t* (*create_enumerator)(linked_list_t *this);
/**
- * @brief Inserts a new item at the beginning of the list.
+ * Inserts a new item at the beginning of the list.
*
- * @param this calling object
- * @param[in] item item value to insert in list
+ * @param item item value to insert in list
*/
void (*insert_first) (linked_list_t *this, void *item);
/**
- * @brief Removes the first item in the list and returns its value.
+ * Removes the first item in the list and returns its value.
*
- * @param this calling object
- * @param[out] item returned value of first item, or NULL
- * @return
- * - SUCCESS
- * - NOT_FOUND, if list is empty
+ * @param item returned value of first item, or NULL
+ * @return SUCCESS, or NOT_FOUND if list is empty
*/
status_t (*remove_first) (linked_list_t *this, void **item);
-
- /**
- * @brief Returns the value of the first list item without removing it.
- *
- * @param this calling object
- * @param[out] item returned value of first item
- * @return
- * - SUCCESS
- * - NOT_FOUND, if list is empty
- */
- status_t (*get_first) (linked_list_t *this, void **item);
-
+
/**
- * @brief Inserts a new item at the end of the list.
- *
- * @param this calling object
- * @param[in] item value to insert into list
+ * Remove an item from the list where the enumerator points to.
+ *
+ * @param enumerator enumerator with position
*/
- void (*insert_last) (linked_list_t *this, void *item);
+ void (*remove_at)(linked_list_t *this, enumerator_t *enumerator);
/**
- * @brief Inserts a new item at a given position in the list.
+ * Remove items from the list matching item.
*
- * @param this calling object
- * @param position position starting at 0 to insert new entry
- * @param[in] item value to insert into list
- * @return
- * - SUCCESS
- * - INVALID_ARG if position not existing
+ * If a compare function is given, it is called for each item, where
+ * the first parameter is the current list item and the second parameter
+ * is the supplied item parameter.
+ * If compare is NULL, compare is is done by pointer.
+ *
+ * @param item item to remove/pass to comparator
+ * @param compare compare function, or NULL
+ * @return number of removed items
*/
- status_t (*insert_at_position) (linked_list_t *this,size_t position, void *item);
+ int (*remove)(linked_list_t *this, void *item, bool (*compare)(void *,void*));
/**
- * @brief Removes an item from a given position in the list.
+ * Returns the value of the first list item without removing it.
*
* @param this calling object
- * @param position position starting at 0 to remove entry from
- * @param[out] item removed item will be stored at this location
- * @return
- * - SUCCESS
- * - INVALID_ARG if position not existing
+ * @param item returned value of first item
+ * @return SUCCESS, NOT_FOUND if list is empty
*/
- status_t (*remove_at_position) (linked_list_t *this, size_t position, void **item);
+ status_t (*get_first) (linked_list_t *this, void **item);
/**
- * @brief Get an item from a given position in the list.
+ * Inserts a new item at the end of the list.
*
- * @param this calling object
- * @param position position starting at 0 to get entry from
- * @param[out] item item will be stored at this location
- * @return
- * - SUCCESS
- * - INVALID_ARG if position not existing
+ * @param item value to insert into list
*/
- status_t (*get_at_position) (linked_list_t *this, size_t position, void **item);
+ void (*insert_last) (linked_list_t *this, void *item);
/**
- * @brief Removes the last item in the list and returns its value.
+ * Removes the last item in the list and returns its value.
*
* @param this calling object
- * @param[out] item returned value of last item, or NULL
- * @return
- * - SUCCESS
- * - NOT_FOUND if list is empty
+ * @param item returned value of last item, or NULL
+ * @return SUCCESS, NOT_FOUND if list is empty
*/
status_t (*remove_last) (linked_list_t *this, void **item);
/**
- * @brief Returns the value of the last list item without removing it.
+ * Returns the value of the last list item without removing it.
*
* @param this calling object
- * @param[out] item returned value of last item
- * @return
- * - SUCCESS
- * - NOT_FOUND if list is empty
+ * @param item returned value of last item
+ * @return SUCCESS, NOT_FOUND if list is empty
*/
status_t (*get_last) (linked_list_t *this, void **item);
- /** @brief Find the first matching element in the list.
+ /** Find the first matching element in the list.
*
* The first object passed to the match function is the current list item,
* followed by the user supplied data.
@@ -210,19 +182,15 @@ struct linked_list_t {
*
* @warning Only use pointers as user supplied data.
*
- * @param this calling object
* @param match comparison function to call on each object
- * @param[out] item
- * - the list item, if found
- * - NULL, otherwise
+ * @param item the list item, if found
* @param ... user data to supply to match function (limited to 5 arguments)
- * @return
- * - SUCCESS, if found
- * - NOT_FOUND, otherwise
+ * @return SUCCESS if found, NOT_FOUND otherwise
*/
- status_t (*find_first) (linked_list_t *this, linked_list_match_t match, void **item, ...);
+ status_t (*find_first) (linked_list_t *this, linked_list_match_t match,
+ void **item, ...);
- /** @brief Find the last matching element in the list.
+ /** Find the last matching element in the list.
*
* The first object passed to the match function is the current list item,
* followed by the user supplied data.
@@ -232,20 +200,16 @@ struct linked_list_t {
*
* @warning Only use pointers as user supplied data.
*
- * @param this calling object
* @param match comparison function to call on each object
- * @param[out] item
- * - the list item, if found
- * - NULL, otherwise
+ * @param item the list item, if found
* @param ... user data to supply to match function (limited to 5 arguments)
- * @return
- * - SUCCESS, if found
- * - NOT_FOUND, otherwise
+ * @return SUCCESS if found, NOT_FOUND otherwise
*/
- status_t (*find_last) (linked_list_t *this, linked_list_match_t match, void **item, ...);
+ status_t (*find_last) (linked_list_t *this, linked_list_match_t match,
+ void **item, ...);
/**
- * @brief Invoke a method on all of the contained objects.
+ * Invoke a method on all of the contained objects.
*
* If a linked list contains objects with function pointers,
* invoke() can call a method on each of the objects. The
@@ -253,79 +217,70 @@ struct linked_list_t {
* which can be evalutated at compile time using the offsetof
* macro, e.g.: list->invoke(list, offsetof(object_t, method));
*
- * @param this calling object
* @param offset offset of the method to invoke on objects
+ * @param ... user data to supply to called function (limited to 5 arguments)
*/
- void (*invoke_offset) (linked_list_t *this, size_t offset);
+ void (*invoke_offset) (linked_list_t *this, size_t offset, ...);
/**
- * @brief Invoke a function on all of the contained objects.
+ * Invoke a function on all of the contained objects.
*
- * @param this calling object
- * @param offset offset of the method to invoke on objects
+ * @param function offset of the method to invoke on objects
+ * @param ... user data to supply to called function (limited to 5 arguments)
*/
- void (*invoke_function) (linked_list_t *this, void (*)(void*));
+ void (*invoke_function) (linked_list_t *this, linked_list_invoke_t function, ...);
/**
- * @brief Clones a list and its objects using the objects' clone method.
+ * Clones a list and its objects using the objects' clone method.
*
- * @param this calling object
* @param offset offset ot the objects clone function
* @return cloned list
*/
linked_list_t *(*clone_offset) (linked_list_t *this, size_t offset);
/**
- * @brief Clones a list and its objects using a given function.
+ * Clones a list and its objects using a given function.
*
- * @param this calling object
* @param function function that clones an object
* @return cloned list
*/
linked_list_t *(*clone_function) (linked_list_t *this, void*(*)(void*));
/**
- * @brief Destroys a linked_list object.
- *
- * @param this calling object
+ * Destroys a linked_list object.
*/
void (*destroy) (linked_list_t *this);
/**
- * @brief Destroys a list and its objects using the destructor.
+ * Destroys a list and its objects using the destructor.
*
* If a linked list and the contained objects should be destroyed, use
* destroy_offset. The supplied offset specifies the destructor to
* call on each object. The offset may be calculated using the offsetof
* macro, e.g.: list->destroy_offset(list, offsetof(object_t, destroy));
*
- * @param this calling object
* @param offset offset of the objects destructor
*/
void (*destroy_offset) (linked_list_t *this, size_t offset);
/**
- * @brief Destroys a list and its contents using a a cleanup function.
+ * Destroys a list and its contents using a a cleanup function.
*
* If a linked list and its contents should get destroyed using a specific
* cleanup function, use destroy_function. This is useful when the
* list contains malloc()-ed blocks which should get freed,
* e.g.: list->destroy_function(list, free);
*
- * @param this calling object
* @param function function to call on each object
*/
void (*destroy_function) (linked_list_t *this, void (*)(void*));
};
/**
- * @brief Creates an empty linked list object.
+ * Creates an empty linked list object.
*
* @return linked_list_t object.
- *
- * @ingroup utils
*/
linked_list_t *linked_list_create(void);
-
-#endif /*LINKED_LIST_H_*/
+#endif /*LINKED_LIST_H_ @} */
diff --git a/src/libstrongswan/utils/mutex.c b/src/libstrongswan/utils/mutex.c
new file mode 100644
index 000000000..425389b4f
--- /dev/null
+++ b/src/libstrongswan/utils/mutex.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * 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.
+ *
+ * $Id: mutex.c 3589 2008-03-13 14:14:44Z martin $
+ */
+
+#include "mutex.h"
+
+#include <library.h>
+#include <debug.h>
+
+#include <pthread.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+
+typedef struct private_mutex_t private_mutex_t;
+typedef struct private_n_mutex_t private_n_mutex_t;
+typedef struct private_r_mutex_t private_r_mutex_t;
+typedef struct private_condvar_t private_condvar_t;
+
+/**
+ * private data of mutex
+ */
+struct private_mutex_t {
+
+ /**
+ * public functions
+ */
+ mutex_t public;
+
+ /**
+ * wrapped pthread mutex
+ */
+ pthread_mutex_t mutex;
+};
+
+/**
+ * private data of mutex, extended by recursive locking information
+ */
+struct private_r_mutex_t {
+
+ /**
+ * public functions
+ */
+ private_mutex_t generic;
+
+ /**
+ * thread which currently owns mutex
+ */
+ pthread_t thread;
+
+ /**
+ * times we have locked the lock
+ */
+ int times;
+};
+
+/**
+ * private data of condvar
+ */
+struct private_condvar_t {
+
+ /**
+ * public functions
+ */
+ condvar_t public;
+
+ /**
+ * wrapped pthread condvar
+ */
+ pthread_cond_t condvar;
+};
+
+/**
+ * Implementation of mutex_t.lock.
+ */
+static void lock(private_mutex_t *this)
+{
+ if (pthread_mutex_lock(&this->mutex))
+ {
+ DBG1("!!!! MUTEX %sLOCK ERROR, your code is buggy !!!", "");
+ }
+}
+
+/**
+ * Implementation of mutex_t.unlock.
+ */
+static void unlock(private_mutex_t *this)
+{
+ if (pthread_mutex_unlock(&this->mutex))
+ {
+ DBG1("!!!! MUTEX %sLOCK ERROR, your code is buggy !!!", "UN");
+ }
+}
+
+/**
+ * Implementation of mutex_t.lock.
+ */
+static void lock_r(private_r_mutex_t *this)
+{
+ pthread_t self = pthread_self();
+
+ if (this->thread == self)
+ {
+ this->times++;
+ return;
+ }
+ lock(&this->generic);
+ this->thread = self;
+ this->times = 1;
+}
+
+/**
+ * Implementation of mutex_t.unlock.
+ */
+static void unlock_r(private_r_mutex_t *this)
+{
+ if (--this->times == 0)
+ {
+ this->thread = 0;
+ unlock(&this->generic);
+ }
+}
+
+/**
+ * Implementation of mutex_t.destroy
+ */
+static void mutex_destroy(private_mutex_t *this)
+{
+ pthread_mutex_destroy(&this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+mutex_t *mutex_create(mutex_type_t type)
+{
+ switch (type)
+ {
+ case MUTEX_RECURSIVE:
+ {
+ private_r_mutex_t *this = malloc_thing(private_r_mutex_t);
+
+ this->generic.public.lock = (void(*)(mutex_t*))lock_r;
+ this->generic.public.unlock = (void(*)(mutex_t*))unlock_r;
+ this->generic.public.destroy = (void(*)(mutex_t*))mutex_destroy;
+
+ pthread_mutex_init(&this->generic.mutex, NULL);
+ this->thread = 0;
+ this->times = 0;
+
+ return &this->generic.public;
+ }
+ case MUTEX_DEFAULT:
+ default:
+ {
+ private_mutex_t *this = malloc_thing(private_mutex_t);
+
+ this->public.lock = (void(*)(mutex_t*))lock;
+ this->public.unlock = (void(*)(mutex_t*))unlock;
+ this->public.destroy = (void(*)(mutex_t*))mutex_destroy;
+
+ pthread_mutex_init(&this->mutex, NULL);
+
+ return &this->public;
+ }
+ }
+}
+
+/**
+ * Implementation of condvar_t.wait.
+ */
+static void wait(private_condvar_t *this, private_mutex_t *mutex)
+{
+ pthread_cond_wait(&this->condvar, &mutex->mutex);
+}
+
+/**
+ * Implementation of condvar_t.timed_wait.
+ */
+static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex,
+ u_int timeout)
+{
+ struct timespec ts;
+ struct timeval tv;
+ u_int s, ms;
+
+ gettimeofday(&tv, NULL);
+
+ s = timeout / 1000;
+ ms = timeout % 1000;
+
+ ts.tv_sec = tv.tv_sec + s;
+ ts.tv_nsec = tv.tv_usec * 1000 + ms * 1000000;
+ if (ts.tv_nsec > 1000000000 /* 1s */)
+ {
+ ts.tv_nsec -= 1000000000;
+ ts.tv_sec++;
+ }
+ return (pthread_cond_timedwait(&this->condvar, &mutex->mutex,
+ &ts) == ETIMEDOUT);
+}
+
+/**
+ * Implementation of condvar_t.signal.
+ */
+static void signal(private_condvar_t *this)
+{
+ pthread_cond_signal(&this->condvar);
+}
+
+/**
+ * Implementation of condvar_t.broadcast.
+ */
+static void broadcast(private_condvar_t *this)
+{
+ pthread_cond_broadcast(&this->condvar);
+}
+
+/**
+ * Implementation of condvar_t.destroy
+ */
+static void condvar_destroy(private_condvar_t *this)
+{
+ pthread_cond_destroy(&this->condvar);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+condvar_t *condvar_create(condvar_type_t type)
+{
+ switch (type)
+ {
+ case CONDVAR_DEFAULT:
+ default:
+ {
+ private_condvar_t *this = malloc_thing(private_condvar_t);
+
+ this->public.wait = (void(*)(condvar_t*, mutex_t *mutex))wait;
+ this->public.timed_wait = (bool(*)(condvar_t*, mutex_t *mutex, u_int timeout))timed_wait;
+ this->public.signal = (void(*)(condvar_t*))signal;
+ this->public.broadcast = (void(*)(condvar_t*))broadcast;
+ this->public.destroy = (void(*)(condvar_t*))condvar_destroy;
+
+ pthread_cond_init(&this->condvar, NULL);
+
+ return &this->public;
+ }
+ }
+}
+
diff --git a/src/libstrongswan/utils/mutex.h b/src/libstrongswan/utils/mutex.h
new file mode 100644
index 000000000..cf557c35c
--- /dev/null
+++ b/src/libstrongswan/utils/mutex.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * 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.
+ */
+
+/**
+ * @defgroup mutex mutex
+ * @{ @ingroup utils
+ */
+
+#ifndef MUTEX_H_
+#define MUTEX_H_
+
+typedef struct mutex_t mutex_t;
+typedef struct condvar_t condvar_t;
+typedef enum mutex_type_t mutex_type_t;
+typedef enum condvar_type_t condvar_type_t;
+
+#include <library.h>
+
+/**
+ * Type of mutex.
+ */
+enum mutex_type_t {
+ /** default mutex */
+ MUTEX_DEFAULT = 0,
+ /** allow recursive locking of the mutex */
+ MUTEX_RECURSIVE = 1,
+};
+
+/**
+ * Type of condvar.
+ */
+enum condvar_type_t {
+ /** default condvar */
+ CONDVAR_DEFAULT = 0,
+};
+
+/**
+ * Mutex wrapper implements simple, portable and advanced mutex functions.
+ */
+struct mutex_t {
+
+ /**
+ * Acquire the lock to the mutex.
+ */
+ void (*lock)(mutex_t *this);
+
+ /**
+ * Release the lock on the mutex.
+ */
+ void (*unlock)(mutex_t *this);
+
+ /**
+ * Destroy a mutex instance.
+ */
+ void (*destroy)(mutex_t *this);
+};
+
+/**
+ * Condvar wrapper to use in conjunction with mutex_t.
+ */
+struct condvar_t {
+
+ /**
+ * Wait on a condvar until it gets signalized.
+ *
+ * @param mutex mutex to release while waiting
+ */
+ void (*wait)(condvar_t *this, mutex_t *mutex);
+
+ /**
+ * Wait on a condvar until it gets signalized, or times out.
+ *
+ * @param mutex mutex to release while waiting
+ * @param timeout timeout im ms
+ * @return TRUE if timed out, FALSE otherwise
+ */
+ bool (*timed_wait)(condvar_t *this, mutex_t *mutex, u_int timeout);
+
+ /**
+ * Wake up a single thread in a condvar.
+ */
+ void (*signal)(condvar_t *this);
+
+ /**
+ * Wake up all threads in a condvar.
+ */
+ void (*broadcast)(condvar_t *this);
+
+ /**
+ * Destroy a condvar and free its resources.
+ */
+ void (*destroy)(condvar_t *this);
+};
+
+/**
+ * Create a mutex instance.
+ *
+ * @param type type of mutex to create
+ * @return unlocked mutex instance
+ */
+mutex_t *mutex_create(mutex_type_t type);
+
+/**
+ * Create a condvar instance.
+ *
+ * @param type type of condvar to create
+ * @return condvar instance
+ */
+condvar_t *condvar_create(condvar_type_t type);
+
+#endif /* MUTEX_H_ @}*/
diff --git a/src/libstrongswan/utils/optionsfrom.c b/src/libstrongswan/utils/optionsfrom.c
index 39e38cc58..18427e197 100644
--- a/src/libstrongswan/utils/optionsfrom.c
+++ b/src/libstrongswan/utils/optionsfrom.c
@@ -1,13 +1,5 @@
-/**
- * @file optionsfrom.c
- *
- * @brief read command line options from a file
- *
- */
-
/*
* Copyright (C) 2007-2008 Andreas Steffen
- *
* Hochschule fuer Technik Rapperswil
*
* This library is free software; you can redistribute it and/or modify it
@@ -20,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
*
- * RCSID $Id$
+ * $Id: optionsfrom.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdio.h>
diff --git a/src/libstrongswan/utils/optionsfrom.h b/src/libstrongswan/utils/optionsfrom.h
index 0014cec36..424b9dc61 100644
--- a/src/libstrongswan/utils/optionsfrom.h
+++ b/src/libstrongswan/utils/optionsfrom.h
@@ -1,10 +1,3 @@
-/**
- * @file optionsfrom.h
- *
- * @brief Read command line options from a file
- *
- */
-
/*
* Copyright (C) 2007-2008 Andreas Steffen
*
@@ -20,7 +13,12 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id$
+ * $Id: optionsfrom.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup optionsfrom optionsfrom
+ * @{ @ingroup utils
*/
#ifndef OPTIONSFROM_H_
@@ -29,41 +27,33 @@
typedef struct options_t options_t;
/**
- * @brief options object.
- *
- * @b Constructors:
- * - options_create()
- *
- * @ingroup utils
+ * Reads additional command line arguments from a file
*/
struct options_t {
+
/**
- * @brief Check if the PKCS#7 contentType is data
+ * Check if the PKCS#7 contentType is data
*
- * @param this calling object
* @param filename file containing the options
* @param argcp pointer to argc
* @param argvp pointer to argv[]
* @param optind current optind, number of next argument
* @return TRUE if optionsfrom parsing successful
*/
- bool (*from) (options_t * this, char *filename, int *argcp, char **argvp[], int optind);
+ bool (*from) (options_t * this, char *filename,
+ int *argcp, char **argvp[], int optind);
/**
- * @brief Destroys the options_t object.
- *
- * @param this options_t object to destroy
+ * Destroys the options_t object.
*/
void (*destroy) (options_t *this);
};
/**
- * @brief Create an options object.
+ * Create an options object.
*
* @return created options_t object
- *
- * @ingroup utils
*/
options_t *options_create(void);
-#endif /*OPTIONSFROM_H_*/
+#endif /*OPTIONSFROM_H_ @} */
diff --git a/src/libstrongswan/utils/randomizer.c b/src/libstrongswan/utils/randomizer.c
deleted file mode 100644
index c15d108c7..000000000
--- a/src/libstrongswan/utils/randomizer.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * @file randomizer.c
- *
- * @brief Implementation of randomizer_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 <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "randomizer.h"
-
-
-typedef struct private_randomizer_t private_randomizer_t;
-
-/**
- * Private data of an randomizer_t object.
- */
-struct private_randomizer_t {
-
- /**
- * Public randomizer_t interface.
- */
- randomizer_t public;
-
- /**
- * @brief Reads a specific number of bytes from random or pseudo random device.
- *
- * @param this calling object
- * @param pseudo_random TRUE, if from pseudo random bytes should be read,
- * FALSE for true random bytes
- * @param bytes number of bytes to read
- * @param[out] buffer pointer to buffer where to write the data in.
- * Size of buffer has to be at least bytes.
- */
- status_t (*get_bytes_from_device) (private_randomizer_t *this,bool pseudo_random, size_t bytes, u_int8_t *buffer);
-};
-
-
-/**
- * Implementation of private_randomizer_t.get_bytes_from_device.
- */
-static status_t get_bytes_from_device(private_randomizer_t *this,bool pseudo_random, size_t bytes, u_int8_t *buffer)
-{
- size_t ndone;
- int device;
- size_t got;
- char * device_name;
-
- device_name = pseudo_random ? DEV_URANDOM : DEV_RANDOM;
-
- device = open(device_name, 0);
- if (device < 0) {
- return FAILED;
- }
- ndone = 0;
-
- /* read until nbytes are read */
- while (ndone < bytes)
- {
- got = read(device, buffer + ndone, bytes - ndone);
- if (got <= 0) {
- close(device);
- return FAILED;
- }
- ndone += got;
- }
- close(device);
- return SUCCESS;
-}
-
-/**
- * Implementation of randomizer_t.get_random_bytes.
- */
-static status_t get_random_bytes(private_randomizer_t *this,size_t bytes, u_int8_t *buffer)
-{
- return this->get_bytes_from_device(this, FALSE, bytes, buffer);
-}
-
-/**
- * Implementation of randomizer_t.allocate_random_bytes.
- */
-static status_t allocate_random_bytes(private_randomizer_t *this, size_t bytes, chunk_t *chunk)
-{
- status_t status;
- chunk->len = bytes;
- chunk->ptr = malloc(bytes);
- status = this->get_bytes_from_device(this, FALSE, bytes, chunk->ptr);
- if (status != SUCCESS)
- {
- free(chunk->ptr);
- }
- return status;
-}
-
-/**
- * Implementation of randomizer_t.get_pseudo_random_bytes.
- */
-static status_t get_pseudo_random_bytes(private_randomizer_t *this,size_t bytes, u_int8_t *buffer)
-{
- return (this->get_bytes_from_device(this, TRUE, bytes, buffer));
-}
-
-/**
- * Implementation of randomizer_t.allocate_pseudo_random_bytes.
- */
-static status_t allocate_pseudo_random_bytes(private_randomizer_t *this, size_t bytes, chunk_t *chunk)
-{
- status_t status;
- chunk->len = bytes;
- chunk->ptr = malloc(bytes);
- status = this->get_bytes_from_device(this, TRUE, bytes, chunk->ptr);
- if (status != SUCCESS)
- {
- free(chunk->ptr);
- }
- return status;
-}
-
-/**
- * Implementation of randomizer_t.destroy.
- */
-static void destroy(private_randomizer_t *this)
-{
- free(this);
-}
-
-/*
- * Described in header.
- */
-randomizer_t *randomizer_create(void)
-{
- private_randomizer_t *this = malloc_thing(private_randomizer_t);
-
- /* public functions */
- this->public.get_random_bytes = (status_t (*) (randomizer_t *,size_t, u_int8_t *)) get_random_bytes;
- this->public.allocate_random_bytes = (status_t (*) (randomizer_t *,size_t, chunk_t *)) allocate_random_bytes;
- this->public.get_pseudo_random_bytes = (status_t (*) (randomizer_t *,size_t, u_int8_t *)) get_pseudo_random_bytes;
- this->public.allocate_pseudo_random_bytes = (status_t (*) (randomizer_t *,size_t, chunk_t *)) allocate_pseudo_random_bytes;
- this->public.destroy = (void (*) (randomizer_t *))destroy;
-
- /* private functions */
- this->get_bytes_from_device = get_bytes_from_device;
-
- return &(this->public);
-}
diff --git a/src/libstrongswan/utils/randomizer.h b/src/libstrongswan/utils/randomizer.h
deleted file mode 100644
index afbade059..000000000
--- a/src/libstrongswan/utils/randomizer.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * @file randomizer.h
- *
- * @brief Interface of randomizer_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 RANDOMIZER_H_
-#define RANDOMIZER_H_
-
-typedef struct randomizer_t randomizer_t;
-
-#include <library.h>
-
-#ifndef DEV_RANDOM
-/**
- * Device to read real random bytes
- */
-# define DEV_RANDOM "/dev/random"
-#endif
-
-#ifndef DEV_URANDOM
-/**
- * Device to read pseudo random bytes
- */
-# define DEV_URANDOM "/dev/urandom"
-#endif
-
-/**
- * @brief Class used to get random and pseudo random values.
- *
- * @b Constructors:
- * - randomizer_create()
- *
- * @ingroup utils
- */
-struct randomizer_t {
-
- /**
- * @brief Reads a specific number of bytes from random device.
- *
- * @param this calling randomizer_t object
- * @param bytes number of bytes to read
- * @param[out] buffer pointer to buffer where to write the data in.
- * Size of buffer has to be at least bytes.
- * @return SUCCESS, or FAILED
- */
- status_t (*get_random_bytes) (randomizer_t *this, size_t bytes, u_int8_t *buffer);
-
- /**
- * @brief Allocates space and writes in random bytes.
- *
- * @param this calling randomizer_t object
- * @param bytes number of bytes to allocate
- * @param[out] chunk chunk which will hold the allocated random bytes
- * @return SUCCESS, or FAILED
- */
- status_t (*allocate_random_bytes) (randomizer_t *this, size_t bytes, chunk_t *chunk);
-
- /**
- * @brief Reads a specific number of bytes from pseudo random device.
- *
- * @param this calling randomizer_t object
- * @param bytes number of bytes to read
- * @param[out] buffer pointer to buffer where to write the data in.
- * size of buffer has to be at least bytes.
- * @return SUCCESS, or FAILED
- */
- status_t (*get_pseudo_random_bytes) (randomizer_t *this,size_t bytes, u_int8_t *buffer);
-
- /**
- * @brief Allocates space and writes in pseudo random bytes.
- *
- * @param this calling randomizer_t object
- * @param bytes number of bytes to allocate
- * @param[out] chunk chunk which will hold the allocated random bytes
- * @return SUCCESS, or FAILED
- */
- status_t (*allocate_pseudo_random_bytes) (randomizer_t *this, size_t bytes, chunk_t *chunk);
-
- /**
- * @brief Destroys a randomizer_t object.
- *
- * @param this randomizer_t object to destroy
- */
- void (*destroy) (randomizer_t *this);
-};
-
-/**
- * @brief Creates a randomizer_t object.
- *
- * @return created randomizer_t, or
- *
- * @ingroup utils
- */
-randomizer_t *randomizer_create(void);
-
-#endif /*RANDOMIZER_H_*/