const char *secret);
int rad_digest_cmp(const uint8_t *a, const uint8_t *b, size_t length);
-RADIUS_PACKET *rad_alloc(int newvector);
-RADIUS_PACKET *rad_alloc_reply(RADIUS_PACKET *);
+RADIUS_PACKET *rad_alloc(TALLOC_CTX *ctx, int newvector);
+RADIUS_PACKET *rad_alloc_reply(TALLOC_CTX *ctx, RADIUS_PACKET *);
void rad_free(RADIUS_PACKET **);
int rad_pwencode(char *encpw, size_t *len, const char *secret,
const uint8_t *vector);
int port;
uint8_t *code;
- packet = rad_alloc(0);
+ packet = rad_alloc(NULL, 0);
if (!packet) {
fr_strerror_printf("Failed allocating packet");
return NULL;
/*
* Allocate the new request data structure
*/
- if ((packet = malloc(sizeof(*packet))) == NULL) {
+ packet = rad_alloc(NULL, 0);
+ if (!packet) {
fr_strerror_printf("out of memory");
return NULL;
}
- memset(packet, 0, sizeof(*packet));
if (flags & 0x02) {
sock_flags = MSG_PEEK;
if (data_len < 0) {
fr_strerror_printf("Error receiving packet: %s", strerror(errno));
/* packet->data is NULL */
- free(packet);
+ rad_free(&packet);
return NULL;
}
packet->data_len = data_len; /* unsigned vs signed */
if (packet->data_len > MAX_PACKET_LEN) {
fr_strerror_printf("Discarding packet: Larger than RFC limitation of 4096 bytes.");
/* packet->data is NULL */
- free(packet);
+ rad_free(&packet);
return NULL;
}
*/
if ((packet->data_len == 0) || !packet->data) {
fr_strerror_printf("Empty packet: Socket is not ready.");
- free(packet);
+ rad_free(&packet);
return NULL;
}
}
-/**
- * @brief Allocate a new RADIUS_PACKET
+/** Allocate a new RADIUS_PACKET
+ *
+ * @param ctx the context in which the packet is allocated. May be NULL if
+ * the packet is not associated with a REQUEST.
+ * @param newvector if TRUE a new request authenticator will be generated.
+ * @return a new RADIUS_PACKET or NULL on error.
*/
-RADIUS_PACKET *rad_alloc(int newvector)
+RADIUS_PACKET *rad_alloc(TALLOC_CTX *ctx, int newvector)
{
RADIUS_PACKET *rp;
- if ((rp = malloc(sizeof(RADIUS_PACKET))) == NULL) {
+ rp = talloc_zero(ctx, RADIUS_PACKET);
+ if (!rp) {
fr_strerror_printf("out of memory");
return NULL;
}
- memset(rp, 0, sizeof(*rp));
rp->id = -1;
rp->offset = -1;
return rp;
}
-RADIUS_PACKET *rad_alloc_reply(RADIUS_PACKET *packet)
+/** Allocate a new RADIUS_PACKET response
+ *
+ * @param ctx the context in which the packet is allocated. May be NULL if
+ * the packet is not associated with a REQUEST.
+ * @param newvector if TRUE a new request authenticator will be generated.
+ * @return a new RADIUS_PACKET or NULL on error.
+ */
+RADIUS_PACKET *rad_alloc_reply(TALLOC_CTX *ctx, RADIUS_PACKET *packet)
{
RADIUS_PACKET *reply;
if (!packet) return NULL;
- reply = rad_alloc(0);
+ reply = rad_alloc(ctx, 0);
if (!reply) return NULL;
/*
pairfree(&radius_packet->vps);
- free(radius_packet);
-
+ talloc_free(radius_packet);
*radius_packet_ptr = NULL;
}
RADIUS_PACKET *fr_tcp_recv(int sockfd, int flags)
{
- RADIUS_PACKET *packet = rad_alloc(0);
+ RADIUS_PACKET *packet = rad_alloc(NULL, 0);
if (!packet) return NULL;
*/
#ifdef EWOULDBLOCK
if (errno == EWOULDBLOCK) {
- packet = rad_alloc(0);
+ packet = rad_alloc(NULL, 0);
if (!packet) return NULL;
packet->sockfd = sockfd;
return NULL;
}
- packet = rad_alloc(0);
+ packet = rad_alloc(NULL, 0);
if (!packet) {
close(newfd);
return NULL;
/*
* Allocate the new request data structure
*/
- if ((packet = malloc(sizeof(*packet))) == NULL) {
+ packet = rad_alloc(NULL, 0);
+ if (!packet) {
fr_strerror_printf("out of memory");
return NULL;
}
- memset(packet, 0, sizeof(*packet));
length = vqp_recvfrom(sockfd, &packet->data, 0,
&packet->src_ipaddr, &packet->src_port,
if (length < 0) {
fr_strerror_printf("Error receiving packet: %s", strerror(errno));
/* packet->data is NULL */
- free(packet);
+ rad_free(&packet);
return NULL;
}
packet->data_len = length; /* unsigned vs signed */
fake->decode = null_socket_dencode;
fake->send = null_socket_send;
- packet = rad_alloc(0);
+ packet = rad_alloc(NULL, 0);
packet->src_ipaddr = sock->src_ipaddr;
packet->src_port = 0;
* Allocate the packet. If we fail, it's a serious
* problem.
*/
- packet = rad_alloc(1);
+ packet = rad_alloc(NULL, 1);
if (!packet) {
radlog(L_ERR, "FATAL: Failed allocating memory for detail");
exit(1);
fp = stdin;
}
- request = rad_alloc(0);
+ request = rad_alloc(NULL, 0);
/*
* Read the VP's.
request_free(&request);
goto unknown;
}
- request->reply = rad_alloc_reply(request->packet);
+ request->reply = rad_alloc_reply(request, request->packet);
if (!request->reply) {
request_free(&request);
goto unknown;
* Allocate a packet for partial reads.
*/
if (!sock->packet) {
- sock->packet = rad_alloc(0);
+ sock->packet = rad_alloc(NULL, 0);
if (!sock->packet) return 0;
sock->packet->sockfd = listener->fd;
* Create and initialize the new request.
*/
request = request_alloc(); /* never fails */
-
- if ((request->reply = rad_alloc(0)) == NULL) {
+ request->reply = rad_alloc(request, 0);
+ if (!request->reply) {
radlog(L_ERR, "No memory");
request_free(&request);
return 1;
request->child_pid = NO_SUCH_CHILD_PID;
#endif
- request->proxy = rad_alloc(1);
+ request->proxy = rad_alloc(request, 1);
rad_assert(request->proxy != NULL);
if (home->ping_check == HOME_PING_CHECK_STATUS_SERVER) {
}
memset(radclient, 0, sizeof(*radclient));
- radclient->request = rad_alloc(1);
+ radclient->request = rad_alloc(NULL, 1);
if (!radclient->request) {
goto oom;
}
/*
* This swaps the various fields.
*/
- reply = rad_alloc_reply(packet);
+ reply = rad_alloc_reply(NULL, packet);
if (!reply) goto oom;
compare = 1;
udp = (const struct udp_header*)(((const uint8_t *) ip) + size_ip);
payload = (const uint8_t *)(((const uint8_t *) udp) + size_udp);
- packet = malloc(sizeof(*packet));
+ packet = rad_alloc(NULL, 0);
if (!packet) {
fprintf(stderr, "Out of memory\n");
return;
}
- memset(packet, 0, sizeof(*packet));
packet->src_ipaddr.af = AF_INET;
packet->src_ipaddr.ipaddr.ip4addr.s_addr = ip->ip_src.s_addr;
packet->src_port = ntohs(udp->udp_sport);
DEBUG(log_dst, " To: %s:%d\n", inet_ntoa(ip->ip_dst), ntohs(udp->udp_dport));
DEBUG(log_dst, " Type: %s\n", fr_packet_codes[packet->code]);
- free(packet);
+ rad_free(&packet);
return;
}
break;
case PW_AUTHENTICATION_REQUEST:
/* save the request for later matching */
- original = rad_alloc_reply(packet);
+ original = rad_alloc_reply(NULL, packet);
if (original) { /* just ignore allocation failures */
rbtree_deletebydata(request_tree, original);
rbtree_insert(request_tree, original);
* Decode the data without bothering to check the signatures.
*/
if (rad_decode(packet, original, radius_secret) != 0) {
- free(packet);
+ rad_free(&packet);
fr_perror("decode");
return;
}
rbtree_deletebydata(request_tree, original);
if (filter_vps && filter_packet(packet)) {
- free(packet);
+ rad_free(&packet);
DEBUG(log_dst, "Packet number %d doesn't match\n", count++);
return;
}
if (!filter_vps ||
((packet->code != PW_AUTHENTICATION_REQUEST) &&
(packet->code != PW_ACCOUNTING_REQUEST))) {
- free(packet);
+ rad_free(&packet);
}
}
/*
* Allocate a null packet for decrypting attributes in CoA requests
*/
- nullpacket = rad_alloc(0);
+ nullpacket = rad_alloc(NULL, 0);
if (!nullpacket) {
fprintf(stderr, "radsniff: Out of memory\n");
exit(1);
* module, and encapsulated into an EAP packet.
*/
if (!request->proxy) {
- if ((request->proxy = rad_alloc(TRUE)) == NULL) {
+ request->proxy = rad_alloc(request, TRUE);
+ if (!request->proxy) {
radlog(L_ERR, "no memory");
exit(1);
}
RADCLIENT *client = sock->client;
if (!sock->packet) {
- sock->packet = rad_alloc(0);
+ sock->packet = rad_alloc(NULL, 0);
if (!sock->packet) return 0;
sock->packet->sockfd = listener->fd;
sock->packet->dst_ipaddr = sock->my_ipaddr;
sock->packet->dst_port = sock->my_port;
- if (sock->request) sock->request->packet = sock->packet;
+ if (sock->request) {
+ talloc_steal(sock->request, sock->packet);
+ sock->request->packet = sock->packet;
+ }
}
/*
/*
* Not sure if we should do this on every packet...
*/
- request->reply = rad_alloc(0);
+ request->reply = rad_alloc(request, 0);
if (!request->reply) return 0;
request->options = RAD_REQUEST_OPTION_DEBUG2;
}
PTHREAD_MUTEX_UNLOCK(&sock->mutex);
- packet = rad_alloc(0);
+ packet = rad_alloc(NULL, 0);
packet->sockfd = listener->fd;
packet->src_ipaddr = sock->other_ipaddr;
packet->src_port = sock->other_port;
*/
fake->server = request->server;
- fake->packet = rad_alloc(1);
+ fake->packet = rad_alloc(request, 1);
if (!fake->packet) {
request_free(&fake);
return NULL;
}
- fake->reply = rad_alloc(0);
+ fake->reply = rad_alloc(request, 0);
if (!fake->reply) {
request_free(&fake);
return NULL;
request->coa->packet->code = 0; /* unknown, as of yet */
request->coa->child_state = REQUEST_RUNNING;
- request->coa->proxy = rad_alloc(0);
+ request->coa->proxy = rad_alloc(request->coa, 0);
if (!request->coa->proxy) {
request_free(&request->coa);
return NULL;
return 1;
}
- if ((req = rad_alloc(1)) == NULL) {
+ req = rad_alloc(NULL, 1);
+ if (!req) {
fr_perror("radclient");
exit(1);
}
return 1;
}
- if ((req = rad_alloc(1)) == NULL) {
+ req = rad_alloc(NULL, 1)
+ if (!req) {
fr_perror("radclient");
exit(1);
}
- if ((req2 = rad_alloc(1)) == NULL) {
+ req2 = rad_alloc(NULL, 1);
+ if (!req2) {
fr_perror("radclient");
exit(1);
}
* we built here.
*/
if (!packet) {
- packet = rad_alloc(1);
+ packet = rad_alloc(NULL, 1);
if (!packet) return RLM_MODULE_FAIL;
packet->sockfd = -1;
packet->code = code;