summaryrefslogtreecommitdiff
path: root/lib/examples
diff options
context:
space:
mode:
Diffstat (limited to 'lib/examples')
-rw-r--r--lib/examples/Makefile.am10
-rw-r--r--lib/examples/client-blocking.c58
-rw-r--r--lib/examples/client-dispatch.c133
-rw-r--r--lib/examples/client-oyo.c66
-rw-r--r--lib/examples/client.conf49
-rw-r--r--lib/examples/server.c174
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;
+}