introduced new logging subsystem using bus:

passive listeners can register on the bus
  active listeners wait for signals actively
  multiplexing allows multiple listeners to receive debug signals
  a lot more...
This commit is contained in:
Martin Willi
2006-10-18 11:46:13 +00:00
parent 8cdce67afa
commit 60356f3375
129 changed files with 4264 additions and 6440 deletions
-1
View File
@@ -4,7 +4,6 @@ ipsec_PROGRAMS = charon
charon_SOURCES = \ charon_SOURCES = \
bus/bus.c bus/bus.h \ bus/bus.c bus/bus.h \
bus/listeners/stream_logger.c bus/listeners/stream_logger.h \
bus/listeners/sys_logger.c bus/listeners/sys_logger.h \ bus/listeners/sys_logger.c bus/listeners/sys_logger.h \
bus/listeners/file_logger.c bus/listeners/file_logger.h \ bus/listeners/file_logger.c bus/listeners/file_logger.h \
config/connections/connection.c config/connections/connection.h \ config/connections/connection.c config/connections/connection.h \
+267 -7
View File
@@ -22,6 +22,102 @@
#include "bus.h" #include "bus.h"
#include <pthread.h>
ENUM(signal_names, SIG_ANY, SIG_MAX,
/** should not get printed */
"SIG_ANY",
/** debugging message types */
"DMN",
"MGR",
"IKE",
"CHD",
"JOB",
"CFG",
"KNL",
"NET",
"ENC",
"LIB",
/** should not get printed */
"SIG_DBG_MAX",
/** all level0 signals are AUDIT signals */
"AUD",
"AUD",
"AUD",
"AUD",
"AUD",
"AUD",
"AUD",
"AUD",
"AUD",
"AUD",
"AUD",
"AUD",
/** should not get printed */
"SIG_MAX",
);
typedef struct active_listener_t active_listener_t;
/**
* information for a active listener
*/
struct active_listener_t {
/**
* associated thread
*/
pthread_t id;
/**
* condvar to wait for a signal
*/
pthread_cond_t cond;
/**
* state of the thread
*/
enum {
/** not registered, do not wait for thread */
UNREGISTERED,
/** registered, if a signal occurs, wait until it is LISTENING */
REGISTERED,
/** listening, deliver signal */
LISTENING,
} state;
/**
* currently processed signals type
*/
signal_t signal;
/**
* verbosity level of the signal
*/
level_t level;
/**
* current processed signals thread number
*/
int thread;
/**
* currently processed signals ike_sa
*/
ike_sa_t *ike_sa;
/**
* currently processed signals format string
*/
char *format;
/**
* currently processed signals format varargs
*/
va_list args;
};
typedef struct private_bus_t private_bus_t; typedef struct private_bus_t private_bus_t;
/** /**
@@ -38,6 +134,16 @@ struct private_bus_t {
*/ */
linked_list_t *listeners; linked_list_t *listeners;
/**
* List of active listeners with listener_state TRUE
*/
linked_list_t *active_listeners;
/**
* mutex to synchronize active listeners
*/
pthread_mutex_t mutex;
/** /**
* Thread local storage for a unique, simple thread ID * Thread local storage for a unique, simple thread ID
*/ */
@@ -76,9 +182,95 @@ static int get_thread_number(private_bus_t *this)
*/ */
static void add_listener(private_bus_t *this, bus_listener_t *listener) static void add_listener(private_bus_t *this, bus_listener_t *listener)
{ {
pthread_mutex_lock(&this->mutex);
this->listeners->insert_last(this->listeners, (void*)listener); this->listeners->insert_last(this->listeners, (void*)listener);
pthread_mutex_unlock(&this->mutex);
} }
/**
* Get the listener object for the calling thread
*/
static active_listener_t *get_active_listener(private_bus_t *this)
{
active_listener_t *current, *found = NULL;
iterator_t *iterator;
/* if the thread was here once before, we have a active_listener record */
iterator = this->active_listeners->create_iterator(this->active_listeners, TRUE);
while (iterator->iterate(iterator, (void**)&current))
{
if (current->id == pthread_self())
{
found = current;
break;
}
}
iterator->destroy(iterator);
if (found == NULL)
{
/* create a new object for a never-seen thread */
found = malloc_thing(active_listener_t);
found->id = pthread_self();
pthread_cond_init(&found->cond, NULL);
this->active_listeners->insert_last(this->active_listeners, found);
}
return found;
}
/**
* Implementation of bus_t.listen.
*/
static signal_t listen_(private_bus_t *this, level_t *level, int *thread,
ike_sa_t **ike_sa, char** format, va_list* args)
{
active_listener_t *listener;
pthread_mutex_lock(&this->mutex);
listener = get_active_listener(this);
/* go "listening", say hello to a thread which have a signal for us */
listener->state = LISTENING;
pthread_cond_broadcast(&listener->cond);
/* wait until it has us delivered a signal, and go back to "registered" */
pthread_cond_wait(&listener->cond, &this->mutex);
pthread_mutex_unlock(&this->mutex);
/* return signal values */
*level = listener->level;
*thread = listener->thread;
*ike_sa = listener->ike_sa;
*format = listener->format;
*args = listener->args;
return listener->signal;
}
/**
* Implementation of bus_t.set_listen_state.
*/
static void set_listen_state(private_bus_t *this, bool active)
{
active_listener_t *listener;
pthread_mutex_lock(&this->mutex);
listener = get_active_listener(this);
if (active)
{
listener->state = REGISTERED;
}
else
{
listener->state = UNREGISTERED;
/* say hello to signal omitter; we are finished processing the signal */
pthread_cond_signal(&listener->cond);
}
pthread_mutex_unlock(&this->mutex);
}
/** /**
* Implementation of bus_t.set_sa. * Implementation of bus_t.set_sa.
*/ */
@@ -88,28 +280,83 @@ static void set_sa(private_bus_t *this, ike_sa_t *ike_sa)
} }
/** /**
* Implementation of bus_t.signal. * Implementation of bus_t.vsignal.
*/ */
static void signal_(private_bus_t *this, signal_t signal, level_t condition, static void vsignal(private_bus_t *this, signal_t signal, level_t level,
char* format, ...) char* format, va_list args)
{ {
iterator_t *iterator; iterator_t *iterator;
bus_listener_t *listener; bus_listener_t *listener;
va_list args; active_listener_t *active_listener;
ike_sa_t *ike_sa; ike_sa_t *ike_sa;
int thread; int thread;
ike_sa = pthread_getspecific(this->thread_sa); ike_sa = pthread_getspecific(this->thread_sa);
thread = get_thread_number(this); thread = get_thread_number(this);
va_start(args, format);
pthread_mutex_lock(&this->mutex);
/* do the job for all passive bus_listeners */
iterator = this->listeners->create_iterator(this->listeners, TRUE); iterator = this->listeners->create_iterator(this->listeners, TRUE);
while (iterator->iterate(iterator, (void**)&listener)) while (iterator->iterate(iterator, (void**)&listener))
{ {
listener->signal(listener, thread, ike_sa, va_list args_copy;
signal, condition, format, args);
va_copy(args_copy, args);
listener->signal(listener, signal, level, thread, ike_sa, format, args_copy);
va_end(args_copy);
} }
iterator->destroy(iterator); iterator->destroy(iterator);
/* wake up all active listeners */
iterator = this->active_listeners->create_iterator(this->active_listeners, TRUE);
while (iterator->iterate(iterator, (void**)&active_listener))
{
/* wait until it is back */
while (active_listener->state == REGISTERED)
{
pthread_cond_wait(&active_listener->cond, &this->mutex);
}
/* if thread is listening now, give it the signal to process */
if (active_listener->state == LISTENING)
{
active_listener->level = level;
active_listener->thread = thread;
active_listener->ike_sa = ike_sa;
active_listener->signal = signal;
active_listener->format = format;
va_copy(active_listener->args, args);
active_listener->state = REGISTERED;
pthread_cond_signal(&active_listener->cond);
}
}
/* we must wait now until all are not in state REGISTERED,
* as they may still use our arguments */
iterator->reset(iterator);
while (iterator->iterate(iterator, (void**)&active_listener))
{
while (active_listener->state == REGISTERED)
{
pthread_cond_wait(&active_listener->cond, &this->mutex);
}
va_end(active_listener->args);
}
iterator->destroy(iterator);
pthread_mutex_unlock(&this->mutex);
}
/**
* Implementation of bus_t.signal.
*/
static void signal_(private_bus_t *this, signal_t signal, level_t level,
char* format, ...)
{
va_list args;
va_start(args, format);
vsignal(this, signal, level, format, args);
va_end(args); va_end(args);
} }
@@ -118,6 +365,14 @@ static void signal_(private_bus_t *this, signal_t signal, level_t condition,
*/ */
static void destroy(private_bus_t *this) static void destroy(private_bus_t *this)
{ {
active_listener_t *listener;
while (this->active_listeners->remove_last(this->active_listeners,
(void**)&listener) == SUCCESS)
{
free(listener);
}
this->active_listeners->destroy(this->active_listeners);
this->listeners->destroy(this->listeners); this->listeners->destroy(this->listeners);
free(this); free(this);
} }
@@ -130,11 +385,16 @@ bus_t *bus_create()
private_bus_t *this = malloc_thing(private_bus_t); private_bus_t *this = malloc_thing(private_bus_t);
this->public.add_listener = (void(*)(bus_t*,bus_listener_t*))add_listener; this->public.add_listener = (void(*)(bus_t*,bus_listener_t*))add_listener;
this->public.listen = (signal_t(*)(bus_t*,level_t*,int*,ike_sa_t**,char**,va_list*))listen_;
this->public.set_listen_state = (void(*)(bus_t*,bool))set_listen_state;
this->public.set_sa = (void(*)(bus_t*,ike_sa_t*))set_sa; this->public.set_sa = (void(*)(bus_t*,ike_sa_t*))set_sa;
this->public.signal = (void(*)(bus_t*,signal_t,level_t,char*,...))signal_; this->public.signal = (void(*)(bus_t*,signal_t,level_t,char*,...))signal_;
this->public.vsignal = (void(*)(bus_t*,signal_t,level_t,char*,va_list))vsignal;
this->public.destroy = (void(*)(bus_t*)) destroy; this->public.destroy = (void(*)(bus_t*)) destroy;
this->listeners = linked_list_create(); this->listeners = linked_list_create();
this->active_listeners = linked_list_create();
pthread_mutex_init(&this->mutex, NULL);
pthread_key_create(&this->thread_id, NULL); pthread_key_create(&this->thread_id, NULL);
pthread_key_create(&this->thread_sa, NULL); pthread_key_create(&this->thread_sa, NULL);
+224 -78
View File
@@ -29,60 +29,81 @@
#include <sa/child_sa.h> #include <sa/child_sa.h>
/**
* @brief Raise a signal for an occured event.
*
* @param sig signal_t signal description
* @param level level for the signal
* @param format printf() style format string
* @param ... printf() style agument list
*/
#define SIG(sig, level, format, ...) charon->bus->signal(charon->bus, sig, level, format, ##__VA_ARGS__)
/**
* @brief Set the IKE_SA the calling thread is using.
*
* @param ike_sa ike_sa to register, or NULL to unregister
*/
#define SIG_SA(ike_sa) charon->bus->set_sa(charon->bus, ike_sa)
/**
* @brief Log a debug message via the signal bus.
*
* @param signal signal_t signal description
* @param format printf() style format string
* @param ... printf() style agument list
*/
#define DBG1(sig, format, ...) charon->bus->signal(charon->bus, sig, LEV_DBG1, format, ##__VA_ARGS__)
#define DBG2(sig, format, ...) charon->bus->signal(charon->bus, sig, LEV_DBG2, format, ##__VA_ARGS__)
#define DBG3(sig, format, ...) charon->bus->signal(charon->bus, sig, LEV_DBG3, format, ##__VA_ARGS__)
#define DBG4(sig, format, ...) charon->bus->signal(charon->bus, sig, LEV_DBG4, format, ##__VA_ARGS__)
typedef enum signal_t signal_t; typedef enum signal_t signal_t;
/**
* @brief signals ommited by the daemon.
*
* Signaling is for different purporses. First, it allows debugging via
* "debugging signal messages", sencondly, it allows to follow certain
* mechanisms currently going on in the daemon. As we are multithreaded,
* and a multiple messages are involved, it's not possible to follow
* one connection setup without further infrastructure. These infrastructure
* is provided by the bus and the signals the whole daemon ommits to the bus.
*
* @par Schema 1: Signals involved in IKE_SA/CHILD_SA initiation
*
* In the initiation of a IKE- or CHILD_SA is triggered by three possible
* sources: User request, a request from the other peer, or a request
* triggered by the kernel.
* Once the user requests initiation, the SIG_INITIATE signal is ommited.
* This signal contains the IKE_SA that got created. Any further signals
* have the same IKE_SA and are therefore easy to trace.
* If the kernel initiates, a SIG_ACQUIRE is sent over the bus.
* If a new IKE_SA is needed, it is set up. If it succeeds, a
* SIG_IKE_ESTABLISHED is ommitted. If the peer didn't accept our DH
* group, the initiation fails. A SIG_DH_INVALID is sent over the bus. It still
* contains the the old IKE_SA. Shortly afterwards, a SIG_DH_RETRY is ommited.
* It contains the NEW IKE_SA. This mechanism allows us to trace the setup even
* beyond a INVALID_KE_PAYLOUD error.
* If the setup fails, SIG_IKE_ESTABLISH_FAILED is sent.
* After a successful establishment of the IKE_SA, or if an already established
* IKE_SA is reused, the child establishment begins. If it is set up with
* the ike_auth transaction, the SIG_CHILD_ESTABLISHED signal is ommited
* directly after the SIG_IKE_ESTABLISHED signal, as both are set up
* simultaneously. The child setup may fail (in a ike_auth, or in a
* create_child_sa exchange), if so, the SIG_CHID_ESTABLISH_FAILED signal
* is raised.
*
* @verbatim
"ipsec up" "peer msg" "kernel acquire"
| | |
V | V
SIG_INITIATE | SIG_ACQUIRE
\ | /
\ |/______________________________________________
\/________________________________ \
/\ \ \ |
| | | | |
V V | V |
SIG_IKE_ESTABLISHED SIG_IKE_ESTABLISH_FALIED | SIG_DH_INVALID |
\ | | | |
\ X | V |
\___________________________/ SIG_DH_RETRY |
/\ \______________/
| |
V V
SIG_CHILD_ESTABLISHED SIG_CHILD_ESTABLISH_FAILED
|
X
@endverbatim
* Other scenarios are much simpler. Termination is just indicated with
* a simple SIG_CHILD_TERMINATED and/or SIG_IKE_TERMINATED signal. There
* are other signals as SIG_CHILD_ROUTED or SIG_CHILD_UNROUTED. Rekeying is
* also trivial (SIG_IKE_REKEYED/SIG_CHILD_REKEYED), but may contain
* SIG_DH_INVALID...
*
* @ingroup bus
*/
enum signal_t { enum signal_t {
/** an IKE_SA has been established */ /** pseudo signal, representing any other signal */
SIG_IKE_UP, SIG_ANY,
/** an IKE_SA has been closed */
SIG_IKE_DOWN,
/** an IKE_SA has been rekeyed */
SIG_IKE_REKEY,
/** a CHILD_SA has been installed */
SIG_CHILD_UP,
/** a CHILD_SA has been closed */
SIG_CHILD_DOWN,
/** a CHILD_SA has been rekeyed */
SIG_CHILD_REKEY,
/** a CHILD_SA has been routed */
SIG_CHILD_ROUTE,
/** a CHILD_SA has been unrouted */
SIG_CHILD_UNROUTE,
/** a remote peer has been authenticated using RSA digital signature */
SIG_AUTH_RSA,
/** a remote peer has been authenticated using preshared keys */
SIG_AUTH_PSK,
/** debugging messages printed from daemon main loop */
SIG_DBG_DMN,
/** debugging message printed from IKE_SA_MANAGER */
SIG_DBG_MGR,
/** debugging message printed from an IKE_SA */ /** debugging message printed from an IKE_SA */
SIG_DBG_IKE, SIG_DBG_IKE,
/** debugging message printed from a CHILD_SA */ /** debugging message printed from a CHILD_SA */
@@ -97,27 +118,103 @@ enum signal_t {
SIG_DBG_NET, SIG_DBG_NET,
/** debugging message printed from message encoding/decoding */ /** debugging message printed from message encoding/decoding */
SIG_DBG_ENC, SIG_DBG_ENC,
/** debugging message printed from libstrongswan via logging hook */
SIG_DBG_LIB,
SIG_MAX, /** number of debug signals */
SIG_DBG_MAX,
/** initiation started on user request */
SIG_INITIATE,
/** acquiring on kernel request */
SIG_ACQUIRE,
/** an IKE_SA has been established */
SIG_IKE_UP,
/** an IKE_SA has been closed as requested */
SIG_IKE_DOWN,
/** an IKE_SA got deleted due an error */
SIG_IKE_FAILED,
/** an IKE_SA has been rekeyed */
SIG_IKE_REKEY,
/** a CHILD_SA has been established */
SIG_CHILD_UP,
/** a CHILD_SA has been closed as requested */
SIG_CHILD_DOWN,
/** a CHILD_SA got deleted due an error */
SIG_CHILD_FAILED,
/** a CHILD_SA has been rekeyed */
SIG_CHILD_REKEY,
/** a CHILD_SA has been routed */
SIG_CHILD_ROUTE,
/** a CHILD_SA has been unrouted */
SIG_CHILD_UNROUTE,
SIG_MAX
}; };
/**
* short names of signals using 3 chars
*/
extern enum_name_t *signal_names;
typedef enum level_t level_t; typedef enum level_t level_t;
/**
* Signal levels used to control output verbosity.
*/
enum level_t { enum level_t {
/** Signal indicates something has failed */ /** numerical levels from 0 to 4 */
LEV_FAILED, LEVEL_0 = 0,
/** Signal indicates something was successful */ LEVEL_1 = 1,
LEV_SUCCESS, LEVEL_2 = 2,
/** Debug level 1, control flow messages */ LEVEL_3 = 3,
LEV_DBG1, LEVEL_4 = 4,
/** Debug level 2, more detail informational messages */ /** absolutely silent, no signal is ommited with this level */
LEV_DBG2, LEVEL_SILENT = -1,
/** Debug level 3, RAW data output */ /** alias for numberical levels */
LEV_DBG3, LEVEL_AUDIT = LEVEL_0,
/** Debug level 4, RAW data with sensitive (private) data */ LEVEL_CTRL = LEVEL_1,
LEV_DBG4, LEVEL_CTRLMORE = LEVEL_2,
LEVEL_RAW = LEVEL_3,
LEVEL_PRIVATE = LEVEL_4,
}; };
/**
* @brief Raise a signal for an occured event.
*
* @param sig signal_t signal description
* @param format printf() style format string
* @param ... printf() style agument list
*/
#define SIG(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_0, format, ##__VA_ARGS__)
/**
* @brief Log a debug message via the signal bus.
*
* @param signal signal_t signal description
* @param format printf() style format string
* @param ... printf() style agument list
*/
#define DBG1(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_1, format, ##__VA_ARGS__)
#define DBG2(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_2, format, ##__VA_ARGS__)
#define DBG3(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_3, format, ##__VA_ARGS__)
#define DBG4(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_4, format, ##__VA_ARGS__)
/**
* @brief Get the type of a signal.
*
* A signal may be a debugging signal with a specific context. They have
* a level specific for their context > 0. All audit signals use the
* type 0. This allows filtering of singals by their type.
*
* @param signal signal to get the type from
* @return type of the signal, between 0..(SIG_DBG_MAX-1)
*/
#define SIG_TYPE(sig) (sig > SIG_DBG_MAX ? SIG_ANY : sig)
typedef struct bus_listener_t bus_listener_t; typedef struct bus_listener_t bus_listener_t;
/** /**
@@ -135,21 +232,21 @@ struct bus_listener_t {
* *
* A numerical identification for the thread is included, as the * A numerical identification for the thread is included, as the
* associated IKE_SA, if any. Signal specifies the type of * associated IKE_SA, if any. Signal specifies the type of
* the event occured, with a verbosity level. The format string specifies * the event occured. The format string specifies
* an additional informational or error message with a printf() like * an additional informational or error message with a printf() like
* variable argument list. This is in the va_list form, as forwarding * variable argument list. This is in the va_list form, as forwarding
* a "..." parameters to functions is not (cleanly) possible. * a "..." parameters to functions is not (cleanly) possible.
* *
* @param this listener * @param this listener
* @param singal kind of the signal (up, down, rekeyed, ...)
* @param level verbosity level of the signal
* @param thread ID of the thread raised this signal * @param thread ID of the thread raised this signal
* @param ike_sa IKE_SA associated to the event * @param ike_sa IKE_SA associated to the event
* @param singal kind of the signal (up, down, rekeyed, ...)
* @param level level for signal
* @param format printf() style format string * @param format printf() style format string
* @param args vprintf() style va_list argument list * @param args vprintf() style va_list argument list
*/ */
void (*signal) (bus_listener_t *this, int thread, ike_sa_t *ike_sa, void (*signal) (bus_listener_t *this, signal_t signal, level_t level,
signal_t signal, level_t level, char* format, va_list args); int thread, ike_sa_t *ike_sa, char* format, va_list args);
}; };
@@ -161,7 +258,8 @@ typedef struct bus_t bus_t;
* The signal bus is not much more than a multiplexer. A listener interested * The signal bus is not much more than a multiplexer. A listener interested
* in receiving event signals registers at the bus. Any signals sent to * in receiving event signals registers at the bus. Any signals sent to
* are delivered to all registered listeners. * are delivered to all registered listeners.
* * To deliver signals to threads, the blocking listen() call may be used
* to wait for a signal.
* *
* @ingroup bus * @ingroup bus
*/ */
@@ -171,12 +269,51 @@ struct bus_t {
* @brief Register a listener to the bus. * @brief Register a listener to the bus.
* *
* A registered listener receives all signals which are sent to the bus. * A registered listener receives all signals which are sent to the bus.
* The listener is passive; the thread which ommited the signal
* processes the listener routine.
* *
* @param this bus * @param this bus
* @param listener listener to register. * @param listener listener to register.
*/ */
void (*add_listener) (bus_t *this, bus_listener_t *listener); void (*add_listener) (bus_t *this, bus_listener_t *listener);
/**
* @brief Listen actively on the bus.
*
* As we are fully multithreaded, we must provide a mechanism
* for active threads to listen to the bus. With the listen() method,
* a thread waits until a signal occurs, and then processes it.
* To prevent the listen() calling thread to miss signals ommited while
* it processes a signal, registration is required. This is done through
* the set_listen_state() method, see below.
*
* @param this bus
* @param level verbosity level of the signal
* @param thread receives thread number ommited the signal
* @param ike_sa receives the IKE_SA involved in the signal, or NULL
* @param format receives the format string supplied with the signal
* @param va_list receives the variable argument list for format
* @return the ommited signal type
*/
signal_t (*listen) (bus_t *this, level_t* level, int *thread,
ike_sa_t **ike_sa, char** format, va_list* args);
/**
* @brief Set the listening state of the calling thread.
*
* To prevent message loss for active listeners using listen(), threads
* must register themself to the bus before starting to listen(). When
* a signal occurs, the ommiter waits until all threads with listen_state
* TRUE are waiting in the listen() method to process the signal.
* It is important that a thread with liste_state TRUE calls listen()
* periodically, or sets it's listening state to FALSE; otherwise
* all signal omitting threads get blocked on the bus.
*
* @param this bus
* @param active TRUE to set to listening
*/
void (*set_listen_state) (bus_t *this, bool active);
/** /**
* @brief Set the IKE_SA the calling thread is using. * @brief Set the IKE_SA the calling thread is using.
* *
@@ -185,8 +322,6 @@ struct bus_t {
* time it checked it out. Before checking it in, the thread unregisters * time it checked it out. Before checking it in, the thread unregisters
* the IKE_SA (by passing NULL). This IKE_SA is stored per-thread, so each * the IKE_SA (by passing NULL). This IKE_SA is stored per-thread, so each
* thread has one IKE_SA registered (or not). * thread has one IKE_SA registered (or not).
* There is a macro to simplify the call.
* @see SIG_SA()
* *
* @param this bus * @param this bus
* @param ike_sa ike_sa to register, or NULL to unregister * @param ike_sa ike_sa to register, or NULL to unregister
@@ -196,22 +331,33 @@ struct bus_t {
/** /**
* @brief Send a signal to the bus. * @brief Send a signal to the bus.
* *
* A signal may belong to an IKE_SA and a CHILD_SA. If so, these * The signal specifies the type of the event occured. The format string
* are supplied to the signal function. The signal specifies the type of * specifies an additional informational or error message with a
* the event occured. The format string specifies an additional * printf() like variable argument list.
* informational or error message with a printf() like variable argument * Some useful macros are available to shorten this call.
* list.
* Some useful macros may be available to shorten this call.
* @see SIG(), DBG1() * @see SIG(), DBG1()
* *
* @param this bus * @param this bus
* @param singal kind of the signal (up, down, rekeyed, ...) * @param singal kind of the signal (up, down, rekeyed, ...)
* @param level status level of the signal to send * @param level verbosity level of the signal
* @param format printf() style format string * @param format printf() style format string
* @param ... printf() style argument list * @param ... printf() style argument list
*/ */
void (*signal) (bus_t *this, signal_t signal, level_t level, char* format, ...); void (*signal) (bus_t *this, signal_t signal, level_t level, char* format, ...);
/**
* @brief Send a signal to the bus using va_list arguments.
*
* Same as bus_t.signal(), but uses va_list argument list.
*
* @param this bus
* @param singal kind of the signal (up, down, rekeyed, ...)
* @param level verbosity level of the signal
* @param format printf() style format string
* @param args va_list arguments
*/
void (*vsignal) (bus_t *this, signal_t signal, level_t level, char* format, va_list args);
/** /**
* @brief Destroy the signal bus. * @brief Destroy the signal bus.
* *
+36 -89
View File
@@ -20,15 +20,11 @@
* for more details. * for more details.
*/ */
/* for fmemopen() */
#define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "file_logger.h" #include "file_logger.h"
#include <bus/listeners/stream_logger.h>
typedef struct private_file_logger_t private_file_logger_t; typedef struct private_file_logger_t private_file_logger_t;
@@ -48,99 +44,58 @@ struct private_file_logger_t {
FILE *out; FILE *out;
/** /**
* Internal used stream logger that does the dirty work * Maximum level to log
*/ */
stream_logger_t *logger; level_t levels[SIG_DBG_MAX];
/**
* Memory stream used for stream_logger
*/
FILE *stream;
/**
* Underlying buffer for stream
*/
char buffer[4096];
}; };
/** /**
* Implementation of bus_listener_t.signal. * Implementation of bus_listener_t.signal.
*/ */
static void signal_(private_file_logger_t *this, int thread, ike_sa_t* ike_sa, static void signal_(private_file_logger_t *this, signal_t signal, level_t level,
signal_t signal, level_t level, int thread, ike_sa_t* ike_sa, char *format, va_list args)
char *format, va_list args)
{ {
char line[512]; if (level <= this->levels[SIG_TYPE(signal)])
char *prefix;
FILE *reader;
switch (signal)
{ {
case SIG_IKE_UP: char buffer[8192];
case SIG_IKE_DOWN: char *current = buffer, *next;
case SIG_IKE_REKEY:
case SIG_DBG_IKE: /* write in memory buffer first */
prefix = "IKE"; vsnprintf(buffer, sizeof(buffer), format, args);
break;
case SIG_DBG_CHD: /* prepend a prefix in front of every line */
prefix = "CHD"; while (current)
break;
case SIG_DBG_JOB:
prefix = "JOG";
break;
case SIG_DBG_CFG:
prefix = "CFG";
break;
case SIG_DBG_KNL:
prefix = "KNL";
break;
case SIG_DBG_NET:
prefix = "NET";
break;
case SIG_DBG_ENC:
prefix = "ENC";
break;
default:
prefix = "???";
break;
}
flockfile(this->stream);
/* reset memory stream */
rewind(this->stream);
memset(this->buffer, '\0', sizeof(this->buffer));
/* log to memstream */
this->logger->listener.signal(&this->logger->listener, thread, ike_sa,
signal, level, format, args);
/* flush is needed to append a '\0' */
fflush(this->stream);
/* create a reader stream that reads out line by line */
reader = fmemopen(this->buffer, sizeof(this->buffer), "r");
while (fgets(line, sizeof(line), reader))
{
if (line[0] == '\0')
{ {
/* abort on EOF */ next = strchr(current, '\n');
break; if (next)
} {
else if (line[0] != '\n') *(next++) = '\0';
{ }
fprintf(this->out, "%.2d[%s] %s", thread, prefix, line); fprintf(this->out, "%.2d[%N] %s\n", thread, signal_names, signal, current);
current = next;
} }
} }
fclose(reader);
funlockfile(this->stream);
} }
/** /**
* Implementation of file_logger_t.set_level. * Implementation of file_logger_t.set_level.
*/ */
static void set_level(private_file_logger_t *this, signal_t signal, level_t max) static void set_level(private_file_logger_t *this, signal_t signal, level_t level)
{ {
this->logger->set_level(this->logger, signal, max); if (signal == SIG_ANY)
{
int i;
for (i = 0; i < SIG_DBG_MAX; i++)
{
this->levels[i] = level;
}
}
else
{
this->levels[SIG_TYPE(signal)] = level;
}
} }
/** /**
@@ -148,8 +103,6 @@ static void set_level(private_file_logger_t *this, signal_t signal, level_t max)
*/ */
static void destroy(private_file_logger_t *this) static void destroy(private_file_logger_t *this)
{ {
fclose(this->stream);
this->logger->destroy(this->logger);
free(this); free(this);
} }
@@ -161,19 +114,13 @@ file_logger_t *file_logger_create(FILE *out)
private_file_logger_t *this = malloc_thing(private_file_logger_t); private_file_logger_t *this = malloc_thing(private_file_logger_t);
/* public functions */ /* public functions */
this->public.listener.signal = (void(*)(bus_listener_t*,int,ike_sa_t*,signal_t,level_t,char*,va_list))signal_; this->public.listener.signal = (void(*)(bus_listener_t*,signal_t,level_t,int,ike_sa_t*,char*,va_list))signal_;
this->public.set_level = (void(*)(file_logger_t*,signal_t,level_t))set_level; this->public.set_level = (void(*)(file_logger_t*,signal_t,level_t))set_level;
this->public.destroy = (void(*)(file_logger_t*))destroy; this->public.destroy = (void(*)(file_logger_t*))destroy;
/* private variables */ /* private variables */
this->out = out; this->out = out;
this->stream = fmemopen(this->buffer, sizeof(this->buffer), "w"); set_level(this, SIG_ANY, LEVEL_SILENT);
if (this->stream == NULL)
{
/* fallback to stderr */
this->stream = stderr;
}
this->logger = stream_logger_create(this->stream);
return &this->public; return &this->public;
} }
+1 -1
View File
@@ -48,7 +48,7 @@ struct file_logger_t {
* *
* @param this stream_logger_t object * @param this stream_logger_t object
* @param singal type of signal * @param singal type of signal
* @param level max level to log * @param level max level to log (0..4)
*/ */
void (*set_level) (file_logger_t *this, signal_t signal, level_t level); void (*set_level) (file_logger_t *this, signal_t signal, level_t level);
-141
View File
@@ -1,141 +0,0 @@
/**
* @file stream_logger.c
*
* @brief Implementation of stream_logger_t.
*
*/
/*
* Copyright (C) 2006 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.
*/
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include "stream_logger.h"
typedef struct private_stream_logger_t private_stream_logger_t;
/**
* @brief Private data of a stream_logger_t object.
*/
struct private_stream_logger_t {
/**
* Public data
*/
stream_logger_t public;
/**
* Maximum level to log
*/
level_t max;
/**
* stream to write log output to
*/
FILE *out;
};
/**
* Implementation of bus_listener_t.signal.
*/
static void signal_(private_stream_logger_t *this, int thread,
ike_sa_t* ike_sa, signal_t signal, level_t level,
char *format, va_list args)
{
FILE *o = this->out;
flockfile(o);
if (level <= this->max)
{
/* then print the info */
switch (signal)
{
case SIG_IKE_UP:
{
if (level == LEV_SUCCESS)
{
fprintf(o, "established: %H[%D]...%H[%D]\n",
ike_sa->get_my_host(ike_sa), ike_sa->get_my_id(ike_sa),
ike_sa->get_other_host(ike_sa), ike_sa->get_other_id(ike_sa));
}
else
{
fprintf(o, "establishing failed: %H[%D]...%H[%D]:\n",
ike_sa->get_my_host(ike_sa), ike_sa->get_my_id(ike_sa),
ike_sa->get_other_host(ike_sa), ike_sa->get_other_id(ike_sa));
fprintf(o, " ");
vfprintf(o, format, args);
fprintf(o, "\n");
}
break;
}
case SIG_DBG_IKE:
case SIG_DBG_CHD:
case SIG_DBG_JOB:
case SIG_DBG_CFG:
case SIG_DBG_KNL:
case SIG_DBG_NET:
case SIG_DBG_ENC:
{
vfprintf(o, format, args);
fprintf(o, "\n");
break;
}
default:
break;
}
}
funlockfile(o);
}
/**
* Implementation of stream_logger_t.set_level.
*/
static void set_level(private_stream_logger_t *this, signal_t signal, level_t max)
{
this->max = max;
}
/**
* Implementation of stream_logger_t.destroy.
*/
static void destroy(private_stream_logger_t *this)
{
free(this);
}
/*
* Described in header.
*/
stream_logger_t *stream_logger_create(FILE *out)
{
private_stream_logger_t *this = malloc_thing(private_stream_logger_t);
/* public functions */
this->public.listener.signal = (void(*)(bus_listener_t*,int,ike_sa_t*,signal_t,level_t,char*,va_list))signal_;
this->public.set_level = (void(*)(stream_logger_t*,signal_t,level_t))set_level;
this->public.destroy = (void(*)(stream_logger_t*))destroy;
/* private variables */
this->max = LEV_DBG4;
this->out = out;
return &this->public;
}
-75
View File
@@ -1,75 +0,0 @@
/**
* @file stream_logger.h
*
* @brief Interface of stream_logger_t.
*
*/
/*
* Copyright (C) 2006 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.
*/
#ifndef STREAM_LOGGER_H_
#define STREAM_LOGGER_H_
#include <stdio.h>
#include <types.h>
#include <bus/bus.h>
typedef struct stream_logger_t stream_logger_t;
/**
* @brief Logger for a file stream which implements bus_listener_t.
*
* @b Constructors:
* - stream_logger_create()
*
* @ingroup listeners
*/
struct stream_logger_t {
/**
* Implements the bus_listener_t interface.
*/
bus_listener_t listener;
/**
* @brief Set the loglevel for a signal type.
*
* @param this stream_logger_t object
* @param singal type of signal
* @param level max level to log
*/
void (*set_level) (stream_logger_t *this, signal_t signal, level_t level);
/**
* @brief Destroys a stream_logger_t object.
*
* @param this stream_logger_t object
*/
void (*destroy) (stream_logger_t *this);
};
/**
* @brief Constructor to create a stream_logger_t object.
*
* @param out output stream to log to
* @return stream_logger_t object
*
* @ingroup utils
*/
stream_logger_t *stream_logger_create(FILE *out);
#endif /* STREAM_LOGGER_H_ */
+37 -89
View File
@@ -20,16 +20,12 @@
* for more details. * for more details.
*/ */
/* for open_memstream() */
#define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#include "sys_logger.h" #include "sys_logger.h"
#include <bus/listeners/stream_logger.h>
typedef struct private_sys_logger_t private_sys_logger_t; typedef struct private_sys_logger_t private_sys_logger_t;
@@ -49,99 +45,59 @@ struct private_sys_logger_t {
int facility; int facility;
/** /**
* Internal used stream logger that does the dirty work * Maximum level to log
*/ */
stream_logger_t *logger; level_t levels[SIG_DBG_MAX];
/**
* Memory stream used for stream_logger
*/
FILE *stream;
/**
* Underlying buffer for stream
*/
char buffer[4096];
}; };
/** /**
* Implementation of bus_listener_t.signal. * Implementation of bus_listener_t.signal.
*/ */
static void signal_(private_sys_logger_t *this, int thread, ike_sa_t* ike_sa, static void signal_(private_sys_logger_t *this, signal_t signal, level_t level,
signal_t signal, level_t level, int thread, ike_sa_t* ike_sa, char *format, va_list args)
char *format, va_list args)
{ {
char line[512]; if (level <= this->levels[SIG_TYPE(signal)])
char *prefix;
FILE *reader;
switch (signal)
{ {
case SIG_IKE_UP: char buffer[8192];
case SIG_IKE_DOWN: char *current = buffer, *next;
case SIG_IKE_REKEY:
case SIG_DBG_IKE: /* write in memory buffer first */
prefix = "IKE"; vsnprintf(buffer, sizeof(buffer), format, args);
break;
case SIG_DBG_CHD: /* do a syslog with every line */
prefix = "CHD"; while (current)
break;
case SIG_DBG_JOB:
prefix = "JOG";
break;
case SIG_DBG_CFG:
prefix = "CFG";
break;
case SIG_DBG_KNL:
prefix = "KNL";
break;
case SIG_DBG_NET:
prefix = "NET";
break;
case SIG_DBG_ENC:
prefix = "ENC";
break;
default:
prefix = "???";
break;
}
flockfile(this->stream);
/* reset memory stream */
rewind(this->stream);
memset(this->buffer, '\0', sizeof(this->buffer));
/* log to memstream */
this->logger->listener.signal(&this->logger->listener, thread, ike_sa,
signal, level, format, args);
/* flush is needed to append a '\0' */
fflush(this->stream);
/* create a reader stream that reads out line by line */
reader = fmemopen(this->buffer, sizeof(this->buffer), "r");
while (fgets(line, sizeof(line), reader))
{
if (line[0] == '\0')
{ {
/* abort on EOF */ next = strchr(current, '\n');
break; if (next)
} {
else if (line[0] != '\n') *(next++) = '\0';
{ }
syslog(this->facility|LOG_INFO, "%.2d[%s] %s", thread, prefix, line); syslog(this->facility|LOG_INFO, "%.2d[%N] %s\n",
thread, signal_names, signal, current);
current = next;
} }
} }
fclose(reader);
funlockfile(this->stream);
} }
/** /**
* Implementation of sys_logger_t.set_level. * Implementation of sys_logger_t.set_level.
*/ */
static void set_level(private_sys_logger_t *this, signal_t signal, level_t max) static void set_level(private_sys_logger_t *this, signal_t signal, level_t level)
{ {
this->logger->set_level(this->logger, signal, max); if (signal == SIG_ANY)
{
int i;
for (i = 0; i < SIG_DBG_MAX; i++)
{
this->levels[i] = level;
}
}
else
{
this->levels[SIG_TYPE(signal)] = level;
}
} }
/** /**
@@ -150,8 +106,6 @@ static void set_level(private_sys_logger_t *this, signal_t signal, level_t max)
static void destroy(private_sys_logger_t *this) static void destroy(private_sys_logger_t *this)
{ {
closelog(); closelog();
fclose(this->stream);
this->logger->destroy(this->logger);
free(this); free(this);
} }
@@ -163,19 +117,13 @@ sys_logger_t *sys_logger_create(int facility)
private_sys_logger_t *this = malloc_thing(private_sys_logger_t); private_sys_logger_t *this = malloc_thing(private_sys_logger_t);
/* public functions */ /* public functions */
this->public.listener.signal = (void(*)(bus_listener_t*,int,ike_sa_t*,signal_t,level_t,char*,va_list))signal_; this->public.listener.signal = (void(*)(bus_listener_t*,signal_t,level_t,int,ike_sa_t*,char*,va_list))signal_;
this->public.set_level = (void(*)(sys_logger_t*,signal_t,level_t))set_level; this->public.set_level = (void(*)(sys_logger_t*,signal_t,level_t))set_level;
this->public.destroy = (void(*)(sys_logger_t*))destroy; this->public.destroy = (void(*)(sys_logger_t*))destroy;
/* private variables */ /* private variables */
this->facility = facility; this->facility = facility;
this->stream = fmemopen(this->buffer, sizeof(this->buffer), "w"); set_level(this, SIG_ANY, LEVEL_SILENT);
if (this->stream == NULL)
{
/* fallback to stderr */
this->stream = stderr;
}
this->logger = stream_logger_create(this->stream);
return &this->public; return &this->public;
} }
+5 -11
View File
@@ -24,19 +24,13 @@
#include <string.h> #include <string.h>
#include <config/connections/connection.h> #include <config/connections/connection.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger.h>
/** ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
* String mappings for cert_policy_t. "CERT_ALWAYS_SEND",
*/ "CERT_SEND_IF_ASKED",
mapping_t cert_policy_m[] = { "CERT_NEVER_SEND"
{CERT_ALWAYS_SEND, "CERT_ALWAYS_SEND"}, );
{CERT_SEND_IF_ASKED, "CERT_SEND_IF_ASKED"},
{CERT_NEVER_SEND, "CERT_NEVER_SEND"},
{MAPPING_END, NULL}
};
typedef struct private_connection_t private_connection_t; typedef struct private_connection_t private_connection_t;
+2 -2
View File
@@ -54,11 +54,11 @@ enum cert_policy_t {
}; };
/** /**
* string mappings for certpolic_t. * enum strings for cert_policy_t
* *
* @ingroup config * @ingroup config
*/ */
extern mapping_t cert_policy_m[]; extern enum_name_t *cert_policy_names;
typedef struct connection_t connection_t; typedef struct connection_t connection_t;
@@ -25,17 +25,17 @@
#include <types.h> #include <types.h>
#include <config/connections/connection.h> #include <config/connections/connection.h>
#include <utils/logger.h> #include <utils/iterator.h>
typedef struct connection_store_t connection_store_t; typedef struct connection_store_t connection_store_t;
/** /**
* @brief The interface for a store of connection_t's. * @brief The interface for a store of connection_t's.
* *
* @b Constructors: * @b Constructors:
* - stroke_create() * - stroke_create()
* *
* @ingroup config * @ingroup config
*/ */
struct connection_store_t { struct connection_store_t {
@@ -47,7 +47,7 @@ struct connection_store_t {
* It may be used after kernel request for traffic protection. * It may be used after kernel request for traffic protection.
* The returned connection gets created/cloned and therefore must * The returned connection gets created/cloned and therefore must
* be destroyed after usage. * be destroyed after usage.
* *
* @param this calling object * @param this calling object
* @param my_id own address of connection * @param my_id own address of connection
* @param other_id others address of connection * @param other_id others address of connection
@@ -55,14 +55,15 @@ struct connection_store_t {
* - connection_t, if found * - connection_t, if found
* - NULL otherwise * - NULL otherwise
*/ */
connection_t *(*get_connection_by_hosts) (connection_store_t *this, host_t *my_host, host_t *other_host); connection_t *(*get_connection_by_hosts)(connection_store_t *this,
host_t *my_host, host_t *other_host);
/** /**
* @brief Returns a connection identified by its name. * @brief Returns a connection identified by its name.
* *
* This call is usefull to get a connection identified its * This call is usefull to get a connection identified its
* name, as on an connection setup. * name, as on an connection setup.
* *
* @param this calling object * @param this calling object
* @param name name of the connection to get * @param name name of the connection to get
* @return * @return
@@ -73,10 +74,10 @@ struct connection_store_t {
/** /**
* @brief Add a connection to the store. * @brief Add a connection to the store.
* *
* After a successful call, the connection is owned by the store and may * After a successful call, the connection is owned by the store and may
* not be manipulated nor destroyed. * not be manipulated nor destroyed.
* *
* @param this calling object * @param this calling object
* @param connection connection to add * @param connection connection to add
* @return * @return
@@ -87,10 +88,10 @@ struct connection_store_t {
/** /**
* @brief Delete a connection from the store. * @brief Delete a connection from the store.
* *
* Remove a connection from the connection store, identified * Remove a connection from the connection store, identified
* by the connections name. * by the connections name.
* *
* @param this calling object * @param this calling object
* @param name name of the connection to delete * @param name name of the connection to delete
* @return * @return
@@ -100,25 +101,16 @@ struct connection_store_t {
status_t (*delete_connection) (connection_store_t *this, char *name); status_t (*delete_connection) (connection_store_t *this, char *name);
/** /**
* @brief Log the connections stored in the store. * @brief Get an iterator for the stored connections.
* *
* Depending on the implementation of the store, the store
* logs various information to the specified logger.
* If logger is NULL, the internal logger is used, if name is
* NULL, all connections are logged
*
* @param this calling object * @param this calling object
* @param logger logger to use for the log, or NULL * @return iterator over all stored connections
* @param name name of the connection, or NULL
* @return
* - SUCCESS, or
* - FAILED
*/ */
void (*log_connections) (connection_store_t *this, logger_t *logger, char *name); iterator_t* (*create_iterator) (connection_store_t *this);
/** /**
* @brief Destroys a connection_store_t object. * @brief Destroys a connection_store_t object.
* *
* @param this calling object * @param this calling object
*/ */
void (*destroy) (connection_store_t *this); void (*destroy) (connection_store_t *this);
@@ -24,8 +24,8 @@
#include "local_connection_store.h" #include "local_connection_store.h"
#include <daemon.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger_manager.h>
typedef struct private_local_connection_store_t private_local_connection_store_t; typedef struct private_local_connection_store_t private_local_connection_store_t;
@@ -49,11 +49,6 @@ struct private_local_connection_store_t {
* Mutex to exclusivly access connection list * Mutex to exclusivly access connection list
*/ */
pthread_mutex_t mutex; pthread_mutex_t mutex;
/**
* Assigned logger
*/
logger_t *logger;
}; };
@@ -74,9 +69,8 @@ static connection_t *get_connection_by_hosts(private_local_connection_store_t *t
connection_t *candidate; connection_t *candidate;
connection_t *found = NULL; connection_t *found = NULL;
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_CFG, "looking for connection for host pair %H...%H",
"looking for connection for host pair %H...%H", my_host, other_host);
my_host, other_host);
pthread_mutex_lock(&(this->mutex)); pthread_mutex_lock(&(this->mutex));
iterator = this->connections->create_iterator(this->connections, TRUE); iterator = this->connections->create_iterator(this->connections, TRUE);
@@ -106,11 +100,9 @@ static connection_t *get_connection_by_hosts(private_local_connection_store_t *t
prio |= PRIO_ADDR_ANY; prio |= PRIO_ADDR_ANY;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_CFG, "candidate connection \"%s\": %H...%H (prio=%d)",
"candidate connection \"%s\": %H...%H (prio=%d)", candidate->get_name(candidate),
candidate->get_name(candidate), candidate_my_host, candidate_other_host, prio);
candidate_my_host, candidate_other_host,
prio);
if (prio > best_prio) if (prio > best_prio)
{ {
@@ -126,11 +118,8 @@ static connection_t *get_connection_by_hosts(private_local_connection_store_t *t
host_t *found_my_host = found->get_my_host(found); host_t *found_my_host = found->get_my_host(found);
host_t *found_other_host = found->get_other_host(found); host_t *found_other_host = found->get_other_host(found);
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_CFG, "found matching connection \"%s\": %H...%H (prio=%d)",
"found matching connection \"%s\": %H...%H (prio=%d)", found->get_name(found), found_my_host, found_other_host, best_prio);
found->get_name(found),
found_my_host, found_other_host,
best_prio);
/* give out a new reference to it */ /* give out a new reference to it */
found->get_ref(found); found->get_ref(found);
@@ -213,40 +202,12 @@ static status_t add_connection(private_local_connection_store_t *this, connectio
} }
/** /**
* Implementation of connection_store_t.log_connections. * Implementation of connection_store_t.create_iterator.
*/ */
void log_connections(private_local_connection_store_t *this, logger_t *logger, char *name) static iterator_t* create_iterator(private_local_connection_store_t *this)
{ {
iterator_t *iterator; return this->connections->create_iterator_locked(this->connections,
connection_t *current; &this->mutex);
if (logger == NULL)
{
logger = this->logger;
}
pthread_mutex_lock(&(this->mutex));
iterator = this->connections->create_iterator(this->connections, TRUE);
if (iterator->get_count(iterator))
{
logger->log(logger, CONTROL, "Templates:");
}
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&current);
if (current->is_ikev2(current) && ( name == NULL || streq(name, current->get_name(current))))
{
host_t *my_host = current->get_my_host(current);
host_t *other_host = current->get_other_host(current);
logger->log(logger, CONTROL, " \"%s\": %H...%H",
current->get_name(current), my_host, other_host);
}
}
iterator->destroy(iterator);
pthread_mutex_unlock(&(this->mutex));
} }
/** /**
@@ -277,12 +238,11 @@ local_connection_store_t * local_connection_store_create(void)
this->public.connection_store.get_connection_by_name = (connection_t*(*)(connection_store_t*,char*))get_connection_by_name; this->public.connection_store.get_connection_by_name = (connection_t*(*)(connection_store_t*,char*))get_connection_by_name;
this->public.connection_store.delete_connection = (status_t(*)(connection_store_t*,char*))delete_connection; this->public.connection_store.delete_connection = (status_t(*)(connection_store_t*,char*))delete_connection;
this->public.connection_store.add_connection = (status_t(*)(connection_store_t*,connection_t*))add_connection; this->public.connection_store.add_connection = (status_t(*)(connection_store_t*,connection_t*))add_connection;
this->public.connection_store.log_connections = (void(*)(connection_store_t*,logger_t*,char*))log_connections; this->public.connection_store.create_iterator = (iterator_t*(*)(connection_store_t*))create_iterator;
this->public.connection_store.destroy = (void(*)(connection_store_t*))destroy; this->public.connection_store.destroy = (void(*)(connection_store_t*))destroy;
/* private variables */ /* private variables */
this->connections = linked_list_create(); this->connections = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
pthread_mutex_init(&(this->mutex), NULL); pthread_mutex_init(&(this->mutex), NULL);
return (&this->public); return (&this->public);
@@ -29,7 +29,6 @@
#include <crypto/rsa/rsa_private_key.h> #include <crypto/rsa/rsa_private_key.h>
#include <crypto/rsa/rsa_public_key.h> #include <crypto/rsa/rsa_public_key.h>
#include <utils/identification.h> #include <utils/identification.h>
#include <utils/logger.h>
typedef struct credential_store_t credential_store_t; typedef struct credential_store_t credential_store_t;
@@ -136,31 +135,28 @@ struct credential_store_t {
x509_t* (*add_ca_certificate) (credential_store_t *this, x509_t *cert); x509_t* (*add_ca_certificate) (credential_store_t *this, x509_t *cert);
/** /**
* @brief Lists all certificates kept in the local credential store. * @brief Create an iterator over all end certificates.
* *
* @param this calling object * @param this calling object
* @param logger logger to be used * @return iterator
* @param utc log dates either in UTC or local time
*/ */
void (*log_certificates) (credential_store_t *this, logger_t *logger, bool utc); iterator_t* (*create_cert_iterator) (credential_store_t *this);
/** /**
* @brief Lists all CA certificates kept in the local credential store. * @brief Create an iterator over all CA certificates.
* *
* @param this calling object * @param this calling object
* @param logger logger to be used * @return iterator
* @param utc log dates either in UTC or local time
*/ */
void (*log_ca_certificates) (credential_store_t *this, logger_t *logger, bool utc); iterator_t* (*create_cacert_iterator) (credential_store_t *this);
/** /**
* @brief Lists all CRLs kept in the local credential store. * @brief Create an iterator over all CRLs.
* *
* @param this calling object * @param this calling object
* @param logger logger to be used * @return iterator
* @param utc log dates either in UTC or local time
*/ */
void (*log_crls) (credential_store_t *this, logger_t *logger, bool utc); iterator_t* (*create_crl_iterator) (credential_store_t *this);
/** /**
* @brief Loads trusted CA certificates from a default directory. * @brief Loads trusted CA certificates from a default directory.
@@ -28,7 +28,6 @@
#include <types.h> #include <types.h>
#include <utils/lexparser.h> #include <utils/lexparser.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <crypto/certinfo.h> #include <crypto/certinfo.h>
#include <crypto/rsa/rsa_public_key.h> #include <crypto/rsa/rsa_public_key.h>
#include <crypto/x509.h> #include <crypto/x509.h>
@@ -56,13 +55,6 @@ struct shared_key_t {
* list of peer IDs * list of peer IDs
*/ */
linked_list_t *peers; linked_list_t *peers;
/**
* @brief Destroys a shared_key_t object.
*
* @param this calling object
*/
void (*destroy) (shared_key_t *this);
}; };
@@ -88,7 +80,6 @@ static void shared_key_destroy(shared_key_t *this)
* @brief Creates a shared_key_t object. * @brief Creates a shared_key_t object.
* *
* @param shared_key shared key value * @param shared_key shared key value
*
* @return shared_key_t object * @return shared_key_t object
* *
* @ingroup config * @ingroup config
@@ -97,9 +88,6 @@ static shared_key_t *shared_key_create(chunk_t secret)
{ {
shared_key_t *this = malloc_thing(shared_key_t); shared_key_t *this = malloc_thing(shared_key_t);
/* private functions */
this->destroy = shared_key_destroy;
/* private data */ /* private data */
this->secret = chunk_clone(secret); this->secret = chunk_clone(secret);
this->peers = linked_list_create(); this->peers = linked_list_create();
@@ -154,11 +142,6 @@ struct private_local_credential_store_t {
* enforce strict crl policy * enforce strict crl policy
*/ */
bool strict; bool strict;
/**
* Assigned logger
*/
logger_t *logger;
}; };
@@ -285,20 +268,19 @@ static rsa_public_key_t *get_trusted_public_key(private_local_credential_store_t
ugh = cert->is_valid(cert, NULL); ugh = cert->is_valid(cert, NULL);
if (ugh != NULL) if (ugh != NULL)
{ {
this->logger->log(this->logger, ERROR, "certificate %s"); DBG1(SIG_DBG_CFG, "certificate %s", ugh);
return NULL; return NULL;
} }
status = cert->get_status(cert); status = cert->get_status(cert);
if (status == CERT_REVOKED || status == CERT_UNTRUSTED || (this->strict && status != CERT_GOOD)) if (status == CERT_REVOKED || status == CERT_UNTRUSTED || (this->strict && status != CERT_GOOD))
{ {
this->logger->log(this->logger, ERROR, "certificate status: %s", DBG1(SIG_DBG_CFG, "certificate status: %N", cert_status_names, status);
enum_name(&cert_status_names, status));
return NULL; return NULL;
} }
if (status == CERT_GOOD && cert->get_until(cert) < time(NULL)) if (status == CERT_GOOD && cert->get_until(cert) < time(NULL))
{ {
this->logger->log(this->logger, ERROR, "certificate is good but crl is stale"); DBG1(SIG_DBG_CFG, "certificate is good but crl is stale");
return NULL; return NULL;
} }
@@ -419,20 +401,20 @@ static cert_status_t verify_by_crl(private_local_credential_store_t* this, const
crl = get_crl(this, issuer_cert); crl = get_crl(this, issuer_cert);
if (crl == NULL) if (crl == NULL)
{ {
this->logger->log(this->logger, ERROR, "crl not found"); DBG1(SIG_DBG_CFG, "crl not found");
goto err; goto err;
} }
this->logger->log(this->logger, CONTROL|LEVEL1, "crl found"); DBG2(SIG_DBG_CFG, "crl found");
issuer_public_key = issuer_cert->get_public_key(issuer_cert); issuer_public_key = issuer_cert->get_public_key(issuer_cert);
valid_signature = crl->verify(crl, issuer_public_key); valid_signature = crl->verify(crl, issuer_public_key);
if (!valid_signature) if (!valid_signature)
{ {
this->logger->log(this->logger, ERROR, "crl signature is invalid"); DBG1(SIG_DBG_CFG, "crl signature is invalid");
goto err; goto err;
} }
this->logger->log(this->logger, CONTROL|LEVEL1, "crl signature is valid"); DBG2(SIG_DBG_CFG, "crl signature is valid");
crl->get_status(crl, certinfo); crl->get_status(crl, certinfo);
@@ -490,8 +472,8 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
*found = (cert_copy != NULL); *found = (cert_copy != NULL);
if (*found) if (*found)
{ {
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_CFG,
"end entitity certificate is already in credential store"); "end entitity certificate is already in credential store");
} }
for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++) for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
@@ -504,39 +486,39 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
identification_t *subject = cert->get_subject(cert); identification_t *subject = cert->get_subject(cert);
identification_t *issuer = cert->get_issuer(cert); identification_t *issuer = cert->get_issuer(cert);
this->logger->log(this->logger, CONTROL|LEVEL1, "subject: '%D'", subject); DBG2(SIG_DBG_CFG, "subject: '%D'", subject);
this->logger->log(this->logger, CONTROL|LEVEL1, "issuer: '%D'", issuer); DBG2(SIG_DBG_CFG, "issuer: '%D'", issuer);
ugh = cert->is_valid(cert, &until); ugh = cert->is_valid(cert, &until);
if (ugh != NULL) if (ugh != NULL)
{ {
this->logger->log(this->logger, ERROR, "certificate %s", ugh); DBG1(SIG_DBG_CFG, "certificate %s", ugh);
return FALSE; return FALSE;
} }
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is valid"); DBG2(SIG_DBG_CFG, "certificate is valid");
issuer_cert = get_issuer_certificate(this, cert); issuer_cert = get_issuer_certificate(this, cert);
if (issuer_cert == NULL) if (issuer_cert == NULL)
{ {
this->logger->log(this->logger, ERROR, "issuer certificate not found"); DBG1(SIG_DBG_CFG, "issuer certificate not found");
return FALSE; return FALSE;
} }
this->logger->log(this->logger, CONTROL|LEVEL1, "issuer certificate found"); DBG2(SIG_DBG_CFG, "issuer certificate found");
issuer_public_key = issuer_cert->get_public_key(issuer_cert); issuer_public_key = issuer_cert->get_public_key(issuer_cert);
valid_signature = cert->verify(cert, issuer_public_key); valid_signature = cert->verify(cert, issuer_public_key);
if (!valid_signature) if (!valid_signature)
{ {
this->logger->log(this->logger, ERROR, "certificate signature is invalid"); DBG1(SIG_DBG_CFG, "certificate signature is invalid");
return FALSE; return FALSE;
} }
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate signature is valid"); DBG2(SIG_DBG_CFG, "certificate signature is valid");
/* check if cert is a self-signed root ca */ /* check if cert is a self-signed root ca */
if (pathlen > 0 && cert->is_self_signed(cert)) if (pathlen > 0 && cert->is_self_signed(cert))
{ {
this->logger->log(this->logger, CONTROL|LEVEL1, "reached self-signed root ca"); DBG2(SIG_DBG_CFG, "reached self-signed root ca");
/* set the definite status and trust interval of the end entity certificate */ /* set the definite status and trust interval of the end entity certificate */
end_cert->set_until(end_cert, until); end_cert->set_until(end_cert, until);
@@ -576,10 +558,10 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
/* if status information is stale */ /* if status information is stale */
if (this->strict && nextUpdate < time(NULL)) if (this->strict && nextUpdate < time(NULL))
{ {
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is good but status is stale"); DBG2(SIG_DBG_CFG, "certificate is good but status is stale");
return FALSE; return FALSE;
} }
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is good"); DBG2(SIG_DBG_CFG, "certificate is good");
/* with strict crl policy the public key must have the same /* with strict crl policy the public key must have the same
* lifetime as the validity of the ocsp status or crl lifetime * lifetime as the validity of the ocsp status or crl lifetime
@@ -589,12 +571,11 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
break; break;
case CERT_REVOKED: case CERT_REVOKED:
{ {
u_char buf[TIMETOA_BUF];
time_t revocationTime = certinfo->get_revocationTime(certinfo); time_t revocationTime = certinfo->get_revocationTime(certinfo);
DBG1(SIG_DBG_CFG,
timetoa(buf, TIMETOA_BUF, &revocationTime, TRUE); "certificate was revoked on %T, reason: %N",
this->logger->log(this->logger, ERROR, "certificate was revoked on %s, reason: %s", revocationTime, crl_reason_names,
buf, certinfo->get_revocationReason(certinfo)); certinfo->get_revocationReason(certinfo));
/* set revocationTime */ /* set revocationTime */
cert->set_until(cert, revocationTime); cert->set_until(cert, revocationTime);
@@ -609,7 +590,8 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
else else
{ {
cert_copy->set_status(cert_copy, CERT_REVOKED); cert_copy->set_status(cert_copy, CERT_REVOKED);
cert_copy->set_until(cert_copy, certinfo->get_revocationTime(certinfo)); cert_copy->set_until(cert_copy,
certinfo->get_revocationTime(certinfo));
} }
} }
return FALSE; return FALSE;
@@ -617,7 +599,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
case CERT_UNKNOWN: case CERT_UNKNOWN:
case CERT_UNDEFINED: case CERT_UNDEFINED:
default: default:
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate status unknown"); DBG2(SIG_DBG_CFG, "certificate status unknown");
if (this->strict) if (this->strict)
{ {
/* update status of end certificate in the credential store */ /* update status of end certificate in the credential store */
@@ -634,7 +616,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
/* go up one step in the trust chain */ /* go up one step in the trust chain */
cert = issuer_cert; cert = issuer_cert;
} }
this->logger->log(this->logger, ERROR, "maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN); DBG1(SIG_DBG_CFG, "maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
return FALSE; return FALSE;
} }
@@ -674,80 +656,27 @@ static x509_t* add_ca_certificate(private_local_credential_store_t *this, x509_t
} }
/** /**
* Implements local_credential_store_t.log_certificates * Implements local_credential_store_t.create_cert_iterator
*/ */
static void log_certificates(private_local_credential_store_t *this, logger_t *logger, bool utc) static iterator_t* create_cert_iterator(private_local_credential_store_t *this)
{ {
iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE); return this->certs->create_iterator(this->certs, TRUE);
if (iterator->get_count(iterator))
{
logger->log(logger, CONTROL, "");
logger->log(logger, CONTROL, "List of X.509 End Entity Certificates:");
logger->log(logger, CONTROL, "");
}
while (iterator->has_next(iterator))
{
x509_t *cert;
bool has_key;
iterator->current(iterator, (void**)&cert);
has_key = has_rsa_private_key(this, cert->get_public_key(cert));
cert->log_certificate(cert, logger, utc, has_key);
}
iterator->destroy(iterator);
} }
/** /**
* Implements local_credential_store_t.log_ca_certificates * Implements local_credential_store_t.create_cacert_iterator
*/ */
static void log_ca_certificates(private_local_credential_store_t *this, logger_t *logger, bool utc) static iterator_t* create_cacert_iterator(private_local_credential_store_t *this)
{ {
iterator_t *iterator = this->ca_certs->create_iterator(this->ca_certs, TRUE); return this->ca_certs->create_iterator(this->ca_certs, TRUE);
if (iterator->get_count(iterator))
{
logger->log(logger, CONTROL, "");
logger->log(logger, CONTROL, "List of X.509 CA Certificates:");
logger->log(logger, CONTROL, "");
}
while (iterator->has_next(iterator))
{
x509_t *cert;
iterator->current(iterator, (void**)&cert);
cert->log_certificate(cert, logger, utc, FALSE);
}
iterator->destroy(iterator);
} }
/** /**
* Implements local_credential_store_t.log_crls * Implements local_credential_store_t.create_crl_iterator
*/ */
static void log_crls(private_local_credential_store_t *this, logger_t *logger, bool utc) static iterator_t* create_crl_iterator(private_local_credential_store_t *this)
{ {
iterator_t *iterator = this->crls->create_iterator(this->crls, TRUE); return this->crls->create_iterator_locked(this->crls, &(this->crls_mutex));
pthread_mutex_lock(&(this->crls_mutex));
if (iterator->get_count(iterator))
{
logger->log(logger, CONTROL, "");
logger->log(logger, CONTROL, "List of X.509 CRLs:");
logger->log(logger, CONTROL, "");
}
while (iterator->has_next(iterator))
{
crl_t *crl;
iterator->current(iterator, (void**)&crl);
crl->log_crl(crl, logger, utc, this->strict);
}
pthread_mutex_unlock(&(this->crls_mutex));
iterator->destroy(iterator);
} }
/** /**
@@ -760,12 +689,12 @@ static void load_ca_certificates(private_local_credential_store_t *this)
DIR* dir; DIR* dir;
x509_t *cert; x509_t *cert;
this->logger->log(this->logger, CONTROL, "loading ca certificates from '%s/'", CA_CERTIFICATE_DIR); DBG1(SIG_DBG_CFG, "loading ca certificates from '%s/'", CA_CERTIFICATE_DIR);
dir = opendir(CA_CERTIFICATE_DIR); dir = opendir(CA_CERTIFICATE_DIR);
if (dir == NULL) if (dir == NULL)
{ {
this->logger->log(this->logger, ERROR, "error opening ca certs directory %s'", CA_CERTIFICATE_DIR); DBG1(SIG_DBG_CFG, "error opening ca certs directory %s'", CA_CERTIFICATE_DIR);
return; return;
} }
@@ -787,9 +716,9 @@ static void load_ca_certificates(private_local_credential_store_t *this)
{ {
err_t ugh = cert->is_valid(cert, NULL); err_t ugh = cert->is_valid(cert, NULL);
if (ugh != NULL) if (ugh != NULL)
{ {
this->logger->log(this->logger, ERROR, "warning: ca certificate %s", ugh); DBG1(SIG_DBG_CFG, "warning: ca certificate %s", ugh);
} }
if (cert->is_ca(cert)) if (cert->is_ca(cert))
{ {
@@ -797,8 +726,7 @@ static void load_ca_certificates(private_local_credential_store_t *this)
} }
else else
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_CFG, " CA basic constraints flag not set, cert discarded");
" CA basic constraints flag not set, cert discarded");
cert->destroy(cert); cert->destroy(cert);
} }
} }
@@ -810,7 +738,7 @@ static void load_ca_certificates(private_local_credential_store_t *this)
/** /**
* Add the latest crl to a linked list * Add the latest crl to a linked list
*/ */
static crl_t* add_crl(linked_list_t *crls, crl_t *crl, logger_t *logger) static crl_t* add_crl(linked_list_t *crls, crl_t *crl)
{ {
bool found = FALSE; bool found = FALSE;
@@ -833,13 +761,13 @@ static crl_t* add_crl(linked_list_t *crls, crl_t *crl, logger_t *logger)
{ {
old_crl->destroy(old_crl); old_crl->destroy(old_crl);
} }
logger->log(logger, CONTROL|LEVEL1, " thisUpdate is newer - existing crl replaced"); DBG2(SIG_DBG_CFG, " thisUpdate is newer - existing crl replaced");
} }
else else
{ {
crl->destroy(crl); crl->destroy(crl);
crl = current_crl; crl = current_crl;
logger->log(logger, CONTROL|LEVEL1, " thisUpdate is not newer - existing crl retained"); DBG2(SIG_DBG_CFG, " thisUpdate is not newer - existing crl retained");
} }
break; break;
} }
@@ -849,7 +777,7 @@ static crl_t* add_crl(linked_list_t *crls, crl_t *crl, logger_t *logger)
if (!found) if (!found)
{ {
crls->insert_last(crls, (void*)crl); crls->insert_last(crls, (void*)crl);
logger->log(logger, CONTROL|LEVEL1, " crl added"); DBG2(SIG_DBG_CFG, " crl added");
} }
return crl; return crl;
} }
@@ -864,12 +792,12 @@ static void load_crls(private_local_credential_store_t *this)
DIR* dir; DIR* dir;
crl_t *crl; crl_t *crl;
this->logger->log(this->logger, CONTROL, "loading crls from '%s/'", CRL_DIR); DBG1(SIG_DBG_CFG, "loading crls from '%s/'", CRL_DIR);
dir = opendir(CRL_DIR); dir = opendir(CRL_DIR);
if (dir == NULL) if (dir == NULL)
{ {
this->logger->log(this->logger, ERROR, "error opening crl directory %s'", CRL_DIR); DBG1(SIG_DBG_CFG, "error opening crl directory %s'", CRL_DIR);
return; return;
} }
@@ -893,10 +821,10 @@ static void load_crls(private_local_credential_store_t *this)
if (ugh != NULL) if (ugh != NULL)
{ {
this->logger->log(this->logger, ERROR, "warning: crl %s", ugh); DBG1(SIG_DBG_CFG, "warning: crl %s", ugh);
} }
pthread_mutex_lock(&(this->crls_mutex)); pthread_mutex_lock(&(this->crls_mutex));
crl = add_crl(this->crls, crl, this->logger); crl = add_crl(this->crls, crl);
pthread_mutex_unlock(&(this->crls_mutex)); pthread_mutex_unlock(&(this->crls_mutex));
} }
} }
@@ -973,7 +901,7 @@ static void load_secrets(private_local_credential_store_t *this)
int line_nr = 0; int line_nr = 0;
chunk_t chunk, src, line; chunk_t chunk, src, line;
this->logger->log(this->logger, CONTROL, "loading secrets from \"%s\"", SECRETS_FILE); DBG1(SIG_DBG_CFG, "loading secrets from \"%s\"", SECRETS_FILE);
fseek(fd, 0, SEEK_END); fseek(fd, 0, SEEK_END);
chunk.len = ftell(fd); chunk.len = ftell(fd);
@@ -996,7 +924,7 @@ static void load_secrets(private_local_credential_store_t *this)
} }
if (!extract_token(&ids, ':', &line)) if (!extract_token(&ids, ':', &line))
{ {
this->logger->log(this->logger, ERROR, "line %d: missing ':' separator", line_nr); DBG1(SIG_DBG_CFG, "line %d: missing ':' separator", line_nr);
goto error; goto error;
} }
/* NULL terminate the ids string by replacing the : separator */ /* NULL terminate the ids string by replacing the : separator */
@@ -1004,7 +932,7 @@ static void load_secrets(private_local_credential_store_t *this)
if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line)) if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
{ {
this->logger->log(this->logger, ERROR, "line %d: missing token", line_nr); DBG1(SIG_DBG_CFG, "line %d: missing token", line_nr);
goto error; goto error;
} }
if (match("RSA", &token)) if (match("RSA", &token))
@@ -1022,13 +950,12 @@ static void load_secrets(private_local_credential_store_t *this)
if (ugh != NULL) if (ugh != NULL)
{ {
this->logger->log(this->logger, ERROR, "line %d: %s", line_nr, ugh); DBG1(SIG_DBG_CFG, "line %d: %s", line_nr, ugh);
goto error; goto error;
} }
if (filename.len == 0) if (filename.len == 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_CFG, "line %d: empty filename", line_nr);
"line %d: empty filename", line_nr);
goto error; goto error;
} }
if (*filename.ptr == '/') if (*filename.ptr == '/')
@@ -1049,8 +976,7 @@ static void load_secrets(private_local_credential_store_t *this)
ugh = extract_secret(&secret, &line); ugh = extract_secret(&secret, &line);
if (ugh != NULL) if (ugh != NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
"line %d: malformed passphrase: %s", line_nr, ugh);
goto error; goto error;
} }
if (secret.len > 0) if (secret.len > 0)
@@ -1072,23 +998,20 @@ static void load_secrets(private_local_credential_store_t *this)
err_t ugh = extract_secret(&secret, &line); err_t ugh = extract_secret(&secret, &line);
if (ugh != NULL) if (ugh != NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
"line %d: malformed secret: %s", line_nr, ugh);
goto error; goto error;
} }
if (ids.len > 0) if (ids.len > 0)
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_CFG, " loading shared key for %s", ids.ptr);
" loading shared key for %s", ids.ptr);
} }
else else
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_CFG, " loading shared key for %%any");
" loading shared key for %%any");
} }
this->logger->log_chunk(this->logger, PRIVATE, " secret:", secret); DBG4(SIG_DBG_CFG, " secret:", secret);
shared_key = shared_key_create(secret); shared_key = shared_key_create(secret);
if (shared_key) if (shared_key)
@@ -1103,8 +1026,7 @@ static void load_secrets(private_local_credential_store_t *this)
ugh = extract_value(&id, &ids); ugh = extract_value(&id, &ids);
if (ugh != NULL) if (ugh != NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_CFG, "line %d: %s", line_nr, ugh);
"line %d: %s", line_nr, ugh);
goto error; goto error;
} }
if (id.len == 0) if (id.len == 0)
@@ -1118,8 +1040,7 @@ static void load_secrets(private_local_credential_store_t *this)
peer_id = identification_create_from_string(id.ptr); peer_id = identification_create_from_string(id.ptr);
if (peer_id == NULL) if (peer_id == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_CFG, "line %d: malformed ID: %s", line_nr, id.ptr);
"line %d: malformed ID: %s", line_nr, id.ptr);
goto error; goto error;
} }
@@ -1137,9 +1058,8 @@ static void load_secrets(private_local_credential_store_t *this)
} }
else else
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_CFG, "line %d: token must be either "
"line %d: token must be either RSA, PSK, or PIN", "RSA, PSK, or PIN", line_nr, token.len);
line_nr, token.len);
goto error; goto error;
} }
} }
@@ -1148,7 +1068,7 @@ error:
} }
else else
{ {
this->logger->log(this->logger, ERROR, "could not open file '%s'", SECRETS_FILE); DBG1(SIG_DBG_CFG, "could not open file '%s'", SECRETS_FILE);
} }
} }
@@ -1195,7 +1115,7 @@ static void destroy(private_local_credential_store_t *this)
/* destroy shared keys list */ /* destroy shared keys list */
while (this->shared_keys->remove_last(this->shared_keys, (void**)&shared_key) == SUCCESS) while (this->shared_keys->remove_last(this->shared_keys, (void**)&shared_key) == SUCCESS)
{ {
shared_key->destroy(shared_key); shared_key_destroy(shared_key);
} }
this->shared_keys->destroy(this->shared_keys); this->shared_keys->destroy(this->shared_keys);
@@ -1218,9 +1138,9 @@ local_credential_store_t * local_credential_store_create(bool strict)
this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify; this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate; this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
this->public.credential_store.add_ca_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_ca_certificate; this->public.credential_store.add_ca_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_ca_certificate;
this->public.credential_store.log_certificates = (void (*) (credential_store_t*,logger_t*,bool))log_certificates; this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator;
this->public.credential_store.log_ca_certificates = (void (*) (credential_store_t*,logger_t*,bool))log_ca_certificates; this->public.credential_store.create_cacert_iterator = (iterator_t* (*) (credential_store_t*))create_cacert_iterator;
this->public.credential_store.log_crls = (void (*) (credential_store_t*,logger_t*,bool))log_crls; this->public.credential_store.create_crl_iterator = (iterator_t* (*) (credential_store_t*))create_crl_iterator;
this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates; this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates;
this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls; this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls;
this->public.credential_store.load_secrets = (void (*) (credential_store_t*))load_secrets; this->public.credential_store.load_secrets = (void (*) (credential_store_t*))load_secrets;
@@ -1230,13 +1150,12 @@ local_credential_store_t * local_credential_store_create(bool strict)
pthread_mutex_init(&(this->crls_mutex), NULL); pthread_mutex_init(&(this->crls_mutex), NULL);
/* private variables */ /* private variables */
this->shared_keys = linked_list_create(); this->shared_keys = linked_list_create();
this->private_keys = linked_list_create(); this->private_keys = linked_list_create();
this->certs = linked_list_create(); this->certs = linked_list_create();
this->ca_certs = linked_list_create(); this->ca_certs = linked_list_create();
this->crls = linked_list_create(); this->crls = linked_list_create();
this->strict = strict; this->strict = strict;
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
return (&this->public); return (&this->public);
} }
+22 -23
View File
@@ -1,8 +1,8 @@
/** /**
* @file local_policy_store.c * @file local_policy_store.c
* *
* @brief Implementation of local_policy_store_t. * @brief Implementation of local_policy_store_t.
* *
*/ */
/* /*
@@ -24,8 +24,8 @@
#include "local_policy_store.h" #include "local_policy_store.h"
#include <daemon.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger_manager.h>
typedef struct private_local_policy_store_t private_local_policy_store_t; typedef struct private_local_policy_store_t private_local_policy_store_t;
@@ -49,11 +49,6 @@ struct private_local_policy_store_t {
* Mutex to exclusivly access list * Mutex to exclusivly access list
*/ */
pthread_mutex_t mutex; pthread_mutex_t mutex;
/**
* Assigned logger
*/
logger_t *logger;
}; };
/** /**
@@ -116,8 +111,7 @@ static policy_t *get_policy(private_local_policy_store_t *this,
policy_t *candidate; policy_t *candidate;
policy_t *found = NULL; policy_t *found = NULL;
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_CFG, "searching policy for ID pair %D...%D", my_id, other_id);
"searching policy for ID pair %D...%D", my_id, other_id);
pthread_mutex_lock(&(this->mutex)); pthread_mutex_lock(&(this->mutex));
iterator = this->policies->create_iterator(this->policies, TRUE); iterator = this->policies->create_iterator(this->policies, TRUE);
@@ -149,16 +143,14 @@ static policy_t *get_policy(private_local_policy_store_t *this,
if (!contains_traffic_selectors(candidate, TRUE, my_ts, my_host) || if (!contains_traffic_selectors(candidate, TRUE, my_ts, my_host) ||
!contains_traffic_selectors(candidate, FALSE, other_ts, other_host)) !contains_traffic_selectors(candidate, FALSE, other_ts, other_host))
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_CFG, "candidate '%s' inacceptable due traffic "
"candidate '%s' inacceptable due traffic selector mismatch", "selector mismatch", candidate->get_name(candidate));
candidate->get_name(candidate));
continue; continue;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_CFG, "candidate policy '%s': %D...%D (prio=%d)",
"candidate policy '%s': %D...%D (prio=%d)", candidate->get_name(candidate),
candidate->get_name(candidate), candidate_my_id, candidate_other_id, prio);
candidate_my_id, candidate_other_id, prio);
if (prio > best_prio) if (prio > best_prio)
{ {
@@ -174,10 +166,8 @@ static policy_t *get_policy(private_local_policy_store_t *this,
identification_t *found_my_id = found->get_my_id(found); identification_t *found_my_id = found->get_my_id(found);
identification_t *found_other_id = found->get_other_id(found); identification_t *found_other_id = found->get_other_id(found);
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_CFG, "found matching policy '%s': %D...%D (prio=%d)",
"found matching policy '%s': %D...%D (prio=%d)", found->get_name(found), found_my_id, found_other_id, best_prio);
found->get_name(found),
found_my_id, found_other_id, best_prio);
/* give out a new reference to it */ /* give out a new reference to it */
found->get_ref(found); found->get_ref(found);
} }
@@ -193,7 +183,7 @@ static policy_t *get_policy_by_name(private_local_policy_store_t *this, char *na
iterator_t *iterator; iterator_t *iterator;
policy_t *current, *found = NULL; policy_t *current, *found = NULL;
this->logger->log(this->logger, CONTROL|LEVEL1, "looking for policy \"%s\"", name); DBG2(SIG_DBG_CFG, "looking for policy '%s'", name);
pthread_mutex_lock(&(this->mutex)); pthread_mutex_lock(&(this->mutex));
iterator = this->policies->create_iterator(this->policies, TRUE); iterator = this->policies->create_iterator(this->policies, TRUE);
@@ -245,6 +235,15 @@ static status_t delete_policy(private_local_policy_store_t *this, char *name)
return NOT_FOUND; return NOT_FOUND;
} }
/**
* Implementation of policy_store_t.create_iterator.
*/
static iterator_t* create_iterator(private_local_policy_store_t *this)
{
return this->policies->create_iterator_locked(this->policies,
&this->mutex);
}
/** /**
* Implementation of policy_store_t.destroy. * Implementation of policy_store_t.destroy.
*/ */
@@ -273,11 +272,11 @@ local_policy_store_t *local_policy_store_create(void)
this->public.policy_store.get_policy = (policy_t*(*)(policy_store_t*,identification_t*,identification_t*,linked_list_t*,linked_list_t*,host_t*,host_t*))get_policy; this->public.policy_store.get_policy = (policy_t*(*)(policy_store_t*,identification_t*,identification_t*,linked_list_t*,linked_list_t*,host_t*,host_t*))get_policy;
this->public.policy_store.get_policy_by_name = (policy_t*(*)(policy_store_t*,char*))get_policy_by_name; this->public.policy_store.get_policy_by_name = (policy_t*(*)(policy_store_t*,char*))get_policy_by_name;
this->public.policy_store.delete_policy = (status_t(*)(policy_store_t*,char*))delete_policy; this->public.policy_store.delete_policy = (status_t(*)(policy_store_t*,char*))delete_policy;
this->public.policy_store.create_iterator = (iterator_t*(*)(policy_store_t*))create_iterator;
this->public.policy_store.destroy = (void(*)(policy_store_t*))destroy; this->public.policy_store.destroy = (void(*)(policy_store_t*))destroy;
/* private variables */ /* private variables */
this->policies = linked_list_create(); this->policies = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
pthread_mutex_init(&(this->mutex), NULL); pthread_mutex_init(&(this->mutex), NULL);
return (&this->public); return (&this->public);
+10 -31
View File
@@ -27,34 +27,23 @@
#include "policy.h" #include "policy.h"
#include <daemon.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/identification.h> #include <utils/identification.h>
#include <utils/logger_manager.h>
/** ENUM(auth_method_names, RSA_DIGITAL_SIGNATURE, DSS_DIGITAL_SIGNATURE,
* String mappings for auth_method_t.
*/
static const char *const auth_method_name[] = {
"RSA signature", "RSA signature",
"pre-shared key", "pre-shared key",
"DSS signature" "DSS signature"
}; );
enum_names auth_method_names =
{ RSA_DIGITAL_SIGNATURE, DSS_DIGITAL_SIGNATURE, auth_method_name, NULL };
/** ENUM(dpd_action_names, DPD_NONE, DPD_RESTART,
* String mappings for dpd_action_t.
*/
static const char *const dpd_action_name[] = {
"DPD_NONE", "DPD_NONE",
"DPD_CLEAR", "DPD_CLEAR",
"DPD_ROUTE", "DPD_ROUTE",
"DPD_RESTART" "DPD_RESTART"
}; );
enum_names dpd_action_names =
{ DPD_NONE, DPD_RESTART, dpd_action_name, NULL };
typedef struct private_policy_t private_policy_t; typedef struct private_policy_t private_policy_t;
@@ -148,11 +137,6 @@ struct private_policy_t {
* What to do with an SA when other peer seams to be dead? * What to do with an SA when other peer seams to be dead?
*/ */
bool dpd_action; bool dpd_action;
/**
* logger
*/
logger_t *logger;
}; };
/** /**
@@ -239,9 +223,7 @@ static linked_list_t *select_traffic_selectors(private_policy_t *this,
traffic_selector_t *supplied_ts, *stored_ts, *selected_ts; traffic_selector_t *supplied_ts, *stored_ts, *selected_ts;
linked_list_t *selected = linked_list_create(); linked_list_t *selected = linked_list_create();
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_CFG, "selecting traffic selectors");
"selecting traffic selectors for %s host",
stored == this->my_ts ? "local" : "remote");
stored_iter = stored->create_iterator(stored, TRUE); stored_iter = stored->create_iterator(stored, TRUE);
supplied_iter = supplied->create_iterator(supplied, TRUE); supplied_iter = supplied->create_iterator(supplied, TRUE);
@@ -258,10 +240,8 @@ static linked_list_t *select_traffic_selectors(private_policy_t *this,
/* iterate over all supplied traffic selectors */ /* iterate over all supplied traffic selectors */
while (supplied_iter->iterate(supplied_iter, (void**)&supplied_ts)) while (supplied_iter->iterate(supplied_iter, (void**)&supplied_ts))
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_CFG, "stored %R <=> %R received",
" stored %s <=> %s received", stored_ts, supplied_ts);
stored_ts->get_string(stored_ts),
supplied_ts->get_string(supplied_ts));
selected_ts = stored_ts->get_subset(stored_ts, supplied_ts); selected_ts = stored_ts->get_subset(stored_ts, supplied_ts);
if (selected_ts) if (selected_ts)
@@ -269,8 +249,8 @@ static linked_list_t *select_traffic_selectors(private_policy_t *this,
/* got a match, add to list */ /* got a match, add to list */
selected->insert_last(selected, (void*)selected_ts); selected->insert_last(selected, (void*)selected_ts);
this->logger->log(this->logger, CONTROL|LEVEL1, " got a match: %s", DBG2(SIG_DBG_CFG, "found traffic selector for %s: %R",
selected_ts->get_string(selected_ts)); stored == this->my_ts ? "us" : "other", selected_ts);
} }
} }
stored_ts->destroy(stored_ts); stored_ts->destroy(stored_ts);
@@ -554,7 +534,6 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
this->proposals = linked_list_create(); this->proposals = linked_list_create();
this->my_ts = linked_list_create(); this->my_ts = linked_list_create();
this->other_ts = linked_list_create(); this->other_ts = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
return &this->public; return &this->public;
} }
+5 -5
View File
@@ -58,11 +58,11 @@ enum auth_method_t {
}; };
/** /**
* string mappings for auth_method_t. * enum names for auth_method_t.
* *
* @ingroup config * @ingroup config
*/ */
extern enum_names auth_method_names; extern enum_name_t *auth_method_names;
typedef enum dpd_action_t dpd_action_t; typedef enum dpd_action_t dpd_action_t;
@@ -86,9 +86,9 @@ enum dpd_action_t {
}; };
/** /**
* String mappings for dpd_action_t. * enum names for dpd_action_t.
*/ */
extern enum_names dpd_action_names; extern enum_name_t *dpd_action_names;
typedef struct policy_t policy_t; typedef struct policy_t policy_t;
@@ -100,6 +100,14 @@ struct policy_store_t {
*/ */
status_t (*delete_policy) (policy_store_t *this, char *name); status_t (*delete_policy) (policy_store_t *this, char *name);
/**
* @brief Get an iterator for the stored policies.
*
* @param this calling object
* @return iterator over all stored policies
*/
iterator_t* (*create_iterator) (policy_store_t *this);
/** /**
* @brief Destroys a policy_store_t object. * @brief Destroys a policy_store_t object.
* *
+21 -33
View File
@@ -26,45 +26,33 @@
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/identification.h> #include <utils/identification.h>
#include <utils/logger.h>
#include <utils/lexparser.h> #include <utils/lexparser.h>
#include <crypto/prfs/prf.h> #include <crypto/prfs/prf.h>
#include <crypto/crypters/crypter.h> #include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h> #include <crypto/signers/signer.h>
/** ENUM(protocol_id_names, PROTO_NONE, PROTO_ESP,
* String mappings for protocol_id_t. "PROTO_NONE",
*/ "IKE",
mapping_t protocol_id_m[] = { "AH",
{PROTO_NONE, "PROTO_NONE"}, "ESP",
{PROTO_IKE, "IKE"}, );
{PROTO_AH, "AH"},
{PROTO_ESP, "ESP"},
{MAPPING_END, NULL}
};
/** ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, UNDEFINED_TRANSFORM_TYPE,
* String mappings for transform_type_t. "UNDEFINED_TRANSFORM_TYPE");
*/ ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, UNDEFINED_TRANSFORM_TYPE,
mapping_t transform_type_m[] = { "ENCRYPTION_ALGORITHM",
{UNDEFINED_TRANSFORM_TYPE, "UNDEFINED_TRANSFORM_TYPE"}, "PSEUDO_RANDOM_FUNCTION",
{ENCRYPTION_ALGORITHM, "ENCRYPTION_ALGORITHM"}, "INTEGRITY_ALGORITHM",
{PSEUDO_RANDOM_FUNCTION, "PSEUDO_RANDOM_FUNCTION"}, "DIFFIE_HELLMAN_GROUP",
{INTEGRITY_ALGORITHM, "INTEGRITY_ALGORITHM"}, "EXTENDED_SEQUENCE_NUMBERS");
{DIFFIE_HELLMAN_GROUP, "DIFFIE_HELLMAN_GROUP"}, ENUM_END(transform_type_names, EXTENDED_SEQUENCE_NUMBERS);
{EXTENDED_SEQUENCE_NUMBERS, "EXTENDED_SEQUENCE_NUMBERS"},
{MAPPING_END, NULL}
};
/** ENUM(extended_sequence_numbers_names, NO_EXT_SEQ_NUMBERS, EXT_SEQ_NUMBERS,
* String mappings for extended_sequence_numbers_t. "NO_EXT_SEQ_NUMBERS",
*/ "EXT_SEQ_NUMBERS",
mapping_t extended_sequence_numbers_m[] = { );
{NO_EXT_SEQ_NUMBERS, "NO_EXT_SEQ_NUMBERS"},
{EXT_SEQ_NUMBERS, "EXT_SEQ_NUMBERS"},
{MAPPING_END, NULL}
};
typedef struct private_proposal_t private_proposal_t; typedef struct private_proposal_t private_proposal_t;
@@ -389,7 +377,7 @@ static void clone_algo_list(linked_list_t *list, linked_list_t *clone_list)
/** /**
* Implements proposal_t.clone * Implements proposal_t.clone
*/ */
static proposal_t *clone(private_proposal_t *this) static proposal_t *clone_(private_proposal_t *this)
{ {
private_proposal_t *clone = (private_proposal_t*)proposal_create(this->protocol); private_proposal_t *clone = (private_proposal_t*)proposal_create(this->protocol);
@@ -523,7 +511,7 @@ proposal_t *proposal_create(protocol_id_t protocol)
this->public.get_protocol = (protocol_id_t(*)(proposal_t*))get_protocol; this->public.get_protocol = (protocol_id_t(*)(proposal_t*))get_protocol;
this->public.set_spi = (void(*)(proposal_t*,u_int64_t))set_spi; this->public.set_spi = (void(*)(proposal_t*,u_int64_t))set_spi;
this->public.get_spi = (u_int64_t(*)(proposal_t*))get_spi; this->public.get_spi = (u_int64_t(*)(proposal_t*))get_spi;
this->public.clone = (proposal_t*(*)(proposal_t*))clone; this->public.clone = (proposal_t*(*)(proposal_t*))clone_;
this->public.destroy = (void(*)(proposal_t*))destroy; this->public.destroy = (void(*)(proposal_t*))destroy;
this->spi = 0; this->spi = 0;
+16 -16
View File
@@ -47,12 +47,12 @@ enum protocol_id_t {
PROTO_ESP = 3, PROTO_ESP = 3,
}; };
/** /**
* String mappings for protocol_id_t. * enum names for protocol_id_t
* *
* @ingroup config * @ingroup config
*/ */
extern mapping_t protocol_id_m[]; extern enum_name_t *protocol_id_names;
typedef enum transform_type_t transform_type_t; typedef enum transform_type_t transform_type_t;
@@ -60,7 +60,7 @@ typedef enum transform_type_t transform_type_t;
/** /**
* Type of a transform, as in IKEv2 RFC 3.3.2. * Type of a transform, as in IKEv2 RFC 3.3.2.
* *
* @ingroup payloads * @ingroup config
*/ */
enum transform_type_t { enum transform_type_t {
UNDEFINED_TRANSFORM_TYPE = 241, UNDEFINED_TRANSFORM_TYPE = 241,
@@ -71,12 +71,12 @@ enum transform_type_t {
EXTENDED_SEQUENCE_NUMBERS = 5 EXTENDED_SEQUENCE_NUMBERS = 5
}; };
/** /**
* String mappings for transform_type_t. * enum names for transform_type_t.
* *
* @ingroup payloads * @ingroup config
*/ */
extern mapping_t transform_type_m[]; extern enum_name_t *transform_type_names;
typedef enum extended_sequence_numbers_t extended_sequence_numbers_t; typedef enum extended_sequence_numbers_t extended_sequence_numbers_t;
@@ -84,19 +84,19 @@ typedef enum extended_sequence_numbers_t extended_sequence_numbers_t;
/** /**
* Extended sequence numbers, as in IKEv2 RFC 3.3.2. * Extended sequence numbers, as in IKEv2 RFC 3.3.2.
* *
* @ingroup payloads * @ingroup config
*/ */
enum extended_sequence_numbers_t { enum extended_sequence_numbers_t {
NO_EXT_SEQ_NUMBERS = 0, NO_EXT_SEQ_NUMBERS = 0,
EXT_SEQ_NUMBERS = 1 EXT_SEQ_NUMBERS = 1
}; };
/** /**
* String mappings for extended_sequence_numbers_t. * enum strings for extended_sequence_numbers_t.
* *
* @ingroup payloads * @ingroup config
*/ */
extern mapping_t extended_sequence_numbers_m[]; extern enum_name_t *extended_sequence_numbers_names;
typedef struct algorithm_t algorithm_t; typedef struct algorithm_t algorithm_t;
+88 -85
View File
@@ -25,12 +25,18 @@
#include <string.h> #include <string.h>
#include <netdb.h> #include <netdb.h>
#include <stdio.h> #include <stdio.h>
#include <printf.h>
#include "traffic_selector.h" #include "traffic_selector.h"
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/identification.h> #include <utils/identification.h>
ENUM(ts_type_name, TS_IPV4_ADDR_RANGE, TS_IPV6_ADDR_RANGE,
"TS_IPV4_ADDR_RANGE",
"TS_IPV6_ADDR_RANGE",
);
typedef struct private_traffic_selector_t private_traffic_selector_t; typedef struct private_traffic_selector_t private_traffic_selector_t;
/** /**
@@ -86,11 +92,6 @@ struct private_traffic_selector_t {
* end of port range * end of port range
*/ */
u_int16_t to_port; u_int16_t to_port;
/**
* string representation of this traffic selector
*/
char *string;
}; };
/** /**
@@ -146,50 +147,43 @@ static u_int8_t calc_netbits(private_traffic_selector_t *this)
return (size * 8); return (size * 8);
} }
/** /**
* internal generic constructor * internal generic constructor
*/ */
static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts_type_t type, u_int16_t from_port, u_int16_t to_port); static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts_type_t type, u_int16_t from_port, u_int16_t to_port);
/** /**
* update the string representation of this traffic selector * output handler in printf()
*/ */
static void update_string(private_traffic_selector_t *this) static int print(FILE *stream, const struct printf_info *info,
const void *const *args)
{ {
char buf[256]; private_traffic_selector_t *this = *((private_traffic_selector_t**)(args[0]));
char addr_str[INET6_ADDRSTRLEN] = "";
u_int8_t mask;
struct protoent *proto; struct protoent *proto;
struct servent *serv; struct servent *serv;
char *serv_proto = NULL; char *serv_proto = NULL;
char proto_str[8] = ""; bool has_proto = FALSE;
char addr_str[INET6_ADDRSTRLEN]; size_t written, total_written = 0;
char port_str[16] = ""; #define fprintf_sum(...) { written = fprintf(__VA_ARGS__); if (written < 0) return written; total_written += written; }
char mask_str[8] = "";
char proto_port_str[32] = ""; if (this == NULL)
bool has_proto = FALSE, has_port = FALSE; {
return fprintf(stream, "(null)");
}
if (this->type == TS_IPV4_ADDR_RANGE) if (this->type == TS_IPV4_ADDR_RANGE)
{ {
u_int8_t mask;
/* build address string */
inet_ntop(AF_INET, &this->from4, addr_str, sizeof(addr_str)); inet_ntop(AF_INET, &this->from4, addr_str, sizeof(addr_str));
/* build network mask string */
mask = calc_netbits(this);
snprintf(mask_str, sizeof(mask_str), "/%d", mask);
} }
else else
{ {
u_int8_t mask;
/* build address string */
inet_ntop(AF_INET6, &this->from6, addr_str, sizeof(addr_str)); inet_ntop(AF_INET6, &this->from6, addr_str, sizeof(addr_str));
/* build network mask string */
mask = calc_netbits(this);
snprintf(mask_str, sizeof(mask_str), "/%d", mask);
} }
mask = calc_netbits(this);
fprintf_sum(stream, "%s/%d", addr_str, mask);
/* build protocol string */ /* build protocol string */
if (this->protocol) if (this->protocol)
@@ -197,12 +191,12 @@ static void update_string(private_traffic_selector_t *this)
proto = getprotobynumber(this->protocol); proto = getprotobynumber(this->protocol);
if (proto) if (proto)
{ {
snprintf(proto_str, sizeof(proto_str), "%s", proto->p_name); fprintf_sum(stream, "[%s", proto->p_name);
serv_proto = proto->p_name; serv_proto = proto->p_name;
} }
else else
{ {
snprintf(proto_str, sizeof(proto_str), "%d", this->protocol); fprintf_sum(stream, "[%d", this->protocol);
} }
has_proto = TRUE; has_proto = TRUE;
} }
@@ -210,55 +204,58 @@ static void update_string(private_traffic_selector_t *this)
/* build port string */ /* build port string */
if (this->from_port == this->to_port) if (this->from_port == this->to_port)
{ {
serv = getservbyport(htons(this->from_port), serv_proto); if (has_proto)
if (serv)
{ {
snprintf(port_str, sizeof(port_str), "%s", serv->s_name); fprintf_sum(stream, "/");
} }
else else
{ {
snprintf(port_str, sizeof(port_str), "%d", this->from_port); fprintf_sum(stream, "[");
}
serv = getservbyport(htons(this->from_port), serv_proto);
if (serv)
{
fprintf_sum(stream, "%s]", serv->s_name);
}
else
{
fprintf_sum(stream, "%d]", this->from_port);
} }
has_port = TRUE;
} }
else if (!(this->from_port == 0 && this->to_port == 0xFFFF)) else if (!(this->from_port == 0 && this->to_port == 0xFFFF))
{ {
snprintf(port_str, sizeof(port_str), "%d-%d", if (has_proto)
this->from_port, this->to_port); {
has_port = TRUE; fprintf_sum(stream, "/");
}
else
{
fprintf_sum(stream, "[");
}
fprintf_sum(stream, "%d-%d]", this->from_port, this->to_port);
} }
/* concatenate port & proto string */ return total_written;
if (has_proto && has_port)
{
snprintf(proto_port_str, sizeof(proto_port_str), "[%s/%s]",
proto_str, port_str);
}
else if (has_proto)
{
snprintf(proto_port_str, sizeof(proto_port_str), "[%s]", proto_str);
}
else if (has_port)
{
snprintf(proto_port_str, sizeof(proto_port_str), "[%s]", port_str);
}
/* concatenate it all */
snprintf(buf, sizeof(buf), "%s%s%s", addr_str, mask_str, proto_port_str);
if (this->string)
{
free(this->string);
}
this->string = strdup(buf);
} }
/** /**
* implements traffic_selector_t.get_string * arginfo handler in printf()
*/ */
static char *get_string(private_traffic_selector_t *this) static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes)
{ {
return this->string; if (n > 0)
{
argtypes[0] = PA_POINTER;
}
return 1;
}
/**
* register printf() handlers
*/
static void __attribute__ ((constructor))print_register()
{
register_printf_function(TRAFFIC_SELECTOR_PRINTF_SPEC, print, print_arginfo);
} }
/** /**
@@ -326,7 +323,6 @@ static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_
new_ts->type = this->type; new_ts->type = this->type;
memcpy(new_ts->from, from, size); memcpy(new_ts->from, from, size);
memcpy(new_ts->to, to, size); memcpy(new_ts->to, to, size);
update_string(new_ts);
return &new_ts->public; return &new_ts->public;
} }
@@ -454,23 +450,43 @@ static u_int8_t get_protocol(private_traffic_selector_t *this)
return this->protocol; return this->protocol;
} }
/**
* Implements traffic_selector_t.is_host.
*/
static bool is_host(private_traffic_selector_t *this, host_t *host)
{
chunk_t addr;
int family = host->get_family(host);
if ((family == AF_INET && this->type == TS_IPV4_ADDR_RANGE) ||
(family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE))
{
addr = host->get_address(host);
if (memeq(addr.ptr, this->from, addr.len) &&
memeq(addr.ptr, this->to, addr.len))
{
return TRUE;
}
}
return FALSE;
}
/** /**
* Implements traffic_selector_t.update_address_range. * Implements traffic_selector_t.update_address_range.
*/ */
static void update_address_range(private_traffic_selector_t *this, host_t *host) static void update_address_range(private_traffic_selector_t *this, host_t *host)
{ {
if ((this->type == TS_IPV4_ADDR_RANGE && this->from4[0] == 0) || if ((this->type == TS_IPV4_ADDR_RANGE && this->from4[0] == 0) ||
(this->type == TS_IPV6_ADDR_RANGE && this->from6[0] == 0 && (this->type == TS_IPV6_ADDR_RANGE && this->from6[0] == 0 &&
this->from6[1] == 0 && this->from6[2] == 0 && this->from6[3] == 0)) this->from6[1] == 0 && this->from6[2] == 0 && this->from6[3] == 0))
{ {
this->type = host->get_family(host) == AF_INET ? this->type = host->get_family(host) == AF_INET ?
TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE; TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE;
chunk_t from = host->get_address(host); chunk_t from = host->get_address(host);
memcpy(this->from, from.ptr, from.len); memcpy(this->from, from.ptr, from.len);
memcpy(this->to, from.ptr, from.len); memcpy(this->to, from.ptr, from.len);
} }
update_string(this);
} }
/** /**
@@ -488,14 +504,12 @@ static traffic_selector_t *clone_(private_traffic_selector_t *this)
{ {
memcpy(clone->from4, this->from4, sizeof(this->from4)); memcpy(clone->from4, this->from4, sizeof(this->from4));
memcpy(clone->to4, this->to4, sizeof(this->to4)); memcpy(clone->to4, this->to4, sizeof(this->to4));
update_string(clone);
return &clone->public; return &clone->public;
} }
case TS_IPV6_ADDR_RANGE: case TS_IPV6_ADDR_RANGE:
{ {
memcpy(clone->from6, this->from6, sizeof(this->from6)); memcpy(clone->from6, this->from6, sizeof(this->from6));
memcpy(clone->to6, this->to6, sizeof(this->to6)); memcpy(clone->to6, this->to6, sizeof(this->to6));
update_string(clone);
return &clone->public; return &clone->public;
} }
default: default:
@@ -511,7 +525,6 @@ static traffic_selector_t *clone_(private_traffic_selector_t *this)
*/ */
static void destroy(private_traffic_selector_t *this) static void destroy(private_traffic_selector_t *this)
{ {
free(this->string);
free(this); free(this);
} }
@@ -552,9 +565,6 @@ traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol, ts_typ
return NULL; return NULL;
} }
} }
update_string(this);
return (&this->public); return (&this->public);
} }
@@ -618,9 +628,6 @@ traffic_selector_t *traffic_selector_create_from_subnet(host_t *net, u_int8_t ne
this->from_port = port; this->from_port = port;
this->to_port = port; this->to_port = port;
} }
update_string(this);
return (&this->public); return (&this->public);
} }
@@ -667,9 +674,6 @@ traffic_selector_t *traffic_selector_create_from_string(u_int8_t protocol, ts_ty
break; break;
} }
} }
update_string(this);
return (&this->public); return (&this->public);
} }
@@ -683,13 +687,13 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts
/* public functions */ /* public functions */
this->public.get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset; this->public.get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset;
this->public.equals = (bool(*)(traffic_selector_t*,traffic_selector_t*))equals; this->public.equals = (bool(*)(traffic_selector_t*,traffic_selector_t*))equals;
this->public.get_string = (char*(*)(traffic_selector_t*))get_string;
this->public.get_from_address = (chunk_t(*)(traffic_selector_t*))get_from_address; this->public.get_from_address = (chunk_t(*)(traffic_selector_t*))get_from_address;
this->public.get_to_address = (chunk_t(*)(traffic_selector_t*))get_to_address; this->public.get_to_address = (chunk_t(*)(traffic_selector_t*))get_to_address;
this->public.get_from_port = (u_int16_t(*)(traffic_selector_t*))get_from_port; this->public.get_from_port = (u_int16_t(*)(traffic_selector_t*))get_from_port;
this->public.get_to_port = (u_int16_t(*)(traffic_selector_t*))get_to_port; this->public.get_to_port = (u_int16_t(*)(traffic_selector_t*))get_to_port;
this->public.get_type = (ts_type_t(*)(traffic_selector_t*))get_type; this->public.get_type = (ts_type_t(*)(traffic_selector_t*))get_type;
this->public.get_protocol = (u_int8_t(*)(traffic_selector_t*))get_protocol; this->public.get_protocol = (u_int8_t(*)(traffic_selector_t*))get_protocol;
this->public.is_host = (bool(*)(traffic_selector_t*,host_t*))is_host;
this->public.update_address_range = (void(*)(traffic_selector_t*,host_t*))update_address_range; this->public.update_address_range = (void(*)(traffic_selector_t*,host_t*))update_address_range;
this->public.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone_; this->public.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone_;
this->public.destroy = (void(*)(traffic_selector_t*))destroy; this->public.destroy = (void(*)(traffic_selector_t*))destroy;
@@ -698,7 +702,6 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts
this->to_port = to_port; this->to_port = to_port;
this->protocol = protocol; this->protocol = protocol;
this->type = type; this->type = type;
this->string = NULL;
return this; return this;
} }
+19 -12
View File
@@ -27,6 +27,11 @@
#include <types.h> #include <types.h>
#include <utils/host.h> #include <utils/host.h>
/**
* printf() specifier for tRaffic selectors
*/
#define TRAFFIC_SELECTOR_PRINTF_SPEC 'R'
typedef enum ts_type_t ts_type_t; typedef enum ts_type_t ts_type_t;
/** /**
@@ -56,9 +61,9 @@ enum ts_type_t {
}; };
/** /**
* string mappings for ts_type_t * enum names for ts_type_t
*/ */
extern mapping_t ts_type_m[]; extern enum_name_t *ts_type_name;
typedef struct traffic_selector_t traffic_selector_t; typedef struct traffic_selector_t traffic_selector_t;
@@ -160,6 +165,18 @@ struct traffic_selector_t {
*/ */
u_int8_t (*get_protocol) (traffic_selector_t *this); u_int8_t (*get_protocol) (traffic_selector_t *this);
/**
* @brief Check if the traffic selector is for a single host.
*
* Traffic selector may describe the end of *-to-host tunnel. In this
* case, the address range is a single address equal to the hosts
* peer address.
*
* @param this calling obect
* @param host host_t specifying the address range
*/
bool (*is_host) (traffic_selector_t *this, host_t* host);
/** /**
* @brief Update the address of a traffic selector. * @brief Update the address of a traffic selector.
* *
@@ -173,16 +190,6 @@ struct traffic_selector_t {
*/ */
void (*update_address_range) (traffic_selector_t *this, host_t* host); void (*update_address_range) (traffic_selector_t *this, host_t* host);
/**
* @brief Get a string representation of the traffic selector.
*
* String points to internal data, do not free/modify.
*
* @param this calling object
* @return pointer to a string.
*/
char* (*get_string) (traffic_selector_t *this);
/** /**
* @brief Compare two traffic selectors for equality. * @brief Compare two traffic selectors for equality.
* *
+139 -75
View File
@@ -21,7 +21,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
*/ */
#include <stdio.h> #include <stdio.h>
#include <signal.h> #include <signal.h>
#include <pthread.h> #include <pthread.h>
@@ -34,7 +34,7 @@
#include <getopt.h> #include <getopt.h>
#include <errno.h> #include <errno.h>
#include "daemon.h" #include "daemon.h"
#include <types.h> #include <types.h>
#include <config/credentials/local_credential_store.h> #include <config/credentials/local_credential_store.h>
@@ -53,11 +53,6 @@ struct private_daemon_t {
*/ */
daemon_t public; daemon_t public;
/**
* A logger_t object assigned for daemon things.
*/
logger_t *logger;
/** /**
* Signal set used for signal handling. * Signal set used for signal handling.
*/ */
@@ -74,6 +69,37 @@ struct private_daemon_t {
*/ */
daemon_t *charon; daemon_t *charon;
/**
* hook in library for debugging messages
*/
extern void (*dbg) (int level, char *fmt, ...);
/**
* Logging hook for library logs, spreads debug message over bus
*/
static void dbg_bus(int level, char *fmt, ...)
{
va_list args;
va_start(args, fmt);
charon->bus->vsignal(charon->bus, SIG_DBG_LIB, level, fmt, args);
va_end(args);
}
/**
* Logging hook for library logs, using stderr output
*/
static void dbg_stderr(int level, char *fmt, ...)
{
va_list args;
va_start(args, fmt);
fprintf(stderr, "00[LIB] ");
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
va_end(args);
}
/** /**
* Run the daemon and handle unix signals * Run the daemon and handle unix signals
*/ */
@@ -94,27 +120,27 @@ static void run(private_daemon_t *this)
error = sigwait(&(this->signal_set), &signal_number); error = sigwait(&(this->signal_set), &signal_number);
if(error) if(error)
{ {
this->logger->log(this->logger, ERROR, "Error %d when waiting for signal", error); DBG1(SIG_DBG_DMN, "error %d while waiting for a signal", error);
return; return;
} }
switch (signal_number) switch (signal_number)
{ {
case SIGHUP: case SIGHUP:
{ {
this->logger->log(this->logger, CONTROL, "Signal of type SIGHUP received. Do nothing"); DBG1(SIG_DBG_DMN, "signal of type SIGHUP received. Ignored");
break; break;
} }
case SIGINT: case SIGINT:
{ {
this->logger->log(this->logger, CONTROL, "Signal of type SIGINT received. Exit main loop"); DBG1(SIG_DBG_DMN, "signal of type SIGINT received. Shutting down");
return; return;
} }
case SIGTERM: case SIGTERM:
this->logger->log(this->logger, CONTROL, "Signal of type SIGTERM received. Exit main loop"); DBG1(SIG_DBG_DMN, "signal of type SIGTERM received. Shutting down");
return; return;
default: default:
{ {
this->logger->log(this->logger, CONTROL, "Unknown signal %d received. Do nothing", signal_number); DBG1(SIG_DBG_DMN, "unknown signal %d received. Ignored", signal_number);
break; break;
} }
} }
@@ -144,20 +170,24 @@ static void destroy(private_daemon_t *this)
/* all child SAs should be down now, so kill kernel interface */ /* all child SAs should be down now, so kill kernel interface */
DESTROY_IF(this->public.kernel_interface); DESTROY_IF(this->public.kernel_interface);
/* destroy other infrastructure */ /* destroy other infrastructure */
DESTROY_IF(this->public.bus);
DESTROY_IF(this->public.outlog);
DESTROY_IF(this->public.syslog);
DESTROY_IF(this->public.job_queue); DESTROY_IF(this->public.job_queue);
DESTROY_IF(this->public.event_queue); DESTROY_IF(this->public.event_queue);
DESTROY_IF(this->public.configuration); DESTROY_IF(this->public.configuration);
DESTROY_IF(this->public.credentials); DESTROY_IF(this->public.credentials);
DESTROY_IF(this->public.connections); DESTROY_IF(this->public.connections);
DESTROY_IF(this->public.policies); DESTROY_IF(this->public.policies);
sched_yield();
/* we hope the sender could send the outstanding deletes, but /* we hope the sender could send the outstanding deletes, but
* we shut down here at any cost */ * we shut down here at any cost */
DESTROY_IF(this->public.sender); DESTROY_IF(this->public.sender);
DESTROY_IF(this->public.send_queue); DESTROY_IF(this->public.send_queue);
DESTROY_IF(this->public.socket); DESTROY_IF(this->public.socket);
/* before destroying bus with its listeners, rehook library logs */
dbg = dbg_stderr;
DESTROY_IF(this->public.bus);
DESTROY_IF(this->public.outlog);
DESTROY_IF(this->public.syslog);
DESTROY_IF(this->public.authlog);
free(this); free(this);
} }
@@ -167,7 +197,7 @@ static void destroy(private_daemon_t *this)
static void kill_daemon(private_daemon_t *this, char *reason) static void kill_daemon(private_daemon_t *this, char *reason)
{ {
/* we send SIGTERM, so the daemon can cleanly shut down */ /* we send SIGTERM, so the daemon can cleanly shut down */
this->logger->log(this->logger, CONTROL, "Killing daemon: %s", reason); DBG1(SIG_DBG_DMN, "killing daemon: %s", reason);
if (this->main_thread_id == pthread_self()) if (this->main_thread_id == pthread_self())
{ {
/* initialization failed, terminate daemon */ /* initialization failed, terminate daemon */
@@ -177,7 +207,7 @@ static void kill_daemon(private_daemon_t *this, char *reason)
} }
else else
{ {
this->logger->log(this->logger, CONTROL, "sending SIGTERM to ourself", reason); DBG1(SIG_DBG_DMN, "sending SIGTERM to ourself");
raise(SIGTERM); raise(SIGTERM);
/* thread must die, since he produced a ciritcal failure and can't continue */ /* thread must die, since he produced a ciritcal failure and can't continue */
pthread_exit(NULL); pthread_exit(NULL);
@@ -187,24 +217,50 @@ static void kill_daemon(private_daemon_t *this, char *reason)
/** /**
* Initialize the daemon, optional with a strict crl policy * Initialize the daemon, optional with a strict crl policy
*/ */
static void initialize(private_daemon_t *this, bool strict) static void initialize(private_daemon_t *this, bool strict, bool syslog,
level_t levels[])
{ {
credential_store_t* credentials; credential_store_t* credentials;
signal_t signal;
/* for uncritical pseudo random numbers */ /* for uncritical pseudo random numbers */
srandom(time(NULL) + getpid()); srandom(time(NULL) + getpid());
/* setup bus and it's listeners first to enable log output */
this->public.bus = bus_create();
this->public.outlog = file_logger_create(stdout);
this->public.syslog = sys_logger_create(LOG_DAEMON);
this->public.authlog = sys_logger_create(LOG_AUTHPRIV);
this->public.bus->add_listener(this->public.bus, &this->public.syslog->listener);
this->public.bus->add_listener(this->public.bus, &this->public.outlog->listener);
this->public.bus->add_listener(this->public.bus, &this->public.authlog->listener);
this->public.authlog->set_level(this->public.authlog, SIG_ANY, LEVEL_AUDIT);
/* set up hook to log dbg message in library via charons message bus */
dbg = dbg_bus;
/* apply loglevels */
for (signal = 0; signal < SIG_DBG_MAX; signal++)
{
if (syslog)
{
this->public.syslog->set_level(this->public.syslog,
signal, levels[signal]);
}
else
{
this->public.outlog->set_level(this->public.outlog,
signal, levels[signal]);
}
}
DBG1(SIG_DBG_DMN, "starting charon (strongSwan Version %s)", VERSION);
this->public.configuration = configuration_create(); this->public.configuration = configuration_create();
this->public.socket = socket_create(IKEV2_UDP_PORT, IKEV2_NATT_PORT); this->public.socket = socket_create(IKEV2_UDP_PORT, IKEV2_NATT_PORT);
this->public.ike_sa_manager = ike_sa_manager_create(); this->public.ike_sa_manager = ike_sa_manager_create();
this->public.job_queue = job_queue_create(); this->public.job_queue = job_queue_create();
this->public.event_queue = event_queue_create(); this->public.event_queue = event_queue_create();
this->public.send_queue = send_queue_create(); this->public.send_queue = send_queue_create();
this->public.bus = bus_create();
this->public.outlog = file_logger_create(stdout);
this->public.bus->add_listener(this->public.bus, &this->public.outlog->listener);
this->public.syslog = sys_logger_create(LOG_DAEMON);
this->public.bus->add_listener(this->public.bus, &this->public.syslog->listener);
this->public.connections = (connection_store_t*)local_connection_store_create(); this->public.connections = (connection_store_t*)local_connection_store_create();
this->public.policies = (policy_store_t*)local_policy_store_create(); this->public.policies = (policy_store_t*)local_policy_store_create();
this->public.credentials = (credential_store_t*)local_credential_store_create(strict); this->public.credentials = (credential_store_t*)local_credential_store_create(strict);
@@ -233,23 +289,19 @@ void signal_handler(int signal)
size_t size; size_t size;
char **strings; char **strings;
size_t i; size_t i;
logger_t *logger;
size = backtrace(array, 20); size = backtrace(array, 20);
strings = backtrace_symbols(array, size); strings = backtrace_symbols(array, size);
logger = logger_manager->get_logger(logger_manager, DAEMON);
logger->log(logger, ERROR, DBG1(SIG_DBG_DMN, "thread %u received %s. Dumping %d frames from stack:",
"Thread %u received %s. Dumping %d frames from stack:", signal == SIGSEGV ? "SIGSEGV" : "SIGILL", pthread_self(), size);
signal == SIGSEGV ? "SIGSEGV" : "SIGILL",
pthread_self(), size);
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
logger->log(logger, ERROR, " %s", strings[i]); DBG1(SIG_DBG_DMN, " %s", strings[i]);
} }
free (strings); free (strings);
logger->log(logger, ERROR, "Killing ourself hard after SIGSEGV"); DBG1(SIG_DBG_DMN, "killing ourself hard after SIGSEGV");
raise(SIGKILL); raise(SIGKILL);
} }
@@ -283,6 +335,7 @@ private_daemon_t *daemon_create(void)
this->public.bus = NULL; this->public.bus = NULL;
this->public.outlog = NULL; this->public.outlog = NULL;
this->public.syslog = NULL; this->public.syslog = NULL;
this->public.authlog = NULL;
this->main_thread_id = pthread_self(); this->main_thread_id = pthread_self();
@@ -298,14 +351,8 @@ private_daemon_t *daemon_create(void)
action.sa_handler = signal_handler; action.sa_handler = signal_handler;
action.sa_mask = this->signal_set; action.sa_mask = this->signal_set;
action.sa_flags = 0; action.sa_flags = 0;
if (sigaction(SIGSEGV, &action, NULL) == -1) sigaction(SIGSEGV, &action, NULL);
{ sigaction(SIGILL, &action, NULL);
this->logger->log(this->logger, ERROR, "signal handler setup for SIGSEGV failed");
}
if (sigaction(SIGILL, &action, NULL) == -1)
{
this->logger->log(this->logger, ERROR, "signal handler setup for SIGILL failed");
}
return this; return this;
} }
@@ -315,64 +362,90 @@ private_daemon_t *daemon_create(void)
static void usage(const char *msg) static void usage(const char *msg)
{ {
if (msg != NULL && *msg != '\0') if (msg != NULL && *msg != '\0')
{
fprintf(stderr, "%s\n", msg); fprintf(stderr, "%s\n", msg);
fprintf(stderr, "Usage: charon" }
" [--help]" fprintf(stderr, "Usage: charon\n"
" [--version]" " [--help]\n"
" [--use-syslog]" " [--version]\n"
" [--strictcrlpolicy]" " [--strictcrlpolicy]\n"
"\n" " [--use-syslog]\n"
); " [--debug-<type> <level>]\n"
exit(msg == NULL? 0 : 1); " <type>: log context type (dmn|mgr|ike|chd|job|cfg|knl|net|enc|lib)\n"
" <level>: log verbosity (-1 = silent, 0 = audit, 1 = control,\n"
" 2 = controlmore, 3 = raw, 4 = private)\n"
"\n"
);
exit(msg == NULL? 0 : 1);
} }
/** /**
* Main function, manages the daemon. * Main function, manages the daemon.
*/ */
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
bool strict_crl_policy = FALSE; bool strict_crl_policy = FALSE;
bool use_syslog = FALSE;
private_daemon_t *private_charon; private_daemon_t *private_charon;
FILE *pid_file; FILE *pid_file;
struct stat stb; struct stat stb;
linked_list_t *list; linked_list_t *list;
host_t *host; host_t *host;
level_t levels[SIG_DBG_MAX];
int signal;
/* handle arguments */ /* use CTRL loglevel for default */
for (;;) for (signal = 0; signal < SIG_DBG_MAX; signal++)
{ {
static const struct option long_opts[] = { levels[signal] = LEVEL_CTRL;
}
/* handle arguments */
for (;;)
{
struct option long_opts[] = {
{ "help", no_argument, NULL, 'h' }, { "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'v' },
{ "use-syslog", no_argument, NULL, 'l' }, { "use-syslog", no_argument, NULL, 'l' },
{ "strictcrlpolicy", no_argument, NULL, 'r' }, { "strictcrlpolicy", no_argument, NULL, 'r' },
{ "debug-dmn", required_argument, &signal, SIG_DBG_DMN },
{ "debug-mgr", required_argument, &signal, SIG_DBG_MGR },
{ "debug-ike", required_argument, &signal, SIG_DBG_IKE },
{ "debug-chd", required_argument, &signal, SIG_DBG_CHD },
{ "debug-job", required_argument, &signal, SIG_DBG_JOB },
{ "debug-cfg", required_argument, &signal, SIG_DBG_CFG },
{ "debug-knl", required_argument, &signal, SIG_DBG_KNL },
{ "debug-net", required_argument, &signal, SIG_DBG_NET },
{ "debug-enc", required_argument, &signal, SIG_DBG_ENC },
{ "debug-lib", required_argument, &signal, SIG_DBG_LIB },
{ 0,0,0,0 } { 0,0,0,0 }
}; };
int c = getopt_long(argc, argv, "", long_opts, NULL); int c = getopt_long(argc, argv, "", long_opts, NULL);
/* Note: "breaking" from case terminates loop */
switch (c) switch (c)
{ {
case EOF: /* end of flags */ case EOF:
break; break;
case 'h': case 'h':
usage(NULL); usage(NULL);
break; /* not actually reached */ break;
case 'v': case 'v':
printf("Linux strongSwan %s\n", VERSION); printf("Linux strongSwan %s\n", VERSION);
exit(0); exit(0);
case 'l': case 'l':
logger_manager->set_output(logger_manager, ALL_LOGGERS, NULL); use_syslog = TRUE;
continue; continue;
case 'r': case 'r':
strict_crl_policy = TRUE; strict_crl_policy = TRUE;
continue; continue;
case 0:
/* option is in signal */
levels[signal] = atoi(optarg);
continue;
default: default:
usage(""); usage("");
break; /* not actually reached */ break;
} }
break; break;
} }
@@ -380,19 +453,13 @@ int main(int argc, char *argv[])
private_charon = daemon_create(); private_charon = daemon_create();
charon = (daemon_t*)private_charon; charon = (daemon_t*)private_charon;
private_charon->logger = logger_manager->get_logger(logger_manager, DAEMON);
private_charon->logger->log(private_charon->logger, CONTROL,
"Starting Charon (strongSwan Version %s)", VERSION);
/* initialize daemon */ /* initialize daemon */
initialize(private_charon, strict_crl_policy); initialize(private_charon, strict_crl_policy, use_syslog, levels);
/* check/setup PID file */ /* check/setup PID file */
if (stat(PID_FILE, &stb) == 0) if (stat(PID_FILE, &stb) == 0)
{ {
private_charon->logger->log(private_charon->logger, ERROR, DBG1(SIG_DBG_DMN, "charon already running (\""PID_FILE"\" exists)");
"charon already running (\""PID_FILE"\" exists)");
destroy(private_charon); destroy(private_charon);
exit(-1); exit(-1);
} }
@@ -404,13 +471,10 @@ int main(int argc, char *argv[])
} }
/* log socket info */ /* log socket info */
list = charon->socket->create_local_address_list(charon->socket); list = charon->socket->create_local_address_list(charon->socket);
private_charon->logger->log(private_charon->logger, CONTROL, DBG1(SIG_DBG_NET, "listening on %d addresses:", list->get_count(list));
"listening on %d addresses:",
list->get_count(list));
while (list->remove_first(list, (void**)&host) == SUCCESS) while (list->remove_first(list, (void**)&host) == SUCCESS)
{ {
private_charon->logger->log(private_charon->logger, CONTROL, DBG1(SIG_DBG_NET, " %H", host);
" %H", host);
host->destroy(host); host->destroy(host);
} }
list->destroy(list); list->destroy(list);
@@ -421,6 +485,6 @@ int main(int argc, char *argv[])
/* normal termination, cleanup and exit */ /* normal termination, cleanup and exit */
destroy(private_charon); destroy(private_charon);
unlink(PID_FILE); unlink(PID_FILE);
return 0; return 0;
} }
+7 -3
View File
@@ -1,8 +1,8 @@
/** /**
* @file daemon.h * @file daemon.h
* *
* @brief Interface of daemon_t. * @brief Interface of daemon_t.
* *
*/ */
/* /*
@@ -39,7 +39,6 @@
#include <queues/send_queue.h> #include <queues/send_queue.h>
#include <queues/job_queue.h> #include <queues/job_queue.h>
#include <queues/event_queue.h> #include <queues/event_queue.h>
#include <utils/logger_manager.h>
#include <config/configuration.h> #include <config/configuration.h>
#include <config/connections/connection_store.h> #include <config/connections/connection_store.h>
#include <config/policies/policy_store.h> #include <config/policies/policy_store.h>
@@ -362,6 +361,11 @@ struct daemon_t {
*/ */
sys_logger_t *syslog; sys_logger_t *syslog;
/**
* A bus listener logging most important events
*/
sys_logger_t *authlog;
/** /**
* Kernel Interface to communicate with kernel * Kernel Interface to communicate with kernel
*/ */
+41 -47
View File
@@ -32,7 +32,6 @@
#include <types.h> #include <types.h>
#include <daemon.h> #include <daemon.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <encoding/payloads/payload.h> #include <encoding/payloads/payload.h>
#include <encoding/payloads/proposal_substructure.h> #include <encoding/payloads/proposal_substructure.h>
#include <encoding/payloads/transform_substructure.h> #include <encoding/payloads/transform_substructure.h>
@@ -222,24 +221,19 @@ struct private_generator_t {
*/ */
u_int8_t last_spi_size; u_int8_t last_spi_size;
/* /**
* Attribute format of the last generated transform attribute. * Attribute format of the last generated transform attribute.
* *
* Used to check if a variable value field is used or not for * Used to check if a variable value field is used or not for
* the transform attribute value. * the transform attribute value.
*/ */
bool attribute_format; bool attribute_format;
/* /**
* Depending on the value of attribute_format this field is used * Depending on the value of attribute_format this field is used
* to hold the length of the transform attribute in bytes. * to hold the length of the transform attribute in bytes.
*/ */
u_int16_t attribute_length; u_int16_t attribute_length;
/**
* Associated Logger.
*/
logger_t *logger;
}; };
/** /**
@@ -312,16 +306,16 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
break; break;
default: default:
this->logger->log(this->logger, ERROR, "U_INT Type %s is not supported", DBG1(SIG_DBG_ENC, "U_INT Type %N is not supported",
mapping_find(encoding_type_m,int_type)); encoding_type_names, int_type);
return; return;
} }
/* U_INT Types of multiple then 8 bits must be aligned */ /* U_INT Types of multiple then 8 bits must be aligned */
if (((number_of_bits % 8) == 0) && (this->current_bit != 0)) if (((number_of_bits % 8) == 0) && (this->current_bit != 0))
{ {
this->logger->log(this->logger, ERROR, "U_INT Type %s is not 8 Bit aligned", DBG1(SIG_DBG_ENC, "U_INT Type %N is not 8 Bit aligned",
mapping_find(encoding_type_m,int_type)); encoding_type_names, int_type);
/* current bit has to be zero for values multiple of 8 bits */ /* current bit has to be zero for values multiple of 8 bits */
return; return;
} }
@@ -341,7 +335,7 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
u_int8_t low_val = *(this->out_position) & 0x0F; u_int8_t low_val = *(this->out_position) & 0x0F;
/* highval is set, low_val is not changed */ /* highval is set, low_val is not changed */
*(this->out_position) = high_val | low_val; *(this->out_position) = high_val | low_val;
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *(this->out_position)); DBG3(SIG_DBG_ENC, " => %d", *(this->out_position));
/* write position is not changed, just bit position is moved */ /* write position is not changed, just bit position is moved */
this->current_bit = 4; this->current_bit = 4;
} }
@@ -352,14 +346,14 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
/* lowval of current byte in buffer has to be set to the new value*/ /* lowval of current byte in buffer has to be set to the new value*/
u_int low_val = *((u_int8_t *)(this->data_struct + offset)) & 0x0F; u_int low_val = *((u_int8_t *)(this->data_struct + offset)) & 0x0F;
*(this->out_position) = high_val | low_val; *(this->out_position) = high_val | low_val;
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *(this->out_position)); DBG3(SIG_DBG_ENC, " => %d", *(this->out_position));
this->out_position++; this->out_position++;
this->current_bit = 0; this->current_bit = 0;
} }
else else
{ {
this->logger->log(this->logger, ERROR, "U_INT_4 Type is not 4 Bit aligned"); DBG1(SIG_DBG_ENC, "U_INT_4 Type is not 4 Bit aligned");
/* 4 Bit integers must have a 4 bit alignment */ /* 4 Bit integers must have a 4 bit alignment */
return; return;
}; };
@@ -370,7 +364,7 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
{ {
/* 8 bit values are written as they are */ /* 8 bit values are written as they are */
*this->out_position = *((u_int8_t *)(this->data_struct + offset)); *this->out_position = *((u_int8_t *)(this->data_struct + offset));
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *(this->out_position)); DBG3(SIG_DBG_ENC, " => %d", *(this->out_position));
this->out_position++; this->out_position++;
break; break;
@@ -380,7 +374,7 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
/* attribute type must not change first bit uf current byte ! */ /* attribute type must not change first bit uf current byte ! */
if (this->current_bit != 1) if (this->current_bit != 1)
{ {
this->logger->log(this->logger, ERROR, "ATTRIBUTE FORMAT flag is not set"); DBG1(SIG_DBG_ENC, "ATTRIBUTE FORMAT flag is not set");
/* first bit has to be set! */ /* first bit has to be set! */
return; return;
} }
@@ -392,7 +386,7 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
int16_val = int16_val & 0xFF7F; int16_val = int16_val & 0xFF7F;
int16_val = int16_val | attribute_format_flag; int16_val = int16_val | attribute_format_flag;
this->logger->log(this->logger, RAW|LEVEL2, " => %d", int16_val); DBG3(SIG_DBG_ENC, " => %d", int16_val);
/* write bytes to buffer (set bit is overwritten)*/ /* write bytes to buffer (set bit is overwritten)*/
this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t)); this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t));
this->current_bit = 0; this->current_bit = 0;
@@ -403,14 +397,14 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
case CONFIGURATION_ATTRIBUTE_LENGTH: case CONFIGURATION_ATTRIBUTE_LENGTH:
{ {
u_int16_t int16_val = htons(*((u_int16_t*)(this->data_struct + offset))); u_int16_t int16_val = htons(*((u_int16_t*)(this->data_struct + offset)));
this->logger->log_bytes(this->logger, RAW|LEVEL2, " =>", (void*)&int16_val, sizeof(int16_val)); DBG3(SIG_DBG_ENC, " => %b", (void*)&int16_val, sizeof(int16_val));
this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t)); this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t));
break; break;
} }
case U_INT_32: case U_INT_32:
{ {
u_int32_t int32_val = htonl(*((u_int32_t*)(this->data_struct + offset))); u_int32_t int32_val = htonl(*((u_int32_t*)(this->data_struct + offset)));
this->logger->log_bytes(this->logger, RAW|LEVEL2, " =>", (void*)&int32_val, sizeof(int32_val)); DBG3(SIG_DBG_ENC, " => %b", (void*)&int32_val, sizeof(int32_val));
this->write_bytes_to_buffer(this,&int32_val,sizeof(u_int32_t)); this->write_bytes_to_buffer(this,&int32_val,sizeof(u_int32_t));
break; break;
} }
@@ -419,8 +413,9 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
/* 64 bit integers are written as two 32 bit integers */ /* 64 bit integers are written as two 32 bit integers */
u_int32_t int32_val_low = htonl(*((u_int32_t*)(this->data_struct + offset))); u_int32_t int32_val_low = htonl(*((u_int32_t*)(this->data_struct + offset)));
u_int32_t int32_val_high = htonl(*((u_int32_t*)(this->data_struct + offset) + 1)); u_int32_t int32_val_high = htonl(*((u_int32_t*)(this->data_struct + offset) + 1));
this->logger->log_bytes(this->logger, RAW|LEVEL2, " => (low)", (void*)&int32_val_low, sizeof(int32_val_low)); DBG3(SIG_DBG_ENC, " => %b %b",
this->logger->log_bytes(this->logger, RAW|LEVEL2, " => (high)", (void*)&int32_val_high, sizeof(int32_val_high)); (void*)&int32_val_low, sizeof(int32_val_low),
(void*)&int32_val_high, sizeof(int32_val_high));
/* TODO add support for big endian machines */ /* TODO add support for big endian machines */
this->write_bytes_to_buffer(this,&int32_val_high,sizeof(u_int32_t)); this->write_bytes_to_buffer(this,&int32_val_high,sizeof(u_int32_t));
this->write_bytes_to_buffer(this,&int32_val_low,sizeof(u_int32_t)); this->write_bytes_to_buffer(this,&int32_val_low,sizeof(u_int32_t));
@@ -431,12 +426,13 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
{ {
/* 64 bit are written as they come :-) */ /* 64 bit are written as they come :-) */
this->write_bytes_to_buffer(this,(this->data_struct + offset),sizeof(u_int64_t)); this->write_bytes_to_buffer(this,(this->data_struct + offset),sizeof(u_int64_t));
this->logger->log_bytes(this->logger, RAW|LEVEL2, " =>", (void*)(this->data_struct + offset), sizeof(u_int64_t)); DBG3(SIG_DBG_ENC, " => %b", (void*)(this->data_struct + offset), sizeof(u_int64_t));
break; break;
} }
default: default:
{ {
this->logger->log(this->logger, ERROR, "U_INT Type %s is not supported", mapping_find(encoding_type_m,int_type)); DBG1(SIG_DBG_ENC, "U_INT Type %N is not supported",
encoding_type_names, int_type);
return; return;
} }
} }
@@ -450,7 +446,7 @@ static void generate_reserved_field(private_generator_t *this,int bits)
/* only one bit or 8 bit fields are supported */ /* only one bit or 8 bit fields are supported */
if ((bits != 1) && (bits != 8)) if ((bits != 1) && (bits != 8))
{ {
this->logger->log(this->logger, ERROR, "Reserved field of %d bits cannot be generated", bits); DBG1(SIG_DBG_ENC, "reserved field of %d bits cannot be generated", bits);
return ; return ;
} }
/* make sure enough space is available in buffer */ /* make sure enough space is available in buffer */
@@ -480,9 +476,8 @@ static void generate_reserved_field(private_generator_t *this,int bits)
/* one byte processing*/ /* one byte processing*/
if (this->current_bit > 0) if (this->current_bit > 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_ENC, "reserved field cannot be written cause "
"Reserved field cannot be written cause allignement of current bit is %d", "alignement of current bit is %d", this->current_bit);
this->current_bit);
return; return;
} }
*(this->out_position) = 0x00; *(this->out_position) = 0x00;
@@ -516,7 +511,7 @@ static void generate_flag (private_generator_t *this,u_int32_t offset)
*(this->out_position) = *(this->out_position) | flag; *(this->out_position) = *(this->out_position) | flag;
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *(this->out_position)); DBG3(SIG_DBG_ENC, " => %d", *(this->out_position));
this->current_bit++; this->current_bit++;
if (this->current_bit >= 8) if (this->current_bit >= 8)
@@ -533,14 +528,14 @@ static void generate_from_chunk (private_generator_t *this,u_int32_t offset)
{ {
if (this->current_bit != 0) if (this->current_bit != 0)
{ {
this->logger->log(this->logger, ERROR, "can not generate a chunk at Bitpos %d", this->current_bit); DBG1(SIG_DBG_ENC, "can not generate a chunk at Bitpos %d", this->current_bit);
return ; return ;
} }
/* position in buffer */ /* position in buffer */
chunk_t *attribute_value = (chunk_t *)(this->data_struct + offset); chunk_t *attribute_value = (chunk_t *)(this->data_struct + offset);
this->logger->log_chunk(this->logger, RAW|LEVEL2, " =>", *attribute_value); DBG3(SIG_DBG_ENC, " => %B", attribute_value);
/* use write_bytes_to_buffer function to do the job */ /* use write_bytes_to_buffer function to do the job */
this->write_bytes_to_buffer(this,attribute_value->ptr,attribute_value->len); this->write_bytes_to_buffer(this,attribute_value->ptr,attribute_value->len);
@@ -558,8 +553,8 @@ static void make_space_available (private_generator_t *this, size_t bits)
size_t new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE; size_t new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE;
size_t out_position_offset = ((this->out_position) - (this->buffer)); size_t out_position_offset = ((this->out_position) - (this->buffer));
this->logger->log(this->logger, CONTROL|LEVEL3, "increased gen buffer from %d to %d byte", DBG2(SIG_DBG_ENC, "increased gen buffer from %d to %d byte",
old_buffer_size, new_buffer_size); old_buffer_size, new_buffer_size);
/* Reallocate space for new buffer */ /* Reallocate space for new buffer */
this->buffer = realloc(this->buffer,new_buffer_size); this->buffer = realloc(this->buffer,new_buffer_size);
@@ -633,7 +628,7 @@ static void write_to_chunk (private_generator_t *this,chunk_t *data)
memcpy(data->ptr,this->buffer,data_length); memcpy(data->ptr,this->buffer,data_length);
data->len = data_length; data->len = data_length;
this->logger->log_chunk(this->logger, RAW|LEVEL3, "generated data of this generator", *data); DBG3(SIG_DBG_ENC, "generated data of this generator %B", data);
} }
/** /**
@@ -655,16 +650,16 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
payload_start = this->out_position; payload_start = this->out_position;
this->logger->log(this->logger, CONTROL|LEVEL1, "generating payload of type %s", DBG2(SIG_DBG_ENC, "generating payload of type %N",
mapping_find(payload_type_m,payload_type)); payload_type_names, payload_type);
/* each payload has its own encoding rules */ /* each payload has its own encoding rules */
payload->get_encoding_rules(payload,&rules,&rule_count); payload->get_encoding_rules(payload,&rules,&rule_count);
for (i = 0; i < rule_count;i++) for (i = 0; i < rule_count;i++)
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, " generating rule %d %s", DBG2(SIG_DBG_ENC, " generating rule %d %N",
i, mapping_find(encoding_type_m,rules[i].type)); i, encoding_type_names, rules[i].type);
switch (rules[i].type) switch (rules[i].type)
{ {
/* all u int values, IKE_SPI,TS_TYPE and ATTRIBUTE_TYPE are generated in generate_u_int_type */ /* all u int values, IKE_SPI,TS_TYPE and ATTRIBUTE_TYPE are generated in generate_u_int_type */
@@ -964,7 +959,7 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
{ {
if (this->attribute_format == FALSE) if (this->attribute_format == FALSE)
{ {
this->logger->log(this->logger, CONTROL|LEVEL3, "attribute value has not fixed size"); DBG2(SIG_DBG_ENC, "attribute value has not fixed size");
/* the attribute value is generated */ /* the attribute value is generated */
this->generate_from_chunk(this,rules[i].offset); this->generate_from_chunk(this,rules[i].offset);
} }
@@ -1012,15 +1007,15 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
break; break;
} }
default: default:
this->logger->log(this->logger, ERROR, "field type %s is not supported", DBG1(SIG_DBG_ENC, "field type %N is not supported",
mapping_find(encoding_type_m,rules[i].type)); encoding_type_names, rules[i].type);
return; return;
} }
} }
this->logger->log(this->logger, CONTROL|LEVEL2, "generating %s payload finished.", DBG2(SIG_DBG_ENC, "generating %N payload finished",
mapping_find(payload_type_m, payload_type)); payload_type_names, payload_type);
this->logger->log_bytes(this->logger, RAW|LEVEL3, "generated data for this payload", DBG3(SIG_DBG_ENC, "generated data for this payload %b",
payload_start, this->out_position-payload_start); payload_start, this->out_position-payload_start);
} }
/** /**
@@ -1072,7 +1067,6 @@ generator_t *generator_create()
this->current_bit = 0; this->current_bit = 0;
this->last_payload_length_position_offset = 0; this->last_payload_length_position_offset = 0;
this->header_length_position_offset = 0; this->header_length_position_offset = 0;
this->logger = logger_manager->get_logger(logger_manager, GENERATOR);
return &(this->public); return &(this->public);
} }
+324 -393
View File
@@ -24,6 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <printf.h>
#include "message.h" #include "message.h"
@@ -33,7 +34,6 @@
#include <encoding/generator.h> #include <encoding/generator.h>
#include <encoding/parser.h> #include <encoding/parser.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <encoding/payloads/encodings.h> #include <encoding/payloads/encodings.h>
#include <encoding/payloads/payload.h> #include <encoding/payloads/payload.h>
#include <encoding/payloads/encryption_payload.h> #include <encoding/payloads/encryption_payload.h>
@@ -42,7 +42,7 @@
/** /**
* Max number of notify payloads per IKEv2 Message * Max number of notify payloads per IKEv2 Message
*/ */
#define MAX_NOTIFY_PAYLOADS 10 #define MAX_NOTIFY_PAYLOADS 20
typedef struct payload_rule_t payload_rule_t; typedef struct payload_rule_t payload_rule_t;
@@ -66,7 +66,7 @@ struct payload_rule_t {
/** /**
* Max occurence of this payload. * Max occurence of this payload.
*/ */
size_t max_occurence; size_t max_occurence;
/** /**
@@ -295,72 +295,6 @@ struct private_message_t {
* The message rule for this message instance * The message rule for this message instance
*/ */
message_rule_t *message_rule; message_rule_t *message_rule;
/**
* Assigned logger.
*/
logger_t *logger;
/**
* Sets the private message_rule member to the rule which
* applies to this message. Must be called before get_payload_rule().
*
* @param this calling object
* @return
* - SUCCESS
* - NOT_FOUND if no message rule applies to this message.
*/
status_t (*set_message_rule) (private_message_t *this);
/**
* Gets the payload_rule_t for a specific message_rule_t and payload type.
*
* @param this calling object
* @param payload_type payload type
* @param[out] payload_rule returned payload_rule_t
* @return
* - SUCCESS
* - NOT_FOUND if payload not defined in current message rule
* - INVALID_STATE if message rule is not set via set_message_rule()
*/
status_t (*get_payload_rule) (private_message_t *this, payload_type_t payload_type, payload_rule_t **payload_rule);
/**
* Encrypts all payloads which has to get encrypted.
*
* Can also be called with messages not containing encrypted content.
*
* @param this calling object
* @param crypter crypter_t object
* @param signer signer_t object
* @return
* - SUCCESS
* - INVALID_STATE if no crypter/signer supplied but needed
*/
status_t (*encrypt_payloads) (private_message_t *this,crypter_t *crypter, signer_t* signer);
/**
* Decrypts encrypted contents, and checks if a payload is encrypted if it has to be.
*
* @param this calling object
* @param crypter crypter_t object
* @param signer signer_t object
* @return
* - SUCCESS
* - FAILED if decryption not successfull
* - INVALID_STATE if no crypter/signer supplied but needed
*/
status_t (*decrypt_payloads) (private_message_t *this,crypter_t *crypter, signer_t* signer);
/**
* Verifies the message. Checks for payloads count.
*
* @param calling object
* @return
* - SUCCESS if message valid, or
* - FAILED if message does not align with message rules.
*/
status_t (*verify) (private_message_t *this);
}; };
/** /**
@@ -549,8 +483,8 @@ static void add_payload(private_message_t *this, payload_t *payload)
payload->set_next_type(payload, NO_PAYLOAD); payload->set_next_type(payload, NO_PAYLOAD);
this->payloads->insert_last(this->payloads, (void*)payload); this->payloads->insert_last(this->payloads, (void*)payload);
this->logger->log(this->logger, CONTROL|LEVEL1, "added payload of type %s to message", DBG2(SIG_DBG_ENC ,"added payload of type %N to message",
mapping_find(payload_type_m, payload->get_type(payload))); payload_type_names, payload->get_type(payload));
} }
/** /**
@@ -566,7 +500,6 @@ static void set_source(private_message_t *this, host_t *host)
*/ */
static void set_destination(private_message_t *this, host_t *host) static void set_destination(private_message_t *this, host_t *host)
{ {
this->packet->set_destination(this->packet, host); this->packet->set_destination(this->packet, host);
} }
@@ -595,46 +528,159 @@ static iterator_t *get_payload_iterator(private_message_t *this)
} }
/** /**
* Build a string containing short names for all payload in this message * output handler in printf()
*/ */
static void build_payload_string(private_message_t *this, char* buffer, size_t size) static int print(FILE *stream, const struct printf_info *info,
const void *const *args)
{ {
private_message_t *this = *((private_message_t**)(args[0]));
iterator_t *iterator; iterator_t *iterator;
payload_t *payload; payload_t *payload;
bool first = TRUE; bool first = TRUE;
size_t total_written = 0;
size_t written;
*buffer = '\0'; if (this == NULL)
size--; {
return fprintf(stream, "(null)");
}
written = fprintf(stream, "%N %s [",
exchange_type_names, this->exchange_type,
this->is_request ? "request" : "response");
if (written < 0)
{
return written;
}
total_written += written;
iterator = this->payloads->create_iterator(this->payloads, TRUE); iterator = this->payloads->create_iterator(this->payloads, TRUE);
while (iterator->iterate(iterator, (void**)&payload)) while (iterator->iterate(iterator, (void**)&payload))
{ {
payload_type_t type = payload->get_type(payload);
char *name = mapping_find(payload_type_short_m, type);
size_t name_len = strlen(name);
if (!first) if (!first)
{ {
strncat(buffer, " ", size); written = fprintf(stream, " ");
if (size) if (written < 0)
{ {
size--; return written;
} }
total_written += written;
} }
else else
{ {
first = FALSE; first = FALSE;
} }
strncat(buffer, name, size); written = fprintf(stream, "%N", payload_type_short_names,
if (name_len > size) payload->get_type(payload));
if (written < 0)
{ {
size = 0; return written;
}
total_written += written;
}
iterator->destroy(iterator);
written = fprintf(stream, "]");
if (written < 0)
{
return written;
}
total_written += written;
return total_written;
}
/**
* arginfo handler in printf()
*/
static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes)
{
if (n > 0)
{
argtypes[0] = PA_POINTER;
}
return 1;
}
/**
* register printf() handlers
*/
static void __attribute__ ((constructor))print_register()
{
register_printf_function(MESSAGE_PRINTF_SPEC, print, print_arginfo);
}
/**
* Implementation of private_message_t.encrypt_payloads.
*/
static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, signer_t* signer)
{
encryption_payload_t *encryption_payload = NULL;
status_t status;
linked_list_t *all_payloads;
if (!this->message_rule->encrypted_content)
{
DBG2(SIG_DBG_ENC, "message doesn't have to be encrypted");
/* message contains no content to encrypt */
return SUCCESS;
}
DBG2(SIG_DBG_ENC, "copy all payloads to a temporary list");
all_payloads = linked_list_create();
/* first copy all payloads in a temporary list */
while (this->payloads->get_count(this->payloads) > 0)
{
void *current_payload;
this->payloads->remove_first(this->payloads,&current_payload);
all_payloads->insert_last(all_payloads,current_payload);
}
encryption_payload = encryption_payload_create();
DBG2(SIG_DBG_ENC, "check each payloads if they have to get encrypted");
while (all_payloads->get_count(all_payloads) > 0)
{
payload_rule_t *payload_rule;
payload_t *current_payload;
bool to_encrypt = FALSE;
all_payloads->remove_first(all_payloads,(void **)&current_payload);
status = get_payload_rule(this,
current_payload->get_type(current_payload),&payload_rule);
/* for payload types which are not found in supported payload list,
* it is presumed that they don't have to be encrypted */
if ((status == SUCCESS) && (payload_rule->encrypted))
{
DBG2(SIG_DBG_ENC, "payload %N gets encrypted",
payload_type_names, current_payload->get_type(current_payload));
to_encrypt = TRUE;
}
if (to_encrypt)
{
DBG2(SIG_DBG_ENC, "insert payload %N to encryption payload",
payload_type_names, current_payload->get_type(current_payload));
encryption_payload->add_payload(encryption_payload,current_payload);
} }
else else
{ {
size -= name_len; DBG2(SIG_DBG_ENC, "insert payload %N unencrypted",
payload_type_names ,current_payload->get_type(current_payload));
add_payload(this, (payload_t*)encryption_payload);
} }
} }
iterator->destroy(iterator);
status = SUCCESS;
DBG2(SIG_DBG_ENC, "encrypting encryption payload");
encryption_payload->set_transforms(encryption_payload, crypter,signer);
status = encryption_payload->encrypt(encryption_payload);
DBG2(SIG_DBG_ENC, "add encrypted payload to payload list");
add_payload(this, (payload_t*)encryption_payload);
all_payloads->destroy(all_payloads);
return status;
} }
/** /**
@@ -648,7 +694,6 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
iterator_t *iterator; iterator_t *iterator;
status_t status; status_t status;
chunk_t packet_data; chunk_t packet_data;
char payload_names[128];
if (is_encoded(this)) if (is_encoded(this))
{ {
@@ -657,50 +702,41 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
return SUCCESS; return SUCCESS;
} }
build_payload_string(this, payload_names, sizeof(payload_names)); DBG1(SIG_DBG_ENC, "generating %M", this);
this->logger->log(this->logger, CONTROL, "generating %s %s (%d) [%s]",
mapping_find(exchange_type_m,this->exchange_type),
this->is_request ? "request" : "response",
this->message_id,
payload_names);
if (this->exchange_type == EXCHANGE_TYPE_UNDEFINED) if (this->exchange_type == EXCHANGE_TYPE_UNDEFINED)
{ {
this->logger->log(this->logger, ERROR | LEVEL1, "exchange type %s is not defined", DBG1(SIG_DBG_ENC, "exchange type is not defined");
mapping_find(exchange_type_m,this->exchange_type));
return INVALID_STATE; return INVALID_STATE;
} }
if (this->packet->get_source(this->packet) == NULL || if (this->packet->get_source(this->packet) == NULL ||
this->packet->get_destination(this->packet) == NULL) this->packet->get_destination(this->packet) == NULL)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, "%s not defined", DBG1(SIG_DBG_ENC, "%s not defined",
!this->packet->get_source(this->packet) ? "source" : "destination"); !this->packet->get_source(this->packet) ? "source" : "destination");
return INVALID_STATE; return INVALID_STATE;
} }
/* set the rules for this messge */ /* set the rules for this messge */
status = this->set_message_rule(this); status = set_message_rule(this);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "no message rules specified for a %s %s", DBG1(SIG_DBG_ENC, "no message rules specified for this message type");
mapping_find(exchange_type_m,this->exchange_type),
this->is_request ? "request" : "response");
return NOT_SUPPORTED; return NOT_SUPPORTED;
} }
/* going to encrypt all content which have to be encrypted */ /* going to encrypt all content which have to be encrypted */
status = this->encrypt_payloads(this, crypter, signer); status = encrypt_payloads(this, crypter, signer);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR | LEVEL1, "could not encrypt payloads"); DBG1(SIG_DBG_ENC, "payload encryption failed");
return status; return status;
} }
/* build ike header */ /* build ike header */
ike_header = ike_header_create(); ike_header = ike_header_create();
ike_header->set_exchange_type(ike_header, this->exchange_type); ike_header->set_exchange_type(ike_header, this->exchange_type);
ike_header->set_message_id(ike_header, this->message_id); ike_header->set_message_id(ike_header, this->message_id);
ike_header->set_response_flag(ike_header, !this->is_request); ike_header->set_response_flag(ike_header, !this->is_request);
@@ -738,7 +774,7 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
/* if last payload is of type encrypted, integrity checksum if necessary */ /* if last payload is of type encrypted, integrity checksum if necessary */
if (payload->get_type(payload) == ENCRYPTED) if (payload->get_type(payload) == ENCRYPTED)
{ {
this->logger->log(this->logger, CONTROL | LEVEL1, "build signature on whole message"); DBG2(SIG_DBG_ENC, "build signature on whole message");
encryption_payload_t *encryption_payload = (encryption_payload_t*)payload; encryption_payload_t *encryption_payload = (encryption_payload_t*)payload;
status = encryption_payload->build_signature(encryption_payload, packet_data); status = encryption_payload->build_signature(encryption_payload, packet_data);
if (status != SUCCESS) if (status != SUCCESS)
@@ -752,8 +788,7 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
/* clone packet for caller */ /* clone packet for caller */
*packet = this->packet->clone(this->packet); *packet = this->packet->clone(this->packet);
this->logger->log(this->logger, CONTROL|LEVEL1, "message of type %s generated successfully", DBG2(SIG_DBG_ENC, "message generated successfully");
mapping_find(exchange_type_m,this->exchange_type));
return SUCCESS; return SUCCESS;
} }
@@ -781,14 +816,13 @@ static status_t parse_header(private_message_t *this)
ike_header_t *ike_header; ike_header_t *ike_header;
status_t status; status_t status;
DBG2(SIG_DBG_ENC, "parsing header of message");
this->logger->log(this->logger, CONTROL|LEVEL1, "parsing Header of message");
this->parser->reset_context(this->parser); this->parser->reset_context(this->parser);
status = this->parser->parse_payload(this->parser,HEADER,(payload_t **) &ike_header); status = this->parser->parse_payload(this->parser,HEADER,(payload_t **) &ike_header);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR | LEVEL1, "header could not be parsed"); DBG1(SIG_DBG_ENC, "header could not be parsed");
return status; return status;
} }
@@ -797,10 +831,10 @@ static status_t parse_header(private_message_t *this)
status = ike_header->payload_interface.verify(&(ike_header->payload_interface)); status = ike_header->payload_interface.verify(&(ike_header->payload_interface));
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR | LEVEL1, "header verification failed"); DBG1(SIG_DBG_ENC, "header verification failed");
ike_header->destroy(ike_header); ike_header->destroy(ike_header);
return status; return status;
} }
if (this->ike_sa_id != NULL) if (this->ike_sa_id != NULL)
{ {
@@ -818,190 +852,23 @@ static status_t parse_header(private_message_t *this)
this->minor_version = ike_header->get_min_version(ike_header); this->minor_version = ike_header->get_min_version(ike_header);
this->first_payload = ike_header->payload_interface.get_next_type(&(ike_header->payload_interface)); this->first_payload = ike_header->payload_interface.get_next_type(&(ike_header->payload_interface));
this->logger->log(this->logger, CONTROL|LEVEL1, "parsed a %s %s", DBG2(SIG_DBG_ENC, "parsed a %N %s", exchange_type_names, this->exchange_type,
mapping_find(exchange_type_m, this->exchange_type), this->is_request ? "request" : "response");
this->is_request ? "request" : "response");
ike_header->destroy(ike_header); ike_header->destroy(ike_header);
/* get the rules for this messge */ /* get the rules for this messge */
status = this->set_message_rule(this); status = set_message_rule(this);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "no message rules specified for a %s %s", DBG1(SIG_DBG_ENC, "no message rules specified for a %N %s",
mapping_find(exchange_type_m,this->exchange_type), exchange_type_names, this->exchange_type,
this->is_request ? "request" : "response"); this->is_request ? "request" : "response");
} }
return status; return status;
} }
/**
* Implementation of message_t.parse_body.
*/
static status_t parse_body(private_message_t *this, crypter_t *crypter, signer_t *signer)
{
status_t status = SUCCESS;
payload_type_t current_payload_type;
char payload_names[128];
current_payload_type = this->first_payload;
this->logger->log(this->logger, CONTROL|LEVEL1, "parsing body of message, first payload is %s",
mapping_find(payload_type_m, current_payload_type));
/* parse payload for payload, while there are more available */
while ((current_payload_type != NO_PAYLOAD))
{
payload_t *current_payload;
this->logger->log(this->logger, CONTROL|LEVEL2, "start parsing a %s payload",
mapping_find(payload_type_m, current_payload_type));
/* parse current payload */
status = this->parser->parse_payload(this->parser,current_payload_type,(payload_t **) &current_payload);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "payload type %s could not be parsed",
mapping_find(payload_type_m,current_payload_type));
return PARSE_ERROR;
}
this->logger->log(this->logger, CONTROL|LEVEL2, "verify payload of type %s",
mapping_find(payload_type_m, current_payload_type));
/* verify it, stop parsig if its invalid */
status = current_payload->verify(current_payload);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "%s payload verification failed",
mapping_find(payload_type_m,current_payload_type));
current_payload->destroy(current_payload);
return VERIFY_ERROR;
}
this->logger->log(this->logger, CONTROL|LEVEL2, "%s payload verified. Adding to payload list",
mapping_find(payload_type_m, current_payload_type));
this->payloads->insert_last(this->payloads,current_payload);
/* an encryption payload is the last one, so STOP here. decryption is done later */
if (current_payload_type == ENCRYPTED)
{
this->logger->log(this->logger, CONTROL|LEVEL2, "%s payload found. Stop parsing",
mapping_find(payload_type_m, current_payload_type));
break;
}
/* get next payload type */
current_payload_type = current_payload->get_next_type(current_payload);
}
if (current_payload_type == ENCRYPTED)
{
status = this->decrypt_payloads(this,crypter,signer);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "Could not decrypt payloads");
return status;
}
}
status = this->verify(this);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "verification of message failed");
return status;
}
build_payload_string(this, payload_names, sizeof(payload_names));
this->logger->log(this->logger, CONTROL, "parsed %s %s (%d) [%s]",
mapping_find(exchange_type_m, this->exchange_type),
this->is_request ? "request" : "response",
this->message_id,
payload_names);
return SUCCESS;
}
/**
* Implementation of private_message_t.verify.
*/
static status_t verify(private_message_t *this)
{
int i;
iterator_t *iterator;
size_t total_found_payloads = 0;
this->logger->log(this->logger, CONTROL|LEVEL1, "verifying message structure");
iterator = this->payloads->create_iterator(this->payloads,TRUE);
/* check for payloads with wrong count*/
for (i = 0; i < this->message_rule->payload_rule_count;i++)
{
size_t found_payloads = 0;
/* check all payloads for specific rule */
iterator->reset(iterator);
while(iterator->has_next(iterator))
{
payload_t *current_payload;
payload_type_t current_payload_type;
iterator->current(iterator,(void **)&current_payload);
current_payload_type = current_payload->get_type(current_payload);
if (current_payload_type == UNKNOWN_PAYLOAD)
{
/* unknown payloads are ignored, IF they are not critical */
unknown_payload_t *unknown_payload = (unknown_payload_t*)current_payload;
if (unknown_payload->is_critical(unknown_payload))
{
this->logger->log(this->logger, ERROR|LEVEL1, "%s (%d) is not supported, but its critical!",
mapping_find(payload_type_m, current_payload_type), current_payload_type);
iterator->destroy(iterator);
return NOT_SUPPORTED;
}
}
else if (current_payload_type == this->message_rule->payload_rules[i].payload_type)
{
found_payloads++;
total_found_payloads++;
this->logger->log(this->logger, CONTROL|LEVEL2, "found payload of type %s",
mapping_find(payload_type_m, this->message_rule->payload_rules[i].payload_type));
/* as soon as ohe payload occures more then specified, the verification fails */
if (found_payloads > this->message_rule->payload_rules[i].max_occurence)
{
this->logger->log(this->logger, ERROR|LEVEL1, "payload of type %s more than %d times (%d) occured in current message",
mapping_find(payload_type_m, current_payload_type),
this->message_rule->payload_rules[i].max_occurence, found_payloads);
iterator->destroy(iterator);
return VERIFY_ERROR;
}
}
}
if (found_payloads < this->message_rule->payload_rules[i].min_occurence)
{
this->logger->log(this->logger, ERROR|LEVEL1, "payload of type %s not occured %d times (%d)",
mapping_find(payload_type_m, this->message_rule->payload_rules[i].payload_type),
this->message_rule->payload_rules[i].min_occurence, found_payloads);
iterator->destroy(iterator);
return VERIFY_ERROR;
}
if ((this->message_rule->payload_rules[i].sufficient) && (this->payloads->get_count(this->payloads) == total_found_payloads))
{
iterator->destroy(iterator);
return SUCCESS;
}
}
iterator->destroy(iterator);
return SUCCESS;
}
/** /**
* Implementation of private_message_t.decrypt_and_verify_payloads. * Implementation of private_message_t.decrypt_and_verify_payloads.
*/ */
@@ -1028,8 +895,8 @@ static status_t decrypt_payloads(private_message_t *this,crypter_t *crypter, sig
/* needed to check */ /* needed to check */
current_payload_type = current_payload->get_type(current_payload); current_payload_type = current_payload->get_type(current_payload);
this->logger->log(this->logger, CONTROL|LEVEL2, "process payload of type %s", DBG2(SIG_DBG_ENC, "process payload of type %N",
mapping_find(payload_type_m,current_payload_type)); payload_type_names, current_payload_type);
if (current_payload_type == ENCRYPTED) if (current_payload_type == ENCRYPTED)
{ {
@@ -1038,31 +905,31 @@ static status_t decrypt_payloads(private_message_t *this,crypter_t *crypter, sig
encryption_payload = (encryption_payload_t*)current_payload; encryption_payload = (encryption_payload_t*)current_payload;
this->logger->log(this->logger, CONTROL | LEVEL2, "found an encryption payload"); DBG2(SIG_DBG_ENC, "found an encryption payload");
if (payload_number != this->payloads->get_count(this->payloads)) if (payload_number != this->payloads->get_count(this->payloads))
{ {
/* encrypted payload is not last one */ /* encrypted payload is not last one */
this->logger->log(this->logger, ERROR, "encrypted payload is not last payload"); DBG1(SIG_DBG_ENC, "encrypted payload is not last payload");
iterator->destroy(iterator); iterator->destroy(iterator);
return VERIFY_ERROR; return VERIFY_ERROR;
} }
/* decrypt */ /* decrypt */
encryption_payload->set_transforms(encryption_payload, crypter, signer); encryption_payload->set_transforms(encryption_payload, crypter, signer);
this->logger->log(this->logger, CONTROL | LEVEL1, "verify signature of encryption payload"); DBG2(SIG_DBG_ENC, "verify signature of encryption payload");
status = encryption_payload->verify_signature(encryption_payload, this->packet->get_data(this->packet)); status = encryption_payload->verify_signature(encryption_payload,
this->packet->get_data(this->packet));
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "encryption payload signature invalid"); DBG1(SIG_DBG_ENC, "encryption payload signature invalid");
iterator->destroy(iterator); iterator->destroy(iterator);
return FAILED; return FAILED;
} }
this->logger->log(this->logger, CONTROL | LEVEL2, "decrypt content of encryption payload"); DBG2(SIG_DBG_ENC, "decrypting content of encryption payload");
status = encryption_payload->decrypt(encryption_payload); status = encryption_payload->decrypt(encryption_payload);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_ENC, "encrypted payload could not be decrypted and parsed");
"encrypted payload could not be decrypted and parsed");
iterator->destroy(iterator); iterator->destroy(iterator);
return PARSE_ERROR; return PARSE_ERROR;
} }
@@ -1073,7 +940,7 @@ static status_t decrypt_payloads(private_message_t *this,crypter_t *crypter, sig
/* check if there are payloads contained in the encryption payload */ /* check if there are payloads contained in the encryption payload */
if (encryption_payload->get_payload_count(encryption_payload) == 0) if (encryption_payload->get_payload_count(encryption_payload) == 0)
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, "encrypted payload is empty"); DBG2(SIG_DBG_ENC, "encrypted payload is empty");
/* remove the encryption payload, is not needed anymore */ /* remove the encryption payload, is not needed anymore */
iterator->remove(iterator); iterator->remove(iterator);
/* encrypted payload contains no other payload */ /* encrypted payload contains no other payload */
@@ -1103,9 +970,8 @@ static status_t decrypt_payloads(private_message_t *this,crypter_t *crypter, sig
while (encryption_payload->get_payload_count(encryption_payload) > 0) while (encryption_payload->get_payload_count(encryption_payload) > 0)
{ {
encryption_payload->remove_first_payload(encryption_payload, &current_encrypted_payload); encryption_payload->remove_first_payload(encryption_payload, &current_encrypted_payload);
this->logger->log(this->logger, CONTROL | LEVEL1, DBG2(SIG_DBG_ENC, "insert unencrypted payload of type %N at end of list",
"insert unencrypted payload of type %s at end of list.", payload_type_names, current_encrypted_payload->get_type(current_encrypted_payload));
mapping_find(payload_type_m, current_encrypted_payload->get_type(current_encrypted_payload)));
this->payloads->insert_last(this->payloads,current_encrypted_payload); this->payloads->insert_last(this->payloads,current_encrypted_payload);
} }
@@ -1117,12 +983,12 @@ static status_t decrypt_payloads(private_message_t *this,crypter_t *crypter, sig
if (current_payload_type != UNKNOWN_PAYLOAD && current_payload_type != NO_PAYLOAD) if (current_payload_type != UNKNOWN_PAYLOAD && current_payload_type != NO_PAYLOAD)
{ {
/* get the ruleset for found payload */ /* get the ruleset for found payload */
status = this->get_payload_rule(this, current_payload_type, &payload_rule); status = get_payload_rule(this, current_payload_type, &payload_rule);
if (status != SUCCESS) if (status != SUCCESS)
{ {
/* payload is not allowed */ /* payload is not allowed */
this->logger->log(this->logger, ERROR, "payload type %s not allowed", DBG1(SIG_DBG_ENC, "payload type %N not allowed",
mapping_find(payload_type_m,current_payload_type)); payload_type_names, current_payload_type);
iterator->destroy(iterator); iterator->destroy(iterator);
return VERIFY_ERROR; return VERIFY_ERROR;
} }
@@ -1131,9 +997,9 @@ static status_t decrypt_payloads(private_message_t *this,crypter_t *crypter, sig
if (payload_rule->encrypted != current_payload_was_encrypted) if (payload_rule->encrypted != current_payload_was_encrypted)
{ {
/* payload was not encrypted, but should have been. or vice-versa */ /* payload was not encrypted, but should have been. or vice-versa */
this->logger->log(this->logger, ERROR, "payload type %s should be %s!", DBG1(SIG_DBG_ENC, "payload type %N should be %s!",
mapping_find(payload_type_m,current_payload_type), payload_type_names, current_payload_type,
(payload_rule->encrypted) ? "encrypted" : "not encrypted"); (payload_rule->encrypted) ? "encrypted" : "not encrypted");
iterator->destroy(iterator); iterator->destroy(iterator);
return VERIFY_ERROR; return VERIFY_ERROR;
} }
@@ -1148,89 +1014,163 @@ static status_t decrypt_payloads(private_message_t *this,crypter_t *crypter, sig
} }
/** /**
* Implementation of private_message_t.encrypt_payloads. * Implementation of private_message_t.verify.
*/ */
static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, signer_t* signer) static status_t verify(private_message_t *this)
{ {
encryption_payload_t *encryption_payload = NULL; int i;
status_t status; iterator_t *iterator;
linked_list_t *all_payloads; size_t total_found_payloads = 0;
if (!this->message_rule->encrypted_content) DBG2(SIG_DBG_ENC, "verifying message structure");
iterator = this->payloads->create_iterator(this->payloads,TRUE);
/* check for payloads with wrong count*/
for (i = 0; i < this->message_rule->payload_rule_count;i++)
{ {
this->logger->log(this->logger, CONTROL | LEVEL1, "message doesn't have to be encrypted"); size_t found_payloads = 0;
/* message contains no content to encrypt */
return SUCCESS;
}
this->logger->log(this->logger, CONTROL | LEVEL2, "copy all payloads to a temporary list"); /* check all payloads for specific rule */
all_payloads = linked_list_create(); iterator->reset(iterator);
/* first copy all payloads in a temporary list */
while (this->payloads->get_count(this->payloads) > 0)
{
void *current_payload;
this->payloads->remove_first(this->payloads,&current_payload);
all_payloads->insert_last(all_payloads,current_payload);
}
encryption_payload = encryption_payload_create();
this->logger->log(this->logger, CONTROL | LEVEL2, "check each payloads if they have to get encrypted");
while (all_payloads->get_count(all_payloads) > 0)
{
payload_rule_t *payload_rule;
payload_t *current_payload;
bool to_encrypt = FALSE;
all_payloads->remove_first(all_payloads,(void **)&current_payload); while(iterator->has_next(iterator))
this->logger->log(this->logger, CONTROL | LEVEL3, "get rule for payload %s",
mapping_find(payload_type_m,current_payload->get_type(current_payload)));
status = this->get_payload_rule(this,current_payload->get_type(current_payload),&payload_rule);
/* for payload types which are not found in supported payload list, it is presumed
* that they don't have to be encrypted */
if ((status == SUCCESS) && (payload_rule->encrypted))
{ {
this->logger->log(this->logger, CONTROL | LEVEL2, "payload %s has to get encrypted", payload_t *current_payload;
mapping_find(payload_type_m,current_payload->get_type(current_payload))); payload_type_t current_payload_type;
to_encrypt = TRUE;
} iterator->current(iterator,(void **)&current_payload);
else if (status != SUCCESS) current_payload_type = current_payload->get_type(current_payload);
{
this->logger->log(this->logger, CONTROL | LEVEL2, "payload %s not defined for exchange type %s. Handle it anyway", if (current_payload_type == UNKNOWN_PAYLOAD)
mapping_find(payload_type_m,current_payload->get_type(current_payload)), {
mapping_find(exchange_type_m,this->exchange_type)); /* unknown payloads are ignored, IF they are not critical */
unknown_payload_t *unknown_payload = (unknown_payload_t*)current_payload;
if (unknown_payload->is_critical(unknown_payload))
{
DBG1(SIG_DBG_ENC, "%N is not supported, but its critical!",
payload_type_names, current_payload_type);
iterator->destroy(iterator);
return NOT_SUPPORTED;
}
}
else if (current_payload_type == this->message_rule->payload_rules[i].payload_type)
{
found_payloads++;
total_found_payloads++;
DBG2(SIG_DBG_ENC, "found payload of type %N",
payload_type_names, this->message_rule->payload_rules[i].payload_type);
/* as soon as ohe payload occures more then specified, the verification fails */
if (found_payloads > this->message_rule->payload_rules[i].max_occurence)
{
DBG1(SIG_DBG_ENC, "payload of type %N more than %d times (%d) occured in current message",
payload_type_names, current_payload_type,
this->message_rule->payload_rules[i].max_occurence, found_payloads);
iterator->destroy(iterator);
return VERIFY_ERROR;
}
}
} }
if (to_encrypt) if (found_payloads < this->message_rule->payload_rules[i].min_occurence)
{ {
this->logger->log(this->logger, CONTROL | LEVEL2, "insert payload %s to encryption payload", DBG1(SIG_DBG_ENC, "payload of type %N not occured %d times (%d)",
mapping_find(payload_type_m,current_payload->get_type(current_payload))); payload_type_names, this->message_rule->payload_rules[i].payload_type,
this->message_rule->payload_rules[i].min_occurence, found_payloads);
encryption_payload->add_payload(encryption_payload,current_payload); iterator->destroy(iterator);
return VERIFY_ERROR;
} }
else if ((this->message_rule->payload_rules[i].sufficient) && (this->payloads->get_count(this->payloads) == total_found_payloads))
{ {
this->logger->log(this->logger, CONTROL | LEVEL2, "insert payload %s as payload wich does not have to be encrypted", iterator->destroy(iterator);
mapping_find(payload_type_m,current_payload->get_type(current_payload))); return SUCCESS;
this->public.add_payload(&(this->public), (payload_t*)encryption_payload);
} }
} }
iterator->destroy(iterator);
status = SUCCESS; return SUCCESS;
this->logger->log(this->logger, CONTROL | LEVEL2, "set transforms for encryption payload ");
encryption_payload->set_transforms(encryption_payload,crypter,signer);
this->logger->log(this->logger, CONTROL | LEVEL1, "encrypt all payloads of encrypted payload");
status = encryption_payload->encrypt(encryption_payload);
this->logger->log(this->logger, CONTROL | LEVEL2, "add encrypted payload to payload list");
this->public.add_payload(&(this->public), (payload_t*)encryption_payload);
all_payloads->destroy(all_payloads);
return status;
} }
/**
* Implementation of message_t.parse_body.
*/
static status_t parse_body(private_message_t *this, crypter_t *crypter, signer_t *signer)
{
status_t status = SUCCESS;
payload_type_t current_payload_type;
current_payload_type = this->first_payload;
DBG2(SIG_DBG_ENC, "parsing body of message, first payload is %N",
payload_type_names, current_payload_type);
/* parse payload for payload, while there are more available */
while ((current_payload_type != NO_PAYLOAD))
{
payload_t *current_payload;
DBG2(SIG_DBG_ENC, "starting parsing a %N payload",
payload_type_names, current_payload_type);
/* parse current payload */
status = this->parser->parse_payload(this->parser,current_payload_type,(payload_t **) &current_payload);
if (status != SUCCESS)
{
DBG1(SIG_DBG_ENC, "payload type %N could not be parsed",
payload_type_names, current_payload_type);
return PARSE_ERROR;
}
DBG2(SIG_DBG_ENC, "verifying payload of type %N",
payload_type_names, current_payload_type);
/* verify it, stop parsig if its invalid */
status = current_payload->verify(current_payload);
if (status != SUCCESS)
{
DBG1(SIG_DBG_ENC, "%N payload verification failed",
payload_type_names, current_payload_type);
current_payload->destroy(current_payload);
return VERIFY_ERROR;
}
DBG2(SIG_DBG_ENC, "%N payload verified. Adding to payload list",
payload_type_names, current_payload_type);
this->payloads->insert_last(this->payloads,current_payload);
/* an encryption payload is the last one, so STOP here. decryption is done later */
if (current_payload_type == ENCRYPTED)
{
DBG2(SIG_DBG_ENC, "%N payload found. Stop parsing",
payload_type_names, current_payload_type);
break;
}
/* get next payload type */
current_payload_type = current_payload->get_next_type(current_payload);
}
if (current_payload_type == ENCRYPTED)
{
status = decrypt_payloads(this,crypter,signer);
if (status != SUCCESS)
{
DBG1(SIG_DBG_ENC, "could not decrypt payloads");
return status;
}
}
status = verify(this);
if (status != SUCCESS)
{
DBG1(SIG_DBG_ENC, "verification of message failed");
return status;
}
DBG1(SIG_DBG_ENC, "parsed %M", this);
return SUCCESS;
}
/** /**
* Implementation of message_t.destroy. * Implementation of message_t.destroy.
@@ -1297,18 +1237,11 @@ message_t *message_create_from_packet(packet_t *packet)
/* private values */ /* private values */
this->exchange_type = EXCHANGE_TYPE_UNDEFINED; this->exchange_type = EXCHANGE_TYPE_UNDEFINED;
this->is_request = TRUE; this->is_request = TRUE;
this->ike_sa_id = NULL; this->ike_sa_id = NULL;
this->first_payload = NO_PAYLOAD; this->first_payload = NO_PAYLOAD;
this->message_id = 0; this->message_id = 0;
/* private functions */
this->set_message_rule = set_message_rule;
this->get_payload_rule = get_payload_rule;
this->encrypt_payloads = encrypt_payloads;
this->decrypt_payloads = decrypt_payloads;
this->verify = verify;
/* private values */ /* private values */
if (packet == NULL) if (packet == NULL)
{ {
@@ -1319,10 +1252,8 @@ message_t *message_create_from_packet(packet_t *packet)
this->payloads = linked_list_create(); this->payloads = linked_list_create();
/* parser is created from data of packet */ /* parser is created from data of packet */
this->parser = parser_create(this->packet->get_data(this->packet)); this->parser = parser_create(this->packet->get_data(this->packet));
this->logger = logger_manager->get_logger(logger_manager, MESSAGE);
return (&this->public); return (&this->public);
} }
+5
View File
@@ -34,6 +34,11 @@
#include <crypto/crypters/crypter.h> #include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h> #include <crypto/signers/signer.h>
/**
* printf() specifier for message
*/
#define MESSAGE_PRINTF_SPEC 'M'
typedef struct message_t message_t; typedef struct message_t message_t;
+67 -84
View File
@@ -30,7 +30,6 @@
#include <types.h> #include <types.h>
#include <definitions.h> #include <definitions.h>
#include <daemon.h> #include <daemon.h>
#include <utils/logger.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <encoding/payloads/encodings.h> #include <encoding/payloads/encodings.h>
#include <encoding/payloads/payload.h> #include <encoding/payloads/payload.h>
@@ -233,11 +232,6 @@ struct private_parser_t {
* Set of encoding rules for this parsing session. * Set of encoding rules for this parsing session.
*/ */
encoding_rule_t *rules; encoding_rule_t *rules;
/**
* Assigned logger_t object.
*/
logger_t *logger;
}; };
/** /**
@@ -247,9 +241,8 @@ static status_t parse_uint4(private_parser_t *this, int rule_number, u_int8_t *o
{ {
if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s", DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, mapping_find(encoding_type_m, rule_number, encoding_type_names, this->rules[rule_number].type);
this->rules[rule_number].type));
return PARSE_ERROR; return PARSE_ERROR;
} }
switch (this->bit_pos) switch (this->bit_pos)
@@ -272,15 +265,15 @@ static status_t parse_uint4(private_parser_t *this, int rule_number, u_int8_t *o
this->byte_pos++; this->byte_pos++;
break; break;
default: default:
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", DBG2(SIG_DBG_ENC, " found rule %d %N on bitpos %d",
rule_number, mapping_find(encoding_type_m, rule_number, encoding_type_names,
this->rules[rule_number].type), this->bit_pos); this->rules[rule_number].type, this->bit_pos);
return PARSE_ERROR; return PARSE_ERROR;
} }
if (output_pos != NULL) if (output_pos != NULL)
{ {
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *output_pos); DBG3(SIG_DBG_ENC, " => %d", *output_pos);
} }
return SUCCESS; return SUCCESS;
@@ -293,16 +286,15 @@ static status_t parse_uint8(private_parser_t *this, int rule_number, u_int8_t *o
{ {
if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s", DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, mapping_find(encoding_type_m, rule_number, encoding_type_names, this->rules[rule_number].type);
this->rules[rule_number].type));
return PARSE_ERROR; return PARSE_ERROR;
} }
if (this->bit_pos) if (this->bit_pos)
{ {
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d",
rule_number, mapping_find(encoding_type_m, rule_number, encoding_type_names,
this->rules[rule_number].type), this->bit_pos); this->rules[rule_number].type, this->bit_pos);
return PARSE_ERROR; return PARSE_ERROR;
} }
@@ -310,7 +302,7 @@ static status_t parse_uint8(private_parser_t *this, int rule_number, u_int8_t *o
if (output_pos != NULL) if (output_pos != NULL)
{ {
*output_pos = *(this->byte_pos); *output_pos = *(this->byte_pos);
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *output_pos); DBG3(SIG_DBG_ENC, " => %d", *output_pos);
} }
this->byte_pos++; this->byte_pos++;
@@ -324,23 +316,21 @@ static status_t parse_uint15(private_parser_t *this, int rule_number, u_int16_t
{ {
if (this->byte_pos + sizeof(u_int16_t) > this->input_roof) if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s", DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, mapping_find(encoding_type_m, rule_number, encoding_type_names, this->rules[rule_number].type);
this->rules[rule_number].type));
return PARSE_ERROR; return PARSE_ERROR;
} }
if (this->bit_pos != 1) if (this->bit_pos != 1)
{ {
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", DBG2(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), encoding_type_names, this->rules[rule_number].type, this->bit_pos);
this->bit_pos);
return PARSE_ERROR; return PARSE_ERROR;
} }
/* caller interested in result ? */ /* caller interested in result ? */
if (output_pos != NULL) if (output_pos != NULL)
{ {
*output_pos = ntohs(*((u_int16_t*)this->byte_pos)) & ~0x8000; *output_pos = ntohs(*((u_int16_t*)this->byte_pos)) & ~0x8000;
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *output_pos); DBG3(SIG_DBG_ENC, " => %d", *output_pos);
} }
this->byte_pos += 2; this->byte_pos += 2;
this->bit_pos = 0; this->bit_pos = 0;
@@ -355,15 +345,14 @@ static status_t parse_uint16(private_parser_t *this, int rule_number, u_int16_t
{ {
if (this->byte_pos + sizeof(u_int16_t) > this->input_roof) if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s", DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type)); rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR; return PARSE_ERROR;
} }
if (this->bit_pos) if (this->bit_pos)
{ {
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), encoding_type_names, this->rules[rule_number].type, this->bit_pos);
this->bit_pos);
return PARSE_ERROR; return PARSE_ERROR;
} }
/* caller interested in result ? */ /* caller interested in result ? */
@@ -371,7 +360,7 @@ static status_t parse_uint16(private_parser_t *this, int rule_number, u_int16_t
{ {
*output_pos = ntohs(*((u_int16_t*)this->byte_pos)); *output_pos = ntohs(*((u_int16_t*)this->byte_pos));
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *output_pos); DBG3(SIG_DBG_ENC, " => %d", *output_pos);
} }
this->byte_pos += 2; this->byte_pos += 2;
@@ -384,15 +373,14 @@ static status_t parse_uint32(private_parser_t *this, int rule_number, u_int32_t
{ {
if (this->byte_pos + sizeof(u_int32_t) > this->input_roof) if (this->byte_pos + sizeof(u_int32_t) > this->input_roof)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s", DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type)); rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR; return PARSE_ERROR;
} }
if (this->bit_pos) if (this->bit_pos)
{ {
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), encoding_type_names, this->rules[rule_number].type, this->bit_pos);
this->bit_pos);
return PARSE_ERROR; return PARSE_ERROR;
} }
/* caller interested in result ? */ /* caller interested in result ? */
@@ -400,7 +388,7 @@ static status_t parse_uint32(private_parser_t *this, int rule_number, u_int32_t
{ {
*output_pos = ntohl(*((u_int32_t*)this->byte_pos)); *output_pos = ntohl(*((u_int32_t*)this->byte_pos));
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *output_pos); DBG3(SIG_DBG_ENC, " => %d", *output_pos);
} }
this->byte_pos += 4; this->byte_pos += 4;
@@ -414,15 +402,14 @@ static status_t parse_uint64(private_parser_t *this, int rule_number, u_int64_t
{ {
if (this->byte_pos + sizeof(u_int64_t) > this->input_roof) if (this->byte_pos + sizeof(u_int64_t) > this->input_roof)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s", DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type)); rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR; return PARSE_ERROR;
} }
if (this->bit_pos) if (this->bit_pos)
{ {
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), encoding_type_names, this->rules[rule_number].type, this->bit_pos);
this->bit_pos);
return PARSE_ERROR; return PARSE_ERROR;
} }
/* caller interested in result ? */ /* caller interested in result ? */
@@ -432,7 +419,7 @@ static status_t parse_uint64(private_parser_t *this, int rule_number, u_int64_t
*(output_pos + 1) = ntohl(*((u_int32_t*)this->byte_pos)); *(output_pos + 1) = ntohl(*((u_int32_t*)this->byte_pos));
*output_pos = ntohl(*(((u_int32_t*)this->byte_pos) + 1)); *output_pos = ntohl(*(((u_int32_t*)this->byte_pos) + 1));
this->logger->log_bytes(this->logger, RAW|LEVEL2, " =>", (void*)output_pos, 8); DBG3(SIG_DBG_ENC, " => %b", (void*)output_pos, sizeof(u_int64_t));
} }
this->byte_pos += 8; this->byte_pos += 8;
@@ -446,15 +433,14 @@ static status_t parse_bytes (private_parser_t *this, int rule_number, u_int8_t *
{ {
if (this->byte_pos + bytes > this->input_roof) if (this->byte_pos + bytes > this->input_roof)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s", DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type)); rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR; return PARSE_ERROR;
} }
if (this->bit_pos) if (this->bit_pos)
{ {
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), encoding_type_names, this->rules[rule_number].type, this->bit_pos);
this->bit_pos);
return PARSE_ERROR; return PARSE_ERROR;
} }
@@ -463,7 +449,7 @@ static status_t parse_bytes (private_parser_t *this, int rule_number, u_int8_t *
{ {
memcpy(output_pos,this->byte_pos,bytes); memcpy(output_pos,this->byte_pos,bytes);
this->logger->log_bytes(this->logger, RAW|LEVEL2, " =>", (void*)output_pos, bytes); DBG3(SIG_DBG_ENC, " => %b", (void*)output_pos, bytes);
} }
this->byte_pos += bytes; this->byte_pos += bytes;
@@ -477,8 +463,8 @@ static status_t parse_bit(private_parser_t *this, int rule_number, bool *output_
{ {
if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s", DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type)); rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR; return PARSE_ERROR;
} }
/* caller interested in result ? */ /* caller interested in result ? */
@@ -494,7 +480,7 @@ static status_t parse_bit(private_parser_t *this, int rule_number, bool *output_
*output_pos = TRUE; *output_pos = TRUE;
} }
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *output_pos); DBG3(SIG_DBG_ENC, " => %d", *output_pos);
} }
this->bit_pos = (this->bit_pos + 1) % 8; this->bit_pos = (this->bit_pos + 1) % 8;
if (this->bit_pos == 0) if (this->bit_pos == 0)
@@ -514,15 +500,15 @@ static status_t parse_list(private_parser_t *this, int rule_number, linked_list_
if (length < 0) if (length < 0)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, " invalid length for rule %d %s", DBG1(SIG_DBG_ENC, " invalid length for rule %d %N",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type)); rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR; return PARSE_ERROR;
} }
if (this->bit_pos) if (this->bit_pos)
{ {
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), this->bit_pos); encoding_type_names, this->rules[rule_number].type, this->bit_pos);
return PARSE_ERROR; return PARSE_ERROR;
} }
@@ -531,13 +517,13 @@ static status_t parse_list(private_parser_t *this, int rule_number, linked_list_
u_int8_t *pos_before = this->byte_pos; u_int8_t *pos_before = this->byte_pos;
payload_t *payload; payload_t *payload;
status_t status; status_t status;
this->logger->log(this->logger, CONTROL|LEVEL1, " %d bytes left, parsing recursivly %s", DBG2(SIG_DBG_ENC, " %d bytes left, parsing recursivly %N",
length, mapping_find(payload_type_m, payload_type)); length, payload_type_names, payload_type);
status = this->public.parse_payload((parser_t*)this, payload_type, &payload); status = this->public.parse_payload((parser_t*)this, payload_type, &payload);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, " parsing of a %s substructure failed", DBG1(SIG_DBG_ENC, " parsing of a %N substructure failed",
mapping_find(payload_type_m, payload_type)); payload_type_names, payload_type);
return status; return status;
} }
list->insert_last(list, payload); list->insert_last(list, payload);
@@ -554,14 +540,14 @@ static status_t parse_chunk(private_parser_t *this, int rule_number, chunk_t *ou
{ {
if (this->byte_pos + length > this->input_roof) if (this->byte_pos + length > this->input_roof)
{ {
this->logger->log(this->logger, ERROR, " not enough input (%d bytes) to parse rule %d %s", DBG1(SIG_DBG_ENC, " not enough input (%d bytes) to parse rule %d %N",
length, rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type)); length, rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR; return PARSE_ERROR;
} }
if (this->bit_pos) if (this->bit_pos)
{ {
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), this->bit_pos); encoding_type_names, this->rules[rule_number].type, this->bit_pos);
return PARSE_ERROR; return PARSE_ERROR;
} }
if (output_pos != NULL) if (output_pos != NULL)
@@ -571,7 +557,7 @@ static status_t parse_chunk(private_parser_t *this, int rule_number, chunk_t *ou
memcpy(output_pos->ptr, this->byte_pos, length); memcpy(output_pos->ptr, this->byte_pos, length);
} }
this->byte_pos += length; this->byte_pos += length;
this->logger->log_bytes(this->logger, RAW|LEVEL2, " =>", (void*)output_pos->ptr, length); DBG3(SIG_DBG_ENC, " => %b", (void*)output_pos->ptr, length);
return SUCCESS; return SUCCESS;
} }
@@ -592,17 +578,16 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
/* create instance of the payload to parse */ /* create instance of the payload to parse */
pld = payload_create(payload_type); pld = payload_create(payload_type);
this->logger->log(this->logger, CONTROL|LEVEL1, "parsing %s payload, %d bytes left", DBG2(SIG_DBG_ENC, "parsing %N payload, %d bytes left",
mapping_find(payload_type_m, payload_type), payload_type_names, payload_type, this->input_roof - this->byte_pos);
this->input_roof-this->byte_pos);
this->logger->log_bytes(this->logger, RAW|LEVEL3, "parsing payload from", this->byte_pos, DBG3(SIG_DBG_ENC, "parsing payload from %b",
this->input_roof-this->byte_pos); this->byte_pos, this->input_roof-this->byte_pos);
if (pld->get_type(pld) == UNKNOWN_PAYLOAD) if (pld->get_type(pld) == UNKNOWN_PAYLOAD)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, " payload type %d is unknown, handling as %s", DBG1(SIG_DBG_ENC, " payload type %d is unknown, handling as %N",
payload_type, mapping_find(payload_type_m, UNKNOWN_PAYLOAD)); payload_type, payload_type_names, UNKNOWN_PAYLOAD);
} }
/* base pointer for output, avoids casting in every rule */ /* base pointer for output, avoids casting in every rule */
@@ -613,8 +598,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
for (rule_number = 0; rule_number < rule_count; rule_number++) for (rule_number = 0; rule_number < rule_count; rule_number++)
{ {
rule = &(this->rules[rule_number]); rule = &(this->rules[rule_number]);
this->logger->log(this->logger, CONTROL|LEVEL2, " parsing rule %d %s", DBG2(SIG_DBG_ENC, " parsing rule %d %N",
rule_number, mapping_find(encoding_type_m, rule->type)); rule_number, encoding_type_names, rule->type);
switch (rule->type) switch (rule->type)
{ {
case U_INT_4: case U_INT_4:
@@ -990,7 +975,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
} }
default: default:
{ {
this->logger->log(this->logger, ERROR, " no rule to parse rule %d %s (%d)", rule_number, mapping_find(encoding_type_m, rule->type), rule->type); DBG1(SIG_DBG_ENC, " no rule to parse rule %d %N",
rule_number, encoding_type_names, rule->type);
pld->destroy(pld); pld->destroy(pld);
return PARSE_ERROR; return PARSE_ERROR;
} }
@@ -999,9 +985,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
rule++; rule++;
} }
*payload = pld; *payload = pld;
this->logger->log(this->logger, CONTROL|LEVEL2, "parsing %s payload finished.", DBG2(SIG_DBG_ENC, "parsing %N payload finished",
mapping_find(payload_type_m, payload_type)); payload_type_names, payload_type);
return SUCCESS; return SUCCESS;
} }
@@ -1038,8 +1024,6 @@ parser_t *parser_create(chunk_t data)
{ {
private_parser_t *this = malloc_thing(private_parser_t); private_parser_t *this = malloc_thing(private_parser_t);
this->logger = logger_manager->get_logger(logger_manager, PARSER);
this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**)) parse_payload; this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**)) parse_payload;
this->public.reset_context = (void(*)(parser_t*)) reset_context; this->public.reset_context = (void(*)(parser_t*)) reset_context;
this->public.get_remaining_byte_count = (int (*) (parser_t *))get_remaining_byte_count; this->public.get_remaining_byte_count = (int (*) (parser_t *))get_remaining_byte_count;
@@ -1055,7 +1039,7 @@ parser_t *parser_create(chunk_t data)
this->parse_bit = parse_bit; this->parse_bit = parse_bit;
this->parse_list = parse_list; this->parse_list = parse_list;
this->parse_chunk = parse_chunk; this->parse_chunk = parse_chunk;
this->input = data.ptr; this->input = data.ptr;
this->byte_pos = data.ptr; this->byte_pos = data.ptr;
this->bit_pos = 0; this->bit_pos = 0;
@@ -1063,4 +1047,3 @@ parser_t *parser_create(chunk_t data)
return (parser_t*)this; return (parser_t*)this;
} }
+3 -9
View File
@@ -26,10 +26,7 @@
#include "cert_payload.h" #include "cert_payload.h"
/** ENUM(cert_encoding_names, CERT_NONE, CERT_X509_HASH_AND_URL_BUNDLE,
* String mappings for cert_encoding_t.
*/
static const char *const cert_encoding_name[] = {
"CERT_NONE", "CERT_NONE",
"CERT_PKCS7_WRAPPED_X509", "CERT_PKCS7_WRAPPED_X509",
"CERT_PGP", "CERT_PGP",
@@ -43,11 +40,8 @@ static const char *const cert_encoding_name[] = {
"CERT_X509_ATTRIBUTE", "CERT_X509_ATTRIBUTE",
"CERT_RAW_RSA_KEY", "CERT_RAW_RSA_KEY",
"CERT_X509_HASH_AND_URL", "CERT_X509_HASH_AND_URL",
"CERT_X509_HASH_AND_URL_BUNDLE" "CERT_X509_HASH_AND_URL_BUNDLE",
}; );
enum_names cert_encoding_names =
{ CERT_NONE, CERT_X509_HASH_AND_URL_BUNDLE, cert_encoding_name, NULL };
typedef struct private_cert_payload_t private_cert_payload_t; typedef struct private_cert_payload_t private_cert_payload_t;
+1 -1
View File
@@ -64,7 +64,7 @@ enum cert_encoding_t {
* *
* @ingroup payloads * @ingroup payloads
*/ */
extern enum_names cert_encoding_names; extern enum_name_t *cert_encoding_names;
typedef struct cert_payload_t cert_payload_t; typedef struct cert_payload_t cert_payload_t;
@@ -58,27 +58,23 @@ struct private_configuration_attribute_t {
chunk_t attribute_value; chunk_t attribute_value;
}; };
/** ENUM_BEGIN(configuration_attribute_type_name, INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS,
* String mappings for configuration_attribute_type_t. "INTERNAL_IP4_ADDRESS",
*/ "INTERNAL_IP4_NETMASK",
mapping_t configuration_attribute_type_m[] = { "INTERNAL_IP4_DNS",
{INTERNAL_IP4_ADDRESS, "INTERNAL_IP4_ADDRESS"}, "INTERNAL_IP4_NBNS",
{INTERNAL_IP4_NETMASK, "INTERNAL_IP4_NETMASK"}, "INTERNAL_ADDRESS_EXPIRY",
{INTERNAL_IP4_DNS, "INTERNAL_IP4_DNS"}, "INTERNAL_IP4_DHCP",
{INTERNAL_IP4_NBNS, "INTERNAL_IP4_NBNS"}, "APPLICATION_VERSION",
{INTERNAL_ADDRESS_EXPIRY, "INTERNAL_ADDRESS_EXPIRY"}, "INTERNAL_IP6_ADDRESS");
{INTERNAL_IP4_DHCP, "INTERNAL_IP4_DHCP"}, ENUM_NEXT(configuration_attribute_type_name, INTERNAL_IP6_DNS, INTERNAL_IP6_SUBNET, INTERNAL_IP6_ADDRESS,
{APPLICATION_VERSION, "APPLICATION_VERSION"}, "INTERNAL_IP6_DNS",
{INTERNAL_IP6_ADDRESS, "INTERNAL_IP6_ADDRESS"}, "INTERNAL_IP6_NBNS",
{INTERNAL_IP6_DNS, "INTERNAL_IP6_DNS"}, "INTERNAL_IP6_DHCP",
{INTERNAL_IP6_NBNS, "INTERNAL_IP6_NBNS"}, "INTERNAL_IP4_SUBNET",
{INTERNAL_IP6_DHCP, "INTERNAL_IP6_DHCP"}, "SUPPORTED_ATTRIBUTES",
{INTERNAL_IP4_SUBNET, "INTERNAL_IP4_SUBNET"}, "INTERNAL_IP6_SUBNET");
{SUPPORTED_ATTRIBUTES, "SUPPORTED_ATTRIBUTES"}, ENUM_END(configuration_attribute_type_name, INTERNAL_IP6_SUBNET);
{INTERNAL_IP6_SUBNET, "INTERNAL_IP6_SUBNET"},
{MAPPING_END, NULL}
};
/** /**
* Encoding rules to parse or generate a configuration attribute. * Encoding rules to parse or generate a configuration attribute.
@@ -62,11 +62,11 @@ enum configuration_attribute_type_t {
}; };
/** /**
* String mappings for configuration_attribute_type_t. * enum names for configuration_attribute_type_t.
* *
* @ingroup payloads * @ingroup payloads
*/ */
extern mapping_t configuration_attribute_type_m[]; extern enum_name_t *configuration_attribute_type_names;
typedef struct configuration_attribute_t configuration_attribute_t; typedef struct configuration_attribute_t configuration_attribute_t;
+27 -44
View File
@@ -28,18 +28,12 @@
#include <encoding/payloads/encodings.h> #include <encoding/payloads/encodings.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
ENUM(config_type_names, CFG_REQUEST, CFG_ACK,
/** "CFG_REQUEST",
* String mappings for config_type_t. "CFG_REPLY",
*/ "CFG_SET",
mapping_t config_type_m[] = { "CFG_ACK",
{CFG_REQUEST, "CFG_REQUEST"}, );
{CFG_REPLY, "CFG_REPLY"},
{CFG_SET, "CFG_SET"},
{CFG_ACK, "CFG_ACK"},
{MAPPING_END, NULL}
};
typedef struct private_cp_payload_t private_cp_payload_t; typedef struct private_cp_payload_t private_cp_payload_t;
@@ -77,13 +71,6 @@ struct private_cp_payload_t {
* Config Type. * Config Type.
*/ */
u_int8_t config_type; u_int8_t config_type;
/**
* @brief Computes the length of this payload.
*
* @param this calling private_cp_payload_t object
*/
void (*compute_length) (private_cp_payload_t *this);
}; };
/** /**
@@ -189,12 +176,31 @@ static void set_next_type(private_cp_payload_t *this,payload_type_t type)
this->next_payload = type; this->next_payload = type;
} }
/**
* recompute the length of the payload.
*/
static void compute_length(private_cp_payload_t *this)
{
iterator_t *iterator;
size_t length = CP_PAYLOAD_HEADER_LENGTH;
iterator = this->attributes->create_iterator(this->attributes,TRUE);
while (iterator->has_next(iterator))
{
payload_t *current_attribute;
iterator->current(iterator,(void **) &current_attribute);
length += current_attribute->get_length(current_attribute);
}
iterator->destroy(iterator);
this->payload_length = length;
}
/** /**
* Implementation of payload_t.get_length. * Implementation of payload_t.get_length.
*/ */
static size_t get_length(private_cp_payload_t *this) static size_t get_length(private_cp_payload_t *this)
{ {
this->compute_length(this); compute_length(this);
return this->payload_length; return this->payload_length;
} }
@@ -212,7 +218,7 @@ static iterator_t *create_configuration_attribute_iterator (private_cp_payload_t
static void add_configuration_attribute (private_cp_payload_t *this,configuration_attribute_t *attribute) static void add_configuration_attribute (private_cp_payload_t *this,configuration_attribute_t *attribute)
{ {
this->attributes->insert_last(this->attributes,(void *) attribute); this->attributes->insert_last(this->attributes,(void *) attribute);
this->compute_length(this); compute_length(this);
} }
/** /**
@@ -231,25 +237,6 @@ static config_type_t get_config_type (private_cp_payload_t *this)
return this->config_type; return this->config_type;
} }
/**
* Implementation of private_cp_payload_t.compute_length.
*/
static void compute_length (private_cp_payload_t *this)
{
iterator_t *iterator;
size_t length = CP_PAYLOAD_HEADER_LENGTH;
iterator = this->attributes->create_iterator(this->attributes,TRUE);
while (iterator->has_next(iterator))
{
payload_t *current_attribute;
iterator->current(iterator,(void **) &current_attribute);
length += current_attribute->get_length(current_attribute);
}
iterator->destroy(iterator);
this->payload_length = length;
}
/** /**
* Implementation of payload_t.destroy and cp_payload_t.destroy. * Implementation of payload_t.destroy and cp_payload_t.destroy.
*/ */
@@ -292,10 +279,6 @@ cp_payload_t *cp_payload_create()
this->public.get_config_type = (config_type_t (*) (cp_payload_t *)) get_config_type; this->public.get_config_type = (config_type_t (*) (cp_payload_t *)) get_config_type;
this->public.destroy = (void (*) (cp_payload_t *)) destroy; this->public.destroy = (void (*) (cp_payload_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */ /* set default values of the fields */
this->critical = FALSE; this->critical = FALSE;
this->next_payload = NO_PAYLOAD; this->next_payload = NO_PAYLOAD;
+3 -3
View File
@@ -52,11 +52,11 @@ enum config_type_t {
}; };
/** /**
* string mappings for config_type_t. * enum name for config_type_t.
* *
* @ingroup payloads * @ingroup payloads
*/ */
extern mapping_t config_type_m[]; extern enum_name_t *config_type_names;
typedef struct cp_payload_t cp_payload_t; typedef struct cp_payload_t cp_payload_t;
+41 -43
View File
@@ -24,46 +24,44 @@
#include "encodings.h" #include "encodings.h"
ENUM(encoding_type_names, U_INT_4, UNKNOWN_DATA,
mapping_t encoding_type_m[] = { "U_INT_4",
{U_INT_4, "U_INT_4"}, "U_INT_8",
{U_INT_8, "U_INT_8"}, "U_INT_16",
{U_INT_16, "U_INT_16"}, "U_INT_32",
{U_INT_32, "U_INT_32"}, "U_INT_64",
{U_INT_64, "U_INT_64"}, "IKE_SPI",
{IKE_SPI, "IKE_SPI"}, "RESERVED_BIT",
{RESERVED_BIT, "RESERVED_BIT"}, "RESERVED_BYTE",
{RESERVED_BYTE, "RESERVED_BYTE"}, "FLAG",
{FLAG, "FLAG"}, "PAYLOAD_LENGTH",
{PAYLOAD_LENGTH, "PAYLOAD_LENGTH"}, "HEADER_LENGTH",
{HEADER_LENGTH, "HEADER_LENGTH"}, "SPI_SIZE",
{SPI_SIZE, "SPI_SIZE"}, "SPI",
{SPI, "SPI"}, "KEY_EXCHANGE_DATA",
{KEY_EXCHANGE_DATA, "KEY_EXCHANGE_DATA"}, "NOTIFICATION_DATA",
{NOTIFICATION_DATA, "NOTIFICATION_DATA"}, "PROPOSALS",
{PROPOSALS, "PROPOSALS"}, "TRANSFORMS",
{TRANSFORMS, "TRANSFORMS"}, "TRANSFORM_ATTRIBUTES",
{TRANSFORM_ATTRIBUTES, "TRANSFORM_ATTRIBUTES"}, "ATTRIBUTE_FORMAT",
{ATTRIBUTE_FORMAT, "ATTRIBUTE_FORMAT"}, "ATTRIBUTE_TYPE",
{ATTRIBUTE_TYPE, "ATTRIBUTE_TYPE"}, "ATTRIBUTE_LENGTH_OR_VALUE",
{ATTRIBUTE_LENGTH_OR_VALUE, "ATTRIBUTE_LENGTH_OR_VALUE"}, "ATTRIBUTE_VALUE",
{ATTRIBUTE_VALUE, "ATTRIBUTE_VALUE"}, "NONCE_DATA",
{NONCE_DATA, "NONCE_DATA"}, "ID_DATA",
{ID_DATA, "ID_DATA"}, "AUTH_DATA",
{AUTH_DATA, "AUTH_DATA"}, "ENCRYPTED_DATA",
{ENCRYPTED_DATA, "ENCRYPTED_DATA"}, "TS_TYPE",
{TS_TYPE, "TS_TYPE"}, "ADDRESS",
{ADDRESS, "ADDRESS"}, "TRAFFIC_SELECTORS",
{TRAFFIC_SELECTORS, "TRAFFIC_SELECTORS"}, "CERT_DATA",
{CERT_DATA, "CERT_DATA"}, "CERTREQ_DATA",
{CERTREQ_DATA, "CERTREQ_DATA"}, "SPIS",
{SPIS, "SPIS"}, "VID_DATA",
{VID_DATA, "VID_DATA"}, "VID_DATA",
{VID_DATA, "VID_DATA"}, "CONFIGURATION_ATTRIBUTES",
{CONFIGURATION_ATTRIBUTES, "CONFIGURATION_ATTRIBUTES"}, "CONFIGURATION_ATTRIBUTE_LENGTH",
{CONFIGURATION_ATTRIBUTE_LENGTH, "CONFIGURATION_ATTRIBUTE_LENGTH"}, "CONFIGURATION_ATTRIBUTE_VALUE",
{CONFIGURATION_ATTRIBUTE_VALUE, "CONFIGURATION_ATTRIBUTE_VALUE"}, "EAP_MESSAGE",
{EAP_MESSAGE, "EAP_MESSAGE"}, "UNKNOWN_DATA",
{UNKNOWN_DATA,"UNKNOWN_DATA"}, );
{MAPPING_END, NULL}
};
+2 -2
View File
@@ -499,11 +499,11 @@ enum encoding_type_t {
}; };
/** /**
* mappings to map encoding_type_t's to strings * enum name for encoding_type_t
* *
* @ingroup payloads * @ingroup payloads
*/ */
extern mapping_t encoding_type_m[]; extern enum_name_t *encoding_type_names;
typedef struct encoding_rule_t encoding_rule_t; typedef struct encoding_rule_t encoding_rule_t;
+379 -418
View File
@@ -29,7 +29,6 @@
#include <daemon.h> #include <daemon.h>
#include <encoding/payloads/encodings.h> #include <encoding/payloads/encodings.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger.h>
#include <encoding/generator.h> #include <encoding/generator.h>
#include <encoding/parser.h> #include <encoding/parser.h>
#include <utils/iterator.h> #include <utils/iterator.h>
@@ -37,8 +36,6 @@
#include <crypto/signers/signer.h> #include <crypto/signers/signer.h>
typedef struct private_encryption_payload_t private_encryption_payload_t; typedef struct private_encryption_payload_t private_encryption_payload_t;
/** /**
@@ -95,32 +92,6 @@ struct private_encryption_payload_t {
* Contained payloads of this encrpytion_payload. * Contained payloads of this encrpytion_payload.
*/ */
linked_list_t *payloads; linked_list_t *payloads;
/**
* logger for this payload, uses MESSAGE context
*/
logger_t *logger;
/**
* @brief Computes the length of this payload.
*
* @param this calling private_encryption_payload_t object
*/
void (*compute_length) (private_encryption_payload_t *this);
/**
* @brief Generate payloads (unencrypted) in chunk decrypted.
*
* @param this calling private_encryption_payload_t object
*/
void (*generate) (private_encryption_payload_t *this);
/**
* @brief Parse payloads from a (unencrypted) chunk.
*
* @param this calling private_encryption_payload_t object
*/
status_t (*parse) (private_encryption_payload_t *this);
}; };
/** /**
@@ -212,389 +183,7 @@ static void set_next_type(private_encryption_payload_t *this, payload_type_t typ
} }
/** /**
* Implementation of payload_t.get_length. * (re-)compute the lenght of the whole payload
*/
static size_t get_length(private_encryption_payload_t *this)
{
this->compute_length(this);
return this->payload_length;
}
/**
* Implementation of payload_t.create_payload_iterator.
*/
static iterator_t *create_payload_iterator (private_encryption_payload_t *this, bool forward)
{
return (this->payloads->create_iterator(this->payloads, forward));
}
/**
* Implementation of payload_t.add_payload.
*/
static void add_payload(private_encryption_payload_t *this, payload_t *payload)
{
payload_t *last_payload;
if (this->payloads->get_count(this->payloads) > 0)
{
this->payloads->get_last(this->payloads,(void **) &last_payload);
last_payload->set_next_type(last_payload, payload->get_type(payload));
}
else
{
this->next_payload = payload->get_type(payload);
}
payload->set_next_type(payload, NO_PAYLOAD);
this->payloads->insert_last(this->payloads, (void*)payload);
this->compute_length(this);
}
/**
* Implementation of encryption_payload_t.remove_first_payload.
*/
static status_t remove_first_payload(private_encryption_payload_t *this, payload_t **payload)
{
return this->payloads->remove_first(this->payloads, (void**)payload);
}
/**
* Implementation of encryption_payload_t.get_payload_count.
*/
static size_t get_payload_count(private_encryption_payload_t *this)
{
return this->payloads->get_count(this->payloads);
}
/**
* Implementation of encryption_payload_t.encrypt.
*/
static status_t encrypt(private_encryption_payload_t *this)
{
chunk_t iv, padding, to_crypt, result;
randomizer_t *randomizer;
status_t status;
size_t block_size;
if (this->signer == NULL || this->crypter == NULL)
{
this->logger->log(this->logger, ERROR, "could not encrypt, signer/crypter not set");
return INVALID_STATE;
}
/* for random data in iv and padding */
randomizer = randomizer_create();
/* build payload chunk */
this->generate(this);
this->logger->log(this->logger, CONTROL|LEVEL2, "encrypting payloads");
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data to encrypt", this->decrypted);
/* build padding */
block_size = this->crypter->get_block_size(this->crypter);
padding.len = block_size - ((this->decrypted.len + 1) % block_size);
status = randomizer->allocate_pseudo_random_bytes(randomizer, padding.len, &padding);
if (status != SUCCESS)
{
randomizer->destroy(randomizer);
return status;
}
/* concatenate payload data, padding, padding len */
to_crypt.len = this->decrypted.len + padding.len + 1;
to_crypt.ptr = malloc(to_crypt.len);
memcpy(to_crypt.ptr, this->decrypted.ptr, this->decrypted.len);
memcpy(to_crypt.ptr + this->decrypted.len, padding.ptr, padding.len);
*(to_crypt.ptr + to_crypt.len - 1) = padding.len;
/* build iv */
iv.len = block_size;
status = randomizer->allocate_pseudo_random_bytes(randomizer, iv.len, &iv);
randomizer->destroy(randomizer);
if (status != SUCCESS)
{
chunk_free(&to_crypt);
chunk_free(&padding);
return status;
}
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before encryption with padding", to_crypt);
/* encrypt to_crypt chunk */
free(this->encrypted.ptr);
status = this->crypter->encrypt(this->crypter, to_crypt, iv, &result);
free(padding.ptr);
free(to_crypt.ptr);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR|LEVEL1, "encryption failed");
free(iv.ptr);
return status;
}
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after encryption", result);
/* build encrypted result with iv and signature */
this->encrypted.len = iv.len + result.len + this->signer->get_block_size(this->signer);
free(this->encrypted.ptr);
this->encrypted.ptr = malloc(this->encrypted.len);
/* fill in result, signature is left out */
memcpy(this->encrypted.ptr, iv.ptr, iv.len);
memcpy(this->encrypted.ptr + iv.len, result.ptr, result.len);
free(result.ptr);
free(iv.ptr);
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after encryption with IV and (invalid) signature", this->encrypted);
return SUCCESS;
}
/**
* Implementation of encryption_payload_t.encrypt.
*/
static status_t decrypt(private_encryption_payload_t *this)
{
chunk_t iv, concatenated;
u_int8_t padding_length;
status_t status;
this->logger->log(this->logger, CONTROL|LEVEL2, "decrypting encryption payload");
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before decryption with IV and (invalid) signature", this->encrypted);
if (this->signer == NULL || this->crypter == NULL)
{
this->logger->log(this->logger, ERROR, "could not decrypt, no crypter/signer set");
return INVALID_STATE;
}
/* get IV */
iv.len = this->crypter->get_block_size(this->crypter);
iv.ptr = this->encrypted.ptr;
/* point concatenated to data + padding + padding_length*/
concatenated.ptr = this->encrypted.ptr + iv.len;
concatenated.len = this->encrypted.len - iv.len - this->signer->get_block_size(this->signer);
/* check the size of input:
* concatenated must be at least on block_size of crypter
*/
if (concatenated.len < iv.len)
{
this->logger->log(this->logger, ERROR, "could not decrypt, invalid input");
return FAILED;
}
/* free previus data, if any */
free(this->decrypted.ptr);
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before decryption", concatenated);
status = this->crypter->decrypt(this->crypter, concatenated, iv, &(this->decrypted));
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "could not decrypt, decryption failed");
return FAILED;
}
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after decryption with padding", this->decrypted);
/* get padding length, sits just bevore signature */
padding_length = *(this->decrypted.ptr + this->decrypted.len - 1);
/* add one byte to the padding length, since the padding_length field is not included */
padding_length++;
this->decrypted.len -= padding_length;
/* check size again */
if (padding_length > concatenated.len || this->decrypted.len < 0)
{
this->logger->log(this->logger, ERROR, "decryption failed, invalid padding length found. Invalid key?");
/* decryption failed :-/ */
return FAILED;
}
/* free padding */
this->decrypted.ptr = realloc(this->decrypted.ptr, this->decrypted.len);
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after decryption without padding", this->decrypted);
this->logger->log(this->logger, CONTROL|LEVEL2, "decryption successful, trying to parse content");
return (this->parse(this));
}
/**
* Implementation of encryption_payload_t.set_transforms.
*/
static void set_transforms(private_encryption_payload_t *this, crypter_t* crypter, signer_t* signer)
{
this->signer = signer;
this->crypter = crypter;
}
/**
* Implementation of encryption_payload_t.build_signature.
*/
static status_t build_signature(private_encryption_payload_t *this, chunk_t data)
{
chunk_t data_without_sig = data;
chunk_t sig;
if (this->signer == NULL)
{
this->logger->log(this->logger, ERROR, "unable to build signature, no signer set");
return INVALID_STATE;
}
sig.len = this->signer->get_block_size(this->signer);
data_without_sig.len -= sig.len;
sig.ptr = data.ptr + data_without_sig.len;
this->logger->log(this->logger, CONTROL|LEVEL2, "building signature");
this->signer->get_signature(this->signer, data_without_sig, sig.ptr);
return SUCCESS;
}
/**
* Implementation of encryption_payload_t.verify_signature.
*/
static status_t verify_signature(private_encryption_payload_t *this, chunk_t data)
{
chunk_t sig, data_without_sig;
bool valid;
if (this->signer == NULL)
{
this->logger->log(this->logger, ERROR, "unable to verify signature, no signer set");
return INVALID_STATE;
}
/* find signature in data chunk */
sig.len = this->signer->get_block_size(this->signer);
if (data.len <= sig.len)
{
this->logger->log(this->logger, ERROR|LEVEL1, "unable to verify signature, invalid input");
return FAILED;
}
sig.ptr = data.ptr + data.len - sig.len;
/* verify it */
data_without_sig.len = data.len - sig.len;
data_without_sig.ptr = data.ptr;
valid = this->signer->verify_signature(this->signer, data_without_sig, sig);
if (!valid)
{
this->logger->log(this->logger, ERROR|LEVEL1, "signature verification failed");
return FAILED;
}
this->logger->log(this->logger, CONTROL|LEVEL2, "signature verification successful");
return SUCCESS;
}
/**
* Implementation of private_encryption_payload_t.generate.
*/
static void generate(private_encryption_payload_t *this)
{
payload_t *current_payload, *next_payload;
generator_t *generator;
iterator_t *iterator;
/* recalculate length before generating */
this->compute_length(this);
/* create iterator */
iterator = this->payloads->create_iterator(this->payloads, TRUE);
/* get first payload */
if (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&current_payload);
this->next_payload = current_payload->get_type(current_payload);
}
else
{
/* no paylads? */
this->logger->log(this->logger, CONTROL|LEVEL1, "generating contained payloads, but no available");
free(this->decrypted.ptr);
this->decrypted = CHUNK_INITIALIZER;
iterator->destroy(iterator);
return;
}
generator = generator_create();
/* build all payload, except last */
while(iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&next_payload);
current_payload->set_next_type(current_payload, next_payload->get_type(next_payload));
generator->generate_payload(generator, current_payload);
current_payload = next_payload;
}
iterator->destroy(iterator);
/* build last payload */
current_payload->set_next_type(current_payload, NO_PAYLOAD);
generator->generate_payload(generator, current_payload);
/* free already generated data */
free(this->decrypted.ptr);
generator->write_to_chunk(generator, &(this->decrypted));
generator->destroy(generator);
this->logger->log(this->logger, CONTROL|LEVEL1, "successfully generated content in encrpytion payload");
}
/**
* Implementation of private_encryption_payload_t.parse.
*/
static status_t parse(private_encryption_payload_t *this)
{
parser_t *parser;
status_t status;
payload_type_t current_payload_type;
/* build a parser on the decrypted data */
parser = parser_create(this->decrypted);
current_payload_type = this->next_payload;
/* parse all payloads */
while (current_payload_type != NO_PAYLOAD)
{
payload_t *current_payload;
status = parser->parse_payload(parser, current_payload_type, (payload_t**)&current_payload);
if (status != SUCCESS)
{
parser->destroy(parser);
return PARSE_ERROR;
}
status = current_payload->verify(current_payload);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "%s verification failed",
mapping_find(payload_type_m,current_payload->get_type(current_payload)));
current_payload->destroy(current_payload);
parser->destroy(parser);
return VERIFY_ERROR;
}
/* get next payload type */
current_payload_type = current_payload->get_next_type(current_payload);
this->payloads->insert_last(this->payloads,current_payload);
}
parser->destroy(parser);
this->logger->log(this->logger, CONTROL|LEVEL1, "succesfully parsed content of encryption payload");
return SUCCESS;
}
/**
* Implementation of private_encryption_payload_t.compute_length.
*/ */
static void compute_length(private_encryption_payload_t *this) static void compute_length(private_encryption_payload_t *this)
{ {
@@ -627,6 +216,384 @@ static void compute_length(private_encryption_payload_t *this)
this->payload_length = length; this->payload_length = length;
} }
/**
* Implementation of payload_t.get_length.
*/
static size_t get_length(private_encryption_payload_t *this)
{
compute_length(this);
return this->payload_length;
}
/**
* Implementation of payload_t.create_payload_iterator.
*/
static iterator_t *create_payload_iterator (private_encryption_payload_t *this, bool forward)
{
return (this->payloads->create_iterator(this->payloads, forward));
}
/**
* Implementation of payload_t.add_payload.
*/
static void add_payload(private_encryption_payload_t *this, payload_t *payload)
{
payload_t *last_payload;
if (this->payloads->get_count(this->payloads) > 0)
{
this->payloads->get_last(this->payloads,(void **) &last_payload);
last_payload->set_next_type(last_payload, payload->get_type(payload));
}
else
{
this->next_payload = payload->get_type(payload);
}
payload->set_next_type(payload, NO_PAYLOAD);
this->payloads->insert_last(this->payloads, (void*)payload);
compute_length(this);
}
/**
* Implementation of encryption_payload_t.remove_first_payload.
*/
static status_t remove_first_payload(private_encryption_payload_t *this, payload_t **payload)
{
return this->payloads->remove_first(this->payloads, (void**)payload);
}
/**
* Implementation of encryption_payload_t.get_payload_count.
*/
static size_t get_payload_count(private_encryption_payload_t *this)
{
return this->payloads->get_count(this->payloads);
}
/**
* Generate payload before encryption.
*/
static void generate(private_encryption_payload_t *this)
{
payload_t *current_payload, *next_payload;
generator_t *generator;
iterator_t *iterator;
/* recalculate length before generating */
compute_length(this);
/* create iterator */
iterator = this->payloads->create_iterator(this->payloads, TRUE);
/* get first payload */
if (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&current_payload);
this->next_payload = current_payload->get_type(current_payload);
}
else
{
/* no paylads? */
DBG2(SIG_DBG_ENC, "generating contained payloads, but none available");
free(this->decrypted.ptr);
this->decrypted = CHUNK_INITIALIZER;
iterator->destroy(iterator);
return;
}
generator = generator_create();
/* build all payload, except last */
while(iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&next_payload);
current_payload->set_next_type(current_payload, next_payload->get_type(next_payload));
generator->generate_payload(generator, current_payload);
current_payload = next_payload;
}
iterator->destroy(iterator);
/* build last payload */
current_payload->set_next_type(current_payload, NO_PAYLOAD);
generator->generate_payload(generator, current_payload);
/* free already generated data */
free(this->decrypted.ptr);
generator->write_to_chunk(generator, &(this->decrypted));
generator->destroy(generator);
DBG2(SIG_DBG_ENC, "successfully generated content in encryption payload");
}
/**
* Implementation of encryption_payload_t.encrypt.
*/
static status_t encrypt(private_encryption_payload_t *this)
{
chunk_t iv, padding, to_crypt, result;
randomizer_t *randomizer;
status_t status;
size_t block_size;
if (this->signer == NULL || this->crypter == NULL)
{
DBG1(SIG_DBG_ENC, "could not encrypt, signer/crypter not set");
return INVALID_STATE;
}
/* for random data in iv and padding */
randomizer = randomizer_create();
/* build payload chunk */
generate(this);
DBG2(SIG_DBG_ENC, "encrypting payloads");
DBG3(SIG_DBG_ENC, "data to encrypt %B", &this->decrypted);
/* build padding */
block_size = this->crypter->get_block_size(this->crypter);
padding.len = block_size - ((this->decrypted.len + 1) % block_size);
status = randomizer->allocate_pseudo_random_bytes(randomizer, padding.len, &padding);
if (status != SUCCESS)
{
randomizer->destroy(randomizer);
return status;
}
/* concatenate payload data, padding, padding len */
to_crypt.len = this->decrypted.len + padding.len + 1;
to_crypt.ptr = malloc(to_crypt.len);
memcpy(to_crypt.ptr, this->decrypted.ptr, this->decrypted.len);
memcpy(to_crypt.ptr + this->decrypted.len, padding.ptr, padding.len);
*(to_crypt.ptr + to_crypt.len - 1) = padding.len;
/* build iv */
iv.len = block_size;
status = randomizer->allocate_pseudo_random_bytes(randomizer, iv.len, &iv);
randomizer->destroy(randomizer);
if (status != SUCCESS)
{
chunk_free(&to_crypt);
chunk_free(&padding);
return status;
}
DBG3(SIG_DBG_ENC, "data before encryption with padding %B", &to_crypt);
/* encrypt to_crypt chunk */
free(this->encrypted.ptr);
status = this->crypter->encrypt(this->crypter, to_crypt, iv, &result);
free(padding.ptr);
free(to_crypt.ptr);
if (status != SUCCESS)
{
DBG2(SIG_DBG_ENC, "encryption failed");
free(iv.ptr);
return status;
}
DBG3(SIG_DBG_ENC, "data after encryption %B", &result);
/* build encrypted result with iv and signature */
this->encrypted.len = iv.len + result.len + this->signer->get_block_size(this->signer);
free(this->encrypted.ptr);
this->encrypted.ptr = malloc(this->encrypted.len);
/* fill in result, signature is left out */
memcpy(this->encrypted.ptr, iv.ptr, iv.len);
memcpy(this->encrypted.ptr + iv.len, result.ptr, result.len);
free(result.ptr);
free(iv.ptr);
DBG3(SIG_DBG_ENC, "data after encryption with IV and (invalid) signature %B",
&this->encrypted);
return SUCCESS;
}
/**
* Parse the payloads after decryption.
*/
static status_t parse(private_encryption_payload_t *this)
{
parser_t *parser;
status_t status;
payload_type_t current_payload_type;
/* build a parser on the decrypted data */
parser = parser_create(this->decrypted);
current_payload_type = this->next_payload;
/* parse all payloads */
while (current_payload_type != NO_PAYLOAD)
{
payload_t *current_payload;
status = parser->parse_payload(parser, current_payload_type, (payload_t**)&current_payload);
if (status != SUCCESS)
{
parser->destroy(parser);
return PARSE_ERROR;
}
status = current_payload->verify(current_payload);
if (status != SUCCESS)
{
DBG1(SIG_DBG_ENC, "%N verification failed",
payload_type_names, current_payload->get_type(current_payload));
current_payload->destroy(current_payload);
parser->destroy(parser);
return VERIFY_ERROR;
}
/* get next payload type */
current_payload_type = current_payload->get_next_type(current_payload);
this->payloads->insert_last(this->payloads,current_payload);
}
parser->destroy(parser);
DBG2(SIG_DBG_ENC, "succesfully parsed content of encryption payload");
return SUCCESS;
}
/**
* Implementation of encryption_payload_t.encrypt.
*/
static status_t decrypt(private_encryption_payload_t *this)
{
chunk_t iv, concatenated;
u_int8_t padding_length;
status_t status;
DBG2(SIG_DBG_ENC, "decrypting encryption payload");
DBG3(SIG_DBG_ENC, "data before decryption with IV and (invalid) signature %B",
&this->encrypted);
if (this->signer == NULL || this->crypter == NULL)
{
DBG1(SIG_DBG_ENC, "could not decrypt, no crypter/signer set");
return INVALID_STATE;
}
/* get IV */
iv.len = this->crypter->get_block_size(this->crypter);
iv.ptr = this->encrypted.ptr;
/* point concatenated to data + padding + padding_length*/
concatenated.ptr = this->encrypted.ptr + iv.len;
concatenated.len = this->encrypted.len - iv.len - this->signer->get_block_size(this->signer);
/* check the size of input:
* concatenated must be at least on block_size of crypter
*/
if (concatenated.len < iv.len)
{
DBG1(SIG_DBG_ENC, "could not decrypt, invalid input");
return FAILED;
}
/* free previus data, if any */
free(this->decrypted.ptr);
DBG3(SIG_DBG_ENC, "data before decryption %B", &concatenated);
status = this->crypter->decrypt(this->crypter, concatenated, iv, &(this->decrypted));
if (status != SUCCESS)
{
DBG1(SIG_DBG_ENC, "could not decrypt, decryption failed");
return FAILED;
}
DBG3(SIG_DBG_ENC, "data after decryption with padding %B", &this->decrypted);
/* get padding length, sits just bevore signature */
padding_length = *(this->decrypted.ptr + this->decrypted.len - 1);
/* add one byte to the padding length, since the padding_length field is not included */
padding_length++;
this->decrypted.len -= padding_length;
/* check size again */
if (padding_length > concatenated.len || this->decrypted.len < 0)
{
DBG1(SIG_DBG_ENC, "decryption failed, invalid padding length found. Invalid key?");
/* decryption failed :-/ */
return FAILED;
}
/* free padding */
this->decrypted.ptr = realloc(this->decrypted.ptr, this->decrypted.len);
DBG3(SIG_DBG_ENC, "data after decryption without padding %B", &this->decrypted);
DBG2(SIG_DBG_ENC, "decryption successful, trying to parse content");
return parse(this);
}
/**
* Implementation of encryption_payload_t.set_transforms.
*/
static void set_transforms(private_encryption_payload_t *this, crypter_t* crypter, signer_t* signer)
{
this->signer = signer;
this->crypter = crypter;
}
/**
* Implementation of encryption_payload_t.build_signature.
*/
static status_t build_signature(private_encryption_payload_t *this, chunk_t data)
{
chunk_t data_without_sig = data;
chunk_t sig;
if (this->signer == NULL)
{
DBG1(SIG_DBG_ENC, "unable to build signature, no signer set");
return INVALID_STATE;
}
sig.len = this->signer->get_block_size(this->signer);
data_without_sig.len -= sig.len;
sig.ptr = data.ptr + data_without_sig.len;
DBG2(SIG_DBG_ENC, "building signature");
this->signer->get_signature(this->signer, data_without_sig, sig.ptr);
return SUCCESS;
}
/**
* Implementation of encryption_payload_t.verify_signature.
*/
static status_t verify_signature(private_encryption_payload_t *this, chunk_t data)
{
chunk_t sig, data_without_sig;
bool valid;
if (this->signer == NULL)
{
DBG1(SIG_DBG_ENC, "unable to verify signature, no signer set");
return INVALID_STATE;
}
/* find signature in data chunk */
sig.len = this->signer->get_block_size(this->signer);
if (data.len <= sig.len)
{
DBG1(SIG_DBG_ENC, "unable to verify signature, invalid input");
return FAILED;
}
sig.ptr = data.ptr + data.len - sig.len;
/* verify it */
data_without_sig.len = data.len - sig.len;
data_without_sig.ptr = data.ptr;
valid = this->signer->verify_signature(this->signer, data_without_sig, sig);
if (!valid)
{
DBG1(SIG_DBG_ENC, "signature verification failed");
return FAILED;
}
DBG2(SIG_DBG_ENC, "signature verification successful");
return SUCCESS;
}
/** /**
* Implementation of payload_t.destroy. * Implementation of payload_t.destroy.
@@ -675,12 +642,6 @@ encryption_payload_t *encryption_payload_create()
this->public.verify_signature = (status_t (*) (encryption_payload_t*, chunk_t)) verify_signature; this->public.verify_signature = (status_t (*) (encryption_payload_t*, chunk_t)) verify_signature;
this->public.destroy = (void (*) (encryption_payload_t *)) destroy; this->public.destroy = (void (*) (encryption_payload_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
this->generate = generate;
this->parse = parse;
this->logger = logger_manager->get_logger(logger_manager, ENCRYPTION_PAYLOAD);
/* set default values of the fields */ /* set default values of the fields */
this->critical = FALSE; this->critical = FALSE;
this->next_payload = NO_PAYLOAD; this->next_payload = NO_PAYLOAD;
+8 -11
View File
@@ -100,19 +100,16 @@ struct private_ike_header_t {
* Length of the whole IKEv2-Message (header and all payloads). * Length of the whole IKEv2-Message (header and all payloads).
*/ */
u_int32_t length; u_int32_t length;
};
/**
* Mappings used to get strings for exchange_type_t.
*/
mapping_t exchange_type_m[] = {
{EXCHANGE_TYPE_UNDEFINED, "EXCHANGE_TYPE_UNDEFINED"},
{IKE_SA_INIT, "IKE_SA_INIT"},
{IKE_AUTH, "IKE_AUTH"},
{CREATE_CHILD_SA, "CREATE_CHILD_SA"},
{INFORMATIONAL, "INFORMATIONAL"}
}; };
ENUM_BEGIN(exchange_type_names, EXCHANGE_TYPE_UNDEFINED, EXCHANGE_TYPE_UNDEFINED,
"EXCHANGE_TYPE_UNDEFINED");
ENUM_NEXT(exchange_type_names, IKE_SA_INIT, INFORMATIONAL, EXCHANGE_TYPE_UNDEFINED,
"IKE_SA_INIT",
"IKE_AUTH",
"CREATE_CHILD_SA",
"INFORMATIONAL");
ENUM_END(exchange_type_names, INFORMATIONAL);
/** /**
* Encoding rules to parse or generate a IKEv2-Header. * Encoding rules to parse or generate a IKEv2-Header.
+2 -2
View File
@@ -93,11 +93,11 @@ enum exchange_type_t{
}; };
/** /**
* string mappings for exchange_type_t * enum name for exchange_type_t
* *
* @ingroup payloads * @ingroup payloads
*/ */
extern mapping_t exchange_type_m[]; extern enum_name_t *exchange_type_names;
typedef struct ike_header_t ike_header_t; typedef struct ike_header_t ike_header_t;
+12 -23
View File
@@ -64,13 +64,6 @@ struct private_ke_payload_t {
* Key Exchange Data of this KE payload. * Key Exchange Data of this KE payload.
*/ */
chunk_t key_exchange_data; chunk_t key_exchange_data;
/**
* @brief Computes the length of this payload.
*
* @param this calling private_ke_payload_t object
*/
void (*compute_length) (private_ke_payload_t *this);
}; };
/** /**
@@ -172,18 +165,9 @@ static void set_next_type(private_ke_payload_t *this,payload_type_t type)
} }
/** /**
* Implementation of payload_t.get_length. * recompute the length of the payload.
*/ */
static size_t get_length(private_ke_payload_t *this) static void compute_length(private_ke_payload_t *this)
{
this->compute_length(this);
return this->payload_length;
}
/**
* Implementation of private_ke_payload_t.compute_length.
*/
static void compute_length (private_ke_payload_t *this)
{ {
size_t length = KE_PAYLOAD_HEADER_LENGTH; size_t length = KE_PAYLOAD_HEADER_LENGTH;
if (this->key_exchange_data.ptr != NULL) if (this->key_exchange_data.ptr != NULL)
@@ -193,6 +177,14 @@ static void compute_length (private_ke_payload_t *this)
this->payload_length = length; this->payload_length = length;
} }
/**
* Implementation of payload_t.get_length.
*/
static size_t get_length(private_ke_payload_t *this)
{
compute_length(this);
return this->payload_length;
}
/** /**
* Implementation of ke_payload_t.get_key_exchange_data. * Implementation of ke_payload_t.get_key_exchange_data.
@@ -218,7 +210,7 @@ static void set_key_exchange_data(private_ke_payload_t *this, chunk_t key_exchan
} }
this->key_exchange_data = chunk_clone(key_exchange_data); this->key_exchange_data = chunk_clone(key_exchange_data);
this->compute_length(this); compute_length(this);
} }
/** /**
@@ -260,9 +252,6 @@ ke_payload_t *ke_payload_create()
this->public.set_dh_group_number =(void (*) (ke_payload_t *,diffie_hellman_group_t)) set_dh_group_number; this->public.set_dh_group_number =(void (*) (ke_payload_t *,diffie_hellman_group_t)) set_dh_group_number;
this->public.destroy = (void (*) (ke_payload_t *)) destroy; this->public.destroy = (void (*) (ke_payload_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */ /* set default values of the fields */
this->critical = FALSE; this->critical = FALSE;
this->next_payload = NO_PAYLOAD; this->next_payload = NO_PAYLOAD;
@@ -282,7 +271,7 @@ ke_payload_t *ke_payload_create_from_diffie_hellman(diffie_hellman_t *dh)
dh->get_my_public_value(dh, &this->key_exchange_data); dh->get_my_public_value(dh, &this->key_exchange_data);
this->dh_group_number = dh->get_dh_group(dh); this->dh_group_number = dh->get_dh_group(dh);
this->compute_length(this); compute_length(this);
return &this->public; return &this->public;
} }
+10 -20
View File
@@ -60,13 +60,6 @@ struct private_nonce_payload_t {
* The contained nonce value. * The contained nonce value.
*/ */
chunk_t nonce; chunk_t nonce;
/**
* @brief Computes the length of this payload.
*
* @param this calling private_nonce_payload_t object
*/
void (*compute_length) (private_nonce_payload_t *this);
}; };
/** /**
@@ -176,22 +169,22 @@ static void set_next_type(private_nonce_payload_t *this,payload_type_t type)
} }
/** /**
* Implementation of payload_t.get_length. * recompute the length of the payload.
*/
static size_t get_length(private_nonce_payload_t *this)
{
this->compute_length(this);
return this->payload_length;
}
/**
* Implementation of private_id_payload_t.compute_length.
*/ */
static void compute_length(private_nonce_payload_t *this) static void compute_length(private_nonce_payload_t *this)
{ {
this->payload_length = NONCE_PAYLOAD_HEADER_LENGTH + this->nonce.len; this->payload_length = NONCE_PAYLOAD_HEADER_LENGTH + this->nonce.len;
} }
/**
* Implementation of payload_t.get_length.
*/
static size_t get_length(private_nonce_payload_t *this)
{
compute_length(this);
return this->payload_length;
}
/** /**
* Implementation of payload_t.destroy and nonce_payload_t.destroy. * Implementation of payload_t.destroy and nonce_payload_t.destroy.
*/ */
@@ -226,9 +219,6 @@ nonce_payload_t *nonce_payload_create()
this->public.set_nonce = (void (*) (nonce_payload_t *,chunk_t)) set_nonce; this->public.set_nonce = (void (*) (nonce_payload_t *,chunk_t)) set_nonce;
this->public.get_nonce = (chunk_t (*) (nonce_payload_t *)) get_nonce; this->public.get_nonce = (chunk_t (*) (nonce_payload_t *)) get_nonce;
/* private functions */
this->compute_length = compute_length;
/* private variables */ /* private variables */
this->critical = FALSE; this->critical = FALSE;
this->next_payload = NO_PAYLOAD; this->next_payload = NO_PAYLOAD;
+69 -81
View File
@@ -28,50 +28,54 @@
#include <daemon.h> #include <daemon.h>
#include <encoding/payloads/encodings.h> #include <encoding/payloads/encodings.h>
#include <crypto/hashers/hasher.h>
#define SHA1_HASH_SIZE 20 ENUM_BEGIN(notify_type_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
"UNSUPPORTED_CRITICAL_PAYLOAD");
/** ENUM_NEXT(notify_type_names, INVALID_IKE_SPI, INVALID_MAJOR_VERSION, UNSUPPORTED_CRITICAL_PAYLOAD,
* String mappings for notify_type_t. "INVALID_IKE_SPI",
*/ "INVALID_MAJOR_VERSION");
mapping_t notify_type_m[] = { ENUM_NEXT(notify_type_names, INVALID_SYNTAX, INVALID_SYNTAX, INVALID_MAJOR_VERSION,
{UNSUPPORTED_CRITICAL_PAYLOAD, "UNSUPPORTED_CRITICAL_PAYLOAD"}, "INVALID_SYNTAX");
{INVALID_IKE_SPI, "INVALID_IKE_SPI"}, ENUM_NEXT(notify_type_names, INVALID_MESSAGE_ID, INVALID_MESSAGE_ID, INVALID_SYNTAX,
{INVALID_MAJOR_VERSION, "INVALID_MAJOR_VERSION"}, "INVALID_MESSAGE_ID");
{INVALID_SYNTAX, "INVALID_SYNTAX"}, ENUM_NEXT(notify_type_names, INVALID_SPI, INVALID_SPI, INVALID_MESSAGE_ID,
{INVALID_MESSAGE_ID, "INVALID_MESSAGE_ID"}, "INVALID_SPI");
{INVALID_SPI, "INVALID_SPI"}, ENUM_NEXT(notify_type_names, NO_PROPOSAL_CHOSEN, NO_PROPOSAL_CHOSEN, INVALID_SPI,
{NO_PROPOSAL_CHOSEN, "NO_PROPOSAL_CHOSEN"}, "NO_PROPOSAL_CHOSEN");
{INVALID_KE_PAYLOAD, "INVALID_KE_PAYLOAD"}, ENUM_NEXT(notify_type_names, INVALID_KE_PAYLOAD, INVALID_KE_PAYLOAD, NO_PROPOSAL_CHOSEN,
{AUTHENTICATION_FAILED, "AUTHENTICATION_FAILED"}, "INVALID_KE_PAYLOAD");
{SINGLE_PAIR_REQUIRED, "SINGLE_PAIR_REQUIRED"}, ENUM_NEXT(notify_type_names, AUTHENTICATION_FAILED, AUTHENTICATION_FAILED, INVALID_KE_PAYLOAD,
{NO_ADDITIONAL_SAS, "NO_ADDITIONAL_SAS"}, "AUTHENTICATION_FAILED");
{INTERNAL_ADDRESS_FAILURE, "INTERNAL_ADDRESS_FAILURE"}, ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, INVALID_SELECTORS, AUTHENTICATION_FAILED,
{FAILED_CP_REQUIRED, "FAILED_CP_REQUIRED"}, "SINGLE_PAIR_REQUIRED",
{TS_UNACCEPTABLE, "TS_UNACCEPTABLE"}, "NO_ADDITIONAL_SAS",
{INVALID_SELECTORS, "INVALID_SELECTORS"}, "INTERNAL_ADDRESS_FAILURE",
{INITIAL_CONTACT, "INITIAL_CONTACT"}, "FAILED_CP_REQUIRED",
{SET_WINDOW_SIZE, "SET_WINDOW_SIZE"}, "TS_UNACCEPTABLE",
{ADDITIONAL_TS_POSSIBLE, "ADDITIONAL_TS_POSSIBLE"}, "INVALID_SELECTORS");
{IPCOMP_SUPPORTED, "IPCOMP_SUPPORTED"}, ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, INVALID_SELECTORS,
{NAT_DETECTION_SOURCE_IP, "NAT_DETECTION_SOURCE_IP"}, "INITIAL_CONTACT",
{NAT_DETECTION_DESTINATION_IP, "NAT_DETECTION_DESTINATION_IP"}, "SET_WINDOW_SIZE",
{COOKIE, "COOKIE"}, "ADDITIONAL_TS_POSSIBLE",
{USE_TRANSPORT_MODE, "USE_TRANSPORT_MODE"}, "IPCOMP_SUPPORTED",
{HTTP_CERT_LOOKUP_SUPPORTED, "HTTP_CERT_LOOKUP_SUPPORTED"}, "NAT_DETECTION_SOURCE_IP",
{REKEY_SA, "REKEY_SA"}, "NAT_DETECTION_DESTINATION_IP",
{ESP_TFC_PADDING_NOT_SUPPORTED, "ESP_TFC_PADDING_NOT_SUPPORTED"}, "COOKIE",
{NON_FIRST_FRAGMENTS_ALSO, "NON_FIRST_FRAGMENTS_ALSO"}, "USE_TRANSPORT_MODE",
{MOBIKE_SUPPORTED, "MOBIKE_SUPPORTED"}, "HTTP_CERT_LOOKUP_SUPPORTED",
{ADDITIONAL_IP4_ADDRESS, "ADDITIONAL_IP4_ADDRESS"}, "REKEY_SA",
{ADDITIONAL_IP6_ADDRESS, "ADDITIONAL_IP6_ADDRESS"}, "ESP_TFC_PADDING_NOT_SUPPORTED",
{NO_ADDITIONAL_ADDRESSES, "NO_ADDITIONAL_ADDRESSES"}, "NON_FIRST_FRAGMENTS_ALSO",
{UPDATE_SA_ADDRESSES, "UPDATE_SA_ADDRESSES"}, "MOBIKE_SUPPORTED",
{COOKIE2, "COOKIE2"}, "ADDITIONAL_IP4_ADDRESS",
{NO_NATS_ALLOWED, "NO_NATS_ALLOWED"}, "ADDITIONAL_IP6_ADDRESS",
{AUTH_LIFETIME, "AUTH_LIFETIME"}, "NO_ADDITIONAL_ADDRESSES",
{MAPPING_END, NULL} "UPDATE_SA_ADDRESSES",
}; "COOKIE2",
"NO_NATS_ALLOWED",
"AUTH_LIFETIME");
ENUM_END(notify_type_names, AUTH_LIFETIME);
typedef struct private_notify_payload_t private_notify_payload_t; typedef struct private_notify_payload_t private_notify_payload_t;
@@ -124,18 +128,6 @@ struct private_notify_payload_t {
* Notification data. * Notification data.
*/ */
chunk_t notification_data; chunk_t notification_data;
/**
* Assigned logger
*/
logger_t *logger;
/**
* @brief Computes the length of this payload.
*
* @param this calling private_ke_payload_t object
*/
void (*compute_length) (private_notify_payload_t *this);
}; };
/** /**
@@ -204,13 +196,13 @@ static status_t verify(private_notify_payload_t *this)
case PROTO_ESP: case PROTO_ESP:
if (this->spi.len != 4) if (this->spi.len != 4)
{ {
this->logger->log(this->logger, ERROR, "Invalid SPI size for %s", DBG1(SIG_DBG_ENC, "Invalid SPI size for %N",
mapping_find(protocol_id_m, this->protocol_id)); protocol_id_names, this->protocol_id);
return FAILED; return FAILED;
} }
break; break;
default: default:
this->logger->log(this->logger, ERROR, "Unknown protocol (%d)", this->protocol_id); DBG1(SIG_DBG_ENC, "Unknown protocol (%d)", this->protocol_id);
return FAILED; return FAILED;
} }
@@ -237,7 +229,7 @@ static status_t verify(private_notify_payload_t *this)
case MODP_8192_BIT: case MODP_8192_BIT:
break; break;
default: default:
this->logger->log(this->logger, ERROR, "Bad DH group (%d)", dh_group); DBG1(SIG_DBG_ENC, "Bad DH group (%d)", dh_group);
return FAILED; return FAILED;
} }
break; break;
@@ -245,10 +237,10 @@ static status_t verify(private_notify_payload_t *this)
case NAT_DETECTION_SOURCE_IP: case NAT_DETECTION_SOURCE_IP:
case NAT_DETECTION_DESTINATION_IP: case NAT_DETECTION_DESTINATION_IP:
{ {
if (this->notification_data.len != SHA1_HASH_SIZE) if (this->notification_data.len != HASH_SIZE_SHA1)
{ {
this->logger->log(this->logger, ERROR, "invalid %s notify length", DBG1(SIG_DBG_ENC, "invalid %N notify length",
mapping_find(notify_type_m, this->notify_type)); notify_type_names, this->notify_type);
return FAILED; return FAILED;
} }
break; break;
@@ -259,8 +251,8 @@ static status_t verify(private_notify_payload_t *this)
{ {
if (this->notification_data.len != 0) if (this->notification_data.len != 0)
{ {
this->logger->log(this->logger, ERROR, "invalid %s notify", DBG1(SIG_DBG_ENC, "invalid %N notify",
mapping_find(notify_type_m, this->notify_type)); notify_type_names, this->notify_type);
return FAILED; return FAILED;
} }
break; break;
@@ -306,16 +298,7 @@ static void set_next_type(private_notify_payload_t *this,payload_type_t type)
} }
/** /**
* Implementation of payload_t.get_length. * recompute the payloads length.
*/
static size_t get_length(private_notify_payload_t *this)
{
this->compute_length(this);
return this->payload_length;
}
/**
* Implementation of private_notify_payload_t.compute_length.
*/ */
static void compute_length (private_notify_payload_t *this) static void compute_length (private_notify_payload_t *this)
{ {
@@ -331,6 +314,15 @@ static void compute_length (private_notify_payload_t *this)
this->payload_length = length; this->payload_length = length;
} }
/**
* Implementation of payload_t.get_length.
*/
static size_t get_length(private_notify_payload_t *this)
{
compute_length(this);
return this->payload_length;
}
/** /**
* Implementation of notify_payload_t.get_protocol_id. * Implementation of notify_payload_t.get_protocol_id.
*/ */
@@ -395,7 +387,7 @@ static void set_spi(private_notify_payload_t *this, u_int32_t spi)
break; break;
} }
this->spi_size = this->spi.len; this->spi_size = this->spi.len;
this->compute_length(this); compute_length(this);
} }
/** /**
@@ -413,7 +405,7 @@ static status_t set_notification_data(private_notify_payload_t *this, chunk_t no
{ {
chunk_free(&this->notification_data); chunk_free(&this->notification_data);
this->notification_data = chunk_clone(notification_data); this->notification_data = chunk_clone(notification_data);
this->compute_length(this); compute_length(this);
return SUCCESS; return SUCCESS;
} }
@@ -455,9 +447,6 @@ notify_payload_t *notify_payload_create()
this->public.set_notification_data = (void (*) (notify_payload_t *,chunk_t)) set_notification_data; this->public.set_notification_data = (void (*) (notify_payload_t *,chunk_t)) set_notification_data;
this->public.destroy = (void (*) (notify_payload_t *)) destroy; this->public.destroy = (void (*) (notify_payload_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */ /* set default values of the fields */
this->critical = FALSE; this->critical = FALSE;
this->next_payload = NO_PAYLOAD; this->next_payload = NO_PAYLOAD;
@@ -469,8 +458,7 @@ notify_payload_t *notify_payload_create()
this->spi_size = 0; this->spi_size = 0;
this->notification_data.ptr = NULL; this->notification_data.ptr = NULL;
this->notification_data.len = 0; this->notification_data.len = 0;
this->logger = logger_manager->get_logger(logger_manager, PAYLOAD);
return &this->public; return &this->public;
} }
@@ -90,12 +90,12 @@ enum notify_type_t {
AUTH_LIFETIME = 16403, AUTH_LIFETIME = 16403,
}; };
/** /**
* String mappings for notify_type_t. * enum name for notify_type_t.
* *
* @ingroup payloads * @ingroup payloads
*/ */
extern mapping_t notify_type_m[]; extern enum_name_t *notify_type_names;
typedef struct notify_payload_t notify_payload_t; typedef struct notify_payload_t notify_payload_t;
+58 -60
View File
@@ -43,67 +43,65 @@
#include <encoding/payloads/eap_payload.h> #include <encoding/payloads/eap_payload.h>
#include <encoding/payloads/unknown_payload.h> #include <encoding/payloads/unknown_payload.h>
/*
* build the mappings for payload_type_t
*/
mapping_t payload_type_m[] = {
{NO_PAYLOAD, "NO_PAYLOAD"},
{SECURITY_ASSOCIATION, "SECURITY_ASSOCIATION"},
{KEY_EXCHANGE, "KEY_EXCHANGE"},
{ID_INITIATOR, "ID_INITIATOR"},
{ID_RESPONDER, "ID_RESPONDER"},
{CERTIFICATE, "CERTIFICATE"},
{CERTIFICATE_REQUEST, "CERTIFICATE_REQUEST"},
{AUTHENTICATION, "AUTHENTICATION"},
{NONCE, "NONCE"},
{NOTIFY, "NOTIFY"},
{DELETE, "DELETE"},
{VENDOR_ID, "VENDOR_ID"},
{TRAFFIC_SELECTOR_INITIATOR, "TRAFFIC_SELECTOR_INITIATOR"},
{TRAFFIC_SELECTOR_RESPONDER, "TRAFFIC_SELECTOR_RESPONDER"},
{ENCRYPTED, "ENCRYPTED"},
{CONFIGURATION, "CONFIGURATION"},
{EXTENSIBLE_AUTHENTICATION, "EXTENSIBLE_AUTHENTICATION"},
{HEADER, "HEADER"},
{PROPOSAL_SUBSTRUCTURE, "PROPOSAL_SUBSTRUCTURE"},
{TRANSFORM_SUBSTRUCTURE, "TRANSFORM_SUBSTRUCTURE"},
{TRANSFORM_ATTRIBUTE, "TRANSFORM_ATTRIBUTE"},
{TRAFFIC_SELECTOR_SUBSTRUCTURE, "TRAFFIC_SELECTOR_SUBSTRUCTURE"},
{CONFIGURATION_ATTRIBUTE,"CONFIGURATION_ATTRIBUTE"},
{UNKNOWN_PAYLOAD,"UNKNOWN_PAYLOAD"},
{MAPPING_END, NULL}
};
/* ENUM_BEGIN(payload_type_names, NO_PAYLOAD, NO_PAYLOAD,
* build the short mappings for payload_type_t "NO_PAYLOAD");
*/ ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, NO_PAYLOAD,
mapping_t payload_type_short_m[] = { "SECURITY_ASSOCIATION",
{NO_PAYLOAD, "--"}, "KEY_EXCHANGE",
{SECURITY_ASSOCIATION, "SA"}, "ID_INITIATOR",
{KEY_EXCHANGE, "KE"}, "ID_RESPONDER",
{ID_INITIATOR, "IDi"}, "CERTIFICATE",
{ID_RESPONDER, "IDr"}, "CERTIFICATE_REQUEST",
{CERTIFICATE, "CERT"}, "AUTHENTICATION",
{CERTIFICATE_REQUEST, "CERTREQ"}, "NONCE",
{AUTHENTICATION, "AUTH"}, "NOTIFY",
{NONCE, "No"}, "DELETE",
{NOTIFY, "N"}, "VENDOR_ID",
{DELETE, "D"}, "TRAFFIC_SELECTOR_INITIATOR",
{VENDOR_ID, "V"}, "TRAFFIC_SELECTOR_RESPONDER",
{TRAFFIC_SELECTOR_INITIATOR, "TSi"}, "ENCRYPTED",
{TRAFFIC_SELECTOR_RESPONDER, "TSr"}, "CONFIGURATION",
{ENCRYPTED, "E"}, "EXTENSIBLE_AUTHENTICATION");
{CONFIGURATION, "CP"}, ENUM_NEXT(payload_type_names, HEADER, UNKNOWN_PAYLOAD, EXTENSIBLE_AUTHENTICATION,
{EXTENSIBLE_AUTHENTICATION, "EAP"}, "HEADER",
{HEADER, "HDR"}, "PROPOSAL_SUBSTRUCTURE",
{PROPOSAL_SUBSTRUCTURE, "PROP"}, "TRANSFORM_SUBSTRUCTURE",
{TRANSFORM_SUBSTRUCTURE, "TRANS"}, "TRANSFORM_ATTRIBUTE",
{TRANSFORM_ATTRIBUTE, "TRANSATTR"}, "TRAFFIC_SELECTOR_SUBSTRUCTURE",
{TRAFFIC_SELECTOR_SUBSTRUCTURE, "TSSUB"}, "CONFIGURATION_ATTRIBUTE",
{CONFIGURATION_ATTRIBUTE, "CPATTR"}, "UNKNOWN_PAYLOAD");
{UNKNOWN_PAYLOAD, "??"}, ENUM_END(payload_type_names, UNKNOWN_PAYLOAD);
{MAPPING_END, NULL}
}; /* short forms of payload names */
ENUM_BEGIN(payload_type_short_names, NO_PAYLOAD, NO_PAYLOAD,
"--");
ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, NO_PAYLOAD,
"SA",
"KE",
"IDi",
"IDr",
"CERT",
"CERTREQ",
"AUTH",
"No",
"N",
"D",
"V",
"TSi",
"TSr",
"E",
"CP",
"EAP");
ENUM_NEXT(payload_type_short_names, HEADER, UNKNOWN_PAYLOAD, EXTENSIBLE_AUTHENTICATION,
"HDR",
"PROP",
"TRANS",
"TRANSATTR",
"TSSUB",
"CPATTR",
"??");
ENUM_END(payload_type_short_names, UNKNOWN_PAYLOAD);
/* /*
* see header * see header
+4 -4
View File
@@ -185,14 +185,14 @@ enum payload_type_t{
/** /**
* String mappings for payload_type_t. * enum names for payload_type_t.
*/ */
extern mapping_t payload_type_m[]; extern enum_name_t *payload_type_names;
/** /**
* Special string mappings for payload_type_t in a short form. * enum names for payload_type_t in a short form.
*/ */
extern mapping_t payload_type_short_m[]; extern enum_name_t *payload_type_short_names;
typedef struct payload_t payload_t; typedef struct payload_t payload_t;
@@ -29,7 +29,7 @@
#include <encoding/payloads/transform_substructure.h> #include <encoding/payloads/transform_substructure.h>
#include <types.h> #include <types.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger_manager.h> #include <daemon.h>
/** /**
@@ -89,18 +89,6 @@ struct private_proposal_substructure_t {
* Transforms are stored in a linked_list_t. * Transforms are stored in a linked_list_t.
*/ */
linked_list_t * transforms; linked_list_t * transforms;
/**
* assigned logger
*/
logger_t *logger;
/**
* @brief Computes the length of this substructure.
*
* @param this calling private_proposal_substructure_t object
*/
void (*compute_length) (private_proposal_substructure_t *this);
}; };
/** /**
@@ -158,13 +146,13 @@ static status_t verify(private_proposal_substructure_t *this)
if ((this->next_payload != NO_PAYLOAD) && (this->next_payload != 2)) if ((this->next_payload != NO_PAYLOAD) && (this->next_payload != 2))
{ {
/* must be 0 or 2 */ /* must be 0 or 2 */
this->logger->log(this->logger, ERROR, "inconsistent next payload"); DBG1(SIG_DBG_ENC, "inconsistent next payload");
return FAILED; return FAILED;
} }
if (this->transforms_count != this->transforms->get_count(this->transforms)) if (this->transforms_count != this->transforms->get_count(this->transforms))
{ {
/* must be the same! */ /* must be the same! */
this->logger->log(this->logger, ERROR, "transform count invalid"); DBG1(SIG_DBG_ENC, "transform count invalid");
return FAILED; return FAILED;
} }
@@ -174,29 +162,26 @@ static status_t verify(private_proposal_substructure_t *this)
case PROTO_ESP: case PROTO_ESP:
if (this->spi.len != 4) if (this->spi.len != 4)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_ENC, "invalid SPI length in %N proposal",
"invalid SPI length in %s proposal", protocol_id_names, this->protocol_id);
mapping_find(protocol_id_m, this->protocol_id));
return FAILED; return FAILED;
} }
break; break;
case PROTO_IKE: case PROTO_IKE:
if (this->spi.len != 0 && this->spi.len != 8) if (this->spi.len != 0 && this->spi.len != 8)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_ENC, "invalid SPI length in IKE proposal");
"invalid SPI length in IKE proposal");
return FAILED; return FAILED;
} }
break; break;
default: default:
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_ENC, "invalid proposal protocol (%d)", this->protocol_id);
"invalid proposal protocol (%d)", this->protocol_id);
return FAILED; return FAILED;
} }
if ((this->protocol_id == 0) || (this->protocol_id >= 4)) if ((this->protocol_id == 0) || (this->protocol_id >= 4))
{ {
/* reserved are not supported */ /* reserved are not supported */
this->logger->log(this->logger, ERROR, "invalid protocol"); DBG1(SIG_DBG_ENC, "invalid protocol");
return FAILED; return FAILED;
} }
@@ -209,7 +194,7 @@ static status_t verify(private_proposal_substructure_t *this)
status = current_transform->verify(current_transform); status = current_transform->verify(current_transform);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "TRANSFORM_SUBSTRUCTURE verification failed"); DBG1(SIG_DBG_ENC, "TRANSFORM_SUBSTRUCTURE verification failed");
break; break;
} }
} }
@@ -251,12 +236,35 @@ static void set_next_type(private_proposal_substructure_t *this,payload_type_t t
{ {
} }
/**
* (re-)compute the length of the payload.
*/
static void compute_length(private_proposal_substructure_t *this)
{
iterator_t *iterator;
size_t transforms_count = 0;
size_t length = PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH;
iterator = this->transforms->create_iterator(this->transforms,TRUE);
while (iterator->has_next(iterator))
{
payload_t * current_transform;
iterator->current(iterator,(void **) &current_transform);
length += current_transform->get_length(current_transform);
transforms_count++;
}
iterator->destroy(iterator);
length += this->spi.len;
this->transforms_count = transforms_count;
this->proposal_length = length;
}
/** /**
* Implementation of payload_t.get_length. * Implementation of payload_t.get_length.
*/ */
static size_t get_length(private_proposal_substructure_t *this) static size_t get_length(private_proposal_substructure_t *this)
{ {
this->compute_length(this); compute_length(this);
return this->proposal_length; return this->proposal_length;
} }
@@ -285,7 +293,7 @@ static void add_transform_substructure (private_proposal_substructure_t *this,tr
transform->set_is_last_transform(transform,TRUE); transform->set_is_last_transform(transform,TRUE);
this->transforms->insert_last(this->transforms,(void *) transform); this->transforms->insert_last(this->transforms,(void *) transform);
this->compute_length(this); compute_length(this);
} }
/** /**
@@ -339,13 +347,13 @@ static void set_spi(private_proposal_substructure_t *this, chunk_t spi)
free(this->spi.ptr); free(this->spi.ptr);
this->spi.ptr = NULL; this->spi.ptr = NULL;
this->spi.len = 0; this->spi.len = 0;
this->compute_length(this); compute_length(this);
} }
this->spi.ptr = clalloc(spi.ptr,spi.len); this->spi.ptr = clalloc(spi.ptr,spi.len);
this->spi.len = spi.len; this->spi.len = spi.len;
this->spi_size = spi.len; this->spi_size = spi.len;
this->compute_length(this); compute_length(this);
} }
/** /**
@@ -360,29 +368,6 @@ static chunk_t get_spi(private_proposal_substructure_t *this)
return spi; return spi;
} }
/**
* Implementation of private_proposal_substructure_t.compute_length.
*/
static void compute_length(private_proposal_substructure_t *this)
{
iterator_t *iterator;
size_t transforms_count = 0;
size_t length = PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH;
iterator = this->transforms->create_iterator(this->transforms,TRUE);
while (iterator->has_next(iterator))
{
payload_t * current_transform;
iterator->current(iterator,(void **) &current_transform);
length += current_transform->get_length(current_transform);
transforms_count++;
}
iterator->destroy(iterator);
length += this->spi.len;
this->transforms_count = transforms_count;
this->proposal_length = length;
}
/** /**
* Implementation of proposal_substructure_t.get_transform_count. * Implementation of proposal_substructure_t.get_transform_count.
*/ */
@@ -544,9 +529,6 @@ proposal_substructure_t *proposal_substructure_create()
this->public.clone = (proposal_substructure_t * (*) (proposal_substructure_t *)) clone_; this->public.clone = (proposal_substructure_t * (*) (proposal_substructure_t *)) clone_;
this->public.destroy = (void (*) (proposal_substructure_t *)) destroy; this->public.destroy = (void (*) (proposal_substructure_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */ /* set default values of the fields */
this->next_payload = NO_PAYLOAD; this->next_payload = NO_PAYLOAD;
this->proposal_length = 0; this->proposal_length = 0;
@@ -556,7 +538,6 @@ proposal_substructure_t *proposal_substructure_create()
this->spi_size = 0; this->spi_size = 0;
this->spi.ptr = NULL; this->spi.ptr = NULL;
this->spi.len = 0; this->spi.len = 0;
this->logger = logger_manager->get_logger(logger_manager, PAYLOAD);
this->transforms = linked_list_create(); this->transforms = linked_list_create();
+27 -44
View File
@@ -27,7 +27,7 @@
#include <encoding/payloads/encodings.h> #include <encoding/payloads/encodings.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger_manager.h> #include <daemon.h>
typedef struct private_sa_payload_t private_sa_payload_t; typedef struct private_sa_payload_t private_sa_payload_t;
@@ -61,18 +61,6 @@ struct private_sa_payload_t {
* Proposals in this payload are stored in a linked_list_t. * Proposals in this payload are stored in a linked_list_t.
*/ */
linked_list_t * proposals; linked_list_t * proposals;
/**
* Logger for error handling
*/
logger_t *logger;
/**
* @brief Computes the length of this payload.
*
* @param this calling private_sa_payload_t object
*/
void (*compute_length) (private_sa_payload_t *this);
}; };
/** /**
@@ -136,15 +124,15 @@ static status_t verify(private_sa_payload_t *this)
{ {
if (first) if (first)
{ {
this->logger->log(this->logger, ERROR, "first proposal is not proposal #1"); DBG1(SIG_DBG_ENC, "first proposal is not proposal #1");
status = FAILED; status = FAILED;
break; break;
} }
if (current_number != (expected_number + 1)) if (current_number != (expected_number + 1))
{ {
this->logger->log(this->logger, ERROR, "proposal number is %d, excepted %d or %d", DBG1(SIG_DBG_ENC, "proposal number is %d, excepted %d or %d",
current_number, expected_number, expected_number + 1); current_number, expected_number, expected_number + 1);
status = FAILED; status = FAILED;
break; break;
} }
@@ -152,7 +140,7 @@ static status_t verify(private_sa_payload_t *this)
else if (current_number < expected_number) else if (current_number < expected_number)
{ {
/* must not be smaller then proceeding one */ /* must not be smaller then proceeding one */
this->logger->log(this->logger, ERROR, "proposal number smaller than that of previous proposal"); DBG1(SIG_DBG_ENC, "proposal number smaller than that of previous proposal");
status = FAILED; status = FAILED;
break; break;
} }
@@ -160,7 +148,7 @@ static status_t verify(private_sa_payload_t *this)
status = current_proposal->payload_interface.verify(&(current_proposal->payload_interface)); status = current_proposal->payload_interface.verify(&(current_proposal->payload_interface));
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "PROPOSAL_SUBSTRUCTURE verification failed"); DBG1(SIG_DBG_ENC, "PROPOSAL_SUBSTRUCTURE verification failed");
break; break;
} }
first = FALSE; first = FALSE;
@@ -224,12 +212,31 @@ static void set_next_type(private_sa_payload_t *this,payload_type_t type)
this->next_payload = type; this->next_payload = type;
} }
/**
* recompute length of the payload.
*/
static void compute_length (private_sa_payload_t *this)
{
iterator_t *iterator;
size_t length = SA_PAYLOAD_HEADER_LENGTH;
iterator = this->proposals->create_iterator(this->proposals,TRUE);
while (iterator->has_next(iterator))
{
payload_t *current_proposal;
iterator->current(iterator,(void **) &current_proposal);
length += current_proposal->get_length(current_proposal);
}
iterator->destroy(iterator);
this->payload_length = length;
}
/** /**
* Implementation of payload_t.get_length. * Implementation of payload_t.get_length.
*/ */
static size_t get_length(private_sa_payload_t *this) static size_t get_length(private_sa_payload_t *this)
{ {
this->compute_length(this); compute_length(this);
return this->payload_length; return this->payload_length;
} }
@@ -259,7 +266,7 @@ static void add_proposal_substructure(private_sa_payload_t *this,proposal_substr
proposal->set_is_last_proposal(proposal, TRUE); proposal->set_is_last_proposal(proposal, TRUE);
proposal->set_proposal_number(proposal, proposal_count + 1); proposal->set_proposal_number(proposal, proposal_count + 1);
this->proposals->insert_last(this->proposals,(void *) proposal); this->proposals->insert_last(this->proposals,(void *) proposal);
this->compute_length(this); compute_length(this);
} }
/** /**
@@ -321,25 +328,6 @@ static linked_list_t *get_proposals(private_sa_payload_t *this)
return proposal_list; return proposal_list;
} }
/**
* Implementation of private_sa_payload_t.compute_length.
*/
static void compute_length (private_sa_payload_t *this)
{
iterator_t *iterator;
size_t length = SA_PAYLOAD_HEADER_LENGTH;
iterator = this->proposals->create_iterator(this->proposals,TRUE);
while (iterator->has_next(iterator))
{
payload_t *current_proposal;
iterator->current(iterator,(void **) &current_proposal);
length += current_proposal->get_length(current_proposal);
}
iterator->destroy(iterator);
this->payload_length = length;
}
/* /*
* Described in header. * Described in header.
*/ */
@@ -363,15 +351,10 @@ sa_payload_t *sa_payload_create()
this->public.get_proposals = (linked_list_t* (*) (sa_payload_t *)) get_proposals; this->public.get_proposals = (linked_list_t* (*) (sa_payload_t *)) get_proposals;
this->public.destroy = (void (*) (sa_payload_t *)) destroy; this->public.destroy = (void (*) (sa_payload_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */ /* set default values of the fields */
this->critical = FALSE; this->critical = FALSE;
this->next_payload = NO_PAYLOAD; this->next_payload = NO_PAYLOAD;
this->payload_length = SA_PAYLOAD_HEADER_LENGTH; this->payload_length = SA_PAYLOAD_HEADER_LENGTH;
this->logger = logger_manager->get_logger(logger_manager, PARSER);
this->proposals = linked_list_create(); this->proposals = linked_list_create();
return &this->public; return &this->public;
} }
@@ -26,15 +26,6 @@
#include <encoding/payloads/encodings.h> #include <encoding/payloads/encodings.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
/**
* String mappings for ts_type_t.
*/
mapping_t ts_type_m[] = {
{TS_IPV4_ADDR_RANGE, "TS_IPV4_ADDR_RANGE"},
{TS_IPV6_ADDR_RANGE, "TS_IPV6_ADDR_RANGE"},
{MAPPING_END, NULL}
};
typedef struct private_traffic_selector_substructure_t private_traffic_selector_substructure_t; typedef struct private_traffic_selector_substructure_t private_traffic_selector_substructure_t;
@@ -65,14 +65,12 @@ struct private_transform_attribute_t {
chunk_t attribute_value; chunk_t attribute_value;
}; };
/**
* String mappings for transform_attribute_type_t. ENUM_BEGIN(transform_attribute_type_name, ATTRIBUTE_UNDEFINED, ATTRIBUTE_UNDEFINED,
*/ "ATTRIBUTE_UNDEFINED");
mapping_t transform_attribute_type_m[] = { ENUM_NEXT(transform_attribute_type_name, KEY_LENGTH, KEY_LENGTH, ATTRIBUTE_UNDEFINED,
{ATTRIBUTE_UNDEFINED, "ATTRIBUTE_UNDEFINED"}, "KEY_LENGTH");
{KEY_LENGTH, "KEY_LENGTH"}, ENUM_END(transform_attribute_type_name, KEY_LENGTH);
{MAPPING_END, NULL}
};
/** /**
* Encoding rules to parse or generate a Transform attribute. * Encoding rules to parse or generate a Transform attribute.
@@ -41,11 +41,11 @@ enum transform_attribute_type_t {
}; };
/** /**
* String mappings for transform_attribute_type_t. * enum name for transform_attribute_type_t.
* *
* @ingroup payloads * @ingroup payloads
*/ */
extern mapping_t transform_attribute_type_m[]; extern enum_name_t *transform_attribute_type_names;
typedef struct transform_attribute_t transform_attribute_t; typedef struct transform_attribute_t transform_attribute_t;
@@ -29,7 +29,7 @@
#include <encoding/payloads/encodings.h> #include <encoding/payloads/encodings.h>
#include <types.h> #include <types.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger_manager.h> #include <daemon.h>
typedef struct private_transform_substructure_t private_transform_substructure_t; typedef struct private_transform_substructure_t private_transform_substructure_t;
@@ -70,18 +70,6 @@ struct private_transform_substructure_t {
* Transforms Attributes are stored in a linked_list_t. * Transforms Attributes are stored in a linked_list_t.
*/ */
linked_list_t *attributes; linked_list_t *attributes;
/**
* assigned logger
*/
logger_t *logger;
/**
* @brief Computes the length of this substructure.
*
* @param this calling private_transform_substructure_t object
*/
void (*compute_length) (private_transform_substructure_t *this);
}; };
@@ -136,7 +124,7 @@ static status_t verify(private_transform_substructure_t *this)
if ((this->next_payload != NO_PAYLOAD) && (this->next_payload != 3)) if ((this->next_payload != NO_PAYLOAD) && (this->next_payload != 3))
{ {
/* must be 0 or 3 */ /* must be 0 or 3 */
this->logger->log(this->logger, ERROR, "inconsistent next payload"); DBG1(SIG_DBG_ENC, "inconsistent next payload");
return FAILED; return FAILED;
} }
@@ -152,8 +140,7 @@ static status_t verify(private_transform_substructure_t *this)
break; break;
default: default:
{ {
this->logger->log(this->logger, ERROR, "invalid transform type: %d", DBG1(SIG_DBG_ENC, "invalid transform type: %d", this->transform_type);
this->transform_type);
return FAILED; return FAILED;
} }
} }
@@ -167,8 +154,7 @@ static status_t verify(private_transform_substructure_t *this)
status = current_attributes->verify(current_attributes); status = current_attributes->verify(current_attributes);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_ENC, "TRANSFORM_ATTRIBUTE verification failed");
"TRANSFORM_ATTRIBUTE verification failed");
} }
} }
iterator->destroy(iterator); iterator->destroy(iterator);
@@ -202,13 +188,31 @@ static payload_type_t get_next_type(private_transform_substructure_t *this)
return (this->next_payload); return (this->next_payload);
} }
/**
* recompute the length of the payload.
*/
static void compute_length (private_transform_substructure_t *this)
{
iterator_t *iterator;
size_t length = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
iterator = this->attributes->create_iterator(this->attributes,TRUE);
while (iterator->has_next(iterator))
{
payload_t * current_attribute;
iterator->current(iterator,(void **) &current_attribute);
length += current_attribute->get_length(current_attribute);
}
iterator->destroy(iterator);
this->transform_length = length;
}
/** /**
* Implementation of payload_t.get_length. * Implementation of payload_t.get_length.
*/ */
static size_t get_length(private_transform_substructure_t *this) static size_t get_length(private_transform_substructure_t *this)
{ {
this->compute_length(this); compute_length(this);
return this->transform_length; return this->transform_length;
} }
@@ -226,7 +230,7 @@ static iterator_t *create_transform_attribute_iterator (private_transform_substr
static void add_transform_attribute (private_transform_substructure_t *this,transform_attribute_t *attribute) static void add_transform_attribute (private_transform_substructure_t *this,transform_attribute_t *attribute)
{ {
this->attributes->insert_last(this->attributes,(void *) attribute); this->attributes->insert_last(this->attributes,(void *) attribute);
this->compute_length(this); compute_length(this);
} }
/** /**
@@ -284,25 +288,6 @@ static u_int16_t get_transform_id (private_transform_substructure_t *this)
return this->transform_id; return this->transform_id;
} }
/**
* Implementation of private_transform_substructure_t.compute_length.
*/
static void compute_length (private_transform_substructure_t *this)
{
iterator_t *iterator;
size_t length = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
iterator = this->attributes->create_iterator(this->attributes,TRUE);
while (iterator->has_next(iterator))
{
payload_t * current_attribute;
iterator->current(iterator,(void **) &current_attribute);
length += current_attribute->get_length(current_attribute);
}
iterator->destroy(iterator);
this->transform_length = length;
}
/** /**
* Implementation of transform_substructure_t.clone. * Implementation of transform_substructure_t.clone.
*/ */
@@ -410,16 +395,12 @@ transform_substructure_t *transform_substructure_create()
this->public.clone = (transform_substructure_t* (*) (transform_substructure_t *)) clone_; this->public.clone = (transform_substructure_t* (*) (transform_substructure_t *)) clone_;
this->public.destroy = (void (*) (transform_substructure_t *)) destroy; this->public.destroy = (void (*) (transform_substructure_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */ /* set default values of the fields */
this->next_payload = NO_PAYLOAD; this->next_payload = NO_PAYLOAD;
this->transform_length = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH; this->transform_length = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
this->transform_id = 0; this->transform_id = 0;
this->transform_type = 0; this->transform_type = 0;
this->attributes = linked_list_create(); this->attributes = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, PAYLOAD);
return (&(this->public)); return (&(this->public));
} }
+24 -35
View File
@@ -69,13 +69,6 @@ struct private_ts_payload_t {
* Contains the traffic selectors of type traffic_selector_substructure_t. * Contains the traffic selectors of type traffic_selector_substructure_t.
*/ */
linked_list_t *traffic_selectors; linked_list_t *traffic_selectors;
/**
* @brief Computes the length of this payload.
*
* @param this calling private_ts_payload_t object
*/
void (*compute_length) (private_ts_payload_t *this);
}; };
/** /**
@@ -195,12 +188,35 @@ static void set_next_type(private_ts_payload_t *this,payload_type_t type)
this->next_payload = type; this->next_payload = type;
} }
/**
* recompute the length of the payload.
*/
static void compute_length (private_ts_payload_t *this)
{
iterator_t *iterator;
size_t ts_count = 0;
size_t length = TS_PAYLOAD_HEADER_LENGTH;
iterator = this->traffic_selectors->create_iterator(this->traffic_selectors,TRUE);
while (iterator->has_next(iterator))
{
payload_t * current_traffic_selector;
iterator->current(iterator,(void **) &current_traffic_selector);
length += current_traffic_selector->get_length(current_traffic_selector);
ts_count++;
}
iterator->destroy(iterator);
this->number_of_traffic_selectors= ts_count;
this->payload_length = length;
}
/** /**
* Implementation of payload_t.get_length. * Implementation of payload_t.get_length.
*/ */
static size_t get_length(private_ts_payload_t *this) static size_t get_length(private_ts_payload_t *this)
{ {
this->compute_length(this); compute_length(this);
return this->payload_length; return this->payload_length;
} }
@@ -259,30 +275,6 @@ static linked_list_t *get_traffic_selectors(private_ts_payload_t *this)
return ts_list; return ts_list;
} }
/**
* Implementation of private_ts_payload_t.compute_length.
*/
static void compute_length (private_ts_payload_t *this)
{
iterator_t *iterator;
size_t ts_count = 0;
size_t length = TS_PAYLOAD_HEADER_LENGTH;
iterator = this->traffic_selectors->create_iterator(this->traffic_selectors,TRUE);
while (iterator->has_next(iterator))
{
payload_t * current_traffic_selector;
iterator->current(iterator,(void **) &current_traffic_selector);
length += current_traffic_selector->get_length(current_traffic_selector);
ts_count++;
}
iterator->destroy(iterator);
this->number_of_traffic_selectors= ts_count;
this->payload_length = length;
}
/** /**
* Implementation of payload_t.destroy and ts_payload_t.destroy. * Implementation of payload_t.destroy and ts_payload_t.destroy.
*/ */
@@ -326,9 +318,6 @@ ts_payload_t *ts_payload_create(bool is_initiator)
this->public.create_traffic_selector_substructure_iterator = (iterator_t* (*) (ts_payload_t *,bool)) create_traffic_selector_substructure_iterator; this->public.create_traffic_selector_substructure_iterator = (iterator_t* (*) (ts_payload_t *,bool)) create_traffic_selector_substructure_iterator;
this->public.get_traffic_selectors = (linked_list_t *(*) (ts_payload_t *)) get_traffic_selectors; this->public.get_traffic_selectors = (linked_list_t *(*) (ts_payload_t *)) get_traffic_selectors;
/* private functions */
this->compute_length = compute_length;
/* private variables */ /* private variables */
this->critical = FALSE; this->critical = FALSE;
this->next_payload = NO_PAYLOAD; this->next_payload = NO_PAYLOAD;
+36 -71
View File
@@ -43,7 +43,6 @@
#include "socket.h" #include "socket.h"
#include <daemon.h> #include <daemon.h>
#include <utils/logger_manager.h>
/* constants for packet handling */ /* constants for packet handling */
#define IP_LEN sizeof(struct iphdr) #define IP_LEN sizeof(struct iphdr)
@@ -126,11 +125,6 @@ struct private_socket_t{
* send socket on nat-t port for IPv6 * send socket on nat-t port for IPv6
*/ */
int send6_natt; int send6_natt;
/**
* logger for this socket
*/
logger_t *logger;
}; };
/** /**
@@ -158,8 +152,7 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
FD_SET(this->recv6, &rfds); FD_SET(this->recv6, &rfds);
} }
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_NET, "waiting for data on raw sockets");
"waiting for data on raw sockets");
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
if (select(max(this->recv4, this->recv6) + 1, &rfds, NULL, NULL, NULL) <= 0) if (select(max(this->recv4, this->recv6) + 1, &rfds, NULL, NULL, NULL) <= 0)
@@ -179,18 +172,16 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
bytes_read = recv(this->recv4, buffer, MAX_PACKET, 0); bytes_read = recv(this->recv4, buffer, MAX_PACKET, 0);
if (bytes_read < 0) if (bytes_read < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "error reading from IPv4 socket: %m");
"error reading from IPv4 socket: %m");
return FAILED; return FAILED;
} }
this->logger->log_bytes(this->logger, RAW, DBG3(SIG_DBG_NET, "received IPv4 packet %b", buffer, bytes_read);
"received IPv4 packet", buffer, bytes_read);
/* read source/dest from raw IP/UDP header */ /* read source/dest from raw IP/UDP header */
if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN) if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "received IPv4 packet too short (%d bytes)",
"received IPv4 packet too short"); bytes_read);
return FAILED; return FAILED;
} }
ip = (struct iphdr*) buffer; ip = (struct iphdr*) buffer;
@@ -207,8 +198,7 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
pkt = packet_create(); pkt = packet_create();
pkt->set_source(pkt, source); pkt->set_source(pkt, source);
pkt->set_destination(pkt, dest); pkt->set_destination(pkt, dest);
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_NET, "received packet: from %#H to %#H", source, dest);
"received packet: from %#H to %#H", source, dest);
data_offset = IP_LEN + UDP_LEN; data_offset = IP_LEN + UDP_LEN;
/* remove non esp marker */ /* remove non esp marker */
if (dest->get_port(dest) == this->natt_port) if (dest->get_port(dest) == this->natt_port)
@@ -244,17 +234,15 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
bytes_read = recvmsg(this->recv6, &msg, 0); bytes_read = recvmsg(this->recv6, &msg, 0);
if (bytes_read < 0) if (bytes_read < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "error reading from IPv6 socket: %m");
"error reading from IPv6 socket: %m");
return FAILED; return FAILED;
} }
this->logger->log_bytes(this->logger, RAW, DBG3(SIG_DBG_NET, "received IPv6 packet %b", buffer, bytes_read);
"received IPv6 packet", buffer, bytes_read);
if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN) if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
{ {
this->logger->log(this->logger, ERROR, DBG3(SIG_DBG_NET, "received IPv6 packet too short (%d bytes)",
"received IPv6 packet too short"); bytes_read);
return FAILED; return FAILED;
} }
@@ -262,10 +250,9 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
{ {
if (cmsgptr->cmsg_len == 0) if (cmsgptr->cmsg_len == 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "error reading IPv6 ancillary data");
"error reading IPv6 ancillary data: %m");
return FAILED; return FAILED;
} }
if (cmsgptr->cmsg_level == SOL_IPV6 && if (cmsgptr->cmsg_level == SOL_IPV6 &&
@@ -286,8 +273,7 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
/* ancillary data missing? */ /* ancillary data missing? */
if (dest == NULL) if (dest == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "error reading IPv6 packet header");
"error reading IPv6 packet header");
return FAILED; return FAILED;
} }
@@ -296,8 +282,7 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
pkt = packet_create(); pkt = packet_create();
pkt->set_source(pkt, source); pkt->set_source(pkt, source);
pkt->set_destination(pkt, dest); pkt->set_destination(pkt, dest);
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_NET, "received packet: from %#H to %#H", source, dest);
"received packet: from %#H to %#H", source, dest);
data_offset = UDP_LEN; data_offset = UDP_LEN;
/* remove non esp marker */ /* remove non esp marker */
if (dest->get_port(dest) == this->natt_port) if (dest->get_port(dest) == this->natt_port)
@@ -335,8 +320,7 @@ status_t sender(private_socket_t *this, packet_t *packet)
dst = packet->get_destination(packet); dst = packet->get_destination(packet);
data = packet->get_data(packet); data = packet->get_data(packet);
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_NET, "sending packet: from %#H to %#H", src, dst);
"sending packet: from %#H to %#H", src, dst);
/* send data */ /* send data */
sport = src->get_port(src); sport = src->get_port(src);
@@ -368,8 +352,8 @@ status_t sender(private_socket_t *this, packet_t *packet)
/* add non esp marker to packet */ /* add non esp marker to packet */
if (data.len > MAX_PACKET - MARKER_LEN) if (data.len > MAX_PACKET - MARKER_LEN)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "unable to send packet: it's too big (%d bytes)",
"unable to send packet: it's too big"); data.len);
return FAILED; return FAILED;
} }
marked = chunk_alloc(data.len + MARKER_LEN); marked = chunk_alloc(data.len + MARKER_LEN);
@@ -382,8 +366,7 @@ status_t sender(private_socket_t *this, packet_t *packet)
} }
else else
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "unable to locate a send socket for port %d", sport);
"unable to locate a send socket for port %d", sport);
return FAILED; return FAILED;
} }
@@ -392,8 +375,7 @@ status_t sender(private_socket_t *this, packet_t *packet)
if (bytes_sent != data.len) if (bytes_sent != data.len)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "error writing to socket: %m");
"error writing to socket: %m");
return FAILED; return FAILED;
} }
return SUCCESS; return SUCCESS;
@@ -551,14 +533,13 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
skt = socket(family, SOCK_DGRAM, IPPROTO_UDP); skt = socket(family, SOCK_DGRAM, IPPROTO_UDP);
if (skt < 0) if (skt < 0)
{ {
this->logger->log(this->logger, ERROR, "could not open send socket: %m"); DBG1(SIG_DBG_NET, "could not open send socket: %m");
return 0; return 0;
} }
if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0) if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "unable to set SO_REUSEADDR on send socket: %m");
"unable to set SO_REUSEADDR on send socket: %m");
close(skt); close(skt);
return 0; return 0;
} }
@@ -574,8 +555,7 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0) if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "unable to set IPSEC_POLICY on send socket: %m");
"unable to set IPSEC_POLICY on send socket: %m");
close(skt); close(skt);
return 0; return 0;
} }
@@ -585,8 +565,7 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND; policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0) if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "unable to set IPSEC_POLICY on send socket: %m");
"unable to set IPSEC_POLICY on send socket: %m");
close(skt); close(skt);
return 0; return 0;
} }
@@ -594,7 +573,7 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
/* bind the send socket */ /* bind the send socket */
if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0) if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{ {
this->logger->log(this->logger, ERROR, "unable to bind send socket: %m"); DBG1(SIG_DBG_NET, "unable to bind send socket: %m");
close(skt); close(skt);
return 0; return 0;
} }
@@ -604,8 +583,7 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
/* enable UDP decapsulation globally, only for one socket needed */ /* enable UDP decapsulation globally, only for one socket needed */
if (setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) if (setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "unable to set UDP_ENCAP: %m; NAT-T may fail");
"unable to set UDP_ENCAP: %m; NAT-T may fail");
} }
} }
@@ -686,16 +664,14 @@ static int open_recv_socket(private_socket_t *this, int family)
skt = socket(family, SOCK_RAW, IPPROTO_UDP); skt = socket(family, SOCK_RAW, IPPROTO_UDP);
if (skt < 0) if (skt < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "unable to create raw socket: %m");
"unable to create raw socket: %m");
return 0; return 0;
} }
if (setsockopt(skt, SOL_SOCKET, SO_ATTACH_FILTER, if (setsockopt(skt, SOL_SOCKET, SO_ATTACH_FILTER,
&ikev2_filter, sizeof(ikev2_filter)) < 0) &ikev2_filter, sizeof(ikev2_filter)) < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "unable to attach IKEv2 filter to raw socket: %m");
"unable to attach IKEv2 filter to raw socket: %m");
close(skt); close(skt);
return 0; return 0;
} }
@@ -705,8 +681,7 @@ static int open_recv_socket(private_socket_t *this, int family)
* 2 or 50 depending on kernel header version */ * 2 or 50 depending on kernel header version */
setsockopt(skt, sol, IPV6_2292PKTINFO, &on, sizeof(on)) < 0) setsockopt(skt, sol, IPV6_2292PKTINFO, &on, sizeof(on)) < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "unable to set IPV6_PKTINFO on raw socket: %m");
"unable to set IPV6_PKTINFO on raw socket: %m");
close(skt); close(skt);
return 0; return 0;
} }
@@ -722,8 +697,7 @@ static int open_recv_socket(private_socket_t *this, int family)
if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0) if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "unable to set IPSEC_POLICY on raw socket: %m");
"unable to set IPSEC_POLICY on raw socket: %m");
close(skt); close(skt);
return 0; return 0;
} }
@@ -776,8 +750,6 @@ socket_t *socket_create(u_int16_t port, u_int16_t natt_port)
this->public.is_local_address = (bool(*)(socket_t*, host_t*,char**))is_local_address; this->public.is_local_address = (bool(*)(socket_t*, host_t*,char**))is_local_address;
this->public.create_local_address_list = (linked_list_t*(*)(socket_t*))create_local_address_list; this->public.create_local_address_list = (linked_list_t*(*)(socket_t*))create_local_address_list;
this->public.destroy = (void(*)(socket_t*)) destroy; this->public.destroy = (void(*)(socket_t*)) destroy;
this->logger = logger_manager->get_logger(logger_manager, SOCKET);
this->port = port; this->port = port;
this->natt_port = natt_port; this->natt_port = natt_port;
@@ -791,16 +763,14 @@ socket_t *socket_create(u_int16_t port, u_int16_t natt_port)
this->recv4 = open_recv_socket(this, AF_INET); this->recv4 = open_recv_socket(this, AF_INET);
if (this->recv4 == 0) if (this->recv4 == 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "could not open IPv4 receive socket, IPv4 disabled");
"could not open IPv4 receive socket, IPv4 disabled");
} }
else else
{ {
this->send4 = open_send_socket(this, AF_INET, this->port); this->send4 = open_send_socket(this, AF_INET, this->port);
if (this->send4 == 0) if (this->send4 == 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "could not open IPv4 send socket, IPv4 disabled");
"could not open IPv4 send socket, IPv4 disabled");
close(this->recv4); close(this->recv4);
} }
else else
@@ -808,8 +778,7 @@ socket_t *socket_create(u_int16_t port, u_int16_t natt_port)
this->send4_natt = open_send_socket(this, AF_INET, this->natt_port); this->send4_natt = open_send_socket(this, AF_INET, this->natt_port);
if (this->send4_natt == 0) if (this->send4_natt == 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "could not open IPv4 NAT-T send socket");
"could not open IPv4 NAT-T send socket");
} }
} }
} }
@@ -817,16 +786,14 @@ socket_t *socket_create(u_int16_t port, u_int16_t natt_port)
this->recv6 = open_recv_socket(this, AF_INET6); this->recv6 = open_recv_socket(this, AF_INET6);
if (this->recv6 == 0) if (this->recv6 == 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "could not open IPv6 receive socket, IPv6 disabled");
"could not open IPv6 receive socket, IPv6 disabled");
} }
else else
{ {
this->send6 = open_send_socket(this, AF_INET6, this->port); this->send6 = open_send_socket(this, AF_INET6, this->port);
if (this->send6 == 0) if (this->send6 == 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "could not open IPv6 send socket, IPv6 disabled");
"could not open IPv6 send socket, IPv6 disabled");
close(this->recv6); close(this->recv6);
} }
else else
@@ -834,16 +801,14 @@ socket_t *socket_create(u_int16_t port, u_int16_t natt_port)
this->send6_natt = open_send_socket(this, AF_INET6, this->natt_port); this->send6_natt = open_send_socket(this, AF_INET6, this->natt_port);
if (this->send6_natt == 0) if (this->send6_natt == 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "could not open IPv6 NAT-T send socket");
"could not open IPv6 NAT-T send socket");
} }
} }
} }
if (!(this->send4 || this->send6) || !(this->recv4 || this->recv6)) if (!(this->send4 || this->send6) || !(this->recv4 || this->recv6))
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "could not create any sockets");
"could not create any sockets");
destroy(this); destroy(this);
charon->kill(charon, "socket initialization failed"); charon->kill(charon, "socket initialization failed");
} }
+2 -8
View File
@@ -40,11 +40,6 @@ struct private_acquire_job_t {
* reqid of the child to rekey * reqid of the child to rekey
*/ */
u_int32_t reqid; u_int32_t reqid;
/**
* Logger ref
*/
logger_t *logger;
}; };
/** /**
@@ -66,8 +61,8 @@ static status_t execute(private_acquire_job_t *this)
this->reqid); this->reqid);
if (ike_sa == NULL) if (ike_sa == NULL)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, DBG2(SIG_DBG_JOB, "CHILD_SA with reqid %d not found for acquiring",
"CHILD_SA not found for acquiring"); this->reqid);
return DESTROY_ME; return DESTROY_ME;
} }
ike_sa->acquire(ike_sa, this->reqid); ike_sa->acquire(ike_sa, this->reqid);
@@ -98,7 +93,6 @@ acquire_job_t *acquire_job_create(u_int32_t reqid)
/* private variables */ /* private variables */
this->reqid = reqid; this->reqid = reqid;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public); return &(this->public);
} }
+2 -8
View File
@@ -51,11 +51,6 @@ struct private_delete_child_sa_job_t {
* inbound SPI of the CHILD_SA * inbound SPI of the CHILD_SA
*/ */
u_int32_t spi; u_int32_t spi;
/**
* Logger ref
*/
logger_t *logger;
}; };
/** /**
@@ -77,8 +72,8 @@ static status_t execute(private_delete_child_sa_job_t *this)
this->reqid); this->reqid);
if (ike_sa == NULL) if (ike_sa == NULL)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, DBG1(SIG_DBG_JOB, "CHILD_SA with reqid %d not found for delete",
"CHILD_SA not found for delete"); this->reqid);
return DESTROY_ME; return DESTROY_ME;
} }
ike_sa->delete_child_sa(ike_sa, this->protocol, this->spi); ike_sa->delete_child_sa(ike_sa, this->protocol, this->spi);
@@ -113,7 +108,6 @@ delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
this->reqid = reqid; this->reqid = reqid;
this->protocol = protocol; this->protocol = protocol;
this->spi = spi; this->spi = spi;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public); return &(this->public);
} }
+2 -9
View File
@@ -45,11 +45,6 @@ struct private_delete_ike_sa_job_t {
* Should the IKE_SA be deleted if it is in ESTABLISHED state? * Should the IKE_SA be deleted if it is in ESTABLISHED state?
*/ */
bool delete_if_established; bool delete_if_established;
/**
* logger ref
*/
logger_t *logger;
}; };
/** /**
@@ -72,7 +67,7 @@ static status_t execute(private_delete_ike_sa_job_t *this)
if (charon->ike_sa_manager->delete(charon->ike_sa_manager, if (charon->ike_sa_manager->delete(charon->ike_sa_manager,
this->ike_sa_id) != SUCCESS) this->ike_sa_id) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, "IKE SA didn't exist anymore"); DBG2(SIG_DBG_JOB, "IKE SA didn't exist anymore");
} }
return DESTROY_ME; return DESTROY_ME;
} }
@@ -96,8 +91,7 @@ static status_t execute(private_delete_ike_sa_job_t *this)
default: default:
{ {
/* IKE_SA is half open and gets destroyed */ /* IKE_SA is half open and gets destroyed */
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_JOB, "deleting half open IKE_SA after timeout");
"deleting half open IKE_SA after timeout");
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
return DESTROY_ME; return DESTROY_ME;
} }
@@ -130,7 +124,6 @@ delete_ike_sa_job_t *delete_ike_sa_job_create(ike_sa_id_t *ike_sa_id,
/* private variables */ /* private variables */
this->ike_sa_id = ike_sa_id->clone(ike_sa_id); this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->delete_if_established = delete_if_established; this->delete_if_established = delete_if_established;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public); return &(this->public);
} }
+11 -21
View File
@@ -41,11 +41,6 @@ struct private_incoming_packet_job_t {
* Assigned packet * Assigned packet
*/ */
packet_t *packet; packet_t *packet;
/**
* logger
*/
logger_t *logger;
}; };
/** /**
@@ -92,8 +87,7 @@ static void send_notify_response(private_incoming_packet_job_t *this,
response->destroy(response); response->destroy(response);
return; return;
} }
this->logger->log(this->logger, CONTROL, "sending %s notify", DBG1(SIG_DBG_NET, "sending %N notify", notify_type_names, type);
mapping_find(notify_type_m, type));
charon->send_queue->add(charon->send_queue, packet); charon->send_queue->add(charon->send_queue, packet);
response->destroy(response); response->destroy(response);
return; return;
@@ -113,13 +107,12 @@ static status_t execute(private_incoming_packet_job_t *this)
message = message_create_from_packet(this->packet->clone(this->packet)); message = message_create_from_packet(this->packet->clone(this->packet));
src = message->get_source(message); src = message->get_source(message);
dst = message->get_destination(message); dst = message->get_destination(message);
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_NET, "received packet: from %#H to %#H", src, dst);
"received packet: from %#H to %#H", src, dst);
status = message->parse_header(message); status = message->parse_header(message);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "received message with invalid IKE header, ignored"); DBG1(SIG_DBG_NET, "received message with invalid IKE header, ignored");
message->destroy(message); message->destroy(message);
return DESTROY_ME; return DESTROY_ME;
} }
@@ -127,10 +120,10 @@ static status_t execute(private_incoming_packet_job_t *this)
if ((message->get_major_version(message) != IKE_MAJOR_VERSION) || if ((message->get_major_version(message) != IKE_MAJOR_VERSION) ||
(message->get_minor_version(message) != IKE_MINOR_VERSION)) (message->get_minor_version(message) != IKE_MINOR_VERSION))
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET,
"received a packet with IKE version %d.%d, not supported", "received a packet with IKE version %d.%d, not supported",
message->get_major_version(message), message->get_major_version(message),
message->get_minor_version(message)); message->get_minor_version(message));
if ((message->get_exchange_type(message) == IKE_SA_INIT) && (message->get_request(message))) if ((message->get_exchange_type(message) == IKE_SA_INIT) && (message->get_request(message)))
{ {
send_notify_response(this, message, INVALID_MAJOR_VERSION); send_notify_response(this, message, INVALID_MAJOR_VERSION);
@@ -145,14 +138,12 @@ static status_t execute(private_incoming_packet_job_t *this)
ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, ike_sa_id); ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, ike_sa_id);
if (ike_sa == NULL) if (ike_sa == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_NET, "received packet for IKE_SA: %J, but no such IKE_SA",
"received packet with SPIs %llx:%llx, but no such IKE_SA", ike_sa_id);
ike_sa_id->get_initiator_spi(ike_sa_id),
ike_sa_id->get_responder_spi(ike_sa_id));
if (message->get_request(message)) if (message->get_request(message))
{ {
/* TODO: send notify if we have NULL crypters, /* TODO: send notify if we have NULL crypters,
* see todo in send_notify_response * see todo in send_notify_response
send_notify_response(this, message, INVALID_IKE_SPI); */ send_notify_response(this, message, INVALID_IKE_SPI); */
} }
ike_sa_id->destroy(ike_sa_id); ike_sa_id->destroy(ike_sa_id);
@@ -207,7 +198,6 @@ incoming_packet_job_t *incoming_packet_job_create(packet_t *packet)
/* private variables */ /* private variables */
this->packet = packet; this->packet = packet;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public); return &(this->public);
} }
+1 -8
View File
@@ -48,11 +48,6 @@ struct private_initiate_job_t {
* associated policy to initiate * associated policy to initiate
*/ */
policy_t *policy; policy_t *policy;
/**
* logger
*/
logger_t *logger;
}; };
/** /**
@@ -80,8 +75,7 @@ static status_t execute(private_initiate_job_t *this)
this->policy->get_ref(this->policy); this->policy->get_ref(this->policy);
if (ike_sa->initiate(ike_sa, this->connection, this->policy) != SUCCESS) if (ike_sa->initiate(ike_sa, this->connection, this->policy) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_JOB, "initiation failed, going to delete IKE_SA");
"initiation failed, going to delete IKE_SA");
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
return DESTROY_ME; return DESTROY_ME;
} }
@@ -115,7 +109,6 @@ initiate_job_t *initiate_job_create(connection_t *connection, policy_t *policy)
/* private variables */ /* private variables */
this->connection = connection; this->connection = connection;
this->policy = policy; this->policy = policy;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &this->public; return &this->public;
} }
+13 -15
View File
@@ -24,18 +24,16 @@
#include "job.h" #include "job.h"
ENUM(job_type_names, INCOMING_PACKET, SEND_DPD,
mapping_t job_type_m[] = { "INCOMING_PACKET",
{INCOMING_PACKET, "INCOMING_PACKET"}, "RETRANSMIT_REQUEST",
{RETRANSMIT_REQUEST, "RETRANSMIT_REQUEST"}, "INITIATE",
{INITIATE, "INITIATE"}, "ROUTE",
{ROUTE, "ROUTE"}, "ACQUIRE",
{ACQUIRE, "ACQUIRE"}, "DELETE_IKE_SA",
{DELETE_IKE_SA, "DELETE_IKE_SA"}, "DELETE_CHILD_SA",
{DELETE_CHILD_SA, "DELETE_CHILD_SA"}, "REKEY_CHILD_SA",
{REKEY_CHILD_SA, "REKEY_CHILD_SA"}, "REKEY_IKE_SA",
{REKEY_IKE_SA, "REKEY_IKE_SA"}, "SEND_KEEPALIVE",
{SEND_KEEPALIVE, "SEND_KEEPALIVE"}, "SEND_DPD",
{SEND_DPD, "SEND_DPD"}, );
{MAPPING_END, NULL}
};
+2 -2
View File
@@ -115,11 +115,11 @@ enum job_type_t {
}; };
/** /**
* string mappings for job_type_t * enum name for job_type_t
* *
* @ingroup jobs * @ingroup jobs
*/ */
extern mapping_t job_type_m[]; extern enum_name_t *job_type_names;
typedef struct job_t job_t; typedef struct job_t job_t;
+2 -8
View File
@@ -50,11 +50,6 @@ struct private_rekey_child_sa_job_t {
* inbound SPI of the CHILD_SA * inbound SPI of the CHILD_SA
*/ */
u_int32_t spi; u_int32_t spi;
/**
* Logger ref
*/
logger_t *logger;
}; };
/** /**
@@ -76,8 +71,8 @@ static status_t execute(private_rekey_child_sa_job_t *this)
this->reqid); this->reqid);
if (ike_sa == NULL) if (ike_sa == NULL)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, DBG2(SIG_DBG_JOB, "CHILD_SA with reqid %d not found for rekeying",
"CHILD_SA not found for rekeying"); this->reqid);
return DESTROY_ME; return DESTROY_ME;
} }
ike_sa->rekey_child_sa(ike_sa, this->protocol, this->spi); ike_sa->rekey_child_sa(ike_sa, this->protocol, this->spi);
@@ -112,7 +107,6 @@ rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
this->reqid = reqid; this->reqid = reqid;
this->protocol = protocol; this->protocol = protocol;
this->spi = spi; this->spi = spi;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public); return &(this->public);
} }
+1 -8
View File
@@ -40,11 +40,6 @@ struct private_rekey_ike_sa_job_t {
* ID of the IKE_SA to rekey * ID of the IKE_SA to rekey
*/ */
ike_sa_id_t *ike_sa_id; ike_sa_id_t *ike_sa_id;
/**
* Logger ref
*/
logger_t *logger;
}; };
/** /**
@@ -66,8 +61,7 @@ static status_t execute(private_rekey_ike_sa_job_t *this)
this->ike_sa_id); this->ike_sa_id);
if (ike_sa == NULL) if (ike_sa == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG2(SIG_DBG_JOB, "IKE_SA %J to rekey not found", this->ike_sa_id);
"IKE_SA to rekey not found");
return DESTROY_ME; return DESTROY_ME;
} }
ike_sa->rekey(ike_sa); ike_sa->rekey(ike_sa);
@@ -99,7 +93,6 @@ rekey_ike_sa_job_t *rekey_ike_sa_job_create(ike_sa_id_t *ike_sa_id)
/* private variables */ /* private variables */
this->ike_sa_id = ike_sa_id->clone(ike_sa_id); this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public); return &(this->public);
} }
@@ -45,11 +45,6 @@ struct private_retransmit_request_job_t {
* ID of the IKE_SA which the message belongs to. * ID of the IKE_SA which the message belongs to.
*/ */
ike_sa_id_t *ike_sa_id; ike_sa_id_t *ike_sa_id;
/**
* Logger reference
*/
logger_t *logger;
}; };
/** /**
@@ -70,8 +65,7 @@ static status_t execute(private_retransmit_request_job_t *this)
ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, this->ike_sa_id); ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, this->ike_sa_id);
if (ike_sa == NULL) if (ike_sa == NULL)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, DBG2(SIG_DBG_JOB, "IKE SA could not be checked out. Already deleted?");
"IKE SA could not be checked out. Already deleted?");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -111,7 +105,6 @@ retransmit_request_job_t *retransmit_request_job_create(u_int32_t message_id,ike
/* private variables */ /* private variables */
this->message_id = message_id; this->message_id = message_id;
this->ike_sa_id = ike_sa_id->clone(ike_sa_id); this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public); return &(this->public);
} }
+2 -10
View File
@@ -52,11 +52,6 @@ struct private_route_job_t {
* route or unroute? * route or unroute?
*/ */
bool route; bool route;
/**
* logger
*/
logger_t *logger;
}; };
/** /**
@@ -83,16 +78,14 @@ static status_t execute(private_route_job_t *this)
{ {
if (ike_sa->route(ike_sa, this->connection, this->policy) != SUCCESS) if (ike_sa->route(ike_sa, this->connection, this->policy) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_JOB, "routing failed");
"routing failed");
} }
} }
else else
{ {
if (ike_sa->unroute(ike_sa, this->policy) == DESTROY_ME) if (ike_sa->unroute(ike_sa, this->policy) == DESTROY_ME)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_JOB, "removing IKE_SA, as last routed CHILD_SA unrouted");
"removing IKE_SA, as last routed CHILD_SA unrouted");
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
return DESTROY_ME; return DESTROY_ME;
} }
@@ -127,7 +120,6 @@ route_job_t *route_job_create(connection_t *connection, policy_t *policy, bool r
this->connection = connection; this->connection = connection;
this->policy = policy; this->policy = policy;
this->route = route; this->route = route;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &this->public; return &this->public;
} }
-6
View File
@@ -44,11 +44,6 @@ struct private_send_dpd_job_t {
* ID of the IKE_SA which the message belongs to. * ID of the IKE_SA which the message belongs to.
*/ */
ike_sa_id_t *ike_sa_id; ike_sa_id_t *ike_sa_id;
/**
* Logger reference.
*/
logger_t *logger;
}; };
/** /**
@@ -110,7 +105,6 @@ send_dpd_job_t *send_dpd_job_create(ike_sa_id_t *ike_sa_id)
/* private variables */ /* private variables */
this->ike_sa_id = ike_sa_id->clone(ike_sa_id); this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public); return &(this->public);
} }
@@ -44,11 +44,6 @@ struct private_send_keepalive_job_t {
* ID of the IKE_SA which the message belongs to. * ID of the IKE_SA which the message belongs to.
*/ */
ike_sa_id_t *ike_sa_id; ike_sa_id_t *ike_sa_id;
/**
* Logger reference.
*/
logger_t *logger;
}; };
/** /**
@@ -103,7 +98,6 @@ send_keepalive_job_t *send_keepalive_job_create(ike_sa_id_t *ike_sa_id)
/* private variables */ /* private variables */
this->ike_sa_id = ike_sa_id->clone(ike_sa_id); this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public); return &(this->public);
} }
+4 -10
View File
@@ -26,7 +26,8 @@
#include "send_queue.h" #include "send_queue.h"
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger_manager.h> #include <bus/bus.h>
#include <daemon.h>
typedef struct private_send_queue_t private_send_queue_t; typedef struct private_send_queue_t private_send_queue_t;
@@ -39,7 +40,7 @@ struct private_send_queue_t {
/** /**
* Public part of the send_queue_t object * Public part of the send_queue_t object
*/ */
send_queue_t public; send_queue_t public;
/** /**
* The packets are stored in a linked list * The packets are stored in a linked list
@@ -56,11 +57,6 @@ struct private_send_queue_t {
* This condvar is used to wake up such a thread * This condvar is used to wake up such a thread
*/ */
pthread_cond_t condvar; pthread_cond_t condvar;
/**
* Logger reference
*/
logger_t *logger;
}; };
/** /**
@@ -111,8 +107,7 @@ static void add(private_send_queue_t *this, packet_t *packet)
src = packet->get_source(packet); src = packet->get_source(packet);
dst = packet->get_destination(packet); dst = packet->get_destination(packet);
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_NET, "sending packet: from %#H to %#H", src, dst);
"sending packet: from %#H to %#H", src, dst);
pthread_mutex_lock(&this->mutex); pthread_mutex_lock(&this->mutex);
this->list->insert_last(this->list, packet); this->list->insert_last(this->list, packet);
@@ -152,7 +147,6 @@ send_queue_t *send_queue_create(void)
this->list = linked_list_create(); this->list = linked_list_create();
pthread_mutex_init(&this->mutex, NULL); pthread_mutex_init(&this->mutex, NULL);
pthread_cond_init(&this->condvar, NULL); pthread_cond_init(&this->condvar, NULL);
this->logger = logger_manager->get_logger(logger_manager, SOCKET);
return (&this->public); return (&this->public);
} }
+48 -119
View File
@@ -47,7 +47,7 @@ struct private_authenticator_t {
authenticator_t public; authenticator_t public;
/** /**
* Assigned IKE_SA. Needed to get objects of type prf_t and logger_t. * Assigned IKE_SA
*/ */
ike_sa_t *ike_sa; ike_sa_t *ike_sa;
@@ -60,57 +60,10 @@ struct private_authenticator_t {
* PRF taken from the IKE_SA. * PRF taken from the IKE_SA.
*/ */
prf_t *prf; prf_t *prf;
/**
* A logger for.
*
* Using logger of IKE_SA.
*/
logger_t *logger;
/**
* @brief Builds the octets to be signed (RSA or PSK) as described in section 2.15 of RFC 4306.
*
* @param this calling object
* @param last_message the last message to include in created octets
* (either binary form of IKE_SA_INIT request or IKE_SA_INIT response)
* @param other_nonce Nonce data received from other peer
* @param id ID of signer
* @param initiator Type of peer. TRUE, if it is original initiator, FALSE otherwise
* @return octets as described in section 2.15. Memory gets allocated and has to get
* destroyed by caller.
*/
chunk_t (*build_tbs_octets) (private_authenticator_t *this,
chunk_t last_message,
chunk_t other_nonce,
identification_t *id,
bool initiator);
/**
* @brief Creates the AUTH data using auth method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
*
* @param this calling object
* @param last_message the last message
* (either binary form of IKE_SA_INIT request or IKE_SA_INIT response)
* @param nonce Nonce data to include in auth data compution
* @param id ID of signer
* @param initiator Type of peer. TRUE, if it is original initiator, FALSE otherwise
* @param secret shared secret as chunk_t. If shared secret is a string,
* the NULL termination is not included.
* @return AUTH data as dscribed in section 2.15 for
* AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
* Memory gets allocated and has to get destroyed by caller.
*/
chunk_t (*build_shared_key_signature) (private_authenticator_t *this,
chunk_t last_message,
chunk_t nonce,
identification_t *id,
bool initiator,
chunk_t secret);
}; };
/** /**
* Implementation of private_authenticator_t.build_tbs_octets. * Builds the octets to be signed (RSA or PSK) as described in section 2.15 of RFC 4306
*/ */
static chunk_t build_tbs_octets(private_authenticator_t *this, static chunk_t build_tbs_octets(private_authenticator_t *this,
chunk_t last_message, chunk_t last_message,
@@ -156,7 +109,7 @@ static chunk_t build_tbs_octets(private_authenticator_t *this,
} }
/** /**
* Implementation of private_authenticator_t.build_shared_key_signature. * Creates the AUTH data using auth method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
*/ */
static chunk_t build_shared_key_signature(private_authenticator_t *this, static chunk_t build_shared_key_signature(private_authenticator_t *this,
chunk_t last_message, chunk_t last_message,
@@ -170,23 +123,18 @@ static chunk_t build_shared_key_signature(private_authenticator_t *this,
chunk_t key = {ptr: key_buffer, len: sizeof(key_buffer)}; chunk_t key = {ptr: key_buffer, len: sizeof(key_buffer)};
chunk_t auth_data; chunk_t auth_data;
chunk_t octets = this->build_tbs_octets(this, last_message, nonce, id, initiator); chunk_t octets = build_tbs_octets(this, last_message, nonce, id, initiator);
/* AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>) */ /* AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>) */
this->prf->set_key(this->prf, secret); this->prf->set_key(this->prf, secret);
this->prf->get_bytes(this->prf, key_pad, key_buffer); this->prf->get_bytes(this->prf, key_pad, key_buffer);
this->prf->set_key(this->prf, key); this->prf->set_key(this->prf, key);
this->prf->allocate_bytes(this->prf, octets, &auth_data); this->prf->allocate_bytes(this->prf, octets, &auth_data);
this->logger->log_chunk(this->logger, RAW|LEVEL2, DBG3(SIG_DBG_IKE, "octets = message + nonce + prf(Sk_px, IDx') %B", &octets);
"octets = message + nonce + prf(Sk_px, IDx')", octets); DBG3(SIG_DBG_IKE, "secret %B", &secret);
this->logger->log_chunk(this->logger, PRIVATE|LEVEL2, DBG3(SIG_DBG_IKE, "keypad %B", &key_pad);
"secret", secret); DBG3(SIG_DBG_IKE, "prf(secret, keypad) %B", &key);
this->logger->log_chunk(this->logger, RAW|LEVEL2, DBG3(SIG_DBG_IKE, "AUTH = prf(prf(secret, keypad), octets) %B", &auth_data);
"keypad", key_pad);
this->logger->log_chunk(this->logger, RAW|LEVEL2,
"prf(secret, keypad)", key);
this->logger->log_chunk(this->logger,RAW | LEVEL2,
"AUTH = prf(prf(secret, keypad), octets)", auth_data);
chunk_free(&octets); chunk_free(&octets);
return auth_data; return auth_data;
@@ -220,19 +168,15 @@ static status_t verify_auth_data (private_authenticator_t *this,
&shared_key); &shared_key);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "no shared key found for '%D' - '%D'",
"no shared key found for '%D' - '%D'", my_id, other_id);
my_id, other_id);
chunk_free(&shared_key); chunk_free(&shared_key);
break; break;
} }
my_auth_data = this->build_shared_key_signature(this, my_auth_data = build_shared_key_signature(this, last_received_packet,
last_received_packet, my_nonce, other_id,
my_nonce, initiator, shared_key);
other_id,
initiator,
shared_key);
chunk_free(&shared_key); chunk_free(&shared_key);
@@ -251,15 +195,15 @@ static status_t verify_auth_data (private_authenticator_t *this,
if (public_key == NULL) if (public_key == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "no RSA public key found for '%D'", other_id);
"no RSA public key found for '%D'", other_id);
status = NOT_FOUND; status = NOT_FOUND;
break; break;
} }
octets = this->build_tbs_octets(this, last_received_packet, my_nonce, other_id, initiator); octets = build_tbs_octets(this, last_received_packet, my_nonce,
other_id, initiator);
status = public_key->verify_emsa_pkcs1_signature(public_key, octets, auth_data); status = public_key->verify_emsa_pkcs1_signature(public_key, octets,
auth_data);
chunk_free(&octets); chunk_free(&octets);
break; break;
} }
@@ -269,9 +213,9 @@ static status_t verify_auth_data (private_authenticator_t *this,
} }
} }
this->logger->log(this->logger, CONTROL, "authentication of '%D' with %s %s", DBG1(SIG_DBG_IKE, "authentication of '%D' with %N %s",
other_id, enum_name(&auth_method_names, auth_method), other_id, auth_method_names, auth_method,
(status == SUCCESS)? "successful":"failed"); (status == SUCCESS)? "successful":"failed");
return status; return status;
} }
@@ -285,10 +229,9 @@ static status_t compute_auth_data (private_authenticator_t *this,
identification_t *my_id, identification_t *my_id,
identification_t *other_id, identification_t *other_id,
bool initiator) bool initiator)
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "authentication of '%D' with %N (myself)",
"authentication of '%D' with %s (myself)", my_id, auth_method_names, this->auth_method);
my_id, enum_name(&auth_method_names, this->auth_method));
switch (this->auth_method) switch (this->auth_method)
{ {
@@ -304,21 +247,18 @@ static status_t compute_auth_data (private_authenticator_t *this,
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "no shared key found for '%D' - '%D'",
"no shared key found for '%D' - '%D'", my_id, other_id);
my_id, other_id);
return status; return status;
} }
auth_data = this->build_shared_key_signature(this, auth_data = build_shared_key_signature(this, last_sent_packet,
last_sent_packet, other_nonce, my_id,
other_nonce, initiator, shared_key);
my_id,
initiator,
shared_key);
chunk_free(&shared_key); chunk_free(&shared_key);
*auth_payload = auth_payload_create(); *auth_payload = auth_payload_create();
(*auth_payload)->set_auth_method(*auth_payload, SHARED_KEY_MESSAGE_INTEGRITY_CODE); (*auth_payload)->set_auth_method(*auth_payload,
SHARED_KEY_MESSAGE_INTEGRITY_CODE);
(*auth_payload)->set_data(*auth_payload, auth_data); (*auth_payload)->set_data(*auth_payload, auth_data);
chunk_free(&auth_data); chunk_free(&auth_data);
@@ -326,44 +266,40 @@ static status_t compute_auth_data (private_authenticator_t *this,
} }
case RSA_DIGITAL_SIGNATURE: case RSA_DIGITAL_SIGNATURE:
{ {
char buf[BUF_LEN]; chunk_t chunk;
chunk_t octets; chunk_t octets;
chunk_t auth_data; chunk_t auth_data;
status_t status; status_t status;
rsa_public_key_t *my_pubkey; rsa_public_key_t *my_pubkey;
rsa_private_key_t *my_key; rsa_private_key_t *my_key;
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_IKE, "looking for RSA public key belonging to '%D'",
"looking for RSA public key belonging to '%D'",
my_id); my_id);
my_pubkey = charon->credentials->get_rsa_public_key(charon->credentials, my_id); my_pubkey = charon->credentials->get_rsa_public_key(charon->credentials, my_id);
if (my_pubkey == NULL) if (my_pubkey == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "no RSA public key found for '%D'", my_id);
"no RSA public key found for '%D'", my_id);
return NOT_FOUND; return NOT_FOUND;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, "matching RSA public key found"); DBG2(SIG_DBG_IKE, "matching RSA public key found");
chunk_to_hex(buf, BUF_LEN, my_pubkey->get_keyid(my_pubkey)); chunk = my_pubkey->get_keyid(my_pubkey);
this->logger->log(this->logger, CONTROL|LEVEL1, "looking for RSA private key with keyid %s", buf); DBG2(SIG_DBG_IKE, "looking for RSA private key with keyid %#B", &chunk);
my_key = charon->credentials->get_rsa_private_key(charon->credentials, my_pubkey); my_key = charon->credentials->get_rsa_private_key(charon->credentials, my_pubkey);
if (my_key == NULL) if (my_key == NULL)
{ {
char buf[BUF_LEN]; DBG1(SIG_DBG_IKE, "no RSA private key found with for %D with keyid %#B",
my_id, &chunk);
chunk_to_hex(buf, BUF_LEN, my_pubkey->get_keyid(my_pubkey));
this->logger->log(this->logger, ERROR,
"no RSA private key found with for %D with keyid %s",
my_id, buf);
return NOT_FOUND; return NOT_FOUND;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, "matching RSA private key found"); DBG2(SIG_DBG_IKE, "matching RSA private key found");
octets = this->build_tbs_octets(this, last_sent_packet, other_nonce, my_id, initiator); octets = build_tbs_octets(this, last_sent_packet, other_nonce,
status = my_key->build_emsa_pkcs1_signature(my_key, HASH_SHA1, octets, &auth_data); my_id, initiator);
status = my_key->build_emsa_pkcs1_signature(my_key, HASH_SHA1,
octets, &auth_data);
chunk_free(&octets); chunk_free(&octets);
if (status != SUCCESS) if (status != SUCCESS)
@@ -371,7 +307,7 @@ static status_t compute_auth_data (private_authenticator_t *this,
my_key->destroy(my_key); my_key->destroy(my_key);
return status; return status;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, "successfully signed with RSA private key"); DBG2(SIG_DBG_IKE, "successfully signed with RSA private key");
*auth_payload = auth_payload_create(); *auth_payload = auth_payload_create();
(*auth_payload)->set_auth_method(*auth_payload, RSA_DIGITAL_SIGNATURE); (*auth_payload)->set_auth_method(*auth_payload, RSA_DIGITAL_SIGNATURE);
@@ -405,20 +341,13 @@ authenticator_t *authenticator_create(ike_sa_t *ike_sa, auth_method_t auth_metho
/* Public functions */ /* Public functions */
this->public.destroy = (void(*)(authenticator_t*))destroy; this->public.destroy = (void(*)(authenticator_t*))destroy;
this->public.verify_auth_data = (status_t (*) (authenticator_t*,auth_payload_t*,chunk_t, this->public.verify_auth_data = (status_t (*) (authenticator_t*,auth_payload_t*,chunk_t,chunk_t,identification_t*,identification_t*,bool)) verify_auth_data;
chunk_t,identification_t*,identification_t*,bool)) verify_auth_data; this->public.compute_auth_data = (status_t (*) (authenticator_t*,auth_payload_t**,chunk_t,chunk_t,identification_t*,identification_t*,bool)) compute_auth_data;
this->public.compute_auth_data = (status_t (*) (authenticator_t*,auth_payload_t**,chunk_t,
chunk_t,identification_t*,identification_t*,bool)) compute_auth_data;
/* private functions */
this->build_tbs_octets = build_tbs_octets;
this->build_shared_key_signature = build_shared_key_signature;
/* private data */ /* private data */
this->ike_sa = ike_sa; this->ike_sa = ike_sa;
this->auth_method = auth_method; this->auth_method = auth_method;
this->prf = this->ike_sa->get_prf(this->ike_sa); this->prf = this->ike_sa->get_prf(this->ike_sa);
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &(this->public); return &(this->public);
} }
+121 -143
View File
@@ -22,25 +22,22 @@
* for more details. * for more details.
*/ */
#define _GNU_SOURCE
#include "child_sa.h" #include "child_sa.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <printf.h>
#include <daemon.h> #include <daemon.h>
ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DELETING,
/** "CREATED",
* String mappings for child_sa_state_t. "ROUTED",
*/ "INSTALLED",
mapping_t child_sa_state_m[] = { "REKEYING",
{CHILD_CREATED, "CREATED"}, "DELETING",
{CHILD_INSTALLED, "INSTALLED"}, );
{CHILD_ROUTED, "ROUTED"},
{CHILD_REKEYING, "REKEYING"},
{CHILD_DELETING, "DELETNG"},
{MAPPING_END, NULL}
};
typedef struct sa_policy_t sa_policy_t; typedef struct sa_policy_t sa_policy_t;
@@ -170,11 +167,6 @@ struct private_child_sa_t {
* Specifies if NAT traversal is used * Specifies if NAT traversal is used
*/ */
bool use_natt; bool use_natt;
/**
* CHILD_SAs own logger
*/
logger_t *logger;
}; };
/** /**
@@ -254,18 +246,15 @@ static void updown(private_child_sa_t *this, bool up)
sa_policy_t *policy; sa_policy_t *policy;
char command[1024]; char command[1024];
char *ifname = NULL; char *ifname = NULL;
char *my_str, *other_str;
char *my_client, *other_client, *my_client_mask, *other_client_mask; char *my_client, *other_client, *my_client_mask, *other_client_mask;
char *pos; char *pos;
FILE *shell; FILE *shell;
/* get ts strings */ /* get ts strings */
iterator->current(iterator, (void**)&policy); iterator->current(iterator, (void**)&policy);
my_str = policy->my_ts->get_string(policy->my_ts);
other_str = policy->other_ts->get_string(policy->other_ts);
/* get subnet/bits from string */ /* get subnet/bits from string */
my_client = strdup(my_str); asprintf(&my_client, "%R", policy->my_ts);
pos = strchr(my_client, '/'); pos = strchr(my_client, '/');
*pos = '\0'; *pos = '\0';
my_client_mask = pos + 1; my_client_mask = pos + 1;
@@ -274,7 +263,7 @@ static void updown(private_child_sa_t *this, bool up)
{ {
*pos = '\0'; *pos = '\0';
} }
other_client = strdup(other_str); asprintf(&other_client, "%R", policy->other_ts);
pos = strchr(other_client, '/'); pos = strchr(other_client, '/');
*pos = '\0'; *pos = '\0';
other_client_mask = pos + 1; other_client_mask = pos + 1;
@@ -313,8 +302,8 @@ static void updown(private_child_sa_t *this, bool up)
"%s" "%s"
"%s", "%s",
up ? "up" : "down", up ? "up" : "down",
/* TODO: fix it: streq(this->me.addr->get_string(this->me.addr), policy->my_ts->is_host(policy->my_ts,
my_client) ? "-host" :*/ "-client", this->me.addr) ? "-host" : "-client",
this->me.addr->get_family(this->me.addr) == AF_INET ? "" : "-ipv6", this->me.addr->get_family(this->me.addr) == AF_INET ? "" : "-ipv6",
this->name, this->name,
ifname, ifname,
@@ -341,9 +330,7 @@ static void updown(private_child_sa_t *this, bool up)
if (shell == NULL) if (shell == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_CHD, "could not execute updown script '%s'", this->script);
"could not execute updown script '%s'",
this->script);
return; return;
} }
@@ -355,8 +342,7 @@ static void updown(private_child_sa_t *this, bool up)
{ {
if (ferror(shell)) if (ferror(shell))
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_CHD, "error reading output from updown script");
"error reading output from updown script");
return; return;
} }
else else
@@ -371,7 +357,7 @@ static void updown(private_child_sa_t *this, bool up)
{ /* trim trailing '\n' */ { /* trim trailing '\n' */
e[-1] = '\0'; e[-1] = '\0';
} }
this->logger->log(this->logger, ERROR, "updown: %s", resp); DBG1(SIG_DBG_CHD, "updown: %s", resp);
} }
} }
pclose(shell); pclose(shell);
@@ -507,15 +493,14 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
dst = this->other.addr; dst = this->other.addr;
} }
this->logger->log(this->logger, CONTROL|LEVEL1, "adding %s %s SA", DBG2(SIG_DBG_CHD, "adding %s %N SA", mine ? "inbound" : "outbound",
mine ? "inbound" : "outbound", protocol_id_names, this->protocol);
mapping_find(protocol_id_m, this->protocol));
/* select encryption algo */ /* select encryption algo */
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &enc_algo)) if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &enc_algo))
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, " using %s for encryption", DBG2(SIG_DBG_CHD, " using %N for encryption",
mapping_find(encryption_algorithm_m, enc_algo->algorithm)); encryption_algorithm_names, enc_algo->algorithm);
} }
else else
{ {
@@ -525,8 +510,8 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
/* select integrity algo */ /* select integrity algo */
if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &int_algo)) if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &int_algo))
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, " using %s for integrity", DBG2(SIG_DBG_CHD, " using %N for integrity",
mapping_find(integrity_algorithm_m, int_algo->algorithm)); integrity_algorithm_names, int_algo->algorithm);
} }
else else
{ {
@@ -547,9 +532,7 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
/* send SA down to the kernel */ /* send SA down to the kernel */
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
" SPI 0x%.8x, src %H dst %H",
ntohl(spi), src, dst);
status = charon->kernel_interface->add_sa(charon->kernel_interface, status = charon->kernel_interface->add_sa(charon->kernel_interface,
src, dst, src, dst,
spi, this->protocol, spi, this->protocol,
@@ -645,8 +628,8 @@ static status_t add_policies(private_child_sa_t *this, linked_list_t *my_ts_list
if (my_ts->get_type(my_ts) != other_ts->get_type(other_ts)) if (my_ts->get_type(my_ts) != other_ts->get_type(other_ts))
{ {
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_CHD,
"CHILD_SA policy uses two different IP families, ignored"); "CHILD_SA policy uses two different IP families, ignored");
continue; continue;
} }
@@ -654,8 +637,8 @@ static status_t add_policies(private_child_sa_t *this, linked_list_t *my_ts_list
if (my_ts->get_protocol(my_ts) != other_ts->get_protocol(other_ts) && if (my_ts->get_protocol(my_ts) != other_ts->get_protocol(other_ts) &&
my_ts->get_protocol(my_ts) && other_ts->get_protocol(other_ts)) my_ts->get_protocol(my_ts) && other_ts->get_protocol(other_ts))
{ {
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_CHD,
"CHILD_SA policy uses two different protocols, ignored"); "CHILD_SA policy uses two different protocols, ignored");
continue; continue;
} }
@@ -774,134 +757,133 @@ static status_t get_use_time(private_child_sa_t *this, bool inbound, time_t *use
} }
/** /**
* Implementation of child_sa_t.log_status. * output handler in printf()
*/ */
static void log_status(private_child_sa_t *this, logger_t *logger) static int print(FILE *stream, const struct printf_info *info,
const void *const *args)
{ {
private_child_sa_t *this = *((private_child_sa_t**)(args[0]));
iterator_t *iterator; iterator_t *iterator;
char use_in_str[12] = "unused"; sa_policy_t *policy;
char use_out_str[12] = "unused"; u_int32_t now, rekeying, use;
char rekey_str[12] = "disabled";
char enc_str[32] = "";
char int_str[32] = "";
u_int32_t use_in, use_out, use_fwd, now, rekeying;
status_t status; status_t status;
size_t written, total_written = 0;
#define fprintf_sum(...) { written = fprintf(__VA_ARGS__); if (written < 0) return written; total_written += written; }
if (logger == NULL) if (this == NULL)
{ {
logger = this->logger; return fprintf(stream, "(null)");
} }
now = (u_int32_t)time(NULL); now = (u_int32_t)time(NULL);
fprintf_sum(stream, "%10s: %N, reqid: %d", this->name,
child_sa_state_names, this->state, this->reqid);
if (this->state == CHILD_INSTALLED) if (this->state == CHILD_INSTALLED)
{ {
/* query SA times */ fprintf_sum(stream, ", %N, SPIs (in/out): 0x%x/0x%x",
status = charon->kernel_interface->query_sa(charon->kernel_interface, protocol_id_names, this->protocol,
this->me.addr, this->me.spi, this->protocol, &use_in); htonl(this->me.spi), htonl(this->other.spi));
if (status == SUCCESS && use_in)
{
snprintf(use_in_str, sizeof(use_in_str), "%ds", now - use_in);
}
status = charon->kernel_interface->query_sa(charon->kernel_interface,
this->other.addr, this->other.spi, this->protocol, &use_out);
if (status == SUCCESS && use_out)
{
snprintf(use_out_str, sizeof(use_out_str), "%ds", now - use_out);
}
/* calculate rekey times */ if (info->alt)
if (this->soft_lifetime)
{ {
rekeying = this->soft_lifetime - (now - this->install_time); fprintf_sum(stream, "\n%10s: ", this->name);
snprintf(rekey_str, sizeof(rekey_str), "%ds", (int)rekeying);
} if (this->protocol == PROTO_ESP)
/* algorithms used */
if (this->protocol == PROTO_ESP)
{
if (this->encryption.key_size)
{ {
snprintf(enc_str, sizeof(enc_str), "%s-%d,", fprintf_sum(stream, "%N",
mapping_find(encryption_algorithm_m, this->encryption.algorithm), encryption_algorithm_names, this->encryption.algorithm);
this->encryption.key_size);
if (this->encryption.key_size)
{
fprintf_sum(stream, "-%d", this->encryption.key_size);
}
fprintf_sum(stream, "/");
}
fprintf_sum(stream, "%N",
integrity_algorithm_names, this->integrity.algorithm);
if (this->integrity.key_size)
{
fprintf_sum(stream, "-%d", this->integrity.key_size);
}
fprintf_sum(stream, ", rekeying: ");
/* calculate rekey times */
if (this->soft_lifetime)
{
rekeying = this->soft_lifetime - (now - this->install_time);
fprintf_sum(stream, "%ds", rekeying);
} }
else else
{ {
snprintf(enc_str, sizeof(enc_str), "%s,", fprintf_sum(stream, "disabled");
mapping_find(encryption_algorithm_m, this->encryption.algorithm));
} }
} }
if (this->integrity.key_size)
{
snprintf(int_str, sizeof(int_str), "%s-%d",
mapping_find(integrity_algorithm_m, this->integrity.algorithm),
this->integrity.key_size);
}
else
{
snprintf(int_str, sizeof(int_str), "%s",
mapping_find(integrity_algorithm_m, this->integrity.algorithm));
}
logger->log(logger, CONTROL|LEVEL1,
" \"%s\": state: %s, reqid: %d, ",
this->name, mapping_find(child_sa_state_m, this->state), this->reqid);
logger->log(logger, CONTROL|LEVEL1,
" \"%s\": %s (%s%s), SPIs (in/out): 0x%x/0x%x",
this->name, this->protocol == PROTO_ESP ? "ESP" : "AH",
enc_str, int_str,
htonl(this->me.spi), htonl(this->other.spi));
logger->log(logger, CONTROL|LEVEL1,
" \"%s\": rekeying: %s, key age (in/out): %s/%s",
this->name, rekey_str, use_in_str, use_out_str);
} }
else #undef fprintf_sum
{ #define fprintf_sum(...) { written = fprintf(__VA_ARGS__); if (written < 0) { iterator->destroy(iterator); return written; } total_written += written; }
logger->log(logger, CONTROL|LEVEL1, " \"%s\": state: %s, reqid: %d",
this->name, mapping_find(child_sa_state_m, this->state),
this->reqid);
}
iterator = this->policies->create_iterator(this->policies, TRUE); iterator = this->policies->create_iterator(this->policies, TRUE);
while (iterator->has_next(iterator)) while (iterator->iterate(iterator, (void**)&policy))
{ {
sa_policy_t *policy; fprintf_sum(stream, "\n%10s: %R===%R, last use (in/out/fwd): ",
char *my_str; this->name, policy->my_ts, policy->other_ts);
char *other_str;
char pol_in_str[12] = "unused";
char pol_out_str[12] = "unused";
char pol_fwd_str[12] = "unused";
/* get ts strings */
iterator->current(iterator, (void**)&policy);
my_str = policy->my_ts->get_string(policy->my_ts);
other_str = policy->other_ts->get_string(policy->other_ts);
/* query policy times */ /* query policy times */
status = charon->kernel_interface->query_policy(charon->kernel_interface, status = charon->kernel_interface->query_policy(charon->kernel_interface,
policy->other_ts, policy->my_ts, POLICY_IN, &use_in); policy->other_ts, policy->my_ts, POLICY_IN, &use);
if (status == SUCCESS && use_in) if (status == SUCCESS && use)
{ {
snprintf(pol_in_str, sizeof(pol_in_str), "%ds", now - use_in); fprintf_sum(stream, "%ds/", now - use);
}
else
{
fprintf_sum(stream, "unused/");
} }
status = charon->kernel_interface->query_policy(charon->kernel_interface, status = charon->kernel_interface->query_policy(charon->kernel_interface,
policy->my_ts, policy->other_ts, POLICY_OUT, &use_out); policy->my_ts, policy->other_ts, POLICY_OUT, &use);
if (status == SUCCESS && use_out) if (status == SUCCESS && use)
{ {
snprintf(pol_out_str, sizeof(pol_out_str), "%ds", now - use_out); fprintf_sum(stream, "%ds/", now - use);
}
else
{
fprintf_sum(stream, "unused/");
} }
status = charon->kernel_interface->query_policy(charon->kernel_interface, status = charon->kernel_interface->query_policy(charon->kernel_interface,
policy->other_ts, policy->my_ts, POLICY_FWD, &use_fwd); policy->other_ts, policy->my_ts, POLICY_FWD, &use);
if (status == SUCCESS && use_fwd) if (status == SUCCESS && use)
{ {
snprintf(pol_fwd_str, sizeof(pol_fwd_str), "%ds", now - use_fwd); fprintf_sum(stream, "%ds", now - use);
}
else
{
fprintf_sum(stream, "unused");
} }
logger->log(logger, CONTROL,
" \"%s\": %s====%s, last use (in/out/fwd): %s/%s/%s",
this->name, my_str, other_str, pol_in_str, pol_out_str, pol_fwd_str);
} }
iterator->destroy(iterator); iterator->destroy(iterator);
return total_written;
}
/**
* arginfo handler in printf()
*/
static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes)
{
if (n > 0)
{
argtypes[0] = PA_POINTER;
}
return 1;
}
/**
* register printf() handlers
*/
static void __attribute__ ((constructor))print_register()
{
register_printf_function(CHILD_SA_PRINTF_SPEC, print, print_arginfo);
} }
/** /**
@@ -936,10 +918,8 @@ static status_t update_sa_hosts(private_child_sa_t *this, host_t *new_me, host_t
spi = this->me.spi; spi = this->me.spi;
} }
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_CHD, "updating %N SA 0x%x, from %#H..#H to %#H..%#H",
"updating %s SA 0x%x, from %#H..#H to %#H..%#H", protocol_id_names, this->protocol, ntohl(spi), src, dst, new_src, new_dst);
mapping_find(protocol_id_m, this->protocol), ntohl(spi),
src, dst, new_src, new_dst);
status = charon->kernel_interface->update_sa(charon->kernel_interface, status = charon->kernel_interface->update_sa(charon->kernel_interface,
dst, spi, this->protocol, dst, spi, this->protocol,
@@ -1138,11 +1118,9 @@ child_sa_t * child_sa_create(u_int32_t rekey, host_t *me, host_t* other,
this->public.get_rekeying_transaction = (void* (*)(child_sa_t*))get_rekeying_transaction; this->public.get_rekeying_transaction = (void* (*)(child_sa_t*))get_rekeying_transaction;
this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state; this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state;
this->public.get_state = (child_sa_state_t(*)(child_sa_t*))get_state; this->public.get_state = (child_sa_state_t(*)(child_sa_t*))get_state;
this->public.log_status = (void (*)(child_sa_t*, logger_t*))log_status;
this->public.destroy = (void(*)(child_sa_t*))destroy; this->public.destroy = (void(*)(child_sa_t*))destroy;
/* private data */ /* private data */
this->logger = logger_manager->get_logger(logger_manager, CHILD_SA);
this->name = strdup("(uninitialized)"); this->name = strdup("(uninitialized)");
this->me.addr = me->clone(me); this->me.addr = me->clone(me);
this->other.addr = other->clone(other); this->other.addr = other->clone(other);
+7 -16
View File
@@ -29,13 +29,17 @@
#include <crypto/prf_plus.h> #include <crypto/prf_plus.h>
#include <encoding/payloads/proposal_substructure.h> #include <encoding/payloads/proposal_substructure.h>
#include <config/proposal.h> #include <config/proposal.h>
#include <utils/logger.h>
/** /**
* Where we should start with reqid enumeration * Where we should start with reqid enumeration
*/ */
#define REQID_START 2000000000 #define REQID_START 2000000000
/**
* Printf() specifier for child_sa_t
*/
#define CHILD_SA_PRINTF_SPEC 'P'
typedef enum child_sa_state_t child_sa_state_t; typedef enum child_sa_state_t child_sa_state_t;
/** /**
@@ -70,9 +74,9 @@ enum child_sa_state_t {
}; };
/** /**
* String mappings for child_sa_state_t. * enum strings for child_sa_state_t.
*/ */
extern mapping_t child_sa_state_m[]; extern enum_name_t *child_sa_state_names;
typedef struct child_sa_t child_sa_t; typedef struct child_sa_t child_sa_t;
@@ -279,19 +283,6 @@ struct child_sa_t {
*/ */
void* (*get_rekeying_transaction) (child_sa_t *this); void* (*get_rekeying_transaction) (child_sa_t *this);
/**
* @brief Log the status of a child_sa to a logger.
*
* The status of ESP/AH SAs is logged with the supplied logger in
* a human readable form.
* Supplying NULL as logger uses the internal child_sa logger
* to do the logging.
*
* @param this calling object
* @param logger logger to use for logging
*/
void (*log_status) (child_sa_t *this, logger_t *logger);
/** /**
* @brief Destroys a child_sa. * @brief Destroys a child_sa.
* *
+160 -217
View File
@@ -24,6 +24,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <string.h> #include <string.h>
#include <printf.h>
#include "ike_sa.h" #include "ike_sa.h"
@@ -31,7 +32,6 @@
#include <daemon.h> #include <daemon.h>
#include <definitions.h> #include <definitions.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <crypto/diffie_hellman.h> #include <crypto/diffie_hellman.h>
#include <crypto/prf_plus.h> #include <crypto/prf_plus.h>
#include <crypto/crypters/crypter.h> #include <crypto/crypters/crypter.h>
@@ -58,18 +58,13 @@
#include <queues/jobs/route_job.h> #include <queues/jobs/route_job.h>
#include <queues/jobs/initiate_job.h> #include <queues/jobs/initiate_job.h>
/** ENUM(ike_sa_state_names, IKE_CREATED, IKE_DELETING,
* String mappings for ike_sa_state_t. "CREATED",
*/ "CONNECTING",
mapping_t ike_sa_state_m[] = { "ESTABLISHED",
{IKE_CREATED, "CREATED"}, "REKEYING",
{IKE_CONNECTING, "CONNECTING"}, "DELETING",
{IKE_ESTABLISHED, "ESTABLISHED"}, );
{IKE_REKEYING, "REKEYING"},
{IKE_DELETING, "DELETING"},
{MAPPING_END, NULL}
};
typedef struct private_ike_sa_t private_ike_sa_t; typedef struct private_ike_sa_t private_ike_sa_t;
@@ -163,11 +158,6 @@ struct private_ike_sa_t {
*/ */
prf_t *prf_auth_r; prf_t *prf_auth_r;
/**
* A logger for this IKE_SA.
*/
logger_t *logger;
/** /**
* NAT hasher. * NAT hasher.
*/ */
@@ -449,8 +439,7 @@ static void dpd_detected(private_ike_sa_t *this)
dpd_action_t action; dpd_action_t action;
job_t *job; job_t *job;
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_IKE, "dead peer detected, handling CHILD_SAs dpd action");
"dead peer detected, handling CHILD_SAs dpd action");
while(this->child_sas->remove_first(this->child_sas, while(this->child_sas->remove_first(this->child_sas,
(void**)&child_sa) == SUCCESS) (void**)&child_sa) == SUCCESS)
@@ -464,8 +453,7 @@ static void dpd_detected(private_ike_sa_t *this)
this->my_host, this->other_host); this->my_host, this->other_host);
if (policy == NULL) if (policy == NULL)
{ {
this->logger->log(this->logger, ERROR, SIG(SIG_CHILD_FAILED, "no policy for CHILD to handle DPD");
"no policy found for this CHILD_SA");
continue; continue;
} }
@@ -479,15 +467,13 @@ static void dpd_detected(private_ike_sa_t *this)
this->my_host, this->other_host); this->my_host, this->other_host);
if (connection == NULL) if (connection == NULL)
{ {
this->logger->log(this->logger, ERROR, SIG(SIG_IKE_FAILED, "no connection found to handle DPD");
"no connection found for this IKE_SA");
break; break;
} }
} }
this->logger->log(this->logger, CONTROL, "dpd action for %s is %s", DBG1(SIG_DBG_IKE, "dpd action for %s is %N",
policy->get_name(policy), policy->get_name(policy), dpd_action_names, action);
enum_name(&dpd_action_names, action));
switch (action) switch (action)
{ {
@@ -530,9 +516,8 @@ static status_t transmit_request(private_ike_sa_t *this)
this->retrans_sequences); this->retrans_sequences);
if (timeout == 0) if (timeout == 0)
{ {
this->logger->log(this->logger, ERROR, SIG(SIG_IKE_FAILED, "giving up after %d retransmits, deleting IKE_SA",
"giving up after %d retransmits, deleting IKE_SA", transmitted - 1);
transmitted - 1);
dpd_detected(this); dpd_detected(this);
return DESTROY_ME; return DESTROY_ME;
} }
@@ -540,8 +525,7 @@ static status_t transmit_request(private_ike_sa_t *this)
status = transaction->get_request(transaction, &request); status = transaction->get_request(transaction, &request);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, /* generating request failed */
"generating request failed");
return status; return status;
} }
message_id = transaction->get_message_id(transaction); message_id = transaction->get_message_id(transaction);
@@ -551,18 +535,15 @@ static status_t transmit_request(private_ike_sa_t *this)
status = request->generate(request, this->crypter_out, this->signer_out, &packet); status = request->generate(request, this->crypter_out, this->signer_out, &packet);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "request generation failed. transaction discarded");
"request generation failed. transaction discarded");
return FAILED; return FAILED;
} }
} }
else else
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "sending retransmit %d for %N request with messageID %d",
"sending retransmit %d for %s request with message ID %d", transmitted, exchange_type_names, request->get_exchange_type(request),
transmitted, message_id);
mapping_find(exchange_type_m, request->get_exchange_type(request)),
message_id);
packet = request->get_packet(request); packet = request->get_packet(request);
} }
/* finally send */ /* finally send */
@@ -614,13 +595,9 @@ static status_t process_transaction_queue(private_ike_sa_t *this)
return SUCCESS; return SUCCESS;
case DESTROY_ME: case DESTROY_ME:
/* critical, IKE_SA unusable, destroy immediately */ /* critical, IKE_SA unusable, destroy immediately */
this->logger->log(this->logger, ERROR,
"transaction initiaton failed, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
default: default:
/* discard transaction, process next one */ /* discard transaction, process next one */
this->logger->log(this->logger, ERROR,
"transaction initiation failed, discarded");
this->transaction_out->destroy(this->transaction_out); this->transaction_out->destroy(this->transaction_out);
this->transaction_out = NULL; this->transaction_out = NULL;
/* handle next transaction */ /* handle next transaction */
@@ -672,9 +649,8 @@ static status_t process_request(private_ike_sa_t *this, message_t *request)
if (last_mid == request_mid) if (last_mid == request_mid)
{ {
/* retransmit detected */ /* retransmit detected */
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "received retransmitted request for message "
"received retransmitted request for message ID %d, retransmitting response", "ID %d, retransmitting response", request_mid);
request_mid);
last->get_response(last, request, &response, &this->transaction_in_next); last->get_response(last, request, &response, &this->transaction_in_next);
packet = response->get_packet(response); packet = response->get_packet(response);
charon->send_queue->add(charon->send_queue, packet); charon->send_queue->add(charon->send_queue, packet);
@@ -685,17 +661,15 @@ static status_t process_request(private_ike_sa_t *this, message_t *request)
if (last_mid > request_mid) if (last_mid > request_mid)
{ {
/* something seriously wrong here, message id may not decrease */ /* something seriously wrong here, message id may not decrease */
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "received request with message ID %d, "
"received request with message ID %d, excepted %d, ingored", "excepted %d, ingored", request_mid, last_mid + 1);
request_mid, last_mid + 1);
return FAILED; return FAILED;
} }
/* we allow jumps in message IDs, as long as they are incremental */ /* we allow jumps in message IDs, as long as they are incremental */
if (last_mid + 1 < request_mid) if (last_mid + 1 < request_mid)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "received request with message ID %d, excepted %d",
"received request with message ID %d, excepted %d", request_mid, last_mid + 1);
request_mid, last_mid + 1);
} }
} }
else else
@@ -703,9 +677,8 @@ static status_t process_request(private_ike_sa_t *this, message_t *request)
if (request_mid != 0) if (request_mid != 0)
{ {
/* warn, but allow it */ /* warn, but allow it */
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "first received request has message ID %d, "
"first received request has message ID %d, excepted 0", "excepted 0", request_mid);
request_mid);
} }
} }
@@ -720,9 +693,8 @@ static status_t process_request(private_ike_sa_t *this, message_t *request)
current = transaction_create(&this->public, request); current = transaction_create(&this->public, request);
if (current == NULL) if (current == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "no idea how to handle received message (exchange"
"no idea how to handle received message (%d), ignored", " type %d), ignored", request->get_exchange_type(request));
request->get_exchange_type(request));
return FAILED; return FAILED;
} }
} }
@@ -731,8 +703,7 @@ static status_t process_request(private_ike_sa_t *this, message_t *request)
status = current->get_response(current, request, &response, &this->transaction_in_next); status = current->get_response(current, request, &response, &this->transaction_in_next);
if (response->generate(response, this->crypter_out, this->signer_out, &packet) != SUCCESS) if (response->generate(response, this->crypter_out, this->signer_out, &packet) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "response generation failed, discarding transaction");
"response generation failed, discarding transaction");
current->destroy(current); current->destroy(current);
return FAILED; return FAILED;
} }
@@ -769,8 +740,8 @@ static status_t process_response(private_ike_sa_t *this, message_t *response)
if (current == NULL || if (current == NULL ||
current->get_message_id(current) != response->get_message_id(response)) current->get_message_id(current) != response->get_message_id(response))
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "received response with message ID %d "
"received response with message ID %d not requested, ignored"); "not requested, ignored", response->get_message_id(response));
return FAILED; return FAILED;
} }
@@ -839,42 +810,38 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
status = message->parse_body(message, this->crypter_in, this->signer_in); status = message->parse_body(message, this->crypter_in, this->signer_in);
if (status != SUCCESS) if (status != SUCCESS)
{ {
if (is_request) if (is_request)
{ {
switch (status) switch (status)
{ {
case NOT_SUPPORTED: case NOT_SUPPORTED:
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "ciritcal unknown payloads found");
"ciritcal unknown payloads found");
if (is_request) if (is_request)
{ {
send_notify_response(this, message, UNSUPPORTED_CRITICAL_PAYLOAD); send_notify_response(this, message, UNSUPPORTED_CRITICAL_PAYLOAD);
} }
break; break;
case PARSE_ERROR: case PARSE_ERROR:
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "message parsing failed");
"message parsing failed");
if (is_request) if (is_request)
{ {
send_notify_response(this, message, INVALID_SYNTAX); send_notify_response(this, message, INVALID_SYNTAX);
} }
break; break;
case VERIFY_ERROR: case VERIFY_ERROR:
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "message verification failed");
"message verification failed");
if (is_request) if (is_request)
{ {
send_notify_response(this, message, INVALID_SYNTAX); send_notify_response(this, message, INVALID_SYNTAX);
} }
break; break;
case FAILED: case FAILED:
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "integrity check failed");
"integrity check failed");
/* ignored */ /* ignored */
break; break;
case INVALID_STATE: case INVALID_STATE:
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "found encrypted message, but no keys available");
"found encrypted message, but no keys available");
if (is_request) if (is_request)
{ {
send_notify_response(this, message, INVALID_SYNTAX); send_notify_response(this, message, INVALID_SYNTAX);
@@ -883,11 +850,10 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
break; break;
} }
} }
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "%N %s with message ID %d processing failed",
"%s %s with message ID %d processing failed", exchange_type_names, message->get_exchange_type(message),
mapping_find(exchange_type_m, message->get_exchange_type(message)), message->get_request(message) ? "request" : "response",
message->get_request(message) ? "request" : "response", message->get_message_id(message));
message->get_message_id(message));
} }
else else
{ {
@@ -927,8 +893,7 @@ static status_t initiate(private_ike_sa_t *this,
*/ */
ike_sa_init_t *ike_sa_init; ike_sa_init_t *ike_sa_init;
this->logger->log(this->logger, CONTROL, SIG(SIG_INITIATE, "initiating new IKE_SA for CHILD_SA");
"initiating IKE_SA");
DESTROY_IF(this->my_host); DESTROY_IF(this->my_host);
this->my_host = connection->get_my_host(connection); this->my_host = connection->get_my_host(connection);
this->my_host = this->my_host->clone(this->my_host); this->my_host = this->my_host->clone(this->my_host);
@@ -938,6 +903,17 @@ static status_t initiate(private_ike_sa_t *this,
this->retrans_sequences = connection->get_retrans_seq(connection); this->retrans_sequences = connection->get_retrans_seq(connection);
this->dpd_delay = connection->get_dpd_delay(connection); this->dpd_delay = connection->get_dpd_delay(connection);
if (this->other_host->is_anyaddr(this->other_host))
{
SIG(SIG_IKE_FAILED,
"can not initiate a connection to %%any, aborting");
SIG(SIG_CHILD_FAILED,
"unable to create an IKE_SA to instantiate policy");
policy->destroy(policy);
connection->destroy(connection);
return DESTROY_ME;
}
this->message_id_out = 1; this->message_id_out = 1;
ike_sa_init = ike_sa_init_create(&this->public); ike_sa_init = ike_sa_init_create(&this->public);
ike_sa_init->set_config(ike_sa_init, connection, policy); ike_sa_init->set_config(ike_sa_init, connection, policy);
@@ -946,10 +922,12 @@ static status_t initiate(private_ike_sa_t *this,
case IKE_DELETING: case IKE_DELETING:
case IKE_REKEYING: case IKE_REKEYING:
{ {
/* if we are in DELETING/REKEYING, we deny set up of a policy. */ /* if we are in DELETING/REKEYING, we deny set up of a policy.
this->logger->log(this->logger, CONTROL, * TODO: would it make sense to queue the transaction and adopt
"creating CHILD_SA discarded, as IKE_SA is in state %s", * it all transactions to the new IKE_SA? */
mapping_find(ike_sa_state_m, this->state)); SIG(SIG_CHILD_FAILED,
"creating CHILD_SA discarded, as IKE_SA is in state %N",
ike_sa_state_names, this->state);
policy->destroy(policy); policy->destroy(policy);
connection->destroy(connection); connection->destroy(connection);
return FAILED; return FAILED;
@@ -957,16 +935,14 @@ static status_t initiate(private_ike_sa_t *this,
case IKE_CONNECTING: case IKE_CONNECTING:
case IKE_ESTABLISHED: case IKE_ESTABLISHED:
{ {
/* if we are ESTABLISHED or CONNECTING,we queue the /* if we are ESTABLISHED or CONNECTING, we queue the
* transaction to create the CHILD_SA. It gets processed * transaction to create the CHILD_SA. It gets processed
* when the IKE_SA is ready to do so. We don't need the * when the IKE_SA is ready to do so. We don't need the
* connection, as the IKE_SA is already established/establishing. * connection, as the IKE_SA is already established/establishing.
*/ */
create_child_sa_t *create_child; create_child_sa_t *create_child;
this->logger->log(this->logger, CONTROL, SIG(SIG_INITIATE, "creating CHILD_SA in existing IKE_SA");
"initiating CHILD_SA");
connection->destroy(connection); connection->destroy(connection);
create_child = create_child_sa_create(&this->public); create_child = create_child_sa_create(&this->public);
create_child->set_policy(create_child, policy); create_child->set_policy(create_child, policy);
@@ -989,13 +965,11 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
if (this->state == IKE_DELETING) if (this->state == IKE_DELETING)
{ {
this->logger->log(this->logger, CONTROL, SIG(SIG_CHILD_FAILED, "acquiring CHILD_SA (reqid %d) failed: "
"acquiring CHILD_SA with reqid %d discarded, as IKE_SA is deleting", "IKE_SA is deleting", reqid);
reqid);
return FAILED; return FAILED;
} }
/* find CHILD_SA */ /* find CHILD_SA */
iterator = this->child_sas->create_iterator(this->child_sas, TRUE); iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
while (iterator->iterate(iterator, (void**)&current)) while (iterator->iterate(iterator, (void**)&current))
@@ -1009,9 +983,8 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
iterator->destroy(iterator); iterator->destroy(iterator);
if (!child_sa) if (!child_sa)
{ {
this->logger->log(this->logger, ERROR, SIG(SIG_CHILD_FAILED, "acquiring CHILD_SA (reqid %d) failed: "
"CHILD_SA with reqid %d not found, unable to acquire", "CHILD_SA not found", reqid);
reqid);
return FAILED; return FAILED;
} }
my_ts = child_sa->get_my_traffic_selectors(child_sa); my_ts = child_sa->get_my_traffic_selectors(child_sa);
@@ -1023,9 +996,8 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
this->my_host, this->other_host); this->my_host, this->other_host);
if (policy == NULL) if (policy == NULL)
{ {
this->logger->log(this->logger, ERROR, SIG(SIG_CHILD_FAILED, "acquiring CHILD_SA (reqid %d) failed: "
"no policy found to acquire CHILD_SA with reqid %d", "no policy found", reqid);
reqid);
return FAILED; return FAILED;
} }
@@ -1035,18 +1007,16 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
{ {
ike_sa_init_t *ike_sa_init; ike_sa_init_t *ike_sa_init;
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_CHD,
"acquiring CHILD_SA with reqid %d, IKE_SA setup needed", "acquiring CHILD_SA with reqid %d, IKE_SA setup needed", reqid);
reqid);
connection = charon->connections->get_connection_by_hosts( connection = charon->connections->get_connection_by_hosts(
charon->connections, this->my_host, this->other_host); charon->connections, this->my_host, this->other_host);
if (connection == NULL) if (connection == NULL)
{ {
this->logger->log(this->logger, ERROR, SIG(SIG_CHILD_FAILED, "acquiring CHILD_SA "
"no connection found to acquire IKE_SA for CHILD_SA with reqid %d", "(reqid %d) failed: no connection found for IKE_SA", reqid);
reqid);
policy->destroy(policy); policy->destroy(policy);
return FAILED; return FAILED;
} }
@@ -1063,9 +1033,7 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
{ {
create_child_sa_t *create_child; create_child_sa_t *create_child;
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_CHD, "acquiring CHILD_SA with reqid %d", reqid);
"acquiring CHILD_SA with reqid %d",
reqid);
create_child = create_child_sa_create(&this->public); create_child = create_child_sa_create(&this->public);
create_child->set_policy(create_child, policy); create_child->set_policy(create_child, policy);
@@ -1151,8 +1119,8 @@ static status_t route(private_ike_sa_t *this, connection_t *connection, policy_t
ts_list_destroy(my_ts_conf); ts_list_destroy(my_ts_conf);
ts_list_destroy(other_ts_conf); ts_list_destroy(other_ts_conf);
iterator->destroy(iterator); iterator->destroy(iterator);
this->logger->log(this->logger, CONTROL, SIG(SIG_CHILD_FAILED, "CHILD_SA with such a policy "
"a CHILD_SA with such a policy already routed"); "already routed");
return FAILED; return FAILED;
} }
@@ -1202,7 +1170,8 @@ static status_t route(private_ike_sa_t *this, connection_t *connection, policy_t
* adopted by the new IKE_SA */ * adopted by the new IKE_SA */
break; break;
case IKE_DELETING: case IKE_DELETING:
/* deny */ SIG(SIG_CHILD_FAILED, "CHILD_SA with such a policy "
"already routed");
return FAILED; return FAILED;
} }
@@ -1218,6 +1187,8 @@ static status_t route(private_ike_sa_t *this, connection_t *connection, policy_t
ts_list_destroy(my_ts); ts_list_destroy(my_ts);
ts_list_destroy(other_ts); ts_list_destroy(other_ts);
this->child_sas->insert_last(this->child_sas, child_sa); this->child_sas->insert_last(this->child_sas, child_sa);
SIG(SIG_CHILD_ROUTE,
"CHILD_SA routed: %R...%R", my_ts, other_ts);
return status; return status;
} }
@@ -1247,6 +1218,7 @@ static status_t unroute(private_ike_sa_t *this, policy_t *policy)
ts_list_equals(other_ts, other_ts_conf)) ts_list_equals(other_ts, other_ts_conf))
{ {
iterator->remove(iterator); iterator->remove(iterator);
SIG(SIG_CHILD_UNROUTE, "CHILD_SA unrouted");
child_sa->destroy(child_sa); child_sa->destroy(child_sa);
ts_list_destroy(my_ts_conf); ts_list_destroy(my_ts_conf);
ts_list_destroy(other_ts_conf); ts_list_destroy(other_ts_conf);
@@ -1296,7 +1268,7 @@ static status_t send_dpd(private_ike_sa_t *this)
{ {
/* to long ago, initiate dead peer detection */ /* to long ago, initiate dead peer detection */
dead_peer_detection_t *dpd; dead_peer_detection_t *dpd;
this->logger->log(this->logger, CONTROL, "sending DPD request"); DBG1(SIG_DBG_IKE, "sending DPD request");
dpd = dead_peer_detection_create(&this->public); dpd = dead_peer_detection_create(&this->public);
queue_transaction(this, (transaction_t*)dpd, FALSE); queue_transaction(this, (transaction_t*)dpd, FALSE);
diff = 0; diff = 0;
@@ -1336,7 +1308,7 @@ static void send_keepalive(private_ike_sa_t *this)
data.len = 1; data.len = 1;
packet->set_data(packet, data); packet->set_data(packet, data);
charon->send_queue->add(charon->send_queue, packet); charon->send_queue->add(charon->send_queue, packet);
this->logger->log(this->logger, CONTROL, "sending keep alive"); DBG1(SIG_DBG_IKE, "sending keep alive");
diff = 0; diff = 0;
} }
job = send_keepalive_job_create(this->ike_sa_id); job = send_keepalive_job_create(this->ike_sa_id);
@@ -1357,18 +1329,20 @@ static ike_sa_state_t get_state(private_ike_sa_t *this)
*/ */
static void set_state(private_ike_sa_t *this, ike_sa_state_t state) static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
{ {
this->logger->log(this->logger, CONTROL, "state change: %s => %s", DBG1(SIG_DBG_IKE, "state change: %N => %N",
mapping_find(ike_sa_state_m, this->state), ike_sa_state_names, this->state,
mapping_find(ike_sa_state_m, state)); ike_sa_state_names, state);
if (state == IKE_ESTABLISHED) if (state == IKE_ESTABLISHED)
{ {
this->time.established = time(NULL); this->time.established = time(NULL);
this->logger->log(this->logger, AUDIT, "IKE_SA established: %H[%D]...%H[%D]",
this->my_host, this->my_id,
this->other_host, this->other_id);
/* start DPD checks */ /* start DPD checks */
send_dpd(this); send_dpd(this);
SIG(SIG_IKE_UP, "IKE_SA established: %H[%D]...%H[%D]",
this->my_host, this->my_id, this->other_host, this->other_id);
} }
this->state = state; this->state = state;
} }
@@ -1467,19 +1441,19 @@ static status_t derive_keys(private_ike_sa_t *this,
/* Create SAs general purpose PRF first, we may use it here */ /* Create SAs general purpose PRF first, we may use it here */
if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo)) if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo))
{ {
this->logger->log(this->logger, ERROR, "no PSEUDO_RANDOM_FUNCTION selected!"); DBG1(SIG_DBG_IKE, "key derivation failed: no PSEUDO_RANDOM_FUNCTION");;
return FAILED; return FAILED;
} }
this->prf = prf_create(algo->algorithm); this->prf = prf_create(algo->algorithm);
if (this->prf == NULL) if (this->prf == NULL)
{ {
this->logger->log(this->logger, ERROR, "PSEUDO_RANDOM_FUNCTION %s not supported!", DBG1(SIG_DBG_IKE, "key derivation failed: PSEUDO_RANDOM_FUNCTION "
mapping_find(pseudo_random_function_m, algo->algorithm)); "%N not supported!", pseudo_random_function_names, algo->algorithm);
return FAILED; return FAILED;
} }
dh->get_shared_secret(dh, &secret); dh->get_shared_secret(dh, &secret);
this->logger->log_chunk(this->logger, PRIVATE, "shared Diffie Hellman secret", secret); DBG4(SIG_DBG_IKE, "shared Diffie Hellman secret %B", &secret);
nonces = chunk_cat("cc", nonce_i, nonce_r); nonces = chunk_cat("cc", nonce_i, nonce_r);
*((u_int64_t*)spi_i.ptr) = this->ike_sa_id->get_initiator_spi(this->ike_sa_id); *((u_int64_t*)spi_i.ptr) = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
*((u_int64_t*)spi_r.ptr) = this->ike_sa_id->get_responder_spi(this->ike_sa_id); *((u_int64_t*)spi_r.ptr) = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
@@ -1490,11 +1464,11 @@ static status_t derive_keys(private_ike_sa_t *this,
* if we are rekeying, SKEYSEED built on another way * if we are rekeying, SKEYSEED built on another way
*/ */
if (child_prf == NULL) /* not rekeying */ if (child_prf == NULL) /* not rekeying */
{ {
/* SKEYSEED = prf(Ni | Nr, g^ir) */ /* SKEYSEED = prf(Ni | Nr, g^ir) */
this->prf->set_key(this->prf, nonces); this->prf->set_key(this->prf, nonces);
this->prf->allocate_bytes(this->prf, secret, &skeyseed); this->prf->allocate_bytes(this->prf, secret, &skeyseed);
this->logger->log_chunk(this->logger, PRIVATE|LEVEL1, "SKEYSEED", skeyseed); DBG4(SIG_DBG_IKE, "SKEYSEED %B", &skeyseed);
this->prf->set_key(this->prf, skeyseed); this->prf->set_key(this->prf, skeyseed);
chunk_free(&skeyseed); chunk_free(&skeyseed);
chunk_free(&secret); chunk_free(&secret);
@@ -1506,7 +1480,7 @@ static status_t derive_keys(private_ike_sa_t *this,
* use OLD SAs PRF functions for both prf_plus and prf */ * use OLD SAs PRF functions for both prf_plus and prf */
secret = chunk_cat("mc", secret, nonces); secret = chunk_cat("mc", secret, nonces);
child_prf->allocate_bytes(child_prf, secret, &skeyseed); child_prf->allocate_bytes(child_prf, secret, &skeyseed);
this->logger->log_chunk(this->logger, PRIVATE|LEVEL1, "SKEYSEED", skeyseed); DBG4(SIG_DBG_IKE, "SKEYSEED %B", &skeyseed);
old_prf->set_key(old_prf, skeyseed); old_prf->set_key(old_prf, skeyseed);
chunk_free(&skeyseed); chunk_free(&skeyseed);
chunk_free(&secret); chunk_free(&secret);
@@ -1522,33 +1496,33 @@ static status_t derive_keys(private_ike_sa_t *this,
this->child_prf = prf_create(algo->algorithm); this->child_prf = prf_create(algo->algorithm);
key_size = this->child_prf->get_key_size(this->child_prf); key_size = this->child_prf->get_key_size(this->child_prf);
prf_plus->allocate_bytes(prf_plus, key_size, &key); prf_plus->allocate_bytes(prf_plus, key_size, &key);
this->logger->log_chunk(this->logger, PRIVATE, "Sk_d secret", key); DBG4(SIG_DBG_IKE, "Sk_d secret %B", &key);
this->child_prf->set_key(this->child_prf, key); this->child_prf->set_key(this->child_prf, key);
chunk_free(&key); chunk_free(&key);
/* SK_ai/SK_ar used for integrity protection => signer_in/signer_out */ /* SK_ai/SK_ar used for integrity protection => signer_in/signer_out */
if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &algo)) if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &algo))
{ {
this->logger->log(this->logger, ERROR, "no INTEGRITY_ALGORITHM selected?!"); DBG1(SIG_DBG_IKE, "key derivation failed: no INTEGRITY_ALGORITHM");
return FAILED; return FAILED;
} }
signer_i = signer_create(algo->algorithm); signer_i = signer_create(algo->algorithm);
signer_r = signer_create(algo->algorithm); signer_r = signer_create(algo->algorithm);
if (signer_i == NULL || signer_r == NULL) if (signer_i == NULL || signer_r == NULL)
{ {
this->logger->log(this->logger, ERROR, "INTEGRITY_ALGORITHM %s not supported!", DBG1(SIG_DBG_IKE, "key derivation failed: INTEGRITY_ALGORITHM "
mapping_find(integrity_algorithm_m,algo->algorithm)); "%N not supported!", integrity_algorithm_names ,algo->algorithm);
return FAILED; return FAILED;
} }
key_size = signer_i->get_key_size(signer_i); key_size = signer_i->get_key_size(signer_i);
prf_plus->allocate_bytes(prf_plus, key_size, &key); prf_plus->allocate_bytes(prf_plus, key_size, &key);
this->logger->log_chunk(this->logger, PRIVATE, "Sk_ai secret", key); DBG4(SIG_DBG_IKE, "Sk_ai secret %B", &key);
signer_i->set_key(signer_i, key); signer_i->set_key(signer_i, key);
chunk_free(&key); chunk_free(&key);
prf_plus->allocate_bytes(prf_plus, key_size, &key); prf_plus->allocate_bytes(prf_plus, key_size, &key);
this->logger->log_chunk(this->logger, PRIVATE, "Sk_ar secret", key); DBG4(SIG_DBG_IKE, "Sk_ar secret %B", &key);
signer_r->set_key(signer_r, key); signer_r->set_key(signer_r, key);
chunk_free(&key); chunk_free(&key);
@@ -1566,28 +1540,27 @@ static status_t derive_keys(private_ike_sa_t *this,
/* SK_ei/SK_er used for encryption => crypter_in/crypter_out */ /* SK_ei/SK_er used for encryption => crypter_in/crypter_out */
if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &algo)) if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &algo))
{ {
this->logger->log(this->logger, ERROR, "no ENCRYPTION_ALGORITHM selected!"); DBG1(SIG_DBG_IKE, "key derivation failed: no ENCRYPTION_ALGORITHM");
return FAILED; return FAILED;
} }
crypter_i = crypter_create(algo->algorithm, algo->key_size / 8); crypter_i = crypter_create(algo->algorithm, algo->key_size / 8);
crypter_r = crypter_create(algo->algorithm, algo->key_size / 8); crypter_r = crypter_create(algo->algorithm, algo->key_size / 8);
if (crypter_i == NULL || crypter_r == NULL) if (crypter_i == NULL || crypter_r == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "key derivation failed: ENCRYPTION_ALGORITHM "
"ENCRYPTION_ALGORITHM %s (key size %d) not supported!", "%N (key size %d) not supported!",
mapping_find(encryption_algorithm_m, algo->algorithm), encryption_algorithm_names, algo->algorithm, algo->key_size);
algo->key_size);
return FAILED; return FAILED;
} }
key_size = crypter_i->get_key_size(crypter_i); key_size = crypter_i->get_key_size(crypter_i);
prf_plus->allocate_bytes(prf_plus, key_size, &key); prf_plus->allocate_bytes(prf_plus, key_size, &key);
this->logger->log_chunk(this->logger, PRIVATE, "Sk_ei secret", key); DBG4(SIG_DBG_IKE, "Sk_ei secret %B", &key);
crypter_i->set_key(crypter_i, key); crypter_i->set_key(crypter_i, key);
chunk_free(&key); chunk_free(&key);
prf_plus->allocate_bytes(prf_plus, key_size, &key); prf_plus->allocate_bytes(prf_plus, key_size, &key);
this->logger->log_chunk(this->logger, PRIVATE, "Sk_er secret", key); DBG4(SIG_DBG_IKE, "Sk_er secret %B", &key);
crypter_r->set_key(crypter_r, key); crypter_r->set_key(crypter_r, key);
chunk_free(&key); chunk_free(&key);
@@ -1609,12 +1582,12 @@ static status_t derive_keys(private_ike_sa_t *this,
key_size = this->prf_auth_i->get_key_size(this->prf_auth_i); key_size = this->prf_auth_i->get_key_size(this->prf_auth_i);
prf_plus->allocate_bytes(prf_plus, key_size, &key); prf_plus->allocate_bytes(prf_plus, key_size, &key);
this->logger->log_chunk(this->logger, PRIVATE, "Sk_pi secret", key); DBG4(SIG_DBG_IKE, "Sk_pi secret %B", &key);
this->prf_auth_i->set_key(this->prf_auth_i, key); this->prf_auth_i->set_key(this->prf_auth_i, key);
chunk_free(&key); chunk_free(&key);
prf_plus->allocate_bytes(prf_plus, key_size, &key); prf_plus->allocate_bytes(prf_plus, key_size, &key);
this->logger->log_chunk(this->logger, PRIVATE, "Sk_pr secret", key); DBG4(SIG_DBG_IKE, "Sk_pr secret %B", &key);
this->prf_auth_r->set_key(this->prf_auth_r, key); this->prf_auth_r->set_key(this->prf_auth_r, key);
chunk_free(&key); chunk_free(&key);
@@ -1781,16 +1754,14 @@ static status_t rekey(private_ike_sa_t *this)
{ {
rekey_ike_sa_t *rekey_ike_sa; rekey_ike_sa_t *rekey_ike_sa;
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "rekeying IKE_SA between %H[%D]..%H[%D]",
"rekeying IKE_SA between: %H[%D]...%H[%D]", this->my_host, this->my_id,
this->my_host, this->my_id,
this->other_host, this->other_id); this->other_host, this->other_id);
if (this->state != IKE_ESTABLISHED) if (this->state != IKE_ESTABLISHED)
{ {
this->logger->log(this->logger, ERROR, SIG(SIG_IKE_FAILED, "unable to rekey IKE_SA in state %N",
"unable to rekey IKE_SA in state %s", ike_sa_state_names, this->state);
mapping_find(ike_sa_state_m, this->state));
return FAILED; return FAILED;
} }
@@ -1828,57 +1799,6 @@ static void adopt_children(private_ike_sa_t *this, private_ike_sa_t *other)
} }
} }
/**
* Implementation of ike_sa_t.log_status.
*/
static void log_status(private_ike_sa_t *this, logger_t *logger, char *name)
{
iterator_t *iterator;
child_sa_t *child_sa;
bool contains_child = FALSE;
/* check for a CHILD_SA with specified name. We then print the IKE_SA,
* even it has another name */
if (name != NULL)
{
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
while (iterator->iterate(iterator, (void**)&child_sa))
{
if (streq(name, child_sa->get_name(child_sa)))
{
contains_child = TRUE;
break;
}
}
iterator->destroy(iterator);
}
if (name == NULL || contains_child || streq(name, this->name))
{
if (logger == NULL)
{
logger = this->logger;
}
logger->log(logger, CONTROL|LEVEL1,
" \"%s\": IKE_SA in state %s, SPIs: 0x%.16llx 0x%.16llx",
this->name,
mapping_find(ike_sa_state_m, this->state),
this->ike_sa_id->get_initiator_spi(this->ike_sa_id),
this->ike_sa_id->get_responder_spi(this->ike_sa_id));
logger->log(logger, CONTROL, " \"%s\": %H[%D]...%H[%D]",
this->name, this->my_host, this->my_id,
this->other_host, this->other_id);
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&child_sa);
child_sa->log_status(child_sa, logger);
}
iterator->destroy(iterator);
}
}
/** /**
* Implementation of public_ike_sa_t.delete. * Implementation of public_ike_sa_t.delete.
*/ */
@@ -1931,19 +1851,57 @@ static void enable_natt (private_ike_sa_t *this, bool local)
{ {
if (local) if (local)
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "local host is behind NAT, using NAT-T, "
"local host is behind NAT, using NAT-T, scheduled keep alives"); "scheduled keep alives");
this->nat_here = TRUE; this->nat_here = TRUE;
send_keepalive(this); send_keepalive(this);
} }
else else
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "remote host is behind NAT, using NAT-T");
"remote host is behind NAT, using NAT-T");
this->nat_there = TRUE; this->nat_there = TRUE;
} }
} }
/**
* output handler in printf()
*/
static int print(FILE *stream, const struct printf_info *info,
const void *const *args)
{
private_ike_sa_t *this = *((private_ike_sa_t**)(args[0]));
if (this == NULL)
{
return fprintf(stream, "(null)");
}
return fprintf(stream, "%10s: %N, %H[%D]...%H[%D] (%J)",
this->name, ike_sa_state_names, this->state,
this->my_host, this->my_id, this->other_host, this->other_id,
this->ike_sa_id);
}
/**
* arginfo handler in printf()
*/
static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes)
{
if (n > 0)
{
argtypes[0] = PA_POINTER;
}
return 1;
}
/**
* register printf() handlers
*/
static void __attribute__ ((constructor))print_register()
{
register_printf_function(IKE_SA_PRINTF_SPEC, print, print_arginfo);
}
/** /**
* Implementation of ike_sa_t.destroy. * Implementation of ike_sa_t.destroy.
*/ */
@@ -1952,17 +1910,6 @@ static void destroy(private_ike_sa_t *this)
child_sa_t *child_sa; child_sa_t *child_sa;
transaction_t *transaction; transaction_t *transaction;
this->logger->log(this->logger, CONTROL|LEVEL2, "going to destroy IKE SA %llu:%llu, role %s",
this->ike_sa_id->get_initiator_spi(this->ike_sa_id),
this->ike_sa_id->get_responder_spi(this->ike_sa_id),
this->ike_sa_id->is_initiator(this->ike_sa_id) ? "initiator" : "responder");
if (this->state == IKE_ESTABLISHED)
{
this->logger->log(this->logger, ERROR,
"destroying an established IKE SA without knowledge from remote peer!");
}
while (this->child_sas->remove_last(this->child_sas, (void**)&child_sa) == SUCCESS) while (this->child_sas->remove_last(this->child_sas, (void**)&child_sa) == SUCCESS)
{ {
child_sa->destroy(child_sa); child_sa->destroy(child_sa);
@@ -1987,10 +1934,8 @@ static void destroy(private_ike_sa_t *this)
DESTROY_IF(this->prf_auth_i); DESTROY_IF(this->prf_auth_i);
DESTROY_IF(this->prf_auth_r); DESTROY_IF(this->prf_auth_r);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "IKE_SA deleted between %H[%D]...%H[%D]",
"IKE_SA deleted between: %H[%D]...%H[%D]", this->my_host, this->my_id, this->other_host, this->other_id);
this->my_host, this->my_id,
this->other_host, this->other_id);
DESTROY_IF(this->my_host); DESTROY_IF(this->my_host);
DESTROY_IF(this->other_host); DESTROY_IF(this->other_host);
@@ -2030,7 +1975,6 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.set_other_id = (void(*)(ike_sa_t*,identification_t*)) set_other_id; this->public.set_other_id = (void(*)(ike_sa_t*,identification_t*)) set_other_id;
this->public.get_next_message_id = (u_int32_t(*)(ike_sa_t*)) get_next_message_id; this->public.get_next_message_id = (u_int32_t(*)(ike_sa_t*)) get_next_message_id;
this->public.retransmit_request = (status_t (*) (ike_sa_t *, u_int32_t)) retransmit_request; this->public.retransmit_request = (status_t (*) (ike_sa_t *, u_int32_t)) retransmit_request;
this->public.log_status = (void (*) (ike_sa_t*,logger_t*,char*))log_status;
this->public.delete = (status_t(*)(ike_sa_t*))delete_; this->public.delete = (status_t(*)(ike_sa_t*))delete_;
this->public.destroy = (void(*)(ike_sa_t*))destroy; this->public.destroy = (void(*)(ike_sa_t*))destroy;
this->public.send_dpd = (status_t (*)(ike_sa_t*)) send_dpd; this->public.send_dpd = (status_t (*)(ike_sa_t*)) send_dpd;
@@ -2057,7 +2001,6 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.adopt_children = (void(*)(ike_sa_t*,ike_sa_t*))adopt_children; this->public.adopt_children = (void(*)(ike_sa_t*,ike_sa_t*))adopt_children;
/* initialize private fields */ /* initialize private fields */
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
this->ike_sa_id = ike_sa_id->clone(ike_sa_id); this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->name = strdup("(uninitialized)"); this->name = strdup("(uninitialized)");
this->child_sas = linked_list_create(); this->child_sas = linked_list_create();
+4 -18
View File
@@ -31,7 +31,6 @@
#include <sa/ike_sa_id.h> #include <sa/ike_sa_id.h>
#include <sa/child_sa.h> #include <sa/child_sa.h>
#include <config/configuration.h> #include <config/configuration.h>
#include <utils/logger.h>
#include <utils/randomizer.h> #include <utils/randomizer.h>
#include <crypto/prfs/prf.h> #include <crypto/prfs/prf.h>
#include <crypto/crypters/crypter.h> #include <crypto/crypters/crypter.h>
@@ -39,9 +38,10 @@
#include <config/connections/connection.h> #include <config/connections/connection.h>
#include <config/policies/policy.h> #include <config/policies/policy.h>
#include <config/proposal.h> #include <config/proposal.h>
#include <utils/logger.h>
#define IKE_SA_PRINTF_SPEC 'K'
typedef enum ike_sa_state_t ike_sa_state_t; typedef enum ike_sa_state_t ike_sa_state_t;
/** /**
@@ -112,9 +112,9 @@ enum ike_sa_state_t {
}; };
/** /**
* String mappings for ike_sa_state_t. * enum names for ike_sa_state_t.
*/ */
extern mapping_t ike_sa_state_m[]; extern enum_name_t *ike_sa_state_names;
typedef struct ike_sa_t ike_sa_t; typedef struct ike_sa_t ike_sa_t;
@@ -403,20 +403,6 @@ struct ike_sa_t {
* @param this calling object * @param this calling object
*/ */
void (*send_keepalive) (ike_sa_t *this); void (*send_keepalive) (ike_sa_t *this);
/**
* @brief Log the status of a the ike sa to a logger.
*
* The status of the IKE SA and all child SAs is logged.
* Supplying NULL as logger uses the internal child_sa logger
* to do the logging. The log is only done if the supplied
* connection name is NULL or matches the connections name.
*
* @param this calling object
* @param logger logger to use for logging
* @param name name of the connection
*/
void (*log_status) (ike_sa_t *this, logger_t *logger, char *name);
/** /**
* @brief Derive all keys and create the transforms for IKE communication. * @brief Derive all keys and create the transforms for IKE communication.
+41 -1
View File
@@ -24,6 +24,8 @@
#include "ike_sa_id.h" #include "ike_sa_id.h"
#include <printf.h>
#include <stdio.h>
typedef struct private_ike_sa_id_t private_ike_sa_id_t; typedef struct private_ike_sa_id_t private_ike_sa_id_t;
@@ -137,7 +139,7 @@ static bool switch_initiator(private_ike_sa_id_t *this)
} }
else else
{ {
this->is_initiator_flag = TRUE; this->is_initiator_flag = TRUE;
} }
return this->is_initiator_flag; return this->is_initiator_flag;
} }
@@ -150,6 +152,44 @@ static ike_sa_id_t* clone(private_ike_sa_id_t *this)
return ike_sa_id_create(this->initiator_spi, this->responder_spi, this->is_initiator_flag); return ike_sa_id_create(this->initiator_spi, this->responder_spi, this->is_initiator_flag);
} }
/**
* output handler in printf()
*/
static int print(FILE *stream, const struct printf_info *info,
const void *const *args)
{
private_ike_sa_id_t *this = *((private_ike_sa_id_t**)(args[0]));
if (this == NULL)
{
return fprintf(stream, "(null)");
}
return fprintf(stream, "%llx:%llx[%c]",
this->initiator_spi, this->responder_spi,
this->is_initiator_flag ? 'i' : 'r');
}
/**
* arginfo handler in printf()
*/
static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes)
{
if (n > 0)
{
argtypes[0] = PA_POINTER;
}
return 1;
}
/**
* register printf() handlers
*/
static void __attribute__ ((constructor))print_register()
{
register_printf_function(IKE_SA_ID_PRINTF_SPEC, print, print_arginfo);
}
/** /**
* Implementation of ike_sa_id_t.destroy. * Implementation of ike_sa_id_t.destroy.
*/ */
+4
View File
@@ -27,6 +27,10 @@
#include <types.h> #include <types.h>
/**
* printf() specifier to print a ike_sa_id.
*/
#define IKE_SA_ID_PRINTF_SPEC 'J'
typedef struct ike_sa_id_t ike_sa_id_t; typedef struct ike_sa_id_t ike_sa_id_t;
+107 -214
View File
@@ -28,20 +28,15 @@
#include <daemon.h> #include <daemon.h>
#include <sa/ike_sa_id.h> #include <sa/ike_sa_id.h>
#include <utils/logger.h> #include <bus/bus.h>
#include <utils/logger_manager.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
typedef struct ike_sa_entry_t ike_sa_entry_t; typedef struct entry_t entry_t;
/** /**
* An entry in the linked list, contains IKE_SA, locking and lookup data. * An entry in the linked list, contains IKE_SA, locking and lookup data.
*/ */
struct ike_sa_entry_t { struct entry_t {
/**
* Destructor, also destroys associated ike_sa_t object.
*/
status_t (*destroy) (ike_sa_entry_t *this);
/** /**
* Number of threads waiting for this ike_sa_t object. * Number of threads waiting for this ike_sa_t object.
@@ -80,9 +75,9 @@ struct ike_sa_entry_t {
}; };
/** /**
* Implementation of ike_sa_entry_t.destroy. * Implementation of entry_t.destroy.
*/ */
static status_t ike_sa_entry_destroy(ike_sa_entry_t *this) static status_t entry_destroy(entry_t *this)
{ {
/* also destroy IKE SA */ /* also destroy IKE SA */
this->ike_sa->destroy(this->ike_sa); this->ike_sa->destroy(this->ike_sa);
@@ -92,19 +87,11 @@ static status_t ike_sa_entry_destroy(ike_sa_entry_t *this)
} }
/** /**
* @brief Creates a new entry for the ike_sa_t list. * Creates a new entry for the ike_sa_t list.
*
* This constructor additionaly creates a new and empty SA.
*
* @param ike_sa_id The associated ike_sa_id_t, will be cloned
* @return ike_sa_entry_t object
*/ */
static ike_sa_entry_t *ike_sa_entry_create(ike_sa_id_t *ike_sa_id) static entry_t *entry_create(ike_sa_id_t *ike_sa_id)
{ {
ike_sa_entry_t *this = malloc_thing(ike_sa_entry_t); entry_t *this = malloc_thing(entry_t);
/* destroy function */
this->destroy = ike_sa_entry_destroy;
this->waiting_threads = 0; this->waiting_threads = 0;
pthread_cond_init(&(this->condvar), NULL); pthread_cond_init(&(this->condvar), NULL);
@@ -140,11 +127,6 @@ struct private_ike_sa_manager_t {
*/ */
pthread_mutex_t mutex; pthread_mutex_t mutex;
/**
* Logger used for this IKE SA Manager.
*/
logger_t *logger;
/** /**
* Linked list with entries for the ike_sa_t objects. * Linked list with entries for the ike_sa_t objects.
*/ */
@@ -159,10 +141,11 @@ struct private_ike_sa_manager_t {
/** /**
* Implementation of private_ike_sa_manager_t.get_entry_by_id. * Implementation of private_ike_sa_manager_t.get_entry_by_id.
*/ */
static status_t get_entry_by_id(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, ike_sa_entry_t **entry) static status_t get_entry_by_id(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, entry_t **entry)
{ {
linked_list_t *list = this->ike_sa_list; linked_list_t *list = this->ike_sa_list;
iterator_t *iterator; iterator_t *iterator;
entry_t *current;
status_t status; status_t status;
/* create iterator over list of ike_sa's */ /* create iterator over list of ike_sa's */
@@ -171,48 +154,30 @@ static status_t get_entry_by_id(private_ike_sa_manager_t *this, ike_sa_id_t *ike
/* default status */ /* default status */
status = NOT_FOUND; status = NOT_FOUND;
while (iterator->has_next(iterator)) while (iterator->iterate(iterator, (void**)&current))
{ {
ike_sa_entry_t *current; if (current->ike_sa_id->equals(current->ike_sa_id, ike_sa_id))
{
iterator->current(iterator, (void**)&current); DBG2(SIG_DBG_MGR, "found entry by both SPIs");
if (current->ike_sa_id->get_responder_spi(current->ike_sa_id) == 0) *entry = current;
status = SUCCESS;
break;
}
if (ike_sa_id->get_responder_spi(ike_sa_id) == 0 ||
current->ike_sa_id->get_responder_spi(current->ike_sa_id) == 0)
{ {
/* seems to be a half ready ike_sa */ /* seems to be a half ready ike_sa */
if ((current->ike_sa_id->get_initiator_spi(current->ike_sa_id) == if ((current->ike_sa_id->get_initiator_spi(current->ike_sa_id) ==
ike_sa_id->get_initiator_spi(ike_sa_id)) && ike_sa_id->get_initiator_spi(ike_sa_id)) &&
(ike_sa_id->is_initiator(ike_sa_id) == (current->ike_sa_id->is_initiator(ike_sa_id) ==
current->ike_sa_id->is_initiator(current->ike_sa_id))) ike_sa_id->is_initiator(current->ike_sa_id)))
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "found entry by initiator SPI");
"found entry by initiator spi %d",
ike_sa_id->get_initiator_spi(ike_sa_id));
*entry = current; *entry = current;
status = SUCCESS; status = SUCCESS;
break; break;
} }
} }
else if (ike_sa_id->get_responder_spi(ike_sa_id) == 0)
{
if ((current->ike_sa_id->get_initiator_spi(current->ike_sa_id) ==
ike_sa_id->get_initiator_spi(ike_sa_id)) &&
(ike_sa_id->is_initiator(ike_sa_id) ==
current->ike_sa_id->is_initiator(current->ike_sa_id)))
{
this->logger->log(this->logger, CONTROL|LEVEL2, "found entry by initiator spi %d",
ike_sa_id->get_initiator_spi(ike_sa_id));
*entry = current;
status = SUCCESS;
break;
}
}
if (current->ike_sa_id->equals(current->ike_sa_id, ike_sa_id))
{
this->logger->log(this->logger, CONTROL|LEVEL2, "found entry by full ID");
*entry = current;
status = SUCCESS;
break;
}
} }
iterator->destroy(iterator); iterator->destroy(iterator);
@@ -222,7 +187,7 @@ static status_t get_entry_by_id(private_ike_sa_manager_t *this, ike_sa_id_t *ike
/** /**
* Implementation of private_ike_sa_manager_t.get_entry_by_sa. * Implementation of private_ike_sa_manager_t.get_entry_by_sa.
*/ */
static status_t get_entry_by_sa(private_ike_sa_manager_t *this, ike_sa_t *ike_sa, ike_sa_entry_t **entry) static status_t get_entry_by_sa(private_ike_sa_manager_t *this, ike_sa_t *ike_sa, entry_t **entry)
{ {
linked_list_t *list = this->ike_sa_list; linked_list_t *list = this->ike_sa_list;
iterator_t *iterator; iterator_t *iterator;
@@ -235,12 +200,12 @@ static status_t get_entry_by_sa(private_ike_sa_manager_t *this, ike_sa_t *ike_sa
while (iterator->has_next(iterator)) while (iterator->has_next(iterator))
{ {
ike_sa_entry_t *current; entry_t *current;
iterator->current(iterator, (void**)&current); iterator->current(iterator, (void**)&current);
/* only pointers are compared */ /* only pointers are compared */
if (current->ike_sa == ike_sa) if (current->ike_sa == ike_sa)
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, "found entry by pointer"); DBG2(SIG_DBG_MGR, "found entry by pointer");
*entry = current; *entry = current;
status = SUCCESS; status = SUCCESS;
break; break;
@@ -254,7 +219,7 @@ static status_t get_entry_by_sa(private_ike_sa_manager_t *this, ike_sa_t *ike_sa
/** /**
* Implementation of private_ike_sa_manager_s.delete_entry. * Implementation of private_ike_sa_manager_s.delete_entry.
*/ */
static status_t delete_entry(private_ike_sa_manager_t *this, ike_sa_entry_t *entry) static status_t delete_entry(private_ike_sa_manager_t *this, entry_t *entry)
{ {
linked_list_t *list = this->ike_sa_list; linked_list_t *list = this->ike_sa_list;
iterator_t *iterator; iterator_t *iterator;
@@ -266,7 +231,7 @@ static status_t delete_entry(private_ike_sa_manager_t *this, ike_sa_entry_t *ent
while (iterator->has_next(iterator)) while (iterator->has_next(iterator))
{ {
ike_sa_entry_t *current; entry_t *current;
iterator->current(iterator, (void**)&current); iterator->current(iterator, (void**)&current);
if (current == entry) if (current == entry)
{ {
@@ -281,23 +246,22 @@ static status_t delete_entry(private_ike_sa_manager_t *this, ike_sa_entry_t *ent
pthread_cond_wait(&(entry->condvar), &(this->mutex)); pthread_cond_wait(&(entry->condvar), &(this->mutex));
} }
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "found entry by pointer, deleting it");
"found entry by pointer. Going to delete it");
iterator->remove(iterator); iterator->remove(iterator);
entry->destroy(entry); entry_destroy(entry);
status = SUCCESS; status = SUCCESS;
break; break;
} }
} }
iterator->destroy(iterator); iterator->destroy(iterator);
return status; return status;
} }
/** /**
* Wait until no other thread is using an IKE_SA, return FALSE if entry not * Wait until no other thread is using an IKE_SA, return FALSE if entry not
* acquireable * acquireable
*/ */
static bool wait_for_entry(private_ike_sa_manager_t *this, ike_sa_entry_t *entry) static bool wait_for_entry(private_ike_sa_manager_t *this, entry_t *entry)
{ {
if (entry->driveout_new_threads) if (entry->driveout_new_threads)
{ {
@@ -351,7 +315,7 @@ static ike_sa_t* checkout_by_id(private_ike_sa_manager_t *this,
iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE); iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE);
while (iterator->has_next(iterator)) while (iterator->has_next(iterator))
{ {
ike_sa_entry_t *entry; entry_t *entry;
identification_t *found_my_id, *found_other_id; identification_t *found_my_id, *found_other_id;
host_t *found_my_host, *found_other_host; host_t *found_my_host, *found_other_host;
int wc; int wc;
@@ -384,9 +348,8 @@ static ike_sa_t* checkout_by_id(private_ike_sa_manager_t *this,
found_other_id->matches(found_other_id, other_id, &wc)) found_other_id->matches(found_other_id, other_id, &wc))
{ {
/* looks good, we take this one */ /* looks good, we take this one */
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_MGR, "found an existing IKE_SA for %H[%D]...%H[%D]",
"found an existing IKE_SA for %H[%D]...%H[%D]", my_host, other_host, my_id, other_id);
my_host, other_host, my_id, other_id);
entry->checked_out = TRUE; entry->checked_out = TRUE;
ike_sa = entry->ike_sa; ike_sa = entry->ike_sa;
} }
@@ -396,7 +359,7 @@ static ike_sa_t* checkout_by_id(private_ike_sa_manager_t *this,
if (!ike_sa) if (!ike_sa)
{ {
u_int64_t initiator_spi; u_int64_t initiator_spi;
ike_sa_entry_t *new_ike_sa_entry; entry_t *new_entry;
ike_sa_id_t *new_ike_sa_id; ike_sa_id_t *new_ike_sa_id;
initiator_spi = get_next_spi(this); initiator_spi = get_next_spi(this);
@@ -404,24 +367,19 @@ static ike_sa_t* checkout_by_id(private_ike_sa_manager_t *this,
new_ike_sa_id->set_initiator_spi(new_ike_sa_id, initiator_spi); new_ike_sa_id->set_initiator_spi(new_ike_sa_id, initiator_spi);
/* create entry */ /* create entry */
new_ike_sa_entry = ike_sa_entry_create(new_ike_sa_id); new_entry = entry_create(new_ike_sa_id);
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "created IKE_SA: %J", new_ike_sa_id);
"created IKE_SA %llx:%llx, role %s",
new_ike_sa_id->get_initiator_spi(new_ike_sa_id),
new_ike_sa_id->get_responder_spi(new_ike_sa_id),
new_ike_sa_id->is_initiator(new_ike_sa_id) ? "initiator" : "responder");
new_ike_sa_id->destroy(new_ike_sa_id); new_ike_sa_id->destroy(new_ike_sa_id);
this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry); this->ike_sa_list->insert_last(this->ike_sa_list, new_entry);
/* check ike_sa out */ /* check ike_sa out */
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_MGR, "new IKE_SA created for IDs [%D]...[%D]", my_id, other_id);
"new IKE_SA created for IDs %D - %D", my_id, other_id); new_entry->checked_out = TRUE;
new_ike_sa_entry->checked_out = TRUE; ike_sa = new_entry->ike_sa;
ike_sa = new_ike_sa_entry->ike_sa;
} }
pthread_mutex_unlock(&(this->mutex)); pthread_mutex_unlock(&(this->mutex));
SIG_SA(ike_sa); charon->bus->set_sa(charon->bus, ike_sa);
return ike_sa; return ike_sa;
} }
@@ -435,14 +393,10 @@ static ike_sa_t* checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id
bool original_initiator; bool original_initiator;
ike_sa_t *ike_sa = NULL; ike_sa_t *ike_sa = NULL;
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "checkout IKE_SA: %J", ike_sa_id);
"checkout IKE_SA %llx:%llx, role %s",
ike_sa_id->get_initiator_spi(ike_sa_id),
ike_sa_id->get_responder_spi(ike_sa_id),
ike_sa_id->is_initiator(ike_sa_id) ? "initiator" : "responder");
this->logger->log(this->logger, CONTROL|LEVEL2, "%d IKE_SAs in manager", DBG2(SIG_DBG_MGR, "%d IKE_SAs in manager",
this->ike_sa_list->get_count(this->ike_sa_list)); this->ike_sa_list->get_count(this->ike_sa_list));
/* each access is locked */ /* each access is locked */
pthread_mutex_lock(&(this->mutex)); pthread_mutex_lock(&(this->mutex));
@@ -457,28 +411,25 @@ static ike_sa_t* checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id
/* we SHOULD have an IKE_SA for these SPIs in the list, /* we SHOULD have an IKE_SA for these SPIs in the list,
* if not, we can't handle the request... * if not, we can't handle the request...
*/ */
ike_sa_entry_t *entry; entry_t *entry;
/* look for the entry */ /* look for the entry */
if (get_entry_by_id(this, ike_sa_id, &entry) == SUCCESS) if (get_entry_by_id(this, ike_sa_id, &entry) == SUCCESS)
{ {
if (wait_for_entry(this, entry)) if (wait_for_entry(this, entry))
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "IKE_SA successfully checked out");
"IKE_SA successfully checked out");
/* ok, this IKE_SA is finally ours */ /* ok, this IKE_SA is finally ours */
entry->checked_out = TRUE; entry->checked_out = TRUE;
ike_sa = entry->ike_sa; ike_sa = entry->ike_sa;
} }
else else
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "IKE_SA found, but not allowed to check it out");
"IKE_SA found, but not allowed to check it out");
} }
} }
else else
{ {
this->logger->log(this->logger, ERROR|LEVEL1, DBG2(SIG_DBG_MGR, "IKE_SA not stored in list");
"IKE_SA not stored in list");
/* looks like there is no such IKE_SA, better luck next time... */ /* looks like there is no such IKE_SA, better luck next time... */
} }
} }
@@ -492,7 +443,7 @@ static ike_sa_t* checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id
* IKE_SA. This could be improved... * IKE_SA. This could be improved...
*/ */
u_int64_t responder_spi; u_int64_t responder_spi;
ike_sa_entry_t *new_ike_sa_entry; entry_t *new_entry;
/* set SPIs, we are the responder */ /* set SPIs, we are the responder */
responder_spi = get_next_spi(this); responder_spi = get_next_spi(this);
@@ -501,45 +452,40 @@ static ike_sa_t* checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id
ike_sa_id->set_responder_spi(ike_sa_id, responder_spi); ike_sa_id->set_responder_spi(ike_sa_id, responder_spi);
/* create entry */ /* create entry */
new_ike_sa_entry = ike_sa_entry_create(ike_sa_id); new_entry = entry_create(ike_sa_id);
this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry); this->ike_sa_list->insert_last(this->ike_sa_list, new_entry);
/* check ike_sa out */ /* check ike_sa out */
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_MGR, "IKE_SA added to list of known IKE_SAs");
"IKE_SA added to list of known IKE_SAs"); new_entry->checked_out = TRUE;
new_ike_sa_entry->checked_out = TRUE; ike_sa = new_entry->ike_sa;
ike_sa = new_ike_sa_entry->ike_sa;
} }
else if (!initiator_spi_set && !responder_spi_set && original_initiator) else if (!initiator_spi_set && !responder_spi_set && original_initiator)
{ {
/* checkout of a new and unused IKE_SA, used for rekeying */ /* checkout of a new and unused IKE_SA, used for rekeying */
ike_sa_entry_t *new_ike_sa_entry; entry_t *new_entry;
ike_sa_id->set_initiator_spi(ike_sa_id, get_next_spi(this)); ike_sa_id->set_initiator_spi(ike_sa_id, get_next_spi(this));
/* create entry */ /* create entry */
new_ike_sa_entry = ike_sa_entry_create(ike_sa_id); new_entry = entry_create(ike_sa_id);
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "created IKE_SA: %J", ike_sa_id);
"created IKE_SA %llx:%llx, role %s",
ike_sa_id->get_initiator_spi(ike_sa_id),
ike_sa_id->get_responder_spi(ike_sa_id),
ike_sa_id->is_initiator(ike_sa_id) ? "initiator" : "responder");
this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry); this->ike_sa_list->insert_last(this->ike_sa_list, new_entry);
/* check ike_sa out */ /* check ike_sa out */
new_ike_sa_entry->checked_out = TRUE; new_entry->checked_out = TRUE;
ike_sa = new_ike_sa_entry->ike_sa; ike_sa = new_entry->ike_sa;
} }
else else
{ {
/* responder set, initiator not: here is something seriously wrong! */ /* responder set, initiator not: here is something seriously wrong! */
this->logger->log(this->logger, ERROR|LEVEL1, "invalid IKE_SA SPIs"); DBG2(SIG_DBG_MGR, "invalid IKE_SA SPIs");
} }
pthread_mutex_unlock(&(this->mutex)); pthread_mutex_unlock(&(this->mutex));
SIG_SA(ike_sa); charon->bus->set_sa(charon->bus, ike_sa);
return ike_sa; return ike_sa;
} }
@@ -557,7 +503,7 @@ static ike_sa_t* checkout_by_child(private_ike_sa_manager_t *this,
iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE); iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE);
while (iterator->has_next(iterator)) while (iterator->has_next(iterator))
{ {
ike_sa_entry_t *entry; entry_t *entry;
iterator->current(iterator, (void**)&entry); iterator->current(iterator, (void**)&entry);
if (wait_for_entry(this, entry)) if (wait_for_entry(this, entry))
@@ -575,63 +521,35 @@ static ike_sa_t* checkout_by_child(private_ike_sa_manager_t *this,
iterator->destroy(iterator); iterator->destroy(iterator);
pthread_mutex_unlock(&(this->mutex)); pthread_mutex_unlock(&(this->mutex));
SIG_SA(ike_sa); charon->bus->set_sa(charon->bus, ike_sa);
return ike_sa; return ike_sa;
} }
/** /**
* Implementation of ike_sa_manager_t.get_ike_sa_list. * Iterator hook for iterate
*/ */
static linked_list_t *get_ike_sa_list(private_ike_sa_manager_t* this) static bool iterate(iterator_t *iterator, void **value)
{ {
linked_list_t *list; if (iterator->has_next(iterator))
iterator_t *iterator;
pthread_mutex_lock(&(this->mutex));
list = linked_list_create();
iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE);
while (iterator->has_next(iterator))
{ {
ike_sa_entry_t *entry; entry_t *entry;
iterator->current(iterator, (void**)&entry); iterator->current(iterator, (void**)&entry);
list->insert_last(list, (void*)entry->ike_sa_id->clone(entry->ike_sa_id)); *value = entry->ike_sa;
return TRUE;
} }
iterator->destroy(iterator); return FALSE;
pthread_mutex_unlock(&(this->mutex));
return list;
} }
/** /**
* Implementation of ike_sa_manager_t.log_status. * Implementation of ike_sa_manager_t.create_iterator.
*/ */
static void log_status(private_ike_sa_manager_t* this, logger_t* logger, char* name) static iterator_t *create_iterator(private_ike_sa_manager_t* this)
{ {
iterator_t *iterator; iterator_t *iterator = this->ike_sa_list->create_iterator_locked(
u_int instances; this->ike_sa_list, &this->mutex);
/* overload iterator */
pthread_mutex_lock(&(this->mutex)); iterator->iterate = iterate;
return iterator;
instances = this->ike_sa_list->get_count(this->ike_sa_list);
if (instances)
{
logger->log(logger, CONTROL, "Instances (%d):", instances);
}
iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE);
while (iterator->has_next(iterator))
{
ike_sa_entry_t *entry;
iterator->current(iterator, (void**)&entry);
if (wait_for_entry(this, entry))
{
entry->ike_sa->log_status(entry->ike_sa, logger, name);
}
}
iterator->destroy(iterator);
pthread_mutex_unlock(&(this->mutex));
} }
/** /**
@@ -645,16 +563,12 @@ static status_t checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
* of a IKE_SA_INIT response). Updating of the SPI MAY be necessary... * of a IKE_SA_INIT response). Updating of the SPI MAY be necessary...
*/ */
status_t retval; status_t retval;
ike_sa_entry_t *entry; entry_t *entry;
ike_sa_id_t *ike_sa_id; ike_sa_id_t *ike_sa_id;
ike_sa_id = ike_sa->get_id(ike_sa); ike_sa_id = ike_sa->get_id(ike_sa);
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "checkin IKE_SA: %J", ike_sa_id);
"checkin IKE_SA %llx:%llx, role %s",
ike_sa_id->get_initiator_spi(ike_sa_id),
ike_sa_id->get_responder_spi(ike_sa_id),
ike_sa_id->is_initiator(ike_sa_id) ? "initiator" : "responder");
pthread_mutex_lock(&(this->mutex)); pthread_mutex_lock(&(this->mutex));
@@ -665,23 +579,22 @@ static status_t checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
entry->ike_sa_id->replace_values(entry->ike_sa_id, ike_sa->get_id(ike_sa)); entry->ike_sa_id->replace_values(entry->ike_sa_id, ike_sa->get_id(ike_sa));
/* signal waiting threads */ /* signal waiting threads */
entry->checked_out = FALSE; entry->checked_out = FALSE;
this->logger->log(this->logger, CONTROL|LEVEL1, "check-in of IKE_SA successful."); DBG2(SIG_DBG_MGR, "check-in of IKE_SA successful.");
pthread_cond_signal(&(entry->condvar)); pthread_cond_signal(&(entry->condvar));
retval = SUCCESS; retval = SUCCESS;
} }
else else
{ {
this->logger->log(this->logger, ERROR, DBG2(SIG_DBG_MGR, "tried to check in nonexisting IKE_SA");
"tried to check in nonexisting IKE_SA");
/* this SA is no more, this REALLY should not happen */ /* this SA is no more, this REALLY should not happen */
retval = NOT_FOUND; retval = NOT_FOUND;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, "%d IKE_SAs in manager now", DBG2(SIG_DBG_MGR, "%d IKE_SAs in manager now",
this->ike_sa_list->get_count(this->ike_sa_list)); this->ike_sa_list->get_count(this->ike_sa_list));
pthread_mutex_unlock(&(this->mutex)); pthread_mutex_unlock(&(this->mutex));
SIG_SA(NULL); charon->bus->set_sa(charon->bus, NULL);
return retval; return retval;
} }
@@ -696,16 +609,12 @@ static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ik
* We take this SA from the list, and start signaling while threads * We take this SA from the list, and start signaling while threads
* are in the condvar. * are in the condvar.
*/ */
ike_sa_entry_t *entry; entry_t *entry;
status_t retval; status_t retval;
ike_sa_id_t *ike_sa_id; ike_sa_id_t *ike_sa_id;
ike_sa_id = ike_sa->get_id(ike_sa); ike_sa_id = ike_sa->get_id(ike_sa);
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "checkin and destroy IKE_SA: %J", ike_sa_id);
"checkin and destroy IKE_SA %llx:%llx, role %s",
ike_sa_id->get_initiator_spi(ike_sa_id),
ike_sa_id->get_responder_spi(ike_sa_id),
ike_sa_id->is_initiator(ike_sa_id) ? "initiator" : "responder");
pthread_mutex_lock(&(this->mutex)); pthread_mutex_lock(&(this->mutex));
@@ -716,19 +625,17 @@ static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ik
delete_entry(this, entry); delete_entry(this, entry);
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_MGR, "check-in and destroy of IKE_SA successful");
"check-in and destroy of IKE_SA successful");
retval = SUCCESS; retval = SUCCESS;
} }
else else
{ {
this->logger->log(this->logger,ERROR, DBG2(SIG_DBG_MGR, "tried to check-in and delete nonexisting IKE_SA");
"tried to check-in and delete nonexisting IKE_SA");
retval = NOT_FOUND; retval = NOT_FOUND;
} }
pthread_mutex_unlock(&(this->mutex)); pthread_mutex_unlock(&(this->mutex));
SIG_SA(NULL); charon->bus->set_sa(charon->bus, ike_sa);
return retval; return retval;
} }
@@ -742,14 +649,10 @@ static status_t delete_(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id)
* We take this SA from the list, and start signaling while threads * We take this SA from the list, and start signaling while threads
* are in the condvar. * are in the condvar.
*/ */
ike_sa_entry_t *entry; entry_t *entry;
status_t retval; status_t retval;
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "delete IKE_SA: %J", ike_sa_id);
"delete IKE_SA %llx:%llx, role %s",
ike_sa_id->get_initiator_spi(ike_sa_id),
ike_sa_id->get_responder_spi(ike_sa_id),
ike_sa_id->is_initiator(ike_sa_id) ? "initiator" : "responder");
pthread_mutex_lock(&(this->mutex)); pthread_mutex_lock(&(this->mutex));
@@ -760,8 +663,7 @@ static status_t delete_(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id)
*/ */
if (entry->ike_sa->delete(entry->ike_sa) == SUCCESS) if (entry->ike_sa->delete(entry->ike_sa) == SUCCESS)
{ {
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_MGR, "initiated delete for IKE_SA");
"initiated delete for IKE_SA");
} }
/* but if the IKE SA is not in a state where the deletion is /* but if the IKE SA is not in a state where the deletion is
* negotiated with the other peer, we can destroy the IKE SA on our own. * negotiated with the other peer, we can destroy the IKE SA on our own.
@@ -774,8 +676,7 @@ static status_t delete_(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id)
} }
else else
{ {
this->logger->log(this->logger,ERROR|LEVEL1, DBG2(SIG_DBG_MGR, "tried to delete nonexisting IKE_SA");
"tried to delete nonexisting IKE_SA");
retval = NOT_FOUND; retval = NOT_FOUND;
} }
@@ -790,7 +691,7 @@ static status_t delete_by_name(private_ike_sa_manager_t *this, char *name)
{ {
iterator_t *iterator; iterator_t *iterator;
iterator_t *child_iter; iterator_t *child_iter;
ike_sa_entry_t *entry; entry_t *entry;
size_t name_len = strlen(name); size_t name_len = strlen(name);
pthread_mutex_lock(&(this->mutex)); pthread_mutex_lock(&(this->mutex));
@@ -910,14 +811,12 @@ static void destroy(private_ike_sa_manager_t *this)
/* destroy all list entries */ /* destroy all list entries */
linked_list_t *list = this->ike_sa_list; linked_list_t *list = this->ike_sa_list;
iterator_t *iterator; iterator_t *iterator;
ike_sa_entry_t *entry; entry_t *entry;
pthread_mutex_lock(&(this->mutex)); pthread_mutex_lock(&(this->mutex));
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_MGR, "going to destroy IKE_SA manager and all managed IKE_SA's");
"going to destroy IKE_SA manager and all managed IKE_SA's");
/* Step 1: drive out all waiting threads */ /* Step 1: drive out all waiting threads */
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "set driveout flags for all stored IKE_SA's");
"set driveout flags for all stored IKE_SA's");
iterator = list->create_iterator(list, TRUE); iterator = list->create_iterator(list, TRUE);
while (iterator->has_next(iterator)) while (iterator->has_next(iterator))
{ {
@@ -926,8 +825,7 @@ static void destroy(private_ike_sa_manager_t *this)
entry->driveout_new_threads = TRUE; entry->driveout_new_threads = TRUE;
entry->driveout_waiting_threads = TRUE; entry->driveout_waiting_threads = TRUE;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, DBG2(SIG_DBG_MGR, "wait for all threads to leave IKE_SA's");
"wait for all threads to leave IKE_SA's");
/* Step 2: wait until all are gone */ /* Step 2: wait until all are gone */
iterator->reset(iterator); iterator->reset(iterator);
while (iterator->has_next(iterator)) while (iterator->has_next(iterator))
@@ -941,7 +839,7 @@ static void destroy(private_ike_sa_manager_t *this)
pthread_cond_wait(&(entry->condvar), &(this->mutex)); pthread_cond_wait(&(entry->condvar), &(this->mutex));
} }
} }
this->logger->log(this->logger, CONTROL|LEVEL2, "delete all IKE_SA's"); DBG2(SIG_DBG_MGR, "delete all IKE_SA's");
/* Step 3: initiate deletion of all IKE_SAs */ /* Step 3: initiate deletion of all IKE_SAs */
iterator->reset(iterator); iterator->reset(iterator);
while (iterator->has_next(iterator)) while (iterator->has_next(iterator))
@@ -951,11 +849,11 @@ static void destroy(private_ike_sa_manager_t *this)
} }
iterator->destroy(iterator); iterator->destroy(iterator);
this->logger->log(this->logger, CONTROL|LEVEL2, "destroy all entries"); DBG2(SIG_DBG_MGR, "destroy all entries");
/* Step 4: destroy all entries */ /* Step 4: destroy all entries */
while (list->remove_last(list, (void**)&entry) == SUCCESS) while (list->remove_last(list, (void**)&entry) == SUCCESS)
{ {
entry->destroy(entry); entry_destroy(entry);
} }
list->destroy(list); list->destroy(list);
pthread_mutex_unlock(&(this->mutex)); pthread_mutex_unlock(&(this->mutex));
@@ -977,21 +875,16 @@ ike_sa_manager_t *ike_sa_manager_create()
this->public.checkout_by_id = (ike_sa_t*(*)(ike_sa_manager_t*,host_t*,host_t*,identification_t*,identification_t*))checkout_by_id; this->public.checkout_by_id = (ike_sa_t*(*)(ike_sa_manager_t*,host_t*,host_t*,identification_t*,identification_t*))checkout_by_id;
this->public.checkout = (ike_sa_t*(*)(ike_sa_manager_t*, ike_sa_id_t*))checkout; this->public.checkout = (ike_sa_t*(*)(ike_sa_manager_t*, ike_sa_id_t*))checkout;
this->public.checkout_by_child = (ike_sa_t*(*)(ike_sa_manager_t*,u_int32_t))checkout_by_child; this->public.checkout_by_child = (ike_sa_t*(*)(ike_sa_manager_t*,u_int32_t))checkout_by_child;
this->public.get_ike_sa_list = (linked_list_t*(*)(ike_sa_manager_t*))get_ike_sa_list; this->public.create_iterator = (iterator_t*(*)(ike_sa_manager_t*))create_iterator;
this->public.log_status = (void(*)(ike_sa_manager_t*,logger_t*,char*))log_status;
this->public.checkin = (status_t(*)(ike_sa_manager_t*,ike_sa_t*))checkin; this->public.checkin = (status_t(*)(ike_sa_manager_t*,ike_sa_t*))checkin;
this->public.delete = (status_t(*)(ike_sa_manager_t*,ike_sa_id_t*))delete_; this->public.delete = (status_t(*)(ike_sa_manager_t*,ike_sa_id_t*))delete_;
this->public.delete_by_name = (status_t(*)(ike_sa_manager_t*,char*))delete_by_name; this->public.delete_by_name = (status_t(*)(ike_sa_manager_t*,char*))delete_by_name;
this->public.checkin_and_destroy = (status_t(*)(ike_sa_manager_t*,ike_sa_t*))checkin_and_destroy; this->public.checkin_and_destroy = (status_t(*)(ike_sa_manager_t*,ike_sa_t*))checkin_and_destroy;
/* initialize private variables */
this->logger = logger_manager->get_logger(logger_manager, IKE_SA_MANAGER);
/* initialize private variables */
this->ike_sa_list = linked_list_create(); this->ike_sa_list = linked_list_create();
pthread_mutex_init(&(this->mutex), NULL); pthread_mutex_init(&(this->mutex), NULL);
this->randomizer = randomizer_create(); this->randomizer = randomizer_create();
return (ike_sa_manager_t*)this; return (ike_sa_manager_t*)this;
} }
+11 -26
View File
@@ -26,8 +26,6 @@
#include <types.h> #include <types.h>
#include <sa/ike_sa.h> #include <sa/ike_sa.h>
#include <utils/logger.h>
typedef struct ike_sa_manager_t ike_sa_manager_t; typedef struct ike_sa_manager_t ike_sa_manager_t;
@@ -84,9 +82,9 @@ struct ike_sa_manager_t {
* @return checked out/created IKE_SA * @return checked out/created IKE_SA
*/ */
ike_sa_t* (*checkout_by_id) (ike_sa_manager_t* this, ike_sa_t* (*checkout_by_id) (ike_sa_manager_t* this,
host_t *my_host, host_t* other_host, host_t *my_host, host_t* other_host,
identification_t *my_id, identification_t *my_id,
identification_t *other_id); identification_t *other_id);
/** /**
* @brief Check out an IKE_SA by protocol and SPI of one of its CHILD_SA. * @brief Check out an IKE_SA by protocol and SPI of one of its CHILD_SA.
@@ -104,30 +102,17 @@ struct ike_sa_manager_t {
ike_sa_t* (*checkout_by_child) (ike_sa_manager_t* this, u_int32_t reqid); ike_sa_t* (*checkout_by_child) (ike_sa_manager_t* this, u_int32_t reqid);
/** /**
* @brief Get a list of all IKE_SA SAs currently set up. * @brief Create an iterator over all stored IKE_SAs.
* *
* The resulting list with all IDs must be destroyed by * The avoid synchronization issues, the iterator locks access
* the caller. There is no guarantee an ike_sa with the * to the manager exclusively, until it gets destroyed.
* corrensponding ID really exists, since it may be deleted * Only use the iterate() functions of this iterator!!! Anything other
* in the meantime by another thread. * is not implemented and causes crashes.
*
* @param this the manager object
* @return a list with ike_sa_id_t s
*/
linked_list_t *(*get_ike_sa_list) (ike_sa_manager_t* this);
/**
* @brief Log the status of the IKE_SA's in the manager.
* *
* A informational log is done to the supplied logger. If logger is
* NULL, an internal logger is used. If a name is supplied,
* only connections with the matching name will be logged.
*
* @param this the manager object * @param this the manager object
* @param logger logger to do the log, or NULL * @return iterator over all IKE_SAs.
* @param name name of a connection, or NULL
*/ */
void (*log_status) (ike_sa_manager_t* this, logger_t* logger, char* name); iterator_t *(*create_iterator) (ike_sa_manager_t* this);
/** /**
* @brief Checkin the SA after usage. * @brief Checkin the SA after usage.
+34 -64
View File
@@ -128,11 +128,6 @@ struct private_create_child_sa_t {
* source of randomness * source of randomness
*/ */
randomizer_t *randomizer; randomizer_t *randomizer;
/**
* Assigned logger.
*/
logger_t *logger;
}; };
/** /**
@@ -236,12 +231,12 @@ static status_t get_request(private_create_child_sa_t *this, message_t **result)
switch (this->rekeyed_sa->get_state(this->rekeyed_sa)) switch (this->rekeyed_sa->get_state(this->rekeyed_sa))
{ {
case CHILD_REKEYING: case CHILD_REKEYING:
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE,
"rekeying a CHILD_SA which is already rekeying, aborted"); "rekeying a CHILD_SA which is already rekeying, aborted");
return FAILED; return FAILED;
case CHILD_DELETING: case CHILD_DELETING:
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE,
"rekeying a CHILD_SA which is deleting, aborted"); "rekeying a CHILD_SA which is deleting, aborted");
return FAILED; return FAILED;
default: default:
break; break;
@@ -289,9 +284,8 @@ static status_t get_request(private_create_child_sa_t *this, message_t **result)
if (this->policy == NULL) if (this->policy == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "no policy found to rekey "
"no policy found to rekey CHILD_SA with reqid %d", "CHILD_SA with reqid %d", this->reqid);
this->reqid);
return FAILED; return FAILED;
} }
} }
@@ -307,8 +301,7 @@ static status_t get_request(private_create_child_sa_t *this, message_t **result)
this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy)); this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy));
if (this->child_sa->alloc(this->child_sa, proposals) != SUCCESS) if (this->child_sa->alloc(this->child_sa, proposals) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "could not install CHILD_SA, CHILD_SA creation aborted");
"could not install CHILD_SA, CHILD_SA creation aborted");
return FAILED; return FAILED;
} }
sa_payload = sa_payload_create_from_proposal_list(proposals); sa_payload = sa_payload_create_from_proposal_list(proposals);
@@ -376,27 +369,23 @@ static status_t process_notifys(private_create_child_sa_t *this, notify_payload_
{ {
notify_type_t notify_type = notify_payload->get_notify_type(notify_payload); notify_type_t notify_type = notify_payload->get_notify_type(notify_payload);
this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s", DBG2(SIG_DBG_IKE, "process notify type %N", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type));
switch (notify_type) switch (notify_type)
{ {
case SINGLE_PAIR_REQUIRED: case SINGLE_PAIR_REQUIRED:
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "received a SINGLE_PAIR_REQUIRED notify");
"received a SINGLE_PAIR_REQUIRED notify");
return FAILED; return FAILED;
} }
case TS_UNACCEPTABLE: case TS_UNACCEPTABLE:
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "received TS_UNACCEPTABLE notify");
"received TS_UNACCEPTABLE notify");
return FAILED; return FAILED;
} }
case NO_PROPOSAL_CHOSEN: case NO_PROPOSAL_CHOSEN:
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "received NO_PROPOSAL_CHOSEN notify");
"received NO_PROPOSAL_CHOSEN notify");
return FAILED; return FAILED;
} }
case REKEY_SA: case REKEY_SA:
@@ -423,18 +412,14 @@ static status_t process_notifys(private_create_child_sa_t *this, notify_payload_
{ {
if (notify_type < 16383) if (notify_type < 16383)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "received %N notify error, CHILD_SA "
"received %s notify error (%d), CHILD_SA creation failed", "creation failed", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type),
notify_type);
return FAILED; return FAILED;
} }
else else
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "received %N notify, ignored",
"received %s notify (%d), ignored", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type),
notify_type);
return SUCCESS; return SUCCESS;
} }
} }
@@ -558,8 +543,7 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
/* check message type */ /* check message type */
if (request->get_exchange_type(request) != CREATE_CHILD_SA) if (request->get_exchange_type(request) != CREATE_CHILD_SA)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "CREATE_CHILD_SA response of invalid type, aborted");
"CREATE_CHILD_SA response of invalid type, aborted");
return FAILED; return FAILED;
} }
@@ -569,8 +553,7 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
this->ike_sa->get_state(this->ike_sa) == IKE_DELETING) this->ike_sa->get_state(this->ike_sa) == IKE_DELETING)
{ {
build_notify(NO_ADDITIONAL_SAS, CHUNK_INITIALIZER, response, TRUE); build_notify(NO_ADDITIONAL_SAS, CHUNK_INITIALIZER, response, TRUE);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "unable to create new CHILD_SAs, as rekeying in progress");
"unable to create new CHILD_SAs, as rekeying in progress");
return FAILED; return FAILED;
} }
@@ -599,8 +582,7 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
u_int8_t dh_buffer[] = {0x00, 0x00}; /* MODP_NONE */ u_int8_t dh_buffer[] = {0x00, 0x00}; /* MODP_NONE */
chunk_t group = chunk_from_buf(dh_buffer); chunk_t group = chunk_from_buf(dh_buffer);
build_notify(INVALID_KE_PAYLOAD, group, response, TRUE); build_notify(INVALID_KE_PAYLOAD, group, response, TRUE);
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "CREATE_CHILD_SA used PFS, sending INVALID_KE_PAYLOAD");
"CREATE_CHILD_SA used PFS, sending INVALID_KE_PAYLOAD");
return FAILED; return FAILED;
} }
case NOTIFY: case NOTIFY:
@@ -615,9 +597,8 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
} }
default: default:
{ {
this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)", DBG1(SIG_DBG_IKE, "ignoring %N payload",
mapping_find(payload_type_m, payload->get_type(payload)), payload_type_names, payload->get_type(payload));
payload->get_type(payload));
break; break;
} }
} }
@@ -628,8 +609,7 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
if (!(sa_request && nonce_request && tsi_request && tsr_request)) if (!(sa_request && nonce_request && tsi_request && tsr_request))
{ {
build_notify(INVALID_SYNTAX, CHUNK_INITIALIZER, response, TRUE); build_notify(INVALID_SYNTAX, CHUNK_INITIALIZER, response, TRUE);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "request message incomplete, no CHILD_SA created");
"request message incomplete, no CHILD_SA created");
return FAILED; return FAILED;
} }
@@ -669,8 +649,7 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
if (this->policy == NULL) if (this->policy == NULL)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "no acceptable policy found, adding TS_UNACCEPTABLE notify");
"no acceptable policy found, adding TS_UNACCEPTABLE notify");
build_notify(TS_UNACCEPTABLE, CHUNK_INITIALIZER, response, TRUE); build_notify(TS_UNACCEPTABLE, CHUNK_INITIALIZER, response, TRUE);
return FAILED; return FAILED;
} }
@@ -686,23 +665,21 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
sa_response = sa_payload_create(); sa_response = sa_payload_create();
/* get proposals from request, and select one with ours */ /* get proposals from request, and select one with ours */
proposal_list = sa_request->get_proposals(sa_request); proposal_list = sa_request->get_proposals(sa_request);
this->logger->log(this->logger, CONTROL|LEVEL1, "selecting proposals:"); DBG2(SIG_DBG_IKE, "selecting proposals:");
this->proposal = this->policy->select_proposal(this->policy, proposal_list); this->proposal = this->policy->select_proposal(this->policy, proposal_list);
destroy_proposal_list(proposal_list); destroy_proposal_list(proposal_list);
/* do we have a proposal? */ /* do we have a proposal? */
if (this->proposal == NULL) if (this->proposal == NULL)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
"CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE); build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
return FAILED; return FAILED;
} }
/* do we have traffic selectors? */ /* do we have traffic selectors? */
else if (this->tsi->get_count(this->tsi) == 0 || this->tsr->get_count(this->tsr) == 0) else if (this->tsi->get_count(this->tsi) == 0 || this->tsr->get_count(this->tsr) == 0)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
"CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
build_notify(TS_UNACCEPTABLE, CHUNK_INITIALIZER, response, TRUE); build_notify(TS_UNACCEPTABLE, CHUNK_INITIALIZER, response, TRUE);
return FAILED; return FAILED;
} }
@@ -723,8 +700,7 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy)); this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy));
if (install_child_sa(this, FALSE) != SUCCESS) if (install_child_sa(this, FALSE) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
"installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE); build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
return FAILED; return FAILED;
} }
@@ -786,8 +762,7 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
/* check message type */ /* check message type */
if (response->get_exchange_type(response) != CREATE_CHILD_SA) if (response->get_exchange_type(response) != CREATE_CHILD_SA)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "CREATE_CHILD_SA response of invalid type, aborting");
"CREATE_CHILD_SA response of invalid type, aborting");
return FAILED; return FAILED;
} }
@@ -826,9 +801,8 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
} }
default: default:
{ {
this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)", DBG1(SIG_DBG_IKE, "ignoring %N payload",
mapping_find(payload_type_m, payload->get_type(payload)), payload_type_names, payload->get_type(payload));
payload->get_type(payload));
break; break;
} }
} }
@@ -837,7 +811,7 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
if (!(sa_payload && nonce_payload && tsi_payload && tsr_payload)) if (!(sa_payload && nonce_payload && tsi_payload && tsr_payload))
{ {
this->logger->log(this->logger, AUDIT, "response message incomplete, no CHILD_SA built"); DBG1(SIG_DBG_IKE, "response message incomplete, no CHILD_SA built");
return FAILED; return FAILED;
} }
@@ -870,14 +844,13 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
this->tsi->get_count(this->tsi) == 0 || this->tsi->get_count(this->tsi) == 0 ||
this->tsr->get_count(this->tsr) == 0) this->tsr->get_count(this->tsr) == 0)
{ {
this->logger->log(this->logger, AUDIT, "CHILD_SA creation failed"); DBG1(SIG_DBG_IKE, "CHILD_SA creation failed");
return FAILED; return FAILED;
} }
new_child = this->child_sa; new_child = this->child_sa;
if (install_child_sa(this, TRUE) != SUCCESS) if (install_child_sa(this, TRUE) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "installing CHILD_SA failed, no CHILD_SA built");
"installing CHILD_SA failed, no CHILD_SA built");
return FAILED; return FAILED;
} }
} }
@@ -909,14 +882,12 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
if (memcmp(this_lowest.ptr, this->nonce_s.ptr, if (memcmp(this_lowest.ptr, this->nonce_s.ptr,
min(this_lowest.len, this->nonce_s.len)) < 0) min(this_lowest.len, this->nonce_s.len)) < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "detected simultaneous CHILD_SA rekeying, deleting ours");
"detected simultaneous CHILD_SA rekeying, deleting ours");
this->lost = TRUE; this->lost = TRUE;
} }
else else
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "detected simultaneous CHILD_SA rekeying, but ours is preferred");
"detected simultaneous CHILD_SA rekeying, but ours is preferred");
} }
} }
/* delete the old SA if we have won the rekeying nonce compare*/ /* delete the old SA if we have won the rekeying nonce compare*/
@@ -994,7 +965,6 @@ create_child_sa_t *create_child_sa_create(ike_sa_t *ike_sa)
this->tsi = NULL; this->tsi = NULL;
this->tsr = NULL; this->tsr = NULL;
this->randomizer = randomizer_create(); this->randomizer = randomizer_create();
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public; return &this->public;
} }
@@ -56,11 +56,6 @@ struct private_dead_peer_detection_t {
* Times we did send the request * Times we did send the request
*/ */
u_int32_t requested; u_int32_t requested;
/**
* Assigned logger.
*/
logger_t *logger;
}; };
/** /**
@@ -187,7 +182,6 @@ dead_peer_detection_t *dead_peer_detection_create(ike_sa_t *ike_sa)
this->message_id = 0; this->message_id = 0;
this->message = NULL; this->message = NULL;
this->requested = 0; this->requested = 0;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public; return &this->public;
} }
+14 -29
View File
@@ -63,11 +63,6 @@ struct private_delete_child_sa_t {
* CHILD SA to delete * CHILD SA to delete
*/ */
child_sa_t *child_sa; child_sa_t *child_sa;
/**
* Assigned logger.
*/
logger_t *logger;
}; };
/** /**
@@ -133,9 +128,8 @@ static status_t get_request(private_delete_child_sa_t *this, message_t **result)
spi = this->child_sa->get_spi(this->child_sa, TRUE); spi = this->child_sa->get_spi(this->child_sa, TRUE);
delete_payload = delete_payload_create(protocol); delete_payload = delete_payload_create(protocol);
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "created DELETE payload for %N CHILD_SA with SPI 0x%x",
"created DELETE payload for %s CHILD_SA with SPI 0x%x", protocol_id_names, protocol, htonl(spi));
mapping_find(protocol_id_m, protocol), htonl(spi));
delete_payload->add_spi(delete_payload, spi); delete_payload->add_spi(delete_payload, spi);
request->add_payload(request, (payload_t*)delete_payload); request->add_payload(request, (payload_t*)delete_payload);
} }
@@ -159,8 +153,7 @@ static status_t process_delete(private_delete_child_sa_t *this, delete_payload_t
protocol = delete_request->get_protocol_id(delete_request); protocol = delete_request->get_protocol_id(delete_request);
if (protocol != PROTO_ESP && protocol != PROTO_AH) if (protocol != PROTO_ESP && protocol != PROTO_AH)
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "CHILD_SA delete response contained unexpected protocol");
"CHILD_SA delete response contained unexpected protocol");
return FAILED; return FAILED;
} }
@@ -184,9 +177,8 @@ static status_t process_delete(private_delete_child_sa_t *this, delete_payload_t
child_sa->set_state(child_sa, CHILD_DELETING); child_sa->set_state(child_sa, CHILD_DELETING);
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "received DELETE for %N CHILD_SA with SPI 0x%x, deleting",
"received DELETE for %s CHILD_SA with SPI 0x%x, deleting", protocol_id_names, protocol, ntohl(spi));
mapping_find(protocol_id_m, protocol), ntohl(spi));
rekey = child_sa->get_rekeying_transaction(child_sa); rekey = child_sa->get_rekeying_transaction(child_sa);
if (rekey) if (rekey)
@@ -208,9 +200,8 @@ static status_t process_delete(private_delete_child_sa_t *this, delete_payload_t
} }
else else
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "received DELETE for %N CHILD_SA with SPI 0x%x, but no such SA",
"received DELETE for %s CHILD_SA with SPI 0x%x, but no such SA", protocol_id_names, protocol, ntohl(spi));
mapping_find(protocol_id_m, protocol), ntohl(spi));
} }
} }
iterator->destroy(iterator); iterator->destroy(iterator);
@@ -251,8 +242,7 @@ static status_t get_response(private_delete_child_sa_t *this, message_t *request
if (request->get_exchange_type(request) != INFORMATIONAL) if (request->get_exchange_type(request) != INFORMATIONAL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "INFORMATIONAL response of invalid type, aborting");
"INFORMATIONAL response of invalid type, aborting");
return FAILED; return FAILED;
} }
@@ -262,8 +252,7 @@ static status_t get_response(private_delete_child_sa_t *this, message_t *request
if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING || if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING ||
this->ike_sa->get_state(this->ike_sa) == IKE_DELETING) this->ike_sa->get_state(this->ike_sa) == IKE_DELETING)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "unable to delete CHILD_SA, as rekeying in progress");
"unable to delete CHILD_SA, as rekeying in progress");
return FAILED; return FAILED;
} }
@@ -283,9 +272,8 @@ static status_t get_response(private_delete_child_sa_t *this, message_t *request
} }
default: default:
{ {
this->logger->log(this->logger, ERROR|LEVEL1, "ignoring payload %s (%d)", DBG2(SIG_DBG_IKE, "ignoring payload %N",
mapping_find(payload_type_m, payload->get_type(payload)), payload_type_names, payload->get_type(payload));
payload->get_type(payload));
break; break;
} }
} }
@@ -305,8 +293,7 @@ static status_t conclude(private_delete_child_sa_t *this, message_t *response,
/* check message type */ /* check message type */
if (response->get_exchange_type(response) != INFORMATIONAL) if (response->get_exchange_type(response) != INFORMATIONAL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "INFORMATIONAL response of invalid type, aborting");
"INFORMATIONAL response of invalid type, aborting");
return FAILED; return FAILED;
} }
@@ -326,9 +313,8 @@ static status_t conclude(private_delete_child_sa_t *this, message_t *response,
} }
default: default:
{ {
this->logger->log(this->logger, ERROR|LEVEL1, "ignoring payload %s (%d)", DBG1(SIG_DBG_IKE, "ignoring payload %N",
mapping_find(payload_type_m, payload->get_type(payload)), payload_type_names, payload->get_type(payload));
payload->get_type(payload));
break; break;
} }
} }
@@ -369,7 +355,6 @@ delete_child_sa_t *delete_child_sa_create(ike_sa_t *ike_sa)
this->message_id = 0; this->message_id = 0;
this->message = NULL; this->message = NULL;
this->requested = 0; this->requested = 0;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public; return &this->public;
} }
+6 -18
View File
@@ -25,7 +25,6 @@
#include <daemon.h> #include <daemon.h>
#include <encoding/payloads/delete_payload.h> #include <encoding/payloads/delete_payload.h>
typedef struct private_delete_ike_sa_t private_delete_ike_sa_t; typedef struct private_delete_ike_sa_t private_delete_ike_sa_t;
/** /**
@@ -57,11 +56,6 @@ struct private_delete_ike_sa_t {
* Times we did send the request * Times we did send the request
*/ */
u_int32_t requested; u_int32_t requested;
/**
* Assigned logger.
*/
logger_t *logger;
}; };
/** /**
@@ -160,8 +154,7 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
/* check message type */ /* check message type */
if (request->get_exchange_type(request) != INFORMATIONAL) if (request->get_exchange_type(request) != INFORMATIONAL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "INFORMATIONAL response of invalid type, deleting IKE_SA");
"INFORMATIONAL response of invalid type, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -181,9 +174,8 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
} }
default: default:
{ {
this->logger->log(this->logger, ERROR|LEVEL1, "ignoring payload %s (%d)", DBG1(SIG_DBG_IKE, "ignoring payload %N",
mapping_find(payload_type_m, payload->get_type(payload)), payload_type_names, payload->get_type(payload));
payload->get_type(payload));
break; break;
} }
} }
@@ -193,14 +185,12 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
if (delete_request && if (delete_request &&
delete_request->get_protocol_id(delete_request) == PROTO_IKE) delete_request->get_protocol_id(delete_request) == PROTO_IKE)
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "DELETE request for IKE_SA received, deleting IKE_SA");
"DELETE request for IKE_SA received, deleting IKE_SA");
} }
else else
{ {
/* should not happen, as we preparsed this at transaction construction */ /* should not happen, as we preparsed this at transaction construction */
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "received a weird DELETE request for IKE_SA, deleting anyway");
"received a weird DELETE request for IKE_SA, deleting anyway");
} }
if (this->ike_sa->get_state(this->ike_sa) == IKE_DELETING) if (this->ike_sa->get_state(this->ike_sa) == IKE_DELETING)
{ {
@@ -222,8 +212,7 @@ static status_t conclude(private_delete_ike_sa_t *this, message_t *response,
/* check message type */ /* check message type */
if (response->get_exchange_type(response) != INFORMATIONAL) if (response->get_exchange_type(response) != INFORMATIONAL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "INFORMATIONAL response of invalid type, deleting IKE_SA");
"INFORMATIONAL response of invalid type, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
/* this is only an acknowledge. We can't do anything here, but delete /* this is only an acknowledge. We can't do anything here, but delete
@@ -260,7 +249,6 @@ delete_ike_sa_t *delete_ike_sa_create(ike_sa_t *ike_sa)
this->message_id = 0; this->message_id = 0;
this->message = NULL; this->message = NULL;
this->requested = 0; this->requested = 0;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public; return &this->public;
} }
+41 -77
View File
@@ -128,11 +128,6 @@ struct private_ike_auth_t {
* reqid to use for CHILD_SA setup * reqid to use for CHILD_SA setup
*/ */
u_int32_t reqid; u_int32_t reqid;
/**
* Assigned logger.
*/
logger_t *logger;
}; };
/** /**
@@ -276,8 +271,7 @@ static status_t get_request(private_ike_auth_t *this, message_t **result)
} }
else else
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "could not find my certificate, certificate payload omitted");
"could not find my certificate, certificate payload omitted");
} }
} }
@@ -308,8 +302,7 @@ static status_t get_request(private_ike_auth_t *this, message_t **result)
authenticator->destroy(authenticator); authenticator->destroy(authenticator);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "could not generate AUTH data, deleting IKE_SA");
"could not generate AUTH data, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
request->add_payload(request, (payload_t*)auth_payload); request->add_payload(request, (payload_t*)auth_payload);
@@ -333,8 +326,7 @@ static status_t get_request(private_ike_auth_t *this, message_t **result)
this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy)); this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy));
if (this->child_sa->alloc(this->child_sa, proposal_list) != SUCCESS) if (this->child_sa->alloc(this->child_sa, proposal_list) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "could not install CHILD_SA, deleting IKE_SA");
"could not install CHILD_SA, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
sa_payload = sa_payload_create_from_proposal_list(proposal_list); sa_payload = sa_payload_create_from_proposal_list(proposal_list);
@@ -376,30 +368,26 @@ static status_t process_notifies(private_ike_auth_t *this, notify_payload_t *not
{ {
notify_type_t notify_type = notify_payload->get_notify_type(notify_payload); notify_type_t notify_type = notify_payload->get_notify_type(notify_payload);
this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s", DBG2(SIG_DBG_IKE, "process notify type %N", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type));
switch (notify_type) switch (notify_type)
{ {
/* these notifies are not critical. no child_sa is built, but IKE stays alive */ /* these notifies are not critical. no child_sa is built, but IKE stays alive */
case SINGLE_PAIR_REQUIRED: case SINGLE_PAIR_REQUIRED:
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "received a SINGLE_PAIR_REQUIRED notify");
"received a SINGLE_PAIR_REQUIRED notify");
this->build_child = FALSE; this->build_child = FALSE;
return SUCCESS; return SUCCESS;
} }
case TS_UNACCEPTABLE: case TS_UNACCEPTABLE:
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "received TS_UNACCEPTABLE notify");
"received TS_UNACCEPTABLE notify");
this->build_child = FALSE; this->build_child = FALSE;
return SUCCESS; return SUCCESS;
} }
case NO_PROPOSAL_CHOSEN: case NO_PROPOSAL_CHOSEN:
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "received NO_PROPOSAL_CHOSEN notify");
"received NO_PROPOSAL_CHOSEN notify");
this->build_child = FALSE; this->build_child = FALSE;
return SUCCESS; return SUCCESS;
} }
@@ -407,18 +395,14 @@ static status_t process_notifies(private_ike_auth_t *this, notify_payload_t *not
{ {
if (notify_type < 16383) if (notify_type < 16383)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "received %N notify error, deleting IKE_SA",
"received %s notify error (%d), deleting IKE_SA", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type),
notify_type);
return DESTROY_ME; return DESTROY_ME;
} }
else else
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "received %N notify, ignored",
"received %s notify (%d), ignored", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type),
notify_type);
return SUCCESS; return SUCCESS;
} }
} }
@@ -461,9 +445,8 @@ static void import_certificate(private_ike_auth_t *this, cert_payload_t *cert_pa
encoding = cert_payload->get_cert_encoding(cert_payload); encoding = cert_payload->get_cert_encoding(cert_payload);
if (encoding != CERT_X509_SIGNATURE) if (encoding != CERT_X509_SIGNATURE)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "certificate payload %N not supported, ignored",
"certificate payload %s not supported, ignored", cert_encoding_names, encoding);
enum_name(&cert_encoding_names, encoding));
return; return;
} }
cert = x509_create_from_chunk(cert_payload->get_data_clone(cert_payload)); cert = x509_create_from_chunk(cert_payload->get_data_clone(cert_payload));
@@ -471,8 +454,7 @@ static void import_certificate(private_ike_auth_t *this, cert_payload_t *cert_pa
{ {
if (charon->credentials->verify(charon->credentials, cert, &found)) if (charon->credentials->verify(charon->credentials, cert, &found))
{ {
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_IKE, "received end entity certificate is trusted, added to store");
"received end entity certificate is trusted, added to store");
if (!found) if (!found)
{ {
charon->credentials->add_end_certificate(charon->credentials, cert); charon->credentials->add_end_certificate(charon->credentials, cert);
@@ -484,15 +466,13 @@ static void import_certificate(private_ike_auth_t *this, cert_payload_t *cert_pa
} }
else else
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "received end entity certificate is not trusted, discarded");
"received end entity certificate is not trusted, discarded");
cert->destroy(cert); cert->destroy(cert);
} }
} }
else else
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "parsing of received certificate failed, discarded");
"parsing of received certificate failed, discarded");
} }
} }
@@ -589,8 +569,7 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
/* check message type */ /* check message type */
if (request->get_exchange_type(request) != IKE_AUTH) if (request->get_exchange_type(request) != IKE_AUTH)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "IKE_AUTH response of invalid type, deleting IKE_SA");
"IKE_AUTH response of invalid type, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -641,9 +620,8 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
} }
default: default:
{ {
this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)", DBG1(SIG_DBG_IKE, "ignoring %N payload",
mapping_find(payload_type_m, payload->get_type(payload)), payload_type_names, payload->get_type(payload));
payload->get_type(payload));
break; break;
} }
} }
@@ -654,8 +632,7 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
if (!(idi_request && auth_request && sa_request && tsi_request && tsr_request)) if (!(idi_request && auth_request && sa_request && tsi_request && tsr_request))
{ {
build_notify(INVALID_SYNTAX, response, TRUE); build_notify(INVALID_SYNTAX, response, TRUE);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "request message incomplete, deleting IKE_SA");
"request message incomplete, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -693,9 +670,8 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
* traffic selectors. Then we would create a IKE_SA without a CHILD_SA. */ * traffic selectors. Then we would create a IKE_SA without a CHILD_SA. */
if (this->policy == NULL) if (this->policy == NULL)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "no acceptable policy for IDs %D - %D found, deleting IKE_SA",
"no acceptable policy for IDs %D - %D found, deleting IKE_SA", my_id, other_id);
my_id, other_id);
my_id->destroy(my_id); my_id->destroy(my_id);
other_id->destroy(other_id); other_id->destroy(other_id);
build_notify(AUTHENTICATION_FAILED, response, TRUE); build_notify(AUTHENTICATION_FAILED, response, TRUE);
@@ -726,8 +702,7 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
} }
else else
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "could not find my certificate, cert payload omitted");
"could not find my certificate, cert payload omitted");
} }
} }
@@ -752,8 +727,7 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
TRUE); TRUE);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "authentication failed, deleting IKE_SA");
"authentication failed, deleting IKE_SA");
build_notify(AUTHENTICATION_FAILED, response, TRUE); build_notify(AUTHENTICATION_FAILED, response, TRUE);
authenticator->destroy(authenticator); authenticator->destroy(authenticator);
return DESTROY_ME; return DESTROY_ME;
@@ -767,8 +741,7 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
authenticator->destroy(authenticator); authenticator->destroy(authenticator);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "authentication data generation failed, deleting IKE_SA");
"authentication data generation failed, deleting IKE_SA");
build_notify(AUTHENTICATION_FAILED, response, TRUE); build_notify(AUTHENTICATION_FAILED, response, TRUE);
return DESTROY_ME; return DESTROY_ME;
} }
@@ -787,22 +760,20 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
/* get proposals from request, and select one with ours */ /* get proposals from request, and select one with ours */
proposal_list = sa_request->get_proposals(sa_request); proposal_list = sa_request->get_proposals(sa_request);
this->logger->log(this->logger, CONTROL|LEVEL1, "selecting proposals:"); DBG2(SIG_DBG_IKE, "selecting proposals:");
this->proposal = this->policy->select_proposal(this->policy, proposal_list); this->proposal = this->policy->select_proposal(this->policy, proposal_list);
destroy_proposal_list(proposal_list); destroy_proposal_list(proposal_list);
/* do we have a proposal? */ /* do we have a proposal? */
if (this->proposal == NULL) if (this->proposal == NULL)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
"CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
build_notify(NO_PROPOSAL_CHOSEN, response, FALSE); build_notify(NO_PROPOSAL_CHOSEN, response, FALSE);
} }
/* do we have traffic selectors? */ /* do we have traffic selectors? */
else if (this->tsi->get_count(this->tsi) == 0 || this->tsr->get_count(this->tsr) == 0) else if (this->tsi->get_count(this->tsi) == 0 || this->tsr->get_count(this->tsr) == 0)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
"CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
build_notify(TS_UNACCEPTABLE, response, FALSE); build_notify(TS_UNACCEPTABLE, response, FALSE);
} }
else else
@@ -819,8 +790,7 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy)); this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy));
if (install_child_sa(this, FALSE) != SUCCESS) if (install_child_sa(this, FALSE) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
"installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
build_notify(NO_PROPOSAL_CHOSEN, response, FALSE); build_notify(NO_PROPOSAL_CHOSEN, response, FALSE);
} }
/* add proposal to sa payload */ /* add proposal to sa payload */
@@ -860,8 +830,7 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
/* check message type */ /* check message type */
if (response->get_exchange_type(response) != IKE_AUTH) if (response->get_exchange_type(response) != IKE_AUTH)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "IKE_AUTH response of invalid type, deleting IKE_SA");
"IKE_AUTH response of invalid type, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -913,9 +882,8 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
} }
default: default:
{ {
this->logger->log(this->logger, CONTROL, "ignoring payload %s (%d)", DBG1(SIG_DBG_IKE, "ignoring payload %N",
mapping_find(payload_type_m, payload->get_type(payload)), payload_type_names, payload->get_type(payload));
payload->get_type(payload));
break; break;
} }
} }
@@ -924,7 +892,7 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
if (!(idr_payload && auth_payload && sa_payload && tsi_payload && tsr_payload)) if (!(idr_payload && auth_payload && sa_payload && tsi_payload && tsr_payload))
{ {
this->logger->log(this->logger, AUDIT, "response message incomplete, deleting IKE_SA"); DBG1(SIG_DBG_IKE, "response message incomplete, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -938,9 +906,8 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
if (!other_id->matches(other_id, configured_other_id, &wildcards)) if (!other_id->matches(other_id, configured_other_id, &wildcards))
{ {
other_id->destroy(other_id); other_id->destroy(other_id);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "other peer uses unacceptable ID (%D, excepted %D), deleting IKE_SA",
"other peer uses unacceptable ID (%D, excepted %D), deleting IKE_SA", other_id, configured_other_id);
other_id, configured_other_id);
return DESTROY_ME; return DESTROY_ME;
} }
/* update other ID. It was already set, but may contain wildcards */ /* update other ID. It was already set, but may contain wildcards */
@@ -972,7 +939,7 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
authenticator->destroy(authenticator); authenticator->destroy(authenticator);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, AUDIT, "authentication failed, deleting IKE_SA"); DBG1(SIG_DBG_IKE, "authentication failed, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
} }
@@ -1003,15 +970,13 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
this->tsr->get_count(this->tsr) == 0 || this->tsr->get_count(this->tsr) == 0 ||
!this->build_child) !this->build_child)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "CHILD_SA creation failed");
"CHILD_SA creation failed");
} }
else else
{ {
if (install_child_sa(this, TRUE) != SUCCESS) if (install_child_sa(this, TRUE) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "installing CHILD_SA failed, no CHILD_SA built");
"installing CHILD_SA failed, no CHILD_SA built");
} }
} }
} }
@@ -1045,7 +1010,7 @@ static void destroy(private_ike_auth_t *this)
ike_auth_t *ike_auth_create(ike_sa_t *ike_sa) ike_auth_t *ike_auth_create(ike_sa_t *ike_sa)
{ {
private_ike_auth_t *this = malloc_thing(private_ike_auth_t); private_ike_auth_t *this = malloc_thing(private_ike_auth_t);
/* transaction interface functions */ /* transaction interface functions */
this->public.transaction.get_request = (status_t(*)(transaction_t*,message_t**))get_request; this->public.transaction.get_request = (status_t(*)(transaction_t*,message_t**))get_request;
this->public.transaction.get_response = (status_t(*)(transaction_t*,message_t*,message_t**,transaction_t**))get_response; this->public.transaction.get_response = (status_t(*)(transaction_t*,message_t*,message_t**,transaction_t**))get_response;
@@ -1075,7 +1040,6 @@ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa)
this->tsr = NULL; this->tsr = NULL;
this->build_child = TRUE; this->build_child = TRUE;
this->reqid = 0; this->reqid = 0;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public; return &this->public;
} }
+44 -77
View File
@@ -154,11 +154,6 @@ struct private_ike_sa_init_t {
* Have we found a matching destination address NAT hash? * Have we found a matching destination address NAT hash?
*/ */
bool natd_dst_matched; bool natd_dst_matched;
/**
* Assigned logger.
*/
logger_t *logger;
}; };
/** /**
@@ -237,8 +232,8 @@ static chunk_t generate_natd_hash(private_ike_sa_init_t *this,
/* natd_hash = SHA1( spi_i | spi_r | address | port ) */ /* natd_hash = SHA1( spi_i | spi_r | address | port ) */
natd_chunk = chunk_cat("cccc", spi_i_chunk, spi_r_chunk, addr_chunk, port_chunk); natd_chunk = chunk_cat("cccc", spi_i_chunk, spi_r_chunk, addr_chunk, port_chunk);
this->nat_hasher->allocate_hash(this->nat_hasher, natd_chunk, &natd_hash); this->nat_hasher->allocate_hash(this->nat_hasher, natd_chunk, &natd_hash);
this->logger->log_chunk(this->logger, RAW, "natd_chunk", natd_chunk); DBG3(SIG_DBG_IKE, "natd_chunk %B", &natd_chunk);
this->logger->log_chunk(this->logger, RAW, "natd_hash", natd_hash); DBG3(SIG_DBG_IKE, "natd_hash %B", &natd_hash);
chunk_free(&natd_chunk); chunk_free(&natd_chunk);
return natd_hash; return natd_hash;
@@ -333,9 +328,8 @@ static status_t get_request(private_ike_sa_init_t *this, message_t **result)
this->diffie_hellman = diffie_hellman_create(dh_group); this->diffie_hellman = diffie_hellman_create(dh_group);
if (this->diffie_hellman == NULL) if (this->diffie_hellman == NULL)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "DH group %N not supported, aborting",
"DH group %s (%d) not supported, aborting", diffie_hellman_group_names, dh_group);
mapping_find(diffie_hellman_group_m, dh_group), dh_group);
return DESTROY_ME; return DESTROY_ME;
} }
} }
@@ -407,21 +401,18 @@ static status_t process_notifys(private_ike_sa_init_t *this, notify_payload_t *n
chunk_t notification_data; chunk_t notification_data;
notify_type_t notify_type = notify_payload->get_notify_type(notify_payload); notify_type_t notify_type = notify_payload->get_notify_type(notify_payload);
this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s", DBG2(SIG_DBG_IKE, "process notify type %N", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type));
switch (notify_type) switch (notify_type)
{ {
case NO_PROPOSAL_CHOSEN: case NO_PROPOSAL_CHOSEN:
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "received a NO_PROPOSAL_CHOSEN notify, deleting IKE_SA");
"received a NO_PROPOSAL_CHOSEN notify, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
case INVALID_MAJOR_VERSION: case INVALID_MAJOR_VERSION:
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "received a INVALID_MAJOR_VERSION notify, deleting IKE_SA");
"received a INVALID_MAJOR_VERSION notify, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
case INVALID_KE_PAYLOAD: case INVALID_KE_PAYLOAD:
@@ -434,14 +425,12 @@ static status_t process_notifys(private_ike_sa_init_t *this, notify_payload_t *n
notify_data = notify_payload->get_notification_data(notify_payload); notify_data = notify_payload->get_notification_data(notify_payload);
dh_group = ntohs(*((u_int16_t*)notify_data.ptr)); dh_group = ntohs(*((u_int16_t*)notify_data.ptr));
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "peer didn't accept DH group %N, it requested %N",
"peer didn't accept DH group %s, it requested %s", diffie_hellman_group_names, old_dh_group,
mapping_find(diffie_hellman_group_m, old_dh_group), diffie_hellman_group_names, dh_group);
mapping_find(diffie_hellman_group_m, dh_group));
if (!this->connection->check_dh_group(this->connection, dh_group)) if (!this->connection->check_dh_group(this->connection, dh_group))
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "requested DH group not acceptable, aborting");
"requested DH group not acceptable, aborting");
return DESTROY_ME; return DESTROY_ME;
} }
retry = ike_sa_init_create(this->ike_sa); retry = ike_sa_init_create(this->ike_sa);
@@ -463,11 +452,11 @@ static status_t process_notifys(private_ike_sa_init_t *this, notify_payload_t *n
if (chunk_equals(notification_data, this->natd_dst_hash)) if (chunk_equals(notification_data, this->natd_dst_hash))
{ {
this->natd_dst_matched = TRUE; this->natd_dst_matched = TRUE;
this->logger->log(this->logger, CONTROL|LEVEL3, "NAT-D dst hash match"); DBG2(SIG_DBG_IKE, "NAT-D dst hash match");
} }
else else
{ {
this->logger->log(this->logger, CONTROL|LEVEL3, "NAT-D dst hash mismatch"); DBG2(SIG_DBG_IKE, "NAT-D dst hash mismatch");
} }
return SUCCESS; return SUCCESS;
} }
@@ -482,11 +471,11 @@ static status_t process_notifys(private_ike_sa_init_t *this, notify_payload_t *n
if (chunk_equals(notification_data, this->natd_src_hash)) if (chunk_equals(notification_data, this->natd_src_hash))
{ {
this->natd_src_matched = TRUE; this->natd_src_matched = TRUE;
this->logger->log(this->logger, CONTROL|LEVEL3, "NAT-D src hash match"); DBG2(SIG_DBG_IKE, "NAT-D src hash match");
} }
else else
{ {
this->logger->log(this->logger, CONTROL|LEVEL3, "NAT-D src hash mismatch"); DBG2(SIG_DBG_IKE, "NAT-D src hash mismatch");
} }
return SUCCESS; return SUCCESS;
} }
@@ -494,18 +483,14 @@ static status_t process_notifys(private_ike_sa_init_t *this, notify_payload_t *n
{ {
if (notify_type < 16383) if (notify_type < 16383)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "received %N notify error, deleting IKE_SA",
"received %s notify error (%d), deleting IKE_SA", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type),
notify_type);
return DESTROY_ME; return DESTROY_ME;
} }
else else
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "received %N notify, ignored",
"received %s notify (%d), ignored", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type),
notify_type);
return SUCCESS; return SUCCESS;
} }
} }
@@ -555,8 +540,7 @@ static status_t get_response(private_ike_sa_init_t *this,
/* check message type */ /* check message type */
if (request->get_exchange_type(request) != IKE_SA_INIT) if (request->get_exchange_type(request) != IKE_SA_INIT)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "IKE_SA_INIT request of invalid type, deleting IKE_SA");
"IKE_SA_INIT request of invalid type, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -569,9 +553,8 @@ static status_t get_response(private_ike_sa_init_t *this,
notify->set_notify_type(notify, NO_PROPOSAL_CHOSEN); notify->set_notify_type(notify, NO_PROPOSAL_CHOSEN);
response->add_payload(response, (payload_t*)notify); response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "no connection for hosts %H...%H found, deleting IKE_SA",
"no connection for hosts %H...%H found, deleting IKE_SA", me, other);
me, other);
return DESTROY_ME; return DESTROY_ME;
} }
@@ -623,10 +606,8 @@ static status_t get_response(private_ike_sa_init_t *this,
} }
default: default:
{ {
this->logger->log(this->logger, ERROR|LEVEL1, DBG2(SIG_DBG_IKE, "ignoring %N payload",
"ignoring %s payload (%d)", payload_type_names, payload->get_type(payload));
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
break; break;
} }
} }
@@ -639,8 +620,7 @@ static status_t get_response(private_ike_sa_init_t *this,
notify_payload_t *notify = notify_payload_create(); notify_payload_t *notify = notify_payload_create();
notify->set_notify_type(notify, INVALID_SYNTAX); notify->set_notify_type(notify, INVALID_SYNTAX);
response->add_payload(response, (payload_t*)notify); response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "request message incomplete, deleting IKE_SA");
"request message incomplete, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -662,8 +642,7 @@ static status_t get_response(private_ike_sa_init_t *this,
notify_payload_t *notify = notify_payload_create(); notify_payload_t *notify = notify_payload_create();
notify->set_notify_type(notify, NO_PROPOSAL_CHOSEN); notify->set_notify_type(notify, NO_PROPOSAL_CHOSEN);
response->add_payload(response, (payload_t*)notify); response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "request did not contain any acceptable proposals, deleting IKE_SA");
"request did not contain any acceptable proposals, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
sa_response = sa_payload_create_from_proposal(this->proposal); sa_response = sa_payload_create_from_proposal(this->proposal);
@@ -692,10 +671,10 @@ static status_t get_response(private_ike_sa_init_t *this,
payload_t *payload; payload_t *payload;
notify_group = this->connection->get_dh_group(this->connection); notify_group = this->connection->get_dh_group(this->connection);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "request used inacceptable DH group %N, sending "
"request used inacceptable DH group %s, sending INVALID_KE_PAYLOAD with %s, deleting IKE_SA", "INVALID_KE_PAYLOAD with %N, deleting IKE_SA",
mapping_find(diffie_hellman_group_m, used_group), diffie_hellman_group_names, used_group,
mapping_find(diffie_hellman_group_m, notify_group)); diffie_hellman_group_names, notify_group);
/* remove already added payloads */ /* remove already added payloads */
iterator = response->get_payload_iterator(response); iterator = response->get_payload_iterator(response);
@@ -740,8 +719,7 @@ static status_t get_response(private_ike_sa_init_t *this,
notify_payload_t *notify = notify_payload_create(); notify_payload_t *notify = notify_payload_create();
notify->set_notify_type(notify, NO_PROPOSAL_CHOSEN); notify->set_notify_type(notify, NO_PROPOSAL_CHOSEN);
response->add_payload(response, (payload_t*)notify); response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "could not get random bytes for nonce, deleting IKE_SA");
"could not get random bytes for nonce, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
nonce_response = nonce_payload_create(); nonce_response = nonce_payload_create();
@@ -763,8 +741,7 @@ static status_t get_response(private_ike_sa_init_t *this,
notify = notify_payload_create(); notify = notify_payload_create();
notify->set_notify_type(notify, INVALID_SYNTAX); notify->set_notify_type(notify, INVALID_SYNTAX);
response->add_payload(response, (payload_t*)notify); response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "request contained wrong number of NAT-D payloads, deleting IKE_SA");
"request contained wrong number of NAT-D payloads, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
if (this->natd_dst_seen && !this->natd_dst_matched) if (this->natd_dst_seen && !this->natd_dst_matched)
@@ -797,8 +774,7 @@ static status_t get_response(private_ike_sa_init_t *this,
notify_payload_t *notify = notify_payload_create(); notify_payload_t *notify = notify_payload_create();
notify->set_notify_type(notify, NO_PROPOSAL_CHOSEN); notify->set_notify_type(notify, NO_PROPOSAL_CHOSEN);
response->add_payload(response, (payload_t*)notify); response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "transform objects could not be created from selected proposal, deleting IKE_SA");
"transform objects could not be created from selected proposal, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -816,8 +792,7 @@ static status_t get_response(private_ike_sa_init_t *this,
* as we don't use a crypter/signer in ike_sa_init... */ * as we don't use a crypter/signer in ike_sa_init... */
if (response->generate(response, NULL, NULL, &response_packet) != SUCCESS) if (response->generate(response, NULL, NULL, &response_packet) != SUCCESS)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "error in response generation, deleting IKE_SA");
"error in response generation, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
response_packet->destroy(response_packet); response_packet->destroy(response_packet);
@@ -870,8 +845,7 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
/* check message type */ /* check message type */
if (response->get_exchange_type(response) != IKE_SA_INIT) if (response->get_exchange_type(response) != IKE_SA_INIT)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "IKE_SA_INIT response of invalid type, deleting IKE_SA");
"IKE_SA_INIT response of invalid type, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -885,8 +859,7 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
responder_spi = response->get_responder_spi(response); responder_spi = response->get_responder_spi(response);
if (responder_spi == 0) if (responder_spi == 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "response contained a SPI of zero, deleting IKE_SA");
"response contained a SPI of zero, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -937,9 +910,8 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
} }
default: default:
{ {
this->logger->log(this->logger, ERROR, "ignoring payload %s (%d)", DBG1(SIG_DBG_IKE, "ignoring payload %N",
mapping_find(payload_type_m, payload->get_type(payload)), payload_type_names, payload->get_type(payload));
payload->get_type(payload));
break; break;
} }
} }
@@ -948,7 +920,7 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
if (!(nonce_payload && sa_payload && ke_payload)) if (!(nonce_payload && sa_payload && ke_payload))
{ {
this->logger->log(this->logger, AUDIT, "response message incomplete, deleting IKE_SA"); DBG1(SIG_DBG_IKE, "response message incomplete, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -965,8 +937,7 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
proposal_list = sa_payload->get_proposals (sa_payload); proposal_list = sa_payload->get_proposals (sa_payload);
if (proposal_list->get_count(proposal_list) != 1) if (proposal_list->get_count(proposal_list) != 1)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "response did not contain a single proposal, deleting IKE_SA");
"response did not contain a single proposal, deleting IKE_SA");
while (proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS) while (proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS)
{ {
proposal->destroy(proposal); proposal->destroy(proposal);
@@ -981,8 +952,7 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
if (this->proposal == NULL) if (this->proposal == NULL)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "peer selected a proposal we did not offer, deleting IKE_SA");
"peer selected a proposal we did not offer, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
} }
@@ -1010,8 +980,7 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
if ((!this->natd_dst_seen && this->natd_src_seen) || if ((!this->natd_dst_seen && this->natd_src_seen) ||
(this->natd_dst_seen && !this->natd_src_seen)) (this->natd_dst_seen && !this->natd_src_seen))
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "request contained wrong number of NAT-D payloads, deleting IKE_SA");
"request contained wrong number of NAT-D payloads, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
if (this->natd_src_seen && !this->natd_src_matched) if (this->natd_src_seen && !this->natd_src_matched)
@@ -1029,7 +998,7 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
other = this->ike_sa->get_other_host(this->ike_sa); other = this->ike_sa->get_other_host(this->ike_sa);
other->set_port(other, IKEV2_NATT_PORT); other->set_port(other, IKEV2_NATT_PORT);
this->logger->log(this->logger, CONTROL|LEVEL1, "switching to port %d", IKEV2_NATT_PORT); DBG2(SIG_DBG_IKE, "switching to port %d", IKEV2_NATT_PORT);
} }
} }
@@ -1043,8 +1012,7 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
this->nonce_i, this->nonce_r, this->nonce_i, this->nonce_r,
TRUE, NULL, NULL) != SUCCESS) TRUE, NULL, NULL) != SUCCESS)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "transform objects could not be created from selected proposal, deleting IKE_SA");
"transform objects could not be created from selected proposal, deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
@@ -1133,7 +1101,6 @@ ike_sa_init_t *ike_sa_init_create(ike_sa_t *ike_sa)
this->natd_dst_seen = FALSE; this->natd_dst_seen = FALSE;
this->natd_src_matched = FALSE; this->natd_src_matched = FALSE;
this->natd_dst_matched = FALSE; this->natd_dst_matched = FALSE;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public; return &this->public;
} }
+35 -65
View File
@@ -113,11 +113,6 @@ struct private_rekey_ike_sa_t {
* next transaction processed by the IKE_SA * next transaction processed by the IKE_SA
*/ */
transaction_t **next; transaction_t **next;
/**
* Assigned logger.
*/
logger_t *logger;
}; };
/** /**
@@ -186,10 +181,8 @@ static status_t get_request(private_rekey_ike_sa_t *this, message_t **result)
if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED && if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED &&
!this->diffie_hellman) !this->diffie_hellman)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "tried to rekey in state %N, aborted",
"tried to rekey in state %s, aborted", ike_sa_state_names, this->ike_sa->get_state(this->ike_sa));
mapping_find(ike_sa_state_m,
this->ike_sa->get_state(this->ike_sa)));
return FAILED; return FAILED;
} }
@@ -226,8 +219,7 @@ static status_t get_request(private_rekey_ike_sa_t *this, message_t **result)
me, other); me, other);
if (this->connection == NULL) if (this->connection == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "no connection found to rekey IKE_SA");
"no connection found to rekey IKE_SA");
return FAILED; return FAILED;
} }
} }
@@ -274,9 +266,8 @@ static status_t get_request(private_rekey_ike_sa_t *this, message_t **result)
this->diffie_hellman = diffie_hellman_create(dh_group); this->diffie_hellman = diffie_hellman_create(dh_group);
if (this->diffie_hellman == NULL) if (this->diffie_hellman == NULL)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "DH group %N not supported, aborting",
"DH group %s (%d) not supported, aborting", diffie_hellman_group_names, dh_group);
mapping_find(diffie_hellman_group_m, dh_group), dh_group);
return FAILED; return FAILED;
} }
} }
@@ -305,15 +296,13 @@ static status_t process_notifys(private_rekey_ike_sa_t *this, notify_payload_t *
{ {
notify_type_t notify_type = notify_payload->get_notify_type(notify_payload); notify_type_t notify_type = notify_payload->get_notify_type(notify_payload);
this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s", DBG2(SIG_DBG_IKE,"process notify type %N", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type));
switch (notify_type) switch (notify_type)
{ {
case NO_PROPOSAL_CHOSEN: case NO_PROPOSAL_CHOSEN:
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "received a NO_PROPOSAL_CHOSEN notify, IKE_SA rekeying failed");
"received a NO_PROPOSAL_CHOSEN notify, IKE_SA rekeying failed");
return FAILED; return FAILED;
} }
case INVALID_KE_PAYLOAD: case INVALID_KE_PAYLOAD:
@@ -326,14 +315,12 @@ static status_t process_notifys(private_rekey_ike_sa_t *this, notify_payload_t *
notify_data = notify_payload->get_notification_data(notify_payload); notify_data = notify_payload->get_notification_data(notify_payload);
dh_group = ntohs(*((u_int16_t*)notify_data.ptr)); dh_group = ntohs(*((u_int16_t*)notify_data.ptr));
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "peer didn't accept DH group %N, it requested %N",
"peer didn't accept DH group %s, it requested %s", diffie_hellman_group_names, old_dh_group,
mapping_find(diffie_hellman_group_m, old_dh_group), diffie_hellman_group_names, dh_group);
mapping_find(diffie_hellman_group_m, dh_group));
if (!this->connection->check_dh_group(this->connection, dh_group)) if (!this->connection->check_dh_group(this->connection, dh_group))
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "requested DH group not acceptable, IKE_SA rekeying failed");
"requested DH group not acceptable, IKE_SA rekeying failed");
return FAILED; return FAILED;
} }
retry = rekey_ike_sa_create(this->ike_sa); retry = rekey_ike_sa_create(this->ike_sa);
@@ -345,18 +332,14 @@ static status_t process_notifys(private_rekey_ike_sa_t *this, notify_payload_t *
{ {
if (notify_type < 16383) if (notify_type < 16383)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "received %N notify error, IKE_SA rekeying failed",
"received %s notify error (%d, IKE_SA rekeying failed", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type),
notify_type);
return FAILED; return FAILED;
} }
else else
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "received %N notify, ignored",
"received %s notify (%d), ignored", notify_type_names, notify_type);
mapping_find(notify_type_m, notify_type),
notify_type);
return SUCCESS; return SUCCESS;
} }
} }
@@ -468,8 +451,7 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
/* check message type */ /* check message type */
if (request->get_exchange_type(request) != CREATE_CHILD_SA) if (request->get_exchange_type(request) != CREATE_CHILD_SA)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "CREATE_CHILD_SA response of invalid type, aborted");
"CREATE_CHILD_SA response of invalid type, aborted");
return FAILED; return FAILED;
} }
@@ -477,8 +459,7 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
if (this->ike_sa->get_state(this->ike_sa) == IKE_DELETING) if (this->ike_sa->get_state(this->ike_sa) == IKE_DELETING)
{ {
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE); build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "unable to rekey, as delete in progress. Sending NO_PROPOSAL_CHOSEN");
"unable to rekey, as delete in progress. Sending NO_PROPOSAL_CHOSEN");
return FAILED; return FAILED;
} }
@@ -492,8 +473,7 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
state == CHILD_DELETING) state == CHILD_DELETING)
{ {
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE); build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_IKE, "unable to rekey, one CHILD_SA is half open. Sending NO_PROPOSAL_CHOSEN");
"unable to rekey, one CHILD_SA is half open. Sending NO_PROPOSAL_CHOSEN");
iterator->destroy(iterator); iterator->destroy(iterator);
return FAILED; return FAILED;
} }
@@ -514,8 +494,7 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
charon->connections, me, other); charon->connections, me, other);
if (this->connection == NULL) if (this->connection == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "no connection found to rekey IKE_SA, sending NO_RROPOSAL_CHOSEN");
"no connection found to rekey IKE_SA, sending NO_RROPOSAL_CHOSEN");
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE); build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
return FAILED; return FAILED;
} }
@@ -552,9 +531,8 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
} }
default: default:
{ {
this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)", DBG1(SIG_DBG_IKE, "ignoring %N payload",
mapping_find(payload_type_m, payload->get_type(payload)), payload_type_names, payload->get_type(payload));
payload->get_type(payload));
break; break;
} }
} }
@@ -565,8 +543,7 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
if (!(sa_request && nonce_request && ke_request)) if (!(sa_request && nonce_request && ke_request))
{ {
build_notify(INVALID_SYNTAX, CHUNK_INITIALIZER, response, TRUE); build_notify(INVALID_SYNTAX, CHUNK_INITIALIZER, response, TRUE);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "request message incomplete, IKE_SA rekeying failed");
"request message incomplete, IKE_SA rekeying failed");
return FAILED; return FAILED;
} }
@@ -591,15 +568,14 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
sa_response = sa_payload_create(); sa_response = sa_payload_create();
/* get proposals from request, and select one with ours */ /* get proposals from request, and select one with ours */
proposal_list = sa_request->get_proposals(sa_request); proposal_list = sa_request->get_proposals(sa_request);
this->logger->log(this->logger, CONTROL|LEVEL1, "selecting proposals:"); DBG2(SIG_DBG_IKE, "selecting proposals:");
this->proposal = this->connection->select_proposal(this->connection, proposal_list); this->proposal = this->connection->select_proposal(this->connection, proposal_list);
destroy_proposal_list(proposal_list); destroy_proposal_list(proposal_list);
/* do we have a proposal? */ /* do we have a proposal? */
if (this->proposal == NULL) if (this->proposal == NULL)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "no proposals acceptable to rekey IKE_SA, sending NO_PROPOSAL_CHOSEN");
"no proposals acceptable to rekey IKE_SA, sending NO_PROPOSAL_CHOSEN");
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE); build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
return FAILED; return FAILED;
} }
@@ -632,10 +608,10 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
chunk_t notify_chunk; chunk_t notify_chunk;
notify_group = this->connection->get_dh_group(this->connection); notify_group = this->connection->get_dh_group(this->connection);
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "request used inacceptable DH group %N, sending "
"request used inacceptable DH group %s, sending INVALID_KE_PAYLOAD with %s", "INVALID_KE_PAYLOAD with %N",
mapping_find(diffie_hellman_group_m, used_group), diffie_hellman_group_names, used_group,
mapping_find(diffie_hellman_group_m, notify_group)); diffie_hellman_group_names, notify_group);
notify_group = htons(notify_group); notify_group = htons(notify_group);
notify_chunk.ptr = (u_int8_t*)&notify_group; notify_chunk.ptr = (u_int8_t*)&notify_group;
@@ -713,8 +689,7 @@ static status_t conclude(private_rekey_ike_sa_t *this, message_t *response,
/* check message type */ /* check message type */
if (response->get_exchange_type(response) != CREATE_CHILD_SA) if (response->get_exchange_type(response) != CREATE_CHILD_SA)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "CREATE_CHILD_SA response of invalid type, aborting");
"CREATE_CHILD_SA response of invalid type, aborting");
return FAILED; return FAILED;
} }
@@ -753,9 +728,8 @@ static status_t conclude(private_rekey_ike_sa_t *this, message_t *response,
} }
default: default:
{ {
this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)", DBG1(SIG_DBG_IKE, "ignoring %N payload",
mapping_find(payload_type_m, payload->get_type(payload)), payload_type_names, payload->get_type(payload));
payload->get_type(payload));
break; break;
} }
} }
@@ -764,7 +738,7 @@ static status_t conclude(private_rekey_ike_sa_t *this, message_t *response,
if (!(sa_payload && nonce_payload && ke_payload)) if (!(sa_payload && nonce_payload && ke_payload))
{ {
this->logger->log(this->logger, AUDIT, "response message incomplete, rekeying IKE_SA failed"); DBG1(SIG_DBG_IKE, "response message incomplete, rekeying IKE_SA failed");
return FAILED; return FAILED;
} }
@@ -784,8 +758,7 @@ static status_t conclude(private_rekey_ike_sa_t *this, message_t *response,
if (this->proposal == NULL) if (this->proposal == NULL)
{ {
this->logger->log(this->logger, AUDIT, DBG1(SIG_DBG_IKE, "no proposal selected, rekeying IKE_SA failed");
"no proposal selected, rekeying IKE_SA failed");
return FAILED; return FAILED;
} }
spi = this->proposal->get_spi(this->proposal); spi = this->proposal->get_spi(this->proposal);
@@ -831,14 +804,12 @@ static status_t conclude(private_rekey_ike_sa_t *this, message_t *response,
if (memcmp(this_lowest.ptr, this->nonce_s.ptr, if (memcmp(this_lowest.ptr, this->nonce_s.ptr,
min(this_lowest.len, this->nonce_s.len)) < 0) min(this_lowest.len, this->nonce_s.len)) < 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "detected simultaneous IKE_SA rekeying, deleting ours");
"detected simultaneous IKE_SA rekeying, deleting ours");
this->lost = TRUE; this->lost = TRUE;
} }
else else
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_IKE, "detected simultaneous IKE_SA rekeying, but ours is preferred");
"detected simultaneous IKE_SA rekeying, but ours is preferred");
} }
if (this->lost) if (this->lost)
{ {
@@ -920,7 +891,6 @@ rekey_ike_sa_t *rekey_ike_sa_create(ike_sa_t *ike_sa)
this->randomizer = randomizer_create(); this->randomizer = randomizer_create();
this->diffie_hellman = NULL; this->diffie_hellman = NULL;
this->proposal = NULL; this->proposal = NULL;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public; return &this->public;
} }
-2
View File
@@ -35,8 +35,6 @@
#include <encoding/payloads/nonce_payload.h> #include <encoding/payloads/nonce_payload.h>
#include <encoding/payloads/notify_payload.h> #include <encoding/payloads/notify_payload.h>
#include <encoding/payloads/delete_payload.h> #include <encoding/payloads/delete_payload.h>
#include <utils/logger_manager.h>
/* /*
* see header file * see header file
+65 -81
View File
@@ -230,11 +230,6 @@ struct private_kernel_interface_t {
* Condvar allows signaling of threads waiting for a reply. * Condvar allows signaling of threads waiting for a reply.
*/ */
pthread_cond_t condvar; pthread_cond_t condvar;
/**
* Logger for XFRM stuff
*/
logger_t *logger;
}; };
@@ -362,15 +357,12 @@ static void receive_messages(private_kernel_interface_t *this)
} }
if (reqid == 0) if (reqid == 0)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_KNL, "received a XFRM_MSG_ACQUIRE, but no reqid found");
"Received a XFRM_MSG_ACQUIRE, but no reqid found");
} }
else else
{ {
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_KNL, "received a XFRM_MSG_ACQUIRE");
"Received a XFRM_MSG_ACQUIRE"); DBG1(SIG_DBG_KNL, "creating acquire job for CHILD_SA with reqid %d",
this->logger->log(this->logger, CONTROL,
"creating acquire job for CHILD_SA with reqid %d",
reqid); reqid);
job = (job_t*)acquire_job_create(reqid); job = (job_t*)acquire_job_create(reqid);
charon->job_queue->add(charon->job_queue, job); charon->job_queue->add(charon->job_queue, job);
@@ -389,12 +381,10 @@ static void receive_messages(private_kernel_interface_t *this)
spi = expire->state.id.spi; spi = expire->state.id.spi;
reqid = expire->state.reqid; reqid = expire->state.reqid;
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_KNL, "received a XFRM_MSG_EXPIRE");
"Received a XFRM_MSG_EXPIRE"); DBG1(SIG_DBG_KNL, "creating %s job for %N CHILD_SA 0x%x (reqid %d)",
this->logger->log(this->logger, CONTROL,
"creating %s job for %s CHILD_SA 0x%x (reqid %d)",
expire->hard ? "delete" : "rekey", expire->hard ? "delete" : "rekey",
mapping_find(protocol_id_m, protocol), ntohl(spi), protocol_id_names, protocol, ntohl(spi),
reqid); reqid);
if (expire->hard) if (expire->hard)
{ {
@@ -457,7 +447,7 @@ static status_t get_spi(private_kernel_interface_t *this,
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
status_t status = SUCCESS; status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "getting spi"); DBG2(SIG_DBG_KNL, "getting spi");
hdr = (struct nlmsghdr*)request; hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST; hdr->nlmsg_flags = NLM_F_REQUEST;
@@ -476,29 +466,29 @@ static status_t get_spi(private_kernel_interface_t *this,
if (send_message(this, hdr, &response) != SUCCESS) if (send_message(this, hdr, &response) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "netlink communication failed"); DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED; return FAILED;
} }
else if (response->nlmsg_type == NLMSG_ERROR) else if (response->nlmsg_type == NLMSG_ERROR)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_ALLOCSPI got an error: %s", DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_ALLOCSPI got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error)); strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
status = FAILED; status = FAILED;
} }
else if (response->nlmsg_type != XFRM_MSG_NEWSA) else if (response->nlmsg_type != XFRM_MSG_NEWSA)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_ALLOCSPI got a unknown reply"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_ALLOCSPI got a unknown reply");
status = FAILED; status = FAILED;
} }
else if (response->nlmsg_len < NLMSG_LENGTH(sizeof(struct xfrm_usersa_info))) else if (response->nlmsg_len < NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)))
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_ALLOCSPI got an invalid reply"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_ALLOCSPI got an invalid reply");
status = FAILED; status = FAILED;
} }
else else
{ {
*spi = ((struct xfrm_usersa_info*)NLMSG_DATA(response))->id.spi; *spi = ((struct xfrm_usersa_info*)NLMSG_DATA(response))->id.spi;
this->logger->log(this->logger, CONTROL|LEVEL1, "SPI is 0x%x", *spi); DBG2(SIG_DBG_KNL, "SPI is 0x%x", *spi);
} }
free(response); free(response);
@@ -526,7 +516,7 @@ static status_t add_sa(private_kernel_interface_t *this,
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
status_t status = SUCCESS; status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "adding SA"); DBG2(SIG_DBG_KNL, "adding SA");
hdr = (struct nlmsghdr*)request; hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -561,12 +551,12 @@ static status_t add_sa(private_kernel_interface_t *this,
alg_name = lookup_algorithm(encryption_algs, enc_alg, &key_size); alg_name = lookup_algorithm(encryption_algs, enc_alg, &key_size);
if (alg_name == NULL) if (alg_name == NULL)
{ {
this->logger->log(this->logger, ERROR, "Algorithm %s not supported by kernel!", DBG1(SIG_DBG_KNL, "algorithm %N not supported by kernel!",
mapping_find(encryption_algorithm_m, enc_alg->algorithm)); encryption_algorithm_names, enc_alg->algorithm);
return FAILED; return FAILED;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, " using encryption algorithm %s with key size %d", DBG2(SIG_DBG_KNL, " using encryption algorithm %N with key size %d",
mapping_find(encryption_algorithm_m, enc_alg->algorithm), key_size); encryption_algorithm_names, enc_alg->algorithm, key_size);
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + key_size); rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + key_size);
hdr->nlmsg_len += rthdr->rta_len; hdr->nlmsg_len += rthdr->rta_len;
@@ -589,12 +579,12 @@ static status_t add_sa(private_kernel_interface_t *this,
alg_name = lookup_algorithm(integrity_algs, int_alg, &key_size); alg_name = lookup_algorithm(integrity_algs, int_alg, &key_size);
if (alg_name == NULL) if (alg_name == NULL)
{ {
this->logger->log(this->logger, ERROR, "Algorithm %s not supported by kernel!", DBG1(SIG_DBG_KNL, "algorithm %N not supported by kernel!",
mapping_find(integrity_algorithm_m, int_alg->algorithm)); integrity_algorithm_names, int_alg->algorithm);
return FAILED; return FAILED;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, " using integrity algorithm %s with key size %d", DBG2(SIG_DBG_KNL, " using integrity algorithm %N with key size %d",
mapping_find(integrity_algorithm_m, int_alg->algorithm), key_size); integrity_algorithm_names, int_alg->algorithm, key_size);
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + key_size); rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + key_size);
hdr->nlmsg_len += rthdr->rta_len; hdr->nlmsg_len += rthdr->rta_len;
@@ -644,18 +634,18 @@ static status_t add_sa(private_kernel_interface_t *this,
if (send_message(this, hdr, &response) != SUCCESS) if (send_message(this, hdr, &response) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "netlink communication failed"); DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED; return FAILED;
} }
else if (response->nlmsg_type != NLMSG_ERROR) else if (response->nlmsg_type != NLMSG_ERROR)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_NEWSA not acknowledged"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_NEWSA not acknowledged");
status = FAILED; status = FAILED;
} }
else if (((struct nlmsgerr*)NLMSG_DATA(response))->error) else if (((struct nlmsgerr*)NLMSG_DATA(response))->error)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_NEWSA got an error: %s", DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_NEWSA got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error)); strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
status = FAILED; status = FAILED;
} }
@@ -681,7 +671,7 @@ static status_t update_sa(
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
status_t status = SUCCESS; status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "getting SA"); DBG2(SIG_DBG_KNL, "getting SA");
hdr = (struct nlmsghdr*)request; hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST; hdr->nlmsg_flags = NLM_F_REQUEST;
@@ -696,30 +686,30 @@ static status_t update_sa(
if (send_message(this, hdr, &update) != SUCCESS) if (send_message(this, hdr, &update) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "netlink communication failed"); DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED; return FAILED;
} }
else if (update->nlmsg_type == NLMSG_ERROR) else if (update->nlmsg_type == NLMSG_ERROR)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETSA got an error: %s", DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_GETSA got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(update))->error)); strerror(-((struct nlmsgerr*)NLMSG_DATA(update))->error));
free(update); free(update);
return FAILED; return FAILED;
} }
else if (update->nlmsg_type != XFRM_MSG_NEWSA) else if (update->nlmsg_type != XFRM_MSG_NEWSA)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETSA got a unknown reply"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_GETSA got a unknown reply");
free(update); free(update);
return FAILED; return FAILED;
} }
else if (update->nlmsg_len < NLMSG_LENGTH(sizeof(struct xfrm_usersa_info))) else if (update->nlmsg_len < NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)))
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETSA got an invalid reply"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_GETSA got an invalid reply");
free(update); free(update);
return FAILED; return FAILED;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, "updating SA"); DBG2(SIG_DBG_KNL, "updating SA");
update->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; update->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
update->nlmsg_type = XFRM_MSG_UPDSA; update->nlmsg_type = XFRM_MSG_UPDSA;
@@ -731,7 +721,7 @@ static status_t update_sa(
if (dst_changes & HOST_DIFF_ADDR) if (dst_changes & HOST_DIFF_ADDR)
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, "destination address changed! replacing SA"); DBG2(SIG_DBG_KNL, "destination address changed! replacing SA");
update->nlmsg_type = XFRM_MSG_NEWSA; update->nlmsg_type = XFRM_MSG_NEWSA;
host2xfrm(new_dst, &sa->id.daddr); host2xfrm(new_dst, &sa->id.daddr);
@@ -756,24 +746,24 @@ static status_t update_sa(
if (send_message(this, update, &response) != SUCCESS) if (send_message(this, update, &response) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "netlink communication failed"); DBG1(SIG_DBG_KNL, "netlink communication failed");
free(update); free(update);
return FAILED; return FAILED;
} }
else if (response->nlmsg_type != NLMSG_ERROR) else if (response->nlmsg_type != NLMSG_ERROR)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_XXXSA not acknowledged"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_XXXSA not acknowledged");
status = FAILED; status = FAILED;
} }
else if (((struct nlmsgerr*)NLMSG_DATA(response))->error) else if (((struct nlmsgerr*)NLMSG_DATA(response))->error)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_XXXSA got an error: %s", DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_XXXSA got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error)); strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
status = FAILED; status = FAILED;
} }
else if (dst_changes & HOST_DIFF_ADDR) else if (dst_changes & HOST_DIFF_ADDR)
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, "deleting old SA"); DBG2(SIG_DBG_KNL, "deleting old SA");
status = this->public.del_sa(&this->public, dst, spi, protocol); status = this->public.del_sa(&this->public, dst, spi, protocol);
} }
@@ -794,7 +784,7 @@ static status_t query_sa(private_kernel_interface_t *this, host_t *dst,
struct xfrm_usersa_id *sa_id; struct xfrm_usersa_id *sa_id;
struct xfrm_usersa_info *sa_info; struct xfrm_usersa_info *sa_info;
this->logger->log(this->logger, CONTROL|LEVEL2, "querying SA"); DBG2(SIG_DBG_KNL, "querying SA");
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
hdr = (struct nlmsghdr*)request; hdr = (struct nlmsghdr*)request;
@@ -810,18 +800,18 @@ static status_t query_sa(private_kernel_interface_t *this, host_t *dst,
if (send_message(this, hdr, &response) != SUCCESS) if (send_message(this, hdr, &response) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "netlink communication failed"); DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED; return FAILED;
} }
else if (response->nlmsg_type != XFRM_MSG_NEWSA) else if (response->nlmsg_type != XFRM_MSG_NEWSA)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETSA not acknowledged"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_GETSA not acknowledged");
free(response); free(response);
return FAILED; return FAILED;
} }
else if (response->nlmsg_len < NLMSG_LENGTH(sizeof(struct xfrm_usersa_info))) else if (response->nlmsg_len < NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)))
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETSA got an invalid reply"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_GETSA got an invalid reply");
free(response); free(response);
return FAILED; return FAILED;
} }
@@ -847,7 +837,7 @@ static status_t del_sa(private_kernel_interface_t *this, host_t *dst,
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
status_t status = SUCCESS; status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "deleting SA"); DBG2(SIG_DBG_KNL, "deleting SA");
hdr = (struct nlmsghdr*)request; hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -862,17 +852,17 @@ static status_t del_sa(private_kernel_interface_t *this, host_t *dst,
if (send_message(this, hdr, &response) != SUCCESS) if (send_message(this, hdr, &response) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "netlink communication failed"); DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED; return FAILED;
} }
else if (response->nlmsg_type != NLMSG_ERROR) else if (response->nlmsg_type != NLMSG_ERROR)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_DELSA not acknowledged"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_DELSA not acknowledged");
status = FAILED; status = FAILED;
} }
else if (((struct nlmsgerr*)NLMSG_DATA(response))->error) else if (((struct nlmsgerr*)NLMSG_DATA(response))->error)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_DELSA got an error: %s", DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_DELSA got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error)); strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
status = FAILED; status = FAILED;
} }
@@ -1010,8 +1000,7 @@ static status_t add_policy(private_kernel_interface_t *this,
if (!update) if (!update)
{ {
current->refcount++; current->refcount++;
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_KNL, "policy already exists, increasing refcount");
"policy already exists, increasing refcount");
if (!high_prio) if (!high_prio)
{ {
/* if added policy is for a ROUTED child_sa, do not /* if added policy is for a ROUTED child_sa, do not
@@ -1033,7 +1022,7 @@ static status_t add_policy(private_kernel_interface_t *this,
policy->refcount = 1; policy->refcount = 1;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, "adding policy"); DBG2(SIG_DBG_KNL, "adding policy");
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
hdr = (struct nlmsghdr*)request; hdr = (struct nlmsghdr*)request;
@@ -1087,20 +1076,18 @@ static status_t add_policy(private_kernel_interface_t *this,
if (send_message(this, hdr, &response) != SUCCESS) if (send_message(this, hdr, &response) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "netlink communication failed"); DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED; return FAILED;
} }
else if (response->nlmsg_type != NLMSG_ERROR) else if (response->nlmsg_type != NLMSG_ERROR)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_UPDPOLICY not acknowledged");
"netlink request XFRM_MSG_UPDPOLICY not acknowledged");
status = FAILED; status = FAILED;
} }
else if (((struct nlmsgerr*)NLMSG_DATA(response))->error) else if (((struct nlmsgerr*)NLMSG_DATA(response))->error)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_UPDPOLICY got an error: %s",
"netlink request XFRM_MSG_UPDPOLICY got an error: %s", strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
status = FAILED; status = FAILED;
} }
@@ -1125,7 +1112,7 @@ static status_t query_policy(private_kernel_interface_t *this,
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
status_t status = SUCCESS; status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "querying policy"); DBG2(SIG_DBG_KNL, "querying policy");
hdr = (struct nlmsghdr*)request; hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST; hdr->nlmsg_flags = NLM_F_REQUEST;
@@ -1138,25 +1125,25 @@ static status_t query_policy(private_kernel_interface_t *this,
if (send_message(this, hdr, &response) != SUCCESS) if (send_message(this, hdr, &response) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "netlink communication failed"); DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED; return FAILED;
} }
else if (response->nlmsg_type == NLMSG_ERROR) else if (response->nlmsg_type == NLMSG_ERROR)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETPOLICY got an error: %s", DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_GETPOLICY got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error)); strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
free(response); free(response);
return FAILED; return FAILED;
} }
else if (response->nlmsg_type != XFRM_MSG_NEWPOLICY) else if (response->nlmsg_type != XFRM_MSG_NEWPOLICY)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETPOLICY got an unknown reply"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_GETPOLICY got an unknown reply");
free(response); free(response);
return FAILED; return FAILED;
} }
else if (response->nlmsg_len < NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info))) else if (response->nlmsg_len < NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)))
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETPOLICY got an invalid reply"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_GETPOLICY got an invalid reply");
free(response); free(response);
return FAILED; return FAILED;
} }
@@ -1185,7 +1172,7 @@ static status_t del_policy(private_kernel_interface_t *this,
iterator_t *iterator; iterator_t *iterator;
status_t status = SUCCESS; status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "deleting policy"); DBG2(SIG_DBG_KNL, "deleting policy");
/* create a policy */ /* create a policy */
memset(&policy, 0, sizeof(kernel_policy_t)); memset(&policy, 0, sizeof(kernel_policy_t));
@@ -1204,8 +1191,7 @@ static status_t del_policy(private_kernel_interface_t *this,
if (--to_delete->refcount > 0) if (--to_delete->refcount > 0)
{ {
/* is used by more SAs, keep in kernel */ /* is used by more SAs, keep in kernel */
this->logger->log(this->logger, CONTROL|LEVEL1, DBG2(SIG_DBG_KNL, "is used by other SAs, not removed");
"is used by other SAs, not removed");
iterator->destroy(iterator); iterator->destroy(iterator);
pthread_mutex_unlock(&this->pol_mutex); pthread_mutex_unlock(&this->pol_mutex);
return SUCCESS; return SUCCESS;
@@ -1219,8 +1205,7 @@ static status_t del_policy(private_kernel_interface_t *this,
pthread_mutex_unlock(&this->pol_mutex); pthread_mutex_unlock(&this->pol_mutex);
if (!to_delete) if (!to_delete)
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, DBG1(SIG_DBG_KNL, "no such policy found");
"no such policy found");
return NOT_FOUND; return NOT_FOUND;
} }
@@ -1239,18 +1224,18 @@ static status_t del_policy(private_kernel_interface_t *this,
if (send_message(this, hdr, &response) != SUCCESS) if (send_message(this, hdr, &response) != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "netlink communication failed"); DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED; return FAILED;
} }
else if (response->nlmsg_type != NLMSG_ERROR) else if (response->nlmsg_type != NLMSG_ERROR)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_DELPOLICY not acknowledged"); DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_DELPOLICY not acknowledged");
status = FAILED; status = FAILED;
} }
else if (((struct nlmsgerr*)NLMSG_DATA(response))->error) else if (((struct nlmsgerr*)NLMSG_DATA(response))->error)
{ {
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_DELPOLICY got an error: %s", DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_DELPOLICY got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error)); strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
status = FAILED; status = FAILED;
} }
@@ -1294,7 +1279,6 @@ kernel_interface_t *kernel_interface_create()
this->pid = getpid(); this->pid = getpid();
this->responses = linked_list_create(); this->responses = linked_list_create();
this->policies = linked_list_create(); this->policies = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, XFRM);
pthread_mutex_init(&(this->rep_mutex),NULL); pthread_mutex_init(&(this->rep_mutex),NULL);
pthread_mutex_init(&(this->pol_mutex),NULL); pthread_mutex_init(&(this->pol_mutex),NULL);
pthread_cond_init(&(this->condvar),NULL); pthread_cond_init(&(this->condvar),NULL);
+8 -21
View File
@@ -32,7 +32,6 @@
#include <queues/job_queue.h> #include <queues/job_queue.h>
#include <queues/jobs/job.h> #include <queues/jobs/job.h>
#include <queues/jobs/incoming_packet_job.h> #include <queues/jobs/incoming_packet_job.h>
#include <utils/logger_manager.h>
typedef struct private_receiver_t private_receiver_t; typedef struct private_receiver_t private_receiver_t;
@@ -50,11 +49,6 @@ struct private_receiver_t {
* Assigned thread. * Assigned thread.
*/ */
pthread_t assigned_thread; pthread_t assigned_thread;
/**
* A logger for the receiver_t object.
*/
logger_t *logger;
}; };
/** /**
@@ -68,20 +62,20 @@ static void receive_packets(private_receiver_t * this)
/* cancellation disabled by default */ /* cancellation disabled by default */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
this->logger->log(this->logger, CONTROL, "receiver thread running, thread_ID: %06u", (int)pthread_self()); DBG1(SIG_DBG_NET, "receiver thread running, thread_ID: %06u",
(int)pthread_self());
while (1) while (TRUE)
{ {
while (charon->socket->receive(charon->socket,&current_packet) == SUCCESS) while (charon->socket->receive(charon->socket,&current_packet) == SUCCESS)
{ {
this->logger->log(this->logger, CONTROL | LEVEL1, "Creating job from packet"); DBG2(SIG_DBG_NET, "creating job from packet");
current_job = (job_t *) incoming_packet_job_create(current_packet); current_job = (job_t *) incoming_packet_job_create(current_packet);
charon->job_queue->add(charon->job_queue,current_job); charon->job_queue->add(charon->job_queue,current_job);
} }
/* bad bad, rebuild the socket ? */ /* bad bad, TODO: rebuild the socket ? */
this->logger->log(this->logger, ERROR, "Receiving from socket failed!"); DBG1(SIG_DBG_NET, "receiving from socket failed!");
} }
} }
@@ -90,12 +84,8 @@ static void receive_packets(private_receiver_t * this)
*/ */
static void destroy(private_receiver_t *this) static void destroy(private_receiver_t *this)
{ {
this->logger->log(this->logger, CONTROL | LEVEL1, "Going to terminate receiver thread");
pthread_cancel(this->assigned_thread); pthread_cancel(this->assigned_thread);
pthread_join(this->assigned_thread, NULL); pthread_join(this->assigned_thread, NULL);
this->logger->log(this->logger, CONTROL | LEVEL1, "Receiver thread terminated");
free(this); free(this);
} }
@@ -108,13 +98,10 @@ receiver_t * receiver_create()
this->public.destroy = (void(*)(receiver_t*)) destroy; this->public.destroy = (void(*)(receiver_t*)) destroy;
this->logger = logger_manager->get_logger(logger_manager, RECEIVER);
if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))receive_packets, this) != 0) if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))receive_packets, this) != 0)
{ {
this->logger->log(this->logger, ERROR, "Receiver thread could not be started");
free(this); free(this);
charon->kill(charon, "Unable to create receiver thread"); charon->kill(charon, "unable to create receiver thread");
} }
return &(this->public); return &(this->public);
+7 -19
View File
@@ -28,7 +28,6 @@
#include <daemon.h> #include <daemon.h>
#include <definitions.h> #include <definitions.h>
#include <utils/logger_manager.h>
#include <queues/job_queue.h> #include <queues/job_queue.h>
@@ -47,11 +46,6 @@ struct private_scheduler_t {
* Assigned thread. * Assigned thread.
*/ */
pthread_t assigned_thread; pthread_t assigned_thread;
/**
* A logger.
*/
logger_t *logger;
}; };
/** /**
@@ -64,16 +58,17 @@ static void get_events(private_scheduler_t * this)
/* cancellation disabled by default */ /* cancellation disabled by default */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
this->logger->log(this->logger, CONTROL, "scheduler thread running, thread_ID: %06u", (int)pthread_self()); DBG1(SIG_DBG_JOB, "scheduler thread running, thread_ID: %06u",
(int)pthread_self());
while (TRUE) while (TRUE)
{ {
this->logger->log(this->logger, CONTROL|LEVEL2, "waiting for next event..."); DBG2(SIG_DBG_JOB, "waiting for next event...");
/* get a job, this block until one is available */ /* get a job, this block until one is available */
current_job = charon->event_queue->get(charon->event_queue); current_job = charon->event_queue->get(charon->event_queue);
/* queue the job in the job queue, workers will eat them */ /* queue the job in the job queue, workers will eat them */
this->logger->log(this->logger, CONTROL | LEVEL1, "got event, adding job %s to job-queue.", DBG2(SIG_DBG_JOB, "got event, adding job %N to job-queue",
mapping_find(job_type_m, current_job->get_type(current_job))); job_type_names, current_job->get_type(current_job));
charon->job_queue->add(charon->job_queue, current_job); charon->job_queue->add(charon->job_queue, current_job);
} }
} }
@@ -83,12 +78,8 @@ static void get_events(private_scheduler_t * this)
*/ */
static void destroy(private_scheduler_t *this) static void destroy(private_scheduler_t *this)
{ {
this->logger->log(this->logger, CONTROL | LEVEL1, "going to terminate scheduler thread");
pthread_cancel(this->assigned_thread); pthread_cancel(this->assigned_thread);
pthread_join(this->assigned_thread, NULL); pthread_join(this->assigned_thread, NULL);
this->logger->log(this->logger, CONTROL | LEVEL1, "scheduler thread terminated");
free(this); free(this);
} }
@@ -98,18 +89,15 @@ static void destroy(private_scheduler_t *this)
scheduler_t * scheduler_create() scheduler_t * scheduler_create()
{ {
private_scheduler_t *this = malloc_thing(private_scheduler_t); private_scheduler_t *this = malloc_thing(private_scheduler_t);
this->public.destroy = (void(*)(scheduler_t*)) destroy;
this->logger = logger_manager->get_logger(logger_manager, SCHEDULER); this->public.destroy = (void(*)(scheduler_t*)) destroy;
if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))get_events, this) != 0) if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))get_events, this) != 0)
{ {
/* thread could not be created */ /* thread could not be created */
this->logger->log(this->logger, ERROR, "scheduler thread could not be created!");
free(this); free(this);
charon->kill(charon, "unable to create scheduler thread"); charon->kill(charon, "unable to create scheduler thread");
} }
return &(this->public); return &(this->public);
} }
+5 -17
View File
@@ -30,7 +30,6 @@
#include <network/socket.h> #include <network/socket.h>
#include <network/packet.h> #include <network/packet.h>
#include <queues/send_queue.h> #include <queues/send_queue.h>
#include <utils/logger_manager.h>
typedef struct private_sender_t private_sender_t; typedef struct private_sender_t private_sender_t;
@@ -48,11 +47,6 @@ struct private_sender_t {
* Assigned thread. * Assigned thread.
*/ */
pthread_t assigned_thread; pthread_t assigned_thread;
/**
* A logger for this sender_t object.
*/
logger_t *logger;
}; };
@@ -67,16 +61,17 @@ static void send_packets(private_sender_t * this)
/* cancellation disabled by default */ /* cancellation disabled by default */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
this->logger->log(this->logger, CONTROL, "sender thread running, thread_ID: %06u", (int)pthread_self()); DBG1(SIG_DBG_NET, "sender thread running, thread_ID: %06u",
(int)pthread_self());
while (TRUE) while (TRUE)
{ {
current_packet = charon->send_queue->get(charon->send_queue); current_packet = charon->send_queue->get(charon->send_queue);
this->logger->log(this->logger, CONTROL|LEVEL1, "Got a packet, sending it"); DBG2(SIG_DBG_NET, "got a packet, sending it");
status = charon->socket->send(charon->socket, current_packet); status = charon->socket->send(charon->socket, current_packet);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, ERROR, "Sending packet failed"); DBG1(SIG_DBG_NET, "sending packet failed");
} }
current_packet->destroy(current_packet); current_packet->destroy(current_packet);
} }
@@ -87,12 +82,8 @@ static void send_packets(private_sender_t * this)
*/ */
static void destroy(private_sender_t *this) static void destroy(private_sender_t *this)
{ {
this->logger->log(this->logger, CONTROL | LEVEL1, "Going to terminate sender thread");
pthread_cancel(this->assigned_thread); pthread_cancel(this->assigned_thread);
pthread_join(this->assigned_thread, NULL); pthread_join(this->assigned_thread, NULL);
this->logger->log(this->logger, CONTROL | LEVEL1, "Sender thread terminated");
free(this); free(this);
} }
@@ -104,14 +95,11 @@ sender_t * sender_create()
private_sender_t *this = malloc_thing(private_sender_t); private_sender_t *this = malloc_thing(private_sender_t);
this->public.destroy = (void(*)(sender_t*)) destroy; this->public.destroy = (void(*)(sender_t*)) destroy;
this->logger = logger_manager->get_logger(logger_manager, SENDER);
if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))send_packets, this) != 0) if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))send_packets, this) != 0)
{ {
this->logger->log(this->logger, ERROR, "Sender thread could not be created");
free(this); free(this);
charon->kill(charon, "Unable to create sender thread"); charon->kill(charon, "unable to create sender thread");
} }
return &(this->public); return &(this->public);
+294 -234
View File
@@ -33,10 +33,11 @@
#include "stroke_interface.h" #include "stroke_interface.h"
#include <stroke.h>
#include <types.h> #include <types.h>
#include <stroke.h>
#include <daemon.h> #include <daemon.h>
#include <crypto/x509.h> #include <crypto/x509.h>
#include <crypto/crl.h>
#include <queues/jobs/initiate_job.h> #include <queues/jobs/initiate_job.h>
#include <queues/jobs/route_job.h> #include <queues/jobs/route_job.h>
#include <utils/leak_detective.h> #include <utils/leak_detective.h>
@@ -59,16 +60,11 @@ struct private_stroke_t {
* Public part of stroke_t object. * Public part of stroke_t object.
*/ */
stroke_t public; stroke_t public;
/**
* Assigned logger_t object in charon.
*/
logger_t *logger;
/** /**
* Logger which logs to stroke * Output stream (stroke console)
*/ */
logger_t *stroke_logger; FILE *out;
/** /**
* Unix socket to listen for strokes * Unix socket to listen for strokes
@@ -76,14 +72,9 @@ struct private_stroke_t {
int socket; int socket;
/** /**
* Thread which reads from the ocket * Thread which reads from the Socket
*/ */
pthread_t assigned_thread; pthread_t assigned_thread;
/**
* Read from the socket and handle stroke messages
*/
void (*stroke_receive) (private_stroke_t *this);
}; };
/** /**
@@ -115,7 +106,7 @@ static void pop_string(stroke_msg_t *msg, char **string)
/** /**
* Load end entitity certificate * Load end entitity certificate
*/ */
static x509_t* load_end_certificate(const char *filename, identification_t **idp, logger_t *logger) static x509_t* load_end_certificate(const char *filename, identification_t **idp)
{ {
char path[PATH_BUF]; char path[PATH_BUF];
x509_t *cert; x509_t *cert;
@@ -142,7 +133,7 @@ static x509_t* load_end_certificate(const char *filename, identification_t **idp
if (ugh != NULL) if (ugh != NULL)
{ {
logger->log(logger, ERROR, "warning: certificate %s", ugh); DBG1(SIG_DBG_CFG, "warning: certificate %s", ugh);
} }
if (!id->equals(id, subject) && !cert->equals_subjectAltName(cert, id)) if (!id->equals(id, subject) && !cert->equals_subjectAltName(cert, id))
{ {
@@ -170,7 +161,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
host_t *my_host, *other_host, *my_subnet, *other_subnet; host_t *my_host, *other_host, *my_subnet, *other_subnet;
proposal_t *proposal; proposal_t *proposal;
traffic_selector_t *my_ts, *other_ts; traffic_selector_t *my_ts, *other_ts;
pop_string(msg, &msg->add_conn.name); pop_string(msg, &msg->add_conn.name);
pop_string(msg, &msg->add_conn.me.address); pop_string(msg, &msg->add_conn.me.address);
pop_string(msg, &msg->add_conn.other.address); pop_string(msg, &msg->add_conn.other.address);
@@ -187,29 +178,27 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
pop_string(msg, &msg->add_conn.algorithms.ike); pop_string(msg, &msg->add_conn.algorithms.ike);
pop_string(msg, &msg->add_conn.algorithms.esp); pop_string(msg, &msg->add_conn.algorithms.esp);
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_CFG, "received stroke: add connection '%s'", msg->add_conn.name);
"received stroke: add connection \"%s\"", msg->add_conn.name);
this->logger->log(this->logger, CONTROL|LEVEL2, "conn %s", msg->add_conn.name); DBG2(SIG_DBG_CFG, "conn %s", msg->add_conn.name);
this->logger->log(this->logger, CONTROL|LEVEL2, " right=%s", msg->add_conn.me.address); DBG2(SIG_DBG_CFG, " right=%s", msg->add_conn.me.address);
this->logger->log(this->logger, CONTROL|LEVEL2, " left=%s", msg->add_conn.other.address); DBG2(SIG_DBG_CFG, " left=%s", msg->add_conn.other.address);
this->logger->log(this->logger, CONTROL|LEVEL2, " rightsubnet=%s", msg->add_conn.me.subnet); DBG2(SIG_DBG_CFG, " rightsubnet=%s", msg->add_conn.me.subnet);
this->logger->log(this->logger, CONTROL|LEVEL2, " leftsubnet=%s", msg->add_conn.other.subnet); DBG2(SIG_DBG_CFG, " leftsubnet=%s", msg->add_conn.other.subnet);
this->logger->log(this->logger, CONTROL|LEVEL2, " rightid=%s", msg->add_conn.me.id); DBG2(SIG_DBG_CFG, " rightid=%s", msg->add_conn.me.id);
this->logger->log(this->logger, CONTROL|LEVEL2, " leftid=%s", msg->add_conn.other.id); DBG2(SIG_DBG_CFG, " leftid=%s", msg->add_conn.other.id);
this->logger->log(this->logger, CONTROL|LEVEL2, " rightcert=%s", msg->add_conn.me.cert); DBG2(SIG_DBG_CFG, " rightcert=%s", msg->add_conn.me.cert);
this->logger->log(this->logger, CONTROL|LEVEL2, " leftcert=%s", msg->add_conn.other.cert); DBG2(SIG_DBG_CFG, " leftcert=%s", msg->add_conn.other.cert);
this->logger->log(this->logger, CONTROL|LEVEL2, " rightca=%s", msg->add_conn.me.ca); DBG2(SIG_DBG_CFG, " rightca=%s", msg->add_conn.me.ca);
this->logger->log(this->logger, CONTROL|LEVEL2, " leftca=%s", msg->add_conn.other.ca); DBG2(SIG_DBG_CFG, " leftca=%s", msg->add_conn.other.ca);
this->logger->log(this->logger, CONTROL|LEVEL2, " ike=%s", msg->add_conn.algorithms.ike); DBG2(SIG_DBG_CFG, " ike=%s", msg->add_conn.algorithms.ike);
this->logger->log(this->logger, CONTROL|LEVEL2, " esp=%s", msg->add_conn.algorithms.esp); DBG2(SIG_DBG_CFG, " esp=%s", msg->add_conn.algorithms.esp);
my_host = msg->add_conn.me.address? my_host = msg->add_conn.me.address?
host_create_from_string(msg->add_conn.me.address, IKE_PORT) : NULL; host_create_from_string(msg->add_conn.me.address, IKE_PORT) : NULL;
if (my_host == NULL) if (my_host == NULL)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, DBG1(SIG_DBG_CFG, "invalid host: %s\n", msg->add_conn.me.address);
"invalid host: %s", msg->add_conn.me.address);
return; return;
} }
@@ -217,8 +206,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
host_create_from_string(msg->add_conn.other.address, IKE_PORT) : NULL; host_create_from_string(msg->add_conn.other.address, IKE_PORT) : NULL;
if (other_host == NULL) if (other_host == NULL)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, DBG1(SIG_DBG_CFG, "invalid host: %s\n", msg->add_conn.other.address);
"invalid host: %s", msg->add_conn.other.address);
my_host->destroy(my_host); my_host->destroy(my_host);
return; return;
} }
@@ -228,8 +216,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
stroke_end_t tmp_end; stroke_end_t tmp_end;
host_t *tmp_host; host_t *tmp_host;
this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, DBG2(SIG_DBG_CFG, "left is other host, swapping ends\n");
"left is other host, swapping ends");
tmp_host = my_host; tmp_host = my_host;
my_host = other_host; my_host = other_host;
@@ -241,8 +228,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
} }
else if (!charon->socket->is_local_address(charon->socket, my_host, NULL)) else if (!charon->socket->is_local_address(charon->socket, my_host, NULL))
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, DBG1(SIG_DBG_CFG, "left nor right host is our side, aborting\n");
"left nor right host is our side, aborting");
goto destroy_hosts; goto destroy_hosts;
} }
@@ -250,8 +236,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
msg->add_conn.me.id : msg->add_conn.me.address); msg->add_conn.me.id : msg->add_conn.me.address);
if (my_id == NULL) if (my_id == NULL)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, DBG1(SIG_DBG_CFG, "invalid ID: %s\n", msg->add_conn.me.id);
"invalid id: %s", msg->add_conn.me.id);
goto destroy_hosts; goto destroy_hosts;
} }
@@ -259,8 +244,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
msg->add_conn.other.id : msg->add_conn.other.address); msg->add_conn.other.id : msg->add_conn.other.address);
if (other_id == NULL) if (other_id == NULL)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, DBG1(SIG_DBG_CFG, "invalid ID: %s\n", msg->add_conn.other.id);
"invalid id: %s", msg->add_conn.other.id);
my_id->destroy(my_id); my_id->destroy(my_id);
goto destroy_hosts; goto destroy_hosts;
} }
@@ -269,8 +253,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
msg->add_conn.me.subnet : msg->add_conn.me.address, IKE_PORT); msg->add_conn.me.subnet : msg->add_conn.me.address, IKE_PORT);
if (my_subnet == NULL) if (my_subnet == NULL)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, DBG1(SIG_DBG_CFG, "invalid subnet: %s\n", msg->add_conn.me.subnet);
"invalid subnet: %s", msg->add_conn.me.subnet);
goto destroy_ids; goto destroy_ids;
} }
@@ -278,8 +261,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
msg->add_conn.other.subnet : msg->add_conn.other.address, IKE_PORT); msg->add_conn.other.subnet : msg->add_conn.other.address, IKE_PORT);
if (other_subnet == NULL) if (other_subnet == NULL)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, DBG1(SIG_DBG_CFG, "invalid subnet: %s\n", msg->add_conn.me.subnet);
"invalid subnet: %s", msg->add_conn.me.subnet);
my_subnet->destroy(my_subnet); my_subnet->destroy(my_subnet);
goto destroy_ids; goto destroy_ids;
} }
@@ -318,7 +300,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
} }
if (msg->add_conn.me.cert) if (msg->add_conn.me.cert)
{ {
x509_t *cert = load_end_certificate(msg->add_conn.me.cert, &my_id, this->logger); x509_t *cert = load_end_certificate(msg->add_conn.me.cert, &my_id);
if (my_ca == NULL && !my_ca_same && cert) if (my_ca == NULL && !my_ca_same && cert)
{ {
@@ -329,7 +311,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
} }
if (msg->add_conn.other.cert) if (msg->add_conn.other.cert)
{ {
x509_t *cert = load_end_certificate(msg->add_conn.other.cert, &other_id, this->logger); x509_t *cert = load_end_certificate(msg->add_conn.other.cert, &other_id);
if (other_ca == NULL && !other_ca_same && cert) if (other_ca == NULL && !other_ca_same && cert)
{ {
@@ -354,9 +336,9 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
{ {
other_ca = identification_create_from_string("%any"); other_ca = identification_create_from_string("%any");
} }
this->logger->log(this->logger, CONTROL|LEVEL1, " my ca: '%D'", my_ca); DBG2(SIG_DBG_CFG, " my ca: '%D'", my_ca);
this->logger->log(this->logger, CONTROL|LEVEL1, " other ca:'%D'", other_ca); DBG2(SIG_DBG_CFG, " other ca:'%D'", other_ca);
this->logger->log(this->logger, CONTROL|LEVEL1, " updown: '%s'", msg->add_conn.me.updown); DBG2(SIG_DBG_CFG, " updown: '%s'", msg->add_conn.me.updown);
connection = connection_create(msg->add_conn.name, connection = connection_create(msg->add_conn.name,
msg->add_conn.ikev2, msg->add_conn.ikev2,
@@ -384,8 +366,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
proposal = proposal_create_from_string(PROTO_IKE, proposal_string); proposal = proposal_create_from_string(PROTO_IKE, proposal_string);
if (proposal == NULL) if (proposal == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_CFG, "invalid IKE proposal string: %s", proposal_string);
"invalid IKE proposal string: %s", proposal_string);
my_id->destroy(my_id); my_id->destroy(my_id);
other_id->destroy(other_id); other_id->destroy(other_id);
my_ts->destroy(my_ts); my_ts->destroy(my_ts);
@@ -435,8 +416,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
proposal = proposal_create_from_string(PROTO_ESP, proposal_string); proposal = proposal_create_from_string(PROTO_ESP, proposal_string);
if (proposal == NULL) if (proposal == NULL)
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_CFG, "invalid ESP proposal string: %s", proposal_string);
"invalid ESP proposal string: %s", proposal_string);
policy->destroy(policy); policy->destroy(policy);
connection->destroy(connection); connection->destroy(connection);
return; return;
@@ -457,11 +437,11 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
/* add to global connection list */ /* add to global connection list */
charon->connections->add_connection(charon->connections, connection); charon->connections->add_connection(charon->connections, connection);
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_CFG, "added connection '%s': %H[%D]...%H[%D]",
"added connection \"%s\": %H[%D]...%H[%D]", msg->add_conn.name, msg->add_conn.name, my_host, my_id, other_host, other_id);
my_host, my_id, other_host, other_id);
/* add to global policy list */ /* add to global policy list */
charon->policies->add_policy(charon->policies, policy); charon->policies->add_policy(charon->policies, policy);
return; return;
/* mopping up after parsing errors */ /* mopping up after parsing errors */
@@ -483,20 +463,18 @@ static void stroke_del_conn(private_stroke_t *this, stroke_msg_t *msg)
status_t status; status_t status;
pop_string(msg, &(msg->del_conn.name)); pop_string(msg, &(msg->del_conn.name));
this->logger->log(this->logger, CONTROL, "received stroke: delete \"%s\"", msg->del_conn.name); DBG1(SIG_DBG_CFG, "received stroke: delete '%s'", msg->del_conn.name);
status = charon->connections->delete_connection(charon->connections, status = charon->connections->delete_connection(charon->connections,
msg->del_conn.name); msg->del_conn.name);
charon->policies->delete_policy(charon->policies, msg->del_conn.name); charon->policies->delete_policy(charon->policies, msg->del_conn.name);
if (status == SUCCESS) if (status == SUCCESS)
{ {
this->stroke_logger->log(this->stroke_logger, CONTROL, fprintf(this->out, "deleted connection '%s'\n", msg->del_conn.name);
"Deleted connection '%s'", msg->del_conn.name);
} }
else else
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, fprintf(this->out, "no connection named '%s'\n", msg->del_conn.name);
"No connection named '%s'", msg->del_conn.name);
} }
} }
@@ -508,19 +486,17 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
initiate_job_t *job; initiate_job_t *job;
connection_t *connection; connection_t *connection;
policy_t *policy; policy_t *policy;
ike_sa_t *init_ike_sa = NULL;
signal_t signal;
pop_string(msg, &(msg->initiate.name)); pop_string(msg, &(msg->initiate.name));
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_CFG, "received stroke: initiate '%s'", msg->initiate.name);
"received stroke: initiate \"%s\"",
msg->initiate.name);
connection = charon->connections->get_connection_by_name(charon->connections, connection = charon->connections->get_connection_by_name(charon->connections,
msg->initiate.name); msg->initiate.name);
if (connection == NULL) if (connection == NULL)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, fprintf(this->out, "no connection named '%s'\n", msg->initiate.name);
"no connection named \"%s\"",
msg->initiate.name);
return; return;
} }
if (!connection->is_ikev2(connection)) if (!connection->is_ikev2(connection))
@@ -533,17 +509,54 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
msg->initiate.name); msg->initiate.name);
if (policy == NULL) if (policy == NULL)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, fprintf(this->out, "no policy named '%s'\n", msg->initiate.name);
"no policy named \"%s\"",
msg->initiate.name);
connection->destroy(connection); connection->destroy(connection);
return; return;
} }
this->stroke_logger->log(this->stroke_logger, CONTROL, fprintf(this->out, "initiating connection '%s'\n", msg->initiate.name);
"initiating connection \"%s\" (see log)...",
msg->initiate.name);
job = initiate_job_create(connection, policy); job = initiate_job_create(connection, policy);
charon->bus->set_listen_state(charon->bus, TRUE);
charon->job_queue->add(charon->job_queue, (job_t*)job); charon->job_queue->add(charon->job_queue, (job_t*)job);
while (TRUE)
{
level_t level;
int thread;
ike_sa_t *ike_sa;
char* format;
va_list args;
signal = charon->bus->listen(charon->bus, &level, &thread, &ike_sa, &format, &args);
if (ike_sa == init_ike_sa && level <= LEVEL_CTRL)
{
if (vfprintf(this->out, format, args) < 0 ||
fprintf(this->out, "\n") < 0 ||
fflush(this->out))
{
break;
}
}
/* TODO: Handle INVALID_KE_PAYLOAD signal (ike_sa switch) */
switch (signal)
{
case SIG_IKE_UP:
case SIG_IKE_FAILED:
case SIG_IKE_DOWN:
if (ike_sa == init_ike_sa)
{
charon->bus->set_listen_state(charon->bus, FALSE);
}
return;
case SIG_INITIATE:
init_ike_sa = ike_sa;
/* fall through */
default:
continue;
}
}
} }
/** /**
@@ -556,10 +569,8 @@ static void stroke_route(private_stroke_t *this, stroke_msg_t *msg, bool route)
policy_t *policy; policy_t *policy;
pop_string(msg, &(msg->route.name)); pop_string(msg, &(msg->route.name));
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_CFG, "received stroke: %s '%s'",
"received stroke: %s \"%s\"", route ? "route" : "unroute", msg->route.name);
route ? "route" : "unroute",
msg->route.name);
/* we wouldn't need a connection, but we only want to route policies /* we wouldn't need a connection, but we only want to route policies
* whose connections are keyexchange=ikev2. */ * whose connections are keyexchange=ikev2. */
@@ -567,9 +578,7 @@ static void stroke_route(private_stroke_t *this, stroke_msg_t *msg, bool route)
msg->route.name); msg->route.name);
if (connection == NULL) if (connection == NULL)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, fprintf(this->out, "no connection named '%s'\n", msg->route.name);
"no connection named \"%s\"",
msg->route.name);
return; return;
} }
if (!connection->is_ikev2(connection)) if (!connection->is_ikev2(connection))
@@ -582,16 +591,12 @@ static void stroke_route(private_stroke_t *this, stroke_msg_t *msg, bool route)
msg->route.name); msg->route.name);
if (policy == NULL) if (policy == NULL)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, fprintf(this->out, "no policy named '%s'\n", msg->route.name);
"no policy named \"%s\"",
msg->route.name);
connection->destroy(connection); connection->destroy(connection);
return; return;
} }
this->stroke_logger->log(this->stroke_logger, CONTROL, fprintf(this->out, "%s policy '%s'\n",
"%s policy \"%s\"", route ? "routing" : "unrouting", msg->route.name);
route ? "routing" : "unrouting",
msg->route.name);
job = route_job_create(connection, policy, route); job = route_job_create(connection, policy, route);
charon->job_queue->add(charon->job_queue, (job_t*)job); charon->job_queue->add(charon->job_queue, (job_t*)job);
} }
@@ -602,37 +607,38 @@ static void stroke_route(private_stroke_t *this, stroke_msg_t *msg, bool route)
static void stroke_terminate(private_stroke_t *this, stroke_msg_t *msg) static void stroke_terminate(private_stroke_t *this, stroke_msg_t *msg)
{ {
pop_string(msg, &(msg->terminate.name)); pop_string(msg, &(msg->terminate.name));
this->logger->log(this->logger, CONTROL, "received stroke: terminate \"%s\"", msg->terminate.name); DBG1(SIG_DBG_CFG, "received stroke: terminate '%s'", msg->terminate.name);
charon->ike_sa_manager->delete_by_name(charon->ike_sa_manager, msg->terminate.name); charon->ike_sa_manager->delete_by_name(charon->ike_sa_manager, msg->terminate.name);
} }
/** /**
* show status of (established) connections * show status of daemon
*/ */
static void stroke_status(private_stroke_t *this, stroke_msg_t *msg) static void stroke_statusall(private_stroke_t *this, stroke_msg_t *msg)
{ {
iterator_t *iterator;
linked_list_t *list; linked_list_t *list;
host_t *host; host_t *host;
connection_t *connection;
policy_t *policy;
ike_sa_t *ike_sa;
leak_detective_status(this->stroke_logger); leak_detective_status(this->out);
this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, fprintf(this->out, "worker threads idle: %d of %d\n",
"job queue load: %d", charon->thread_pool->get_idle_threads(charon->thread_pool),
charon->job_queue->get_count(charon->job_queue)); charon->thread_pool->get_pool_size(charon->thread_pool));
this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, fprintf(this->out, "job queue load: %d\n",
"scheduled events: %d", charon->job_queue->get_count(charon->job_queue));
charon->event_queue->get_count(charon->event_queue)); fprintf(this->out, "scheduled events: %d\n",
charon->event_queue->get_count(charon->event_queue));
list = charon->socket->create_local_address_list(charon->socket); list = charon->socket->create_local_address_list(charon->socket);
this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, fprintf(this->out, "listening on %d addresses:\n", list->get_count(list));
"listening on %d addresses:",
list->get_count(list));
while (list->remove_first(list, (void**)&host) == SUCCESS) while (list->remove_first(list, (void**)&host) == SUCCESS)
{ {
this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, fprintf(this->out, " %H\n", host);
" %H", host);
host->destroy(host); host->destroy(host);
} }
list->destroy(list); list->destroy(list);
@@ -640,10 +646,101 @@ static void stroke_status(private_stroke_t *this, stroke_msg_t *msg)
{ {
pop_string(msg, &(msg->status.name)); pop_string(msg, &(msg->status.name));
} }
charon->connections->log_connections(charon->connections,
this->stroke_logger, msg->status.name); fprintf(this->out, "connections:\n");
charon->ike_sa_manager->log_status(charon->ike_sa_manager, iterator = charon->connections->create_iterator(charon->connections);
this->stroke_logger, msg->status.name); while (iterator->iterate(iterator, (void**)&connection))
{
if (connection->is_ikev2(connection) && (msg->status.name == NULL ||
streq(msg->status.name, connection->get_name(connection))))
{
fprintf(this->out, "%10s: %H...%H\n",
connection->get_name(connection),
connection->get_my_host(connection),
connection->get_other_host(connection));
}
}
iterator->destroy(iterator);
fprintf(this->out, "policies:\n");
iterator = charon->policies->create_iterator(charon->policies);
while (iterator->iterate(iterator, (void**)&policy))
{
if (msg->status.name == NULL ||
streq(msg->status.name, policy->get_name(policy)))
{
fprintf(this->out, "%10s: %D...%D\n",
policy->get_name(policy),
policy->get_my_id(policy),
policy->get_other_id(policy));
}
}
iterator->destroy(iterator);
fprintf(this->out, "IKE_SAs:\n");
iterator = charon->ike_sa_manager->create_iterator(charon->ike_sa_manager);
while (iterator->iterate(iterator, (void**)&ike_sa))
{
bool ike_sa_printed = FALSE;
child_sa_t *child_sa;
iterator_t *children = ike_sa->create_child_sa_iterator(ike_sa);
while (children->iterate(children, (void**)&child_sa))
{
if (!ike_sa_printed &&
(msg->status.name == NULL ||
streq(msg->status.name, child_sa->get_name(child_sa)) ||
streq(msg->status.name, ike_sa->get_name(ike_sa))))
{
fprintf(this->out, "%#K\n", ike_sa);
ike_sa_printed = TRUE;
}
if (ike_sa_printed)
{
fprintf(this->out, "%#P\n", child_sa);
}
}
children->destroy(children);
}
iterator->destroy(iterator);
}
/**
* show status of daemon
*/
static void stroke_status(private_stroke_t *this, stroke_msg_t *msg)
{
iterator_t *iterator;
ike_sa_t *ike_sa;
if (msg->status.name)
{
pop_string(msg, &(msg->status.name));
}
iterator = charon->ike_sa_manager->create_iterator(charon->ike_sa_manager);
while (iterator->iterate(iterator, (void**)&ike_sa))
{
bool ike_sa_printed = FALSE;
child_sa_t *child_sa;
iterator_t *children = ike_sa->create_child_sa_iterator(ike_sa);
while (children->iterate(children, (void**)&child_sa))
{
if (!ike_sa_printed &&
(msg->status.name == NULL ||
streq(msg->status.name, child_sa->get_name(child_sa)) ||
streq(msg->status.name, ike_sa->get_name(ike_sa))))
{
fprintf(this->out, "%K\n", ike_sa);
ike_sa_printed = TRUE;
}
if (ike_sa_printed)
{
fprintf(this->out, "%P\n", child_sa);
}
}
children->destroy(children);
}
iterator->destroy(iterator);
} }
/** /**
@@ -651,17 +748,62 @@ static void stroke_status(private_stroke_t *this, stroke_msg_t *msg)
*/ */
static void stroke_list(private_stroke_t *this, stroke_msg_t *msg) static void stroke_list(private_stroke_t *this, stroke_msg_t *msg)
{ {
iterator_t *iterator;
if (msg->list.flags & LIST_CERTS) if (msg->list.flags & LIST_CERTS)
{ {
charon->credentials->log_certificates(charon->credentials, this->stroke_logger, msg->list.utc); x509_t *cert;
iterator = charon->credentials->create_cert_iterator(charon->credentials);
if (iterator->get_count(iterator))
{
fprintf(this->out, "List of X.509 End Entity Certificates:\n");
fprintf(this->out, "--------------------------------------\n");
}
while (iterator->iterate(iterator, (void**)&cert))
{
fprintf(this->out, "%#Q", cert, msg->list.utc);
if (charon->credentials->has_rsa_private_key(
charon->credentials, cert->get_public_key(cert)))
{
fprintf(this->out, ", has private key");
}
fprintf(this->out, "\n\n");
}
iterator->destroy(iterator);
} }
if (msg->list.flags & LIST_CACERTS) if (msg->list.flags & LIST_CACERTS)
{ {
charon->credentials->log_ca_certificates(charon->credentials, this->stroke_logger, msg->list.utc); x509_t *cert;
iterator = charon->credentials->create_cacert_iterator(charon->credentials);
if (iterator->get_count(iterator))
{
fprintf(this->out, "List of X.509 CA Certificates:\n");
fprintf(this->out, "------------------------------\n");
}
while (iterator->iterate(iterator, (void**)&cert))
{
fprintf(this->out, "%#Q\n\n", cert, msg->list.utc);
}
iterator->destroy(iterator);
} }
if (msg->list.flags & LIST_CRLS) if (msg->list.flags & LIST_CRLS)
{ {
charon->credentials->log_crls(charon->credentials, this->stroke_logger, msg->list.utc); crl_t *crl;
iterator = charon->credentials->create_crl_iterator(charon->credentials);
if (iterator->get_count(iterator))
{
fprintf(this->out, "List of X.509 CRLs:\n");
fprintf(this->out, "-------------------\n");
}
while (iterator->iterate(iterator, (void**)&crl))
{
fprintf(this->out, "%#U\n\n", crl, msg->list.utc);
}
iterator->destroy(iterator);
} }
} }
@@ -680,107 +822,41 @@ static void stroke_reread(private_stroke_t *this, stroke_msg_t *msg)
} }
} }
logger_context_t get_context(char *context) signal_t get_signal_from_logtype(char *type)
{ {
if (strcasecmp(context, "ALL") == 0) return ALL_LOGGERS; if (strcasecmp(type, "any") == 0) return SIG_ANY;
else if (strcasecmp(context, "PARSR") == 0) return PARSER; else if (strcasecmp(type, "mgr") == 0) return SIG_DBG_MGR;
else if (strcasecmp(context, "GNRAT") == 0) return GENERATOR; else if (strcasecmp(type, "ike") == 0) return SIG_DBG_IKE;
else if (strcasecmp(context, "IKESA") == 0) return IKE_SA; else if (strcasecmp(type, "chd") == 0) return SIG_DBG_CHD;
else if (strcasecmp(context, "SAMGR") == 0) return IKE_SA_MANAGER; else if (strcasecmp(type, "job") == 0) return SIG_DBG_JOB;
else if (strcasecmp(context, "CHDSA") == 0) return CHILD_SA; else if (strcasecmp(type, "cfg") == 0) return SIG_DBG_CFG;
else if (strcasecmp(context, "MESSG") == 0) return MESSAGE; else if (strcasecmp(type, "knl") == 0) return SIG_DBG_KNL;
else if (strcasecmp(context, "TPOOL") == 0) return THREAD_POOL; else if (strcasecmp(type, "net") == 0) return SIG_DBG_NET;
else if (strcasecmp(context, "WORKR") == 0) return WORKER; else if (strcasecmp(type, "enc") == 0) return SIG_DBG_ENC;
else if (strcasecmp(context, "SCHED") == 0) return SCHEDULER; else if (strcasecmp(type, "lib") == 0) return SIG_DBG_LIB;
else if (strcasecmp(context, "SENDR") == 0) return SENDER; else return -1;
else if (strcasecmp(context, "RECVR") == 0) return RECEIVER;
else if (strcasecmp(context, "SOCKT") == 0) return SOCKET;
else if (strcasecmp(context, "TESTR") == 0) return TESTER;
else if (strcasecmp(context, "DAEMN") == 0) return DAEMON;
else if (strcasecmp(context, "CONFG") == 0) return CONFIG;
else if (strcasecmp(context, "ENCPL") == 0) return ENCRYPTION_PAYLOAD;
else if (strcasecmp(context, "PAYLD") == 0) return PAYLOAD;
else if (strcasecmp(context, "XFRM") == 0) return XFRM;
else return -2;
} }
/** /**
* set the type of logged messages in a context * set the verbosity debug output
*/
static void stroke_logtype(private_stroke_t *this, stroke_msg_t *msg)
{
pop_string(msg, &(msg->logtype.context));
pop_string(msg, &(msg->logtype.type));
this->logger->log(this->logger, CONTROL, "received stroke: logtype for %s", msg->logtype.context);
log_level_t level;
logger_context_t context = get_context(msg->logtype.context);
if (context == -2)
{
this->stroke_logger->log(this->stroke_logger, ERROR, "invalid context (%s)!", msg->logtype.context);
return;
}
if (strcasecmp(msg->logtype.type, "CONTROL") == 0)
level = CONTROL;
else if (strcasecmp(msg->logtype.type, "ERROR") == 0)
level = ERROR;
else if (strcasecmp(msg->logtype.type, "AUDIT") == 0)
level = AUDIT;
else if (strcasecmp(msg->logtype.type, "RAW") == 0)
level = RAW;
else if (strcasecmp(msg->logtype.type, "PRIVATE") == 0)
level = PRIVATE;
else
{
this->stroke_logger->log(this->stroke_logger, ERROR, "invalid type (%s)!", msg->logtype.type);
return;
}
if (msg->logtype.enable)
{
logger_manager->enable_log_level(logger_manager, context, level);
}
else
{
logger_manager->disable_log_level(logger_manager, context, level);
}
}
/**
* set the verbosity of a logger
*/ */
static void stroke_loglevel(private_stroke_t *this, stroke_msg_t *msg) static void stroke_loglevel(private_stroke_t *this, stroke_msg_t *msg)
{ {
log_level_t level; signal_t signal;
logger_context_t context;
pop_string(msg, &(msg->loglevel.context));
this->logger->log(this->logger, CONTROL, "received stroke: loglevel for %s", msg->loglevel.context);
context = get_context(msg->loglevel.context); pop_string(msg, &(msg->loglevel.type));
if (context == -2) DBG1(SIG_DBG_CFG, "received stroke: loglevel %d for %s",
msg->loglevel.level, msg->loglevel.type);
signal = get_signal_from_logtype(msg->loglevel.type);
if (signal < 0)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, "invalid context (%s)!", msg->loglevel.context); fprintf(this->out, "invalid type (%s)!\n", msg->loglevel.type);
return; return;
} }
if (msg->loglevel.level == 0) charon->outlog->set_level(charon->outlog, signal, msg->loglevel.level);
level = LEVEL0; charon->syslog->set_level(charon->syslog, signal, msg->loglevel.level);
else if (msg->loglevel.level == 1)
level = LEVEL1;
else if (msg->loglevel.level == 2)
level = LEVEL2;
else if (msg->loglevel.level == 3)
level = LEVEL3;
else
{
this->stroke_logger->log(this->stroke_logger, ERROR, "invalid level (%d)!", msg->loglevel.level);
return;
}
logger_manager->enable_log_level(logger_manager, context, level);
} }
/** /**
@@ -794,7 +870,6 @@ static void stroke_receive(private_stroke_t *this)
int strokeaddrlen = sizeof(strokeaddr); int strokeaddrlen = sizeof(strokeaddr);
ssize_t bytes_read; ssize_t bytes_read;
int strokefd; int strokefd;
FILE *strokefile;
int oldstate; int oldstate;
/* disable cancellation by default */ /* disable cancellation by default */
@@ -809,7 +884,7 @@ static void stroke_receive(private_stroke_t *this)
if (strokefd < 0) if (strokefd < 0)
{ {
this->logger->log(this->logger, ERROR, "accepting stroke connection failed: %s", strerror(errno)); DBG1(SIG_DBG_CFG, "accepting stroke connection failed: %m");
continue; continue;
} }
@@ -817,7 +892,7 @@ static void stroke_receive(private_stroke_t *this)
bytes_read = recv(strokefd, &msg_length, sizeof(msg_length), MSG_PEEK); bytes_read = recv(strokefd, &msg_length, sizeof(msg_length), MSG_PEEK);
if (bytes_read != sizeof(msg_length)) if (bytes_read != sizeof(msg_length))
{ {
this->logger->log(this->logger, ERROR, "reading lenght of stroke message failed"); DBG1(SIG_DBG_CFG, "reading lenght of stroke message failed");
close(strokefd); close(strokefd);
continue; continue;
} }
@@ -827,24 +902,21 @@ static void stroke_receive(private_stroke_t *this)
bytes_read = recv(strokefd, msg, msg_length, 0); bytes_read = recv(strokefd, msg, msg_length, 0);
if (bytes_read != msg_length) if (bytes_read != msg_length)
{ {
this->logger->log(this->logger, ERROR, "reading stroke message failed: %s"); DBG1(SIG_DBG_CFG, "reading stroke message failed: %m");
close(strokefd); close(strokefd);
continue; continue;
} }
strokefile = fdopen(dup(strokefd), "w"); this->out = fdopen(dup(strokefd), "w");
if (strokefile == NULL) if (this->out == NULL)
{ {
this->logger->log(this->logger, ERROR, "opening stroke output channel failed:", strerror(errno)); DBG1(SIG_DBG_CFG, "opening stroke output channel failed: %m");
close(strokefd); close(strokefd);
free(msg); free(msg);
continue; continue;
} }
/* setup a logger which writes status to the unix socket */ DBG3(SIG_DBG_CFG, "stroke message %b", (void*)msg, msg_length);
this->stroke_logger = logger_create("", CONTROL|ERROR, FALSE, strokefile);
this->logger->log_bytes(this->logger, RAW, "stroke message", (void*)msg, msg_length);
switch (msg->type) switch (msg->type)
{ {
@@ -864,8 +936,7 @@ static void stroke_receive(private_stroke_t *this)
stroke_status(this, msg); stroke_status(this, msg);
break; break;
case STR_STATUS_ALL: case STR_STATUS_ALL:
this->stroke_logger->enable_level(this->stroke_logger, LEVEL1); stroke_statusall(this, msg);
stroke_status(this, msg);
break; break;
case STR_ADD_CONN: case STR_ADD_CONN:
stroke_add_conn(this, msg); stroke_add_conn(this, msg);
@@ -873,9 +944,6 @@ static void stroke_receive(private_stroke_t *this)
case STR_DEL_CONN: case STR_DEL_CONN:
stroke_del_conn(this, msg); stroke_del_conn(this, msg);
break; break;
case STR_LOGTYPE:
stroke_logtype(this, msg);
break;
case STR_LOGLEVEL: case STR_LOGLEVEL:
stroke_loglevel(this, msg); stroke_loglevel(this, msg);
break; break;
@@ -886,10 +954,9 @@ static void stroke_receive(private_stroke_t *this)
stroke_reread(this, msg); stroke_reread(this, msg);
break; break;
default: default:
this->logger->log(this->logger, ERROR, "received invalid stroke"); DBG1(SIG_DBG_CFG, "received unknown stroke");
} }
this->stroke_logger->destroy(this->stroke_logger); fclose(this->out);
fclose(strokefile);
close(strokefd); close(strokefd);
free(msg); free(msg);
} }
@@ -900,7 +967,6 @@ static void stroke_receive(private_stroke_t *this)
*/ */
static void destroy(private_stroke_t *this) static void destroy(private_stroke_t *this)
{ {
pthread_cancel(this->assigned_thread); pthread_cancel(this->assigned_thread);
pthread_join(this->assigned_thread, NULL); pthread_join(this->assigned_thread, NULL);
@@ -909,7 +975,6 @@ static void destroy(private_stroke_t *this)
free(this); free(this);
} }
/* /*
* Described in header-file * Described in header-file
*/ */
@@ -921,16 +986,11 @@ stroke_t *stroke_create()
/* public functions */ /* public functions */
this->public.destroy = (void (*)(stroke_t*))destroy; this->public.destroy = (void (*)(stroke_t*))destroy;
/* private functions */
this->stroke_receive = stroke_receive;
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
/* set up unix socket */ /* set up unix socket */
this->socket = socket(AF_UNIX, SOCK_STREAM, 0); this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
if (this->socket == -1) if (this->socket == -1)
{ {
this->logger->log(this->logger, ERROR, "could not create whack socket"); DBG1(SIG_DBG_CFG, "could not create whack socket");
free(this); free(this);
return NULL; return NULL;
} }
@@ -938,7 +998,7 @@ stroke_t *stroke_create()
old = umask(~S_IRWXU); old = umask(~S_IRWXU);
if (bind(this->socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr)) < 0) if (bind(this->socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr)) < 0)
{ {
this->logger->log(this->logger, ERROR, "could not bind stroke socket: %s", strerror(errno)); DBG1(SIG_DBG_CFG, "could not bind stroke socket: %m");
close(this->socket); close(this->socket);
free(this); free(this);
return NULL; return NULL;
@@ -947,7 +1007,7 @@ stroke_t *stroke_create()
if (listen(this->socket, 0) < 0) if (listen(this->socket, 0) < 0)
{ {
this->logger->log(this->logger, ERROR, "could not listen on stroke socket: %s", strerror(errno)); DBG1(SIG_DBG_CFG, "could not listen on stroke socket: %m");
close(this->socket); close(this->socket);
unlink(socket_addr.sun_path); unlink(socket_addr.sun_path);
free(this); free(this);
@@ -955,9 +1015,9 @@ stroke_t *stroke_create()
} }
/* start a thread reading from the socket */ /* start a thread reading from the socket */
if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))this->stroke_receive, this) != 0) if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))stroke_receive, this) != 0)
{ {
this->logger->log(this->logger, ERROR, "Could not spawn stroke thread"); DBG1(SIG_DBG_CFG, "Could not spawn stroke thread");
close(this->socket); close(this->socket);
unlink(socket_addr.sun_path); unlink(socket_addr.sun_path);
free(this); free(this);
+1 -14
View File
@@ -23,9 +23,6 @@
#ifndef STROKE_INTERFACE_H_ #ifndef STROKE_INTERFACE_H_
#define STROKE_INTERFACE_H_ #define STROKE_INTERFACE_H_
#include <config/policies/policy_store.h>
#include <config/connections/connection_store.h>
#include <config/credentials/credential_store.h>
typedef struct stroke_t stroke_t; typedef struct stroke_t stroke_t;
@@ -36,17 +33,7 @@ typedef struct stroke_t stroke_t;
* *
* stroke_t allows config manipulation (as whack in pluto). * stroke_t allows config manipulation (as whack in pluto).
* Messages of type stroke_msg_t's are sent over a unix socket * Messages of type stroke_msg_t's are sent over a unix socket
* (/var/run/charon.ctl). stroke_t implements the connections_t * (/var/run/charon.ctl).
* and the policies_t interface, which means it acts as a
* configuration backend for those too. stroke_t uses an own
* thread to read from the socket.
*
* @warning DO NOT cast stroke_t to any of the implemented interfaces!
* stroke_t implements multiple interfaces, so you must use
* stroke_t.interface_xy to access the specific interface! You have
* been warned...
*
* @todo Add clean thread cancellation
* *
* @b Constructors: * @b Constructors:
* - stroke_create() * - stroke_create()
+36 -33
View File
@@ -27,10 +27,9 @@
#include <errno.h> #include <errno.h>
#include "thread_pool.h" #include "thread_pool.h"
#include <daemon.h> #include <daemon.h>
#include <queues/job_queue.h> #include <queues/job_queue.h>
#include <utils/logger.h>
typedef struct private_thread_pool_t private_thread_pool_t; typedef struct private_thread_pool_t private_thread_pool_t;
@@ -47,17 +46,17 @@ struct private_thread_pool_t {
/** /**
* Number of running threads. * Number of running threads.
*/ */
size_t pool_size; u_int pool_size;
/**
* Number of threads waiting for work
*/
u_int idle_threads;
/** /**
* Array of thread ids. * Array of thread ids.
*/ */
pthread_t *threads; pthread_t *threads;
/**
* Logger of the thread pool.
*/
logger_t *logger;
} ; } ;
/** /**
@@ -71,13 +70,14 @@ static void process_jobs(private_thread_pool_t *this)
/* cancellation disabled by default */ /* cancellation disabled by default */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_JOB, "worker thread running, thread_ID: %06u",
"worker thread running, thread_ID: %06u", (int)pthread_self());
(int)pthread_self());
while (TRUE) while (TRUE)
{ {
this->idle_threads++;
job = charon->job_queue->get(charon->job_queue); job = charon->job_queue->get(charon->job_queue);
this->idle_threads--;
status = job->execute(job); status = job->execute(job);
@@ -91,11 +91,19 @@ static void process_jobs(private_thread_pool_t *this)
/** /**
* Implementation of thread_pool_t.get_pool_size. * Implementation of thread_pool_t.get_pool_size.
*/ */
static size_t get_pool_size(private_thread_pool_t *this) static u_int get_pool_size(private_thread_pool_t *this)
{ {
return this->pool_size; return this->pool_size;
} }
/**
* Implementation of thread_pool_t.get_idle_threads.
*/
static u_int get_idle_threads(private_thread_pool_t *this)
{
return this->idle_threads;
}
/** /**
* Implementation of thread_pool_t.destroy. * Implementation of thread_pool_t.destroy.
*/ */
@@ -103,9 +111,9 @@ static void destroy(private_thread_pool_t *this)
{ {
int current; int current;
/* flag thread for termination */ /* flag thread for termination */
for (current = 0; current < this->pool_size; current++) { for (current = 0; current < this->pool_size; current++)
this->logger->log(this->logger, CONTROL, {
"cancelling worker thread #%d", current+1); DBG1(SIG_DBG_JOB, "cancelling worker thread #%d", current+1);
pthread_cancel(this->threads[current]); pthread_cancel(this->threads[current]);
} }
@@ -113,13 +121,11 @@ static void destroy(private_thread_pool_t *this)
for (current = 0; current < this->pool_size; current++) { for (current = 0; current < this->pool_size; current++) {
if (pthread_join(this->threads[current], NULL) == 0) if (pthread_join(this->threads[current], NULL) == 0)
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_JOB, "worker thread #%d terminated", current+1);
"worker thread #%d terminated", current+1);
} }
else else
{ {
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_JOB, "could not terminate worker thread #%d", current+1);
"could not terminate worker thread #%d", current+1);
} }
} }
@@ -138,39 +144,36 @@ thread_pool_t *thread_pool_create(size_t pool_size)
/* fill in public fields */ /* fill in public fields */
this->public.destroy = (void(*)(thread_pool_t*))destroy; this->public.destroy = (void(*)(thread_pool_t*))destroy;
this->public.get_pool_size = (size_t(*)(thread_pool_t*))get_pool_size; this->public.get_pool_size = (u_int(*)(thread_pool_t*))get_pool_size;
this->public.get_idle_threads = (u_int(*)(thread_pool_t*))get_idle_threads;
/* initialize member */ /* initialize member */
this->pool_size = pool_size; this->pool_size = pool_size;
this->idle_threads = 0;
this->threads = malloc(sizeof(pthread_t) * pool_size); this->threads = malloc(sizeof(pthread_t) * pool_size);
this->logger = logger_manager->get_logger(logger_manager, THREAD_POOL);
/* try to create as many threads as possible, up to pool_size */ /* try to create as many threads as possible, up to pool_size */
for (current = 0; current < pool_size; current++) for (current = 0; current < pool_size; current++)
{ {
if (pthread_create(&(this->threads[current]), NULL, if (pthread_create(&(this->threads[current]), NULL,
(void*(*)(void*))process_jobs, this) == 0) (void*(*)(void*))process_jobs, this) == 0)
{ {
this->logger->log(this->logger, CONTROL, DBG1(SIG_DBG_JOB, "created worker thread #%d", current+1);
"created worker thread #%d", current+1);
} }
else else
{ {
/* creation failed, is it the first one? */ /* creation failed, is it the first one? */
if (current == 0) if (current == 0)
{ {
this->logger->log(this->logger, ERROR, "Could not create any thread");
free(this->threads); free(this->threads);
free(this); free(this);
return NULL; charon->kill(charon, "could not create any worker threads");
} }
/* not all threads could be created, but at least one :-/ */ /* not all threads could be created, but at least one :-/ */
this->logger->log(this->logger, ERROR, DBG1(SIG_DBG_JOB, "could only create %d from requested %d threads!",
"Could only create %d from requested %d threads!", current, pool_size);
current, pool_size);
this->pool_size = current; this->pool_size = current;
return (thread_pool_t*)this; break;
} }
} }
return (thread_pool_t*)this; return (thread_pool_t*)this;
+11 -2
View File
@@ -45,13 +45,22 @@ typedef struct thread_pool_t thread_pool_t;
* @ingroup threads * @ingroup threads
*/ */
struct thread_pool_t { struct thread_pool_t {
/** /**
* @brief Return currently instanciated thread count. * @brief Return currently instanciated thread count.
* *
* @param thread_pool calling object * @param thread_pool calling object
* @return size of thread pool * @return size of thread pool
*/ */
size_t (*get_pool_size) (thread_pool_t *thread_pool); u_int (*get_pool_size) (thread_pool_t *thread_pool);
/**
* @brief Get the number of threads currently waiting for work.
*
* @param thread_pool calling object
* @return number of idle threads
*/
u_int (*get_idle_threads) (thread_pool_t *thread_pool);
/** /**
* @brief Destroy a thread_pool_t object. * @brief Destroy a thread_pool_t object.
+1 -4
View File
@@ -30,12 +30,9 @@ crypto/diffie_hellman.c crypto/diffie_hellman.h \
utils/identification.c utils/identification.h \ utils/identification.c utils/identification.h \
utils/linked_list.c utils/linked_list.h utils/iterator.h\ utils/linked_list.c utils/linked_list.h utils/iterator.h\
utils/randomizer.c utils/randomizer.h \ utils/randomizer.c utils/randomizer.h \
utils/logger.c utils/logger.h \
utils/logger_manager.c utils/logger_manager.h \
utils/host.c utils/host.h \ utils/host.c utils/host.h \
utils/lexparser.c utils/lexparser.h \ utils/lexparser.c utils/lexparser.h \
utils/leak_detective.c utils/leak_detective.h \ utils/leak_detective.c utils/leak_detective.h
utils/tester.c utils/tester.h
libstrongswan_la_LIBADD = -lgmp -lpthread libstrongswan_la_LIBADD = -lgmp -lpthread
+29 -49
View File
@@ -13,14 +13,14 @@
* for more details. * for more details.
*/ */
#include <stdlib.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include "types.h"
#include "asn1.h" #include "asn1.h"
#include <utils/logger_manager.h> #include <types.h>
#include <library.h>
/* some common prefabricated ASN.1 constants */ /* some common prefabricated ASN.1 constants */
static u_char ASN1_INTEGER_0_str[] = { 0x02, 0x00 }; static u_char ASN1_INTEGER_0_str[] = { 0x02, 0x00 };
@@ -80,17 +80,6 @@ static const asn1Object_t algorithmIdentifierObjects[] = {
#define ALGORITHM_ID_PARAMETERS 2 #define ALGORITHM_ID_PARAMETERS 2
#define ALGORITHM_ID_ROOF 3 #define ALGORITHM_ID_ROOF 3
static logger_t *logger = NULL;
/**
* initializes the ASN.1 logger
*/
static void asn1_init_logger(void)
{
if (logger == NULL)
logger = logger_manager->get_logger(logger_manager, ASN1);
}
/** /**
* return the ASN.1 encoded algorithm identifier * return the ASN.1 encoded algorithm identifier
*/ */
@@ -171,14 +160,14 @@ u_int asn1_length(chunk_t *blob)
if (n > blob->len) if (n > blob->len)
{ {
logger->log(logger, ERROR|LEVEL1, "number of length octets is larger than ASN.1 object"); DBG2("number of length octets is larger than ASN.1 object");
return ASN1_INVALID_LENGTH; return ASN1_INVALID_LENGTH;
} }
if (n > sizeof(len)) if (n > sizeof(len))
{ {
logger->log(logger, ERROR|LEVEL1, "number of length octets is larger than limit of %d octets", DBG2("number of length octets is larger than limit of %d octets",
(int)sizeof(len)); (int)sizeof(len));
return ASN1_INVALID_LENGTH; return ASN1_INVALID_LENGTH;
} }
@@ -289,8 +278,6 @@ time_t asn1totime(const chunk_t *utctime, asn1_t type)
*/ */
void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit) void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit)
{ {
asn1_init_logger();
ctx->blobs[0] = blob; ctx->blobs[0] = blob;
ctx->level0 = level0; ctx->level0 = level0;
ctx->implicit = implicit; ctx->implicit = implicit;
@@ -310,7 +297,7 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type)
oid = known_oid(object); oid = known_oid(object);
if (oid != OID_UNKNOWN) if (oid != OID_UNKNOWN)
{ {
logger->log(logger, CONTROL|LEVEL2, " '%s'", oid_names[oid].name); DBG2(" '%s'", oid_names[oid].name);
return; return;
} }
break; break;
@@ -319,22 +306,18 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type)
case ASN1_PRINTABLESTRING: case ASN1_PRINTABLESTRING:
case ASN1_T61STRING: case ASN1_T61STRING:
case ASN1_VISIBLESTRING: case ASN1_VISIBLESTRING:
logger->log(logger, CONTROL|LEVEL2, " '%.*s'", (int)object.len, object.ptr); DBG2(" '%.*s'", (int)object.len, object.ptr);
return; return;
case ASN1_UTCTIME: case ASN1_UTCTIME:
case ASN1_GENERALIZEDTIME: case ASN1_GENERALIZEDTIME:
{ {
char buf[TIMETOA_BUF]; DBG2(" '%T'", asn1totime(&object, type));
time_t time = asn1totime(&object, type);
timetoa(buf, TIMETOA_BUF, &time, TRUE);
logger->log(logger, CONTROL|LEVEL2, " '%s'", buf);
} }
return; return;
default: default:
break; break;
} }
logger->log_chunk(logger, RAW|LEVEL1, "", object); DBG3("%B", &object);
} }
/** /**
@@ -372,7 +355,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
if ((obj.flags & ASN1_DEF) && (blob->len == 0 || *start_ptr != obj.type) ) if ((obj.flags & ASN1_DEF) && (blob->len == 0 || *start_ptr != obj.type) )
{ {
/* field is missing */ /* field is missing */
logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", *level, obj.name); DBG2("L%d - %s:", *level, obj.name);
if (obj.type & ASN1_CONSTRUCTED) if (obj.type & ASN1_CONSTRUCTED)
{ {
(*objectID)++ ; /* skip context-specific tag */ (*objectID)++ ; /* skip context-specific tag */
@@ -397,7 +380,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
if (blob->len < 2) if (blob->len < 2)
{ {
logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN.1 object smaller than 2 octets", DBG2("L%d - %s: ASN.1 object smaller than 2 octets",
*level, obj.name); *level, obj.name);
return FALSE; return FALSE;
} }
@@ -406,7 +389,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len) if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len)
{ {
logger->log(logger, ERROR|LEVEL1, "L%d - %s: length of ASN.1 object invalid or too large", DBG2("L%d - %s: length of ASN.1 object invalid or too large",
*level, obj.name); *level, obj.name);
return FALSE; return FALSE;
} }
@@ -419,7 +402,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
if (obj.flags & ASN1_RAW) if (obj.flags & ASN1_RAW)
{ {
logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", *level, obj.name); DBG2("L%d - %s:", *level, obj.name);
object->ptr = start_ptr; object->ptr = start_ptr;
object->len = (size_t)(blob->ptr - start_ptr); object->len = (size_t)(blob->ptr - start_ptr);
return TRUE; return TRUE;
@@ -427,13 +410,13 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
if (*start_ptr != obj.type && !(ctx->implicit && *objectID == 0)) if (*start_ptr != obj.type && !(ctx->implicit && *objectID == 0))
{ {
logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x", DBG1("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
*level, obj.name, obj.type, *start_ptr); *level, obj.name, obj.type, *start_ptr);
logger->log_bytes(logger, RAW|LEVEL1, "", start_ptr, (u_int)(blob->ptr - start_ptr)); DBG3("%b", start_ptr, (u_int)(blob->ptr - start_ptr));
return FALSE; return FALSE;
} }
logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", ctx->level0+obj.level, obj.name); DBG2("L%d - %s:", ctx->level0+obj.level, obj.name);
/* In case of "SEQUENCE OF" or "SET OF" start a loop */ /* In case of "SEQUENCE OF" or "SET OF" start a loop */
if (obj.flags & ASN1_LOOP) if (obj.flags & ASN1_LOOP)
@@ -458,7 +441,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
{ {
object->ptr = start_ptr; object->ptr = start_ptr;
object->len = (size_t)(blob->ptr - start_ptr); object->len = (size_t)(blob->ptr - start_ptr);
logger->log_chunk(logger, RAW|LEVEL2, "", *object); DBG3("%B", object);
} }
else if (obj.flags & ASN1_BODY) else if (obj.flags & ASN1_BODY)
{ {
@@ -478,15 +461,14 @@ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const c
/* an ASN.1 object must possess at least a tag and length field */ /* an ASN.1 object must possess at least a tag and length field */
if (object->len < 2) if (object->len < 2)
{ {
logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN.1 object smaller than 2 octets", DBG2("L%d - %s: ASN.1 object smaller than 2 octets", level, name);
level, name);
return FALSE; return FALSE;
} }
if (*object->ptr != type) if (*object->ptr != type)
{ {
logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x", DBG2("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
level, name, type, *object->ptr); level, name, type, *object->ptr);
return FALSE; return FALSE;
} }
@@ -494,12 +476,12 @@ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const c
if (len == ASN1_INVALID_LENGTH || object->len < len) if (len == ASN1_INVALID_LENGTH || object->len < len)
{ {
logger->log(logger, ERROR|LEVEL1, "L%d - %s: length of ASN.1 object invalid or too large", DBG2("L%d - %s: length of ASN.1 object invalid or too large",
level, name); level, name);
return FALSE; return FALSE;
} }
logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", level, name); DBG2("L%d - %s:", level, name);
debug_asn1_simple_object(*object, type); debug_asn1_simple_object(*object, type);
return TRUE; return TRUE;
} }
@@ -546,18 +528,16 @@ bool is_asn1(chunk_t blob)
{ {
u_int len; u_int len;
u_char tag = *blob.ptr; u_char tag = *blob.ptr;
asn1_init_logger();
if (tag != ASN1_SEQUENCE && tag != ASN1_SET) if (tag != ASN1_SEQUENCE && tag != ASN1_SET)
{ {
logger->log(logger, ERROR|LEVEL2, " file content is not binary ASN.1"); DBG2(" file content is not binary ASN.1");
return FALSE; return FALSE;
} }
len = asn1_length(&blob); len = asn1_length(&blob);
if (len != blob.len) if (len != blob.len)
{ {
logger->log(logger, ERROR|LEVEL2, " file size does not match ASN.1 coded length"); DBG2(" file size does not match ASN.1 coded length");
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@@ -708,7 +688,7 @@ chunk_t timetoasn1(const time_t *time, asn1_t type)
{ {
int offset; int offset;
const char *format; const char *format;
char buf[TIMETOA_BUF]; char buf[32];
chunk_t formatted_time; chunk_t formatted_time;
struct tm *t = gmtime(time); struct tm *t = gmtime(time);
@@ -722,8 +702,8 @@ chunk_t timetoasn1(const time_t *time, asn1_t type)
format = "%02d%02d%02d%02d%02d%02dZ"; format = "%02d%02d%02d%02d%02d%02dZ";
offset = (t->tm_year < 100)? 0 : -100; offset = (t->tm_year < 100)? 0 : -100;
} }
sprintf(buf, format, t->tm_year + offset, t->tm_mon + 1, t->tm_mday snprintf(buf, sizeof(buf), format, t->tm_year + offset,
, t->tm_hour, t->tm_min, t->tm_sec); t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
formatted_time.ptr = buf; formatted_time.ptr = buf;
formatted_time.len = strlen(buf); formatted_time.len = strlen(buf);
return asn1_simple_object(type, formatted_time); return asn1_simple_object(type, formatted_time);
+14 -30
View File
@@ -20,28 +20,18 @@
#include <stddef.h> #include <stddef.h>
#include <sys/types.h> #include <sys/types.h>
#include "asn1.h"
#include "pem.h" #include "pem.h"
#include "ttodata.h"
#include <library.h>
#include <asn1/asn1.h>
#include <asn1/ttodata.h>
#include <utils/lexparser.h> #include <utils/lexparser.h>
#include <utils/logger_manager.h>
#include <crypto/hashers/hasher.h> #include <crypto/hashers/hasher.h>
#include <crypto/crypters/crypter.h> #include <crypto/crypters/crypter.h>
#define PKCS5_SALT_LEN 8 /* bytes */ #define PKCS5_SALT_LEN 8 /* bytes */
static logger_t *logger = NULL;
/**
* initializes the PEM logger
*/
static void pem_init_logger(void)
{
if (logger == NULL)
logger = logger_manager->get_logger(logger_manager, ASN1);
}
/** /**
* check the presence of a pattern in a character string * check the presence of a pattern in a character string
*/ */
@@ -79,8 +69,7 @@ static bool find_boundary(const char* tag, chunk_t *line)
{ {
if (present("-----", line)) if (present("-----", line))
{ {
logger->log(logger, CONTROL|LEVEL2, DBG2(" -----%s %.*s-----", tag, (int)name.len, name.ptr);
" -----%s %.*s-----", tag, (int)name.len, name.ptr);
return TRUE; return TRUE;
} }
line->ptr++; line->len--; name.len++; line->ptr++; line->len--; name.len++;
@@ -185,8 +174,6 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
iv.ptr = iv_buf; iv.ptr = iv_buf;
iv.len = 0; iv.len = 0;
pem_init_logger();
while (fetchline(&src, &line)) while (fetchline(&src, &line))
{ {
if (state == PEM_PRE) if (state == PEM_PRE)
@@ -222,7 +209,7 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
} }
/* we are looking for a parameter: value pair */ /* we are looking for a parameter: value pair */
logger->log(logger, CONTROL|LEVEL2, " %.*s", (int)line.len, line.ptr); DBG2(" %.*s", (int)line.len, line.ptr);
ugh = extract_parameter_value(&name, &value, &line); ugh = extract_parameter_value(&name, &value, &line);
if (ugh != NULL) if (ugh != NULL)
continue; continue;
@@ -289,8 +276,7 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
*pgp = TRUE; *pgp = TRUE;
data.ptr++; data.ptr++;
data.len--; data.len--;
logger->log(logger, CONTROL|LEVEL2, " Armor checksum: %.*s", DBG2(" Armor checksum: %.*s", (int)data.len, data.ptr);
(int)data.len, data.ptr);
continue; continue;
} }
@@ -327,8 +313,6 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
FILE *fd = fopen(filename, "r"); FILE *fd = fopen(filename, "r");
pem_init_logger();
if (fd) if (fd)
{ {
int bytes; int bytes;
@@ -338,19 +322,19 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
blob->ptr = malloc(blob->len); blob->ptr = malloc(blob->len);
bytes = fread(blob->ptr, 1, blob->len, fd); bytes = fread(blob->ptr, 1, blob->len, fd);
fclose(fd); fclose(fd);
logger->log(logger, CONTROL, " loading %s file '%s' (%d bytes)", type, filename, bytes); DBG1(" loading %s file '%s' (%d bytes)", type, filename, bytes);
*pgp = FALSE; *pgp = FALSE;
/* try DER format */ /* try DER format */
if (is_asn1(*blob)) if (is_asn1(*blob))
{ {
logger->log(logger, CONTROL|LEVEL1, " file coded in DER format"); DBG2(" file coded in DER format");
return TRUE; return TRUE;
} }
if (passphrase != NULL) if (passphrase != NULL)
logger->log_bytes(logger, PRIVATE, " passphrase:", passphrase->ptr, passphrase->len); DBG4(" passphrase:", passphrase->ptr, passphrase->len);
/* try PEM format */ /* try PEM format */
ugh = pem_to_bin(blob, passphrase, pgp); ugh = pem_to_bin(blob, passphrase, pgp);
@@ -359,24 +343,24 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
{ {
if (*pgp) if (*pgp)
{ {
logger->log(logger, CONTROL|LEVEL1, " file coded in armored PGP format"); DBG2(" file coded in armored PGP format");
return TRUE; return TRUE;
} }
if (is_asn1(*blob)) if (is_asn1(*blob))
{ {
logger->log(logger, CONTROL|LEVEL1, " file coded in PEM format"); DBG2(" file coded in PEM format");
return TRUE; return TRUE;
} }
ugh = "file coded in unknown format, discarded"; ugh = "file coded in unknown format, discarded";
} }
/* a conversion error has occured */ /* a conversion error has occured */
logger->log(logger, ERROR, " %s", ugh); DBG1(" %s", ugh);
chunk_free(blob); chunk_free(blob);
} }
else else
{ {
logger->log(logger, ERROR, " could not open %s file '%s'", type, filename); DBG1(" could not open %s file '%s'", type, filename);
} }
return FALSE; return FALSE;
} }
+9 -21
View File
@@ -69,24 +69,15 @@ struct private_certinfo_t {
crl_reason_t revocationReason; crl_reason_t revocationReason;
}; };
/** ENUM(cert_status_names, CERT_GOOD, CERT_UNTRUSTED,
* RFC 2560 OCSP - certificate status
*/
static const char *const cert_status_name[] = {
"good", "good",
"revoked", "revoked",
"unknown", "unknown",
"unknown", "unknown",
"untrusted" "untrusted",
}; );
enum_names cert_status_names = ENUM(crl_reason_names, REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL,
{ CERT_GOOD, CERT_UNTRUSTED, cert_status_name, NULL};
/**
* RFC 2459 CRL reason codes
*/
static const char *const crl_reason_name[] = {
"unspecified", "unspecified",
"key compromise", "key compromise",
"ca compromise", "ca compromise",
@@ -95,11 +86,8 @@ static const char *const crl_reason_name[] = {
"cessation of operation", "cessation of operation",
"certificate hold", "certificate hold",
"reason #7", "reason #7",
"remove from crl" "remove from crl",
}; );
enum_names crl_reason_names =
{ REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL, crl_reason_name, NULL};
/** /**
* Implements certinfo_t.get_serialNumber * Implements certinfo_t.get_serialNumber
@@ -168,9 +156,9 @@ static void set_revocationReason(private_certinfo_t *this, crl_reason_t reason)
/** /**
* Implements certinfo_t.get_revocationReason * Implements certinfo_t.get_revocationReason
*/ */
static const char *get_revocationReason(const private_certinfo_t *this) static crl_reason_t get_revocationReason(const private_certinfo_t *this)
{ {
return enum_name(&crl_reason_names, this->revocationReason); return this->revocationReason;
} }
/** /**
@@ -205,7 +193,7 @@ certinfo_t *certinfo_create(chunk_t serial)
this->public.set_revocationTime = (void (*) (certinfo_t*,time_t))set_revocationTime; this->public.set_revocationTime = (void (*) (certinfo_t*,time_t))set_revocationTime;
this->public.get_revocationTime = (time_t (*) (const certinfo_t*))get_revocationTime; this->public.get_revocationTime = (time_t (*) (const certinfo_t*))get_revocationTime;
this->public.set_revocationReason = (void (*) (certinfo_t*, crl_reason_t))set_revocationReason; this->public.set_revocationReason = (void (*) (certinfo_t*, crl_reason_t))set_revocationReason;
this->public.get_revocationReason = (const char *(*) (const certinfo_t*))get_revocationReason; this->public.get_revocationReason = (crl_reason_t(*) (const certinfo_t*))get_revocationReason;
this->public.destroy = (void (*) (certinfo_t*))destroy; this->public.destroy = (void (*) (certinfo_t*))destroy;
return &this->public; return &this->public;
+23 -33
View File
@@ -29,8 +29,6 @@
/** /**
* RFC 2560 OCSP - certificate status * RFC 2560 OCSP - certificate status
*/ */
extern enum_names cert_status_names;
typedef enum { typedef enum {
CERT_GOOD = 0, CERT_GOOD = 0,
CERT_REVOKED = 1, CERT_REVOKED = 1,
@@ -39,12 +37,11 @@ typedef enum {
CERT_UNTRUSTED = 4 /* private use */ CERT_UNTRUSTED = 4 /* private use */
} cert_status_t; } cert_status_t;
extern enum_name_t *cert_status_names;
/** /**
* RFC 2459 CRL reason codes * RFC 2459 CRL reason codes
*/ */
extern enum_names crl_reason_names;
typedef enum { typedef enum {
REASON_UNSPECIFIED = 0, REASON_UNSPECIFIED = 0,
REASON_KEY_COMPROMISE = 1, REASON_KEY_COMPROMISE = 1,
@@ -56,6 +53,8 @@ typedef enum {
REASON_REMOVE_FROM_CRL = 8 REASON_REMOVE_FROM_CRL = 8
} crl_reason_t; } crl_reason_t;
extern enum_name_t *crl_reason_names;
typedef struct certinfo_t certinfo_t; typedef struct certinfo_t certinfo_t;
/** /**
@@ -67,85 +66,76 @@ typedef struct certinfo_t certinfo_t;
struct certinfo_t { struct certinfo_t {
/** /**
* @brief Get serial number * @brief Get serial number.
* *
*
* @param this calling object * @param this calling object
* @return serialNumber * @return serialNumber
*/ */
chunk_t (*get_serialNumber) (const certinfo_t *this); chunk_t (*get_serialNumber) (const certinfo_t *this);
/** /**
* @brief Set certificate status * @brief Set certificate status.
* *
*
* @param this calling object * @param this calling object
* @param status status * @param status status
*/ */
void (*set_status) (certinfo_t *this, cert_status_t status); void (*set_status) (certinfo_t *this, cert_status_t status);
/** /**
* @brief Get certificate status * @brief Get certificate status.
* *
*
* @param this calling object * @param this calling object
* @return status * @return status
*/ */
cert_status_t (*get_status) (const certinfo_t *this); cert_status_t (*get_status) (const certinfo_t *this);
/** /**
* @brief Set nextUpdate * @brief Set nextUpdate.
* *
*
* @param this calling object * @param this calling object
* @return nextUpdate * @return nextUpdate
*/ */
void (*set_nextUpdate) (certinfo_t *this, time_t nextUpdate); void (*set_nextUpdate) (certinfo_t *this, time_t nextUpdate);
/** /**
* @brief Get nextUpdate * @brief Get nextUpdate.
* *
*
* @param this calling object * @param this calling object
* @return nextUpdate * @return nextUpdate
*/ */
time_t (*get_nextUpdate) (const certinfo_t *this); time_t (*get_nextUpdate) (const certinfo_t *this);
/** /**
* @brief Set revocationTime * @brief Set revocationTime.
* *
*
* @param this calling object * @param this calling object
* @param revocationTime revocationTime * @param revocationTime revocationTime
*/ */
void (*set_revocationTime) (certinfo_t *this, time_t revocationTime); void (*set_revocationTime) (certinfo_t *this, time_t revocationTime);
/** /**
* @brief Get revocationTime * @brief Get revocationTime.
* *
*
* @param this calling object * @param this calling object
* @return revocationTime * @return revocationTime
*/ */
time_t (*get_revocationTime) (const certinfo_t *this); time_t (*get_revocationTime) (const certinfo_t *this);
/** /**
* @brief Set revocationReason * @brief Set revocationReason.
* *
*
* @param this calling object * @param this calling object
* @param reason revocationReason * @param reason revocationReason
*/ */
void (*set_revocationReason) (certinfo_t *this, crl_reason_t reason); void (*set_revocationReason) (certinfo_t *this, crl_reason_t reason);
/** /**
* @brief Get revocationReason * @brief Get revocationReason.
* *
*
* @param this calling object * @param this calling object
* @return revocationReason * @return revocationReason
*/ */
const char *(*get_revocationReason) (const certinfo_t *this); crl_reason_t (*get_revocationReason) (const certinfo_t *this);
/** /**
* @brief Destroys the certinfo_t object. * @brief Destroys the certinfo_t object.
+89 -46
View File
@@ -23,13 +23,14 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <printf.h>
#include <types.h> #include <types.h>
#include <library.h>
#include <definitions.h> #include <definitions.h>
#include <asn1/oid.h> #include <asn1/oid.h>
#include <asn1/asn1.h> #include <asn1/asn1.h>
#include <asn1/pem.h> #include <asn1/pem.h>
#include <utils/logger_manager.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/identification.h> #include <utils/identification.h>
@@ -39,7 +40,6 @@
#define CRL_WARNING_INTERVAL 7 /* days */ #define CRL_WARNING_INTERVAL 7 /* days */
static logger_t *logger;
extern char* check_expiry(time_t expiration_date, int warning_interval, bool strict); extern char* check_expiry(time_t expiration_date, int warning_interval, bool strict);
extern time_t parse_time(chunk_t blob, int level0); extern time_t parse_time(chunk_t blob, int level0);
extern void parse_authorityKeyIdentifier(chunk_t blob, int level0 , chunk_t *authKeyID, chunk_t *authKeySerialNumber); extern void parse_authorityKeyIdentifier(chunk_t blob, int level0 , chunk_t *authKeyID, chunk_t *authKeySerialNumber);
@@ -206,9 +206,9 @@ static crl_reason_t parse_crl_reasonCode(chunk_t object)
{ {
reason = *object.ptr; reason = *object.ptr;
} }
logger->log(logger, CONTROL|LEVEL2, " '%s'", enum_name(&crl_reason_names, reason)); DBG2(" '%N'", crl_reason_names, reason);
return reason; return reason;
} }
/** /**
@@ -219,7 +219,7 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
asn1_ctx_t ctx; asn1_ctx_t ctx;
bool critical; bool critical;
chunk_t extnID; chunk_t extnID;
chunk_t userCertificate; chunk_t userCertificate = CHUNK_INITIALIZER;
revokedCert_t *revokedCert = NULL; revokedCert_t *revokedCert = NULL;
chunk_t object; chunk_t object;
u_int level; u_int level;
@@ -245,14 +245,14 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
break; break;
case CRL_OBJ_VERSION: case CRL_OBJ_VERSION:
crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1; crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
logger->log(logger, CONTROL|LEVEL2, " v%d", crl->version); DBG2(" v%d", crl->version);
break; break;
case CRL_OBJ_SIG_ALG: case CRL_OBJ_SIG_ALG:
crl->sigAlg = parse_algorithmIdentifier(object, level, NULL); crl->sigAlg = parse_algorithmIdentifier(object, level, NULL);
break; break;
case CRL_OBJ_ISSUER: case CRL_OBJ_ISSUER:
crl->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); crl->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
logger->log(logger, CONTROL|LEVEL1, " '%D'", crl->issuer); DBG2(" '%D'", crl->issuer);
break; break;
case CRL_OBJ_THIS_UPDATE: case CRL_OBJ_THIS_UPDATE:
crl->thisUpdate = parse_time(object, level); crl->thisUpdate = parse_time(object, level);
@@ -277,7 +277,7 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
case CRL_OBJ_CRL_ENTRY_CRITICAL: case CRL_OBJ_CRL_ENTRY_CRITICAL:
case CRL_OBJ_CRITICAL: case CRL_OBJ_CRITICAL:
critical = object.len && *object.ptr; critical = object.len && *object.ptr;
logger->log(logger, CONTROL|LEVEL2, " %s",(critical)?"TRUE":"FALSE"); DBG2(" %s",(critical)?"TRUE":"FALSE");
break; break;
case CRL_OBJ_CRL_ENTRY_EXTN_VALUE: case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
case CRL_OBJ_EXTN_VALUE: case CRL_OBJ_EXTN_VALUE:
@@ -314,25 +314,22 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
*/ */
static err_t is_valid(const private_crl_t *this, time_t *until, bool strict) static err_t is_valid(const private_crl_t *this, time_t *until, bool strict)
{ {
char buf[TIMETOA_BUF];
time_t current_time = time(NULL); time_t current_time = time(NULL);
timetoa(buf, BUF_LEN, &this->thisUpdate, TRUE); DBG2(" this update : %T", this->thisUpdate);
logger->log(logger, CONTROL|LEVEL1, " this update : %s", buf); DBG2(" current time: %T", current_time);
timetoa(buf, BUF_LEN, &current_time, TRUE); DBG2(" next update: %T", this->nextUpdate);
logger->log(logger, CONTROL|LEVEL1, " current time: %s", buf);
timetoa(buf, BUF_LEN, &this->nextUpdate, TRUE);
logger->log(logger, CONTROL|LEVEL1, " next update: %s", buf);
if (strict && until != NULL if (strict && until != NULL &&
&& (*until == UNDEFINED_TIME || this->nextUpdate < *until)) (*until == UNDEFINED_TIME || this->nextUpdate < *until))
{ {
*until = this->nextUpdate; *until = this->nextUpdate;
} }
if (current_time > this->nextUpdate) if (current_time > this->nextUpdate)
{
return "has expired"; return "has expired";
logger->log(logger, CONTROL|LEVEL1, " crl is valid", buf); }
DBG2(" crl is valid");
return NULL; return NULL;
} }
@@ -437,38 +434,88 @@ static void destroy(private_crl_t *this)
} }
/** /**
* log crl * output handler in printf()
*/ */
static void log_crl(const private_crl_t *this, logger_t *logger, bool utc, bool strict) static int print(FILE *stream, const struct printf_info *info,
const void *const *args)
{ {
identification_t *issuer = this->issuer; private_crl_t *this = *((private_crl_t**)(args[0]));
linked_list_t *revokedCertificates = this->revokedCertificates; bool utc = TRUE;
int written = 0;
char buf[BUF_LEN]; time_t now;
timetoa(buf, BUF_LEN, &this->installed, utc);
logger->log(logger, CONTROL, "%s, revoked certs: %d",
buf, revokedCertificates->get_count(revokedCertificates));
logger->log(logger, CONTROL, " issuer: '%D'", issuer);
timetoa(buf, BUF_LEN, &this->thisUpdate, utc); if (info->alt)
logger->log(logger, CONTROL, " updates: this %s", buf); {
utc = *((bool*)(args[1]));
}
timetoa(buf, BUF_LEN, &this->nextUpdate, utc); if (this == NULL)
logger->log(logger, CONTROL, " next %s %s", buf, {
check_expiry(this->nextUpdate, CRL_WARNING_INTERVAL, strict)); return fprintf(stream, "(null)");
}
now = time(NULL);
written += fprintf(stream, " issuer: %D\n", this->issuer);
written += fprintf(stream, " installed: %#T, revoked certs: %d\n", this->installed, utc,
this->revokedCertificates->get_count(this->revokedCertificates));
written += fprintf(stream, " updates: this %#T\n", this->thisUpdate, utc);
written += fprintf(stream, " next %#T ");
if (this->nextUpdate == UNDEFINED_TIME)
{
written += fprintf(stream, "ok (expires never)");
}
else if (now > this->nextUpdate)
{
written += fprintf(stream, "expired (since %V)", now, this->nextUpdate);
}
else if (now > this->nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
{
written += fprintf(stream, "ok (expires in %V)", now, this->nextUpdate);
}
else
{
written += fprintf(stream, "ok");
}
if (this->authKeyID.ptr)
{
written += fprintf(stream, "\n authkey: %#B", &this->authKeyID);
}
if (this->authKeySerialNumber.ptr)
{
written += fprintf(stream, "\n aserial: %#B", &this->authKeySerialNumber);
}
return written;
}
if (this->authKeyID.ptr != NULL) /**
* arginfo handler in printf()
*/
static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes)
{
if (info->alt)
{ {
chunk_to_hex(buf, BUF_LEN, this->authKeyID); if (n > 1)
logger->log(logger, CONTROL, " authkey: %s", buf); {
argtypes[0] = PA_INT;
argtypes[1] = PA_INT;
}
return 2;
} }
if (this->authKeySerialNumber.ptr != NULL)
if (n > 0)
{ {
chunk_to_hex(buf, BUF_LEN, this->authKeySerialNumber); argtypes[0] = PA_INT;
logger->log(logger, CONTROL, " aserial: %s", buf);
} }
return 1;
}
/**
* register printf() handlers
*/
static void __attribute__ ((constructor))print_register()
{
register_printf_function(CRL_PRINTF_SPEC, print, print_arginfo);
} }
/* /*
@@ -494,11 +541,7 @@ crl_t *crl_create_from_chunk(chunk_t chunk)
this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer; this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer;
this->public.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify; this->public.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify;
this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status; this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status;
this->public.log_crl = (void (*) (const crl_t*,logger_t*,bool,bool))log_crl;
this->public.destroy = (void (*) (crl_t*))destroy; this->public.destroy = (void (*) (crl_t*))destroy;
/* we do not use a per-instance logger right now, since its not always accessible */
logger = logger_manager->get_logger(logger_manager, ASN1);
if (!parse_x509crl(chunk, 0, this)) if (!parse_x509crl(chunk, 0, this))
{ {
+7 -11
View File
@@ -29,7 +29,13 @@
#include <crypto/certinfo.h> #include <crypto/certinfo.h>
#include <utils/identification.h> #include <utils/identification.h>
#include <utils/iterator.h> #include <utils/iterator.h>
#include <utils/logger.h>
/**
* printf specifier for printing crls. When using the
* #-modifier, an additional bool argument defines if times
* are printed in UTC.
*/
#define CRL_PRINTF_SPEC 'U'
typedef struct crl_t crl_t; typedef struct crl_t crl_t;
@@ -115,16 +121,6 @@ struct crl_t {
* @param this crl to destroy * @param this crl to destroy
*/ */
void (*destroy) (crl_t *this); void (*destroy) (crl_t *this);
/**
* @brief Log x509 crl info.
*
* @param this crl to log
* @param logger logger to be used
* @param utc log dates either in UTC or local time
* @param strict expiry of nextUpdate is fatal with strict == TRUE
*/
void (*log_crl) (const crl_t *this, logger_t *logger, bool utc, bool strict);
}; };
/** /**
+18 -20
View File
@@ -28,27 +28,25 @@
#include <crypto/crypters/des_crypter.h> #include <crypto/crypters/des_crypter.h>
/** ENUM_BEGIN(encryption_algorithm_names, ENCR_UNDEFINED, ENCR_UNDEFINED,
* String mappings for encryption_algorithm_t. "UNDEFINED");
*/ ENUM_NEXT(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32, ENCR_UNDEFINED,
mapping_t encryption_algorithm_m[] = { "DES_IV64",
{ENCR_UNDEFINED, "UNDEFINED"}, "DES",
{ENCR_DES_IV64, "DES_IV64"}, "3DES",
{ENCR_DES, "DES"}, "RC5",
{ENCR_3DES, "3DES"}, "IDEA",
{ENCR_RC5, "RC5"}, "CAST",
{ENCR_IDEA, "IDEA"}, "BLOWFISH",
{ENCR_CAST, "CAST"}, "3IDEA",
{ENCR_BLOWFISH, "BLOWFISH"}, "DES_IV32");
{ENCR_3IDEA, "3IDEA"}, ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CTR, ENCR_DES_IV32,
{ENCR_DES_IV32, "DES_IV32"}, "NULL",
{ENCR_NULL, "NULL"}, "AES_CBC",
{ENCR_AES_CBC, "AES_CBC"}, "AES_CTR");
{ENCR_AES_CTR, "AES_CTR"}, ENUM_END(encryption_algorithm_names, ENCR_AES_CTR);
{MAPPING_END, NULL}
};
/* /*
* Described in header. * Described in header.
*/ */
crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size) crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size)

Some files were not shown because too many files have changed in this diff Show More