diff options
Diffstat (limited to 'lib/examples')
-rw-r--r-- | lib/examples/Makefile.am | 10 | ||||
-rw-r--r-- | lib/examples/client-blocking.c | 58 | ||||
-rw-r--r-- | lib/examples/client-dispatch.c | 133 | ||||
-rw-r--r-- | lib/examples/client-oyo.c | 66 | ||||
-rw-r--r-- | lib/examples/client.conf | 49 | ||||
-rw-r--r-- | lib/examples/server.c | 174 |
6 files changed, 460 insertions, 30 deletions
diff --git a/lib/examples/Makefile.am b/lib/examples/Makefile.am index f300627..63b6abe 100644 --- a/lib/examples/Makefile.am +++ b/lib/examples/Makefile.am @@ -1,8 +1,10 @@ AUTOMAKE_OPTIONS = foreign INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir) -AM_CFLAGS = -Wall -Werror -g +AM_CFLAGS = -Wall -Werror -g #-DDEBUG -DDEBUG_LEVENT -noinst_PROGRAMS = client +LDADD = ../libradsec.la #-lefence +CFLAGS = $(AM_CFLAGS) -DUSE_CONFIG_FILE + +noinst_PROGRAMS = client client2 server client_SOURCES = client-blocking.c -client_LDADD = ../libradsec.la #-lefence -client_CFLAGS = $(AM_CFLAGS) -DUSE_CONFIG_FILE +client2_SOURCES = client-dispatch.c diff --git a/lib/examples/client-blocking.c b/lib/examples/client-blocking.c index cce00bf..bebde65 100644 --- a/lib/examples/client-blocking.c +++ b/lib/examples/client-blocking.c @@ -1,27 +1,40 @@ /* RADIUS/RadSec client using libradsec in blocking mode. */ +/* Copyright 2010,2011,2013 NORDUnet A/S. All rights reserved. + See LICENSE for licensing information. */ + #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <assert.h> #include <radsec/radsec.h> #include <radsec/request.h> #include "err.h" -#include "debug.h" /* For rs_dump_packet(). */ +#include "debug.h" /* For rs_dump_message(). */ #define SECRET "sikrit" #define USER_NAME "molgan@PROJECT-MOONSHOT.ORG" #define USER_PW "password" struct rs_error * -blocking_client (const char *config_fn, const char *configuration, +blocking_client (const char *av1, const char *av2, const char *av3, int use_request_object_flag) { struct rs_context *h = NULL; struct rs_connection *conn = NULL; struct rs_request *request = NULL; - struct rs_packet *req = NULL, *resp = NULL; + struct rs_message *req = NULL, *resp = NULL; struct rs_error *err = NULL; int r; +#if defined (USE_CONFIG_FILE) + const char *config_fn= av1; + const char *configuration = av2; +#else + const char *host = av1; + const char *service = av2; + const char *proto = av3; + struct rs_peer *server; +#endif r = rs_context_create (&h); if (r) @@ -31,15 +44,25 @@ blocking_client (const char *config_fn, const char *configuration, } #if !defined (USE_CONFIG_FILE) + /* Do it without a configuration file by setting all stuff "by + hand". Doesn't work for TLS at the moment because we don't have an + API for setting the X509 cert file names and such. */ { - struct rs_peer *server; + int conn_type = RS_CONN_TYPE_UDP; if (rs_conn_create (h, &conn, NULL)) goto cleanup; - rs_conn_set_type (conn, RS_CONN_TYPE_UDP); - if (rs_peer_create (conn, &server)) + if (proto) + { + if (!strncmp (proto, "udp", strlen ("udp"))) + conn_type = RS_CONN_TYPE_UDP; + else if (!strncmp (proto, "tls", strlen ("tls"))) + conn_type = RS_CONN_TYPE_TLS; + } + rs_conn_set_type (conn, conn_type); + if (rs_peer_create_for_conn (conn, &server)) goto cleanup; - if (rs_peer_set_address (server, av1, av2)) + if (rs_peer_set_address (server, host, service)) goto cleanup; rs_peer_set_timeout (server, 1); rs_peer_set_retries (server, 3); @@ -62,21 +85,21 @@ blocking_client (const char *config_fn, const char *configuration, } else { - if (rs_packet_create_authn_request (conn, &req, USER_NAME, USER_PW)) + if (rs_message_create_authn_request (conn, &req, USER_NAME, USER_PW)) goto cleanup; - if (rs_packet_send (req, NULL)) + if (rs_message_send (req)) goto cleanup; - if (rs_conn_receive_packet (conn, req, &resp)) + if (rs_conn_receive_message (conn, req, &resp)) goto cleanup; } if (resp) { - rs_dump_packet (resp); - if (rs_packet_code (resp) == PW_ACCESS_ACCEPT) + rs_dump_message (resp); + if (rs_message_code (resp) == PW_ACCESS_ACCEPT) printf ("Good auth.\n"); else - printf ("Bad auth: %d\n", rs_packet_code (resp)); + printf ("Bad auth: %d\n", rs_message_code (resp)); } else fprintf (stderr, "%s: no response\n", __func__); @@ -85,8 +108,12 @@ blocking_client (const char *config_fn, const char *configuration, err = rs_err_ctx_pop (h); if (err == RSE_OK) err = rs_err_conn_pop (conn); +#if !defined (USE_CONFIG_FILE) + rs_peer_free_address (server); + rs_peer_free_secret (server); +#endif if (resp) - rs_packet_destroy (resp); + rs_message_destroy (resp); if (request) rs_request_destroy (request); if (conn) @@ -118,7 +145,8 @@ main (int argc, char *argv[]) } if (argc < 3) usage (argc, argv); - err = blocking_client (argv[1], argv[2], use_request_object_flag); + err = blocking_client (argv[1], argv[2], argc >= 3 ? argv[3] : NULL, + use_request_object_flag); if (err) { fprintf (stderr, "error: %s: %d\n", rs_err_msg (err), rs_err_code (err, 0)); diff --git a/lib/examples/client-dispatch.c b/lib/examples/client-dispatch.c new file mode 100644 index 0000000..8a80ec6 --- /dev/null +++ b/lib/examples/client-dispatch.c @@ -0,0 +1,133 @@ +/* RADIUS/RadSec client using libradsec in user dispatch mode. */ + +#include <stdio.h> +#include <string.h> +#include <radsec/radsec.h> +#include <event2/event.h> +#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, &state); + if (rs_packet_create_authn_request (conn, &req_msg, USER_NAME, USER_PW)) + 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)) + 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 <sys/select.h> +#include <errno.h> +#include <stdio.h> + +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/<had error>. */ + 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 a19b699..288a084 100644 --- a/lib/examples/client.conf +++ b/lib/examples/client.conf @@ -9,31 +9,58 @@ realm blocking-udp { } } +realm testcli-udp { + type = "UDP" + timeout = 2 + retries = 2 + server { + hostname = "srv1" + service = "4711" + secret = "sikrit" + } +} + realm blocking-tls { type = "TLS" timeout = 1 retries = 3 - cacertfile = "tests/demoCA/newcerts/01.pem" - certfile = "tests/demoCA/newcerts/03.pem" - certkeyfile = "tests/demoCA/private/cli1.key" + 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" server { hostname = "srv1" + # test setup: radsecproxy fronting freeradius on 2083 service = "2083" + # test setup: examples/server on 4711 + #service = "4711" secret = "sikrit" } } -realm blocking-tls-psk { +realm testcli { type = "TLS" - timeout = 1 - retries = 3 - #pskstr = "sikrit psk" - pskhexstr = "deadbeef4711" - pskid = "Client_identity" - pskex = "PSK" + 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 = "4711" + 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 = "4433" + service = "2083" secret = "sikrit" } } diff --git a/lib/examples/server.c b/lib/examples/server.c new file mode 100644 index 0000000..fb51866 --- /dev/null +++ b/lib/examples/server.c @@ -0,0 +1,174 @@ +/* RADIUS/RadSec server using libradsec. */ + +/* Copyright 2013 NORDUnet A/S. All rights reserved. + See LICENSE for licensing information. */ + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <radsec/radsec.h> +#include <event2/event.h> +#include "debug.h" /* For rs_dump_message(). */ + +#define CONFIG_FILE "examples/server.conf" +#define CONFIG "tls" + +#define SECRET "sikrit" +#define USER_NAME "molgan@PROJECT-MOONSHOT.ORG" +#define USER_PW "password" + +static struct rs_peer * +client_filter_cb (const struct rs_listener *listener, + void *user_data) +{ + printf ("DEBUG: listener %p (user_data=%p) asking for a client filter list\n", + listener, user_data); + return NULL; +} + +static void +disco_cb (void *user_data) +{ + struct rs_connection *conn = user_data; + assert (conn); + printf ("DEBUG: conn %p disconnected\n", conn); +} + +static void +read_cb (struct rs_message *message, void *user_data) +{ + struct rs_connection *conn = user_data; + assert (conn); + printf ("DEBUG: msg received on connection %p\n", conn); + rs_dump_message (message); + //if (message_verify_response (conn, fixme)) error; +} + +static void +new_conn_cb (struct rs_connection *conn, void *user_data) +{ + const struct rs_listener *l = user_data; + struct rs_conn_callbacks cb = {NULL, /* connected */ + disco_cb, + read_cb, + NULL}; /* msg sent */ + + printf ("DEBUG: new connection on listener %p: %p, fd=%d\n", + l, conn, rs_conn_get_fd (conn)); + rs_conn_set_callbacks (conn, &cb, conn); +} + +void +err_cb (struct rs_connection *conn, void *user_data) +{ + struct rs_listener *listener = user_data; + struct rs_error *err = NULL; + assert (conn); + err = rs_err_conn_pop (conn); + + printf ("DEBUG: error on conn %p, listener %p: %d (%s)\n", conn, listener, + rs_err_code (err, 0), rs_err_msg (err)); +} + +#if 0 +void +stdin_cb (evutil_socket_t s, short flags, void *user_data) +{ + struct rs_listener *l = user_data; + + printf ("DEBUG: got data on stdin, quitting\n"); + assert (event_base_loopbreak (rs_listener_get_eventbase (l)) == 0); +} +#endif + +struct rs_error * +server (struct rs_context *ctx) +{ + int r = 0; + struct rs_error *err = NULL; + struct rs_listener *listener = NULL; + const struct rs_listener_callbacks cbs = + {client_filter_cb, new_conn_cb, err_cb}; + struct event *read_event = NULL; + + if (rs_listener_create (ctx, &listener, CONFIG)) + goto out; + rs_listener_set_callbacks (listener, &cbs, listener); + if (rs_listener_listen (listener)) + goto out; + +#if 0 + /* Listen on stdin too, for quitting the server nicely without + having to trap SIGKILL. */ + read_event = event_new (rs_listener_get_eventbase (listener), + fileno (stdin), + EV_READ, + stdin_cb, + listener); + assert (read_event != NULL); + assert (event_add (read_event, NULL) == 0); +#endif + + do + r = rs_listener_dispatch (listener); + while (r == 0); + + printf ("DEBUG: rs_listener_dispatch done (r=%d)\n", r); + if (r < 0) + printf ("DEBUG: libevent signals error: %s\n", evutil_gai_strerror (r)); + if (r == 1) + printf ("DEBUG: no events registered, exiting\n"); + + out: + err = rs_err_ctx_pop (ctx); + if (err == NULL) + err = rs_err_listener_pop (listener); + + if (read_event) + event_free (read_event); + read_event = NULL; + if (listener) + { + assert (rs_listener_close (listener) == RSE_OK); + //rs_listener_destroy (listener); + } + listener = NULL; + + 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; + + { /* DEBUG printouts */ + char *buf = NULL; + int err = rs_context_print_config (ctx, &buf); + assert (err == RSE_OK); + fputs (buf, stdout); + free (buf); + } + + err = server (ctx); + + out: + if (err) + { + fprintf (stderr, "%s: error: %s: %d\n", + argv[0], rs_err_msg (err), rs_err_code (err, 0)); + return rs_err_code (err, 1); + } + + if (ctx) + rs_context_destroy (ctx); + + return 0; +} |