From 94e3f46ef6c976f6bbd670555262ec6466314d8a Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Sun, 26 Sep 2010 00:37:40 +0200 Subject: [PATCH] Example client crafting simple packet using freeradius-libradius. --- lib/base.c | 2 + lib/debug.h | 73 ++++++++++++++++++++++++++++++++++ lib/examples/Makefile | 3 ++ lib/examples/client.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/libradsec-base.h | 2 +- lib/libradsec-impl.h | 97 +++++++++++++++++++++++++++++++++++++++++++++ lib/libradsec-levent.h | 20 +--------- lib/libradsec.h | 92 +++++++++++-------------------------------- lib/radsec.c | 71 +++++++++++++++++++++++++++++++++ 9 files changed, 377 insertions(+), 88 deletions(-) create mode 100644 lib/debug.h create mode 100644 lib/examples/client.c create mode 100644 lib/libradsec-impl.h create mode 100644 lib/radsec.c diff --git a/lib/base.c b/lib/base.c index 77de4e2..2081b1c 100644 --- a/lib/base.c +++ b/lib/base.c @@ -1,3 +1,5 @@ +/* See the file COPYING for licensing information. */ + #include #include #include diff --git a/lib/debug.h b/lib/debug.h new file mode 100644 index 0000000..83c3650 --- /dev/null +++ b/lib/debug.h @@ -0,0 +1,73 @@ +#define hd(p, l) { int i; \ + for (i = 1; i <= l; i++) { \ + printf ("%02x ", p[i-1]); \ + if (i % 8 == 0) printf (" "); \ + if (i % 16 == 0) printf ("\n"); } \ + printf ("\n"); } + +/* From freeradius-server/src/lib/radius.c */ +#include +static void print_hex(RADIUS_PACKET *packet) +{ + int i; + + if (!packet->data) return; + + printf(" Code:\t\t%u\n", packet->data[0]); + printf(" Id:\t\t%u\n", packet->data[1]); + printf(" Length:\t%u\n", ((packet->data[2] << 8) | + (packet->data[3]))); + printf(" Vector:\t"); + for (i = 4; i < 20; i++) { + printf("%02x", packet->data[i]); + } + printf("\n"); + + if (packet->data_len > 20) { + int total; + const uint8_t *ptr; + printf(" Data:"); + + total = packet->data_len - 20; + ptr = packet->data + 20; + + while (total > 0) { + int attrlen; + + printf("\t\t"); + if (total < 2) { /* too short */ + printf("%02x\n", *ptr); + break; + } + + if (ptr[1] > total) { /* too long */ + for (i = 0; i < total; i++) { + printf("%02x ", ptr[i]); + } + break; + } + + printf("%02x %02x ", ptr[0], ptr[1]); + attrlen = ptr[1] - 2; + ptr += 2; + total -= 2; + + for (i = 0; i < attrlen; i++) { + if ((i > 0) && ((i & 0x0f) == 0x00)) + printf("\t\t\t"); + printf("%02x ", ptr[i]); + if ((i & 0x0f) == 0x0f) printf("\n"); + } + + if ((attrlen & 0x0f) != 0x00) printf("\n"); + + ptr += attrlen; + total -= attrlen; + } + } + fflush(stdout); +} + +/* Local Variables: */ +/* c-file-style: "stroustrup" */ +/* End: */ diff --git a/lib/examples/Makefile b/lib/examples/Makefile index abced14..1817d90 100644 --- a/lib/examples/Makefile +++ b/lib/examples/Makefile @@ -5,5 +5,8 @@ all: blocking.o blocking.o: blocking.c blocking.h ../libradsec-base.h ../libradsec.h $(CC) $(CFLAGS) -c -I .. $^ +client: client.c ../radsec.o ../libradsec.h ../debug.h + $(CC) $(CFLAGS) -o $@ -L /usr/lib/freeradius -lfreeradius-radius $^ + clean: -rm *.o diff --git a/lib/examples/client.c b/lib/examples/client.c new file mode 100644 index 0000000..64a4436 --- /dev/null +++ b/lib/examples/client.c @@ -0,0 +1,105 @@ +/* RADIUS client doing blocking i/o. */ + +#include +#include +#include +#include +#include "../libradsec.h" +#include "../debug.h" + +#define SECRET "sikrit" +#define USER_NAME "bob" +#define USER_PW "hemligt" + +int +rsx_client () +{ + fr_randctx fr_ctx; + struct rs_handle *ctx; + struct rs_connection *conn; + RADIUS_PACKET *pkt; + VALUE_PAIR *vp; + char user_pw[MAX_STRING_LEN]; + uint8_t reqauth[AUTH_VECTOR_LEN]; + + fr_log_fp = stderr; + fr_debug_flag = 1; + fr_randinit (&fr_ctx, 0); + fr_rand_seed (NULL, 0); + + printf ("creating context\n"); + if (rs_context_create(&ctx)) + return -1; + +#if 0 + printf ("reading config\n"); + if (rs_context_config_read(ctx, "libradsec.conf")) + return -1; +#endif + + printf ("init dict"); + if (dict_init("/usr/share/freeradius", "dictionary")) + return -1; + +#if 0 + printf ("creating connection\n"); + if (rs_conn_create(ctx, &conn)) + return -1; +#endif + + printf ("creating a packet\n"); + pkt = rad_alloc (1); + if (!pkt) { + fr_perror ("pairmake"); + return -1; + } + + { + size_t pwlen = sizeof(USER_PW); + strncpy (user_pw, USER_PW, sizeof(user_pw)); + rad_pwencode(user_pw, &pwlen, SECRET, reqauth); + } + + printf ("creating value pairs\n"); + vp = pairmake ("User-Name", USER_NAME, 0); + if (!vp) { + fr_perror ("paircreate"); + return -1; + } + pairadd (&vp, pairmake ("User-Password", user_pw, 0)); + pkt->vps = vp; + + printf ("attributes:\n"); + vp_printlist (stdout, vp); + + printf ("encoding packet\n"); + rad_encode (pkt, NULL, SECRET); + print_hex (pkt); /* DEBUG */ + +#if 0 + rs_packet_create (&pkt, RS_ACCESS_REQUEST); + rs_attrib_create (&attr, RS_...); + rs_packet_add_attrib (pkt, attr); +#endif + + //rs_packet_send (conn, pkt, ...); + + rad_free(&pkt); + +#if 0 + printf ("destroying connection\n"); + if (rs_conn_destroy(conn)) + return -1; +#endif + + printf ("destroying context\n"); + rs_context_destroy(ctx); + + return 0; +} + +int +main (int argc, char *argv[]) +{ + exit (rsx_client ()); +} diff --git a/lib/libradsec-base.h b/lib/libradsec-base.h index d8c9a2b..5d8dd11 100644 --- a/lib/libradsec-base.h +++ b/lib/libradsec-base.h @@ -1,7 +1,7 @@ /** @file libradsec-base.h @brief Low level API for libradsec. */ -/* FIXME: License blurb goes here. */ +/* See the file COPYING for licensing information. */ #include #include diff --git a/lib/libradsec-impl.h b/lib/libradsec-impl.h new file mode 100644 index 0000000..913de4a --- /dev/null +++ b/lib/libradsec-impl.h @@ -0,0 +1,97 @@ +/** @file libradsec-impl.h + @brief Libraray internal header file for libradsec. */ + +/* See the file COPYING for licensing information. */ + +/* Constants. */ +#define RS_HEADER_LEN 4 + +/* Data types. */ +enum rs_conn_type { + RS_CONN_TYPE_NONE = 0, + RS_CONN_TYPE_UDP, + RS_CONN_TYPE_TCP, + RS_CONN_TYPE_TLS, + RS_CONN_TYPE_DTLS, +}; +typedef unsigned int rs_conn_type_t; + +enum rs_cred_type { + RS_CRED_NONE = 0, + RS_CRED_TLS_PSK_RSA, /* RFC 4279. */ +}; +typedef unsigned int rs_cred_type_t; + +struct rs_credentials { + enum rs_cred_type type; + char *identity; + char *secret; +}; + +typedef void * (*rs_calloc_fp)(size_t nmemb, size_t size); +typedef void * (*rs_malloc_fp)(size_t size); +typedef void (*rs_free_fp)(void *ptr); +typedef void * (*rs_realloc_fp)(void *ptr, size_t size); +struct rs_alloc_scheme { + rs_calloc_fp calloc; + rs_malloc_fp malloc; + rs_free_fp free; + rs_realloc_fp realloc; +}; + +typedef void (*rs_conn_connected_cb)(void *user_data /* FIXME: peer? */); +typedef void (*rs_conn_disconnected_cb)(void *user_data /* FIXME: reason? */); +typedef void (*rs_conn_packet_received_cb)(const struct rs_packet *packet, + void *user_data); +typedef void (*rs_conn_packet_sent_cb)(void *user_data); + +/** Connection callbacks. */ +struct rs_conn_callbacks { + /** Callback invoked when the connection has been established. */ + rs_conn_connected_cb connected_cb; + /** Callback invoked when the connection has been torn down. */ + rs_conn_disconnected_cb disconnected_cb; + /** Callback invoked when a packet was received. */ + rs_conn_packet_received_cb received_cb; + /** Callback invoked when a packet was successfully sent. */ + rs_conn_packet_sent_cb sent_cb; +}; + +struct rs_handle { + struct rs_alloc_scheme alloc_scheme; + /* TODO: dictionary? */ +}; + +struct rs_connection { + struct rs_handle *ctx; + enum rs_conn_type conn_type; + struct rs_credentials transport_credentials; + struct rs_conn_callbacks callbacks; +}; + +struct rs_attribute { + uint8_t type; + uint8_t length; + uint8_t *value; +}; + +struct rs_packet { + uint8_t code; + uint8_t id; + uint8_t auth[16]; + struct list *attrs; +}; + +/* Convenience macros. */ +#define rs_calloc(ctx, nmemb, size) \ + (ctx->alloc_scheme.calloc ? ctx->alloc_scheme.calloc : calloc)(nmemb, size) +#define rs_malloc(ctx, size) \ + (ctx->alloc_scheme.malloc ? ctx->alloc_scheme.malloc : malloc)(size) +#define rs_free(ctx, ptr) \ + (ctx->alloc_scheme.free ? ctx->alloc_scheme.free : free)(ptr) +#define rs_(ctx, realloc, ptr, size) \ + (ctx->alloc_scheme.realloc ? ctx->alloc_scheme.realloc : realloc)(ptr, size) + +/* Local Variables: */ +/* c-file-style: "stroustrup" */ +/* End: */ diff --git a/lib/libradsec-levent.h b/lib/libradsec-levent.h index 4189dfc..3caa4ad 100644 --- a/lib/libradsec-levent.h +++ b/lib/libradsec-levent.h @@ -1,7 +1,7 @@ /** @file libradsec-levent.h @brief API for libradsec-libevent. */ -/* FIXME: License blurb goes here. */ +/* See the file COPYING for licensing information. */ #include #include "libradsec.h" @@ -12,24 +12,6 @@ struct rs_connection { char open_flag; }; -typedef void (*rs_conn_connected_cb)(void *user_data /* FIXME: peer? */); -typedef void (*rs_conn_disconnected_cb)(void *user_data /* FIXME: reason? */); -typedef void (*rs_conn_packet_received_cb)(const struct rs_packet *packet, - void *user_data); -typedef void (*rs_conn_packet_sent_cb)(void *user_data); - -/** Connection callbacks. */ -struct rs_conn_callbacks { - /** Callback invoked when the connection has been established. */ - rs_conn_connected_cb connected_cb; - /** Callback invoked when the connection has been torn down. */ - rs_conn_disconnected_cb disconnected_cb; - /** Callback invoked when a packet was received. */ - rs_conn_packet_received_cb received_cb; - /** Callback invoked when a packet was successfully sent. */ - rs_conn_packet_sent_cb sent_cb; -}; - /* Function prototypes. */ diff --git a/lib/libradsec.h b/lib/libradsec.h index 61cb9e6..e371747 100644 --- a/lib/libradsec.h +++ b/lib/libradsec.h @@ -1,77 +1,33 @@ /** @file libradsec.h @brief Header file for libradsec. */ - -/* FIXME: License blurb goes here. */ +/* See the file COPYING for licensing information. */ #include -#include "../list.h" /* FIXME: ../ is not very nice */ - -#define RS_HEADER_LEN 4 - /* Data types. */ - -enum rs_conn_type { - RS_CONN_TYPE_NONE = 0, - RS_CONN_TYPE_UDP, - RS_CONN_TYPE_TCP, - RS_CONN_TYPE_TLS, - RS_CONN_TYPE_DTLS, -}; -typedef unsigned int rs_conn_type_t; - -enum rs_cred_type { - RS_CRED_NONE = 0, - RS_CRED_TLS_PSK_RSA, /* RFC 4279. */ -}; -typedef unsigned int rs_cred_type_t; - -struct rs_credentials { - enum rs_cred_type type; - char *identity; - char *secret; -}; - -typedef void * (*rs_calloc_fp)(size_t nmemb, size_t size); -typedef void * (*rs_malloc_fp)(size_t size); -typedef void (*rs_free_fp)(void *ptr); -typedef void * (*rs_realloc_fp)(void *ptr, size_t size); -struct rs_alloc_scheme { - rs_calloc_fp calloc; - rs_malloc_fp malloc; - rs_free_fp free; - rs_realloc_fp realloc; -}; - -struct rs_handle { - enum rs_conn_type conn_type; - struct rs_credentials transport_credentials; - struct rs_alloc_scheme alloc_scheme; -}; - -struct rs_attribute { - uint8_t type; - uint8_t length; - uint8_t *value; -}; - -struct rs_packet { - uint8_t code; - uint8_t id; - uint8_t auth[16]; - struct list *attrs; -}; - - -/* Convenience macros. */ -#define rs_calloc(ctx, nmemb, size) \ - (ctx->alloc_scheme.calloc ? ctx->alloc_scheme.calloc : calloc)(nmemb, size) -#define rs_malloc(ctx, size) \ - (ctx->alloc_scheme.malloc ? ctx->alloc_scheme.malloc : malloc)(size) -#define rs_free(ctx, ptr) \ - (ctx->alloc_scheme.free ? ctx->alloc_scheme.free : free)(ptr) -#define rs_(ctx, realloc, ptr, size) \ - (ctx->alloc_scheme.realloc ? ctx->alloc_scheme.realloc : realloc)(ptr, size) +struct rs_handle; /* radsec-impl.h */ +struct rs_alloc_scheme; /* radsec-impl.h */ +struct rs_connection; /* radsec-impl.h */ +struct rs_conn_callbacks; /* radsec-impl.h */ +struct rs_packet; /* radsec-impl.h */ +struct rs_conn; /* radsec-impl.h */ +struct event_base; /* */ + +/* Function prototypes. */ +int rs_context_create(struct rs_handle **ctx); +void rs_context_destroy(struct rs_handle *ctx); +int rs_context_set_alloc_scheme(struct rs_handle *ctx, struct rs_alloc_scheme *scheme); +int rs_context_config_read(struct rs_handle *ctx, const char *config_file); + +int rs_conn_create(const struct rs_handle *ctx, struct rs_connection **conn); +int rs_conn_destroy(struct rs_connection *conn); +int rs_conn_set_eventbase(struct rs_connection *conn, struct event_base *eb); +int rs_conn_set_callbacks(struct rs_connection *conn, struct rs_conn_callbacks *cb); +int rs_conn_set_server(struct rs_connection *conn, const char *name); +int rs_conn_get_server(const struct rs_connection *conn, const char *name, size_t buflen); /* NAME <-- most recent server we spoke to */ + +int rs_packet_send(const struct rs_conn *conn, const struct rs_packet *pkt, void *user_data); +int rs_packet_receive(const struct rs_conn *conn, struct rs_packet **pkt); /* Local Variables: */ /* c-file-style: "stroustrup" */ diff --git a/lib/radsec.c b/lib/radsec.c new file mode 100644 index 0000000..760da84 --- /dev/null +++ b/lib/radsec.c @@ -0,0 +1,71 @@ +#include +#include +#include "libradsec.h" +#include "libradsec-impl.h" + +#define ERR_OK 0 +#define ERR_NOMEM 1 +#define ERR_NOSYS 2 +#define ERR_SOME_ERROR 99 + +int rs_context_create(struct rs_handle **ctx) +{ + *ctx = (struct rs_handle *) malloc (sizeof (struct rs_handle)); + return (ctx ? ERR_OK : ERR_NOMEM); +} + +void rs_context_destroy(struct rs_handle *ctx) +{ + free (ctx); +} + +int rs_context_set_alloc_scheme(struct rs_handle *ctx, struct rs_alloc_scheme *scheme) +{ + return ERR_NOSYS; +} + +int rs_context_config_read(struct rs_handle *ctx, const char *config_file) +{ + return ERR_NOSYS; +} + +int rs_conn_create(const struct rs_handle *ctx, struct rs_connection **conn) +{ + return ERR_NOSYS; +} + +int rs_conn_destroy(struct rs_connection *conn) +{ + return ERR_NOSYS; +} + +int rs_conn_set_eventbase(struct rs_connection *conn, struct event_base *eb) +{ + return ERR_NOSYS; +} + +int rs_conn_set_callbacks(struct rs_connection *conn, struct rs_conn_callbacks *cb) +{ + return ERR_NOSYS; +} + +int rs_conn_set_server(struct rs_connection *conn, const char *name) +{ + return ERR_NOSYS; +} + +int rs_conn_get_server(const struct rs_connection *conn, const char *name, size_t buflen) +{ + return ERR_NOSYS; +} + +int rs_packet_send(const struct rs_conn *conn, const struct rs_packet *pkt, void *user_data) +{ + return ERR_NOSYS; +} + +int rs_packet_receive(const struct rs_conn *conn, struct rs_packet **pkt) +{ + return ERR_NOSYS; +} + -- 2.1.4