diff options
Diffstat (limited to 'lib/include/radsec/radsec-impl.h')
-rw-r--r-- | lib/include/radsec/radsec-impl.h | 175 |
1 files changed, 124 insertions, 51 deletions
diff --git a/lib/include/radsec/radsec-impl.h b/lib/include/radsec/radsec-impl.h index e472703..7da00dd 100644 --- a/lib/include/radsec/radsec-impl.h +++ b/lib/include/radsec/radsec-impl.h @@ -1,5 +1,5 @@ /** @file libradsec-impl.h - @brief Libraray internal header file for libradsec. */ + @brief Libraray internal header file for libradsec. */ /* Copyright 2010-2013 NORDUnet A/S. All rights reserved. See LICENSE for licensing information. */ @@ -7,19 +7,26 @@ #ifndef _RADSEC_RADSEC_IMPL_H_ #define _RADSEC_RADSEC_IMPL_H_ 1 +#include <assert.h> #include <event2/util.h> #include <confuse.h> #if defined(RS_ENABLE_TLS) #include <openssl/ssl.h> #endif +#include "compat.h" -/* Constants. */ +/**************/ +/* Constants. */ #define RS_HEADER_LEN 4 +#define RS_CONN_MAGIC_BASE 0xAE004711u +#define RS_CONN_MAGIC_GENERIC 0x843AEF47u +#define RS_CONN_MAGIC_LISTENER 0xDCB04783u -/* Data types. */ +/***************/ +/* Data types. */ enum rs_cred_type { RS_CRED_NONE = 0, - /* TLS pre-shared keys, RFC 4279. */ + /* TLS pre-shared keys, RFC 4279. */ RS_CRED_TLS_PSK, /* RS_CRED_TLS_DH_PSK, */ /* RS_CRED_TLS_RSA_PSK, */ @@ -32,6 +39,17 @@ enum rs_key_encoding { }; typedef unsigned int rs_key_encoding_t; +enum rs_peer_type { + RS_PEER_TYPE_CLIENT = 1, + RS_PEER_TYPE_SERVER = 2 +}; + +enum rs_conn_subtype { + RS_CONN_OBJTYPE_BASE = 1, + RS_CONN_OBJTYPE_GENERIC, + RS_CONN_OBJTYPE_LISTENER, +}; + #if defined (__cplusplus) extern "C" { #endif @@ -41,7 +59,6 @@ struct rs_credentials { char *identity; char *secret; enum rs_key_encoding secret_encoding; - unsigned int secret_len; }; struct rs_error { @@ -49,105 +66,161 @@ struct rs_error { char buf[1024]; }; -/** Configuration object for a connection. */ +/** Configuration object for a connection. */ struct rs_peer { - struct rs_connection *conn; + enum rs_peer_type type; + struct rs_conn_base *connbase; /**< For error handling. */ struct rs_realm *realm; char *hostname; char *service; - char *secret; /* RADIUS secret. */ + char *secret; /* RADIUS secret. */ struct evutil_addrinfo *addr_cache; + char *cacertfile; + char *cacertpath; + char *certfile; + char *certkeyfile; + struct rs_credentials *transport_cred; struct rs_peer *next; }; -/** Configuration object for a RADIUS realm. */ +/** Configuration object for a RADIUS realm. */ struct rs_realm { char *name; enum rs_conn_type type; int timeout; int retries; - char *cacertfile; - char *cacertpath; - char *certfile; - char *certkeyfile; - struct rs_credentials *transport_cred; + struct rs_listener *listeners; + struct rs_peer *local_addr; struct rs_peer *peers; struct rs_realm *next; }; -/** Top configuration object. */ +/** Top configuration object. */ struct rs_config { struct rs_realm *realms; cfg_t *cfg; }; +/** Libradsec context. */ struct rs_context { struct rs_config *config; + struct rs_realm *realms; struct rs_alloc_scheme alloc_scheme; struct rs_error *err; + struct event_base *evb; }; -struct rs_connection { +/** Base class for a connection. */ +struct rs_conn_base { + uint32_t magic; /* Must be one of RS_CONN_MAGIC_*. */ struct rs_context *ctx; - struct rs_realm *realm; /* Owned by ctx. */ - struct event_base *evb; /* Event base. */ - struct event *tev; /* Timeout event. */ - struct rs_conn_callbacks callbacks; - void *user_data; + struct rs_realm *realm; /* Owned by ctx. */ + enum rs_conn_type transport; + /** For a listener, allowed client addr/port pairs. + For an outgoing connection, set of configured servers. + For an incoming connection, the peer (as the only entry). */ struct rs_peer *peers; - struct rs_peer *active_peer; - struct rs_error *err; struct timeval timeout; - char is_connecting; /* FIXME: replace with a single state member */ - char is_connected; /* FIXME: replace with a single state member */ - int fd; /* Socket. */ - int tryagain; /* For server failover. */ - int nextid; /* Next RADIUS packet identifier. */ - /* TCP transport specifics. */ - struct bufferevent *bev; /* Buffer event. */ - /* UDP transport specifics. */ - struct event *wev; /* Write event (for UDP). */ - struct event *rev; /* Read event (for UDP). */ - struct rs_packet *out_queue; /* Queue for outgoing UDP packets. */ + int tryagain; /* For server failover. */ + void *user_data; + struct rs_error *err; + int fd; /* Socket. */ + /* TCP transport specifics. */ + struct bufferevent *bev; /* Buffer event. */ + /* UDP transport specifics. */ + struct event *wev; /* Write event (for UDP). */ + struct event *rev; /* Read event (for UDP). */ +}; + +enum rs_conn_state { + RS_CONN_STATE_UNDEFINED = 0, + RS_CONN_STATE_CONNECTING, + RS_CONN_STATE_CONNECTED, +}; + +/** A generic connection. */ +struct rs_connection { + struct rs_conn_base base_; + struct event *tev; /* Timeout event. */ + struct rs_conn_callbacks callbacks; + enum rs_conn_state state; + struct rs_peer *active_peer; + struct rs_message *out_queue; /* Queue for outgoing UDP packets. */ #if defined(RS_ENABLE_TLS) - /* TLS specifics. */ + /* TLS specifics. */ SSL_CTX *tls_ctx; SSL *tls_ssl; #endif }; -enum rs_packet_flags { - RS_PACKET_HEADER_READ, - RS_PACKET_RECEIVED, - RS_PACKET_SENT, +/** A listening connection. Spawns generic connections when peers + connect to it. */ +struct rs_listener { + struct rs_conn_base base_; + struct evconnlistener *evlistener; + struct rs_listener_callbacks callbacks; + struct rs_listener *next; +}; + +enum rs_message_flags { + RS_MESSAGE_HEADER_READ, + RS_MESSAGE_RECEIVED, + RS_MESSAGE_SENT, }; struct radius_packet; -struct rs_packet { +struct rs_message { struct rs_connection *conn; unsigned int flags; uint8_t hdr[RS_HEADER_LEN]; - struct radius_packet *rpkt; /* FreeRADIUS object. */ - struct rs_packet *next; /* Used for UDP output queue. */ + struct radius_packet *rpkt; /* FreeRADIUS object. */ + struct rs_message *next; /* Used for UDP output queue. */ }; #if defined (__cplusplus) } #endif -/* Convenience macros. */ -#define rs_calloc(h, nmemb, size) \ - (h->alloc_scheme.calloc ? h->alloc_scheme.calloc : calloc)(nmemb, size) -#define rs_malloc(h, size) \ - (h->alloc_scheme.malloc ? h->alloc_scheme.malloc : malloc)(size) -#define rs_free(h, ptr) \ - (h->alloc_scheme.free ? h->alloc_scheme.free : free)(ptr) -#define rs_realloc(h, realloc, ptr, size) \ - (h->alloc_scheme.realloc ? h->alloc_scheme.realloc : realloc)(ptr, size) +/***********************/ +/* Convenience macros. */ + +/* Memory allocation. */ +#define rs_calloc(h, nmemb, size) ((h)->alloc_scheme.calloc != NULL \ + ? (h)->alloc_scheme.calloc : calloc)((nmemb), (size)) +#define rs_malloc(h, size) ((h)->alloc_scheme.malloc != NULL \ + ? (h)->alloc_scheme.malloc : malloc)((size)) +#define rs_free(h, ptr) ((h)->alloc_scheme.free != NULL \ + ? (h)->alloc_scheme.free : free)((ptr)) +#define rs_realloc(h, ptr, size) ((h)->alloc_scheme.realloc != NULL \ + ? (h)->alloc_scheme.realloc : realloc)((ptr), (size)) #define min(a, b) ((a) < (b) ? (a) : (b)) #define max(a, b) ((a) > (b) ? (a) : (b)) +/* Basic CPP-based classes, proudly borrowed from Tor. */ +#if defined(__GNUC__) && __GNUC__ > 3 + #define STRUCT_OFFSET(tp, member) __builtin_offsetof(tp, member) +#else + #define STRUCT_OFFSET(tp, member) \ + ((off_t) (((char*)&((tp*)0)->member)-(char*)0)) +#endif +#define SUBTYPE_P(p, subtype, basemember) \ + ((void*) (((char*)(p)) - STRUCT_OFFSET(subtype, basemember))) +#define DOWNCAST(to, ptr) ((to*)SUBTYPE_P(ptr, to, base_)) +#define TO_BASE_CONN(c) (&((c)->base_)) +static struct rs_connection *TO_GENERIC_CONN (struct rs_conn_base *); +static struct rs_listener *TO_LISTENER_CONN (struct rs_conn_base *); +static INLINE struct rs_connection *TO_GENERIC_CONN (struct rs_conn_base *b) +{ + assert (b->magic == RS_CONN_MAGIC_GENERIC); + return DOWNCAST (struct rs_connection, b); +} +static INLINE struct rs_listener *TO_LISTENER_CONN (struct rs_conn_base *b) +{ + assert (b->magic == RS_CONN_MAGIC_LISTENER); + return DOWNCAST (struct rs_listener, b); +} + #endif /* _RADSEC_RADSEC_IMPL_H_ */ /* Local Variables: */ |