|
@@ -20,8 +20,10 @@
|
|
|
#include <includes.h>
|
|
|
#include <freeradius-client.h>
|
|
|
#include <pathnames.h>
|
|
|
+#include "freeradius-client.h"
|
|
|
#include "util.h"
|
|
|
#include "radius_user.h"
|
|
|
+#include "parameters.h"
|
|
|
|
|
|
#include "lwip/sockets.h"
|
|
|
|
|
@@ -194,22 +196,12 @@ static void strappend(char *dest, unsigned max_size, int *pos, const char *src)
|
|
|
* on failure as return value.
|
|
|
*/
|
|
|
|
|
|
-#define RS_PORT_NUM 1812
|
|
|
-//#define RS_IP_ADDR "192.168.1.2"
|
|
|
-#define RS_IP_ADDR "192.168.14.234"
|
|
|
|
|
|
-#define DEVICE_PORT_NUM 1812
|
|
|
-//#define DEVICE_IP_ADDR "192.168.1.6"
|
|
|
-#define DEVICE_IP_ADDR "192.168.14.37"
|
|
|
-
|
|
|
-#define BUF_LEN 300
|
|
|
-
|
|
|
-static uint8_t send_buffer[BUF_LEN];
|
|
|
-static uint8_t recv_buffer[BUF_LEN];
|
|
|
+#define RECV_BUF_LEN 100
|
|
|
+static char recv_buffer[RECV_BUF_LEN];
|
|
|
|
|
|
int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
|
|
|
{
|
|
|
-#if 1
|
|
|
struct sockaddr_in sa,ra;
|
|
|
int socket;
|
|
|
fdsets sets;
|
|
@@ -225,80 +217,94 @@ int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
|
|
|
int result = 0;
|
|
|
VALUE_PAIR* vp;
|
|
|
|
|
|
-
|
|
|
+ char rcNetParams[20];
|
|
|
+ uint32_t port;
|
|
|
+ uint8_t tmpLen;
|
|
|
+
|
|
|
initFdsets(&sets);
|
|
|
|
|
|
if(data->secret != NULL) {
|
|
|
strlcpy(secret, data->secret, MAX_SECRET_LENGTH);
|
|
|
}
|
|
|
|
|
|
+ // Устанавливаем сетевые параметры
|
|
|
+ memset(rcNetParams, 0, 20);
|
|
|
+ GetRDSIpStr(rcNetParams, &tmpLen);
|
|
|
+
|
|
|
+ // IP radius server
|
|
|
memset(&ra, 0, sizeof(struct sockaddr_in));
|
|
|
ra.sin_family = AF_INET;
|
|
|
- ra.sin_addr.s_addr = inet_addr(RS_IP_ADDR);
|
|
|
- ra.sin_port = htons(RS_PORT_NUM);
|
|
|
+ ra.sin_addr.s_addr = inet_addr(rcNetParams);
|
|
|
|
|
|
+ // port
|
|
|
+ memset(rcNetParams, 0, 20);
|
|
|
+ GetRDSPortStr(rcNetParams, &tmpLen);
|
|
|
+ port = atoi(rcNetParams);
|
|
|
+ ra.sin_port = htons(port);
|
|
|
+
|
|
|
socket = socket(PF_INET, SOCK_DGRAM, 0);
|
|
|
if ( socket < 0 )
|
|
|
{
|
|
|
- printf("socket call failed");
|
|
|
+ //printf("socket call failed");
|
|
|
return -1;
|
|
|
}
|
|
|
-
|
|
|
- // TODO bind?
|
|
|
-
|
|
|
+
|
|
|
// Build a request (PW_ACCESS_REQUEST)
|
|
|
- auth = (AUTH_HDR *) send_buffer;
|
|
|
+ auth = (AUTH_HDR *) msg;
|
|
|
auth->code = data->code;
|
|
|
auth->id = data->seq_nbr;
|
|
|
|
|
|
rc_random_vector(vector);
|
|
|
- memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
|
|
|
+ memcpy((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
|
|
|
|
|
|
total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;
|
|
|
-
|
|
|
auth->length = htons ((unsigned short) total_length);
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
// Bind socket
|
|
|
+ memset(rcNetParams, 0, 20);
|
|
|
+ GetIpStr(rcNetParams, &tmpLen);
|
|
|
+
|
|
|
memset(&sa, 0, sizeof(struct sockaddr_in));
|
|
|
sa.sin_family = AF_INET;
|
|
|
- sa.sin_addr.s_addr = inet_addr(DEVICE_IP_ADDR);
|
|
|
- sa.sin_port = htons(DEVICE_PORT_NUM);
|
|
|
+ sa.sin_addr.s_addr = inet_addr(rcNetParams);
|
|
|
+ sa.sin_port = htons(port);
|
|
|
|
|
|
if (bind(socket, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1)
|
|
|
{
|
|
|
- printf("Bind to Port Number %d ,IP address %s failed\n", DEVICE_PORT_NUM, DEVICE_IP_ADDR);
|
|
|
+ //printf("Bind to Port Number %d ,IP address %s failed\n", DEVICE_PORT_NUM, DEVICE_IP_ADDR);
|
|
|
close(socket);
|
|
|
- return 0;
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
sendLen = sendto(socket, (char*)auth, total_length, 0, (struct sockaddr*)&ra, sizeof(ra));
|
|
|
if(sendLen < 0)
|
|
|
{
|
|
|
- printf("send failed\n");
|
|
|
+ //printf("send failed\n");
|
|
|
close(socket);
|
|
|
- return 0;
|
|
|
+ return NET_ERR_RC;
|
|
|
}
|
|
|
|
|
|
+ // Подготовка буфера для приема
|
|
|
+ memset(recv_buffer, 0, RECV_BUF_LEN);
|
|
|
+
|
|
|
// Получение ответа, select
|
|
|
if (!recvSelect(&sets, &socket, 2000)) {
|
|
|
- //timeCount = HAL_GetTick() - timeCount;
|
|
|
- printf("SOCK recv timeout!\r\n");
|
|
|
+ //printf("SOCK recv timeout!\r\n");
|
|
|
close(socket);
|
|
|
- return 0;
|
|
|
+ return NET_ERR_RC;
|
|
|
}
|
|
|
|
|
|
// Данные можно принимать
|
|
|
socklen_t sl = sizeof(sa);
|
|
|
- recvLen = recvfrom(socket, recv_buffer, BUF_LEN, 0, (struct sockaddr*)&ra, &sl);
|
|
|
+ recvLen = recvfrom(socket, recv_buffer, RECV_BUF_LEN, 0, (struct sockaddr*)&ra, &sl);
|
|
|
|
|
|
recv_auth = (AUTH_HDR*)recv_buffer;
|
|
|
|
|
|
// Проверки размера входящего сообщения
|
|
|
if (recvLen < AUTH_HDR_LEN || recvLen < ntohs(recv_auth->length)) {
|
|
|
- printf("radius_server: reply is too short\r\n");
|
|
|
+ //printf("radius_server: reply is too short\r\n");
|
|
|
close(socket);
|
|
|
- return 0;
|
|
|
+ return NET_ERR_RC;
|
|
|
}
|
|
|
|
|
|
if (recvLen > ntohs(recv_auth->length))
|
|
@@ -310,28 +316,28 @@ int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
|
|
|
attr = recv_buffer + AUTH_HDR_LEN;
|
|
|
while (attr < (recv_buffer + recvLen)) {
|
|
|
if (attr[0] == 0) {
|
|
|
- printf("radius_server: attribute zero is invalid\r\n");
|
|
|
+ //printf("radius_server: attribute zero is invalid\r\n");
|
|
|
close(socket);
|
|
|
- return 0;
|
|
|
+ return NET_ERR_RC;
|
|
|
}
|
|
|
|
|
|
if (attr[1] < 2) {
|
|
|
- printf("radius_server: attribute length is too small\r\n");
|
|
|
+ //printf("radius_server: attribute length is too small\r\n");
|
|
|
close(socket);
|
|
|
- return 0;
|
|
|
+ return NET_ERR_RC;
|
|
|
}
|
|
|
|
|
|
if ((attr + attr[1]) > (recv_buffer + recvLen)) {
|
|
|
- printf("radius_server: attribute overflows the packet\r\n");
|
|
|
+ //printf("radius_server: attribute overflows the packet\r\n");
|
|
|
close(socket);
|
|
|
- return 0;
|
|
|
+ return NET_ERR_RC;
|
|
|
}
|
|
|
|
|
|
attr += attr[1];
|
|
|
}
|
|
|
|
|
|
|
|
|
- result = rc_check_reply (recv_auth, BUF_LEN, secret, vector, data->seq_nbr);
|
|
|
+ result = rc_check_reply(recv_auth, RECV_BUF_LEN, secret, vector, data->seq_nbr);
|
|
|
|
|
|
length = ntohs(recv_auth->length) - AUTH_HDR_LEN;
|
|
|
if (length > 0) {
|
|
@@ -363,7 +369,7 @@ int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
|
|
|
(recv_auth->code == PW_PASSWORD_ACK) ||
|
|
|
(recv_auth->code == PW_ACCOUNTING_RESPONSE))
|
|
|
{
|
|
|
- result = OK_RC;
|
|
|
+ result = RC_GetAccessRights(recv_buffer);
|
|
|
}
|
|
|
else if ((recv_auth->code == PW_ACCESS_REJECT) ||
|
|
|
(recv_auth->code == PW_PASSWORD_REJECT))
|
|
@@ -376,333 +382,9 @@ int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
|
|
|
result = BADRESP_RC;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- printf("Radius server end communication\r\n");
|
|
|
+ //printf("\r\nRadius server end communication\r\n");
|
|
|
close(socket);
|
|
|
return result;
|
|
|
-
|
|
|
- //getnameinfo(SA(&our_sockaddr), SS_LEN(&our_sockaddr), NULL, 0, our_addr_txt, sizeof(our_addr_txt), NI_NUMERICHOST);
|
|
|
- //getnameinfo(auth_addr->ai_addr, auth_addr->ai_addrlen, NULL, 0, auth_addr_txt, sizeof(auth_addr_txt), NI_NUMERICHOST);
|
|
|
-
|
|
|
-
|
|
|
-#endif
|
|
|
-
|
|
|
-#if 0
|
|
|
- int sockfd;
|
|
|
- AUTH_HDR *auth, *recv_auth;
|
|
|
- char *server_name; /* Name of server to query */
|
|
|
- struct sockaddr_storage our_sockaddr;
|
|
|
- struct addrinfo *auth_addr = NULL;
|
|
|
- socklen_t salen;
|
|
|
- int result = 0;
|
|
|
- int total_length;
|
|
|
- int length, pos;
|
|
|
- int retry_max;
|
|
|
- unsigned discover_local_ip;
|
|
|
- size_t secretlen;
|
|
|
- char secret[MAX_SECRET_LENGTH + 1];
|
|
|
- unsigned char vector[AUTH_VECTOR_LEN];
|
|
|
- uint8_t recv_buffer[BUFFER_LEN];
|
|
|
- uint8_t send_buffer[BUFFER_LEN];
|
|
|
- char our_addr_txt[50]; /* hold a text IP */
|
|
|
- char auth_addr_txt[50]; /* hold a text IP */
|
|
|
- uint8_t *attr;
|
|
|
- int retries;
|
|
|
- VALUE_PAIR *vp;
|
|
|
- //struct pollfd pfd;
|
|
|
- double start_time, timeout;
|
|
|
-
|
|
|
-
|
|
|
- server_name = data->server;
|
|
|
- if (server_name == NULL || server_name[0] == '\0')
|
|
|
- return ERROR_RC;
|
|
|
-
|
|
|
- if(data->secret != NULL)
|
|
|
- {
|
|
|
- //strlcpy(secret, data->secret, MAX_SECRET_LENGTH);
|
|
|
- memcpy(secret, data->secret, MAX_SECRET_LENGTH);
|
|
|
- }
|
|
|
-
|
|
|
- if (rc_find_server_addr (rh, server_name, &auth_addr, secret, flags) != 0)
|
|
|
- {
|
|
|
- rc_log(LOG_ERR, "rc_send_server: unable to find server: %s", server_name);
|
|
|
- return ERROR_RC;
|
|
|
- }
|
|
|
-
|
|
|
- rc_own_bind_addr(rh, &our_sockaddr);
|
|
|
- discover_local_ip = 0;
|
|
|
- if (our_sockaddr.ss_family == AF_INET) {
|
|
|
- if (((struct sockaddr_in*)(&our_sockaddr))->sin_addr.s_addr == INADDR_ANY) {
|
|
|
- discover_local_ip = 1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- DEBUG(LOG_ERR, "DEBUG: rc_send_server: creating socket to: %s", server_name);
|
|
|
- if (discover_local_ip) {
|
|
|
- result = rc_get_srcaddr(SA(&our_sockaddr), auth_addr->ai_addr);
|
|
|
- if (result != 0) {
|
|
|
- memset (secret, '\0', sizeof (secret));
|
|
|
- rc_log(LOG_ERR, "rc_send_server: cannot figure our own address");
|
|
|
- result = ERROR_RC;
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- sockfd = socket (our_sockaddr.ss_family, SOCK_DGRAM, 0);
|
|
|
- if (sockfd < 0)
|
|
|
- {
|
|
|
- memset (secret, '\0', sizeof (secret));
|
|
|
- rc_log(LOG_ERR, "rc_send_server: socket: %s", strerror(errno));
|
|
|
- result = ERROR_RC;
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- if (our_sockaddr.ss_family == AF_INET)
|
|
|
- ((struct sockaddr_in*)&our_sockaddr)->sin_port = 0;
|
|
|
- else
|
|
|
- ((struct sockaddr_in6*)&our_sockaddr)->sin6_port = 0;
|
|
|
-
|
|
|
- if (bind(sockfd, SA(&our_sockaddr), SS_LEN(&our_sockaddr)) < 0)
|
|
|
- {
|
|
|
- close (sockfd);
|
|
|
- memset (secret, '\0', sizeof (secret));
|
|
|
- rc_log(LOG_ERR, "rc_send_server: bind: %s: %s", server_name, strerror(errno));
|
|
|
- result = ERROR_RC;
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- retry_max = data->retries; /* Max. numbers to try for reply */
|
|
|
- retries = 0; /* Init retry cnt for blocking call */
|
|
|
-
|
|
|
- if (data->svc_port) {
|
|
|
- if (our_sockaddr.ss_family == AF_INET)
|
|
|
- ((struct sockaddr_in*)auth_addr->ai_addr)->sin_port = htons ((unsigned short) data->svc_port);
|
|
|
- else
|
|
|
- ((struct sockaddr_in6*)auth_addr->ai_addr)->sin6_port = htons ((unsigned short) data->svc_port);
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Fill in NAS-IP-Address (if needed)
|
|
|
- */
|
|
|
- if (rc_avpair_get(data->send_pairs, PW_NAS_IP_ADDRESS, 0) == NULL &&
|
|
|
- rc_avpair_get(data->send_pairs, PW_NAS_IPV6_ADDRESS, 0) == NULL) {
|
|
|
- if (our_sockaddr.ss_family == AF_INET) {
|
|
|
- uint32_t ip;
|
|
|
- ip = *((uint32_t*)(&((struct sockaddr_in*)&our_sockaddr)->sin_addr));
|
|
|
- ip = ntohl(ip);
|
|
|
-
|
|
|
- rc_avpair_add(rh, &(data->send_pairs), PW_NAS_IP_ADDRESS,
|
|
|
- &ip, 0, 0);
|
|
|
- } else {
|
|
|
- void *p;
|
|
|
- p = &((struct sockaddr_in6*)&our_sockaddr)->sin6_addr;
|
|
|
-
|
|
|
- rc_avpair_add(rh, &(data->send_pairs), PW_NAS_IPV6_ADDRESS,
|
|
|
- p, 0, 0);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Build a request */
|
|
|
- auth = (AUTH_HDR *) send_buffer;
|
|
|
- auth->code = data->code;
|
|
|
- auth->id = data->seq_nbr;
|
|
|
-
|
|
|
- if (data->code == PW_ACCOUNTING_REQUEST)
|
|
|
- {
|
|
|
- total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;
|
|
|
-
|
|
|
- auth->length = htons ((unsigned short) total_length);
|
|
|
-
|
|
|
- memset((char *) auth->vector, 0, AUTH_VECTOR_LEN);
|
|
|
- secretlen = strlen (secret);
|
|
|
- memcpy ((char *) auth + total_length, secret, secretlen);
|
|
|
- rc_md5_calc (vector, (unsigned char *) auth, total_length + secretlen);
|
|
|
- memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- rc_random_vector (vector);
|
|
|
- memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
|
|
|
-
|
|
|
- total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;
|
|
|
-
|
|
|
- auth->length = htons ((unsigned short) total_length);
|
|
|
- }
|
|
|
-
|
|
|
- getnameinfo(SA(&our_sockaddr), SS_LEN(&our_sockaddr), NULL, 0, our_addr_txt, sizeof(our_addr_txt), NI_NUMERICHOST);
|
|
|
- getnameinfo(auth_addr->ai_addr, auth_addr->ai_addrlen, NULL, 0, auth_addr_txt, sizeof(auth_addr_txt), NI_NUMERICHOST);
|
|
|
-
|
|
|
- DEBUG(LOG_ERR, "DEBUG: local %s : 0, remote %s : %u\n",
|
|
|
- our_addr_txt, auth_addr_txt, data->svc_port);
|
|
|
-
|
|
|
- for (;;)
|
|
|
- {
|
|
|
- do {
|
|
|
- result = sendto (sockfd, (char *) auth, (unsigned int)total_length,
|
|
|
- (int) 0, SA(auth_addr->ai_addr), auth_addr->ai_addrlen);
|
|
|
- } while (result == -1 && errno == EINTR);
|
|
|
- if (result == -1) {
|
|
|
- rc_log(LOG_ERR, "%s: socket: %s", __FUNCTION__, strerror(errno));
|
|
|
- }
|
|
|
-
|
|
|
- pfd.fd = sockfd;
|
|
|
- pfd.events = POLLIN;
|
|
|
- pfd.revents = 0;
|
|
|
- start_time = rc_getctime();
|
|
|
- for (timeout = data->timeout; timeout > 0;
|
|
|
- timeout -= rc_getctime() - start_time) {
|
|
|
- result = poll(&pfd, 1, timeout * 1000);
|
|
|
- if (result != -1 || errno != EINTR)
|
|
|
- break;
|
|
|
- }
|
|
|
- if (result == -1)
|
|
|
- {
|
|
|
- rc_log(LOG_ERR, "rc_send_server: poll: %s", strerror(errno));
|
|
|
- memset (secret, '\0', sizeof (secret));
|
|
|
- close (sockfd);
|
|
|
- result = ERROR_RC;
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- if (result == 1 && (pfd.revents & POLLIN) != 0)
|
|
|
- break;
|
|
|
-
|
|
|
- /*
|
|
|
- * Timed out waiting for response. Retry "retry_max" times
|
|
|
- * before giving up. If retry_max = 0, don't retry at all.
|
|
|
- */
|
|
|
- if (retries++ >= retry_max)
|
|
|
- {
|
|
|
- rc_log(LOG_ERR,
|
|
|
- "rc_send_server: no reply from RADIUS server %s:%u",
|
|
|
- auth_addr_txt, data->svc_port);
|
|
|
- close (sockfd);
|
|
|
- memset (secret, '\0', sizeof (secret));
|
|
|
- result = TIMEOUT_RC;
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- }
|
|
|
- salen = auth_addr->ai_addrlen;
|
|
|
- do {
|
|
|
- length = recvfrom (sockfd, (char *) recv_buffer,
|
|
|
- (int) sizeof (recv_buffer),
|
|
|
- (int) 0, SA(auth_addr->ai_addr), &salen);
|
|
|
- } while(length == -1 && errno == EINTR);
|
|
|
-
|
|
|
- if (length <= 0)
|
|
|
- {
|
|
|
- rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: %s", server_name,\
|
|
|
- data->svc_port, strerror(errno));
|
|
|
- close (sockfd);
|
|
|
- memset (secret, '\0', sizeof (secret));
|
|
|
- result = ERROR_RC;
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- recv_auth = (AUTH_HDR *)recv_buffer;
|
|
|
-
|
|
|
- if (length < AUTH_HDR_LEN || length < ntohs(recv_auth->length)) {
|
|
|
- rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: reply is too short",
|
|
|
- server_name, data->svc_port);
|
|
|
- close(sockfd);
|
|
|
- memset(secret, '\0', sizeof(secret));
|
|
|
- result = ERROR_RC;
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * If UDP is larger than RADIUS, shorten it to RADIUS.
|
|
|
- */
|
|
|
- if (length > ntohs(recv_auth->length)) length = ntohs(recv_auth->length);
|
|
|
-
|
|
|
- /*
|
|
|
- * Verify that it's a valid RADIUS packet before doing ANYTHING with it.
|
|
|
- */
|
|
|
- attr = recv_buffer + AUTH_HDR_LEN;
|
|
|
- while (attr < (recv_buffer + length)) {
|
|
|
- if (attr[0] == 0) {
|
|
|
- rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: attribute zero is invalid",
|
|
|
- server_name, data->svc_port);
|
|
|
- close(sockfd);
|
|
|
- memset(secret, '\0', sizeof(secret));
|
|
|
- return ERROR_RC;
|
|
|
- }
|
|
|
-
|
|
|
- if (attr[1] < 2) {
|
|
|
- rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: attribute length is too small",
|
|
|
- server_name, data->svc_port);
|
|
|
- close(sockfd);
|
|
|
- memset(secret, '\0', sizeof(secret));
|
|
|
- return ERROR_RC;
|
|
|
- }
|
|
|
-
|
|
|
- if ((attr + attr[1]) > (recv_buffer + length)) {
|
|
|
- rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: attribute overflows the packet",
|
|
|
- server_name, data->svc_port);
|
|
|
- close(sockfd);
|
|
|
- memset(secret, '\0', sizeof(secret));
|
|
|
- return ERROR_RC;
|
|
|
- }
|
|
|
-
|
|
|
- attr += attr[1];
|
|
|
- }
|
|
|
-
|
|
|
- result = rc_check_reply (recv_auth, BUFFER_LEN, secret, vector, data->seq_nbr);
|
|
|
-
|
|
|
- length = ntohs(recv_auth->length) - AUTH_HDR_LEN;
|
|
|
- if (length > 0) {
|
|
|
- data->receive_pairs = rc_avpair_gen(rh, NULL, recv_auth->data,
|
|
|
- length, 0);
|
|
|
- } else {
|
|
|
- data->receive_pairs = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- close (sockfd);
|
|
|
- memset (secret, '\0', sizeof (secret));
|
|
|
-
|
|
|
- if (result != OK_RC) {
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- if (msg) {
|
|
|
- *msg = '\0';
|
|
|
- pos = 0;
|
|
|
- vp = data->receive_pairs;
|
|
|
- while (vp)
|
|
|
- {
|
|
|
- if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE, 0)))
|
|
|
- {
|
|
|
- strappend(msg, PW_MAX_MSG_SIZE, &pos, vp->strvalue);
|
|
|
- strappend(msg, PW_MAX_MSG_SIZE, &pos, "\n");
|
|
|
- vp = vp->next;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if ((recv_auth->code == PW_ACCESS_ACCEPT) ||
|
|
|
- (recv_auth->code == PW_PASSWORD_ACK) ||
|
|
|
- (recv_auth->code == PW_ACCOUNTING_RESPONSE))
|
|
|
- {
|
|
|
- result = OK_RC;
|
|
|
- }
|
|
|
- else if ((recv_auth->code == PW_ACCESS_REJECT) ||
|
|
|
- (recv_auth->code == PW_PASSWORD_REJECT))
|
|
|
- {
|
|
|
- result = REJECT_RC;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- rc_log(LOG_ERR, "rc_send_server: received RADIUS server response neither ACCEPT nor REJECT, invalid");
|
|
|
- result = BADRESP_RC;
|
|
|
- }
|
|
|
-
|
|
|
- cleanup:
|
|
|
- if (auth_addr)
|
|
|
- freeaddrinfo(auth_addr);
|
|
|
-
|
|
|
- return result;
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
/** Verify items in returned packet
|