Alphabetise radsec.sym.
[libradsec.git] / lib / examples / server.c
1 /* RADIUS/RadSec server using libradsec. */
2
3 /* Copyright 2013 NORDUnet A/S. All rights reserved.
4    See LICENSE for licensing information. */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <assert.h>
9 #include <string.h>
10 #include <radsec/radsec.h>
11 #include <event2/event.h>
12 #include "debug.h"              /* For rs_dump_message(). */
13
14 #define CONFIG_FILE "examples/server.conf"
15 #define CONFIG "tls"
16
17 #define SECRET "sikrit"
18 #define USER_NAME "molgan@PROJECT-MOONSHOT.ORG"
19 #define USER_PW "password"
20
21 static struct rs_peer *
22 client_filter_cb (const struct rs_listener *listener,
23                   void *user_data)
24 {
25   printf ("DEBUG: listener %p (user_data=%p) asking for a client filter list\n",
26           listener, user_data);
27   return NULL;
28 }
29
30 static void
31 disco_cb (void *user_data)
32 {
33   struct rs_connection *conn = user_data;
34   assert (conn);
35   printf ("DEBUG: conn %p disconnected\n", conn);
36 }
37
38 static void
39 read_cb (struct rs_message *message, void *user_data)
40 {
41   struct rs_connection *conn = user_data;
42   assert (conn);
43   printf ("DEBUG: msg received on connection %p\n", conn);
44   rs_dump_message (message);
45   //if (message_verify_response (conn, fixme)) error;
46 }
47
48 static void
49 new_conn_cb (struct rs_connection *conn, void *user_data)
50 {
51   const struct rs_listener *l = user_data;
52   struct rs_conn_callbacks cb = {NULL, /* connected */
53                                  disco_cb,
54                                  read_cb,
55                                  NULL}; /* msg sent */
56
57   printf ("DEBUG: new connection on listener %p: %p, fd=%d\n",
58           l, conn, rs_conn_get_fd (conn));
59   rs_conn_set_callbacks (conn, &cb, conn);
60 }
61
62 void
63 err_cb (struct rs_connection *conn, void *user_data)
64 {
65   struct rs_listener *listener = user_data;
66   struct rs_error *err = NULL;
67   assert (conn);
68   err = rs_err_conn_pop (conn);
69
70   printf ("DEBUG: error on conn %p, listener %p: %d (%s)\n", conn, listener,
71           rs_err_code (err, 0), rs_err_msg (err));
72 }
73
74 #if 0
75 void
76 stdin_cb (evutil_socket_t s, short flags, void *user_data)
77 {
78   struct rs_listener *l = user_data;
79
80   printf ("DEBUG: got data on stdin, quitting\n");
81   assert (event_base_loopbreak (rs_listener_get_eventbase (l)) == 0);
82 }
83 #endif
84
85 struct rs_error *
86 server (struct rs_context *ctx)
87 {
88   int r = 0;
89   struct rs_error *err = NULL;
90   struct rs_listener *listener = NULL;
91   const struct rs_listener_callbacks cbs =
92     {client_filter_cb, new_conn_cb, err_cb};
93   struct event *read_event = NULL;
94
95   if (rs_listener_create (ctx, &listener, CONFIG))
96     goto out;
97   rs_listener_set_callbacks (listener, &cbs, listener);
98   if (rs_listener_listen (listener))
99     goto out;
100
101 #if 0
102   /* Listen on stdin too, for quitting the server nicely without
103      having to trap SIGKILL. */
104   read_event = event_new (rs_listener_get_eventbase (listener),
105                           fileno (stdin),
106                           EV_READ,
107                           stdin_cb,
108                           listener);
109   assert (read_event != NULL);
110   assert (event_add (read_event, NULL) == 0);
111 #endif
112
113   do
114     r = rs_listener_dispatch (listener);
115   while (r == 0);
116
117   printf ("DEBUG: rs_listener_dispatch done (r=%d)\n", r);
118   if (r < 0)
119     printf ("DEBUG: libevent signals error: %s\n", evutil_gai_strerror (r));
120   if (r == 1)
121     printf ("DEBUG: no events registered, exiting\n");
122
123  out:
124   err = rs_err_ctx_pop (ctx);
125   if (err == NULL)
126     err = rs_err_listener_pop (listener);
127
128   if (read_event)
129     event_free (read_event);
130   read_event = NULL;
131   if (listener)
132     {
133       assert (rs_listener_close (listener) == RSE_OK);
134       //rs_listener_destroy (listener);
135     }
136   listener = NULL;
137
138   return err;
139 }
140
141 int
142 main (int argc, char *argv[])
143 {
144   struct rs_error *err = NULL;
145   struct rs_context *ctx = NULL;
146
147   if (rs_context_create (&ctx))
148     goto out;
149   if (rs_context_read_config (ctx, CONFIG_FILE))
150     goto out;
151
152   {                             /* DEBUG printouts */
153     char *buf = NULL;
154     int err = rs_context_print_config (ctx, &buf);
155     assert (err == RSE_OK);
156     fputs (buf, stdout);
157     free (buf);
158   }
159
160   err = server (ctx);
161
162  out:
163   if (err)
164     {
165       fprintf (stderr, "%s: error: %s: %d\n",
166                argv[0], rs_err_msg (err), rs_err_code (err, 0));
167       return rs_err_code (err, 1);
168     }
169
170   if (ctx)
171     rs_context_destroy (ctx);
172
173   return 0;
174 }