radius_attributes.c
Go to the documentation of this file.
1 /**
2  * @file radius_attributes.c
3  * @brief Formatting and parsing of RADIUS attributes
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2022-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneEAP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL RADIUS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "radius/radius.h"
37 #include "debug.h"
38 
39 //Check EAP library configuration
40 #if (RADIUS_SUPPORT == ENABLED)
41 
42 
43 /**
44  * @brief Append an attribute to a RADIUS packet
45  * @param[in] packet Pointer to the RADIUS packet
46  * @param[in] type Attribute type
47  * @param[in] value Attribute value
48  * @param[in] length Length of the attribute value
49  **/
50 
51 void radiusAddAttribute(RadiusPacket *packet, uint8_t type, const void *value,
52  size_t length)
53 {
54  size_t n;
55  RadiusAttribute *attribute;
56 
57  //Check the length of the attribute value
59  {
60  //Retrieve the actual length of the RADIUS packet
61  n = ntohs(packet->length);
62 
63  //Point to the buffer where to format the RADIUS attribute
64  attribute = (RadiusAttribute *) ((uint8_t *) packet + n);
65 
66  //The Type field is one octet
67  attribute->type = type;
68 
69  //The Length field is one octet, and indicates the length of this Attribute
70  //including the Type, Length and Value fields (refer to RFC 2865, section 5)
71  attribute->length = sizeof(RadiusAttribute) + length;
72 
73  //Copy attribute value
74  osMemcpy(attribute->value, value, length);
75 
76  //Adjust the length of the RADIUS packet
77  n += attribute->length;
78  //Fix the length field
79  packet->length = htons(n);
80  }
81 }
82 
83 
84 /**
85  * @brief Search a RADIUS packet for a given attribute
86  * @param[in] packet Pointer to the RADIUS packet
87  * @param[in] type Attribute type
88  * @param[in] index Attribute occurrence index
89  * @return If the specified attribute is found, a pointer to the corresponding
90  * attribute is returned. Otherwise NULL pointer is returned
91  **/
92 
94  uint8_t type, uint_t index)
95 {
96  uint_t k;
97  size_t i;
98  size_t n;
99  const RadiusAttribute *attribute;
100 
101  //Retrieve the actual length of the RADIUS packet
102  n = ntohs(packet->length);
103 
104  //Check the length of the RADIUS packet
105  if(n > sizeof(RadiusPacket))
106  {
107  //Calculate the length of the RADIUS attributes
108  n -= sizeof(RadiusPacket);
109 
110  //Initialize occurrence index
111  k = 0;
112 
113  //Loop through the attributes
114  for(i = 0; i < n; i += attribute->length)
115  {
116  //Point to the attribute
117  attribute = (RadiusAttribute *) (packet->attributes + i);
118 
119  //Malformed attribute?
120  if(attribute->length < sizeof(RadiusAttribute) ||
121  attribute->length > n)
122  {
123  return NULL;
124  }
125 
126  //Matching attribute type?
127  if(attribute->type == type)
128  {
129  //Matching occurrence found?
130  if(k++ == index)
131  {
132  return attribute;
133  }
134  }
135  }
136  }
137 
138  //The specified attribute type was not found
139  return NULL;
140 }
141 
142 #endif
143 
uint8_t type
Definition: coap_common.h:176
unsigned int uint_t
Definition: compiler_port.h:50
#define htons(value)
Definition: cpu_endian.h:413
#define ntohs(value)
Definition: cpu_endian.h:421
Debugging facilities.
uint8_t n
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
RADIUS (Remote Authentication Dial In User Service)
RadiusPacket
Definition: radius.h:89
void radiusAddAttribute(RadiusPacket *packet, uint8_t type, const void *value, size_t length)
Append an attribute to a RADIUS packet.
const RadiusAttribute * radiusGetAttribute(const RadiusPacket *packet, uint8_t type, uint_t index)
Search a RADIUS packet for a given attribute.
Formatting and parsing of RADIUS attributes.
RadiusAttribute
#define RADIUS_MAX_ATTR_VALUE_LEN
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369