user dispatch WIP 0
[libradsec.git] / lib / examples / client-dispatch.c
diff --git a/lib/examples/client-dispatch.c b/lib/examples/client-dispatch.c
new file mode 100644 (file)
index 0000000..e007654
--- /dev/null
@@ -0,0 +1,134 @@
+/* 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);
+  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;
+}