123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- /*
- * $Id: buildreq.c,v 1.17 2010/02/04 10:27:09 aland Exp $
- *
- * Copyright (C) 1995,1997 Lars Fenneberg
- *
- * See the file COPYRIGHT for the respective terms and conditions.
- * If the file is missing contact me at lf@elemental.net
- * and I'll send you a copy.
- *
- */
- #include <radius_config.h>
- #include <includes.h>
- #include <freeradius-client.h>
- #include "util.h"
- /** Build a skeleton RADIUS request using information from the config file
- *
- * @param rh a handle to parsed configuration.
- * @param data a pointer to a #SEND_DATA structure.
- * @param code one of standard RADIUS codes (e.g., %PW_ACCESS_REQUEST).
- * @param server the name of the server.
- * @param port the server's port number.
- * @param secret the secret used by the server.
- * @param timeout the timeout in seconds of a message.
- * @param retries the number of retries.
- */
- void rc_buildreq(rc_handle const *rh, SEND_DATA *data, int code, char *server, unsigned short port,
- char *secret, int timeout, int retries)
- {
- data->server = server;
- data->secret = secret;
- data->svc_port = port;
- data->seq_nbr = rc_get_id();
- data->timeout = timeout;
- data->retries = retries;
- data->code = code;
- }
- /** Generates a random ID
- *
- * @return the random ID.
- */
- unsigned char rc_get_id()
- {
- return (unsigned char)(random() & UCHAR_MAX);
- }
- /** Builds an authentication/accounting request for port id client_port with the value_pairs send and submits it to a server
- *
- * @param rh a handle to parsed configuration.
- * @param client_port the client port number to use (may be zero to use any available).
- * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
- * @param received an allocated array of received values.
- * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
- * %PW_REPLY_MESSAGE received.
- * @param add_nas_port if non-zero it will include %PW_NAS_PORT in sent pairs.
- * @param request_type one of standard RADIUS codes (e.g., %PW_ACCESS_REQUEST).
- * @return received value_pairs in received, messages from the server in msg and %OK_RC (0) on success, negative
- * on failure as return value.
- */
- int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
- char *msg, int add_nas_port, int request_type)
- {
- SEND_DATA data;
- VALUE_PAIR *adt_vp = NULL;
- int result;
- int i, skip_count;
- SERVER *aaaserver;
- int timeout = rc_conf_int(rh, "radius_timeout");
- int retries = rc_conf_int(rh, "radius_retries");
- int radius_deadtime = rc_conf_int(rh, "radius_deadtime");
- double start_time = 0;
- double now = 0;
- time_t dtime;
- unsigned type;
- // -----------------------------------------------------------------------------
- // Мои дополнения
- SERVER myServer;
- char myServerName[NAME_LENGTH] = "192.168.14.234";
- char mySecret[MAX_SECRET_LENGTH] = "12345";
-
- myServer.max = 1;
- myServer.name[0] = myServerName;
- myServer.port[0] = 1645;
- myServer.secret[0] = mySecret;
- myServer.deadtime_ends[0] = 5000;
-
- aaaserver = &myServer;
- type = AUTH;
-
- if (aaaserver == NULL)
- return ERROR_RC;
- data.send_pairs = send;
- data.receive_pairs = NULL;
-
- if (add_nas_port != 0) {
- /*
- * Fill in NAS-Port
- */
- if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT,
- &client_port, 0, 0) == NULL)
- return ERROR_RC;
- }
-
- // -----------------------------------------------------------------------------
- //
- #if 1
- skip_count = 0;
- result = ERROR_RC;
- for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
- ; i++, now = rc_getctime())
- {
- if (aaaserver->deadtime_ends[i] != -1 &&
- aaaserver->deadtime_ends[i] > start_time) {
- skip_count++;
- continue;
- }
- if (data.receive_pairs != NULL) {
- rc_avpair_free(data.receive_pairs);
- data.receive_pairs = NULL;
- }
- rc_buildreq(rh, &data, request_type, aaaserver->name[i],
- aaaserver->port[i], aaaserver->secret[i], timeout, retries);
- if (request_type == PW_ACCOUNTING_REQUEST) {
- dtime = now - start_time;
- rc_avpair_assign(adt_vp, &dtime, 0);
- }
- //result = rc_send_server (rh, &data, msg, type);
- if (result == TIMEOUT_RC && radius_deadtime > 0)
- aaaserver->deadtime_ends[i] = start_time + (double)radius_deadtime;
- }
- if (result == OK_RC || result == REJECT_RC || skip_count == 0)
- goto exit;
- result = ERROR_RC;
- for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
- ; i++)
- {
- if (aaaserver->deadtime_ends[i] == -1 ||
- aaaserver->deadtime_ends[i] <= start_time) {
- continue;
- }
- if (data.receive_pairs != NULL) {
- rc_avpair_free(data.receive_pairs);
- data.receive_pairs = NULL;
- }
- rc_buildreq(rh, &data, request_type, aaaserver->name[i],
- aaaserver->port[i], aaaserver->secret[i], timeout, retries);
- if (request_type == PW_ACCOUNTING_REQUEST) {
- dtime = rc_getctime() - start_time;
- rc_avpair_assign(adt_vp, &dtime, 0);
- }
- result = rc_send_server (rh, &data, msg, type);
- if (result != TIMEOUT_RC)
- aaaserver->deadtime_ends[i] = -1;
- }
- exit:
- if (request_type != PW_ACCOUNTING_REQUEST) {
- *received = data.receive_pairs;
- } else {
- rc_avpair_free(data.receive_pairs);
- }
- #endif
- return result;
-
- #if 0
- SEND_DATA data;
- VALUE_PAIR *adt_vp = NULL;
- int result;
- int i, skip_count;
- SERVER *aaaserver;
- int timeout = rc_conf_int(rh, "radius_timeout");
- int retries = rc_conf_int(rh, "radius_retries");
- int radius_deadtime = rc_conf_int(rh, "radius_deadtime");
- double start_time = 0;
- double now = 0;
- time_t dtime;
- unsigned type;
- if (request_type != PW_ACCOUNTING_REQUEST) {
- aaaserver = rc_conf_srv(rh, "authserver");
- type = AUTH;
- } else {
- aaaserver = rc_conf_srv(rh, "acctserver");
- type = ACCT;
- }
- if (aaaserver == NULL)
- return ERROR_RC;
- data.send_pairs = send;
- data.receive_pairs = NULL;
- if (add_nas_port != 0) {
- /*
- * Fill in NAS-Port
- */
- if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT,
- &client_port, 0, 0) == NULL)
- return ERROR_RC;
- }
- if (request_type == PW_ACCOUNTING_REQUEST) {
- /*
- * Fill in Acct-Delay-Time
- */
- dtime = 0;
- now = rc_getctime();
- adt_vp = rc_avpair_get(data.send_pairs, PW_ACCT_DELAY_TIME, 0);
- if (adt_vp == NULL) {
- adt_vp = rc_avpair_add(rh, &(data.send_pairs),
- PW_ACCT_DELAY_TIME, &dtime, 0, 0);
- if (adt_vp == NULL)
- return ERROR_RC;
- start_time = now;
- } else {
- start_time = now - adt_vp->lvalue;
- }
- }
- skip_count = 0;
- result = ERROR_RC;
- for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
- ; i++, now = rc_getctime())
- {
- if (aaaserver->deadtime_ends[i] != -1 &&
- aaaserver->deadtime_ends[i] > start_time) {
- skip_count++;
- continue;
- }
- if (data.receive_pairs != NULL) {
- rc_avpair_free(data.receive_pairs);
- data.receive_pairs = NULL;
- }
- rc_buildreq(rh, &data, request_type, aaaserver->name[i],
- aaaserver->port[i], aaaserver->secret[i], timeout, retries);
- if (request_type == PW_ACCOUNTING_REQUEST) {
- dtime = now - start_time;
- rc_avpair_assign(adt_vp, &dtime, 0);
- }
- //result = rc_send_server (rh, &data, msg, type);
- if (result == TIMEOUT_RC && radius_deadtime > 0)
- aaaserver->deadtime_ends[i] = start_time + (double)radius_deadtime;
- }
- if (result == OK_RC || result == REJECT_RC || skip_count == 0)
- goto exit;
- result = ERROR_RC;
- for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
- ; i++)
- {
- if (aaaserver->deadtime_ends[i] == -1 ||
- aaaserver->deadtime_ends[i] <= start_time) {
- continue;
- }
- if (data.receive_pairs != NULL) {
- rc_avpair_free(data.receive_pairs);
- data.receive_pairs = NULL;
- }
- rc_buildreq(rh, &data, request_type, aaaserver->name[i],
- aaaserver->port[i], aaaserver->secret[i], timeout, retries);
- if (request_type == PW_ACCOUNTING_REQUEST) {
- dtime = rc_getctime() - start_time;
- rc_avpair_assign(adt_vp, &dtime, 0);
- }
- //result = rc_send_server (rh, &data, msg, type);
- if (result != TIMEOUT_RC)
- aaaserver->deadtime_ends[i] = -1;
- }
- exit:
- if (request_type != PW_ACCOUNTING_REQUEST) {
- *received = data.receive_pairs;
- } else {
- rc_avpair_free(data.receive_pairs);
- }
- return result;
- #endif
- }
- /** Builds an authentication request for port id client_port with the value_pairs send and submits it to a server
- *
- * @param rh a handle to parsed configuration.
- * @param client_port the client port number to use (may be zero to use any available).
- * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
- * @param received an allocated array of received values.
- * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
- * %PW_REPLY_MESSAGE received.
- * @return received value_pairs in @received, messages from the server in msg (if non-NULL),
- * and %OK_RC (0) on success, negative on failure as return value.
- */
- int rc_auth(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
- char *msg)
- {
- //return rc_aaa(rh, client_port, send, received, msg, 1, PW_ACCESS_REQUEST);
- return rc_aaa(rh, client_port, send, received, msg, 0, PW_ACCESS_REQUEST);
- }
- /** Builds an authentication request for proxying
- *
- * Builds an authentication request with the value_pairs send and submits it to a server.
- * Works for a proxy; does not add IP address, and does does not rely on config file.
- *
- * @param rh a handle to parsed configuration.
- * @param client_port the client port number to use (may be zero to use any available).
- * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
- * @param received an allocated array of received values.
- * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of
- * any %PW_REPLY_MESSAGE received.
- * @return received value_pairs in @received, messages from the server in msg (if non-NULL)
- * and %OK_RC (0) on success, negative on failure as return value.
- */
- int rc_auth_proxy(rc_handle *rh, VALUE_PAIR *send, VALUE_PAIR **received, char *msg)
- {
- return rc_aaa(rh, 0, send, received, msg, 0, PW_ACCESS_REQUEST);
- }
- /** Builds an accounting request for port id client_port with the value_pairs at send
- *
- * @note NAS-IP-Address, NAS-Port and Acct-Delay-Time get filled in by this function, the rest has to be supplied.
- *
- * @param rh a handle to parsed configuration.
- * @param client_port the client port number to use (may be zero to use any available).
- * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
- * @return received value_pairs in @received, and %OK_RC (0) on success, negative on failure as return value.
- */
- int rc_acct(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send)
- {
- return rc_aaa(rh, client_port, send, NULL, NULL, 1, PW_ACCOUNTING_REQUEST);
- }
- /** Builds an accounting request with the value_pairs at send
- *
- * @param rh a handle to parsed configuration.
- * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
- * @return %OK_RC (0) on success, negative on failure as return value.
- */
- int rc_acct_proxy(rc_handle *rh, VALUE_PAIR *send)
- {
- return rc_aaa(rh, 0, send, NULL, NULL, 0, PW_ACCOUNTING_REQUEST);
- }
- /** Asks the server hostname on the specified port for a status message
- *
- * @param rh a handle to parsed configuration.
- * @param host the name of the server.
- * @param secret the secret used by the server.
- * @param port the server's port number.
- * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
- * %PW_REPLY_MESSAGE received.
- * @return %OK_RC (0) on success, negative on failure as return value.
- */
- int rc_check(rc_handle *rh, char *host, char *secret, unsigned short port, char *msg)
- {
- SEND_DATA data;
- int result;
- uint32_t service_type;
- int timeout = rc_conf_int(rh, "radius_timeout");
- int retries = rc_conf_int(rh, "radius_retries");
- data.send_pairs = data.receive_pairs = NULL;
- /*
- * Fill in Service-Type
- */
- service_type = PW_ADMINISTRATIVE;
- rc_avpair_add(rh, &(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, 0);
- rc_buildreq(rh, &data, PW_STATUS_SERVER, host, port, secret, timeout, retries);
- //result = rc_send_server (rh, &data, msg, ACCT);
- rc_avpair_free(data.receive_pairs);
- return result;
- }
|