Radcli library 1.5.3
A simple radius library
Loading...
Searching...
No Matches
buildreq.c
1/*
2 * Copyright (C) 1995,1997 Lars Fenneberg
3 *
4 * See the file COPYRIGHT for the respective terms and conditions.
5 * If the file is missing contact me at lf@elemental.net
6 * and I'll send you a copy.
7 *
8 */
9#include <config.h>
10#include <includes.h>
11#include <radcli/radcli.h>
12#include "util.h"
13
20
21/* Generates a random ID
22 *
23 * @return the random ID.
24 */
26static unsigned char rc_get_id()
27{
28 return (unsigned char)(random() & UCHAR_MAX);
29}
31
47void rc_buildreq(rc_handle const *rh, SEND_DATA * data, int code, char *server,
48 unsigned short port, char *secret, int timeout, int retries)
49{
50 data->server = server;
51 data->secret = secret;
52 data->svc_port = port;
53 data->seq_nbr = rc_get_id();
54 data->timeout = timeout;
55 data->retries = retries;
56 data->code = code;
57}
58
69static int rc_select_aaa_server(rc_handle *rh, SERVER **aaaserver,
70 rc_type *type, rc_standard_codes request_type)
71{
72 if (rh->so_type == RC_SOCKET_TLS || rh->so_type == RC_SOCKET_DTLS ||
73 request_type != PW_ACCOUNTING_REQUEST) {
74 *aaaserver = rc_conf_srv(rh, "authserver");
75 *type = AUTH;
76 } else {
77 *aaaserver = rc_conf_srv(rh, "acctserver");
78 *type = ACCT;
79 }
80
81 if (*aaaserver == NULL)
82 return ERROR_RC;
83
84 return OK_RC;
85}
86
102static int rc_fill_acct_pairs(rc_handle const *rh, SEND_DATA *data,
103 uint32_t nas_port, int add_nas_port,
104 rc_standard_codes request_type,
105 VALUE_PAIR **adt_vp, double *start_time)
106{
107 time_t dtime;
108 double now;
109
110 if (add_nas_port != 0
111 && rc_avpair_get(data->send_pairs, PW_NAS_PORT, 0) == NULL) {
112 /*
113 * Fill in NAS-Port
114 */
115 if (rc_avpair_add(rh, &(data->send_pairs), PW_NAS_PORT,
116 &nas_port, 0, 0) == NULL)
117 return ERROR_RC;
118 }
119
120 if (request_type == PW_ACCOUNTING_REQUEST) {
121 /*
122 * Fill in Acct-Delay-Time
123 */
124 dtime = 0;
125 now = rc_getmtime();
126 *adt_vp = rc_avpair_get(data->send_pairs, PW_ACCT_DELAY_TIME, 0);
127 if (*adt_vp == NULL) {
128 *adt_vp = rc_avpair_add(rh, &(data->send_pairs),
129 PW_ACCT_DELAY_TIME, &dtime, 0,
130 0);
131 if (*adt_vp == NULL)
132 return ERROR_RC;
133 *start_time = now;
134 } else {
135 *start_time = now - (*adt_vp)->lvalue;
136 }
137 }
138
139 return OK_RC;
140}
141
166int rc_aaa_ctx(rc_handle * rh, RC_AAA_CTX ** ctx, uint32_t nas_port,
167 VALUE_PAIR * send, VALUE_PAIR ** received, char *msg,
168 int add_nas_port, rc_standard_codes request_type)
169{
170 SERVER *aaaserver;
171 rc_type type;
172
173 if (rc_select_aaa_server(rh, &aaaserver, &type, request_type) != OK_RC)
174 return ERROR_RC;
175
176 return rc_aaa_ctx_server(rh, ctx, aaaserver, type,
177 nas_port, send, received, msg,
178 add_nas_port, request_type);
179}
180
205int rc_aaa_ctx_server(rc_handle * rh, RC_AAA_CTX ** ctx, SERVER * aaaserver,
206 rc_type type,
207 uint32_t nas_port,
208 VALUE_PAIR * send, VALUE_PAIR ** received,
209 char *msg, int add_nas_port,
210 rc_standard_codes request_type)
211{
212 SEND_DATA data;
213 VALUE_PAIR *adt_vp = NULL;
214 int result;
215 int timeout = rc_conf_int(rh, "radius_timeout");
216 int retries = rc_conf_int(rh, "radius_retries");
217 double start_time = 0;
218 time_t dtime;
219 int servernum;
220
221 data.send_pairs = send;
222 data.receive_pairs = NULL;
223
224 if (rc_fill_acct_pairs(rh, &data, nas_port, add_nas_port, request_type,
225 &adt_vp, &start_time) != OK_RC)
226 return ERROR_RC;
227
228 if (data.receive_pairs != NULL) {
230 data.receive_pairs = NULL;
231 }
232
233 servernum = 0;
234 do {
235 rc_buildreq(rh, &data, request_type, aaaserver->name[servernum],
236 aaaserver->port[servernum],
237 aaaserver->secret[servernum], timeout, retries);
238
239 if (request_type == PW_ACCOUNTING_REQUEST) {
240 dtime = rc_getmtime() - start_time;
241 rc_avpair_assign(adt_vp, &dtime, 0);
242 }
243
244 result = rc_send_server_ctx(rh, ctx, &data, msg, type, 0);
245
246 if ((result == OK_RC) || (result == CHALLENGE_RC) || (result == REJECT_RC)) {
247 if (request_type != PW_ACCOUNTING_REQUEST) {
248 *received = data.receive_pairs;
249 } else {
251 }
252
253 DEBUG(LOG_INFO,
254 "rc_send_server_ctx returned success for server %u", servernum);
255 return result;
256 }
257
259 data.receive_pairs = NULL;
260
261 DEBUG(LOG_INFO, "rc_send_server_ctx returned error (%d) for server %u: (remaining: %d)",
262 result, servernum, aaaserver->max-servernum);
263 servernum++;
264 } while (servernum < aaaserver->max && ((result == TIMEOUT_RC) || (result == NETUNREACH_RC)));
265
266 return result;
267}
268
283int rc_aaa(rc_handle * rh, uint32_t nas_port, VALUE_PAIR * send,
284 VALUE_PAIR ** received, char *msg, int add_nas_port,
285 rc_standard_codes request_type)
286{
287 return rc_aaa_ctx(rh, NULL, nas_port, send, received, msg,
288 add_nas_port, request_type);
289}
290
303int rc_auth(rc_handle * rh, uint32_t nas_port, VALUE_PAIR * send,
304 VALUE_PAIR ** received, char *msg)
305{
306
307 return rc_aaa(rh, nas_port, send, received, msg, 1,
308 PW_ACCESS_REQUEST);
309}
310
325int rc_auth_proxy(rc_handle * rh, VALUE_PAIR * send, VALUE_PAIR ** received,
326 char *msg)
327{
328 return rc_aaa(rh, 0, send, received, msg, 0, PW_ACCESS_REQUEST);
329}
330
342int rc_acct(rc_handle * rh, uint32_t nas_port, VALUE_PAIR * send)
343{
344 return rc_aaa(rh, nas_port, send, NULL, NULL, 1,
345 PW_ACCOUNTING_REQUEST);
346}
347
355int rc_acct_proxy(rc_handle * rh, VALUE_PAIR * send)
356{
357
358 return rc_aaa(rh, 0, send, NULL, NULL, 0, PW_ACCOUNTING_REQUEST);
359}
360
373static int rc_aaa_ctx_server_async(rc_handle * rh, SERVER * aaaserver,
374 rc_type type, uint32_t nas_port,
375 VALUE_PAIR * send)
376{
377 SEND_DATA data;
378 VALUE_PAIR *adt_vp = NULL;
379 double start_time = 0;
380 time_t dtime;
381 int timeout = rc_conf_int(rh, "radius_timeout");
382 int retries = rc_conf_int(rh, "radius_retries");
383 int servernum;
384 int result;
385 int sent = 0;
386
387 data.send_pairs = send;
388 data.receive_pairs = NULL;
389
390 if (rc_fill_acct_pairs(rh, &data, nas_port, 1, PW_ACCOUNTING_REQUEST,
391 &adt_vp, &start_time) != OK_RC)
392 return ERROR_RC;
393
394 for (servernum = 0; servernum < aaaserver->max; servernum++) {
395 dtime = rc_getmtime() - start_time;
396 rc_avpair_assign(adt_vp, &dtime, 0);
397
398 /* timeout/retries are not consulted by rc_send_server_ctx()
399 * when no_wait is set below; passed through unchanged only
400 * so SEND_DATA/DEBUG output reflect the real configuration. */
401 rc_buildreq(rh, &data, PW_ACCOUNTING_REQUEST,
402 aaaserver->name[servernum],
403 aaaserver->port[servernum],
404 aaaserver->secret[servernum], timeout, retries);
405
406 result = rc_send_server_ctx(rh, NULL, &data, NULL, type, 1);
407
408 if (data.receive_pairs != NULL) {
410 data.receive_pairs = NULL;
411 }
412
413 if (result == OK_RC) {
414 sent++;
415 } else {
416 DEBUG(LOG_INFO,
417 "rc_send_server_ctx returned error (%d) for server %u",
418 result, servernum);
419 }
420 }
421
422 return sent > 0 ? OK_RC : ERROR_RC;
423}
424
443int rc_acct_async(rc_handle * rh, uint32_t nas_port, VALUE_PAIR * send)
444{
445 SERVER *aaaserver;
446 rc_type type;
447
448 if (rc_select_aaa_server(rh, &aaaserver, &type, PW_ACCOUNTING_REQUEST) != OK_RC)
449 return ERROR_RC;
450
451 return rc_aaa_ctx_server_async(rh, aaaserver, type, nas_port, send);
452}
453
464int rc_check(rc_handle * rh, char *host, char *secret, unsigned short port,
465 char *msg)
466{
467 SEND_DATA data;
468 int result;
469 uint32_t service_type;
470 int timeout = rc_conf_int(rh, "radius_timeout");
471 int retries = rc_conf_int(rh, "radius_retries");
472 rc_type type;
473
474 data.send_pairs = data.receive_pairs = NULL;
475
476 if (rh->so_type == RC_SOCKET_TLS || rh->so_type == RC_SOCKET_DTLS)
477 type = AUTH;
478 else
479 type = ACCT;
480
481 /*
482 * Fill in Service-Type
483 */
484
485 service_type = PW_ADMINISTRATIVE;
486 rc_avpair_add(rh, &(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0,
487 0);
488
489 rc_buildreq(rh, &data, PW_STATUS_SERVER, host, port, secret, timeout,
490 retries);
491 result = rc_send_server(rh, &data, msg, type);
492
494
495 return result;
496}
497
int rc_acct(rc_handle *rh, uint32_t nas_port, VALUE_PAIR *send)
Builds an accounting request for port id nas_port with the value_pairs at send.
Definition buildreq.c:342
rc_type
Definition radcli.h:74
int rc_auth_proxy(rc_handle *rh, VALUE_PAIR *send, VALUE_PAIR **received, char *msg)
Builds an authentication request for proxying.
Definition buildreq.c:325
int rc_auth(rc_handle *rh, uint32_t nas_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg)
Builds an authentication request for port id nas_port with the value_pairs send and submits it to a s...
Definition buildreq.c:303
struct rc_aaa_ctx_st RC_AAA_CTX
Definition radcli.h:537
void rc_buildreq(rc_handle const *rh, SEND_DATA *data, int code, char *server, unsigned short port, char *secret, int timeout, int retries)
Build a skeleton RADIUS request using information from the config file.
Definition buildreq.c:47
int rc_acct_proxy(rc_handle *rh, VALUE_PAIR *send)
Builds an accounting request with the value_pairs at send.
Definition buildreq.c:355
void rc_avpair_free(VALUE_PAIR *pair)
Frees all value_pairs in the list.
Definition avpair.c:584
int rc_aaa_ctx(rc_handle *rh, RC_AAA_CTX **ctx, uint32_t nas_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, int add_nas_port, rc_standard_codes request_type)
Builds an authentication/accounting request and submits it to a server, optionally returning context.
Definition buildreq.c:166
int rc_aaa(rc_handle *rh, uint32_t nas_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, int add_nas_port, rc_standard_codes request_type)
Builds an authentication/accounting request for port id nas_port with the value_pairs send and submit...
Definition buildreq.c:283
int rc_avpair_assign(VALUE_PAIR *vp, void const *pval, int len)
Assigns the given value to an attribute-value pair.
Definition avpair.c:135
int rc_send_server(rc_handle *rh, SEND_DATA *data, char *msg, rc_type type)
Sends a request to a RADIUS server and waits for the reply.
Definition sendserver.c:231
int rc_acct_async(rc_handle *rh, uint32_t nas_port, VALUE_PAIR *send)
Sends an accounting request to every configured accounting server without waiting for a reply.
Definition buildreq.c:443
int rc_aaa_ctx_server(rc_handle *rh, RC_AAA_CTX **ctx, SERVER *aaaserver, rc_type type, uint32_t nas_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, int add_nas_port, rc_standard_codes request_type)
Builds an authentication/accounting request and submits it to a specific server.
Definition buildreq.c:205
int rc_conf_int(rc_handle const *rh, char const *optname)
Get the value of a config option as an integer.
Definition config.c:864
int rc_check(rc_handle *rh, char *host, char *secret, unsigned short port, char *msg)
Asks the server hostname on the specified port for a status message.
Definition buildreq.c:464
rc_standard_codes
Definition radcli.h:132
SERVER * rc_conf_srv(rc_handle const *rh, char const *optname)
Get the value of a config option.
Definition config.c:875
VALUE_PAIR * rc_avpair_add(rc_handle const *rh, VALUE_PAIR **list, uint32_t attrid, void const *pval, int len, uint32_t vendorspec)
Adds an attribute-value pair to the given list.
Definition avpair.c:46
VALUE_PAIR * rc_avpair_get(VALUE_PAIR *vp, uint32_t attrid, uint32_t vendorspec)
Find the first attribute value-pair (which matches the given attribute) from the specified value-pair...
Definition avpair.c:480
@ ACCT
Request for accounting server.
Definition radcli.h:76
@ AUTH
Request for authentication server.
Definition radcli.h:75
@ PW_NAS_PORT
Its type is integer.
Definition radcli.h:155
@ PW_SERVICE_TYPE
Its type is integer.
Definition radcli.h:156
@ PW_ACCT_DELAY_TIME
Its type is integer.
Definition radcli.h:191
@ RC_SOCKET_DTLS
DTLS socket.
Definition radcli.h:108
@ RC_SOCKET_TLS
TLS socket.
Definition radcli.h:107
Public API of the radcli library.
int timeout
Session timeout in seconds.
Definition radcli.h:519
char * secret
Shared secret of RADIUS server.
Definition radcli.h:518
uint8_t seq_nbr
Packet sequence number.
Definition radcli.h:515
int svc_port
RADIUS protocol destination port.
Definition radcli.h:517
char * server
Name/address of RADIUS server.
Definition radcli.h:516
VALUE_PAIR * send_pairs
More a/v pairs to send.
Definition radcli.h:521
VALUE_PAIR * receive_pairs
Where to place received a/v pairs.
Definition radcli.h:522
uint8_t code
RADIUS packet code.
Definition radcli.h:514