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 = \
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/file_logger.c bus/listeners/file_logger.h \
config/connections/connection.c config/connections/connection.h \
+267 -7
View File
@@ -22,6 +22,102 @@
#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;
/**
@@ -38,6 +134,16 @@ struct private_bus_t {
*/
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
*/
@@ -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)
{
pthread_mutex_lock(&this->mutex);
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.
*/
@@ -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,
char* format, ...)
static void vsignal(private_bus_t *this, signal_t signal, level_t level,
char* format, va_list args)
{
iterator_t *iterator;
bus_listener_t *listener;
va_list args;
active_listener_t *active_listener;
ike_sa_t *ike_sa;
int thread;
ike_sa = pthread_getspecific(this->thread_sa);
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);
while (iterator->iterate(iterator, (void**)&listener))
{
listener->signal(listener, thread, ike_sa,
signal, condition, format, args);
va_list args_copy;
va_copy(args_copy, args);
listener->signal(listener, signal, level, thread, ike_sa, format, args_copy);
va_end(args_copy);
}
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);
}
@@ -118,6 +365,14 @@ static void signal_(private_bus_t *this, signal_t signal, level_t condition,
*/
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);
free(this);
}
@@ -130,11 +385,16 @@ bus_t *bus_create()
private_bus_t *this = malloc_thing(private_bus_t);
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.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->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_sa, NULL);
+224 -78
View File
@@ -29,60 +29,81 @@
#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;
/**
* @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 {
/** an IKE_SA has been established */
SIG_IKE_UP,
/** 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,
/** pseudo signal, representing any other signal */
SIG_ANY,
/** 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 */
SIG_DBG_IKE,
/** debugging message printed from a CHILD_SA */
@@ -97,27 +118,103 @@ enum signal_t {
SIG_DBG_NET,
/** debugging message printed from message encoding/decoding */
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;
/**
* Signal levels used to control output verbosity.
*/
enum level_t {
/** Signal indicates something has failed */
LEV_FAILED,
/** Signal indicates something was successful */
LEV_SUCCESS,
/** Debug level 1, control flow messages */
LEV_DBG1,
/** Debug level 2, more detail informational messages */
LEV_DBG2,
/** Debug level 3, RAW data output */
LEV_DBG3,
/** Debug level 4, RAW data with sensitive (private) data */
LEV_DBG4,
/** numerical levels from 0 to 4 */
LEVEL_0 = 0,
LEVEL_1 = 1,
LEVEL_2 = 2,
LEVEL_3 = 3,
LEVEL_4 = 4,
/** absolutely silent, no signal is ommited with this level */
LEVEL_SILENT = -1,
/** alias for numberical levels */
LEVEL_AUDIT = LEVEL_0,
LEVEL_CTRL = LEVEL_1,
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;
/**
@@ -135,21 +232,21 @@ struct bus_listener_t {
*
* A numerical identification for the thread is included, as the
* 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
* variable argument list. This is in the va_list form, as forwarding
* a "..." parameters to functions is not (cleanly) possible.
*
* @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 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 args vprintf() style va_list argument list
*/
void (*signal) (bus_listener_t *this, int thread, ike_sa_t *ike_sa,
signal_t signal, level_t level, char* format, va_list args);
void (*signal) (bus_listener_t *this, signal_t signal, level_t level,
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
* in receiving event signals registers at the bus. Any signals sent to
* 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
*/
@@ -171,12 +269,51 @@ struct bus_t {
* @brief Register a listener 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 listener listener to register.
*/
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.
*
@@ -185,8 +322,6 @@ struct bus_t {
* 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
* thread has one IKE_SA registered (or not).
* There is a macro to simplify the call.
* @see SIG_SA()
*
* @param this bus
* @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.
*
* A signal may belong to an IKE_SA and a CHILD_SA. If so, these
* are supplied to the signal function. The signal specifies the type of
* the event occured. The format string specifies an additional
* informational or error message with a printf() like variable argument
* list.
* Some useful macros may be available to shorten this call.
* The signal specifies the type of the event occured. The format string
* specifies an additional informational or error message with a
* printf() like variable argument list.
* Some useful macros are available to shorten this call.
* @see SIG(), DBG1()
*
* @param this bus
* @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 ... printf() style argument list
*/
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.
*
+36 -89
View File
@@ -20,15 +20,11 @@
* for more details.
*/
/* for fmemopen() */
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include "file_logger.h"
#include <bus/listeners/stream_logger.h>
typedef struct private_file_logger_t private_file_logger_t;
@@ -48,99 +44,58 @@ struct private_file_logger_t {
FILE *out;
/**
* Internal used stream logger that does the dirty work
* Maximum level to log
*/
stream_logger_t *logger;
/**
* Memory stream used for stream_logger
*/
FILE *stream;
/**
* Underlying buffer for stream
*/
char buffer[4096];
level_t levels[SIG_DBG_MAX];
};
/**
* Implementation of bus_listener_t.signal.
*/
static void signal_(private_file_logger_t *this, int thread, ike_sa_t* ike_sa,
signal_t signal, level_t level,
char *format, va_list args)
static void signal_(private_file_logger_t *this, signal_t signal, level_t level,
int thread, ike_sa_t* ike_sa, char *format, va_list args)
{
char line[512];
char *prefix;
FILE *reader;
switch (signal)
if (level <= this->levels[SIG_TYPE(signal)])
{
case SIG_IKE_UP:
case SIG_IKE_DOWN:
case SIG_IKE_REKEY:
case SIG_DBG_IKE:
prefix = "IKE";
break;
case SIG_DBG_CHD:
prefix = "CHD";
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')
char buffer[8192];
char *current = buffer, *next;
/* write in memory buffer first */
vsnprintf(buffer, sizeof(buffer), format, args);
/* prepend a prefix in front of every line */
while (current)
{
/* abort on EOF */
break;
}
else if (line[0] != '\n')
{
fprintf(this->out, "%.2d[%s] %s", thread, prefix, line);
next = strchr(current, '\n');
if (next)
{
*(next++) = '\0';
}
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.
*/
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)
{
fclose(this->stream);
this->logger->destroy(this->logger);
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);
/* 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.destroy = (void(*)(file_logger_t*))destroy;
/* private variables */
this->out = out;
this->stream = fmemopen(this->buffer, sizeof(this->buffer), "w");
if (this->stream == NULL)
{
/* fallback to stderr */
this->stream = stderr;
}
this->logger = stream_logger_create(this->stream);
set_level(this, SIG_ANY, LEVEL_SILENT);
return &this->public;
}
+1 -1
View File
@@ -48,7 +48,7 @@ struct file_logger_t {
*
* @param this stream_logger_t object
* @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);
-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 open_memstream() */
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include "sys_logger.h"
#include <bus/listeners/stream_logger.h>
typedef struct private_sys_logger_t private_sys_logger_t;
@@ -49,99 +45,59 @@ struct private_sys_logger_t {
int facility;
/**
* Internal used stream logger that does the dirty work
* Maximum level to log
*/
stream_logger_t *logger;
/**
* Memory stream used for stream_logger
*/
FILE *stream;
/**
* Underlying buffer for stream
*/
char buffer[4096];
level_t levels[SIG_DBG_MAX];
};
/**
* Implementation of bus_listener_t.signal.
*/
static void signal_(private_sys_logger_t *this, int thread, ike_sa_t* ike_sa,
signal_t signal, level_t level,
char *format, va_list args)
static void signal_(private_sys_logger_t *this, signal_t signal, level_t level,
int thread, ike_sa_t* ike_sa, char *format, va_list args)
{
char line[512];
char *prefix;
FILE *reader;
switch (signal)
if (level <= this->levels[SIG_TYPE(signal)])
{
case SIG_IKE_UP:
case SIG_IKE_DOWN:
case SIG_IKE_REKEY:
case SIG_DBG_IKE:
prefix = "IKE";
break;
case SIG_DBG_CHD:
prefix = "CHD";
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')
char buffer[8192];
char *current = buffer, *next;
/* write in memory buffer first */
vsnprintf(buffer, sizeof(buffer), format, args);
/* do a syslog with every line */
while (current)
{
/* abort on EOF */
break;
}
else if (line[0] != '\n')
{
syslog(this->facility|LOG_INFO, "%.2d[%s] %s", thread, prefix, line);
next = strchr(current, '\n');
if (next)
{
*(next++) = '\0';
}
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.
*/
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)
{
closelog();
fclose(this->stream);
this->logger->destroy(this->logger);
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);
/* 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.destroy = (void(*)(sys_logger_t*))destroy;
/* private variables */
this->facility = facility;
this->stream = fmemopen(this->buffer, sizeof(this->buffer), "w");
if (this->stream == NULL)
{
/* fallback to stderr */
this->stream = stderr;
}
this->logger = stream_logger_create(this->stream);
set_level(this, SIG_ANY, LEVEL_SILENT);
return &this->public;
}
+5 -11
View File
@@ -24,19 +24,13 @@
#include <string.h>
#include <config/connections/connection.h>
#include <utils/linked_list.h>
#include <utils/logger.h>
/**
* String mappings for cert_policy_t.
*/
mapping_t cert_policy_m[] = {
{CERT_ALWAYS_SEND, "CERT_ALWAYS_SEND"},
{CERT_SEND_IF_ASKED, "CERT_SEND_IF_ASKED"},
{CERT_NEVER_SEND, "CERT_NEVER_SEND"},
{MAPPING_END, NULL}
};
ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
"CERT_ALWAYS_SEND",
"CERT_SEND_IF_ASKED",
"CERT_NEVER_SEND"
);
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
*/
extern mapping_t cert_policy_m[];
extern enum_name_t *cert_policy_names;
typedef struct connection_t connection_t;
@@ -25,17 +25,17 @@
#include <types.h>
#include <config/connections/connection.h>
#include <utils/logger.h>
#include <utils/iterator.h>
typedef struct connection_store_t connection_store_t;
/**
* @brief The interface for a store of connection_t's.
*
*
* @b Constructors:
* - stroke_create()
*
*
* @ingroup config
*/
struct connection_store_t {
@@ -47,7 +47,7 @@ struct connection_store_t {
* It may be used after kernel request for traffic protection.
* The returned connection gets created/cloned and therefore must
* be destroyed after usage.
*
*
* @param this calling object
* @param my_id own address of connection
* @param other_id others address of connection
@@ -55,14 +55,15 @@ struct connection_store_t {
* - connection_t, if found
* - 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.
*
*
* This call is usefull to get a connection identified its
* name, as on an connection setup.
*
*
* @param this calling object
* @param name name of the connection to get
* @return
@@ -73,10 +74,10 @@ struct connection_store_t {
/**
* @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.
*
*
* @param this calling object
* @param connection connection to add
* @return
@@ -87,10 +88,10 @@ struct connection_store_t {
/**
* @brief Delete a connection from the store.
*
*
* Remove a connection from the connection store, identified
* by the connections name.
*
*
* @param this calling object
* @param name name of the connection to delete
* @return
@@ -100,25 +101,16 @@ struct connection_store_t {
status_t (*delete_connection) (connection_store_t *this, char *name);
/**
* @brief Log the connections stored in the store.
*
* 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
*
* @brief Get an iterator for the stored connections.
*
* @param this calling object
* @param logger logger to use for the log, or NULL
* @param name name of the connection, or NULL
* @return
* - SUCCESS, or
* - FAILED
* @return iterator over all stored connections
*/
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.
*
*
* @param this calling object
*/
void (*destroy) (connection_store_t *this);
@@ -24,8 +24,8 @@
#include "local_connection_store.h"
#include <daemon.h>
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
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
*/
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 *found = NULL;
this->logger->log(this->logger, CONTROL|LEVEL1,
"looking for connection for host pair %H...%H",
my_host, other_host);
DBG2(SIG_DBG_CFG, "looking for connection for host pair %H...%H",
my_host, other_host);
pthread_mutex_lock(&(this->mutex));
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;
}
this->logger->log(this->logger, CONTROL|LEVEL2,
"candidate connection \"%s\": %H...%H (prio=%d)",
candidate->get_name(candidate),
candidate_my_host, candidate_other_host,
prio);
DBG2(SIG_DBG_CFG, "candidate connection \"%s\": %H...%H (prio=%d)",
candidate->get_name(candidate),
candidate_my_host, candidate_other_host, 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_other_host = found->get_other_host(found);
this->logger->log(this->logger, CONTROL|LEVEL1,
"found matching connection \"%s\": %H...%H (prio=%d)",
found->get_name(found),
found_my_host, found_other_host,
best_prio);
DBG2(SIG_DBG_CFG, "found matching connection \"%s\": %H...%H (prio=%d)",
found->get_name(found), found_my_host, found_other_host, best_prio);
/* give out a new reference to it */
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;
connection_t *current;
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));
return this->connections->create_iterator_locked(this->connections,
&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.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.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;
/* private variables */
this->connections = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
pthread_mutex_init(&(this->mutex), NULL);
return (&this->public);
@@ -29,7 +29,6 @@
#include <crypto/rsa/rsa_private_key.h>
#include <crypto/rsa/rsa_public_key.h>
#include <utils/identification.h>
#include <utils/logger.h>
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);
/**
* @brief Lists all certificates kept in the local credential store.
* @brief Create an iterator over all end certificates.
*
* @param this calling object
* @param logger logger to be used
* @param utc log dates either in UTC or local time
* @return iterator
*/
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 logger logger to be used
* @param utc log dates either in UTC or local time
* @return iterator
*/
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 logger logger to be used
* @param utc log dates either in UTC or local time
* @return iterator
*/
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.
@@ -28,7 +28,6 @@
#include <types.h>
#include <utils/lexparser.h>
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <crypto/certinfo.h>
#include <crypto/rsa/rsa_public_key.h>
#include <crypto/x509.h>
@@ -56,13 +55,6 @@ struct shared_key_t {
* list of peer IDs
*/
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.
*
* @param shared_key shared key value
*
* @return shared_key_t object
*
* @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);
/* private functions */
this->destroy = shared_key_destroy;
/* private data */
this->secret = chunk_clone(secret);
this->peers = linked_list_create();
@@ -154,11 +142,6 @@ struct private_local_credential_store_t {
* enforce strict crl policy
*/
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);
if (ugh != NULL)
{
this->logger->log(this->logger, ERROR, "certificate %s");
DBG1(SIG_DBG_CFG, "certificate %s", ugh);
return NULL;
}
status = cert->get_status(cert);
if (status == CERT_REVOKED || status == CERT_UNTRUSTED || (this->strict && status != CERT_GOOD))
{
this->logger->log(this->logger, ERROR, "certificate status: %s",
enum_name(&cert_status_names, status));
DBG1(SIG_DBG_CFG, "certificate status: %N", cert_status_names, status);
return 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;
}
@@ -419,20 +401,20 @@ static cert_status_t verify_by_crl(private_local_credential_store_t* this, const
crl = get_crl(this, issuer_cert);
if (crl == NULL)
{
this->logger->log(this->logger, ERROR, "crl not found");
DBG1(SIG_DBG_CFG, "crl not found");
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);
if (!valid_signature)
{
this->logger->log(this->logger, ERROR, "crl signature is invalid");
DBG1(SIG_DBG_CFG, "crl signature is invalid");
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);
@@ -490,8 +472,8 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
*found = (cert_copy != NULL);
if (*found)
{
this->logger->log(this->logger, CONTROL|LEVEL1,
"end entitity certificate is already in credential store");
DBG2(SIG_DBG_CFG,
"end entitity certificate is already in credential store");
}
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 *issuer = cert->get_issuer(cert);
this->logger->log(this->logger, CONTROL|LEVEL1, "subject: '%D'", subject);
this->logger->log(this->logger, CONTROL|LEVEL1, "issuer: '%D'", issuer);
DBG2(SIG_DBG_CFG, "subject: '%D'", subject);
DBG2(SIG_DBG_CFG, "issuer: '%D'", issuer);
ugh = cert->is_valid(cert, &until);
if (ugh != NULL)
{
this->logger->log(this->logger, ERROR, "certificate %s", ugh);
DBG1(SIG_DBG_CFG, "certificate %s", ugh);
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);
if (issuer_cert == NULL)
{
this->logger->log(this->logger, ERROR, "issuer certificate not found");
DBG1(SIG_DBG_CFG, "issuer certificate not found");
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);
valid_signature = cert->verify(cert, issuer_public_key);
if (!valid_signature)
{
this->logger->log(this->logger, ERROR, "certificate signature is invalid");
DBG1(SIG_DBG_CFG, "certificate signature is invalid");
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 */
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 */
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 (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;
}
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
* 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;
case CERT_REVOKED:
{
u_char buf[TIMETOA_BUF];
time_t revocationTime = certinfo->get_revocationTime(certinfo);
timetoa(buf, TIMETOA_BUF, &revocationTime, TRUE);
this->logger->log(this->logger, ERROR, "certificate was revoked on %s, reason: %s",
buf, certinfo->get_revocationReason(certinfo));
DBG1(SIG_DBG_CFG,
"certificate was revoked on %T, reason: %N",
revocationTime, crl_reason_names,
certinfo->get_revocationReason(certinfo));
/* set 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
{
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;
@@ -617,7 +599,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
case CERT_UNKNOWN:
case CERT_UNDEFINED:
default:
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate status unknown");
DBG2(SIG_DBG_CFG, "certificate status unknown");
if (this->strict)
{
/* 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 */
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;
}
@@ -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);
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);
return this->certs->create_iterator(this->certs, TRUE);
}
/**
* 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);
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);
return this->ca_certs->create_iterator(this->ca_certs, TRUE);
}
/**
* 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);
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);
return this->crls->create_iterator_locked(this->crls, &(this->crls_mutex));
}
/**
@@ -760,12 +689,12 @@ static void load_ca_certificates(private_local_credential_store_t *this)
DIR* dir;
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);
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;
}
@@ -787,9 +716,9 @@ static void load_ca_certificates(private_local_credential_store_t *this)
{
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))
{
@@ -797,8 +726,7 @@ static void load_ca_certificates(private_local_credential_store_t *this)
}
else
{
this->logger->log(this->logger, ERROR,
" CA basic constraints flag not set, cert discarded");
DBG1(SIG_DBG_CFG, " CA basic constraints flag not set, cert discarded");
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
*/
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;
@@ -833,13 +761,13 @@ static crl_t* add_crl(linked_list_t *crls, crl_t *crl, logger_t *logger)
{
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
{
crl->destroy(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;
}
@@ -849,7 +777,7 @@ static crl_t* add_crl(linked_list_t *crls, crl_t *crl, logger_t *logger)
if (!found)
{
crls->insert_last(crls, (void*)crl);
logger->log(logger, CONTROL|LEVEL1, " crl added");
DBG2(SIG_DBG_CFG, " crl added");
}
return crl;
}
@@ -864,12 +792,12 @@ static void load_crls(private_local_credential_store_t *this)
DIR* dir;
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);
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;
}
@@ -893,10 +821,10 @@ static void load_crls(private_local_credential_store_t *this)
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));
crl = add_crl(this->crls, crl, this->logger);
crl = add_crl(this->crls, crl);
pthread_mutex_unlock(&(this->crls_mutex));
}
}
@@ -973,7 +901,7 @@ static void load_secrets(private_local_credential_store_t *this)
int line_nr = 0;
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);
chunk.len = ftell(fd);
@@ -996,7 +924,7 @@ static void load_secrets(private_local_credential_store_t *this)
}
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;
}
/* 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))
{
this->logger->log(this->logger, ERROR, "line %d: missing token", line_nr);
DBG1(SIG_DBG_CFG, "line %d: missing token", line_nr);
goto error;
}
if (match("RSA", &token))
@@ -1022,13 +950,12 @@ static void load_secrets(private_local_credential_store_t *this)
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;
}
if (filename.len == 0)
{
this->logger->log(this->logger, ERROR,
"line %d: empty filename", line_nr);
DBG1(SIG_DBG_CFG, "line %d: empty filename", line_nr);
goto error;
}
if (*filename.ptr == '/')
@@ -1049,8 +976,7 @@ static void load_secrets(private_local_credential_store_t *this)
ugh = extract_secret(&secret, &line);
if (ugh != NULL)
{
this->logger->log(this->logger, ERROR,
"line %d: malformed passphrase: %s", line_nr, ugh);
DBG1(SIG_DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
goto error;
}
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);
if (ugh != NULL)
{
this->logger->log(this->logger, ERROR,
"line %d: malformed secret: %s", line_nr, ugh);
DBG1(SIG_DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
goto error;
}
if (ids.len > 0)
{
this->logger->log(this->logger, CONTROL,
" loading shared key for %s", ids.ptr);
DBG1(SIG_DBG_CFG, " loading shared key for %s", ids.ptr);
}
else
{
this->logger->log(this->logger, CONTROL,
" loading shared key for %%any");
DBG1(SIG_DBG_CFG, " 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);
if (shared_key)
@@ -1103,8 +1026,7 @@ static void load_secrets(private_local_credential_store_t *this)
ugh = extract_value(&id, &ids);
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;
}
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);
if (peer_id == NULL)
{
this->logger->log(this->logger, ERROR,
"line %d: malformed ID: %s", line_nr, id.ptr);
DBG1(SIG_DBG_CFG, "line %d: malformed ID: %s", line_nr, id.ptr);
goto error;
}
@@ -1137,9 +1058,8 @@ static void load_secrets(private_local_credential_store_t *this)
}
else
{
this->logger->log(this->logger, ERROR,
"line %d: token must be either RSA, PSK, or PIN",
line_nr, token.len);
DBG1(SIG_DBG_CFG, "line %d: token must be either "
"RSA, PSK, or PIN", line_nr, token.len);
goto error;
}
}
@@ -1148,7 +1068,7 @@ error:
}
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 */
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);
@@ -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.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.log_certificates = (void (*) (credential_store_t*,logger_t*,bool))log_certificates;
this->public.credential_store.log_ca_certificates = (void (*) (credential_store_t*,logger_t*,bool))log_ca_certificates;
this->public.credential_store.log_crls = (void (*) (credential_store_t*,logger_t*,bool))log_crls;
this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator;
this->public.credential_store.create_cacert_iterator = (iterator_t* (*) (credential_store_t*))create_cacert_iterator;
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_crls = (void (*) (credential_store_t*))load_crls;
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);
/* private variables */
this->shared_keys = linked_list_create();
this->shared_keys = linked_list_create();
this->private_keys = linked_list_create();
this->certs = linked_list_create();
this->ca_certs = linked_list_create();
this->crls = linked_list_create();
this->certs = linked_list_create();
this->ca_certs = linked_list_create();
this->crls = linked_list_create();
this->strict = strict;
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
return (&this->public);
}
+22 -23
View File
@@ -1,8 +1,8 @@
/**
* @file local_policy_store.c
*
*
* @brief Implementation of local_policy_store_t.
*
*
*/
/*
@@ -24,8 +24,8 @@
#include "local_policy_store.h"
#include <daemon.h>
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
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
*/
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 *found = NULL;
this->logger->log(this->logger, CONTROL|LEVEL1,
"searching policy for ID pair %D...%D", my_id, other_id);
DBG2(SIG_DBG_CFG, "searching policy for ID pair %D...%D", my_id, other_id);
pthread_mutex_lock(&(this->mutex));
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) ||
!contains_traffic_selectors(candidate, FALSE, other_ts, other_host))
{
this->logger->log(this->logger, CONTROL|LEVEL2,
"candidate '%s' inacceptable due traffic selector mismatch",
candidate->get_name(candidate));
DBG2(SIG_DBG_CFG, "candidate '%s' inacceptable due traffic "
"selector mismatch", candidate->get_name(candidate));
continue;
}
this->logger->log(this->logger, CONTROL|LEVEL2,
"candidate policy '%s': %D...%D (prio=%d)",
candidate->get_name(candidate),
candidate_my_id, candidate_other_id, prio);
DBG2(SIG_DBG_CFG, "candidate policy '%s': %D...%D (prio=%d)",
candidate->get_name(candidate),
candidate_my_id, candidate_other_id, 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_other_id = found->get_other_id(found);
this->logger->log(this->logger, CONTROL,
"found matching policy '%s': %D...%D (prio=%d)",
found->get_name(found),
found_my_id, found_other_id, best_prio);
DBG1(SIG_DBG_CFG, "found matching policy '%s': %D...%D (prio=%d)",
found->get_name(found), found_my_id, found_other_id, best_prio);
/* give out a new reference to it */
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;
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));
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;
}
/**
* 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.
*/
@@ -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_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.create_iterator = (iterator_t*(*)(policy_store_t*))create_iterator;
this->public.policy_store.destroy = (void(*)(policy_store_t*))destroy;
/* private variables */
this->policies = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
pthread_mutex_init(&(this->mutex), NULL);
return (&this->public);
+10 -31
View File
@@ -27,34 +27,23 @@
#include "policy.h"
#include <daemon.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
#include <utils/logger_manager.h>
/**
* String mappings for auth_method_t.
*/
static const char *const auth_method_name[] = {
ENUM(auth_method_names, RSA_DIGITAL_SIGNATURE, DSS_DIGITAL_SIGNATURE,
"RSA signature",
"pre-shared key",
"DSS signature"
};
);
enum_names auth_method_names =
{ RSA_DIGITAL_SIGNATURE, DSS_DIGITAL_SIGNATURE, auth_method_name, NULL };
/**
* String mappings for dpd_action_t.
*/
static const char *const dpd_action_name[] = {
ENUM(dpd_action_names, DPD_NONE, DPD_RESTART,
"DPD_NONE",
"DPD_CLEAR",
"DPD_ROUTE",
"DPD_RESTART"
};
enum_names dpd_action_names =
{ DPD_NONE, DPD_RESTART, dpd_action_name, NULL };
);
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?
*/
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;
linked_list_t *selected = linked_list_create();
this->logger->log(this->logger, CONTROL|LEVEL1,
"selecting traffic selectors for %s host",
stored == this->my_ts ? "local" : "remote");
DBG2(SIG_DBG_CFG, "selecting traffic selectors");
stored_iter = stored->create_iterator(stored, 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 */
while (supplied_iter->iterate(supplied_iter, (void**)&supplied_ts))
{
this->logger->log(this->logger, CONTROL|LEVEL2,
" stored %s <=> %s received",
stored_ts->get_string(stored_ts),
supplied_ts->get_string(supplied_ts));
DBG2(SIG_DBG_CFG, "stored %R <=> %R received",
stored_ts, supplied_ts);
selected_ts = stored_ts->get_subset(stored_ts, supplied_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 */
selected->insert_last(selected, (void*)selected_ts);
this->logger->log(this->logger, CONTROL|LEVEL1, " got a match: %s",
selected_ts->get_string(selected_ts));
DBG2(SIG_DBG_CFG, "found traffic selector for %s: %R",
stored == this->my_ts ? "us" : "other", selected_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->my_ts = linked_list_create();
this->other_ts = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
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
*/
extern enum_names auth_method_names;
extern enum_name_t *auth_method_names;
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;
@@ -100,6 +100,14 @@ struct policy_store_t {
*/
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.
*
+21 -33
View File
@@ -26,45 +26,33 @@
#include <utils/linked_list.h>
#include <utils/identification.h>
#include <utils/logger.h>
#include <utils/lexparser.h>
#include <crypto/prfs/prf.h>
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
/**
* String mappings for protocol_id_t.
*/
mapping_t protocol_id_m[] = {
{PROTO_NONE, "PROTO_NONE"},
{PROTO_IKE, "IKE"},
{PROTO_AH, "AH"},
{PROTO_ESP, "ESP"},
{MAPPING_END, NULL}
};
ENUM(protocol_id_names, PROTO_NONE, PROTO_ESP,
"PROTO_NONE",
"IKE",
"AH",
"ESP",
);
/**
* String mappings for transform_type_t.
*/
mapping_t transform_type_m[] = {
{UNDEFINED_TRANSFORM_TYPE, "UNDEFINED_TRANSFORM_TYPE"},
{ENCRYPTION_ALGORITHM, "ENCRYPTION_ALGORITHM"},
{PSEUDO_RANDOM_FUNCTION, "PSEUDO_RANDOM_FUNCTION"},
{INTEGRITY_ALGORITHM, "INTEGRITY_ALGORITHM"},
{DIFFIE_HELLMAN_GROUP, "DIFFIE_HELLMAN_GROUP"},
{EXTENDED_SEQUENCE_NUMBERS, "EXTENDED_SEQUENCE_NUMBERS"},
{MAPPING_END, NULL}
};
ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, UNDEFINED_TRANSFORM_TYPE,
"UNDEFINED_TRANSFORM_TYPE");
ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, UNDEFINED_TRANSFORM_TYPE,
"ENCRYPTION_ALGORITHM",
"PSEUDO_RANDOM_FUNCTION",
"INTEGRITY_ALGORITHM",
"DIFFIE_HELLMAN_GROUP",
"EXTENDED_SEQUENCE_NUMBERS");
ENUM_END(transform_type_names, EXTENDED_SEQUENCE_NUMBERS);
/**
* String mappings for extended_sequence_numbers_t.
*/
mapping_t extended_sequence_numbers_m[] = {
{NO_EXT_SEQ_NUMBERS, "NO_EXT_SEQ_NUMBERS"},
{EXT_SEQ_NUMBERS, "EXT_SEQ_NUMBERS"},
{MAPPING_END, NULL}
};
ENUM(extended_sequence_numbers_names, NO_EXT_SEQ_NUMBERS, EXT_SEQ_NUMBERS,
"NO_EXT_SEQ_NUMBERS",
"EXT_SEQ_NUMBERS",
);
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
*/
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);
@@ -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.set_spi = (void(*)(proposal_t*,u_int64_t))set_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->spi = 0;
+16 -16
View File
@@ -47,12 +47,12 @@ enum protocol_id_t {
PROTO_ESP = 3,
};
/**
* String mappings for protocol_id_t.
*
/**
* enum names for protocol_id_t
*
* @ingroup config
*/
extern mapping_t protocol_id_m[];
extern enum_name_t *protocol_id_names;
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.
*
* @ingroup payloads
* @ingroup config
*/
enum transform_type_t {
UNDEFINED_TRANSFORM_TYPE = 241,
@@ -71,12 +71,12 @@ enum transform_type_t {
EXTENDED_SEQUENCE_NUMBERS = 5
};
/**
* String mappings for transform_type_t.
*
* @ingroup payloads
/**
* enum names for transform_type_t.
*
* @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;
@@ -84,19 +84,19 @@ typedef enum extended_sequence_numbers_t extended_sequence_numbers_t;
/**
* Extended sequence numbers, as in IKEv2 RFC 3.3.2.
*
* @ingroup payloads
* @ingroup config
*/
enum extended_sequence_numbers_t {
NO_EXT_SEQ_NUMBERS = 0,
EXT_SEQ_NUMBERS = 1
};
/**
* String mappings for extended_sequence_numbers_t.
*
* @ingroup payloads
/**
* enum strings for extended_sequence_numbers_t.
*
* @ingroup config
*/
extern mapping_t extended_sequence_numbers_m[];
extern enum_name_t *extended_sequence_numbers_names;
typedef struct algorithm_t algorithm_t;
+88 -85
View File
@@ -25,12 +25,18 @@
#include <string.h>
#include <netdb.h>
#include <stdio.h>
#include <printf.h>
#include "traffic_selector.h"
#include <utils/linked_list.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;
/**
@@ -86,11 +92,6 @@ struct private_traffic_selector_t {
* end of port range
*/
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);
}
/**
* 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);
/**
* 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 servent *serv;
char *serv_proto = NULL;
char proto_str[8] = "";
char addr_str[INET6_ADDRSTRLEN];
char port_str[16] = "";
char mask_str[8] = "";
char proto_port_str[32] = "";
bool has_proto = FALSE, has_port = FALSE;
bool has_proto = FALSE;
size_t written, total_written = 0;
#define fprintf_sum(...) { written = fprintf(__VA_ARGS__); if (written < 0) return written; total_written += written; }
if (this == NULL)
{
return fprintf(stream, "(null)");
}
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));
/* build network mask string */
mask = calc_netbits(this);
snprintf(mask_str, sizeof(mask_str), "/%d", mask);
}
else
{
u_int8_t mask;
/* build address string */
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 */
if (this->protocol)
@@ -197,12 +191,12 @@ static void update_string(private_traffic_selector_t *this)
proto = getprotobynumber(this->protocol);
if (proto)
{
snprintf(proto_str, sizeof(proto_str), "%s", proto->p_name);
fprintf_sum(stream, "[%s", proto->p_name);
serv_proto = proto->p_name;
}
else
{
snprintf(proto_str, sizeof(proto_str), "%d", this->protocol);
fprintf_sum(stream, "[%d", this->protocol);
}
has_proto = TRUE;
}
@@ -210,55 +204,58 @@ static void update_string(private_traffic_selector_t *this)
/* build port string */
if (this->from_port == this->to_port)
{
serv = getservbyport(htons(this->from_port), serv_proto);
if (serv)
if (has_proto)
{
snprintf(port_str, sizeof(port_str), "%s", serv->s_name);
fprintf_sum(stream, "/");
}
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))
{
snprintf(port_str, sizeof(port_str), "%d-%d",
this->from_port, this->to_port);
has_port = TRUE;
if (has_proto)
{
fprintf_sum(stream, "/");
}
else
{
fprintf_sum(stream, "[");
}
fprintf_sum(stream, "%d-%d]", this->from_port, this->to_port);
}
/* concatenate port & proto string */
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);
return total_written;
}
/**
* 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;
memcpy(new_ts->from, from, size);
memcpy(new_ts->to, to, size);
update_string(new_ts);
return &new_ts->public;
}
@@ -454,23 +450,43 @@ static u_int8_t get_protocol(private_traffic_selector_t *this)
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.
*/
static void update_address_range(private_traffic_selector_t *this, host_t *host)
{
if ((this->type == TS_IPV4_ADDR_RANGE && this->from4[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->type == TS_IPV6_ADDR_RANGE && this->from6[0] == 0 &&
this->from6[1] == 0 && this->from6[2] == 0 && this->from6[3] == 0))
{
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);
memcpy(this->from, 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->to4, this->to4, sizeof(this->to4));
update_string(clone);
return &clone->public;
}
case TS_IPV6_ADDR_RANGE:
{
memcpy(clone->from6, this->from6, sizeof(this->from6));
memcpy(clone->to6, this->to6, sizeof(this->to6));
update_string(clone);
return &clone->public;
}
default:
@@ -511,7 +525,6 @@ static traffic_selector_t *clone_(private_traffic_selector_t *this)
*/
static void destroy(private_traffic_selector_t *this)
{
free(this->string);
free(this);
}
@@ -552,9 +565,6 @@ traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol, ts_typ
return NULL;
}
}
update_string(this);
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->to_port = port;
}
update_string(this);
return (&this->public);
}
@@ -667,9 +674,6 @@ traffic_selector_t *traffic_selector_create_from_string(u_int8_t protocol, ts_ty
break;
}
}
update_string(this);
return (&this->public);
}
@@ -683,13 +687,13 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts
/* public functions */
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.get_string = (char*(*)(traffic_selector_t*))get_string;
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_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_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.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.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone_;
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->protocol = protocol;
this->type = type;
this->string = NULL;
return this;
}
+19 -12
View File
@@ -27,6 +27,11 @@
#include <types.h>
#include <utils/host.h>
/**
* printf() specifier for tRaffic selectors
*/
#define TRAFFIC_SELECTOR_PRINTF_SPEC 'R'
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;
@@ -160,6 +165,18 @@ struct traffic_selector_t {
*/
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.
*
@@ -173,16 +190,6 @@ struct traffic_selector_t {
*/
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.
*
+139 -75
View File
@@ -21,7 +21,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
@@ -34,7 +34,7 @@
#include <getopt.h>
#include <errno.h>
#include "daemon.h"
#include "daemon.h"
#include <types.h>
#include <config/credentials/local_credential_store.h>
@@ -53,11 +53,6 @@ struct private_daemon_t {
*/
daemon_t public;
/**
* A logger_t object assigned for daemon things.
*/
logger_t *logger;
/**
* Signal set used for signal handling.
*/
@@ -74,6 +69,37 @@ struct private_daemon_t {
*/
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
*/
@@ -94,27 +120,27 @@ static void run(private_daemon_t *this)
error = sigwait(&(this->signal_set), &signal_number);
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;
}
switch (signal_number)
{
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;
}
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;
}
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;
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;
}
}
@@ -144,20 +170,24 @@ static void destroy(private_daemon_t *this)
/* all child SAs should be down now, so kill kernel interface */
DESTROY_IF(this->public.kernel_interface);
/* 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.event_queue);
DESTROY_IF(this->public.configuration);
DESTROY_IF(this->public.credentials);
DESTROY_IF(this->public.connections);
DESTROY_IF(this->public.policies);
sched_yield();
/* 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.send_queue);
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);
}
@@ -167,7 +197,7 @@ static void destroy(private_daemon_t *this)
static void kill_daemon(private_daemon_t *this, char *reason)
{
/* 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())
{
/* initialization failed, terminate daemon */
@@ -177,7 +207,7 @@ static void kill_daemon(private_daemon_t *this, char *reason)
}
else
{
this->logger->log(this->logger, CONTROL, "sending SIGTERM to ourself", reason);
DBG1(SIG_DBG_DMN, "sending SIGTERM to ourself");
raise(SIGTERM);
/* thread must die, since he produced a ciritcal failure and can't continue */
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
*/
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;
signal_t signal;
/* for uncritical pseudo random numbers */
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.socket = socket_create(IKEV2_UDP_PORT, IKEV2_NATT_PORT);
this->public.ike_sa_manager = ike_sa_manager_create();
this->public.job_queue = job_queue_create();
this->public.event_queue = event_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.policies = (policy_store_t*)local_policy_store_create();
this->public.credentials = (credential_store_t*)local_credential_store_create(strict);
@@ -233,23 +289,19 @@ void signal_handler(int signal)
size_t size;
char **strings;
size_t i;
logger_t *logger;
size = backtrace(array, 20);
strings = backtrace_symbols(array, size);
logger = logger_manager->get_logger(logger_manager, DAEMON);
logger->log(logger, ERROR,
"Thread %u received %s. Dumping %d frames from stack:",
signal == SIGSEGV ? "SIGSEGV" : "SIGILL",
pthread_self(), size);
DBG1(SIG_DBG_DMN, "thread %u received %s. Dumping %d frames from stack:",
signal == SIGSEGV ? "SIGSEGV" : "SIGILL", pthread_self(), size);
for (i = 0; i < size; i++)
{
logger->log(logger, ERROR, " %s", strings[i]);
DBG1(SIG_DBG_DMN, " %s", strings[i]);
}
free (strings);
logger->log(logger, ERROR, "Killing ourself hard after SIGSEGV");
DBG1(SIG_DBG_DMN, "killing ourself hard after SIGSEGV");
raise(SIGKILL);
}
@@ -283,6 +335,7 @@ private_daemon_t *daemon_create(void)
this->public.bus = NULL;
this->public.outlog = NULL;
this->public.syslog = NULL;
this->public.authlog = NULL;
this->main_thread_id = pthread_self();
@@ -298,14 +351,8 @@ private_daemon_t *daemon_create(void)
action.sa_handler = signal_handler;
action.sa_mask = this->signal_set;
action.sa_flags = 0;
if (sigaction(SIGSEGV, &action, NULL) == -1)
{
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");
}
sigaction(SIGSEGV, &action, NULL);
sigaction(SIGILL, &action, NULL);
return this;
}
@@ -315,64 +362,90 @@ private_daemon_t *daemon_create(void)
static void usage(const char *msg)
{
if (msg != NULL && *msg != '\0')
{
fprintf(stderr, "%s\n", msg);
fprintf(stderr, "Usage: charon"
" [--help]"
" [--version]"
" [--use-syslog]"
" [--strictcrlpolicy]"
"\n"
);
exit(msg == NULL? 0 : 1);
}
fprintf(stderr, "Usage: charon\n"
" [--help]\n"
" [--version]\n"
" [--strictcrlpolicy]\n"
" [--use-syslog]\n"
" [--debug-<type> <level>]\n"
" <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.
*/
int main(int argc, char *argv[])
{
{
bool strict_crl_policy = FALSE;
bool use_syslog = FALSE;
private_daemon_t *private_charon;
FILE *pid_file;
struct stat stb;
linked_list_t *list;
host_t *host;
level_t levels[SIG_DBG_MAX];
int signal;
/* handle arguments */
for (;;)
{
static const struct option long_opts[] = {
/* use CTRL loglevel for default */
for (signal = 0; signal < SIG_DBG_MAX; signal++)
{
levels[signal] = LEVEL_CTRL;
}
/* handle arguments */
for (;;)
{
struct option long_opts[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "use-syslog", no_argument, NULL, 'l' },
{ "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 }
};
int c = getopt_long(argc, argv, "", long_opts, NULL);
/* Note: "breaking" from case terminates loop */
switch (c)
{
case EOF: /* end of flags */
case EOF:
break;
case 'h':
usage(NULL);
break; /* not actually reached */
break;
case 'v':
printf("Linux strongSwan %s\n", VERSION);
exit(0);
case 'l':
logger_manager->set_output(logger_manager, ALL_LOGGERS, NULL);
use_syslog = TRUE;
continue;
case 'r':
strict_crl_policy = TRUE;
continue;
case 0:
/* option is in signal */
levels[signal] = atoi(optarg);
continue;
default:
usage("");
break; /* not actually reached */
break;
}
break;
}
@@ -380,19 +453,13 @@ int main(int argc, char *argv[])
private_charon = daemon_create();
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(private_charon, strict_crl_policy);
initialize(private_charon, strict_crl_policy, use_syslog, levels);
/* check/setup PID file */
if (stat(PID_FILE, &stb) == 0)
{
private_charon->logger->log(private_charon->logger, ERROR,
"charon already running (\""PID_FILE"\" exists)");
DBG1(SIG_DBG_DMN, "charon already running (\""PID_FILE"\" exists)");
destroy(private_charon);
exit(-1);
}
@@ -404,13 +471,10 @@ int main(int argc, char *argv[])
}
/* log socket info */
list = charon->socket->create_local_address_list(charon->socket);
private_charon->logger->log(private_charon->logger, CONTROL,
"listening on %d addresses:",
list->get_count(list));
DBG1(SIG_DBG_NET, "listening on %d addresses:", list->get_count(list));
while (list->remove_first(list, (void**)&host) == SUCCESS)
{
private_charon->logger->log(private_charon->logger, CONTROL,
" %H", host);
DBG1(SIG_DBG_NET, " %H", host);
host->destroy(host);
}
list->destroy(list);
@@ -421,6 +485,6 @@ int main(int argc, char *argv[])
/* normal termination, cleanup and exit */
destroy(private_charon);
unlink(PID_FILE);
return 0;
}
+7 -3
View File
@@ -1,8 +1,8 @@
/**
* @file daemon.h
*
*
* @brief Interface of daemon_t.
*
*
*/
/*
@@ -39,7 +39,6 @@
#include <queues/send_queue.h>
#include <queues/job_queue.h>
#include <queues/event_queue.h>
#include <utils/logger_manager.h>
#include <config/configuration.h>
#include <config/connections/connection_store.h>
#include <config/policies/policy_store.h>
@@ -362,6 +361,11 @@ struct daemon_t {
*/
sys_logger_t *syslog;
/**
* A bus listener logging most important events
*/
sys_logger_t *authlog;
/**
* Kernel Interface to communicate with kernel
*/
+41 -47
View File
@@ -32,7 +32,6 @@
#include <types.h>
#include <daemon.h>
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <encoding/payloads/payload.h>
#include <encoding/payloads/proposal_substructure.h>
#include <encoding/payloads/transform_substructure.h>
@@ -222,24 +221,19 @@ struct private_generator_t {
*/
u_int8_t last_spi_size;
/*
/**
* Attribute format of the last generated transform attribute.
*
*
* Used to check if a variable value field is used or not for
* the transform attribute value.
*/
bool attribute_format;
/*
/**
* Depending on the value of attribute_format this field is used
* to hold the length of the transform attribute in bytes.
*/
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;
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;
}
/* U_INT Types of multiple then 8 bits must be aligned */
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",
mapping_find(encoding_type_m,int_type));
DBG1(SIG_DBG_ENC, "U_INT Type %N is not 8 Bit aligned",
encoding_type_names, int_type);
/* current bit has to be zero for values multiple of 8 bits */
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;
/* highval is set, low_val is not changed */
*(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 */
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*/
u_int low_val = *((u_int8_t *)(this->data_struct + offset)) & 0x0F;
*(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->current_bit = 0;
}
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 */
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 */
*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++;
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 ! */
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! */
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 | 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)*/
this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t));
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:
{
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));
break;
}
case U_INT_32:
{
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));
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 */
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));
this->logger->log_bytes(this->logger, RAW|LEVEL2, " => (low)", (void*)&int32_val_low, sizeof(int32_val_low));
this->logger->log_bytes(this->logger, RAW|LEVEL2, " => (high)", (void*)&int32_val_high, sizeof(int32_val_high));
DBG3(SIG_DBG_ENC, " => %b %b",
(void*)&int32_val_low, sizeof(int32_val_low),
(void*)&int32_val_high, sizeof(int32_val_high));
/* 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_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 :-) */
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;
}
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;
}
}
@@ -450,7 +446,7 @@ static void generate_reserved_field(private_generator_t *this,int bits)
/* only one bit or 8 bit fields are supported */
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 ;
}
/* 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*/
if (this->current_bit > 0)
{
this->logger->log(this->logger, ERROR,
"Reserved field cannot be written cause allignement of current bit is %d",
this->current_bit);
DBG1(SIG_DBG_ENC, "reserved field cannot be written cause "
"alignement of current bit is %d", this->current_bit);
return;
}
*(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->logger->log(this->logger, RAW|LEVEL2, " => %d", *(this->out_position));
DBG3(SIG_DBG_ENC, " => %d", *(this->out_position));
this->current_bit++;
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)
{
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 ;
}
/* position in buffer */
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 */
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 out_position_offset = ((this->out_position) - (this->buffer));
this->logger->log(this->logger, CONTROL|LEVEL3, "increased gen buffer from %d to %d byte",
old_buffer_size, new_buffer_size);
DBG2(SIG_DBG_ENC, "increased gen buffer from %d to %d byte",
old_buffer_size, new_buffer_size);
/* Reallocate space for new buffer */
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);
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;
this->logger->log(this->logger, CONTROL|LEVEL1, "generating payload of type %s",
mapping_find(payload_type_m,payload_type));
DBG2(SIG_DBG_ENC, "generating payload of type %N",
payload_type_names, payload_type);
/* each payload has its own encoding rules */
payload->get_encoding_rules(payload,&rules,&rule_count);
for (i = 0; i < rule_count;i++)
{
this->logger->log(this->logger, CONTROL|LEVEL2, " generating rule %d %s",
i, mapping_find(encoding_type_m,rules[i].type));
DBG2(SIG_DBG_ENC, " generating rule %d %N",
i, encoding_type_names, 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 */
@@ -964,7 +959,7 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
{
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 */
this->generate_from_chunk(this,rules[i].offset);
}
@@ -1012,15 +1007,15 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
break;
}
default:
this->logger->log(this->logger, ERROR, "field type %s is not supported",
mapping_find(encoding_type_m,rules[i].type));
DBG1(SIG_DBG_ENC, "field type %N is not supported",
encoding_type_names, rules[i].type);
return;
}
}
this->logger->log(this->logger, CONTROL|LEVEL2, "generating %s payload finished.",
mapping_find(payload_type_m, payload_type));
this->logger->log_bytes(this->logger, RAW|LEVEL3, "generated data for this payload",
payload_start, this->out_position-payload_start);
DBG2(SIG_DBG_ENC, "generating %N payload finished",
payload_type_names, payload_type);
DBG3(SIG_DBG_ENC, "generated data for this payload %b",
payload_start, this->out_position-payload_start);
}
/**
@@ -1072,7 +1067,6 @@ generator_t *generator_create()
this->current_bit = 0;
this->last_payload_length_position_offset = 0;
this->header_length_position_offset = 0;
this->logger = logger_manager->get_logger(logger_manager, GENERATOR);
return &(this->public);
}
+324 -393
View File
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
#include <printf.h>
#include "message.h"
@@ -33,7 +34,6 @@
#include <encoding/generator.h>
#include <encoding/parser.h>
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <encoding/payloads/encodings.h>
#include <encoding/payloads/payload.h>
#include <encoding/payloads/encryption_payload.h>
@@ -42,7 +42,7 @@
/**
* 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;
@@ -66,7 +66,7 @@ struct payload_rule_t {
/**
* Max occurence of this payload.
*/
*/
size_t max_occurence;
/**
@@ -295,72 +295,6 @@ struct private_message_t {
* The message rule for this message instance
*/
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);
this->payloads->insert_last(this->payloads, (void*)payload);
this->logger->log(this->logger, CONTROL|LEVEL1, "added payload of type %s to message",
mapping_find(payload_type_m, payload->get_type(payload)));
DBG2(SIG_DBG_ENC ,"added payload of type %N to message",
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)
{
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;
payload_t *payload;
bool first = TRUE;
size_t total_written = 0;
size_t written;
*buffer = '\0';
size--;
if (this == NULL)
{
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);
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)
{
strncat(buffer, " ", size);
if (size)
written = fprintf(stream, " ");
if (written < 0)
{
size--;
return written;
}
total_written += written;
}
else
{
first = FALSE;
}
strncat(buffer, name, size);
if (name_len > size)
written = fprintf(stream, "%N", payload_type_short_names,
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
{
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;
status_t status;
chunk_t packet_data;
char payload_names[128];
if (is_encoded(this))
{
@@ -657,50 +702,41 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
return SUCCESS;
}
build_payload_string(this, payload_names, sizeof(payload_names));
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);
DBG1(SIG_DBG_ENC, "generating %M", this);
if (this->exchange_type == EXCHANGE_TYPE_UNDEFINED)
{
this->logger->log(this->logger, ERROR | LEVEL1, "exchange type %s is not defined",
mapping_find(exchange_type_m,this->exchange_type));
DBG1(SIG_DBG_ENC, "exchange type is not defined");
return INVALID_STATE;
}
if (this->packet->get_source(this->packet) == NULL ||
this->packet->get_destination(this->packet) == NULL)
{
this->logger->log(this->logger, ERROR|LEVEL1, "%s not defined",
!this->packet->get_source(this->packet) ? "source" : "destination");
DBG1(SIG_DBG_ENC, "%s not defined",
!this->packet->get_source(this->packet) ? "source" : "destination");
return INVALID_STATE;
}
/* set the rules for this messge */
status = this->set_message_rule(this);
status = set_message_rule(this);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "no message rules specified for a %s %s",
mapping_find(exchange_type_m,this->exchange_type),
this->is_request ? "request" : "response");
DBG1(SIG_DBG_ENC, "no message rules specified for this message type");
return NOT_SUPPORTED;
}
/* 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)
{
this->logger->log(this->logger, ERROR | LEVEL1, "could not encrypt payloads");
DBG1(SIG_DBG_ENC, "payload encryption failed");
return status;
}
/* build ike header */
ike_header = ike_header_create();
ike_header->set_exchange_type(ike_header, this->exchange_type);
ike_header->set_message_id(ike_header, this->message_id);
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 (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;
status = encryption_payload->build_signature(encryption_payload, packet_data);
if (status != SUCCESS)
@@ -752,8 +788,7 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
/* clone packet for caller */
*packet = this->packet->clone(this->packet);
this->logger->log(this->logger, CONTROL|LEVEL1, "message of type %s generated successfully",
mapping_find(exchange_type_m,this->exchange_type));
DBG2(SIG_DBG_ENC, "message generated successfully");
return SUCCESS;
}
@@ -781,14 +816,13 @@ static status_t parse_header(private_message_t *this)
ike_header_t *ike_header;
status_t status;
this->logger->log(this->logger, CONTROL|LEVEL1, "parsing Header of message");
DBG2(SIG_DBG_ENC, "parsing header of message");
this->parser->reset_context(this->parser);
status = this->parser->parse_payload(this->parser,HEADER,(payload_t **) &ike_header);
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;
}
@@ -797,10 +831,10 @@ static status_t parse_header(private_message_t *this)
status = ike_header->payload_interface.verify(&(ike_header->payload_interface));
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);
return status;
}
}
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->first_payload = ike_header->payload_interface.get_next_type(&(ike_header->payload_interface));
this->logger->log(this->logger, CONTROL|LEVEL1, "parsed a %s %s",
mapping_find(exchange_type_m, this->exchange_type),
this->is_request ? "request" : "response");
DBG2(SIG_DBG_ENC, "parsed a %N %s", exchange_type_names, this->exchange_type,
this->is_request ? "request" : "response");
ike_header->destroy(ike_header);
ike_header->destroy(ike_header);
/* get the rules for this messge */
status = this->set_message_rule(this);
status = set_message_rule(this);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "no message rules specified for a %s %s",
mapping_find(exchange_type_m,this->exchange_type),
this->is_request ? "request" : "response");
DBG1(SIG_DBG_ENC, "no message rules specified for a %N %s",
exchange_type_names, this->exchange_type,
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.
*/
@@ -1028,8 +895,8 @@ static status_t decrypt_payloads(private_message_t *this,crypter_t *crypter, sig
/* needed to check */
current_payload_type = current_payload->get_type(current_payload);
this->logger->log(this->logger, CONTROL|LEVEL2, "process payload of type %s",
mapping_find(payload_type_m,current_payload_type));
DBG2(SIG_DBG_ENC, "process payload of type %N",
payload_type_names, current_payload_type);
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;
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))
{
/* 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);
return VERIFY_ERROR;
}
/* decrypt */
encryption_payload->set_transforms(encryption_payload, crypter, signer);
this->logger->log(this->logger, CONTROL | LEVEL1, "verify signature of encryption payload");
status = encryption_payload->verify_signature(encryption_payload, this->packet->get_data(this->packet));
DBG2(SIG_DBG_ENC, "verify signature of encryption payload");
status = encryption_payload->verify_signature(encryption_payload,
this->packet->get_data(this->packet));
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "encryption payload signature invalid");
DBG1(SIG_DBG_ENC, "encryption payload signature invalid");
iterator->destroy(iterator);
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);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"encrypted payload could not be decrypted and parsed");
DBG1(SIG_DBG_ENC, "encrypted payload could not be decrypted and parsed");
iterator->destroy(iterator);
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 */
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 */
iterator->remove(iterator);
/* 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)
{
encryption_payload->remove_first_payload(encryption_payload, &current_encrypted_payload);
this->logger->log(this->logger, CONTROL | LEVEL1,
"insert unencrypted payload of type %s at end of list.",
mapping_find(payload_type_m, current_encrypted_payload->get_type(current_encrypted_payload)));
DBG2(SIG_DBG_ENC, "insert unencrypted payload of type %N at end of list",
payload_type_names, current_encrypted_payload->get_type(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)
{
/* 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)
{
/* payload is not allowed */
this->logger->log(this->logger, ERROR, "payload type %s not allowed",
mapping_find(payload_type_m,current_payload_type));
DBG1(SIG_DBG_ENC, "payload type %N not allowed",
payload_type_names, current_payload_type);
iterator->destroy(iterator);
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)
{
/* payload was not encrypted, but should have been. or vice-versa */
this->logger->log(this->logger, ERROR, "payload type %s should be %s!",
mapping_find(payload_type_m,current_payload_type),
(payload_rule->encrypted) ? "encrypted" : "not encrypted");
DBG1(SIG_DBG_ENC, "payload type %N should be %s!",
payload_type_names, current_payload_type,
(payload_rule->encrypted) ? "encrypted" : "not encrypted");
iterator->destroy(iterator);
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;
status_t status;
linked_list_t *all_payloads;
int i;
iterator_t *iterator;
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");
/* message contains no content to encrypt */
return SUCCESS;
}
size_t found_payloads = 0;
this->logger->log(this->logger, CONTROL | LEVEL2, "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();
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;
/* check all payloads for specific rule */
iterator->reset(iterator);
all_payloads->remove_first(all_payloads,(void **)&current_payload);
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))
while(iterator->has_next(iterator))
{
this->logger->log(this->logger, CONTROL | LEVEL2, "payload %s has to get encrypted",
mapping_find(payload_type_m,current_payload->get_type(current_payload)));
to_encrypt = TRUE;
}
else if (status != SUCCESS)
{
this->logger->log(this->logger, CONTROL | LEVEL2, "payload %s not defined for exchange type %s. Handle it anyway",
mapping_find(payload_type_m,current_payload->get_type(current_payload)),
mapping_find(exchange_type_m,this->exchange_type));
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))
{
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",
mapping_find(payload_type_m,current_payload->get_type(current_payload)));
encryption_payload->add_payload(encryption_payload,current_payload);
DBG1(SIG_DBG_ENC, "payload of type %N not occured %d times (%d)",
payload_type_names, this->message_rule->payload_rules[i].payload_type,
this->message_rule->payload_rules[i].min_occurence, found_payloads);
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",
mapping_find(payload_type_m,current_payload->get_type(current_payload)));
this->public.add_payload(&(this->public), (payload_t*)encryption_payload);
iterator->destroy(iterator);
return SUCCESS;
}
}
status = 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;
iterator->destroy(iterator);
return SUCCESS;
}
/**
* 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.
@@ -1297,18 +1237,11 @@ message_t *message_create_from_packet(packet_t *packet)
/* private values */
this->exchange_type = EXCHANGE_TYPE_UNDEFINED;
this->is_request = TRUE;
this->ike_sa_id = NULL;
this->first_payload = NO_PAYLOAD;
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;
this->is_request = TRUE;
this->ike_sa_id = NULL;
this->first_payload = NO_PAYLOAD;
this->message_id = 0;
/* private values */
if (packet == NULL)
{
@@ -1319,10 +1252,8 @@ message_t *message_create_from_packet(packet_t *packet)
this->payloads = linked_list_create();
/* parser is created from data of packet */
this->parser = parser_create(this->packet->get_data(this->packet));
this->logger = logger_manager->get_logger(logger_manager, MESSAGE);
this->parser = parser_create(this->packet->get_data(this->packet));
return (&this->public);
}
+5
View File
@@ -34,6 +34,11 @@
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
/**
* printf() specifier for message
*/
#define MESSAGE_PRINTF_SPEC 'M'
typedef struct message_t message_t;
+67 -84
View File
@@ -30,7 +30,6 @@
#include <types.h>
#include <definitions.h>
#include <daemon.h>
#include <utils/logger.h>
#include <utils/linked_list.h>
#include <encoding/payloads/encodings.h>
#include <encoding/payloads/payload.h>
@@ -233,11 +232,6 @@ struct private_parser_t {
* Set of encoding rules for this parsing session.
*/
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)
{
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s",
rule_number, mapping_find(encoding_type_m,
this->rules[rule_number].type));
DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR;
}
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++;
break;
default:
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
rule_number, mapping_find(encoding_type_m,
this->rules[rule_number].type), this->bit_pos);
DBG2(SIG_DBG_ENC, " found rule %d %N on bitpos %d",
rule_number, encoding_type_names,
this->rules[rule_number].type, this->bit_pos);
return PARSE_ERROR;
}
if (output_pos != NULL)
{
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *output_pos);
DBG3(SIG_DBG_ENC, " => %d", *output_pos);
}
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)
{
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s",
rule_number, mapping_find(encoding_type_m,
this->rules[rule_number].type));
DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR;
}
if (this->bit_pos)
{
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
rule_number, mapping_find(encoding_type_m,
this->rules[rule_number].type), this->bit_pos);
DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d",
rule_number, encoding_type_names,
this->rules[rule_number].type, this->bit_pos);
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)
{
*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++;
@@ -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)
{
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s",
rule_number, mapping_find(encoding_type_m,
this->rules[rule_number].type));
DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR;
}
if (this->bit_pos != 1)
{
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
this->bit_pos);
DBG2(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
encoding_type_names, this->rules[rule_number].type, this->bit_pos);
return PARSE_ERROR;
}
/* caller interested in result ? */
if (output_pos != NULL)
{
*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->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)
{
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR;
}
if (this->bit_pos)
{
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
this->bit_pos);
DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
encoding_type_names, this->rules[rule_number].type, this->bit_pos);
return PARSE_ERROR;
}
/* 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));
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *output_pos);
DBG3(SIG_DBG_ENC, " => %d", *output_pos);
}
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)
{
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR;
}
if (this->bit_pos)
{
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
this->bit_pos);
DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
encoding_type_names, this->rules[rule_number].type, this->bit_pos);
return PARSE_ERROR;
}
/* 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));
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *output_pos);
DBG3(SIG_DBG_ENC, " => %d", *output_pos);
}
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)
{
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR;
}
if (this->bit_pos)
{
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
this->bit_pos);
DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
encoding_type_names, this->rules[rule_number].type, this->bit_pos);
return PARSE_ERROR;
}
/* 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 = 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;
@@ -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)
{
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR;
}
if (this->bit_pos)
{
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
this->bit_pos);
DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
encoding_type_names, this->rules[rule_number].type, this->bit_pos);
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);
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;
@@ -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)
{
this->logger->log(this->logger, ERROR|LEVEL1, " not enough input to parse rule %d %s",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
DBG1(SIG_DBG_ENC, " not enough input to parse rule %d %N",
rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR;
}
/* 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;
}
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;
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)
{
this->logger->log(this->logger, ERROR|LEVEL1, " invalid length for rule %d %s",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
DBG1(SIG_DBG_ENC, " invalid length for rule %d %N",
rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR;
}
if (this->bit_pos)
{
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), this->bit_pos);
DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
encoding_type_names, this->rules[rule_number].type, this->bit_pos);
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;
payload_t *payload;
status_t status;
this->logger->log(this->logger, CONTROL|LEVEL1, " %d bytes left, parsing recursivly %s",
length, mapping_find(payload_type_m, payload_type));
DBG2(SIG_DBG_ENC, " %d bytes left, parsing recursivly %N",
length, payload_type_names, payload_type);
status = this->public.parse_payload((parser_t*)this, payload_type, &payload);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, " parsing of a %s substructure failed",
mapping_find(payload_type_m, payload_type));
DBG1(SIG_DBG_ENC, " parsing of a %N substructure failed",
payload_type_names, payload_type);
return status;
}
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)
{
this->logger->log(this->logger, ERROR, " not enough input (%d bytes) to parse rule %d %s",
length, rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
DBG1(SIG_DBG_ENC, " not enough input (%d bytes) to parse rule %d %N",
length, rule_number, encoding_type_names, this->rules[rule_number].type);
return PARSE_ERROR;
}
if (this->bit_pos)
{
this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), this->bit_pos);
DBG1(SIG_DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
encoding_type_names, this->rules[rule_number].type, this->bit_pos);
return PARSE_ERROR;
}
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);
}
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;
}
@@ -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 */
pld = payload_create(payload_type);
this->logger->log(this->logger, CONTROL|LEVEL1, "parsing %s payload, %d bytes left",
mapping_find(payload_type_m, payload_type),
this->input_roof-this->byte_pos);
DBG2(SIG_DBG_ENC, "parsing %N payload, %d bytes left",
payload_type_names, payload_type, this->input_roof - this->byte_pos);
this->logger->log_bytes(this->logger, RAW|LEVEL3, "parsing payload from", this->byte_pos,
this->input_roof-this->byte_pos);
DBG3(SIG_DBG_ENC, "parsing payload from %b",
this->byte_pos, this->input_roof-this->byte_pos);
if (pld->get_type(pld) == UNKNOWN_PAYLOAD)
{
this->logger->log(this->logger, ERROR|LEVEL1, " payload type %d is unknown, handling as %s",
payload_type, mapping_find(payload_type_m, UNKNOWN_PAYLOAD));
DBG1(SIG_DBG_ENC, " payload type %d is unknown, handling as %N",
payload_type, payload_type_names, UNKNOWN_PAYLOAD);
}
/* 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++)
{
rule = &(this->rules[rule_number]);
this->logger->log(this->logger, CONTROL|LEVEL2, " parsing rule %d %s",
rule_number, mapping_find(encoding_type_m, rule->type));
DBG2(SIG_DBG_ENC, " parsing rule %d %N",
rule_number, encoding_type_names, rule->type);
switch (rule->type)
{
case U_INT_4:
@@ -990,7 +975,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
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);
return PARSE_ERROR;
}
@@ -999,9 +985,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
rule++;
}
*payload = pld;
this->logger->log(this->logger, CONTROL|LEVEL2, "parsing %s payload finished.",
mapping_find(payload_type_m, payload_type));
*payload = pld;
DBG2(SIG_DBG_ENC, "parsing %N payload finished",
payload_type_names, payload_type);
return SUCCESS;
}
@@ -1038,8 +1024,6 @@ parser_t *parser_create(chunk_t data)
{
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.reset_context = (void(*)(parser_t*)) reset_context;
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_list = parse_list;
this->parse_chunk = parse_chunk;
this->input = data.ptr;
this->byte_pos = data.ptr;
this->bit_pos = 0;
@@ -1063,4 +1047,3 @@ parser_t *parser_create(chunk_t data)
return (parser_t*)this;
}
+3 -9
View File
@@ -26,10 +26,7 @@
#include "cert_payload.h"
/**
* String mappings for cert_encoding_t.
*/
static const char *const cert_encoding_name[] = {
ENUM(cert_encoding_names, CERT_NONE, CERT_X509_HASH_AND_URL_BUNDLE,
"CERT_NONE",
"CERT_PKCS7_WRAPPED_X509",
"CERT_PGP",
@@ -43,11 +40,8 @@ static const char *const cert_encoding_name[] = {
"CERT_X509_ATTRIBUTE",
"CERT_RAW_RSA_KEY",
"CERT_X509_HASH_AND_URL",
"CERT_X509_HASH_AND_URL_BUNDLE"
};
enum_names cert_encoding_names =
{ CERT_NONE, CERT_X509_HASH_AND_URL_BUNDLE, cert_encoding_name, NULL };
"CERT_X509_HASH_AND_URL_BUNDLE",
);
typedef struct private_cert_payload_t private_cert_payload_t;
+1 -1
View File
@@ -64,7 +64,7 @@ enum cert_encoding_t {
*
* @ingroup payloads
*/
extern enum_names cert_encoding_names;
extern enum_name_t *cert_encoding_names;
typedef struct cert_payload_t cert_payload_t;
@@ -58,27 +58,23 @@ struct private_configuration_attribute_t {
chunk_t attribute_value;
};
/**
* String mappings for configuration_attribute_type_t.
*/
mapping_t configuration_attribute_type_m[] = {
{INTERNAL_IP4_ADDRESS, "INTERNAL_IP4_ADDRESS"},
{INTERNAL_IP4_NETMASK, "INTERNAL_IP4_NETMASK"},
{INTERNAL_IP4_DNS, "INTERNAL_IP4_DNS"},
{INTERNAL_IP4_NBNS, "INTERNAL_IP4_NBNS"},
{INTERNAL_ADDRESS_EXPIRY, "INTERNAL_ADDRESS_EXPIRY"},
{INTERNAL_IP4_DHCP, "INTERNAL_IP4_DHCP"},
{APPLICATION_VERSION, "APPLICATION_VERSION"},
{INTERNAL_IP6_ADDRESS, "INTERNAL_IP6_ADDRESS"},
{INTERNAL_IP6_DNS, "INTERNAL_IP6_DNS"},
{INTERNAL_IP6_NBNS, "INTERNAL_IP6_NBNS"},
{INTERNAL_IP6_DHCP, "INTERNAL_IP6_DHCP"},
{INTERNAL_IP4_SUBNET, "INTERNAL_IP4_SUBNET"},
{SUPPORTED_ATTRIBUTES, "SUPPORTED_ATTRIBUTES"},
{INTERNAL_IP6_SUBNET, "INTERNAL_IP6_SUBNET"},
{MAPPING_END, NULL}
};
ENUM_BEGIN(configuration_attribute_type_name, INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS,
"INTERNAL_IP4_ADDRESS",
"INTERNAL_IP4_NETMASK",
"INTERNAL_IP4_DNS",
"INTERNAL_IP4_NBNS",
"INTERNAL_ADDRESS_EXPIRY",
"INTERNAL_IP4_DHCP",
"APPLICATION_VERSION",
"INTERNAL_IP6_ADDRESS");
ENUM_NEXT(configuration_attribute_type_name, INTERNAL_IP6_DNS, INTERNAL_IP6_SUBNET, INTERNAL_IP6_ADDRESS,
"INTERNAL_IP6_DNS",
"INTERNAL_IP6_NBNS",
"INTERNAL_IP6_DHCP",
"INTERNAL_IP4_SUBNET",
"SUPPORTED_ATTRIBUTES",
"INTERNAL_IP6_SUBNET");
ENUM_END(configuration_attribute_type_name, INTERNAL_IP6_SUBNET);
/**
* 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
*/
extern mapping_t configuration_attribute_type_m[];
extern enum_name_t *configuration_attribute_type_names;
typedef struct configuration_attribute_t configuration_attribute_t;
+27 -44
View File
@@ -28,18 +28,12 @@
#include <encoding/payloads/encodings.h>
#include <utils/linked_list.h>
/**
* String mappings for config_type_t.
*/
mapping_t config_type_m[] = {
{CFG_REQUEST, "CFG_REQUEST"},
{CFG_REPLY, "CFG_REPLY"},
{CFG_SET, "CFG_SET"},
{CFG_ACK, "CFG_ACK"},
{MAPPING_END, NULL}
};
ENUM(config_type_names, CFG_REQUEST, CFG_ACK,
"CFG_REQUEST",
"CFG_REPLY",
"CFG_SET",
"CFG_ACK",
);
typedef struct private_cp_payload_t private_cp_payload_t;
@@ -77,13 +71,6 @@ struct private_cp_payload_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;
}
/**
* 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.
*/
static size_t get_length(private_cp_payload_t *this)
{
this->compute_length(this);
compute_length(this);
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)
{
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;
}
/**
* 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.
*/
@@ -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.destroy = (void (*) (cp_payload_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */
this->critical = FALSE;
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
*/
extern mapping_t config_type_m[];
extern enum_name_t *config_type_names;
typedef struct cp_payload_t cp_payload_t;
+41 -43
View File
@@ -24,46 +24,44 @@
#include "encodings.h"
mapping_t encoding_type_m[] = {
{U_INT_4, "U_INT_4"},
{U_INT_8, "U_INT_8"},
{U_INT_16, "U_INT_16"},
{U_INT_32, "U_INT_32"},
{U_INT_64, "U_INT_64"},
{IKE_SPI, "IKE_SPI"},
{RESERVED_BIT, "RESERVED_BIT"},
{RESERVED_BYTE, "RESERVED_BYTE"},
{FLAG, "FLAG"},
{PAYLOAD_LENGTH, "PAYLOAD_LENGTH"},
{HEADER_LENGTH, "HEADER_LENGTH"},
{SPI_SIZE, "SPI_SIZE"},
{SPI, "SPI"},
{KEY_EXCHANGE_DATA, "KEY_EXCHANGE_DATA"},
{NOTIFICATION_DATA, "NOTIFICATION_DATA"},
{PROPOSALS, "PROPOSALS"},
{TRANSFORMS, "TRANSFORMS"},
{TRANSFORM_ATTRIBUTES, "TRANSFORM_ATTRIBUTES"},
{ATTRIBUTE_FORMAT, "ATTRIBUTE_FORMAT"},
{ATTRIBUTE_TYPE, "ATTRIBUTE_TYPE"},
{ATTRIBUTE_LENGTH_OR_VALUE, "ATTRIBUTE_LENGTH_OR_VALUE"},
{ATTRIBUTE_VALUE, "ATTRIBUTE_VALUE"},
{NONCE_DATA, "NONCE_DATA"},
{ID_DATA, "ID_DATA"},
{AUTH_DATA, "AUTH_DATA"},
{ENCRYPTED_DATA, "ENCRYPTED_DATA"},
{TS_TYPE, "TS_TYPE"},
{ADDRESS, "ADDRESS"},
{TRAFFIC_SELECTORS, "TRAFFIC_SELECTORS"},
{CERT_DATA, "CERT_DATA"},
{CERTREQ_DATA, "CERTREQ_DATA"},
{SPIS, "SPIS"},
{VID_DATA, "VID_DATA"},
{VID_DATA, "VID_DATA"},
{CONFIGURATION_ATTRIBUTES, "CONFIGURATION_ATTRIBUTES"},
{CONFIGURATION_ATTRIBUTE_LENGTH, "CONFIGURATION_ATTRIBUTE_LENGTH"},
{CONFIGURATION_ATTRIBUTE_VALUE, "CONFIGURATION_ATTRIBUTE_VALUE"},
{EAP_MESSAGE, "EAP_MESSAGE"},
{UNKNOWN_DATA,"UNKNOWN_DATA"},
{MAPPING_END, NULL}
};
ENUM(encoding_type_names, U_INT_4, UNKNOWN_DATA,
"U_INT_4",
"U_INT_8",
"U_INT_16",
"U_INT_32",
"U_INT_64",
"IKE_SPI",
"RESERVED_BIT",
"RESERVED_BYTE",
"FLAG",
"PAYLOAD_LENGTH",
"HEADER_LENGTH",
"SPI_SIZE",
"SPI",
"KEY_EXCHANGE_DATA",
"NOTIFICATION_DATA",
"PROPOSALS",
"TRANSFORMS",
"TRANSFORM_ATTRIBUTES",
"ATTRIBUTE_FORMAT",
"ATTRIBUTE_TYPE",
"ATTRIBUTE_LENGTH_OR_VALUE",
"ATTRIBUTE_VALUE",
"NONCE_DATA",
"ID_DATA",
"AUTH_DATA",
"ENCRYPTED_DATA",
"TS_TYPE",
"ADDRESS",
"TRAFFIC_SELECTORS",
"CERT_DATA",
"CERTREQ_DATA",
"SPIS",
"VID_DATA",
"VID_DATA",
"CONFIGURATION_ATTRIBUTES",
"CONFIGURATION_ATTRIBUTE_LENGTH",
"CONFIGURATION_ATTRIBUTE_VALUE",
"EAP_MESSAGE",
"UNKNOWN_DATA",
);
+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
*/
extern mapping_t encoding_type_m[];
extern enum_name_t *encoding_type_names;
typedef struct encoding_rule_t encoding_rule_t;
+379 -418
View File
@@ -29,7 +29,6 @@
#include <daemon.h>
#include <encoding/payloads/encodings.h>
#include <utils/linked_list.h>
#include <utils/logger.h>
#include <encoding/generator.h>
#include <encoding/parser.h>
#include <utils/iterator.h>
@@ -37,8 +36,6 @@
#include <crypto/signers/signer.h>
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.
*/
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.
*/
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.
* (re-)compute the lenght of the whole payload
*/
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;
}
/**
* 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.
@@ -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.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 */
this->critical = FALSE;
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).
*/
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.
+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
*/
extern mapping_t exchange_type_m[];
extern enum_name_t *exchange_type_names;
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.
*/
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)
{
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)
static void compute_length(private_ke_payload_t *this)
{
size_t length = KE_PAYLOAD_HEADER_LENGTH;
if (this->key_exchange_data.ptr != NULL)
@@ -193,6 +177,14 @@ static void compute_length (private_ke_payload_t *this)
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.
@@ -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->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.destroy = (void (*) (ke_payload_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */
this->critical = FALSE;
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);
this->dh_group_number = dh->get_dh_group(dh);
this->compute_length(this);
compute_length(this);
return &this->public;
}
+10 -20
View File
@@ -60,13 +60,6 @@ struct private_nonce_payload_t {
* The contained nonce value.
*/
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.
*/
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.
* recompute the length of the payload.
*/
static void compute_length(private_nonce_payload_t *this)
{
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.
*/
@@ -226,9 +219,6 @@ nonce_payload_t *nonce_payload_create()
this->public.set_nonce = (void (*) (nonce_payload_t *,chunk_t)) set_nonce;
this->public.get_nonce = (chunk_t (*) (nonce_payload_t *)) get_nonce;
/* private functions */
this->compute_length = compute_length;
/* private variables */
this->critical = FALSE;
this->next_payload = NO_PAYLOAD;
+69 -81
View File
@@ -28,50 +28,54 @@
#include <daemon.h>
#include <encoding/payloads/encodings.h>
#include <crypto/hashers/hasher.h>
#define SHA1_HASH_SIZE 20
/**
* String mappings for notify_type_t.
*/
mapping_t notify_type_m[] = {
{UNSUPPORTED_CRITICAL_PAYLOAD, "UNSUPPORTED_CRITICAL_PAYLOAD"},
{INVALID_IKE_SPI, "INVALID_IKE_SPI"},
{INVALID_MAJOR_VERSION, "INVALID_MAJOR_VERSION"},
{INVALID_SYNTAX, "INVALID_SYNTAX"},
{INVALID_MESSAGE_ID, "INVALID_MESSAGE_ID"},
{INVALID_SPI, "INVALID_SPI"},
{NO_PROPOSAL_CHOSEN, "NO_PROPOSAL_CHOSEN"},
{INVALID_KE_PAYLOAD, "INVALID_KE_PAYLOAD"},
{AUTHENTICATION_FAILED, "AUTHENTICATION_FAILED"},
{SINGLE_PAIR_REQUIRED, "SINGLE_PAIR_REQUIRED"},
{NO_ADDITIONAL_SAS, "NO_ADDITIONAL_SAS"},
{INTERNAL_ADDRESS_FAILURE, "INTERNAL_ADDRESS_FAILURE"},
{FAILED_CP_REQUIRED, "FAILED_CP_REQUIRED"},
{TS_UNACCEPTABLE, "TS_UNACCEPTABLE"},
{INVALID_SELECTORS, "INVALID_SELECTORS"},
{INITIAL_CONTACT, "INITIAL_CONTACT"},
{SET_WINDOW_SIZE, "SET_WINDOW_SIZE"},
{ADDITIONAL_TS_POSSIBLE, "ADDITIONAL_TS_POSSIBLE"},
{IPCOMP_SUPPORTED, "IPCOMP_SUPPORTED"},
{NAT_DETECTION_SOURCE_IP, "NAT_DETECTION_SOURCE_IP"},
{NAT_DETECTION_DESTINATION_IP, "NAT_DETECTION_DESTINATION_IP"},
{COOKIE, "COOKIE"},
{USE_TRANSPORT_MODE, "USE_TRANSPORT_MODE"},
{HTTP_CERT_LOOKUP_SUPPORTED, "HTTP_CERT_LOOKUP_SUPPORTED"},
{REKEY_SA, "REKEY_SA"},
{ESP_TFC_PADDING_NOT_SUPPORTED, "ESP_TFC_PADDING_NOT_SUPPORTED"},
{NON_FIRST_FRAGMENTS_ALSO, "NON_FIRST_FRAGMENTS_ALSO"},
{MOBIKE_SUPPORTED, "MOBIKE_SUPPORTED"},
{ADDITIONAL_IP4_ADDRESS, "ADDITIONAL_IP4_ADDRESS"},
{ADDITIONAL_IP6_ADDRESS, "ADDITIONAL_IP6_ADDRESS"},
{NO_ADDITIONAL_ADDRESSES, "NO_ADDITIONAL_ADDRESSES"},
{UPDATE_SA_ADDRESSES, "UPDATE_SA_ADDRESSES"},
{COOKIE2, "COOKIE2"},
{NO_NATS_ALLOWED, "NO_NATS_ALLOWED"},
{AUTH_LIFETIME, "AUTH_LIFETIME"},
{MAPPING_END, NULL}
};
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,
"INVALID_IKE_SPI",
"INVALID_MAJOR_VERSION");
ENUM_NEXT(notify_type_names, INVALID_SYNTAX, INVALID_SYNTAX, INVALID_MAJOR_VERSION,
"INVALID_SYNTAX");
ENUM_NEXT(notify_type_names, INVALID_MESSAGE_ID, INVALID_MESSAGE_ID, INVALID_SYNTAX,
"INVALID_MESSAGE_ID");
ENUM_NEXT(notify_type_names, INVALID_SPI, INVALID_SPI, INVALID_MESSAGE_ID,
"INVALID_SPI");
ENUM_NEXT(notify_type_names, NO_PROPOSAL_CHOSEN, NO_PROPOSAL_CHOSEN, INVALID_SPI,
"NO_PROPOSAL_CHOSEN");
ENUM_NEXT(notify_type_names, INVALID_KE_PAYLOAD, INVALID_KE_PAYLOAD, NO_PROPOSAL_CHOSEN,
"INVALID_KE_PAYLOAD");
ENUM_NEXT(notify_type_names, AUTHENTICATION_FAILED, AUTHENTICATION_FAILED, INVALID_KE_PAYLOAD,
"AUTHENTICATION_FAILED");
ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, INVALID_SELECTORS, AUTHENTICATION_FAILED,
"SINGLE_PAIR_REQUIRED",
"NO_ADDITIONAL_SAS",
"INTERNAL_ADDRESS_FAILURE",
"FAILED_CP_REQUIRED",
"TS_UNACCEPTABLE",
"INVALID_SELECTORS");
ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, INVALID_SELECTORS,
"INITIAL_CONTACT",
"SET_WINDOW_SIZE",
"ADDITIONAL_TS_POSSIBLE",
"IPCOMP_SUPPORTED",
"NAT_DETECTION_SOURCE_IP",
"NAT_DETECTION_DESTINATION_IP",
"COOKIE",
"USE_TRANSPORT_MODE",
"HTTP_CERT_LOOKUP_SUPPORTED",
"REKEY_SA",
"ESP_TFC_PADDING_NOT_SUPPORTED",
"NON_FIRST_FRAGMENTS_ALSO",
"MOBIKE_SUPPORTED",
"ADDITIONAL_IP4_ADDRESS",
"ADDITIONAL_IP6_ADDRESS",
"NO_ADDITIONAL_ADDRESSES",
"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;
@@ -124,18 +128,6 @@ struct private_notify_payload_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:
if (this->spi.len != 4)
{
this->logger->log(this->logger, ERROR, "Invalid SPI size for %s",
mapping_find(protocol_id_m, this->protocol_id));
DBG1(SIG_DBG_ENC, "Invalid SPI size for %N",
protocol_id_names, this->protocol_id);
return FAILED;
}
break;
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;
}
@@ -237,7 +229,7 @@ static status_t verify(private_notify_payload_t *this)
case MODP_8192_BIT:
break;
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;
}
break;
@@ -245,10 +237,10 @@ static status_t verify(private_notify_payload_t *this)
case NAT_DETECTION_SOURCE_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",
mapping_find(notify_type_m, this->notify_type));
DBG1(SIG_DBG_ENC, "invalid %N notify length",
notify_type_names, this->notify_type);
return FAILED;
}
break;
@@ -259,8 +251,8 @@ static status_t verify(private_notify_payload_t *this)
{
if (this->notification_data.len != 0)
{
this->logger->log(this->logger, ERROR, "invalid %s notify",
mapping_find(notify_type_m, this->notify_type));
DBG1(SIG_DBG_ENC, "invalid %N notify",
notify_type_names, this->notify_type);
return FAILED;
}
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.
*/
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.
* recompute the payloads length.
*/
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;
}
/**
* 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.
*/
@@ -395,7 +387,7 @@ static void set_spi(private_notify_payload_t *this, u_int32_t spi)
break;
}
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);
this->notification_data = chunk_clone(notification_data);
this->compute_length(this);
compute_length(this);
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.destroy = (void (*) (notify_payload_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */
this->critical = FALSE;
this->next_payload = NO_PAYLOAD;
@@ -469,8 +458,7 @@ notify_payload_t *notify_payload_create()
this->spi_size = 0;
this->notification_data.ptr = NULL;
this->notification_data.len = 0;
this->logger = logger_manager->get_logger(logger_manager, PAYLOAD);
return &this->public;
}
@@ -90,12 +90,12 @@ enum notify_type_t {
AUTH_LIFETIME = 16403,
};
/**
* String mappings for notify_type_t.
*
/**
* enum name for notify_type_t.
*
* @ingroup payloads
*/
extern mapping_t notify_type_m[];
extern enum_name_t *notify_type_names;
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/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}
};
/*
* build the short mappings for payload_type_t
*/
mapping_t payload_type_short_m[] = {
{NO_PAYLOAD, "--"},
{SECURITY_ASSOCIATION, "SA"},
{KEY_EXCHANGE, "KE"},
{ID_INITIATOR, "IDi"},
{ID_RESPONDER, "IDr"},
{CERTIFICATE, "CERT"},
{CERTIFICATE_REQUEST, "CERTREQ"},
{AUTHENTICATION, "AUTH"},
{NONCE, "No"},
{NOTIFY, "N"},
{DELETE, "D"},
{VENDOR_ID, "V"},
{TRAFFIC_SELECTOR_INITIATOR, "TSi"},
{TRAFFIC_SELECTOR_RESPONDER, "TSr"},
{ENCRYPTED, "E"},
{CONFIGURATION, "CP"},
{EXTENSIBLE_AUTHENTICATION, "EAP"},
{HEADER, "HDR"},
{PROPOSAL_SUBSTRUCTURE, "PROP"},
{TRANSFORM_SUBSTRUCTURE, "TRANS"},
{TRANSFORM_ATTRIBUTE, "TRANSATTR"},
{TRAFFIC_SELECTOR_SUBSTRUCTURE, "TSSUB"},
{CONFIGURATION_ATTRIBUTE, "CPATTR"},
{UNKNOWN_PAYLOAD, "??"},
{MAPPING_END, NULL}
};
ENUM_BEGIN(payload_type_names, NO_PAYLOAD, NO_PAYLOAD,
"NO_PAYLOAD");
ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, NO_PAYLOAD,
"SECURITY_ASSOCIATION",
"KEY_EXCHANGE",
"ID_INITIATOR",
"ID_RESPONDER",
"CERTIFICATE",
"CERTIFICATE_REQUEST",
"AUTHENTICATION",
"NONCE",
"NOTIFY",
"DELETE",
"VENDOR_ID",
"TRAFFIC_SELECTOR_INITIATOR",
"TRAFFIC_SELECTOR_RESPONDER",
"ENCRYPTED",
"CONFIGURATION",
"EXTENSIBLE_AUTHENTICATION");
ENUM_NEXT(payload_type_names, HEADER, UNKNOWN_PAYLOAD, EXTENSIBLE_AUTHENTICATION,
"HEADER",
"PROPOSAL_SUBSTRUCTURE",
"TRANSFORM_SUBSTRUCTURE",
"TRANSFORM_ATTRIBUTE",
"TRAFFIC_SELECTOR_SUBSTRUCTURE",
"CONFIGURATION_ATTRIBUTE",
"UNKNOWN_PAYLOAD");
ENUM_END(payload_type_names, UNKNOWN_PAYLOAD);
/* 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
+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;
@@ -29,7 +29,7 @@
#include <encoding/payloads/transform_substructure.h>
#include <types.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.
*/
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))
{
/* must be 0 or 2 */
this->logger->log(this->logger, ERROR, "inconsistent next payload");
DBG1(SIG_DBG_ENC, "inconsistent next payload");
return FAILED;
}
if (this->transforms_count != this->transforms->get_count(this->transforms))
{
/* must be the same! */
this->logger->log(this->logger, ERROR, "transform count invalid");
DBG1(SIG_DBG_ENC, "transform count invalid");
return FAILED;
}
@@ -174,29 +162,26 @@ static status_t verify(private_proposal_substructure_t *this)
case PROTO_ESP:
if (this->spi.len != 4)
{
this->logger->log(this->logger, ERROR,
"invalid SPI length in %s proposal",
mapping_find(protocol_id_m, this->protocol_id));
DBG1(SIG_DBG_ENC, "invalid SPI length in %N proposal",
protocol_id_names, this->protocol_id);
return FAILED;
}
break;
case PROTO_IKE:
if (this->spi.len != 0 && this->spi.len != 8)
{
this->logger->log(this->logger, ERROR,
"invalid SPI length in IKE proposal");
DBG1(SIG_DBG_ENC, "invalid SPI length in IKE proposal");
return FAILED;
}
break;
default:
this->logger->log(this->logger, ERROR,
"invalid proposal protocol (%d)", this->protocol_id);
DBG1(SIG_DBG_ENC, "invalid proposal protocol (%d)", this->protocol_id);
return FAILED;
}
if ((this->protocol_id == 0) || (this->protocol_id >= 4))
{
/* reserved are not supported */
this->logger->log(this->logger, ERROR, "invalid protocol");
DBG1(SIG_DBG_ENC, "invalid protocol");
return FAILED;
}
@@ -209,7 +194,7 @@ static status_t verify(private_proposal_substructure_t *this)
status = current_transform->verify(current_transform);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "TRANSFORM_SUBSTRUCTURE verification failed");
DBG1(SIG_DBG_ENC, "TRANSFORM_SUBSTRUCTURE verification failed");
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.
*/
static size_t get_length(private_proposal_substructure_t *this)
{
this->compute_length(this);
compute_length(this);
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);
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);
this->spi.ptr = NULL;
this->spi.len = 0;
this->compute_length(this);
compute_length(this);
}
this->spi.ptr = clalloc(spi.ptr,spi.len);
this->spi.len = 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;
}
/**
* 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.
*/
@@ -544,9 +529,6 @@ proposal_substructure_t *proposal_substructure_create()
this->public.clone = (proposal_substructure_t * (*) (proposal_substructure_t *)) clone_;
this->public.destroy = (void (*) (proposal_substructure_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */
this->next_payload = NO_PAYLOAD;
this->proposal_length = 0;
@@ -556,7 +538,6 @@ proposal_substructure_t *proposal_substructure_create()
this->spi_size = 0;
this->spi.ptr = NULL;
this->spi.len = 0;
this->logger = logger_manager->get_logger(logger_manager, PAYLOAD);
this->transforms = linked_list_create();
+27 -44
View File
@@ -27,7 +27,7 @@
#include <encoding/payloads/encodings.h>
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <daemon.h>
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.
*/
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)
{
this->logger->log(this->logger, ERROR, "first proposal is not proposal #1");
DBG1(SIG_DBG_ENC, "first proposal is not proposal #1");
status = FAILED;
break;
}
if (current_number != (expected_number + 1))
{
this->logger->log(this->logger, ERROR, "proposal number is %d, excepted %d or %d",
current_number, expected_number, expected_number + 1);
DBG1(SIG_DBG_ENC, "proposal number is %d, excepted %d or %d",
current_number, expected_number, expected_number + 1);
status = FAILED;
break;
}
@@ -152,7 +140,7 @@ static status_t verify(private_sa_payload_t *this)
else if (current_number < expected_number)
{
/* 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;
break;
}
@@ -160,7 +148,7 @@ static status_t verify(private_sa_payload_t *this)
status = current_proposal->payload_interface.verify(&(current_proposal->payload_interface));
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "PROPOSAL_SUBSTRUCTURE verification failed");
DBG1(SIG_DBG_ENC, "PROPOSAL_SUBSTRUCTURE verification failed");
break;
}
first = FALSE;
@@ -224,12 +212,31 @@ static void set_next_type(private_sa_payload_t *this,payload_type_t 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.
*/
static size_t get_length(private_sa_payload_t *this)
{
this->compute_length(this);
compute_length(this);
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_proposal_number(proposal, proposal_count + 1);
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;
}
/**
* 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.
*/
@@ -363,15 +351,10 @@ sa_payload_t *sa_payload_create()
this->public.get_proposals = (linked_list_t* (*) (sa_payload_t *)) get_proposals;
this->public.destroy = (void (*) (sa_payload_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */
this->critical = FALSE;
this->next_payload = NO_PAYLOAD;
this->payload_length = SA_PAYLOAD_HEADER_LENGTH;
this->logger = logger_manager->get_logger(logger_manager, PARSER);
this->proposals = linked_list_create();
return &this->public;
}
@@ -26,15 +26,6 @@
#include <encoding/payloads/encodings.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;
@@ -65,14 +65,12 @@ struct private_transform_attribute_t {
chunk_t attribute_value;
};
/**
* String mappings for transform_attribute_type_t.
*/
mapping_t transform_attribute_type_m[] = {
{ATTRIBUTE_UNDEFINED, "ATTRIBUTE_UNDEFINED"},
{KEY_LENGTH, "KEY_LENGTH"},
{MAPPING_END, NULL}
};
ENUM_BEGIN(transform_attribute_type_name, ATTRIBUTE_UNDEFINED, ATTRIBUTE_UNDEFINED,
"ATTRIBUTE_UNDEFINED");
ENUM_NEXT(transform_attribute_type_name, KEY_LENGTH, KEY_LENGTH, ATTRIBUTE_UNDEFINED,
"KEY_LENGTH");
ENUM_END(transform_attribute_type_name, KEY_LENGTH);
/**
* 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
*/
extern mapping_t transform_attribute_type_m[];
extern enum_name_t *transform_attribute_type_names;
typedef struct transform_attribute_t transform_attribute_t;
@@ -29,7 +29,7 @@
#include <encoding/payloads/encodings.h>
#include <types.h>
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <daemon.h>
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.
*/
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))
{
/* must be 0 or 3 */
this->logger->log(this->logger, ERROR, "inconsistent next payload");
DBG1(SIG_DBG_ENC, "inconsistent next payload");
return FAILED;
}
@@ -152,8 +140,7 @@ static status_t verify(private_transform_substructure_t *this)
break;
default:
{
this->logger->log(this->logger, ERROR, "invalid transform type: %d",
this->transform_type);
DBG1(SIG_DBG_ENC, "invalid transform type: %d", this->transform_type);
return FAILED;
}
}
@@ -167,8 +154,7 @@ static status_t verify(private_transform_substructure_t *this)
status = current_attributes->verify(current_attributes);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"TRANSFORM_ATTRIBUTE verification failed");
DBG1(SIG_DBG_ENC, "TRANSFORM_ATTRIBUTE verification failed");
}
}
iterator->destroy(iterator);
@@ -202,13 +188,31 @@ static payload_type_t get_next_type(private_transform_substructure_t *this)
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.
*/
static size_t get_length(private_transform_substructure_t *this)
{
this->compute_length(this);
compute_length(this);
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)
{
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;
}
/**
* 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.
*/
@@ -410,16 +395,12 @@ transform_substructure_t *transform_substructure_create()
this->public.clone = (transform_substructure_t* (*) (transform_substructure_t *)) clone_;
this->public.destroy = (void (*) (transform_substructure_t *)) destroy;
/* private functions */
this->compute_length = compute_length;
/* set default values of the fields */
this->next_payload = NO_PAYLOAD;
this->transform_length = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
this->transform_id = 0;
this->transform_type = 0;
this->attributes = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, PAYLOAD);
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.
*/
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;
}
/**
* 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.
*/
static size_t get_length(private_ts_payload_t *this)
{
this->compute_length(this);
compute_length(this);
return this->payload_length;
}
@@ -259,30 +275,6 @@ static linked_list_t *get_traffic_selectors(private_ts_payload_t *this)
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.
*/
@@ -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.get_traffic_selectors = (linked_list_t *(*) (ts_payload_t *)) get_traffic_selectors;
/* private functions */
this->compute_length = compute_length;
/* private variables */
this->critical = FALSE;
this->next_payload = NO_PAYLOAD;
+36 -71
View File
@@ -43,7 +43,6 @@
#include "socket.h"
#include <daemon.h>
#include <utils/logger_manager.h>
/* constants for packet handling */
#define IP_LEN sizeof(struct iphdr)
@@ -126,11 +125,6 @@ struct private_socket_t{
* send socket on nat-t port for IPv6
*/
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);
}
this->logger->log(this->logger, CONTROL|LEVEL1,
"waiting for data on raw sockets");
DBG2(SIG_DBG_NET, "waiting for data on raw sockets");
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
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);
if (bytes_read < 0)
{
this->logger->log(this->logger, ERROR,
"error reading from IPv4 socket: %m");
DBG1(SIG_DBG_NET, "error reading from IPv4 socket: %m");
return FAILED;
}
this->logger->log_bytes(this->logger, RAW,
"received IPv4 packet", buffer, bytes_read);
DBG3(SIG_DBG_NET, "received IPv4 packet %b", buffer, bytes_read);
/* read source/dest from raw IP/UDP header */
if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
{
this->logger->log(this->logger, ERROR,
"received IPv4 packet too short");
DBG1(SIG_DBG_NET, "received IPv4 packet too short (%d bytes)",
bytes_read);
return FAILED;
}
ip = (struct iphdr*) buffer;
@@ -207,8 +198,7 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
pkt = packet_create();
pkt->set_source(pkt, source);
pkt->set_destination(pkt, dest);
this->logger->log(this->logger, CONTROL|LEVEL1,
"received packet: from %#H to %#H", source, dest);
DBG2(SIG_DBG_NET, "received packet: from %#H to %#H", source, dest);
data_offset = IP_LEN + UDP_LEN;
/* remove non esp marker */
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);
if (bytes_read < 0)
{
this->logger->log(this->logger, ERROR,
"error reading from IPv6 socket: %m");
DBG1(SIG_DBG_NET, "error reading from IPv6 socket: %m");
return FAILED;
}
this->logger->log_bytes(this->logger, RAW,
"received IPv6 packet", buffer, bytes_read);
DBG3(SIG_DBG_NET, "received IPv6 packet %b", buffer, bytes_read);
if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
{
this->logger->log(this->logger, ERROR,
"received IPv6 packet too short");
DBG3(SIG_DBG_NET, "received IPv6 packet too short (%d bytes)",
bytes_read);
return FAILED;
}
@@ -262,10 +250,9 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
{
if (cmsgptr->cmsg_len == 0)
if (cmsgptr->cmsg_len == 0)
{
this->logger->log(this->logger, ERROR,
"error reading IPv6 ancillary data: %m");
DBG1(SIG_DBG_NET, "error reading IPv6 ancillary data");
return FAILED;
}
if (cmsgptr->cmsg_level == SOL_IPV6 &&
@@ -286,8 +273,7 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
/* ancillary data missing? */
if (dest == NULL)
{
this->logger->log(this->logger, ERROR,
"error reading IPv6 packet header");
DBG1(SIG_DBG_NET, "error reading IPv6 packet header");
return FAILED;
}
@@ -296,8 +282,7 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
pkt = packet_create();
pkt->set_source(pkt, source);
pkt->set_destination(pkt, dest);
this->logger->log(this->logger, CONTROL|LEVEL1,
"received packet: from %#H to %#H", source, dest);
DBG2(SIG_DBG_NET, "received packet: from %#H to %#H", source, dest);
data_offset = UDP_LEN;
/* remove non esp marker */
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);
data = packet->get_data(packet);
this->logger->log(this->logger, CONTROL|LEVEL1,
"sending packet: from %#H to %#H", src, dst);
DBG2(SIG_DBG_NET, "sending packet: from %#H to %#H", src, dst);
/* send data */
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 */
if (data.len > MAX_PACKET - MARKER_LEN)
{
this->logger->log(this->logger, ERROR,
"unable to send packet: it's too big");
DBG1(SIG_DBG_NET, "unable to send packet: it's too big (%d bytes)",
data.len);
return FAILED;
}
marked = chunk_alloc(data.len + MARKER_LEN);
@@ -382,8 +366,7 @@ status_t sender(private_socket_t *this, packet_t *packet)
}
else
{
this->logger->log(this->logger, ERROR,
"unable to locate a send socket for port %d", sport);
DBG1(SIG_DBG_NET, "unable to locate a send socket for port %d", sport);
return FAILED;
}
@@ -392,8 +375,7 @@ status_t sender(private_socket_t *this, packet_t *packet)
if (bytes_sent != data.len)
{
this->logger->log(this->logger, ERROR,
"error writing to socket: %m");
DBG1(SIG_DBG_NET, "error writing to socket: %m");
return FAILED;
}
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);
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;
}
if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
{
this->logger->log(this->logger, ERROR,
"unable to set SO_REUSEADDR on send socket: %m");
DBG1(SIG_DBG_NET, "unable to set SO_REUSEADDR on send socket: %m");
close(skt);
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)
{
this->logger->log(this->logger, ERROR,
"unable to set IPSEC_POLICY on send socket: %m");
DBG1(SIG_DBG_NET, "unable to set IPSEC_POLICY on send socket: %m");
close(skt);
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;
if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
{
this->logger->log(this->logger, ERROR,
"unable to set IPSEC_POLICY on send socket: %m");
DBG1(SIG_DBG_NET, "unable to set IPSEC_POLICY on send socket: %m");
close(skt);
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 */
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);
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 */
if (setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
{
this->logger->log(this->logger, ERROR,
"unable to set UDP_ENCAP: %m; NAT-T may fail");
DBG1(SIG_DBG_NET, "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);
if (skt < 0)
{
this->logger->log(this->logger, ERROR,
"unable to create raw socket: %m");
DBG1(SIG_DBG_NET, "unable to create raw socket: %m");
return 0;
}
if (setsockopt(skt, SOL_SOCKET, SO_ATTACH_FILTER,
&ikev2_filter, sizeof(ikev2_filter)) < 0)
{
this->logger->log(this->logger, ERROR,
"unable to attach IKEv2 filter to raw socket: %m");
DBG1(SIG_DBG_NET, "unable to attach IKEv2 filter to raw socket: %m");
close(skt);
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 */
setsockopt(skt, sol, IPV6_2292PKTINFO, &on, sizeof(on)) < 0)
{
this->logger->log(this->logger, ERROR,
"unable to set IPV6_PKTINFO on raw socket: %m");
DBG1(SIG_DBG_NET, "unable to set IPV6_PKTINFO on raw socket: %m");
close(skt);
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)
{
this->logger->log(this->logger, ERROR,
"unable to set IPSEC_POLICY on raw socket: %m");
DBG1(SIG_DBG_NET, "unable to set IPSEC_POLICY on raw socket: %m");
close(skt);
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.create_local_address_list = (linked_list_t*(*)(socket_t*))create_local_address_list;
this->public.destroy = (void(*)(socket_t*)) destroy;
this->logger = logger_manager->get_logger(logger_manager, SOCKET);
this->port = 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);
if (this->recv4 == 0)
{
this->logger->log(this->logger, ERROR,
"could not open IPv4 receive socket, IPv4 disabled");
DBG1(SIG_DBG_NET, "could not open IPv4 receive socket, IPv4 disabled");
}
else
{
this->send4 = open_send_socket(this, AF_INET, this->port);
if (this->send4 == 0)
{
this->logger->log(this->logger, ERROR,
"could not open IPv4 send socket, IPv4 disabled");
DBG1(SIG_DBG_NET, "could not open IPv4 send socket, IPv4 disabled");
close(this->recv4);
}
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);
if (this->send4_natt == 0)
{
this->logger->log(this->logger, ERROR,
"could not open IPv4 NAT-T send socket");
DBG1(SIG_DBG_NET, "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);
if (this->recv6 == 0)
{
this->logger->log(this->logger, ERROR,
"could not open IPv6 receive socket, IPv6 disabled");
DBG1(SIG_DBG_NET, "could not open IPv6 receive socket, IPv6 disabled");
}
else
{
this->send6 = open_send_socket(this, AF_INET6, this->port);
if (this->send6 == 0)
{
this->logger->log(this->logger, ERROR,
"could not open IPv6 send socket, IPv6 disabled");
DBG1(SIG_DBG_NET, "could not open IPv6 send socket, IPv6 disabled");
close(this->recv6);
}
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);
if (this->send6_natt == 0)
{
this->logger->log(this->logger, ERROR,
"could not open IPv6 NAT-T send socket");
DBG1(SIG_DBG_NET, "could not open IPv6 NAT-T send socket");
}
}
}
if (!(this->send4 || this->send6) || !(this->recv4 || this->recv6))
{
this->logger->log(this->logger, ERROR,
"could not create any sockets");
DBG1(SIG_DBG_NET, "could not create any sockets");
destroy(this);
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
*/
u_int32_t reqid;
/**
* Logger ref
*/
logger_t *logger;
};
/**
@@ -66,8 +61,8 @@ static status_t execute(private_acquire_job_t *this)
this->reqid);
if (ike_sa == NULL)
{
this->logger->log(this->logger, ERROR|LEVEL1,
"CHILD_SA not found for acquiring");
DBG2(SIG_DBG_JOB, "CHILD_SA with reqid %d not found for acquiring",
this->reqid);
return DESTROY_ME;
}
ike_sa->acquire(ike_sa, this->reqid);
@@ -98,7 +93,6 @@ acquire_job_t *acquire_job_create(u_int32_t reqid)
/* private variables */
this->reqid = reqid;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public);
}
+2 -8
View File
@@ -51,11 +51,6 @@ struct private_delete_child_sa_job_t {
* inbound SPI of the CHILD_SA
*/
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);
if (ike_sa == NULL)
{
this->logger->log(this->logger, ERROR|LEVEL1,
"CHILD_SA not found for delete");
DBG1(SIG_DBG_JOB, "CHILD_SA with reqid %d not found for delete",
this->reqid);
return DESTROY_ME;
}
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->protocol = protocol;
this->spi = spi;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
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?
*/
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,
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;
}
@@ -96,8 +91,7 @@ static status_t execute(private_delete_ike_sa_job_t *this)
default:
{
/* IKE_SA is half open and gets destroyed */
this->logger->log(this->logger, AUDIT,
"deleting half open IKE_SA after timeout");
DBG1(SIG_DBG_JOB, "deleting half open IKE_SA after timeout");
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
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 */
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->delete_if_established = delete_if_established;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public);
}
+11 -21
View File
@@ -41,11 +41,6 @@ struct private_incoming_packet_job_t {
* Assigned 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);
return;
}
this->logger->log(this->logger, CONTROL, "sending %s notify",
mapping_find(notify_type_m, type));
DBG1(SIG_DBG_NET, "sending %N notify", notify_type_names, type);
charon->send_queue->add(charon->send_queue, packet);
response->destroy(response);
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));
src = message->get_source(message);
dst = message->get_destination(message);
this->logger->log(this->logger, CONTROL,
"received packet: from %#H to %#H", src, dst);
DBG1(SIG_DBG_NET, "received packet: from %#H to %#H", src, dst);
status = message->parse_header(message);
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);
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) ||
(message->get_minor_version(message) != IKE_MINOR_VERSION))
{
this->logger->log(this->logger, ERROR,
"received a packet with IKE version %d.%d, not supported",
message->get_major_version(message),
message->get_minor_version(message));
DBG1(SIG_DBG_NET,
"received a packet with IKE version %d.%d, not supported",
message->get_major_version(message),
message->get_minor_version(message));
if ((message->get_exchange_type(message) == IKE_SA_INIT) && (message->get_request(message)))
{
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);
if (ike_sa == NULL)
{
this->logger->log(this->logger, ERROR,
"received packet with SPIs %llx:%llx, but no such IKE_SA",
ike_sa_id->get_initiator_spi(ike_sa_id),
ike_sa_id->get_responder_spi(ike_sa_id));
DBG1(SIG_DBG_NET, "received packet for IKE_SA: %J, but no such IKE_SA",
ike_sa_id);
if (message->get_request(message))
{
/* TODO: send notify if we have NULL crypters,
* see todo in send_notify_response
/* TODO: send notify if we have NULL crypters,
* see todo in send_notify_response
send_notify_response(this, message, INVALID_IKE_SPI); */
}
ike_sa_id->destroy(ike_sa_id);
@@ -207,7 +198,6 @@ incoming_packet_job_t *incoming_packet_job_create(packet_t *packet)
/* private variables */
this->packet = packet;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public);
}
+1 -8
View File
@@ -48,11 +48,6 @@ struct private_initiate_job_t {
* associated policy to initiate
*/
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);
if (ike_sa->initiate(ike_sa, this->connection, this->policy) != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"initiation failed, going to delete IKE_SA");
DBG1(SIG_DBG_JOB, "initiation failed, going to delete IKE_SA");
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
return DESTROY_ME;
}
@@ -115,7 +109,6 @@ initiate_job_t *initiate_job_create(connection_t *connection, policy_t *policy)
/* private variables */
this->connection = connection;
this->policy = policy;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &this->public;
}
+13 -15
View File
@@ -24,18 +24,16 @@
#include "job.h"
mapping_t job_type_m[] = {
{INCOMING_PACKET, "INCOMING_PACKET"},
{RETRANSMIT_REQUEST, "RETRANSMIT_REQUEST"},
{INITIATE, "INITIATE"},
{ROUTE, "ROUTE"},
{ACQUIRE, "ACQUIRE"},
{DELETE_IKE_SA, "DELETE_IKE_SA"},
{DELETE_CHILD_SA, "DELETE_CHILD_SA"},
{REKEY_CHILD_SA, "REKEY_CHILD_SA"},
{REKEY_IKE_SA, "REKEY_IKE_SA"},
{SEND_KEEPALIVE, "SEND_KEEPALIVE"},
{SEND_DPD, "SEND_DPD"},
{MAPPING_END, NULL}
};
ENUM(job_type_names, INCOMING_PACKET, SEND_DPD,
"INCOMING_PACKET",
"RETRANSMIT_REQUEST",
"INITIATE",
"ROUTE",
"ACQUIRE",
"DELETE_IKE_SA",
"DELETE_CHILD_SA",
"REKEY_CHILD_SA",
"REKEY_IKE_SA",
"SEND_KEEPALIVE",
"SEND_DPD",
);
+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
*/
extern mapping_t job_type_m[];
extern enum_name_t *job_type_names;
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
*/
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);
if (ike_sa == NULL)
{
this->logger->log(this->logger, ERROR|LEVEL1,
"CHILD_SA not found for rekeying");
DBG2(SIG_DBG_JOB, "CHILD_SA with reqid %d not found for rekeying",
this->reqid);
return DESTROY_ME;
}
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->protocol = protocol;
this->spi = spi;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
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
*/
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);
if (ike_sa == NULL)
{
this->logger->log(this->logger, ERROR,
"IKE_SA to rekey not found");
DBG2(SIG_DBG_JOB, "IKE_SA %J to rekey not found", this->ike_sa_id);
return DESTROY_ME;
}
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 */
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public);
}
@@ -45,11 +45,6 @@ struct private_retransmit_request_job_t {
* ID of the IKE_SA which the message belongs to.
*/
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);
if (ike_sa == NULL)
{
this->logger->log(this->logger, ERROR|LEVEL1,
"IKE SA could not be checked out. Already deleted?");
DBG2(SIG_DBG_JOB, "IKE SA could not be checked out. Already deleted?");
return DESTROY_ME;
}
@@ -111,7 +105,6 @@ retransmit_request_job_t *retransmit_request_job_create(u_int32_t message_id,ike
/* private variables */
this->message_id = message_id;
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public);
}
+2 -10
View File
@@ -52,11 +52,6 @@ struct private_route_job_t {
* route or unroute?
*/
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)
{
this->logger->log(this->logger, ERROR,
"routing failed");
DBG1(SIG_DBG_JOB, "routing failed");
}
}
else
{
if (ike_sa->unroute(ike_sa, this->policy) == DESTROY_ME)
{
this->logger->log(this->logger, ERROR,
"removing IKE_SA, as last routed CHILD_SA unrouted");
DBG1(SIG_DBG_JOB, "removing IKE_SA, as last routed CHILD_SA unrouted");
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
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->policy = policy;
this->route = route;
this->logger = logger_manager->get_logger(logger_manager, WORKER);
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.
*/
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 */
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public);
}
@@ -44,11 +44,6 @@ struct private_send_keepalive_job_t {
* ID of the IKE_SA which the message belongs to.
*/
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 */
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->logger = logger_manager->get_logger(logger_manager, WORKER);
return &(this->public);
}
+4 -10
View File
@@ -26,7 +26,8 @@
#include "send_queue.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;
@@ -39,7 +40,7 @@ struct private_send_queue_t {
/**
* Public part of the send_queue_t object
*/
send_queue_t public;
send_queue_t public;
/**
* 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
*/
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);
dst = packet->get_destination(packet);
this->logger->log(this->logger, CONTROL,
"sending packet: from %#H to %#H", src, dst);
DBG1(SIG_DBG_NET, "sending packet: from %#H to %#H", src, dst);
pthread_mutex_lock(&this->mutex);
this->list->insert_last(this->list, packet);
@@ -152,7 +147,6 @@ send_queue_t *send_queue_create(void)
this->list = linked_list_create();
pthread_mutex_init(&this->mutex, NULL);
pthread_cond_init(&this->condvar, NULL);
this->logger = logger_manager->get_logger(logger_manager, SOCKET);
return (&this->public);
}
+48 -119
View File
@@ -47,7 +47,7 @@ struct private_authenticator_t {
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;
@@ -60,57 +60,10 @@ struct private_authenticator_t {
* PRF taken from the IKE_SA.
*/
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,
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,
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 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>) */
this->prf->set_key(this->prf, secret);
this->prf->get_bytes(this->prf, key_pad, key_buffer);
this->prf->set_key(this->prf, key);
this->prf->allocate_bytes(this->prf, octets, &auth_data);
this->logger->log_chunk(this->logger, RAW|LEVEL2,
"octets = message + nonce + prf(Sk_px, IDx')", octets);
this->logger->log_chunk(this->logger, PRIVATE|LEVEL2,
"secret", secret);
this->logger->log_chunk(this->logger, RAW|LEVEL2,
"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);
DBG3(SIG_DBG_IKE, "octets = message + nonce + prf(Sk_px, IDx') %B", &octets);
DBG3(SIG_DBG_IKE, "secret %B", &secret);
DBG3(SIG_DBG_IKE, "keypad %B", &key_pad);
DBG3(SIG_DBG_IKE, "prf(secret, keypad) %B", &key);
DBG3(SIG_DBG_IKE, "AUTH = prf(prf(secret, keypad), octets) %B", &auth_data);
chunk_free(&octets);
return auth_data;
@@ -220,19 +168,15 @@ static status_t verify_auth_data (private_authenticator_t *this,
&shared_key);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"no shared key found for '%D' - '%D'",
my_id, other_id);
DBG1(SIG_DBG_IKE, "no shared key found for '%D' - '%D'",
my_id, other_id);
chunk_free(&shared_key);
break;
}
my_auth_data = this->build_shared_key_signature(this,
last_received_packet,
my_nonce,
other_id,
initiator,
shared_key);
my_auth_data = build_shared_key_signature(this, last_received_packet,
my_nonce, other_id,
initiator, shared_key);
chunk_free(&shared_key);
@@ -251,15 +195,15 @@ static status_t verify_auth_data (private_authenticator_t *this,
if (public_key == NULL)
{
this->logger->log(this->logger, ERROR,
"no RSA public key found for '%D'", other_id);
DBG1(SIG_DBG_IKE, "no RSA public key found for '%D'", other_id);
status = NOT_FOUND;
break;
}
octets = this->build_tbs_octets(this, last_received_packet, my_nonce, other_id, initiator);
status = public_key->verify_emsa_pkcs1_signature(public_key, octets, auth_data);
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);
chunk_free(&octets);
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",
other_id, enum_name(&auth_method_names, auth_method),
(status == SUCCESS)? "successful":"failed");
DBG1(SIG_DBG_IKE, "authentication of '%D' with %N %s",
other_id, auth_method_names, auth_method,
(status == SUCCESS)? "successful":"failed");
return status;
}
@@ -285,10 +229,9 @@ static status_t compute_auth_data (private_authenticator_t *this,
identification_t *my_id,
identification_t *other_id,
bool initiator)
{
this->logger->log(this->logger, CONTROL,
"authentication of '%D' with %s (myself)",
my_id, enum_name(&auth_method_names, this->auth_method));
{
DBG1(SIG_DBG_IKE, "authentication of '%D' with %N (myself)",
my_id, auth_method_names, this->auth_method);
switch (this->auth_method)
{
@@ -304,21 +247,18 @@ static status_t compute_auth_data (private_authenticator_t *this,
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"no shared key found for '%D' - '%D'",
my_id, other_id);
DBG1(SIG_DBG_IKE, "no shared key found for '%D' - '%D'",
my_id, other_id);
return status;
}
auth_data = this->build_shared_key_signature(this,
last_sent_packet,
other_nonce,
my_id,
initiator,
shared_key);
auth_data = build_shared_key_signature(this, last_sent_packet,
other_nonce, my_id,
initiator, shared_key);
chunk_free(&shared_key);
*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);
chunk_free(&auth_data);
@@ -326,44 +266,40 @@ static status_t compute_auth_data (private_authenticator_t *this,
}
case RSA_DIGITAL_SIGNATURE:
{
char buf[BUF_LEN];
chunk_t chunk;
chunk_t octets;
chunk_t auth_data;
status_t status;
rsa_public_key_t *my_pubkey;
rsa_private_key_t *my_key;
this->logger->log(this->logger, CONTROL|LEVEL1,
"looking for RSA public key belonging to '%D'",
DBG2(SIG_DBG_IKE, "looking for RSA public key belonging to '%D'",
my_id);
my_pubkey = charon->credentials->get_rsa_public_key(charon->credentials, my_id);
if (my_pubkey == NULL)
{
this->logger->log(this->logger, ERROR,
"no RSA public key found for '%D'", my_id);
DBG1(SIG_DBG_IKE, "no RSA public key found for '%D'", my_id);
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));
this->logger->log(this->logger, CONTROL|LEVEL1, "looking for RSA private key with keyid %s", buf);
chunk = my_pubkey->get_keyid(my_pubkey);
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);
if (my_key == NULL)
{
char buf[BUF_LEN];
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);
DBG1(SIG_DBG_IKE, "no RSA private key found with for %D with keyid %#B",
my_id, &chunk);
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);
status = my_key->build_emsa_pkcs1_signature(my_key, HASH_SHA1, octets, &auth_data);
octets = build_tbs_octets(this, last_sent_packet, other_nonce,
my_id, initiator);
status = my_key->build_emsa_pkcs1_signature(my_key, HASH_SHA1,
octets, &auth_data);
chunk_free(&octets);
if (status != SUCCESS)
@@ -371,7 +307,7 @@ static status_t compute_auth_data (private_authenticator_t *this,
my_key->destroy(my_key);
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)->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 */
this->public.destroy = (void(*)(authenticator_t*))destroy;
this->public.verify_auth_data = (status_t (*) (authenticator_t*,auth_payload_t*,chunk_t,
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;
/* private functions */
this->build_tbs_octets = build_tbs_octets;
this->build_shared_key_signature = build_shared_key_signature;
this->public.verify_auth_data = (status_t (*) (authenticator_t*,auth_payload_t*,chunk_t,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;
/* private data */
this->ike_sa = ike_sa;
this->auth_method = auth_method;
this->prf = this->ike_sa->get_prf(this->ike_sa);
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &(this->public);
}
+121 -143
View File
@@ -22,25 +22,22 @@
* for more details.
*/
#define _GNU_SOURCE
#include "child_sa.h"
#include <stdio.h>
#include <string.h>
#include <printf.h>
#include <daemon.h>
/**
* String mappings for child_sa_state_t.
*/
mapping_t child_sa_state_m[] = {
{CHILD_CREATED, "CREATED"},
{CHILD_INSTALLED, "INSTALLED"},
{CHILD_ROUTED, "ROUTED"},
{CHILD_REKEYING, "REKEYING"},
{CHILD_DELETING, "DELETNG"},
{MAPPING_END, NULL}
};
ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DELETING,
"CREATED",
"ROUTED",
"INSTALLED",
"REKEYING",
"DELETING",
);
typedef struct sa_policy_t sa_policy_t;
@@ -170,11 +167,6 @@ struct private_child_sa_t {
* Specifies if NAT traversal is used
*/
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;
char command[1024];
char *ifname = NULL;
char *my_str, *other_str;
char *my_client, *other_client, *my_client_mask, *other_client_mask;
char *pos;
FILE *shell;
/* 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);
/* get subnet/bits from string */
my_client = strdup(my_str);
asprintf(&my_client, "%R", policy->my_ts);
pos = strchr(my_client, '/');
*pos = '\0';
my_client_mask = pos + 1;
@@ -274,7 +263,7 @@ static void updown(private_child_sa_t *this, bool up)
{
*pos = '\0';
}
other_client = strdup(other_str);
asprintf(&other_client, "%R", policy->other_ts);
pos = strchr(other_client, '/');
*pos = '\0';
other_client_mask = pos + 1;
@@ -313,8 +302,8 @@ static void updown(private_child_sa_t *this, bool up)
"%s"
"%s",
up ? "up" : "down",
/* TODO: fix it: streq(this->me.addr->get_string(this->me.addr),
my_client) ? "-host" :*/ "-client",
policy->my_ts->is_host(policy->my_ts,
this->me.addr) ? "-host" : "-client",
this->me.addr->get_family(this->me.addr) == AF_INET ? "" : "-ipv6",
this->name,
ifname,
@@ -341,9 +330,7 @@ static void updown(private_child_sa_t *this, bool up)
if (shell == NULL)
{
this->logger->log(this->logger, ERROR,
"could not execute updown script '%s'",
this->script);
DBG1(SIG_DBG_CHD, "could not execute updown script '%s'", this->script);
return;
}
@@ -355,8 +342,7 @@ static void updown(private_child_sa_t *this, bool up)
{
if (ferror(shell))
{
this->logger->log(this->logger, ERROR,
"error reading output from updown script");
DBG1(SIG_DBG_CHD, "error reading output from updown script");
return;
}
else
@@ -371,7 +357,7 @@ static void updown(private_child_sa_t *this, bool up)
{ /* trim trailing '\n' */
e[-1] = '\0';
}
this->logger->log(this->logger, ERROR, "updown: %s", resp);
DBG1(SIG_DBG_CHD, "updown: %s", resp);
}
}
pclose(shell);
@@ -507,15 +493,14 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
dst = this->other.addr;
}
this->logger->log(this->logger, CONTROL|LEVEL1, "adding %s %s SA",
mine ? "inbound" : "outbound",
mapping_find(protocol_id_m, this->protocol));
DBG2(SIG_DBG_CHD, "adding %s %N SA", mine ? "inbound" : "outbound",
protocol_id_names, this->protocol);
/* select encryption algo */
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &enc_algo))
{
this->logger->log(this->logger, CONTROL|LEVEL2, " using %s for encryption",
mapping_find(encryption_algorithm_m, enc_algo->algorithm));
DBG2(SIG_DBG_CHD, " using %N for encryption",
encryption_algorithm_names, enc_algo->algorithm);
}
else
{
@@ -525,8 +510,8 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
/* select integrity algo */
if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &int_algo))
{
this->logger->log(this->logger, CONTROL|LEVEL2, " using %s for integrity",
mapping_find(integrity_algorithm_m, int_algo->algorithm));
DBG2(SIG_DBG_CHD, " using %N for integrity",
integrity_algorithm_names, int_algo->algorithm);
}
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 */
this->logger->log(this->logger, CONTROL|LEVEL2,
" SPI 0x%.8x, src %H dst %H",
ntohl(spi), src, dst);
DBG2(SIG_DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
status = charon->kernel_interface->add_sa(charon->kernel_interface,
src, dst,
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))
{
this->logger->log(this->logger, CONTROL|LEVEL1,
"CHILD_SA policy uses two different IP families, ignored");
DBG2(SIG_DBG_CHD,
"CHILD_SA policy uses two different IP families, ignored");
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) &&
my_ts->get_protocol(my_ts) && other_ts->get_protocol(other_ts))
{
this->logger->log(this->logger, CONTROL|LEVEL1,
"CHILD_SA policy uses two different protocols, ignored");
DBG2(SIG_DBG_CHD,
"CHILD_SA policy uses two different protocols, ignored");
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;
char use_in_str[12] = "unused";
char use_out_str[12] = "unused";
char rekey_str[12] = "disabled";
char enc_str[32] = "";
char int_str[32] = "";
u_int32_t use_in, use_out, use_fwd, now, rekeying;
sa_policy_t *policy;
u_int32_t now, rekeying, use;
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);
fprintf_sum(stream, "%10s: %N, reqid: %d", this->name,
child_sa_state_names, this->state, this->reqid);
if (this->state == CHILD_INSTALLED)
{
/* query SA times */
status = charon->kernel_interface->query_sa(charon->kernel_interface,
this->me.addr, this->me.spi, this->protocol, &use_in);
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);
}
fprintf_sum(stream, ", %N, SPIs (in/out): 0x%x/0x%x",
protocol_id_names, this->protocol,
htonl(this->me.spi), htonl(this->other.spi));
/* calculate rekey times */
if (this->soft_lifetime)
if (info->alt)
{
rekeying = this->soft_lifetime - (now - this->install_time);
snprintf(rekey_str, sizeof(rekey_str), "%ds", (int)rekeying);
}
/* algorithms used */
if (this->protocol == PROTO_ESP)
{
if (this->encryption.key_size)
fprintf_sum(stream, "\n%10s: ", this->name);
if (this->protocol == PROTO_ESP)
{
snprintf(enc_str, sizeof(enc_str), "%s-%d,",
mapping_find(encryption_algorithm_m, this->encryption.algorithm),
this->encryption.key_size);
fprintf_sum(stream, "%N",
encryption_algorithm_names, this->encryption.algorithm);
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
{
snprintf(enc_str, sizeof(enc_str), "%s,",
mapping_find(encryption_algorithm_m, this->encryption.algorithm));
fprintf_sum(stream, "disabled");
}
}
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
{
logger->log(logger, CONTROL|LEVEL1, " \"%s\": state: %s, reqid: %d",
this->name, mapping_find(child_sa_state_m, this->state),
this->reqid);
}
#undef fprintf_sum
#define fprintf_sum(...) { written = fprintf(__VA_ARGS__); if (written < 0) { iterator->destroy(iterator); return written; } total_written += written; }
iterator = this->policies->create_iterator(this->policies, TRUE);
while (iterator->has_next(iterator))
while (iterator->iterate(iterator, (void**)&policy))
{
sa_policy_t *policy;
char *my_str;
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);
fprintf_sum(stream, "\n%10s: %R===%R, last use (in/out/fwd): ",
this->name, policy->my_ts, policy->other_ts);
/* query policy times */
status = charon->kernel_interface->query_policy(charon->kernel_interface,
policy->other_ts, policy->my_ts, POLICY_IN, &use_in);
if (status == SUCCESS && use_in)
policy->other_ts, policy->my_ts, POLICY_IN, &use);
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,
policy->my_ts, policy->other_ts, POLICY_OUT, &use_out);
if (status == SUCCESS && use_out)
policy->my_ts, policy->other_ts, POLICY_OUT, &use);
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,
policy->other_ts, policy->my_ts, POLICY_FWD, &use_fwd);
if (status == SUCCESS && use_fwd)
policy->other_ts, policy->my_ts, POLICY_FWD, &use);
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);
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;
}
this->logger->log(this->logger, CONTROL|LEVEL1,
"updating %s SA 0x%x, from %#H..#H to %#H..%#H",
mapping_find(protocol_id_m, this->protocol), ntohl(spi),
src, dst, new_src, new_dst);
DBG2(SIG_DBG_CHD, "updating %N SA 0x%x, from %#H..#H to %#H..%#H",
protocol_id_names, this->protocol, ntohl(spi), src, dst, new_src, new_dst);
status = charon->kernel_interface->update_sa(charon->kernel_interface,
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.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.log_status = (void (*)(child_sa_t*, logger_t*))log_status;
this->public.destroy = (void(*)(child_sa_t*))destroy;
/* private data */
this->logger = logger_manager->get_logger(logger_manager, CHILD_SA);
this->name = strdup("(uninitialized)");
this->me.addr = me->clone(me);
this->other.addr = other->clone(other);
+7 -16
View File
@@ -29,13 +29,17 @@
#include <crypto/prf_plus.h>
#include <encoding/payloads/proposal_substructure.h>
#include <config/proposal.h>
#include <utils/logger.h>
/**
* Where we should start with reqid enumeration
*/
#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;
/**
@@ -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;
@@ -279,19 +283,6 @@ struct child_sa_t {
*/
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.
*
+160 -217
View File
@@ -24,6 +24,7 @@
#include <sys/time.h>
#include <string.h>
#include <printf.h>
#include "ike_sa.h"
@@ -31,7 +32,6 @@
#include <daemon.h>
#include <definitions.h>
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <crypto/diffie_hellman.h>
#include <crypto/prf_plus.h>
#include <crypto/crypters/crypter.h>
@@ -58,18 +58,13 @@
#include <queues/jobs/route_job.h>
#include <queues/jobs/initiate_job.h>
/**
* String mappings for ike_sa_state_t.
*/
mapping_t ike_sa_state_m[] = {
{IKE_CREATED, "CREATED"},
{IKE_CONNECTING, "CONNECTING"},
{IKE_ESTABLISHED, "ESTABLISHED"},
{IKE_REKEYING, "REKEYING"},
{IKE_DELETING, "DELETING"},
{MAPPING_END, NULL}
};
ENUM(ike_sa_state_names, IKE_CREATED, IKE_DELETING,
"CREATED",
"CONNECTING",
"ESTABLISHED",
"REKEYING",
"DELETING",
);
typedef struct private_ike_sa_t private_ike_sa_t;
@@ -163,11 +158,6 @@ struct private_ike_sa_t {
*/
prf_t *prf_auth_r;
/**
* A logger for this IKE_SA.
*/
logger_t *logger;
/**
* NAT hasher.
*/
@@ -449,8 +439,7 @@ static void dpd_detected(private_ike_sa_t *this)
dpd_action_t action;
job_t *job;
this->logger->log(this->logger, CONTROL|LEVEL1,
"dead peer detected, handling CHILD_SAs dpd action");
DBG2(SIG_DBG_IKE, "dead peer detected, handling CHILD_SAs dpd action");
while(this->child_sas->remove_first(this->child_sas,
(void**)&child_sa) == SUCCESS)
@@ -464,8 +453,7 @@ static void dpd_detected(private_ike_sa_t *this)
this->my_host, this->other_host);
if (policy == NULL)
{
this->logger->log(this->logger, ERROR,
"no policy found for this CHILD_SA");
SIG(SIG_CHILD_FAILED, "no policy for CHILD to handle DPD");
continue;
}
@@ -479,15 +467,13 @@ static void dpd_detected(private_ike_sa_t *this)
this->my_host, this->other_host);
if (connection == NULL)
{
this->logger->log(this->logger, ERROR,
"no connection found for this IKE_SA");
SIG(SIG_IKE_FAILED, "no connection found to handle DPD");
break;
}
}
this->logger->log(this->logger, CONTROL, "dpd action for %s is %s",
policy->get_name(policy),
enum_name(&dpd_action_names, action));
DBG1(SIG_DBG_IKE, "dpd action for %s is %N",
policy->get_name(policy), dpd_action_names, action);
switch (action)
{
@@ -530,9 +516,8 @@ static status_t transmit_request(private_ike_sa_t *this)
this->retrans_sequences);
if (timeout == 0)
{
this->logger->log(this->logger, ERROR,
"giving up after %d retransmits, deleting IKE_SA",
transmitted - 1);
SIG(SIG_IKE_FAILED, "giving up after %d retransmits, deleting IKE_SA",
transmitted - 1);
dpd_detected(this);
return DESTROY_ME;
}
@@ -540,8 +525,7 @@ static status_t transmit_request(private_ike_sa_t *this)
status = transaction->get_request(transaction, &request);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"generating request failed");
/* generating request failed */
return status;
}
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);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"request generation failed. transaction discarded");
DBG1(SIG_DBG_IKE, "request generation failed. transaction discarded");
return FAILED;
}
}
else
{
this->logger->log(this->logger, CONTROL,
"sending retransmit %d for %s request with message ID %d",
transmitted,
mapping_find(exchange_type_m, request->get_exchange_type(request)),
message_id);
DBG1(SIG_DBG_IKE, "sending retransmit %d for %N request with messageID %d",
transmitted, exchange_type_names, request->get_exchange_type(request),
message_id);
packet = request->get_packet(request);
}
/* finally send */
@@ -614,13 +595,9 @@ static status_t process_transaction_queue(private_ike_sa_t *this)
return SUCCESS;
case DESTROY_ME:
/* critical, IKE_SA unusable, destroy immediately */
this->logger->log(this->logger, ERROR,
"transaction initiaton failed, deleting IKE_SA");
return DESTROY_ME;
default:
/* 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 = NULL;
/* 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)
{
/* retransmit detected */
this->logger->log(this->logger, ERROR,
"received retransmitted request for message ID %d, retransmitting response",
request_mid);
DBG1(SIG_DBG_IKE, "received retransmitted request for message "
"ID %d, retransmitting response", request_mid);
last->get_response(last, request, &response, &this->transaction_in_next);
packet = response->get_packet(response);
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)
{
/* something seriously wrong here, message id may not decrease */
this->logger->log(this->logger, ERROR,
"received request with message ID %d, excepted %d, ingored",
request_mid, last_mid + 1);
DBG1(SIG_DBG_IKE, "received request with message ID %d, "
"excepted %d, ingored", request_mid, last_mid + 1);
return FAILED;
}
/* we allow jumps in message IDs, as long as they are incremental */
if (last_mid + 1 < request_mid)
{
this->logger->log(this->logger, ERROR,
"received request with message ID %d, excepted %d",
request_mid, last_mid + 1);
DBG1(SIG_DBG_IKE, "received request with message ID %d, excepted %d",
request_mid, last_mid + 1);
}
}
else
@@ -703,9 +677,8 @@ static status_t process_request(private_ike_sa_t *this, message_t *request)
if (request_mid != 0)
{
/* warn, but allow it */
this->logger->log(this->logger, CONTROL,
"first received request has message ID %d, excepted 0",
request_mid);
DBG1(SIG_DBG_IKE, "first received request has message ID %d, "
"excepted 0", 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);
if (current == NULL)
{
this->logger->log(this->logger, ERROR,
"no idea how to handle received message (%d), ignored",
request->get_exchange_type(request));
DBG1(SIG_DBG_IKE, "no idea how to handle received message (exchange"
" type %d), ignored", request->get_exchange_type(request));
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);
if (response->generate(response, this->crypter_out, this->signer_out, &packet) != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"response generation failed, discarding transaction");
DBG1(SIG_DBG_IKE, "response generation failed, discarding transaction");
current->destroy(current);
return FAILED;
}
@@ -769,8 +740,8 @@ static status_t process_response(private_ike_sa_t *this, message_t *response)
if (current == NULL ||
current->get_message_id(current) != response->get_message_id(response))
{
this->logger->log(this->logger, ERROR,
"received response with message ID %d not requested, ignored");
DBG1(SIG_DBG_IKE, "received response with message ID %d "
"not requested, ignored", response->get_message_id(response));
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);
if (status != SUCCESS)
{
if (is_request)
{
switch (status)
{
case NOT_SUPPORTED:
this->logger->log(this->logger, ERROR,
"ciritcal unknown payloads found");
DBG1(SIG_DBG_IKE, "ciritcal unknown payloads found");
if (is_request)
{
send_notify_response(this, message, UNSUPPORTED_CRITICAL_PAYLOAD);
}
break;
case PARSE_ERROR:
this->logger->log(this->logger, ERROR,
"message parsing failed");
DBG1(SIG_DBG_IKE, "message parsing failed");
if (is_request)
{
send_notify_response(this, message, INVALID_SYNTAX);
}
break;
case VERIFY_ERROR:
this->logger->log(this->logger, ERROR,
"message verification failed");
DBG1(SIG_DBG_IKE, "message verification failed");
if (is_request)
{
send_notify_response(this, message, INVALID_SYNTAX);
}
break;
case FAILED:
this->logger->log(this->logger, ERROR,
"integrity check failed");
DBG1(SIG_DBG_IKE, "integrity check failed");
/* ignored */
break;
case INVALID_STATE:
this->logger->log(this->logger, ERROR,
"found encrypted message, but no keys available");
DBG1(SIG_DBG_IKE, "found encrypted message, but no keys available");
if (is_request)
{
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;
}
}
this->logger->log(this->logger, ERROR,
"%s %s with message ID %d processing failed",
mapping_find(exchange_type_m, message->get_exchange_type(message)),
message->get_request(message) ? "request" : "response",
message->get_message_id(message));
DBG1(SIG_DBG_IKE, "%N %s with message ID %d processing failed",
exchange_type_names, message->get_exchange_type(message),
message->get_request(message) ? "request" : "response",
message->get_message_id(message));
}
else
{
@@ -927,8 +893,7 @@ static status_t initiate(private_ike_sa_t *this,
*/
ike_sa_init_t *ike_sa_init;
this->logger->log(this->logger, CONTROL,
"initiating IKE_SA");
SIG(SIG_INITIATE, "initiating new IKE_SA for CHILD_SA");
DESTROY_IF(this->my_host);
this->my_host = connection->get_my_host(connection);
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->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;
ike_sa_init = ike_sa_init_create(&this->public);
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_REKEYING:
{
/* if we are in DELETING/REKEYING, we deny set up of a policy. */
this->logger->log(this->logger, CONTROL,
"creating CHILD_SA discarded, as IKE_SA is in state %s",
mapping_find(ike_sa_state_m, this->state));
/* if we are in DELETING/REKEYING, we deny set up of a policy.
* TODO: would it make sense to queue the transaction and adopt
* it all transactions to the new IKE_SA? */
SIG(SIG_CHILD_FAILED,
"creating CHILD_SA discarded, as IKE_SA is in state %N",
ike_sa_state_names, this->state);
policy->destroy(policy);
connection->destroy(connection);
return FAILED;
@@ -957,16 +935,14 @@ static status_t initiate(private_ike_sa_t *this,
case IKE_CONNECTING:
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
* when the IKE_SA is ready to do so. We don't need the
* connection, as the IKE_SA is already established/establishing.
*/
create_child_sa_t *create_child;
this->logger->log(this->logger, CONTROL,
"initiating CHILD_SA");
SIG(SIG_INITIATE, "creating CHILD_SA in existing IKE_SA");
connection->destroy(connection);
create_child = create_child_sa_create(&this->public);
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)
{
this->logger->log(this->logger, CONTROL,
"acquiring CHILD_SA with reqid %d discarded, as IKE_SA is deleting",
reqid);
SIG(SIG_CHILD_FAILED, "acquiring CHILD_SA (reqid %d) failed: "
"IKE_SA is deleting", reqid);
return FAILED;
}
/* find CHILD_SA */
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
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);
if (!child_sa)
{
this->logger->log(this->logger, ERROR,
"CHILD_SA with reqid %d not found, unable to acquire",
reqid);
SIG(SIG_CHILD_FAILED, "acquiring CHILD_SA (reqid %d) failed: "
"CHILD_SA not found", reqid);
return FAILED;
}
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);
if (policy == NULL)
{
this->logger->log(this->logger, ERROR,
"no policy found to acquire CHILD_SA with reqid %d",
reqid);
SIG(SIG_CHILD_FAILED, "acquiring CHILD_SA (reqid %d) failed: "
"no policy found", reqid);
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;
this->logger->log(this->logger, CONTROL,
"acquiring CHILD_SA with reqid %d, IKE_SA setup needed",
reqid);
DBG1(SIG_DBG_CHD,
"acquiring CHILD_SA with reqid %d, IKE_SA setup needed", reqid);
connection = charon->connections->get_connection_by_hosts(
charon->connections, this->my_host, this->other_host);
if (connection == NULL)
{
this->logger->log(this->logger, ERROR,
"no connection found to acquire IKE_SA for CHILD_SA with reqid %d",
reqid);
SIG(SIG_CHILD_FAILED, "acquiring CHILD_SA "
"(reqid %d) failed: no connection found for IKE_SA", reqid);
policy->destroy(policy);
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;
this->logger->log(this->logger, CONTROL,
"acquiring CHILD_SA with reqid %d",
reqid);
DBG1(SIG_DBG_CHD, "acquiring CHILD_SA with reqid %d", reqid);
create_child = create_child_sa_create(&this->public);
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(other_ts_conf);
iterator->destroy(iterator);
this->logger->log(this->logger, CONTROL,
"a CHILD_SA with such a policy already routed");
SIG(SIG_CHILD_FAILED, "CHILD_SA with such a policy "
"already routed");
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 */
break;
case IKE_DELETING:
/* deny */
SIG(SIG_CHILD_FAILED, "CHILD_SA with such a policy "
"already routed");
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(other_ts);
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;
}
@@ -1247,6 +1218,7 @@ static status_t unroute(private_ike_sa_t *this, policy_t *policy)
ts_list_equals(other_ts, other_ts_conf))
{
iterator->remove(iterator);
SIG(SIG_CHILD_UNROUTE, "CHILD_SA unrouted");
child_sa->destroy(child_sa);
ts_list_destroy(my_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 */
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);
queue_transaction(this, (transaction_t*)dpd, FALSE);
diff = 0;
@@ -1336,7 +1308,7 @@ static void send_keepalive(private_ike_sa_t *this)
data.len = 1;
packet->set_data(packet, data);
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;
}
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)
{
this->logger->log(this->logger, CONTROL, "state change: %s => %s",
mapping_find(ike_sa_state_m, this->state),
mapping_find(ike_sa_state_m, state));
DBG1(SIG_DBG_IKE, "state change: %N => %N",
ike_sa_state_names, this->state,
ike_sa_state_names, state);
if (state == IKE_ESTABLISHED)
{
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 */
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;
}
@@ -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 */
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;
}
this->prf = prf_create(algo->algorithm);
if (this->prf == NULL)
{
this->logger->log(this->logger, ERROR, "PSEUDO_RANDOM_FUNCTION %s not supported!",
mapping_find(pseudo_random_function_m, algo->algorithm));
DBG1(SIG_DBG_IKE, "key derivation failed: PSEUDO_RANDOM_FUNCTION "
"%N not supported!", pseudo_random_function_names, algo->algorithm);
return FAILED;
}
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);
*((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);
@@ -1490,11 +1464,11 @@ static status_t derive_keys(private_ike_sa_t *this,
* if we are rekeying, SKEYSEED built on another way
*/
if (child_prf == NULL) /* not rekeying */
{
{
/* SKEYSEED = prf(Ni | Nr, g^ir) */
this->prf->set_key(this->prf, nonces);
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);
chunk_free(&skeyseed);
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 */
secret = chunk_cat("mc", secret, nonces);
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);
chunk_free(&skeyseed);
chunk_free(&secret);
@@ -1522,33 +1496,33 @@ static status_t derive_keys(private_ike_sa_t *this,
this->child_prf = prf_create(algo->algorithm);
key_size = this->child_prf->get_key_size(this->child_prf);
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);
chunk_free(&key);
/* SK_ai/SK_ar used for integrity protection => signer_in/signer_out */
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;
}
signer_i = signer_create(algo->algorithm);
signer_r = signer_create(algo->algorithm);
if (signer_i == NULL || signer_r == NULL)
{
this->logger->log(this->logger, ERROR, "INTEGRITY_ALGORITHM %s not supported!",
mapping_find(integrity_algorithm_m,algo->algorithm));
DBG1(SIG_DBG_IKE, "key derivation failed: INTEGRITY_ALGORITHM "
"%N not supported!", integrity_algorithm_names ,algo->algorithm);
return FAILED;
}
key_size = signer_i->get_key_size(signer_i);
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);
chunk_free(&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);
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 */
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;
}
crypter_i = 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)
{
this->logger->log(this->logger, ERROR,
"ENCRYPTION_ALGORITHM %s (key size %d) not supported!",
mapping_find(encryption_algorithm_m, algo->algorithm),
algo->key_size);
DBG1(SIG_DBG_IKE, "key derivation failed: ENCRYPTION_ALGORITHM "
"%N (key size %d) not supported!",
encryption_algorithm_names, algo->algorithm, algo->key_size);
return FAILED;
}
key_size = crypter_i->get_key_size(crypter_i);
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);
chunk_free(&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);
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);
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);
chunk_free(&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);
chunk_free(&key);
@@ -1781,16 +1754,14 @@ static status_t rekey(private_ike_sa_t *this)
{
rekey_ike_sa_t *rekey_ike_sa;
this->logger->log(this->logger, CONTROL,
"rekeying IKE_SA between: %H[%D]...%H[%D]",
this->my_host, this->my_id,
DBG1(SIG_DBG_IKE, "rekeying IKE_SA between %H[%D]..%H[%D]",
this->my_host, this->my_id,
this->other_host, this->other_id);
if (this->state != IKE_ESTABLISHED)
{
this->logger->log(this->logger, ERROR,
"unable to rekey IKE_SA in state %s",
mapping_find(ike_sa_state_m, this->state));
SIG(SIG_IKE_FAILED, "unable to rekey IKE_SA in state %N",
ike_sa_state_names, this->state);
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.
*/
@@ -1931,19 +1851,57 @@ static void enable_natt (private_ike_sa_t *this, bool local)
{
if (local)
{
this->logger->log(this->logger, CONTROL,
"local host is behind NAT, using NAT-T, scheduled keep alives");
DBG1(SIG_DBG_IKE, "local host is behind NAT, using NAT-T, "
"scheduled keep alives");
this->nat_here = TRUE;
send_keepalive(this);
}
else
{
this->logger->log(this->logger, CONTROL,
"remote host is behind NAT, using NAT-T");
DBG1(SIG_DBG_IKE, "remote host is behind NAT, using NAT-T");
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.
*/
@@ -1952,17 +1910,6 @@ static void destroy(private_ike_sa_t *this)
child_sa_t *child_sa;
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)
{
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_r);
this->logger->log(this->logger, AUDIT,
"IKE_SA deleted between: %H[%D]...%H[%D]",
this->my_host, this->my_id,
this->other_host, this->other_id);
DBG1(SIG_DBG_IKE, "IKE_SA deleted between %H[%D]...%H[%D]",
this->my_host, this->my_id, this->other_host, this->other_id);
DESTROY_IF(this->my_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.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.log_status = (void (*) (ike_sa_t*,logger_t*,char*))log_status;
this->public.delete = (status_t(*)(ike_sa_t*))delete_;
this->public.destroy = (void(*)(ike_sa_t*))destroy;
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;
/* 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->name = strdup("(uninitialized)");
this->child_sas = linked_list_create();
+4 -18
View File
@@ -31,7 +31,6 @@
#include <sa/ike_sa_id.h>
#include <sa/child_sa.h>
#include <config/configuration.h>
#include <utils/logger.h>
#include <utils/randomizer.h>
#include <crypto/prfs/prf.h>
#include <crypto/crypters/crypter.h>
@@ -39,9 +38,10 @@
#include <config/connections/connection.h>
#include <config/policies/policy.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;
/**
@@ -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;
@@ -403,20 +403,6 @@ struct ike_sa_t {
* @param this calling object
*/
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.
+41 -1
View File
@@ -24,6 +24,8 @@
#include "ike_sa_id.h"
#include <printf.h>
#include <stdio.h>
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
{
this->is_initiator_flag = TRUE;
this->is_initiator_flag = TRUE;
}
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);
}
/**
* 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.
*/
+4
View File
@@ -27,6 +27,10 @@
#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;
+107 -214
View File
@@ -28,20 +28,15 @@
#include <daemon.h>
#include <sa/ike_sa_id.h>
#include <utils/logger.h>
#include <utils/logger_manager.h>
#include <bus/bus.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.
*/
struct ike_sa_entry_t {
/**
* Destructor, also destroys associated ike_sa_t object.
*/
status_t (*destroy) (ike_sa_entry_t *this);
struct entry_t {
/**
* 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 */
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.
*
* 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
* Creates a new entry for the ike_sa_t list.
*/
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);
/* destroy function */
this->destroy = ike_sa_entry_destroy;
entry_t *this = malloc_thing(entry_t);
this->waiting_threads = 0;
pthread_cond_init(&(this->condvar), NULL);
@@ -140,11 +127,6 @@ struct private_ike_sa_manager_t {
*/
pthread_mutex_t mutex;
/**
* Logger used for this IKE SA Manager.
*/
logger_t *logger;
/**
* 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.
*/
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;
iterator_t *iterator;
entry_t *current;
status_t status;
/* 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 */
status = NOT_FOUND;
while (iterator->has_next(iterator))
while (iterator->iterate(iterator, (void**)&current))
{
ike_sa_entry_t *current;
iterator->current(iterator, (void**)&current);
if (current->ike_sa_id->get_responder_spi(current->ike_sa_id) == 0)
if (current->ike_sa_id->equals(current->ike_sa_id, ike_sa_id))
{
DBG2(SIG_DBG_MGR, "found entry by both SPIs");
*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 */
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)))
(current->ike_sa_id->is_initiator(ike_sa_id) ==
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));
DBG2(SIG_DBG_MGR, "found entry by initiator SPI");
*entry = current;
status = SUCCESS;
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);
@@ -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.
*/
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;
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))
{
ike_sa_entry_t *current;
entry_t *current;
iterator->current(iterator, (void**)&current);
/* only pointers are compared */
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;
status = SUCCESS;
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.
*/
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;
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))
{
ike_sa_entry_t *current;
entry_t *current;
iterator->current(iterator, (void**)&current);
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));
}
this->logger->log(this->logger, CONTROL|LEVEL2,
"found entry by pointer. Going to delete it");
DBG2(SIG_DBG_MGR, "found entry by pointer, deleting it");
iterator->remove(iterator);
entry->destroy(entry);
entry_destroy(entry);
status = SUCCESS;
break;
}
}
iterator->destroy(iterator);
return status;
return status;
}
/**
* Wait until no other thread is using an IKE_SA, return FALSE if entry not
* 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)
{
@@ -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);
while (iterator->has_next(iterator))
{
ike_sa_entry_t *entry;
entry_t *entry;
identification_t *found_my_id, *found_other_id;
host_t *found_my_host, *found_other_host;
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))
{
/* looks good, we take this one */
this->logger->log(this->logger, CONTROL|LEVEL1,
"found an existing IKE_SA for %H[%D]...%H[%D]",
my_host, other_host, my_id, other_id);
DBG2(SIG_DBG_MGR, "found an existing IKE_SA for %H[%D]...%H[%D]",
my_host, other_host, my_id, other_id);
entry->checked_out = TRUE;
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)
{
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;
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);
/* create entry */
new_ike_sa_entry = ike_sa_entry_create(new_ike_sa_id);
this->logger->log(this->logger, CONTROL|LEVEL2,
"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_entry = entry_create(new_ike_sa_id);
DBG2(SIG_DBG_MGR, "created IKE_SA: %J", 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 */
this->logger->log(this->logger, CONTROL|LEVEL1,
"new IKE_SA created for IDs %D - %D", my_id, other_id);
new_ike_sa_entry->checked_out = TRUE;
ike_sa = new_ike_sa_entry->ike_sa;
DBG2(SIG_DBG_MGR, "new IKE_SA created for IDs [%D]...[%D]", my_id, other_id);
new_entry->checked_out = TRUE;
ike_sa = new_entry->ike_sa;
}
pthread_mutex_unlock(&(this->mutex));
SIG_SA(ike_sa);
charon->bus->set_sa(charon->bus, 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;
ike_sa_t *ike_sa = NULL;
this->logger->log(this->logger, CONTROL|LEVEL2,
"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");
DBG2(SIG_DBG_MGR, "checkout IKE_SA: %J", ike_sa_id);
this->logger->log(this->logger, CONTROL|LEVEL2, "%d IKE_SAs in manager",
this->ike_sa_list->get_count(this->ike_sa_list));
DBG2(SIG_DBG_MGR, "%d IKE_SAs in manager",
this->ike_sa_list->get_count(this->ike_sa_list));
/* each access is locked */
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,
* if not, we can't handle the request...
*/
ike_sa_entry_t *entry;
entry_t *entry;
/* look for the entry */
if (get_entry_by_id(this, ike_sa_id, &entry) == SUCCESS)
{
if (wait_for_entry(this, entry))
{
this->logger->log(this->logger, CONTROL|LEVEL2,
"IKE_SA successfully checked out");
DBG2(SIG_DBG_MGR, "IKE_SA successfully checked out");
/* ok, this IKE_SA is finally ours */
entry->checked_out = TRUE;
ike_sa = entry->ike_sa;
}
else
{
this->logger->log(this->logger, CONTROL|LEVEL2,
"IKE_SA found, but not allowed to check it out");
DBG2(SIG_DBG_MGR, "IKE_SA found, but not allowed to check it out");
}
}
else
{
this->logger->log(this->logger, ERROR|LEVEL1,
"IKE_SA not stored in list");
DBG2(SIG_DBG_MGR, "IKE_SA not stored in list");
/* 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...
*/
u_int64_t responder_spi;
ike_sa_entry_t *new_ike_sa_entry;
entry_t *new_entry;
/* set SPIs, we are the responder */
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);
/* 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 */
this->logger->log(this->logger, CONTROL|LEVEL1,
"IKE_SA added to list of known IKE_SAs");
new_ike_sa_entry->checked_out = TRUE;
ike_sa = new_ike_sa_entry->ike_sa;
DBG2(SIG_DBG_MGR, "IKE_SA added to list of known IKE_SAs");
new_entry->checked_out = TRUE;
ike_sa = new_entry->ike_sa;
}
else if (!initiator_spi_set && !responder_spi_set && original_initiator)
{
/* 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));
/* create entry */
new_ike_sa_entry = ike_sa_entry_create(ike_sa_id);
this->logger->log(this->logger, CONTROL|LEVEL2,
"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");
new_entry = entry_create(ike_sa_id);
DBG2(SIG_DBG_MGR, "created IKE_SA: %J", 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 */
new_ike_sa_entry->checked_out = TRUE;
ike_sa = new_ike_sa_entry->ike_sa;
new_entry->checked_out = TRUE;
ike_sa = new_entry->ike_sa;
}
else
{
/* 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));
SIG_SA(ike_sa);
charon->bus->set_sa(charon->bus, 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);
while (iterator->has_next(iterator))
{
ike_sa_entry_t *entry;
entry_t *entry;
iterator->current(iterator, (void**)&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);
pthread_mutex_unlock(&(this->mutex));
SIG_SA(ike_sa);
charon->bus->set_sa(charon->bus, 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;
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))
if (iterator->has_next(iterator))
{
ike_sa_entry_t *entry;
entry_t *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);
pthread_mutex_unlock(&(this->mutex));
return list;
return FALSE;
}
/**
* 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;
u_int instances;
pthread_mutex_lock(&(this->mutex));
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));
iterator_t *iterator = this->ike_sa_list->create_iterator_locked(
this->ike_sa_list, &this->mutex);
/* overload iterator */
iterator->iterate = iterate;
return iterator;
}
/**
@@ -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...
*/
status_t retval;
ike_sa_entry_t *entry;
entry_t *entry;
ike_sa_id_t *ike_sa_id;
ike_sa_id = ike_sa->get_id(ike_sa);
this->logger->log(this->logger, CONTROL|LEVEL2,
"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");
DBG2(SIG_DBG_MGR, "checkin IKE_SA: %J", ike_sa_id);
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));
/* signal waiting threads */
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));
retval = SUCCESS;
}
else
{
this->logger->log(this->logger, ERROR,
"tried to check in nonexisting IKE_SA");
DBG2(SIG_DBG_MGR, "tried to check in nonexisting IKE_SA");
/* this SA is no more, this REALLY should not happen */
retval = NOT_FOUND;
}
this->logger->log(this->logger, CONTROL|LEVEL2, "%d IKE_SAs in manager now",
this->ike_sa_list->get_count(this->ike_sa_list));
DBG2(SIG_DBG_MGR, "%d IKE_SAs in manager now",
this->ike_sa_list->get_count(this->ike_sa_list));
pthread_mutex_unlock(&(this->mutex));
SIG_SA(NULL);
charon->bus->set_sa(charon->bus, NULL);
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
* are in the condvar.
*/
ike_sa_entry_t *entry;
entry_t *entry;
status_t retval;
ike_sa_id_t *ike_sa_id;
ike_sa_id = ike_sa->get_id(ike_sa);
this->logger->log(this->logger, CONTROL|LEVEL2,
"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");
DBG2(SIG_DBG_MGR, "checkin and destroy IKE_SA: %J", ike_sa_id);
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);
this->logger->log(this->logger, CONTROL|LEVEL1,
"check-in and destroy of IKE_SA successful");
DBG2(SIG_DBG_MGR, "check-in and destroy of IKE_SA successful");
retval = SUCCESS;
}
else
{
this->logger->log(this->logger,ERROR,
"tried to check-in and delete nonexisting IKE_SA");
DBG2(SIG_DBG_MGR, "tried to check-in and delete nonexisting IKE_SA");
retval = NOT_FOUND;
}
pthread_mutex_unlock(&(this->mutex));
SIG_SA(NULL);
charon->bus->set_sa(charon->bus, ike_sa);
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
* are in the condvar.
*/
ike_sa_entry_t *entry;
entry_t *entry;
status_t retval;
this->logger->log(this->logger, CONTROL|LEVEL2,
"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");
DBG2(SIG_DBG_MGR, "delete IKE_SA: %J", ike_sa_id);
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)
{
this->logger->log(this->logger, CONTROL|LEVEL1,
"initiated delete for IKE_SA");
DBG2(SIG_DBG_MGR, "initiated delete for IKE_SA");
}
/* 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.
@@ -774,8 +676,7 @@ static status_t delete_(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id)
}
else
{
this->logger->log(this->logger,ERROR|LEVEL1,
"tried to delete nonexisting IKE_SA");
DBG2(SIG_DBG_MGR, "tried to delete nonexisting IKE_SA");
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 *child_iter;
ike_sa_entry_t *entry;
entry_t *entry;
size_t name_len = strlen(name);
pthread_mutex_lock(&(this->mutex));
@@ -910,14 +811,12 @@ static void destroy(private_ike_sa_manager_t *this)
/* destroy all list entries */
linked_list_t *list = this->ike_sa_list;
iterator_t *iterator;
ike_sa_entry_t *entry;
entry_t *entry;
pthread_mutex_lock(&(this->mutex));
this->logger->log(this->logger, CONTROL|LEVEL1,
"going to destroy IKE_SA manager and all managed IKE_SA's");
DBG2(SIG_DBG_MGR, "going to destroy IKE_SA manager and all managed IKE_SA's");
/* Step 1: drive out all waiting threads */
this->logger->log(this->logger, CONTROL|LEVEL2,
"set driveout flags for all stored IKE_SA's");
DBG2(SIG_DBG_MGR, "set driveout flags for all stored IKE_SA's");
iterator = list->create_iterator(list, TRUE);
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_waiting_threads = TRUE;
}
this->logger->log(this->logger, CONTROL|LEVEL2,
"wait for all threads to leave IKE_SA's");
DBG2(SIG_DBG_MGR, "wait for all threads to leave IKE_SA's");
/* Step 2: wait until all are gone */
iterator->reset(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));
}
}
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 */
iterator->reset(iterator);
while (iterator->has_next(iterator))
@@ -951,11 +849,11 @@ static void destroy(private_ike_sa_manager_t *this)
}
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 */
while (list->remove_last(list, (void**)&entry) == SUCCESS)
{
entry->destroy(entry);
entry_destroy(entry);
}
list->destroy(list);
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 = (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.get_ike_sa_list = (linked_list_t*(*)(ike_sa_manager_t*))get_ike_sa_list;
this->public.log_status = (void(*)(ike_sa_manager_t*,logger_t*,char*))log_status;
this->public.create_iterator = (iterator_t*(*)(ike_sa_manager_t*))create_iterator;
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_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;
/* initialize private variables */
this->logger = logger_manager->get_logger(logger_manager, IKE_SA_MANAGER);
/* initialize private variables */
this->ike_sa_list = linked_list_create();
pthread_mutex_init(&(this->mutex), NULL);
this->randomizer = randomizer_create();
return (ike_sa_manager_t*)this;
}
+11 -26
View File
@@ -26,8 +26,6 @@
#include <types.h>
#include <sa/ike_sa.h>
#include <utils/logger.h>
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
*/
ike_sa_t* (*checkout_by_id) (ike_sa_manager_t* this,
host_t *my_host, host_t* other_host,
identification_t *my_id,
identification_t *other_id);
host_t *my_host, host_t* other_host,
identification_t *my_id,
identification_t *other_id);
/**
* @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);
/**
* @brief Get a list of all IKE_SA SAs currently set up.
*
* The resulting list with all IDs must be destroyed by
* the caller. There is no guarantee an ike_sa with the
* corrensponding ID really exists, since it may be deleted
* in the meantime by another thread.
*
* @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.
* @brief Create an iterator over all stored IKE_SAs.
*
* The avoid synchronization issues, the iterator locks access
* to the manager exclusively, until it gets destroyed.
* Only use the iterate() functions of this iterator!!! Anything other
* is not implemented and causes crashes.
*
* 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 logger logger to do the log, or NULL
* @param name name of a connection, or NULL
* @return iterator over all IKE_SAs.
*/
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.
+34 -64
View File
@@ -128,11 +128,6 @@ struct private_create_child_sa_t {
* source of randomness
*/
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))
{
case CHILD_REKEYING:
this->logger->log(this->logger, ERROR,
"rekeying a CHILD_SA which is already rekeying, aborted");
DBG1(SIG_DBG_IKE,
"rekeying a CHILD_SA which is already rekeying, aborted");
return FAILED;
case CHILD_DELETING:
this->logger->log(this->logger, ERROR,
"rekeying a CHILD_SA which is deleting, aborted");
DBG1(SIG_DBG_IKE,
"rekeying a CHILD_SA which is deleting, aborted");
return FAILED;
default:
break;
@@ -289,9 +284,8 @@ static status_t get_request(private_create_child_sa_t *this, message_t **result)
if (this->policy == NULL)
{
this->logger->log(this->logger, ERROR,
"no policy found to rekey CHILD_SA with reqid %d",
this->reqid);
DBG1(SIG_DBG_IKE, "no policy found to rekey "
"CHILD_SA with reqid %d", this->reqid);
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));
if (this->child_sa->alloc(this->child_sa, proposals) != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"could not install CHILD_SA, CHILD_SA creation aborted");
DBG1(SIG_DBG_IKE, "could not install CHILD_SA, CHILD_SA creation aborted");
return FAILED;
}
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);
this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s",
mapping_find(notify_type_m, notify_type));
DBG2(SIG_DBG_IKE, "process notify type %N", notify_type_names, notify_type);
switch (notify_type)
{
case SINGLE_PAIR_REQUIRED:
{
this->logger->log(this->logger, AUDIT,
"received a SINGLE_PAIR_REQUIRED notify");
DBG1(SIG_DBG_IKE, "received a SINGLE_PAIR_REQUIRED notify");
return FAILED;
}
case TS_UNACCEPTABLE:
{
this->logger->log(this->logger, CONTROL,
"received TS_UNACCEPTABLE notify");
DBG1(SIG_DBG_IKE, "received TS_UNACCEPTABLE notify");
return FAILED;
}
case NO_PROPOSAL_CHOSEN:
{
this->logger->log(this->logger, CONTROL,
"received NO_PROPOSAL_CHOSEN notify");
DBG1(SIG_DBG_IKE, "received NO_PROPOSAL_CHOSEN notify");
return FAILED;
}
case REKEY_SA:
@@ -423,18 +412,14 @@ static status_t process_notifys(private_create_child_sa_t *this, notify_payload_
{
if (notify_type < 16383)
{
this->logger->log(this->logger, AUDIT,
"received %s notify error (%d), CHILD_SA creation failed",
mapping_find(notify_type_m, notify_type),
notify_type);
DBG1(SIG_DBG_IKE, "received %N notify error, CHILD_SA "
"creation failed", notify_type_names, notify_type);
return FAILED;
}
else
{
this->logger->log(this->logger, CONTROL,
"received %s notify (%d), ignored",
mapping_find(notify_type_m, notify_type),
notify_type);
DBG1(SIG_DBG_IKE, "received %N notify, ignored",
notify_type_names, notify_type);
return SUCCESS;
}
}
@@ -558,8 +543,7 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
/* check message type */
if (request->get_exchange_type(request) != CREATE_CHILD_SA)
{
this->logger->log(this->logger, ERROR,
"CREATE_CHILD_SA response of invalid type, aborted");
DBG1(SIG_DBG_IKE, "CREATE_CHILD_SA response of invalid type, aborted");
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)
{
build_notify(NO_ADDITIONAL_SAS, CHUNK_INITIALIZER, response, TRUE);
this->logger->log(this->logger, AUDIT,
"unable to create new CHILD_SAs, as rekeying in progress");
DBG1(SIG_DBG_IKE, "unable to create new CHILD_SAs, as rekeying in progress");
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 */
chunk_t group = chunk_from_buf(dh_buffer);
build_notify(INVALID_KE_PAYLOAD, group, response, TRUE);
this->logger->log(this->logger, CONTROL,
"CREATE_CHILD_SA used PFS, sending INVALID_KE_PAYLOAD");
DBG1(SIG_DBG_IKE, "CREATE_CHILD_SA used PFS, sending INVALID_KE_PAYLOAD");
return FAILED;
}
case NOTIFY:
@@ -615,9 +597,8 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
}
default:
{
this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
DBG1(SIG_DBG_IKE, "ignoring %N payload",
payload_type_names, payload->get_type(payload));
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))
{
build_notify(INVALID_SYNTAX, CHUNK_INITIALIZER, response, TRUE);
this->logger->log(this->logger, AUDIT,
"request message incomplete, no CHILD_SA created");
DBG1(SIG_DBG_IKE, "request message incomplete, no CHILD_SA created");
return FAILED;
}
@@ -669,8 +649,7 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
if (this->policy == NULL)
{
this->logger->log(this->logger, AUDIT,
"no acceptable policy found, adding TS_UNACCEPTABLE notify");
DBG1(SIG_DBG_IKE, "no acceptable policy found, adding TS_UNACCEPTABLE notify");
build_notify(TS_UNACCEPTABLE, CHUNK_INITIALIZER, response, TRUE);
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();
/* get proposals from request, and select one with ours */
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);
destroy_proposal_list(proposal_list);
/* do we have a proposal? */
if (this->proposal == NULL)
{
this->logger->log(this->logger, AUDIT,
"CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
DBG1(SIG_DBG_IKE, "CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
return FAILED;
}
/* do we have traffic selectors? */
else if (this->tsi->get_count(this->tsi) == 0 || this->tsr->get_count(this->tsr) == 0)
{
this->logger->log(this->logger, AUDIT,
"CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
DBG1(SIG_DBG_IKE, "CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
build_notify(TS_UNACCEPTABLE, CHUNK_INITIALIZER, response, TRUE);
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));
if (install_child_sa(this, FALSE) != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
DBG1(SIG_DBG_IKE, "installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
return FAILED;
}
@@ -786,8 +762,7 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
/* check message type */
if (response->get_exchange_type(response) != CREATE_CHILD_SA)
{
this->logger->log(this->logger, ERROR,
"CREATE_CHILD_SA response of invalid type, aborting");
DBG1(SIG_DBG_IKE, "CREATE_CHILD_SA response of invalid type, aborting");
return FAILED;
}
@@ -826,9 +801,8 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
}
default:
{
this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
DBG1(SIG_DBG_IKE, "ignoring %N payload",
payload_type_names, payload->get_type(payload));
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))
{
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;
}
@@ -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->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;
}
new_child = this->child_sa;
if (install_child_sa(this, TRUE) != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"installing CHILD_SA failed, no CHILD_SA built");
DBG1(SIG_DBG_IKE, "installing CHILD_SA failed, no CHILD_SA built");
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,
min(this_lowest.len, this->nonce_s.len)) < 0)
{
this->logger->log(this->logger, ERROR,
"detected simultaneous CHILD_SA rekeying, deleting ours");
DBG1(SIG_DBG_IKE, "detected simultaneous CHILD_SA rekeying, deleting ours");
this->lost = TRUE;
}
else
{
this->logger->log(this->logger, ERROR,
"detected simultaneous CHILD_SA rekeying, but ours is preferred");
DBG1(SIG_DBG_IKE, "detected simultaneous CHILD_SA rekeying, but ours is preferred");
}
}
/* 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->tsr = NULL;
this->randomizer = randomizer_create();
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public;
}
@@ -56,11 +56,6 @@ struct private_dead_peer_detection_t {
* Times we did send the request
*/
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 = NULL;
this->requested = 0;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public;
}
+14 -29
View File
@@ -63,11 +63,6 @@ struct private_delete_child_sa_t {
* CHILD SA to delete
*/
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);
delete_payload = delete_payload_create(protocol);
this->logger->log(this->logger, CONTROL,
"created DELETE payload for %s CHILD_SA with SPI 0x%x",
mapping_find(protocol_id_m, protocol), htonl(spi));
DBG1(SIG_DBG_IKE, "created DELETE payload for %N CHILD_SA with SPI 0x%x",
protocol_id_names, protocol, htonl(spi));
delete_payload->add_spi(delete_payload, spi);
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);
if (protocol != PROTO_ESP && protocol != PROTO_AH)
{
this->logger->log(this->logger, CONTROL,
"CHILD_SA delete response contained unexpected protocol");
DBG1(SIG_DBG_IKE, "CHILD_SA delete response contained unexpected protocol");
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);
this->logger->log(this->logger, CONTROL,
"received DELETE for %s CHILD_SA with SPI 0x%x, deleting",
mapping_find(protocol_id_m, protocol), ntohl(spi));
DBG1(SIG_DBG_IKE, "received DELETE for %N CHILD_SA with SPI 0x%x, deleting",
protocol_id_names, protocol, ntohl(spi));
rekey = child_sa->get_rekeying_transaction(child_sa);
if (rekey)
@@ -208,9 +200,8 @@ static status_t process_delete(private_delete_child_sa_t *this, delete_payload_t
}
else
{
this->logger->log(this->logger, ERROR,
"received DELETE for %s CHILD_SA with SPI 0x%x, but no such SA",
mapping_find(protocol_id_m, protocol), ntohl(spi));
DBG1(SIG_DBG_IKE, "received DELETE for %N CHILD_SA with SPI 0x%x, but no such SA",
protocol_id_names, protocol, ntohl(spi));
}
}
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)
{
this->logger->log(this->logger, ERROR,
"INFORMATIONAL response of invalid type, aborting");
DBG1(SIG_DBG_IKE, "INFORMATIONAL response of invalid type, aborting");
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 ||
this->ike_sa->get_state(this->ike_sa) == IKE_DELETING)
{
this->logger->log(this->logger, AUDIT,
"unable to delete CHILD_SA, as rekeying in progress");
DBG1(SIG_DBG_IKE, "unable to delete CHILD_SA, as rekeying in progress");
return FAILED;
}
@@ -283,9 +272,8 @@ static status_t get_response(private_delete_child_sa_t *this, message_t *request
}
default:
{
this->logger->log(this->logger, ERROR|LEVEL1, "ignoring payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
DBG2(SIG_DBG_IKE, "ignoring payload %N",
payload_type_names, payload->get_type(payload));
break;
}
}
@@ -305,8 +293,7 @@ static status_t conclude(private_delete_child_sa_t *this, message_t *response,
/* check message type */
if (response->get_exchange_type(response) != INFORMATIONAL)
{
this->logger->log(this->logger, ERROR,
"INFORMATIONAL response of invalid type, aborting");
DBG1(SIG_DBG_IKE, "INFORMATIONAL response of invalid type, aborting");
return FAILED;
}
@@ -326,9 +313,8 @@ static status_t conclude(private_delete_child_sa_t *this, message_t *response,
}
default:
{
this->logger->log(this->logger, ERROR|LEVEL1, "ignoring payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
DBG1(SIG_DBG_IKE, "ignoring payload %N",
payload_type_names, payload->get_type(payload));
break;
}
}
@@ -369,7 +355,6 @@ delete_child_sa_t *delete_child_sa_create(ike_sa_t *ike_sa)
this->message_id = 0;
this->message = NULL;
this->requested = 0;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public;
}
+6 -18
View File
@@ -25,7 +25,6 @@
#include <daemon.h>
#include <encoding/payloads/delete_payload.h>
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
*/
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 */
if (request->get_exchange_type(request) != INFORMATIONAL)
{
this->logger->log(this->logger, ERROR,
"INFORMATIONAL response of invalid type, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "INFORMATIONAL response of invalid type, deleting IKE_SA");
return DESTROY_ME;
}
@@ -181,9 +174,8 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
}
default:
{
this->logger->log(this->logger, ERROR|LEVEL1, "ignoring payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
DBG1(SIG_DBG_IKE, "ignoring payload %N",
payload_type_names, payload->get_type(payload));
break;
}
}
@@ -193,14 +185,12 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
if (delete_request &&
delete_request->get_protocol_id(delete_request) == PROTO_IKE)
{
this->logger->log(this->logger, CONTROL,
"DELETE request for IKE_SA received, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "DELETE request for IKE_SA received, deleting IKE_SA");
}
else
{
/* should not happen, as we preparsed this at transaction construction */
this->logger->log(this->logger, CONTROL,
"received a weird DELETE request for IKE_SA, deleting anyway");
DBG1(SIG_DBG_IKE, "received a weird DELETE request for IKE_SA, deleting anyway");
}
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 */
if (response->get_exchange_type(response) != INFORMATIONAL)
{
this->logger->log(this->logger, ERROR,
"INFORMATIONAL response of invalid type, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "INFORMATIONAL response of invalid type, deleting IKE_SA");
return DESTROY_ME;
}
/* 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 = NULL;
this->requested = 0;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public;
}
+41 -77
View File
@@ -128,11 +128,6 @@ struct private_ike_auth_t {
* reqid to use for CHILD_SA setup
*/
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
{
this->logger->log(this->logger, ERROR,
"could not find my certificate, certificate payload omitted");
DBG1(SIG_DBG_IKE, "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);
if (status != SUCCESS)
{
this->logger->log(this->logger, AUDIT,
"could not generate AUTH data, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "could not generate AUTH data, deleting IKE_SA");
return DESTROY_ME;
}
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));
if (this->child_sa->alloc(this->child_sa, proposal_list) != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"could not install CHILD_SA, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "could not install CHILD_SA, deleting IKE_SA");
return DESTROY_ME;
}
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);
this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s",
mapping_find(notify_type_m, notify_type));
DBG2(SIG_DBG_IKE, "process notify type %N", notify_type_names, notify_type);
switch (notify_type)
{
/* these notifies are not critical. no child_sa is built, but IKE stays alive */
case SINGLE_PAIR_REQUIRED:
{
this->logger->log(this->logger, AUDIT,
"received a SINGLE_PAIR_REQUIRED notify");
DBG1(SIG_DBG_IKE, "received a SINGLE_PAIR_REQUIRED notify");
this->build_child = FALSE;
return SUCCESS;
}
case TS_UNACCEPTABLE:
{
this->logger->log(this->logger, CONTROL,
"received TS_UNACCEPTABLE notify");
DBG1(SIG_DBG_IKE, "received TS_UNACCEPTABLE notify");
this->build_child = FALSE;
return SUCCESS;
}
case NO_PROPOSAL_CHOSEN:
{
this->logger->log(this->logger, CONTROL,
"received NO_PROPOSAL_CHOSEN notify");
DBG1(SIG_DBG_IKE, "received NO_PROPOSAL_CHOSEN notify");
this->build_child = FALSE;
return SUCCESS;
}
@@ -407,18 +395,14 @@ static status_t process_notifies(private_ike_auth_t *this, notify_payload_t *not
{
if (notify_type < 16383)
{
this->logger->log(this->logger, AUDIT,
"received %s notify error (%d), deleting IKE_SA",
mapping_find(notify_type_m, notify_type),
notify_type);
DBG1(SIG_DBG_IKE, "received %N notify error, deleting IKE_SA",
notify_type_names, notify_type);
return DESTROY_ME;
}
else
{
this->logger->log(this->logger, CONTROL,
"received %s notify (%d), ignored",
mapping_find(notify_type_m, notify_type),
notify_type);
DBG1(SIG_DBG_IKE, "received %N notify, ignored",
notify_type_names, notify_type);
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);
if (encoding != CERT_X509_SIGNATURE)
{
this->logger->log(this->logger, ERROR,
"certificate payload %s not supported, ignored",
enum_name(&cert_encoding_names, encoding));
DBG1(SIG_DBG_IKE, "certificate payload %N not supported, ignored",
cert_encoding_names, encoding);
return;
}
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))
{
this->logger->log(this->logger, CONTROL|LEVEL1,
"received end entity certificate is trusted, added to store");
DBG2(SIG_DBG_IKE, "received end entity certificate is trusted, added to store");
if (!found)
{
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
{
this->logger->log(this->logger, CONTROL,
"received end entity certificate is not trusted, discarded");
DBG1(SIG_DBG_IKE, "received end entity certificate is not trusted, discarded");
cert->destroy(cert);
}
}
else
{
this->logger->log(this->logger, CONTROL,
"parsing of received certificate failed, discarded");
DBG1(SIG_DBG_IKE, "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 */
if (request->get_exchange_type(request) != IKE_AUTH)
{
this->logger->log(this->logger, ERROR,
"IKE_AUTH response of invalid type, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "IKE_AUTH response of invalid type, deleting IKE_SA");
return DESTROY_ME;
}
@@ -641,9 +620,8 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
}
default:
{
this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
DBG1(SIG_DBG_IKE, "ignoring %N payload",
payload_type_names, payload->get_type(payload));
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))
{
build_notify(INVALID_SYNTAX, response, TRUE);
this->logger->log(this->logger, AUDIT,
"request message incomplete, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "request message incomplete, deleting IKE_SA");
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. */
if (this->policy == NULL)
{
this->logger->log(this->logger, AUDIT,
"no acceptable policy for IDs %D - %D found, deleting IKE_SA",
my_id, other_id);
DBG1(SIG_DBG_IKE, "no acceptable policy for IDs %D - %D found, deleting IKE_SA",
my_id, other_id);
my_id->destroy(my_id);
other_id->destroy(other_id);
build_notify(AUTHENTICATION_FAILED, response, TRUE);
@@ -726,8 +702,7 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
}
else
{
this->logger->log(this->logger, ERROR,
"could not find my certificate, cert payload omitted");
DBG1(SIG_DBG_IKE, "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);
if (status != SUCCESS)
{
this->logger->log(this->logger, AUDIT,
"authentication failed, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "authentication failed, deleting IKE_SA");
build_notify(AUTHENTICATION_FAILED, response, TRUE);
authenticator->destroy(authenticator);
return DESTROY_ME;
@@ -767,8 +741,7 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
authenticator->destroy(authenticator);
if (status != SUCCESS)
{
this->logger->log(this->logger, AUDIT,
"authentication data generation failed, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "authentication data generation failed, deleting IKE_SA");
build_notify(AUTHENTICATION_FAILED, response, TRUE);
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 */
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);
destroy_proposal_list(proposal_list);
/* do we have a proposal? */
if (this->proposal == NULL)
{
this->logger->log(this->logger, AUDIT,
"CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
DBG1(SIG_DBG_IKE, "CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
build_notify(NO_PROPOSAL_CHOSEN, response, FALSE);
}
/* do we have traffic selectors? */
else if (this->tsi->get_count(this->tsi) == 0 || this->tsr->get_count(this->tsr) == 0)
{
this->logger->log(this->logger, AUDIT,
"CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
DBG1(SIG_DBG_IKE, "CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
build_notify(TS_UNACCEPTABLE, response, FALSE);
}
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));
if (install_child_sa(this, FALSE) != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
DBG1(SIG_DBG_IKE, "installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
build_notify(NO_PROPOSAL_CHOSEN, response, FALSE);
}
/* add proposal to sa payload */
@@ -860,8 +830,7 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
/* check message type */
if (response->get_exchange_type(response) != IKE_AUTH)
{
this->logger->log(this->logger, ERROR,
"IKE_AUTH response of invalid type, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "IKE_AUTH response of invalid type, deleting IKE_SA");
return DESTROY_ME;
}
@@ -913,9 +882,8 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
}
default:
{
this->logger->log(this->logger, CONTROL, "ignoring payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
DBG1(SIG_DBG_IKE, "ignoring payload %N",
payload_type_names, payload->get_type(payload));
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))
{
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;
}
@@ -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))
{
other_id->destroy(other_id);
this->logger->log(this->logger, AUDIT,
"other peer uses unacceptable ID (%D, excepted %D), deleting IKE_SA",
other_id, configured_other_id);
DBG1(SIG_DBG_IKE, "other peer uses unacceptable ID (%D, excepted %D), deleting IKE_SA",
other_id, configured_other_id);
return DESTROY_ME;
}
/* 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);
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;
}
}
@@ -1003,15 +970,13 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
this->tsr->get_count(this->tsr) == 0 ||
!this->build_child)
{
this->logger->log(this->logger, AUDIT,
"CHILD_SA creation failed");
DBG1(SIG_DBG_IKE, "CHILD_SA creation failed");
}
else
{
if (install_child_sa(this, TRUE) != SUCCESS)
{
this->logger->log(this->logger, ERROR,
"installing CHILD_SA failed, no CHILD_SA built");
DBG1(SIG_DBG_IKE, "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)
{
private_ike_auth_t *this = malloc_thing(private_ike_auth_t);
/* transaction interface functions */
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;
@@ -1075,7 +1040,6 @@ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa)
this->tsr = NULL;
this->build_child = TRUE;
this->reqid = 0;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
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?
*/
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_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->logger->log_chunk(this->logger, RAW, "natd_chunk", natd_chunk);
this->logger->log_chunk(this->logger, RAW, "natd_hash", natd_hash);
DBG3(SIG_DBG_IKE, "natd_chunk %B", &natd_chunk);
DBG3(SIG_DBG_IKE, "natd_hash %B", &natd_hash);
chunk_free(&natd_chunk);
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);
if (this->diffie_hellman == NULL)
{
this->logger->log(this->logger, AUDIT,
"DH group %s (%d) not supported, aborting",
mapping_find(diffie_hellman_group_m, dh_group), dh_group);
DBG1(SIG_DBG_IKE, "DH group %N not supported, aborting",
diffie_hellman_group_names, dh_group);
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;
notify_type_t notify_type = notify_payload->get_notify_type(notify_payload);
this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s",
mapping_find(notify_type_m, notify_type));
DBG2(SIG_DBG_IKE, "process notify type %N", notify_type_names, notify_type);
switch (notify_type)
{
case NO_PROPOSAL_CHOSEN:
{
this->logger->log(this->logger, AUDIT,
"received a NO_PROPOSAL_CHOSEN notify, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "received a NO_PROPOSAL_CHOSEN notify, deleting IKE_SA");
return DESTROY_ME;
}
case INVALID_MAJOR_VERSION:
{
this->logger->log(this->logger, AUDIT,
"received a INVALID_MAJOR_VERSION notify, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "received a INVALID_MAJOR_VERSION notify, deleting IKE_SA");
return DESTROY_ME;
}
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);
dh_group = ntohs(*((u_int16_t*)notify_data.ptr));
this->logger->log(this->logger, AUDIT,
"peer didn't accept DH group %s, it requested %s",
mapping_find(diffie_hellman_group_m, old_dh_group),
mapping_find(diffie_hellman_group_m, dh_group));
DBG1(SIG_DBG_IKE, "peer didn't accept DH group %N, it requested %N",
diffie_hellman_group_names, old_dh_group,
diffie_hellman_group_names, dh_group);
if (!this->connection->check_dh_group(this->connection, dh_group))
{
this->logger->log(this->logger, AUDIT,
"requested DH group not acceptable, aborting");
DBG1(SIG_DBG_IKE, "requested DH group not acceptable, aborting");
return DESTROY_ME;
}
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))
{
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
{
this->logger->log(this->logger, CONTROL|LEVEL3, "NAT-D dst hash mismatch");
DBG2(SIG_DBG_IKE, "NAT-D dst hash mismatch");
}
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))
{
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
{
this->logger->log(this->logger, CONTROL|LEVEL3, "NAT-D src hash mismatch");
DBG2(SIG_DBG_IKE, "NAT-D src hash mismatch");
}
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)
{
this->logger->log(this->logger, AUDIT,
"received %s notify error (%d), deleting IKE_SA",
mapping_find(notify_type_m, notify_type),
notify_type);
DBG1(SIG_DBG_IKE, "received %N notify error, deleting IKE_SA",
notify_type_names, notify_type);
return DESTROY_ME;
}
else
{
this->logger->log(this->logger, CONTROL,
"received %s notify (%d), ignored",
mapping_find(notify_type_m, notify_type),
notify_type);
DBG1(SIG_DBG_IKE, "received %N notify, ignored",
notify_type_names, notify_type);
return SUCCESS;
}
}
@@ -555,8 +540,7 @@ static status_t get_response(private_ike_sa_init_t *this,
/* check message type */
if (request->get_exchange_type(request) != IKE_SA_INIT)
{
this->logger->log(this->logger, ERROR,
"IKE_SA_INIT request of invalid type, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "IKE_SA_INIT request of invalid type, deleting IKE_SA");
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);
response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT,
"no connection for hosts %H...%H found, deleting IKE_SA",
me, other);
DBG1(SIG_DBG_IKE, "no connection for hosts %H...%H found, deleting IKE_SA",
me, other);
return DESTROY_ME;
}
@@ -623,10 +606,8 @@ static status_t get_response(private_ike_sa_init_t *this,
}
default:
{
this->logger->log(this->logger, ERROR|LEVEL1,
"ignoring %s payload (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
DBG2(SIG_DBG_IKE, "ignoring %N payload",
payload_type_names, payload->get_type(payload));
break;
}
}
@@ -639,8 +620,7 @@ static status_t get_response(private_ike_sa_init_t *this,
notify_payload_t *notify = notify_payload_create();
notify->set_notify_type(notify, INVALID_SYNTAX);
response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT,
"request message incomplete, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "request message incomplete, deleting IKE_SA");
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->set_notify_type(notify, NO_PROPOSAL_CHOSEN);
response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT,
"request did not contain any acceptable proposals, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "request did not contain any acceptable proposals, deleting IKE_SA");
return DESTROY_ME;
}
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;
notify_group = this->connection->get_dh_group(this->connection);
this->logger->log(this->logger, AUDIT,
"request used inacceptable DH group %s, sending INVALID_KE_PAYLOAD with %s, deleting IKE_SA",
mapping_find(diffie_hellman_group_m, used_group),
mapping_find(diffie_hellman_group_m, notify_group));
DBG1(SIG_DBG_IKE, "request used inacceptable DH group %N, sending "
"INVALID_KE_PAYLOAD with %N, deleting IKE_SA",
diffie_hellman_group_names, used_group,
diffie_hellman_group_names, notify_group);
/* remove already added payloads */
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->set_notify_type(notify, NO_PROPOSAL_CHOSEN);
response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT,
"could not get random bytes for nonce, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "could not get random bytes for nonce, deleting IKE_SA");
return DESTROY_ME;
}
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->set_notify_type(notify, INVALID_SYNTAX);
response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT,
"request contained wrong number of NAT-D payloads, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "request contained wrong number of NAT-D payloads, deleting IKE_SA");
return DESTROY_ME;
}
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->set_notify_type(notify, NO_PROPOSAL_CHOSEN);
response->add_payload(response, (payload_t*)notify);
this->logger->log(this->logger, AUDIT,
"transform objects could not be created from selected proposal, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "transform objects could not be created from selected proposal, deleting IKE_SA");
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... */
if (response->generate(response, NULL, NULL, &response_packet) != SUCCESS)
{
this->logger->log(this->logger, AUDIT,
"error in response generation, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "error in response generation, deleting IKE_SA");
return DESTROY_ME;
}
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 */
if (response->get_exchange_type(response) != IKE_SA_INIT)
{
this->logger->log(this->logger, ERROR,
"IKE_SA_INIT response of invalid type, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "IKE_SA_INIT response of invalid type, deleting IKE_SA");
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);
if (responder_spi == 0)
{
this->logger->log(this->logger, ERROR,
"response contained a SPI of zero, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "response contained a SPI of zero, deleting IKE_SA");
return DESTROY_ME;
}
@@ -937,9 +910,8 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
}
default:
{
this->logger->log(this->logger, ERROR, "ignoring payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
DBG1(SIG_DBG_IKE, "ignoring payload %N",
payload_type_names, payload->get_type(payload));
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))
{
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;
}
@@ -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);
if (proposal_list->get_count(proposal_list) != 1)
{
this->logger->log(this->logger, AUDIT,
"response did not contain a single proposal, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "response did not contain a single proposal, deleting IKE_SA");
while (proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS)
{
proposal->destroy(proposal);
@@ -981,8 +952,7 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
if (this->proposal == NULL)
{
this->logger->log(this->logger, AUDIT,
"peer selected a proposal we did not offer, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "peer selected a proposal we did not offer, deleting IKE_SA");
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) ||
(this->natd_dst_seen && !this->natd_src_seen))
{
this->logger->log(this->logger, AUDIT,
"request contained wrong number of NAT-D payloads, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "request contained wrong number of NAT-D payloads, deleting IKE_SA");
return DESTROY_ME;
}
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->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,
TRUE, NULL, NULL) != SUCCESS)
{
this->logger->log(this->logger, AUDIT,
"transform objects could not be created from selected proposal, deleting IKE_SA");
DBG1(SIG_DBG_IKE, "transform objects could not be created from selected proposal, deleting IKE_SA");
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_src_matched = FALSE;
this->natd_dst_matched = FALSE;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public;
}
+35 -65
View File
@@ -113,11 +113,6 @@ struct private_rekey_ike_sa_t {
* next transaction processed by the IKE_SA
*/
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 &&
!this->diffie_hellman)
{
this->logger->log(this->logger, ERROR,
"tried to rekey in state %s, aborted",
mapping_find(ike_sa_state_m,
this->ike_sa->get_state(this->ike_sa)));
DBG1(SIG_DBG_IKE, "tried to rekey in state %N, aborted",
ike_sa_state_names, this->ike_sa->get_state(this->ike_sa));
return FAILED;
}
@@ -226,8 +219,7 @@ static status_t get_request(private_rekey_ike_sa_t *this, message_t **result)
me, other);
if (this->connection == NULL)
{
this->logger->log(this->logger, ERROR,
"no connection found to rekey IKE_SA");
DBG1(SIG_DBG_IKE, "no connection found to rekey IKE_SA");
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);
if (this->diffie_hellman == NULL)
{
this->logger->log(this->logger, AUDIT,
"DH group %s (%d) not supported, aborting",
mapping_find(diffie_hellman_group_m, dh_group), dh_group);
DBG1(SIG_DBG_IKE, "DH group %N not supported, aborting",
diffie_hellman_group_names, dh_group);
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);
this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s",
mapping_find(notify_type_m, notify_type));
DBG2(SIG_DBG_IKE,"process notify type %N", notify_type_names, notify_type);
switch (notify_type)
{
case NO_PROPOSAL_CHOSEN:
{
this->logger->log(this->logger, AUDIT,
"received a NO_PROPOSAL_CHOSEN notify, IKE_SA rekeying failed");
DBG1(SIG_DBG_IKE, "received a NO_PROPOSAL_CHOSEN notify, IKE_SA rekeying failed");
return FAILED;
}
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);
dh_group = ntohs(*((u_int16_t*)notify_data.ptr));
this->logger->log(this->logger, AUDIT,
"peer didn't accept DH group %s, it requested %s",
mapping_find(diffie_hellman_group_m, old_dh_group),
mapping_find(diffie_hellman_group_m, dh_group));
DBG1(SIG_DBG_IKE, "peer didn't accept DH group %N, it requested %N",
diffie_hellman_group_names, old_dh_group,
diffie_hellman_group_names, dh_group);
if (!this->connection->check_dh_group(this->connection, dh_group))
{
this->logger->log(this->logger, AUDIT,
"requested DH group not acceptable, IKE_SA rekeying failed");
DBG1(SIG_DBG_IKE, "requested DH group not acceptable, IKE_SA rekeying failed");
return FAILED;
}
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)
{
this->logger->log(this->logger, AUDIT,
"received %s notify error (%d, IKE_SA rekeying failed",
mapping_find(notify_type_m, notify_type),
notify_type);
DBG1(SIG_DBG_IKE, "received %N notify error, IKE_SA rekeying failed",
notify_type_names, notify_type);
return FAILED;
}
else
{
this->logger->log(this->logger, CONTROL,
"received %s notify (%d), ignored",
mapping_find(notify_type_m, notify_type),
notify_type);
DBG1(SIG_DBG_IKE, "received %N notify, ignored",
notify_type_names, notify_type);
return SUCCESS;
}
}
@@ -468,8 +451,7 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
/* check message type */
if (request->get_exchange_type(request) != CREATE_CHILD_SA)
{
this->logger->log(this->logger, ERROR,
"CREATE_CHILD_SA response of invalid type, aborted");
DBG1(SIG_DBG_IKE, "CREATE_CHILD_SA response of invalid type, aborted");
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)
{
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
this->logger->log(this->logger, CONTROL,
"unable to rekey, as delete in progress. Sending NO_PROPOSAL_CHOSEN");
DBG1(SIG_DBG_IKE, "unable to rekey, as delete in progress. Sending NO_PROPOSAL_CHOSEN");
return FAILED;
}
@@ -492,8 +473,7 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
state == CHILD_DELETING)
{
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
this->logger->log(this->logger, CONTROL,
"unable to rekey, one CHILD_SA is half open. Sending NO_PROPOSAL_CHOSEN");
DBG1(SIG_DBG_IKE, "unable to rekey, one CHILD_SA is half open. Sending NO_PROPOSAL_CHOSEN");
iterator->destroy(iterator);
return FAILED;
}
@@ -514,8 +494,7 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
charon->connections, me, other);
if (this->connection == NULL)
{
this->logger->log(this->logger, ERROR,
"no connection found to rekey IKE_SA, sending NO_RROPOSAL_CHOSEN");
DBG1(SIG_DBG_IKE, "no connection found to rekey IKE_SA, sending NO_RROPOSAL_CHOSEN");
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
return FAILED;
}
@@ -552,9 +531,8 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
}
default:
{
this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
DBG1(SIG_DBG_IKE, "ignoring %N payload",
payload_type_names, payload->get_type(payload));
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))
{
build_notify(INVALID_SYNTAX, CHUNK_INITIALIZER, response, TRUE);
this->logger->log(this->logger, AUDIT,
"request message incomplete, IKE_SA rekeying failed");
DBG1(SIG_DBG_IKE, "request message incomplete, IKE_SA rekeying 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();
/* get proposals from request, and select one with ours */
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);
destroy_proposal_list(proposal_list);
/* do we have a proposal? */
if (this->proposal == NULL)
{
this->logger->log(this->logger, AUDIT,
"no proposals acceptable to rekey IKE_SA, sending NO_PROPOSAL_CHOSEN");
DBG1(SIG_DBG_IKE, "no proposals acceptable to rekey IKE_SA, sending NO_PROPOSAL_CHOSEN");
build_notify(NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER, response, TRUE);
return FAILED;
}
@@ -632,10 +608,10 @@ static status_t get_response(private_rekey_ike_sa_t *this, message_t *request,
chunk_t notify_chunk;
notify_group = this->connection->get_dh_group(this->connection);
this->logger->log(this->logger, AUDIT,
"request used inacceptable DH group %s, sending INVALID_KE_PAYLOAD with %s",
mapping_find(diffie_hellman_group_m, used_group),
mapping_find(diffie_hellman_group_m, notify_group));
DBG1(SIG_DBG_IKE, "request used inacceptable DH group %N, sending "
"INVALID_KE_PAYLOAD with %N",
diffie_hellman_group_names, used_group,
diffie_hellman_group_names, notify_group);
notify_group = htons(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 */
if (response->get_exchange_type(response) != CREATE_CHILD_SA)
{
this->logger->log(this->logger, ERROR,
"CREATE_CHILD_SA response of invalid type, aborting");
DBG1(SIG_DBG_IKE, "CREATE_CHILD_SA response of invalid type, aborting");
return FAILED;
}
@@ -753,9 +728,8 @@ static status_t conclude(private_rekey_ike_sa_t *this, message_t *response,
}
default:
{
this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
DBG1(SIG_DBG_IKE, "ignoring %N payload",
payload_type_names, payload->get_type(payload));
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))
{
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;
}
@@ -784,8 +758,7 @@ static status_t conclude(private_rekey_ike_sa_t *this, message_t *response,
if (this->proposal == NULL)
{
this->logger->log(this->logger, AUDIT,
"no proposal selected, rekeying IKE_SA failed");
DBG1(SIG_DBG_IKE, "no proposal selected, rekeying IKE_SA failed");
return FAILED;
}
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,
min(this_lowest.len, this->nonce_s.len)) < 0)
{
this->logger->log(this->logger, ERROR,
"detected simultaneous IKE_SA rekeying, deleting ours");
DBG1(SIG_DBG_IKE, "detected simultaneous IKE_SA rekeying, deleting ours");
this->lost = TRUE;
}
else
{
this->logger->log(this->logger, ERROR,
"detected simultaneous IKE_SA rekeying, but ours is preferred");
DBG1(SIG_DBG_IKE, "detected simultaneous IKE_SA rekeying, but ours is preferred");
}
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->diffie_hellman = NULL;
this->proposal = NULL;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public;
}
-2
View File
@@ -35,8 +35,6 @@
#include <encoding/payloads/nonce_payload.h>
#include <encoding/payloads/notify_payload.h>
#include <encoding/payloads/delete_payload.h>
#include <utils/logger_manager.h>
/*
* 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.
*/
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)
{
this->logger->log(this->logger, ERROR,
"Received a XFRM_MSG_ACQUIRE, but no reqid found");
DBG1(SIG_DBG_KNL, "received a XFRM_MSG_ACQUIRE, but no reqid found");
}
else
{
this->logger->log(this->logger, CONTROL|LEVEL1,
"Received a XFRM_MSG_ACQUIRE");
this->logger->log(this->logger, CONTROL,
"creating acquire job for CHILD_SA with reqid %d",
DBG2(SIG_DBG_KNL, "received a XFRM_MSG_ACQUIRE");
DBG1(SIG_DBG_KNL, "creating acquire job for CHILD_SA with reqid %d",
reqid);
job = (job_t*)acquire_job_create(reqid);
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;
reqid = expire->state.reqid;
this->logger->log(this->logger, CONTROL|LEVEL1,
"Received a XFRM_MSG_EXPIRE");
this->logger->log(this->logger, CONTROL,
"creating %s job for %s CHILD_SA 0x%x (reqid %d)",
DBG2(SIG_DBG_KNL, "received a XFRM_MSG_EXPIRE");
DBG1(SIG_DBG_KNL, "creating %s job for %N CHILD_SA 0x%x (reqid %d)",
expire->hard ? "delete" : "rekey",
mapping_find(protocol_id_m, protocol), ntohl(spi),
protocol_id_names, protocol, ntohl(spi),
reqid);
if (expire->hard)
{
@@ -457,7 +447,7 @@ static status_t get_spi(private_kernel_interface_t *this,
memset(&request, 0, sizeof(request));
status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "getting spi");
DBG2(SIG_DBG_KNL, "getting spi");
hdr = (struct nlmsghdr*)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)
{
this->logger->log(this->logger, ERROR, "netlink communication failed");
DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED;
}
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));
status = FAILED;
}
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;
}
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;
}
else
{
*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);
@@ -526,7 +516,7 @@ static status_t add_sa(private_kernel_interface_t *this,
memset(&request, 0, sizeof(request));
status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "adding SA");
DBG2(SIG_DBG_KNL, "adding SA");
hdr = (struct nlmsghdr*)request;
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);
if (alg_name == NULL)
{
this->logger->log(this->logger, ERROR, "Algorithm %s not supported by kernel!",
mapping_find(encryption_algorithm_m, enc_alg->algorithm));
DBG1(SIG_DBG_KNL, "algorithm %N not supported by kernel!",
encryption_algorithm_names, enc_alg->algorithm);
return FAILED;
}
this->logger->log(this->logger, CONTROL|LEVEL2, " using encryption algorithm %s with key size %d",
mapping_find(encryption_algorithm_m, enc_alg->algorithm), key_size);
DBG2(SIG_DBG_KNL, " using encryption algorithm %N with key size %d",
encryption_algorithm_names, enc_alg->algorithm, key_size);
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + key_size);
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);
if (alg_name == NULL)
{
this->logger->log(this->logger, ERROR, "Algorithm %s not supported by kernel!",
mapping_find(integrity_algorithm_m, int_alg->algorithm));
DBG1(SIG_DBG_KNL, "algorithm %N not supported by kernel!",
integrity_algorithm_names, int_alg->algorithm);
return FAILED;
}
this->logger->log(this->logger, CONTROL|LEVEL2, " using integrity algorithm %s with key size %d",
mapping_find(integrity_algorithm_m, int_alg->algorithm), key_size);
DBG2(SIG_DBG_KNL, " using integrity algorithm %N with key size %d",
integrity_algorithm_names, int_alg->algorithm, key_size);
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + key_size);
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)
{
this->logger->log(this->logger, ERROR, "netlink communication failed");
DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED;
}
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;
}
else if (((struct nlmsgerr*)NLMSG_DATA(response))->error)
{
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_NEWSA got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_NEWSA got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
status = FAILED;
}
@@ -681,7 +671,7 @@ static status_t update_sa(
memset(&request, 0, sizeof(request));
status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "getting SA");
DBG2(SIG_DBG_KNL, "getting SA");
hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST;
@@ -696,30 +686,30 @@ static status_t update_sa(
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;
}
else if (update->nlmsg_type == NLMSG_ERROR)
{
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETSA got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(update))->error));
DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_GETSA got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(update))->error));
free(update);
return FAILED;
}
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);
return FAILED;
}
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);
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_type = XFRM_MSG_UPDSA;
@@ -731,7 +721,7 @@ static status_t update_sa(
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;
host2xfrm(new_dst, &sa->id.daddr);
@@ -756,24 +746,24 @@ static status_t update_sa(
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);
return FAILED;
}
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;
}
else if (((struct nlmsgerr*)NLMSG_DATA(response))->error)
{
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_XXXSA got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_XXXSA got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
status = FAILED;
}
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);
}
@@ -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_info *sa_info;
this->logger->log(this->logger, CONTROL|LEVEL2, "querying SA");
DBG2(SIG_DBG_KNL, "querying SA");
memset(&request, 0, sizeof(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)
{
this->logger->log(this->logger, ERROR, "netlink communication failed");
DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED;
}
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);
return FAILED;
}
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);
return FAILED;
}
@@ -847,7 +837,7 @@ static status_t del_sa(private_kernel_interface_t *this, host_t *dst,
memset(&request, 0, sizeof(request));
status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "deleting SA");
DBG2(SIG_DBG_KNL, "deleting SA");
hdr = (struct nlmsghdr*)request;
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)
{
this->logger->log(this->logger, ERROR, "netlink communication failed");
DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED;
}
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;
}
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));
status = FAILED;
}
@@ -1010,8 +1000,7 @@ static status_t add_policy(private_kernel_interface_t *this,
if (!update)
{
current->refcount++;
this->logger->log(this->logger, CONTROL|LEVEL1,
"policy already exists, increasing refcount");
DBG2(SIG_DBG_KNL, "policy already exists, increasing refcount");
if (!high_prio)
{
/* 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;
}
this->logger->log(this->logger, CONTROL|LEVEL2, "adding policy");
DBG2(SIG_DBG_KNL, "adding policy");
memset(&request, 0, sizeof(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)
{
this->logger->log(this->logger, ERROR, "netlink communication failed");
DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED;
}
else if (response->nlmsg_type != NLMSG_ERROR)
{
this->logger->log(this->logger, ERROR,
"netlink request XFRM_MSG_UPDPOLICY not acknowledged");
DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_UPDPOLICY not acknowledged");
status = FAILED;
}
else if (((struct nlmsgerr*)NLMSG_DATA(response))->error)
{
this->logger->log(this->logger, ERROR,
"netlink request XFRM_MSG_UPDPOLICY got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_UPDPOLICY got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
status = FAILED;
}
@@ -1125,7 +1112,7 @@ static status_t query_policy(private_kernel_interface_t *this,
memset(&request, 0, sizeof(request));
status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "querying policy");
DBG2(SIG_DBG_KNL, "querying policy");
hdr = (struct nlmsghdr*)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)
{
this->logger->log(this->logger, ERROR, "netlink communication failed");
DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED;
}
else if (response->nlmsg_type == NLMSG_ERROR)
{
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETPOLICY got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_GETPOLICY got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
free(response);
return FAILED;
}
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);
return FAILED;
}
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);
return FAILED;
}
@@ -1185,7 +1172,7 @@ static status_t del_policy(private_kernel_interface_t *this,
iterator_t *iterator;
status_t status = SUCCESS;
this->logger->log(this->logger, CONTROL|LEVEL2, "deleting policy");
DBG2(SIG_DBG_KNL, "deleting policy");
/* create a policy */
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)
{
/* is used by more SAs, keep in kernel */
this->logger->log(this->logger, CONTROL|LEVEL1,
"is used by other SAs, not removed");
DBG2(SIG_DBG_KNL, "is used by other SAs, not removed");
iterator->destroy(iterator);
pthread_mutex_unlock(&this->pol_mutex);
return SUCCESS;
@@ -1219,8 +1205,7 @@ static status_t del_policy(private_kernel_interface_t *this,
pthread_mutex_unlock(&this->pol_mutex);
if (!to_delete)
{
this->logger->log(this->logger, CONTROL|LEVEL2,
"no such policy found");
DBG1(SIG_DBG_KNL, "no such policy 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)
{
this->logger->log(this->logger, ERROR, "netlink communication failed");
DBG1(SIG_DBG_KNL, "netlink communication failed");
return FAILED;
}
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;
}
else if (((struct nlmsgerr*)NLMSG_DATA(response))->error)
{
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_DELPOLICY got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
DBG1(SIG_DBG_KNL, "netlink request XFRM_MSG_DELPOLICY got an error: %s",
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
status = FAILED;
}
@@ -1294,7 +1279,6 @@ kernel_interface_t *kernel_interface_create()
this->pid = getpid();
this->responses = 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->pol_mutex),NULL);
pthread_cond_init(&(this->condvar),NULL);
+8 -21
View File
@@ -32,7 +32,6 @@
#include <queues/job_queue.h>
#include <queues/jobs/job.h>
#include <queues/jobs/incoming_packet_job.h>
#include <utils/logger_manager.h>
typedef struct private_receiver_t private_receiver_t;
@@ -50,11 +49,6 @@ struct private_receiver_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 */
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)
{
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);
charon->job_queue->add(charon->job_queue,current_job);
}
/* bad bad, rebuild the socket ? */
this->logger->log(this->logger, ERROR, "Receiving from socket failed!");
/* bad bad, TODO: rebuild the socket ? */
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)
{
this->logger->log(this->logger, CONTROL | LEVEL1, "Going to terminate receiver thread");
pthread_cancel(this->assigned_thread);
pthread_join(this->assigned_thread, NULL);
this->logger->log(this->logger, CONTROL | LEVEL1, "Receiver thread terminated");
free(this);
}
@@ -108,13 +98,10 @@ receiver_t * receiver_create()
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)
{
this->logger->log(this->logger, ERROR, "Receiver thread could not be started");
free(this);
charon->kill(charon, "Unable to create receiver thread");
charon->kill(charon, "unable to create receiver thread");
}
return &(this->public);
+7 -19
View File
@@ -28,7 +28,6 @@
#include <daemon.h>
#include <definitions.h>
#include <utils/logger_manager.h>
#include <queues/job_queue.h>
@@ -47,11 +46,6 @@ struct private_scheduler_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 */
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)
{
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 */
current_job = charon->event_queue->get(charon->event_queue);
/* 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.",
mapping_find(job_type_m, current_job->get_type(current_job)));
DBG2(SIG_DBG_JOB, "got event, adding job %N to job-queue",
job_type_names, current_job->get_type(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)
{
this->logger->log(this->logger, CONTROL | LEVEL1, "going to terminate scheduler thread");
pthread_cancel(this->assigned_thread);
pthread_join(this->assigned_thread, NULL);
this->logger->log(this->logger, CONTROL | LEVEL1, "scheduler thread terminated");
free(this);
}
@@ -98,18 +89,15 @@ static void destroy(private_scheduler_t *this)
scheduler_t * scheduler_create()
{
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)
{
/* thread could not be created */
this->logger->log(this->logger, ERROR, "scheduler thread could not be created!");
free(this);
charon->kill(charon, "unable to create scheduler thread");
}
return &(this->public);
}
+5 -17
View File
@@ -30,7 +30,6 @@
#include <network/socket.h>
#include <network/packet.h>
#include <queues/send_queue.h>
#include <utils/logger_manager.h>
typedef struct private_sender_t private_sender_t;
@@ -48,11 +47,6 @@ struct private_sender_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 */
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)
{
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);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR, "Sending packet failed");
DBG1(SIG_DBG_NET, "sending packet failed");
}
current_packet->destroy(current_packet);
}
@@ -87,12 +82,8 @@ static void send_packets(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_join(this->assigned_thread, NULL);
this->logger->log(this->logger, CONTROL | LEVEL1, "Sender thread terminated");
free(this);
}
@@ -104,14 +95,11 @@ sender_t * sender_create()
private_sender_t *this = malloc_thing(private_sender_t);
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)
{
this->logger->log(this->logger, ERROR, "Sender thread could not be created");
free(this);
charon->kill(charon, "Unable to create sender thread");
charon->kill(charon, "unable to create sender thread");
}
return &(this->public);
+294 -234
View File
@@ -33,10 +33,11 @@
#include "stroke_interface.h"
#include <stroke.h>
#include <types.h>
#include <stroke.h>
#include <daemon.h>
#include <crypto/x509.h>
#include <crypto/crl.h>
#include <queues/jobs/initiate_job.h>
#include <queues/jobs/route_job.h>
#include <utils/leak_detective.h>
@@ -59,16 +60,11 @@ struct private_stroke_t {
* Public part of stroke_t object.
*/
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
@@ -76,14 +72,9 @@ struct private_stroke_t {
int socket;
/**
* Thread which reads from the ocket
* Thread which reads from the Socket
*/
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
*/
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];
x509_t *cert;
@@ -142,7 +133,7 @@ static x509_t* load_end_certificate(const char *filename, identification_t **idp
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))
{
@@ -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;
proposal_t *proposal;
traffic_selector_t *my_ts, *other_ts;
pop_string(msg, &msg->add_conn.name);
pop_string(msg, &msg->add_conn.me.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.esp);
this->logger->log(this->logger, CONTROL,
"received stroke: add connection \"%s\"", msg->add_conn.name);
DBG1(SIG_DBG_CFG, "received stroke: add connection '%s'", msg->add_conn.name);
this->logger->log(this->logger, CONTROL|LEVEL2, "conn %s", msg->add_conn.name);
this->logger->log(this->logger, CONTROL|LEVEL2, " right=%s", msg->add_conn.me.address);
this->logger->log(this->logger, CONTROL|LEVEL2, " left=%s", msg->add_conn.other.address);
this->logger->log(this->logger, CONTROL|LEVEL2, " rightsubnet=%s", msg->add_conn.me.subnet);
this->logger->log(this->logger, CONTROL|LEVEL2, " leftsubnet=%s", msg->add_conn.other.subnet);
this->logger->log(this->logger, CONTROL|LEVEL2, " rightid=%s", msg->add_conn.me.id);
this->logger->log(this->logger, CONTROL|LEVEL2, " leftid=%s", msg->add_conn.other.id);
this->logger->log(this->logger, CONTROL|LEVEL2, " rightcert=%s", msg->add_conn.me.cert);
this->logger->log(this->logger, CONTROL|LEVEL2, " leftcert=%s", msg->add_conn.other.cert);
this->logger->log(this->logger, CONTROL|LEVEL2, " rightca=%s", msg->add_conn.me.ca);
this->logger->log(this->logger, CONTROL|LEVEL2, " leftca=%s", msg->add_conn.other.ca);
this->logger->log(this->logger, CONTROL|LEVEL2, " 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, "conn %s", msg->add_conn.name);
DBG2(SIG_DBG_CFG, " right=%s", msg->add_conn.me.address);
DBG2(SIG_DBG_CFG, " left=%s", msg->add_conn.other.address);
DBG2(SIG_DBG_CFG, " rightsubnet=%s", msg->add_conn.me.subnet);
DBG2(SIG_DBG_CFG, " leftsubnet=%s", msg->add_conn.other.subnet);
DBG2(SIG_DBG_CFG, " rightid=%s", msg->add_conn.me.id);
DBG2(SIG_DBG_CFG, " leftid=%s", msg->add_conn.other.id);
DBG2(SIG_DBG_CFG, " rightcert=%s", msg->add_conn.me.cert);
DBG2(SIG_DBG_CFG, " leftcert=%s", msg->add_conn.other.cert);
DBG2(SIG_DBG_CFG, " rightca=%s", msg->add_conn.me.ca);
DBG2(SIG_DBG_CFG, " leftca=%s", msg->add_conn.other.ca);
DBG2(SIG_DBG_CFG, " ike=%s", msg->add_conn.algorithms.ike);
DBG2(SIG_DBG_CFG, " esp=%s", msg->add_conn.algorithms.esp);
my_host = msg->add_conn.me.address?
host_create_from_string(msg->add_conn.me.address, IKE_PORT) : NULL;
if (my_host == NULL)
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"invalid host: %s", msg->add_conn.me.address);
DBG1(SIG_DBG_CFG, "invalid host: %s\n", msg->add_conn.me.address);
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;
if (other_host == NULL)
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"invalid host: %s", msg->add_conn.other.address);
DBG1(SIG_DBG_CFG, "invalid host: %s\n", msg->add_conn.other.address);
my_host->destroy(my_host);
return;
}
@@ -228,8 +216,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
stroke_end_t tmp_end;
host_t *tmp_host;
this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1,
"left is other host, swapping ends");
DBG2(SIG_DBG_CFG, "left is other host, swapping ends\n");
tmp_host = my_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))
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"left nor right host is our side, aborting");
DBG1(SIG_DBG_CFG, "left nor right host is our side, aborting\n");
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);
if (my_id == NULL)
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"invalid id: %s", msg->add_conn.me.id);
DBG1(SIG_DBG_CFG, "invalid ID: %s\n", msg->add_conn.me.id);
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);
if (other_id == NULL)
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"invalid id: %s", msg->add_conn.other.id);
DBG1(SIG_DBG_CFG, "invalid ID: %s\n", msg->add_conn.other.id);
my_id->destroy(my_id);
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);
if (my_subnet == NULL)
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"invalid subnet: %s", msg->add_conn.me.subnet);
DBG1(SIG_DBG_CFG, "invalid subnet: %s\n", msg->add_conn.me.subnet);
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);
if (other_subnet == NULL)
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"invalid subnet: %s", msg->add_conn.me.subnet);
DBG1(SIG_DBG_CFG, "invalid subnet: %s\n", msg->add_conn.me.subnet);
my_subnet->destroy(my_subnet);
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)
{
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)
{
@@ -329,7 +311,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
}
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)
{
@@ -354,9 +336,9 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
{
other_ca = identification_create_from_string("%any");
}
this->logger->log(this->logger, CONTROL|LEVEL1, " my ca: '%D'", my_ca);
this->logger->log(this->logger, CONTROL|LEVEL1, " other ca:'%D'", other_ca);
this->logger->log(this->logger, CONTROL|LEVEL1, " updown: '%s'", msg->add_conn.me.updown);
DBG2(SIG_DBG_CFG, " my ca: '%D'", my_ca);
DBG2(SIG_DBG_CFG, " other ca:'%D'", other_ca);
DBG2(SIG_DBG_CFG, " updown: '%s'", msg->add_conn.me.updown);
connection = connection_create(msg->add_conn.name,
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);
if (proposal == NULL)
{
this->logger->log(this->logger, ERROR,
"invalid IKE proposal string: %s", proposal_string);
DBG1(SIG_DBG_CFG, "invalid IKE proposal string: %s", proposal_string);
my_id->destroy(my_id);
other_id->destroy(other_id);
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);
if (proposal == NULL)
{
this->logger->log(this->logger, ERROR,
"invalid ESP proposal string: %s", proposal_string);
DBG1(SIG_DBG_CFG, "invalid ESP proposal string: %s", proposal_string);
policy->destroy(policy);
connection->destroy(connection);
return;
@@ -457,11 +437,11 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
/* add to global connection list */
charon->connections->add_connection(charon->connections, connection);
this->logger->log(this->logger, CONTROL,
"added connection \"%s\": %H[%D]...%H[%D]", msg->add_conn.name,
my_host, my_id, other_host, other_id);
DBG1(SIG_DBG_CFG, "added connection '%s': %H[%D]...%H[%D]",
msg->add_conn.name, my_host, my_id, other_host, other_id);
/* add to global policy list */
charon->policies->add_policy(charon->policies, policy);
return;
/* 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;
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,
msg->del_conn.name);
charon->policies->delete_policy(charon->policies, msg->del_conn.name);
if (status == SUCCESS)
{
this->stroke_logger->log(this->stroke_logger, CONTROL,
"Deleted connection '%s'", msg->del_conn.name);
fprintf(this->out, "deleted connection '%s'\n", msg->del_conn.name);
}
else
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"No connection named '%s'", msg->del_conn.name);
fprintf(this->out, "no connection named '%s'\n", msg->del_conn.name);
}
}
@@ -508,19 +486,17 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
initiate_job_t *job;
connection_t *connection;
policy_t *policy;
ike_sa_t *init_ike_sa = NULL;
signal_t signal;
pop_string(msg, &(msg->initiate.name));
this->logger->log(this->logger, CONTROL,
"received stroke: initiate \"%s\"",
msg->initiate.name);
DBG1(SIG_DBG_CFG, "received stroke: initiate '%s'", msg->initiate.name);
connection = charon->connections->get_connection_by_name(charon->connections,
msg->initiate.name);
if (connection == NULL)
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"no connection named \"%s\"",
msg->initiate.name);
fprintf(this->out, "no connection named '%s'\n", msg->initiate.name);
return;
}
if (!connection->is_ikev2(connection))
@@ -533,17 +509,54 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
msg->initiate.name);
if (policy == NULL)
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"no policy named \"%s\"",
msg->initiate.name);
fprintf(this->out, "no policy named '%s'\n", msg->initiate.name);
connection->destroy(connection);
return;
}
this->stroke_logger->log(this->stroke_logger, CONTROL,
"initiating connection \"%s\" (see log)...",
msg->initiate.name);
fprintf(this->out, "initiating connection '%s'\n", msg->initiate.name);
job = initiate_job_create(connection, policy);
charon->bus->set_listen_state(charon->bus, TRUE);
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;
pop_string(msg, &(msg->route.name));
this->logger->log(this->logger, CONTROL,
"received stroke: %s \"%s\"",
route ? "route" : "unroute",
msg->route.name);
DBG1(SIG_DBG_CFG, "received stroke: %s '%s'",
route ? "route" : "unroute", msg->route.name);
/* we wouldn't need a connection, but we only want to route policies
* 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);
if (connection == NULL)
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"no connection named \"%s\"",
msg->route.name);
fprintf(this->out, "no connection named '%s'\n", msg->route.name);
return;
}
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);
if (policy == NULL)
{
this->stroke_logger->log(this->stroke_logger, ERROR,
"no policy named \"%s\"",
msg->route.name);
fprintf(this->out, "no policy named '%s'\n", msg->route.name);
connection->destroy(connection);
return;
}
this->stroke_logger->log(this->stroke_logger, CONTROL,
"%s policy \"%s\"",
route ? "routing" : "unrouting",
msg->route.name);
fprintf(this->out, "%s policy '%s'\n",
route ? "routing" : "unrouting", msg->route.name);
job = route_job_create(connection, policy, route);
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)
{
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);
}
/**
* 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;
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,
"job queue load: %d",
charon->job_queue->get_count(charon->job_queue));
this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1,
"scheduled events: %d",
charon->event_queue->get_count(charon->event_queue));
fprintf(this->out, "worker threads idle: %d of %d\n",
charon->thread_pool->get_idle_threads(charon->thread_pool),
charon->thread_pool->get_pool_size(charon->thread_pool));
fprintf(this->out, "job queue load: %d\n",
charon->job_queue->get_count(charon->job_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);
this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1,
"listening on %d addresses:",
list->get_count(list));
fprintf(this->out, "listening on %d addresses:\n", list->get_count(list));
while (list->remove_first(list, (void**)&host) == SUCCESS)
{
this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1,
" %H", host);
fprintf(this->out, " %H\n", host);
host->destroy(host);
}
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));
}
charon->connections->log_connections(charon->connections,
this->stroke_logger, msg->status.name);
charon->ike_sa_manager->log_status(charon->ike_sa_manager,
this->stroke_logger, msg->status.name);
fprintf(this->out, "connections:\n");
iterator = charon->connections->create_iterator(charon->connections);
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)
{
iterator_t *iterator;
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)
{
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)
{
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;
else if (strcasecmp(context, "PARSR") == 0) return PARSER;
else if (strcasecmp(context, "GNRAT") == 0) return GENERATOR;
else if (strcasecmp(context, "IKESA") == 0) return IKE_SA;
else if (strcasecmp(context, "SAMGR") == 0) return IKE_SA_MANAGER;
else if (strcasecmp(context, "CHDSA") == 0) return CHILD_SA;
else if (strcasecmp(context, "MESSG") == 0) return MESSAGE;
else if (strcasecmp(context, "TPOOL") == 0) return THREAD_POOL;
else if (strcasecmp(context, "WORKR") == 0) return WORKER;
else if (strcasecmp(context, "SCHED") == 0) return SCHEDULER;
else if (strcasecmp(context, "SENDR") == 0) return SENDER;
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;
if (strcasecmp(type, "any") == 0) return SIG_ANY;
else if (strcasecmp(type, "mgr") == 0) return SIG_DBG_MGR;
else if (strcasecmp(type, "ike") == 0) return SIG_DBG_IKE;
else if (strcasecmp(type, "chd") == 0) return SIG_DBG_CHD;
else if (strcasecmp(type, "job") == 0) return SIG_DBG_JOB;
else if (strcasecmp(type, "cfg") == 0) return SIG_DBG_CFG;
else if (strcasecmp(type, "knl") == 0) return SIG_DBG_KNL;
else if (strcasecmp(type, "net") == 0) return SIG_DBG_NET;
else if (strcasecmp(type, "enc") == 0) return SIG_DBG_ENC;
else if (strcasecmp(type, "lib") == 0) return SIG_DBG_LIB;
else return -1;
}
/**
* set the type of logged messages in a context
*/
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
* set the verbosity debug output
*/
static void stroke_loglevel(private_stroke_t *this, stroke_msg_t *msg)
{
log_level_t level;
logger_context_t context;
pop_string(msg, &(msg->loglevel.context));
this->logger->log(this->logger, CONTROL, "received stroke: loglevel for %s", msg->loglevel.context);
signal_t signal;
context = get_context(msg->loglevel.context);
if (context == -2)
pop_string(msg, &(msg->loglevel.type));
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;
}
if (msg->loglevel.level == 0)
level = LEVEL0;
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);
charon->outlog->set_level(charon->outlog, signal, msg->loglevel.level);
charon->syslog->set_level(charon->syslog, signal, msg->loglevel.level);
}
/**
@@ -794,7 +870,6 @@ static void stroke_receive(private_stroke_t *this)
int strokeaddrlen = sizeof(strokeaddr);
ssize_t bytes_read;
int strokefd;
FILE *strokefile;
int oldstate;
/* disable cancellation by default */
@@ -809,7 +884,7 @@ static void stroke_receive(private_stroke_t *this)
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;
}
@@ -817,7 +892,7 @@ static void stroke_receive(private_stroke_t *this)
bytes_read = recv(strokefd, &msg_length, sizeof(msg_length), MSG_PEEK);
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);
continue;
}
@@ -827,24 +902,21 @@ static void stroke_receive(private_stroke_t *this)
bytes_read = recv(strokefd, msg, msg_length, 0);
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);
continue;
}
strokefile = fdopen(dup(strokefd), "w");
if (strokefile == NULL)
this->out = fdopen(dup(strokefd), "w");
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);
free(msg);
continue;
}
/* setup a logger which writes status to the unix socket */
this->stroke_logger = logger_create("", CONTROL|ERROR, FALSE, strokefile);
this->logger->log_bytes(this->logger, RAW, "stroke message", (void*)msg, msg_length);
DBG3(SIG_DBG_CFG, "stroke message %b", (void*)msg, msg_length);
switch (msg->type)
{
@@ -864,8 +936,7 @@ static void stroke_receive(private_stroke_t *this)
stroke_status(this, msg);
break;
case STR_STATUS_ALL:
this->stroke_logger->enable_level(this->stroke_logger, LEVEL1);
stroke_status(this, msg);
stroke_statusall(this, msg);
break;
case STR_ADD_CONN:
stroke_add_conn(this, msg);
@@ -873,9 +944,6 @@ static void stroke_receive(private_stroke_t *this)
case STR_DEL_CONN:
stroke_del_conn(this, msg);
break;
case STR_LOGTYPE:
stroke_logtype(this, msg);
break;
case STR_LOGLEVEL:
stroke_loglevel(this, msg);
break;
@@ -886,10 +954,9 @@ static void stroke_receive(private_stroke_t *this)
stroke_reread(this, msg);
break;
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(strokefile);
fclose(this->out);
close(strokefd);
free(msg);
}
@@ -900,7 +967,6 @@ static void stroke_receive(private_stroke_t *this)
*/
static void destroy(private_stroke_t *this)
{
pthread_cancel(this->assigned_thread);
pthread_join(this->assigned_thread, NULL);
@@ -909,7 +975,6 @@ static void destroy(private_stroke_t *this)
free(this);
}
/*
* Described in header-file
*/
@@ -921,16 +986,11 @@ stroke_t *stroke_create()
/* public functions */
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 */
this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
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);
return NULL;
}
@@ -938,7 +998,7 @@ stroke_t *stroke_create()
old = umask(~S_IRWXU);
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);
free(this);
return NULL;
@@ -947,7 +1007,7 @@ stroke_t *stroke_create()
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);
unlink(socket_addr.sun_path);
free(this);
@@ -955,9 +1015,9 @@ stroke_t *stroke_create()
}
/* 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);
unlink(socket_addr.sun_path);
free(this);
+1 -14
View File
@@ -23,9 +23,6 @@
#ifndef 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;
@@ -36,17 +33,7 @@ typedef struct stroke_t stroke_t;
*
* stroke_t allows config manipulation (as whack in pluto).
* Messages of type stroke_msg_t's are sent over a unix socket
* (/var/run/charon.ctl). stroke_t implements the connections_t
* 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
* (/var/run/charon.ctl).
*
* @b Constructors:
* - stroke_create()
+36 -33
View File
@@ -27,10 +27,9 @@
#include <errno.h>
#include "thread_pool.h"
#include <daemon.h>
#include <queues/job_queue.h>
#include <utils/logger.h>
typedef struct private_thread_pool_t private_thread_pool_t;
@@ -47,17 +46,17 @@ struct private_thread_pool_t {
/**
* 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.
*/
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 */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
this->logger->log(this->logger, CONTROL,
"worker thread running, thread_ID: %06u",
(int)pthread_self());
DBG1(SIG_DBG_JOB, "worker thread running, thread_ID: %06u",
(int)pthread_self());
while (TRUE)
{
this->idle_threads++;
job = charon->job_queue->get(charon->job_queue);
this->idle_threads--;
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.
*/
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;
}
/**
* 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.
*/
@@ -103,9 +111,9 @@ static void destroy(private_thread_pool_t *this)
{
int current;
/* flag thread for termination */
for (current = 0; current < this->pool_size; current++) {
this->logger->log(this->logger, CONTROL,
"cancelling worker thread #%d", current+1);
for (current = 0; current < this->pool_size; current++)
{
DBG1(SIG_DBG_JOB, "cancelling worker thread #%d", current+1);
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++) {
if (pthread_join(this->threads[current], NULL) == 0)
{
this->logger->log(this->logger, CONTROL,
"worker thread #%d terminated", current+1);
DBG1(SIG_DBG_JOB, "worker thread #%d terminated", current+1);
}
else
{
this->logger->log(this->logger, ERROR,
"could not terminate worker thread #%d", current+1);
DBG1(SIG_DBG_JOB, "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 */
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 */
this->pool_size = pool_size;
this->idle_threads = 0;
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 */
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)
{
this->logger->log(this->logger, CONTROL,
"created worker thread #%d", current+1);
DBG1(SIG_DBG_JOB, "created worker thread #%d", current+1);
}
else
{
/* 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);
return NULL;
charon->kill(charon, "could not create any worker threads");
}
/* not all threads could be created, but at least one :-/ */
this->logger->log(this->logger, ERROR,
"Could only create %d from requested %d threads!",
current, pool_size);
DBG1(SIG_DBG_JOB, "could only create %d from requested %d threads!",
current, pool_size);
this->pool_size = current;
return (thread_pool_t*)this;
break;
}
}
return (thread_pool_t*)this;
+11 -2
View File
@@ -45,13 +45,22 @@ typedef struct thread_pool_t thread_pool_t;
* @ingroup threads
*/
struct thread_pool_t {
/**
* @brief Return currently instanciated thread count.
*
*
* @param thread_pool calling object
* @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.
+1 -4
View File
@@ -30,12 +30,9 @@ crypto/diffie_hellman.c crypto/diffie_hellman.h \
utils/identification.c utils/identification.h \
utils/linked_list.c utils/linked_list.h utils/iterator.h\
utils/randomizer.c utils/randomizer.h \
utils/logger.c utils/logger.h \
utils/logger_manager.c utils/logger_manager.h \
utils/host.c utils/host.h \
utils/lexparser.c utils/lexparser.h \
utils/leak_detective.c utils/leak_detective.h \
utils/tester.c utils/tester.h
utils/leak_detective.c utils/leak_detective.h
libstrongswan_la_LIBADD = -lgmp -lpthread
+29 -49
View File
@@ -13,14 +13,14 @@
* for more details.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "types.h"
#include "asn1.h"
#include <utils/logger_manager.h>
#include <types.h>
#include <library.h>
/* some common prefabricated ASN.1 constants */
static u_char ASN1_INTEGER_0_str[] = { 0x02, 0x00 };
@@ -80,17 +80,6 @@ static const asn1Object_t algorithmIdentifierObjects[] = {
#define ALGORITHM_ID_PARAMETERS 2
#define ALGORITHM_ID_ROOF 3
static logger_t *logger = NULL;
/**
* initializes the ASN.1 logger
*/
static void asn1_init_logger(void)
{
if (logger == NULL)
logger = logger_manager->get_logger(logger_manager, ASN1);
}
/**
* return the ASN.1 encoded algorithm identifier
*/
@@ -171,14 +160,14 @@ u_int asn1_length(chunk_t *blob)
if (n > blob->len)
{
logger->log(logger, ERROR|LEVEL1, "number of length octets is larger than ASN.1 object");
DBG2("number of length octets is larger than ASN.1 object");
return ASN1_INVALID_LENGTH;
}
if (n > sizeof(len))
{
logger->log(logger, ERROR|LEVEL1, "number of length octets is larger than limit of %d octets",
(int)sizeof(len));
DBG2("number of length octets is larger than limit of %d octets",
(int)sizeof(len));
return ASN1_INVALID_LENGTH;
}
@@ -289,8 +278,6 @@ time_t asn1totime(const chunk_t *utctime, asn1_t type)
*/
void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit)
{
asn1_init_logger();
ctx->blobs[0] = blob;
ctx->level0 = level0;
ctx->implicit = implicit;
@@ -310,7 +297,7 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type)
oid = known_oid(object);
if (oid != OID_UNKNOWN)
{
logger->log(logger, CONTROL|LEVEL2, " '%s'", oid_names[oid].name);
DBG2(" '%s'", oid_names[oid].name);
return;
}
break;
@@ -319,22 +306,18 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type)
case ASN1_PRINTABLESTRING:
case ASN1_T61STRING:
case ASN1_VISIBLESTRING:
logger->log(logger, CONTROL|LEVEL2, " '%.*s'", (int)object.len, object.ptr);
DBG2(" '%.*s'", (int)object.len, object.ptr);
return;
case ASN1_UTCTIME:
case ASN1_GENERALIZEDTIME:
{
char buf[TIMETOA_BUF];
time_t time = asn1totime(&object, type);
timetoa(buf, TIMETOA_BUF, &time, TRUE);
logger->log(logger, CONTROL|LEVEL2, " '%s'", buf);
DBG2(" '%T'", asn1totime(&object, type));
}
return;
default:
break;
}
logger->log_chunk(logger, RAW|LEVEL1, "", object);
DBG3("%B", &object);
}
/**
@@ -372,7 +355,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
if ((obj.flags & ASN1_DEF) && (blob->len == 0 || *start_ptr != obj.type) )
{
/* field is missing */
logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", *level, obj.name);
DBG2("L%d - %s:", *level, obj.name);
if (obj.type & ASN1_CONSTRUCTED)
{
(*objectID)++ ; /* skip context-specific tag */
@@ -397,7 +380,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
if (blob->len < 2)
{
logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN.1 object smaller than 2 octets",
DBG2("L%d - %s: ASN.1 object smaller than 2 octets",
*level, obj.name);
return FALSE;
}
@@ -406,7 +389,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len)
{
logger->log(logger, ERROR|LEVEL1, "L%d - %s: length of ASN.1 object invalid or too large",
DBG2("L%d - %s: length of ASN.1 object invalid or too large",
*level, obj.name);
return FALSE;
}
@@ -419,7 +402,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
if (obj.flags & ASN1_RAW)
{
logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", *level, obj.name);
DBG2("L%d - %s:", *level, obj.name);
object->ptr = start_ptr;
object->len = (size_t)(blob->ptr - start_ptr);
return TRUE;
@@ -427,13 +410,13 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
if (*start_ptr != obj.type && !(ctx->implicit && *objectID == 0))
{
logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
DBG1("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
*level, obj.name, obj.type, *start_ptr);
logger->log_bytes(logger, RAW|LEVEL1, "", start_ptr, (u_int)(blob->ptr - start_ptr));
DBG3("%b", start_ptr, (u_int)(blob->ptr - start_ptr));
return FALSE;
}
logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", ctx->level0+obj.level, obj.name);
DBG2("L%d - %s:", ctx->level0+obj.level, obj.name);
/* In case of "SEQUENCE OF" or "SET OF" start a loop */
if (obj.flags & ASN1_LOOP)
@@ -458,7 +441,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
{
object->ptr = start_ptr;
object->len = (size_t)(blob->ptr - start_ptr);
logger->log_chunk(logger, RAW|LEVEL2, "", *object);
DBG3("%B", object);
}
else if (obj.flags & ASN1_BODY)
{
@@ -478,15 +461,14 @@ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const c
/* an ASN.1 object must possess at least a tag and length field */
if (object->len < 2)
{
logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN.1 object smaller than 2 octets",
level, name);
DBG2("L%d - %s: ASN.1 object smaller than 2 octets", level, name);
return FALSE;
}
if (*object->ptr != type)
{
logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
level, name, type, *object->ptr);
DBG2("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
level, name, type, *object->ptr);
return FALSE;
}
@@ -494,12 +476,12 @@ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const c
if (len == ASN1_INVALID_LENGTH || object->len < len)
{
logger->log(logger, ERROR|LEVEL1, "L%d - %s: length of ASN.1 object invalid or too large",
level, name);
DBG2("L%d - %s: length of ASN.1 object invalid or too large",
level, name);
return FALSE;
}
logger->log(logger, CONTROL|LEVEL2, "L%d - %s:", level, name);
DBG2("L%d - %s:", level, name);
debug_asn1_simple_object(*object, type);
return TRUE;
}
@@ -546,18 +528,16 @@ bool is_asn1(chunk_t blob)
{
u_int len;
u_char tag = *blob.ptr;
asn1_init_logger();
if (tag != ASN1_SEQUENCE && tag != ASN1_SET)
{
logger->log(logger, ERROR|LEVEL2, " file content is not binary ASN.1");
DBG2(" file content is not binary ASN.1");
return FALSE;
}
len = asn1_length(&blob);
if (len != blob.len)
{
logger->log(logger, ERROR|LEVEL2, " file size does not match ASN.1 coded length");
DBG2(" file size does not match ASN.1 coded length");
return FALSE;
}
return TRUE;
@@ -708,7 +688,7 @@ chunk_t timetoasn1(const time_t *time, asn1_t type)
{
int offset;
const char *format;
char buf[TIMETOA_BUF];
char buf[32];
chunk_t formatted_time;
struct tm *t = gmtime(time);
@@ -722,8 +702,8 @@ chunk_t timetoasn1(const time_t *time, asn1_t type)
format = "%02d%02d%02d%02d%02d%02dZ";
offset = (t->tm_year < 100)? 0 : -100;
}
sprintf(buf, format, t->tm_year + offset, t->tm_mon + 1, t->tm_mday
, t->tm_hour, t->tm_min, t->tm_sec);
snprintf(buf, sizeof(buf), format, t->tm_year + offset,
t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
formatted_time.ptr = buf;
formatted_time.len = strlen(buf);
return asn1_simple_object(type, formatted_time);
+14 -30
View File
@@ -20,28 +20,18 @@
#include <stddef.h>
#include <sys/types.h>
#include "asn1.h"
#include "pem.h"
#include "ttodata.h"
#include <library.h>
#include <asn1/asn1.h>
#include <asn1/ttodata.h>
#include <utils/lexparser.h>
#include <utils/logger_manager.h>
#include <crypto/hashers/hasher.h>
#include <crypto/crypters/crypter.h>
#define PKCS5_SALT_LEN 8 /* bytes */
static logger_t *logger = NULL;
/**
* initializes the PEM logger
*/
static void pem_init_logger(void)
{
if (logger == NULL)
logger = logger_manager->get_logger(logger_manager, ASN1);
}
/**
* check the presence of a pattern in a character string
*/
@@ -79,8 +69,7 @@ static bool find_boundary(const char* tag, chunk_t *line)
{
if (present("-----", line))
{
logger->log(logger, CONTROL|LEVEL2,
" -----%s %.*s-----", tag, (int)name.len, name.ptr);
DBG2(" -----%s %.*s-----", tag, (int)name.len, name.ptr);
return TRUE;
}
line->ptr++; line->len--; name.len++;
@@ -185,8 +174,6 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
iv.ptr = iv_buf;
iv.len = 0;
pem_init_logger();
while (fetchline(&src, &line))
{
if (state == PEM_PRE)
@@ -222,7 +209,7 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
}
/* we are looking for a parameter: value pair */
logger->log(logger, CONTROL|LEVEL2, " %.*s", (int)line.len, line.ptr);
DBG2(" %.*s", (int)line.len, line.ptr);
ugh = extract_parameter_value(&name, &value, &line);
if (ugh != NULL)
continue;
@@ -289,8 +276,7 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
*pgp = TRUE;
data.ptr++;
data.len--;
logger->log(logger, CONTROL|LEVEL2, " Armor checksum: %.*s",
(int)data.len, data.ptr);
DBG2(" Armor checksum: %.*s", (int)data.len, data.ptr);
continue;
}
@@ -327,8 +313,6 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
FILE *fd = fopen(filename, "r");
pem_init_logger();
if (fd)
{
int bytes;
@@ -338,19 +322,19 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
blob->ptr = malloc(blob->len);
bytes = fread(blob->ptr, 1, blob->len, fd);
fclose(fd);
logger->log(logger, CONTROL, " loading %s file '%s' (%d bytes)", type, filename, bytes);
DBG1(" loading %s file '%s' (%d bytes)", type, filename, bytes);
*pgp = FALSE;
/* try DER format */
if (is_asn1(*blob))
{
logger->log(logger, CONTROL|LEVEL1, " file coded in DER format");
DBG2(" file coded in DER format");
return TRUE;
}
if (passphrase != NULL)
logger->log_bytes(logger, PRIVATE, " passphrase:", passphrase->ptr, passphrase->len);
DBG4(" passphrase:", passphrase->ptr, passphrase->len);
/* try PEM format */
ugh = pem_to_bin(blob, passphrase, pgp);
@@ -359,24 +343,24 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
{
if (*pgp)
{
logger->log(logger, CONTROL|LEVEL1, " file coded in armored PGP format");
DBG2(" file coded in armored PGP format");
return TRUE;
}
if (is_asn1(*blob))
{
logger->log(logger, CONTROL|LEVEL1, " file coded in PEM format");
DBG2(" file coded in PEM format");
return TRUE;
}
ugh = "file coded in unknown format, discarded";
}
/* a conversion error has occured */
logger->log(logger, ERROR, " %s", ugh);
DBG1(" %s", ugh);
chunk_free(blob);
}
else
{
logger->log(logger, ERROR, " could not open %s file '%s'", type, filename);
DBG1(" could not open %s file '%s'", type, filename);
}
return FALSE;
}
+9 -21
View File
@@ -69,24 +69,15 @@ struct private_certinfo_t {
crl_reason_t revocationReason;
};
/**
* RFC 2560 OCSP - certificate status
*/
static const char *const cert_status_name[] = {
ENUM(cert_status_names, CERT_GOOD, CERT_UNTRUSTED,
"good",
"revoked",
"unknown",
"unknown",
"untrusted"
};
"untrusted",
);
enum_names cert_status_names =
{ CERT_GOOD, CERT_UNTRUSTED, cert_status_name, NULL};
/**
* RFC 2459 CRL reason codes
*/
static const char *const crl_reason_name[] = {
ENUM(crl_reason_names, REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL,
"unspecified",
"key compromise",
"ca compromise",
@@ -95,11 +86,8 @@ static const char *const crl_reason_name[] = {
"cessation of operation",
"certificate hold",
"reason #7",
"remove from crl"
};
enum_names crl_reason_names =
{ REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL, crl_reason_name, NULL};
"remove from crl",
);
/**
* Implements certinfo_t.get_serialNumber
@@ -168,9 +156,9 @@ static void set_revocationReason(private_certinfo_t *this, crl_reason_t reason)
/**
* Implements certinfo_t.get_revocationReason
*/
static const char *get_revocationReason(const private_certinfo_t *this)
static crl_reason_t get_revocationReason(const private_certinfo_t *this)
{
return enum_name(&crl_reason_names, this->revocationReason);
return this->revocationReason;
}
/**
@@ -205,7 +193,7 @@ certinfo_t *certinfo_create(chunk_t serial)
this->public.set_revocationTime = (void (*) (certinfo_t*,time_t))set_revocationTime;
this->public.get_revocationTime = (time_t (*) (const certinfo_t*))get_revocationTime;
this->public.set_revocationReason = (void (*) (certinfo_t*, crl_reason_t))set_revocationReason;
this->public.get_revocationReason = (const char *(*) (const certinfo_t*))get_revocationReason;
this->public.get_revocationReason = (crl_reason_t(*) (const certinfo_t*))get_revocationReason;
this->public.destroy = (void (*) (certinfo_t*))destroy;
return &this->public;
+23 -33
View File
@@ -29,8 +29,6 @@
/**
* RFC 2560 OCSP - certificate status
*/
extern enum_names cert_status_names;
typedef enum {
CERT_GOOD = 0,
CERT_REVOKED = 1,
@@ -39,12 +37,11 @@ typedef enum {
CERT_UNTRUSTED = 4 /* private use */
} cert_status_t;
extern enum_name_t *cert_status_names;
/**
* RFC 2459 CRL reason codes
*/
extern enum_names crl_reason_names;
typedef enum {
REASON_UNSPECIFIED = 0,
REASON_KEY_COMPROMISE = 1,
@@ -56,6 +53,8 @@ typedef enum {
REASON_REMOVE_FROM_CRL = 8
} crl_reason_t;
extern enum_name_t *crl_reason_names;
typedef struct certinfo_t certinfo_t;
/**
@@ -67,85 +66,76 @@ typedef struct certinfo_t certinfo_t;
struct certinfo_t {
/**
* @brief Get serial number
*
*
* @brief Get serial number.
*
* @param this calling object
* @return serialNumber
*/
chunk_t (*get_serialNumber) (const certinfo_t *this);
/**
* @brief Set certificate status
*
*
* @brief Set certificate status.
*
* @param this calling object
* @param status status
*/
void (*set_status) (certinfo_t *this, cert_status_t status);
/**
* @brief Get certificate status
*
*
* @brief Get certificate status.
*
* @param this calling object
* @return status
*/
cert_status_t (*get_status) (const certinfo_t *this);
/**
* @brief Set nextUpdate
*
*
* @brief Set nextUpdate.
*
* @param this calling object
* @return nextUpdate
*/
void (*set_nextUpdate) (certinfo_t *this, time_t nextUpdate);
/**
* @brief Get nextUpdate
*
*
* @brief Get nextUpdate.
*
* @param this calling object
* @return nextUpdate
*/
time_t (*get_nextUpdate) (const certinfo_t *this);
/**
* @brief Set revocationTime
*
*
* @brief Set revocationTime.
*
* @param this calling object
* @param revocationTime revocationTime
*/
void (*set_revocationTime) (certinfo_t *this, time_t revocationTime);
/**
* @brief Get revocationTime
*
*
* @brief Get revocationTime.
*
* @param this calling object
* @return revocationTime
*/
time_t (*get_revocationTime) (const certinfo_t *this);
/**
* @brief Set revocationReason
*
*
* @brief Set revocationReason.
*
* @param this calling object
* @param reason revocationReason
*/
void (*set_revocationReason) (certinfo_t *this, crl_reason_t reason);
/**
* @brief Get revocationReason
*
*
* @brief Get revocationReason.
*
* @param this calling object
* @return revocationReason
*/
const char *(*get_revocationReason) (const certinfo_t *this);
crl_reason_t (*get_revocationReason) (const certinfo_t *this);
/**
* @brief Destroys the certinfo_t object.
+89 -46
View File
@@ -23,13 +23,14 @@
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <printf.h>
#include <types.h>
#include <library.h>
#include <definitions.h>
#include <asn1/oid.h>
#include <asn1/asn1.h>
#include <asn1/pem.h>
#include <utils/logger_manager.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
@@ -39,7 +40,6 @@
#define CRL_WARNING_INTERVAL 7 /* days */
static logger_t *logger;
extern char* check_expiry(time_t expiration_date, int warning_interval, bool strict);
extern time_t parse_time(chunk_t blob, int level0);
extern void parse_authorityKeyIdentifier(chunk_t blob, int level0 , chunk_t *authKeyID, chunk_t *authKeySerialNumber);
@@ -206,9 +206,9 @@ static crl_reason_t parse_crl_reasonCode(chunk_t object)
{
reason = *object.ptr;
}
logger->log(logger, CONTROL|LEVEL2, " '%s'", enum_name(&crl_reason_names, reason));
DBG2(" '%N'", crl_reason_names, reason);
return reason;
return reason;
}
/**
@@ -219,7 +219,7 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
asn1_ctx_t ctx;
bool critical;
chunk_t extnID;
chunk_t userCertificate;
chunk_t userCertificate = CHUNK_INITIALIZER;
revokedCert_t *revokedCert = NULL;
chunk_t object;
u_int level;
@@ -245,14 +245,14 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
break;
case CRL_OBJ_VERSION:
crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
logger->log(logger, CONTROL|LEVEL2, " v%d", crl->version);
DBG2(" v%d", crl->version);
break;
case CRL_OBJ_SIG_ALG:
crl->sigAlg = parse_algorithmIdentifier(object, level, NULL);
break;
case CRL_OBJ_ISSUER:
crl->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
logger->log(logger, CONTROL|LEVEL1, " '%D'", crl->issuer);
DBG2(" '%D'", crl->issuer);
break;
case CRL_OBJ_THIS_UPDATE:
crl->thisUpdate = parse_time(object, level);
@@ -277,7 +277,7 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
case CRL_OBJ_CRL_ENTRY_CRITICAL:
case CRL_OBJ_CRITICAL:
critical = object.len && *object.ptr;
logger->log(logger, CONTROL|LEVEL2, " %s",(critical)?"TRUE":"FALSE");
DBG2(" %s",(critical)?"TRUE":"FALSE");
break;
case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
case CRL_OBJ_EXTN_VALUE:
@@ -314,25 +314,22 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
*/
static err_t is_valid(const private_crl_t *this, time_t *until, bool strict)
{
char buf[TIMETOA_BUF];
time_t current_time = time(NULL);
timetoa(buf, BUF_LEN, &this->thisUpdate, TRUE);
logger->log(logger, CONTROL|LEVEL1, " this update : %s", buf);
timetoa(buf, BUF_LEN, &current_time, TRUE);
logger->log(logger, CONTROL|LEVEL1, " current time: %s", buf);
timetoa(buf, BUF_LEN, &this->nextUpdate, TRUE);
logger->log(logger, CONTROL|LEVEL1, " next update: %s", buf);
DBG2(" this update : %T", this->thisUpdate);
DBG2(" current time: %T", current_time);
DBG2(" next update: %T", this->nextUpdate);
if (strict && until != NULL
&& (*until == UNDEFINED_TIME || this->nextUpdate < *until))
if (strict && until != NULL &&
(*until == UNDEFINED_TIME || this->nextUpdate < *until))
{
*until = this->nextUpdate;
}
if (current_time > this->nextUpdate)
{
return "has expired";
logger->log(logger, CONTROL|LEVEL1, " crl is valid", buf);
}
DBG2(" crl is valid");
return NULL;
}
@@ -437,38 +434,88 @@ static void destroy(private_crl_t *this)
}
/**
* log crl
* output handler in printf()
*/
static void log_crl(const private_crl_t *this, logger_t *logger, bool utc, bool strict)
static int print(FILE *stream, const struct printf_info *info,
const void *const *args)
{
identification_t *issuer = this->issuer;
linked_list_t *revokedCertificates = this->revokedCertificates;
char buf[BUF_LEN];
timetoa(buf, BUF_LEN, &this->installed, utc);
logger->log(logger, CONTROL, "%s, revoked certs: %d",
buf, revokedCertificates->get_count(revokedCertificates));
logger->log(logger, CONTROL, " issuer: '%D'", issuer);
private_crl_t *this = *((private_crl_t**)(args[0]));
bool utc = TRUE;
int written = 0;
time_t now;
timetoa(buf, BUF_LEN, &this->thisUpdate, utc);
logger->log(logger, CONTROL, " updates: this %s", buf);
if (info->alt)
{
utc = *((bool*)(args[1]));
}
timetoa(buf, BUF_LEN, &this->nextUpdate, utc);
logger->log(logger, CONTROL, " next %s %s", buf,
check_expiry(this->nextUpdate, CRL_WARNING_INTERVAL, strict));
if (this == NULL)
{
return fprintf(stream, "(null)");
}
now = time(NULL);
written += fprintf(stream, " issuer: %D\n", this->issuer);
written += fprintf(stream, " installed: %#T, revoked certs: %d\n", this->installed, utc,
this->revokedCertificates->get_count(this->revokedCertificates));
written += fprintf(stream, " updates: this %#T\n", this->thisUpdate, utc);
written += fprintf(stream, " next %#T ");
if (this->nextUpdate == UNDEFINED_TIME)
{
written += fprintf(stream, "ok (expires never)");
}
else if (now > this->nextUpdate)
{
written += fprintf(stream, "expired (since %V)", now, this->nextUpdate);
}
else if (now > this->nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
{
written += fprintf(stream, "ok (expires in %V)", now, this->nextUpdate);
}
else
{
written += fprintf(stream, "ok");
}
if (this->authKeyID.ptr)
{
written += fprintf(stream, "\n authkey: %#B", &this->authKeyID);
}
if (this->authKeySerialNumber.ptr)
{
written += fprintf(stream, "\n aserial: %#B", &this->authKeySerialNumber);
}
return written;
}
if (this->authKeyID.ptr != NULL)
/**
* arginfo handler in printf()
*/
static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes)
{
if (info->alt)
{
chunk_to_hex(buf, BUF_LEN, this->authKeyID);
logger->log(logger, CONTROL, " authkey: %s", buf);
if (n > 1)
{
argtypes[0] = PA_INT;
argtypes[1] = PA_INT;
}
return 2;
}
if (this->authKeySerialNumber.ptr != NULL)
if (n > 0)
{
chunk_to_hex(buf, BUF_LEN, this->authKeySerialNumber);
logger->log(logger, CONTROL, " aserial: %s", buf);
argtypes[0] = PA_INT;
}
return 1;
}
/**
* register printf() handlers
*/
static void __attribute__ ((constructor))print_register()
{
register_printf_function(CRL_PRINTF_SPEC, print, print_arginfo);
}
/*
@@ -494,11 +541,7 @@ crl_t *crl_create_from_chunk(chunk_t chunk)
this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer;
this->public.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify;
this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status;
this->public.log_crl = (void (*) (const crl_t*,logger_t*,bool,bool))log_crl;
this->public.destroy = (void (*) (crl_t*))destroy;
/* we do not use a per-instance logger right now, since its not always accessible */
logger = logger_manager->get_logger(logger_manager, ASN1);
if (!parse_x509crl(chunk, 0, this))
{
+7 -11
View File
@@ -29,7 +29,13 @@
#include <crypto/certinfo.h>
#include <utils/identification.h>
#include <utils/iterator.h>
#include <utils/logger.h>
/**
* printf specifier for printing crls. When using the
* #-modifier, an additional bool argument defines if times
* are printed in UTC.
*/
#define CRL_PRINTF_SPEC 'U'
typedef struct crl_t crl_t;
@@ -115,16 +121,6 @@ struct crl_t {
* @param this crl to destroy
*/
void (*destroy) (crl_t *this);
/**
* @brief Log x509 crl info.
*
* @param this crl to log
* @param logger logger to be used
* @param utc log dates either in UTC or local time
* @param strict expiry of nextUpdate is fatal with strict == TRUE
*/
void (*log_crl) (const crl_t *this, logger_t *logger, bool utc, bool strict);
};
/**
+18 -20
View File
@@ -28,27 +28,25 @@
#include <crypto/crypters/des_crypter.h>
/**
* String mappings for encryption_algorithm_t.
*/
mapping_t encryption_algorithm_m[] = {
{ENCR_UNDEFINED, "UNDEFINED"},
{ENCR_DES_IV64, "DES_IV64"},
{ENCR_DES, "DES"},
{ENCR_3DES, "3DES"},
{ENCR_RC5, "RC5"},
{ENCR_IDEA, "IDEA"},
{ENCR_CAST, "CAST"},
{ENCR_BLOWFISH, "BLOWFISH"},
{ENCR_3IDEA, "3IDEA"},
{ENCR_DES_IV32, "DES_IV32"},
{ENCR_NULL, "NULL"},
{ENCR_AES_CBC, "AES_CBC"},
{ENCR_AES_CTR, "AES_CTR"},
{MAPPING_END, NULL}
};
ENUM_BEGIN(encryption_algorithm_names, ENCR_UNDEFINED, ENCR_UNDEFINED,
"UNDEFINED");
ENUM_NEXT(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32, ENCR_UNDEFINED,
"DES_IV64",
"DES",
"3DES",
"RC5",
"IDEA",
"CAST",
"BLOWFISH",
"3IDEA",
"DES_IV32");
ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CTR, ENCR_DES_IV32,
"NULL",
"AES_CBC",
"AES_CTR");
ENUM_END(encryption_algorithm_names, ENCR_AES_CTR);
/*
/*
* Described in header.
*/
crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size)

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