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:
@@ -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
@@ -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**)¤t))
|
||||
{
|
||||
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
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_ */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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**)¤t);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
@@ -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,¤t_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 **)¤t_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 **) ¤t_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 **)¤t_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, ¤t_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,¤t_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 **)¤t_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 **)¤t_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 **) ¤t_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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 **) ¤t_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 **) ¤t_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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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**)¤t_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**)¤t_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**)¤t_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**)¤t_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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 **) ¤t_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 **) ¤t_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,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 **) ¤t_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 **) ¤t_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 **) ¤t_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 **) ¤t_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));
|
||||
}
|
||||
|
||||
@@ -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 **) ¤t_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 **) ¤t_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
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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**)¤t))
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
@@ -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**)¤t))
|
||||
{
|
||||
ike_sa_entry_t *current;
|
||||
|
||||
iterator->current(iterator, (void**)¤t);
|
||||
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**)¤t);
|
||||
/* 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**)¤t);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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*)¬ify_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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,¤t_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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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, ¤t_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))
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user