Revamping for listeners.
[radsecproxy.git] / lib / examples / client-blocking.c
1 /* RADIUS/RadSec client using libradsec in blocking mode. */
2
3 /* Copyright 2010,2011,2013 NORDUnet A/S. All rights reserved.
4    See LICENSE for licensing information. */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <assert.h>
10 #include <radsec/radsec.h>
11 #include <radsec/request.h>
12 #include "err.h"
13 #include "debug.h"              /* For rs_dump_message().  */
14
15 #define SECRET "sikrit"
16 #define USER_NAME "molgan@PROJECT-MOONSHOT.ORG"
17 #define USER_PW "password"
18
19 struct rs_error *
20 blocking_client (const char *av1, const char *av2, const char *av3,
21                  int use_request_object_flag)
22 {
23   struct rs_context *h = NULL;
24   struct rs_connection *conn = NULL;
25   struct rs_request *request = NULL;
26   struct rs_message *req = NULL, *resp = NULL;
27   struct rs_error *err = NULL;
28   int r;
29 #if defined (USE_CONFIG_FILE)
30   const char *config_fn= av1;
31   const char *configuration = av2;
32 #else
33   const char *host = av1;
34   const char *service = av2;
35   const char *proto = av3;
36   struct rs_peer *server;
37 #endif
38
39   r = rs_context_create (&h);
40   if (r)
41     {
42       assert(r == RSE_NOMEM);
43       assert (!"out of RAM -- unable to create libradsec context");
44     }
45
46 #if !defined (USE_CONFIG_FILE)
47   /* Do it without a configuration file by setting all stuff "by
48    hand".  Doesn't work for TLS at the moment because we don't have an
49    API for setting the X509 cert file names and such. */
50   {
51     int conn_type = RS_CONN_TYPE_UDP;
52
53     if (rs_conn_create (h, &conn, NULL))
54       goto cleanup;
55     if (proto)
56       {
57         if (!strncmp (proto, "udp", strlen ("udp")))
58           conn_type = RS_CONN_TYPE_UDP;
59         else if (!strncmp (proto, "tls", strlen ("tls")))
60           conn_type = RS_CONN_TYPE_TLS;
61       }
62     rs_conn_set_type (conn, conn_type);
63     if (rs_peer_create_for_conn (conn, &server))
64       goto cleanup;
65     if (rs_peer_set_address (server, host, service))
66       goto cleanup;
67     rs_peer_set_timeout (server, 1);
68     rs_peer_set_retries (server, 3);
69     if (rs_peer_set_secret (server, SECRET))
70       goto cleanup;
71   }
72 #else  /* defined (USE_CONFIG_FILE) */
73   if (rs_context_read_config (h, config_fn))
74     goto cleanup;
75   if (rs_conn_create (h, &conn, configuration))
76     goto cleanup;
77 #endif  /* defined (USE_CONFIG_FILE) */
78
79   if (use_request_object_flag)
80     {
81       if (rs_request_create_authn (conn, &request, USER_NAME, USER_PW, SECRET))
82         goto cleanup;
83       if (rs_request_send (request, &resp))
84         goto cleanup;
85     }
86   else
87     {
88       if (rs_message_create_authn_request (conn, &req, USER_NAME, USER_PW, SECRET))
89         goto cleanup;
90       if (rs_message_send (req, NULL))
91         goto cleanup;
92       if (rs_conn_receive_message (conn, req, &resp))
93         goto cleanup;
94     }
95
96   if (resp)
97     {
98       rs_dump_message (resp);
99       if (rs_message_code (resp) == PW_ACCESS_ACCEPT)
100         printf ("Good auth.\n");
101       else
102         printf ("Bad auth: %d\n", rs_message_code (resp));
103     }
104   else
105     fprintf (stderr, "%s: no response\n", __func__);
106
107  cleanup:
108   err = rs_err_ctx_pop (h);
109   if (err == RSE_OK)
110     err = rs_err_conn_pop (conn);
111 #if !defined (USE_CONFIG_FILE)
112   rs_peer_free_address (server);
113   rs_peer_free_secret (server);
114 #endif
115   if (resp)
116     rs_message_destroy (resp);
117   if (request)
118     rs_request_destroy (request);
119   if (conn)
120     rs_conn_destroy (conn);
121   if (h)
122     rs_context_destroy (h);
123
124   return err;
125 }
126
127 void
128 usage (int argc, char *argv[])
129 {
130   fprintf (stderr, "usage: %s: [-r] config-file config-name\n", argv[0]);
131   exit (1);
132 }
133
134 int
135 main (int argc, char *argv[])
136 {
137   int use_request_object_flag = 0;
138   struct rs_error *err;
139
140   if (argc > 1 && argv[1] && argv[1][0] == '-' && argv[1][1] == 'r')
141     {
142       use_request_object_flag = 1;
143       argc--;
144       argv++;
145     }
146   if (argc < 3)
147     usage (argc, argv);
148   err = blocking_client (argv[1], argv[2], argc >= 3 ? argv[3] : NULL,
149                          use_request_object_flag);
150   if (err)
151     {
152       fprintf (stderr, "error: %s: %d\n", rs_err_msg (err), rs_err_code (err, 0));
153       return rs_err_code (err, 1);
154     }
155   return 0;
156 }