From 52acaa7cea2bb152c47208d93331fdc39f4a5566 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Thu, 24 Jan 2013 11:23:43 +0100 Subject: [PATCH] user dispatch WIP 0 --- lib/conn.c | 18 +++++- lib/examples/Makefile.am | 7 ++- lib/examples/client-dispatch.c | 134 +++++++++++++++++++++++++++++++++++++++++ lib/examples/client-oyo.c | 66 ++++++++++++++++++++ lib/examples/client.conf | 26 +++++--- lib/include/radsec/radsec.h | 19 +++++- lib/radsec.sym | 1 + 7 files changed, 259 insertions(+), 12 deletions(-) create mode 100644 lib/examples/client-dispatch.c create mode 100644 lib/examples/client-oyo.c diff --git a/lib/conn.c b/lib/conn.c index 09a1ac0..17f893d 100644 --- a/lib/conn.c +++ b/lib/conn.c @@ -193,7 +193,23 @@ rs_conn_get_current_peer (struct rs_connection *conn, return rs_err_conn_push_fl (conn, RSE_NOSYS, __FILE__, __LINE__, NULL); } -int rs_conn_fd (struct rs_connection *conn) +int +rs_conn_dispatch(struct rs_connection *conn) +{ + assert (conn); + return event_base_loop (conn->evb, EVLOOP_ONCE); +} + +#if 0 +struct event_base +*rs_conn_get_evb(const struct rs_connection *conn) +{ + assert (conn); + return conn->evb; +} +#endif + +int rs_conn_get_fd (struct rs_connection *conn) { assert (conn); assert (conn->active_peer); diff --git a/lib/examples/Makefile.am b/lib/examples/Makefile.am index bfd31e8..9a2cd55 100644 --- a/lib/examples/Makefile.am +++ b/lib/examples/Makefile.am @@ -2,7 +2,12 @@ AUTOMAKE_OPTIONS = foreign INCLUDES = -I$(top_srcdir)/include AM_CFLAGS = -Wall -Werror -g -noinst_PROGRAMS = client +noinst_PROGRAMS = client client2 + client_SOURCES = client-blocking.c client_LDADD = ../libradsec.la #-lefence client_CFLAGS = $(AM_CFLAGS) -DUSE_CONFIG_FILE + +client2_SOURCES = client-dispatch.c +client2_LDADD = ../libradsec.la #-lefence +client2_CFLAGS = $(AM_CFLAGS) -DUSE_CONFIG_FILE diff --git a/lib/examples/client-dispatch.c b/lib/examples/client-dispatch.c new file mode 100644 index 0000000..e007654 --- /dev/null +++ b/lib/examples/client-dispatch.c @@ -0,0 +1,134 @@ +/* RADIUS/RadSec client using libradsec in user dispatch mode. */ + +#include +#include +#include +#include +#include "debug.h" /* For rs_dump_packet(). */ + +#define CONFIG "dispatching-tls" +#define CONFIG_FILE "examples/client.conf" + +#define SECRET "sikrit" +#define USER_NAME "molgan@PROJECT-MOONSHOT.ORG" +#define USER_PW "password" + +struct state { + struct rs_packet *msg; + unsigned packet_sent_flag : 1; + unsigned packet_received_flag : 1; +}; + +static void +connected_cb (void *user_data) +{ + printf ("%s\n", __FUNCTION__); +} + +static void +disconnected_cb (void *user_data) +{ + printf ("%s\n", __FUNCTION__); +} + +static void +msg_received_cb (struct rs_packet *packet, void *user_data) +{ + struct state *state = (struct state *) user_data; + + printf ("%s\n", __FUNCTION__); + + state->msg = packet; + state->packet_received_flag = 1; +} + +static void +msg_sent_cb (void *user_data) +{ + struct state *state = (struct state *) user_data; + + printf ("%s\n", __FUNCTION__); + + rs_packet_destroy (state->msg); + state->packet_sent_flag = 1; +} + +struct rs_error * +dispatching_client (struct rs_context *ctx) +{ + struct rs_connection *conn = NULL; + struct rs_conn_callbacks cb = { connected_cb, disconnected_cb, + msg_received_cb, msg_sent_cb }; + struct rs_packet *req_msg = NULL; + struct rs_error *err = NULL; + struct state state; + + memset (&state, 0, sizeof (state)); + + if (rs_conn_create(ctx, &conn, CONFIG)) + goto out; + rs_conn_set_callbacks (conn, &cb); + if (rs_packet_create_authn_request (conn, &req_msg, + USER_NAME, USER_PW, SECRET)) + goto out; + /* Doesn't really send the message but rather queues it for sending. + msg_received_cb() will be invoked with user_data = &state when + the message has been sent. */ + if (rs_packet_send (req_msg, &state)) + goto out; + + while (1) + { + if (rs_conn_dispatch (conn)) + goto out; + if (state.packet_received_flag) + { + rs_dump_packet (state.msg); /* debug printout */ + if (rs_packet_code (state.msg) == PW_ACCESS_ACCEPT) + printf ("Good auth.\n"); + else + printf ("Bad auth: %d\n", rs_packet_code (state.msg)); + rs_packet_destroy (state.msg); + break; + } + } + + if (rs_conn_destroy(conn)) + goto out; + conn = NULL; + + out: + err = rs_err_ctx_pop (ctx); + if (err == RSE_OK) + err = rs_err_conn_pop (conn); + + if (conn) + rs_conn_destroy(conn); + + return err; +} + +int +main (int argc, char *argv[]) +{ + struct rs_error *err = NULL; + struct rs_context *ctx = NULL; + + if (rs_context_create(&ctx)) + goto out; + if (rs_context_read_config(ctx, CONFIG_FILE)) + goto out; + + err = dispatching_client (ctx); + + out: + if (ctx) + rs_context_destroy(ctx); + + if (err) + { + fprintf (stderr, "error: %s: %d\n", rs_err_msg (err), rs_err_code (err, 0)); + return rs_err_code (err, 1); + } + return 0; +} diff --git a/lib/examples/client-oyo.c b/lib/examples/client-oyo.c new file mode 100644 index 0000000..2cee605 --- /dev/null +++ b/lib/examples/client-oyo.c @@ -0,0 +1,66 @@ +/* RADIUS/RadSec client using libradsec in on-your-own mode. */ + +#include +#include +#include + +int +loop () +{ + int n; + fd_set rfds, wfds, xfds; + //struct timeval timeout = {1,0}; /* 1 second. */ + + fd = FIXME; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + FD_ZERO(&wfds); + FD_SET(fd, &wfds); + FD_ZERO(&xfds); + FD_SET(fd, &xfds); + + while (1) + { + n = select (fd + 1, &rfds, &wfds, &xfds, NULL); + if (n == 0) + { + /* Timeout. */ + fprintf (stderr, "timeout on fd %d after %d seconds\n", fd, + timeout.tv_sec); + return -1; + } + else if (n == -1) + { + /* Error. */ + perror ("select"); + return -errno; + } + else + { + /* Ready to read/write/. */ + if (FD_ISSET(fd, &rfds)) + { + printf ("reading msg\n"); + radsec_recv_blocking(fd, &msg_in); + if (!verify_packet(&msg_in)) + } + if (FD_ISSET(fd, &wfds)) + { + radsec_send(fd, &msg_out); + printf ("msg sent\n"); + } + if (FD_ISSET(fd, &xfds)) + { + fprintf (stderr, "error on fd %d\n", fd); + return -1; + } + } + } +} + +int +main (int argc, char *argv[]) +{ + return loop (); +} diff --git a/lib/examples/client.conf b/lib/examples/client.conf index bf57434..32af3c0 100644 --- a/lib/examples/client.conf +++ b/lib/examples/client.conf @@ -13,15 +13,27 @@ realm blocking-tls { type = "TLS" timeout = 1 retries = 3 - cacertfile = "tests/demoCA/newcerts/01.pem" - certfile = "tests/demoCA/newcerts/02.pem" - certkeyfile = "tests/demoCA/private/c2key.pem" + cacertfile = "/home/linus/p/radsecproxy/demoCA/newcerts/01.pem" + certfile = "/home/linus/p/radsecproxy/demoCA/newcerts/03.pem" + certkeyfile = "/home/linus/p/radsecproxy/demoCA/private/cli1.key" #pskstr = "sikrit psk" - pskhexstr = "deadbeef4711" - pskid = "Client_identity" - pskex = "PSK" + #pskhexstr = "deadbeef4711" + #pskid = "Client_identity" + #pskex = "PSK" server { - hostname = "localhost" + hostname = "srv1" + service = "2083" + secret = "sikrit" + } +} + +realm dispatching-tls { + type = "TLS" + cacertfile = "/home/linus/p/radsecproxy/demoCA/newcerts/01.pem" + certfile = "/home/linus/p/radsecproxy/demoCA/newcerts/03.pem" + certkeyfile = "/home/linus/p/radsecproxy/demoCA/private/cli1.key" + server { + hostname = "srv1" service = "2083" secret = "sikrit" } diff --git a/lib/include/radsec/radsec.h b/lib/include/radsec/radsec.h index 7bd7f10..e54a8e3 100644 --- a/lib/include/radsec/radsec.h +++ b/lib/include/radsec/radsec.h @@ -203,8 +203,9 @@ int rs_context_read_config(struct rs_context *ctx, const char *config_file); packet is associated with a connection when it's created (\a rs_packet_create) or received (\a rs_conn_receive_packet). - If \a config is not NULL it should be the name of a configuration - found in the config file read in using \a rs_context_read_config. + If \a config is not NULL it should be the name of a realm found in + a config file that has already been read using \a rs_context_read_config. + \return On success, RSE_OK (0) is returned. On error, !0 is returned and a struct \a rs_error is pushed on the error stack for the context. The error can be accessed using \a @@ -271,9 +272,21 @@ int rs_conn_receive_packet(struct rs_connection *conn, struct rs_packet *request, struct rs_packet **pkt_out); +/** Run the dispatcher for the event base associated with \a conn. A + * wrapper around event_base_dispatch() for not having to hand out the + * event base. */ +int rs_conn_dispatch(struct rs_connection *conn); + +#if 0 +/** Get the event base associated with connection \a conn. + * \return struct event_base*. */ +struct event_base *rs_conn_get_evb(const struct rs_connection *conn); +#endif + +#define rs_conn_fd rs_conn_get_fd /* Old name. */ /** Get the file descriptor associated with connection \a conn. * \return File descriptor. */ -int rs_conn_fd(struct rs_connection *conn); +int rs_conn_get_fd(struct rs_connection *conn); /** Set the timeout value for connection \a conn. */ void rs_conn_set_timeout(struct rs_connection *conn, struct timeval *tv); diff --git a/lib/radsec.sym b/lib/radsec.sym index f234082..9158c20 100644 --- a/lib/radsec.sym +++ b/lib/radsec.sym @@ -41,6 +41,7 @@ rs_conn_create rs_conn_del_callbacks rs_conn_destroy rs_conn_disconnect +rs_conn_dispatch rs_conn_fd rs_conn_get_callbacks rs_conn_get_current_peer -- 2.1.4