The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
radius.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 
18 /*
19  * $Id: 3ece3aed65bc83a3ed34116c66bb9a0ace804aaa $
20  *
21  * @file protocols/radius/radius.h
22  * @brief Structures and prototypes for base RADIUS functionality.
23  *
24  * @copyright 1999-2017 The FreeRADIUS server project
25  */
26 #include <freeradius-devel/radius/defs.h>
27 #include <freeradius-devel/util/packet.h>
28 #include <freeradius-devel/util/rand.h>
29 #include <freeradius-devel/util/log.h>
30 #include <freeradius-devel/util/dbuff.h>
31 #include <freeradius-devel/io/test_point.h>
32 
33 #define RADIUS_AUTH_VECTOR_OFFSET 4
34 #define RADIUS_HEADER_LENGTH 20
35 #define RADIUS_MAX_STRING_LENGTH 253
36 #define RADIUS_MAX_TUNNEL_PASSWORD_LENGTH 249
37 #define RADIUS_AUTH_VECTOR_LENGTH 16
38 #define RADIUS_MESSAGE_AUTHENTICATOR_LENGTH 16
39 #define RADIUS_MAX_PASS_LENGTH 256
40 #define RADIUS_MAX_ATTRIBUTES 255
41 #define RADIUS_MAX_PACKET_SIZE 4096
42 
43 #define RADIUS_VENDORPEC_USR 429
44 #define RADIUS_VENDORPEC_LUCENT 4846
45 #define RADIUS_VENDORPEC_STARENT 8164
46 
47 /*
48  * protocols/radius/base.c
49  */
50 
51 
52 #define FR_RADIUS_PACKET_CODE_VALID(_x) ((_x > 0) && (_x < FR_RADIUS_CODE_MAX))
53 
54 #define AUTH_PASS_LEN (RADIUS_AUTH_VECTOR_LENGTH)
55 
56 #define FR_TUNNEL_FR_ENC_LENGTH(_x) (2 + 1 + _x + PAD(_x + 1, 16))
57 
58 /** Control whether Message-Authenticator is required in Access-Requests
59  *
60  * @note Don't change the enum values. They allow efficient bistmasking.
61  */
62 typedef enum {
63  FR_RADIUS_REQUIRE_MA_NO = 0x00, //!< Do not require Message-Authenticator
64  FR_RADIUS_REQUIRE_MA_AUTO = 0x01, //!< Only require Message-Authenticator if we've previously
65  ///< received a packet from this client with Message-Authenticator.
66  ///< @note This isn't used by the radius protocol code, but may be used
67  ///< to drive logic in modules.
68  FR_RADIUS_REQUIRE_MA_YES = 0x02 //!< Require Message-Authenticator
69 
71 
72 /** Control whether Proxy-State is allowed in Access-Requests
73  *
74  * @note Don't change the enum values. They allow efficient bistmasking.
75  */
76 typedef enum {
77  FR_RADIUS_LIMIT_PROXY_STATE_NO = 0x00, //!< Do not limit Proxy-State. Allow proxy-state to be sent in
78  ///< all packets.
79  FR_RADIUS_LIMIT_PROXY_STATE_AUTO = 0x01, //!< Do not allow Proxy-State unless:
80  ///< - All packets received from a client have containted proxy state.
81  ///< - The client has sent a packet with a Message-Authenticator.
82  ///< @note This isn't used by the radius protocol code, but may be used
83  ///< to drive logic in modules.
84  FR_RADIUS_LIMIT_PROXY_STATE_YES = 0x02, //!< Limit Proxy-State. Do not allow Proxy-State to be sent in
85  ///< packets which do not have a Message-Authenticator attribute.
86 
88 
89 typedef struct {
93 
94 typedef struct {
95  char const *secret;
96  size_t secret_length;
97 
98  bool secure_transport; //!< for TLS
99 
100  uint32_t proxy_state; //!< if so, this is its value
102 
103 typedef struct {
105 
107 
108  fr_fast_rand_t rand_ctx; //!< for tunnel passwords
109  int salt_offset; //!< for tunnel passwords
110 
111 
112  uint8_t tag; //!< current tag for encoding
113 
115 
118 
119  bool add_proxy_state; //!< do we add a Proxy-State?
120  bool disallow_tunnel_passwords; //!< not all packets can have tunnel passwords
123 
124 typedef struct {
126 
128 
129  TALLOC_CTX *tmp_ctx; //!< for temporary things cleaned up during decoding
130  uint8_t const *end; //!< end of the packet
131 
132  uint8_t request_code; //!< original code for the request.
133 
134  bool tunnel_password_zeros; //!< check for trailing zeros on decode
135  bool verify; //!< can skip verify for dynamic clients
137  bool limit_proxy_state; //!< Don't allow Proxy-State in requests
138 
139  fr_radius_tag_ctx_t **tags; //!< for decoding tagged attributes
140  fr_pair_list_t *tag_root; //!< Where to insert tag attributes.
141  TALLOC_CTX *tag_root_ctx; //!< Where to allocate new tag attributes.
143 
144 typedef enum {
145  RADIUS_FLAG_ENCRYPT_INVALID = -1, //!< Invalid encryption flag.
146  RADIUS_FLAG_ENCRYPT_NONE = 0, //!< No encryption.
147  RADIUS_FLAG_ENCRYPT_USER_PASSWORD = 1, //!< Encrypt attribute RFC 2865 style.
148  RADIUS_FLAG_ENCRYPT_TUNNEL_PASSWORD = 2, //!< Encrypt attribute RFC 2868 style.
149  RADIUS_FLAG_ENCRYPT_ASCEND_SECRET = 3, //!< Encrypt attribute ascend style.
151 
152 typedef struct {
153  unsigned int long_extended : 1; //!< Attribute is a long extended attribute
154  unsigned int extended : 1; //!< Attribute is an extended attribute
155  unsigned int concat : 1; //!< Attribute is concatenated
156  unsigned int has_tag : 1; //!< Attribute has a tag
157  unsigned int abinary : 1; //!< Attribute is in "abinary" format
158  fr_radius_attr_flags_encrypt_t encrypt; //!< Attribute is encrypted
160 
161 DIAG_OFF(unused-function)
162 /** Return RADIUS-specific flags for a given attribute
163  */
165 {
167 }
168 
169 #define fr_radius_flag_has_tag(_da) fr_radius_attr_flags(_da)->has_tag
170 #define fr_radius_flag_concat(_da) fr_radius_attr_flags(_da)->concat
171 #define fr_radius_flag_abinary(_da) fr_radius_attr_flags(_da)->abinary
172 #define fr_radius_flag_encrypted(_da) fr_radius_attr_flags(_da)->encrypt
173 
175 {
176  fr_radius_attr_flags_t const *flags = fr_radius_attr_flags(da);
177 
178  return flags->extended || flags->long_extended;
179 }
180 
181 #define fr_radius_flag_long_extended(_da) fr_radius_attr_flags(_da)->long_extended
182 DIAG_ON(unused-function)
183 
185 extern size_t fr_radius_require_ma_table_len;
186 
189 
192 
193 extern char const *fr_radius_packet_name[FR_RADIUS_CODE_MAX];
194 
195 /*
196  * protocols/radius/base.c
197  */
198 int fr_radius_allow_reply(int code, bool allowed[static FR_RADIUS_CODE_MAX]);
199 
200 int fr_radius_sign(uint8_t *packet, uint8_t const *vector,
201  uint8_t const *secret, size_t secret_len) CC_HINT(nonnull (1,3));
202 
203 int fr_radius_verify(uint8_t *packet, uint8_t const *vector,
204  uint8_t const *secret, size_t secret_len,
205  bool require_message_authenticator, bool limit_proxy_state) CC_HINT(nonnull (1,3));
206 
207 bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p,
208  uint32_t max_attributes, bool require_message_authenticator, decode_fail_t *reason) CC_HINT(nonnull (1,2));
209 
211  char const *secret, uint8_t const *vector);
212 
213 ssize_t fr_radius_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, unsigned int *code);
214 
216 
217 ssize_t fr_radius_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
218  uint8_t *packet, size_t packet_len,
219  fr_radius_decode_ctx_t *decode_ctx) CC_HINT(nonnull);
220 
222  uint8_t *packet, size_t packet_len,
223  uint8_t const *vector, char const *secret) CC_HINT(nonnull(1,2,3,6));
224 
225 int fr_radius_global_init(void);
226 
227 void fr_radius_global_free(void);
228 
229 /*
230  * protocols/radius/packet.c
231  */
233  fr_packet_t const *original,
234  char const *secret) CC_HINT(nonnull (1,2,4));
235 
236 bool fr_packet_ok(fr_packet_t *packet, uint32_t max_attributes, bool require_message_authenticator,
237  decode_fail_t *reason) CC_HINT(nonnull (1));
238 
239 int fr_packet_verify(fr_packet_t *packet, fr_packet_t *original,
240  char const *secret) CC_HINT(nonnull (1,3));
241 int fr_packet_sign(fr_packet_t *packet, fr_packet_t const *original,
242  char const *secret) CC_HINT(nonnull (1,3));
243 
244 fr_packet_t *fr_packet_recv(TALLOC_CTX *ctx, int fd, int flags, uint32_t max_attributes, bool require_message_authenticator);
245 int fr_packet_send(fr_packet_t *packet, fr_pair_list_t *list,
246  fr_packet_t const *original, char const *secret) CC_HINT(nonnull (1,2,4));
247 
248 #define fr_packet_log_hex(_log, _packet) _fr_packet_log_hex(_log, _packet, __FILE__, __LINE__)
249 void _fr_packet_log_hex(fr_log_t const *log, fr_packet_t const *packet, char const *file, int line) CC_HINT(nonnull);
250 
251 /*
252  * protocols/radius/abinary.c
253  */
255 
256 ssize_t fr_radius_decode_abinary(fr_pair_t *vp, uint8_t const *data, size_t data_len);
257 
258 /*
259  * protocols/radius/encode.c
260  */
262 
264 
265 /*
266  * protocols/radius/decode.c
267  */
268 int fr_radius_decode_tlv_ok(uint8_t const *data, size_t length, size_t dv_type, size_t dv_length);
269 
270 ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *list,
271  fr_dict_attr_t const *parent,
272  uint8_t const *data, size_t const attr_len,
273  void *packet_ctx) CC_HINT(nonnull);
274 
275 ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *list,
276  fr_dict_attr_t const *parent,
277  uint8_t const *data, size_t data_len,
278  fr_radius_decode_ctx_t *packet_ctx) CC_HINT(nonnull);
279 
280 ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *list,
281  uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx) CC_HINT(nonnull);
282 
284  uint8_t const *data, size_t data_len) CC_HINT(nonnull);
285 
286 void fr_radius_packet_header_log(fr_log_t const *log, fr_packet_t *packet, bool received);
287 
288 void fr_radius_packet_log(fr_log_t const *log, fr_packet_t *packet, fr_pair_list_t *list, bool received);
int const char * file
Definition: acutest.h:702
int const char int line
Definition: acutest.h:702
#define DIAG_ON(_x)
Definition: build.h:456
#define DIAG_OFF(_x)
Definition: build.h:455
@ FR_RADIUS_CODE_MAX
Maximum possible protocol code.
Definition: defs.h:53
static int sockfd
Definition: dhcpclient.c:56
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
Definition: dict.h:170
static fr_slen_t in
Definition: dict.h:821
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
Definition: dict_ext.h:140
IPv4/6 prefix.
Definition: merged_model.c:272
unsigned short uint16_t
Definition: merged_model.c:31
unsigned int uint32_t
Definition: merged_model.c:33
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
static fr_internal_encode_ctx_t encode_ctx
static char * secret
Definition: radclient-ng.c:69
unsigned int has_tag
Attribute has a tag.
Definition: radius.h:156
bool secure_transport
for TLS
Definition: radius.h:98
ssize_t fr_radius_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len)
Definition: decode.c:2088
fr_pair_t * parent
Definition: radius.h:90
fr_radius_tag_ctx_t ** tags
for decoding tagged attributes
Definition: radius.h:139
uint32_t proxy_state
if so, this is its value
Definition: radius.h:100
static fr_radius_attr_flags_t const * fr_radius_attr_flags(fr_dict_attr_t const *da)
Return RADIUS-specific flags for a given attribute.
Definition: radius.h:164
fr_radius_require_ma_t
Control whether Message-Authenticator is required in Access-Requests.
Definition: radius.h:62
@ FR_RADIUS_REQUIRE_MA_NO
Do not require Message-Authenticator.
Definition: radius.h:63
@ FR_RADIUS_REQUIRE_MA_YES
Require Message-Authenticator.
Definition: radius.h:68
@ FR_RADIUS_REQUIRE_MA_AUTO
Only require Message-Authenticator if we've previously received a packet from this client with Messag...
Definition: radius.h:64
fr_fast_rand_t rand_ctx
for tunnel passwords
Definition: radius.h:108
fr_radius_ctx_t const * common
Definition: radius.h:104
ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx)
Create a "normal" fr_pair_t from the given data.
Definition: decode.c:1983
uint8_t request_code
original code for the request.
Definition: radius.h:132
ssize_t fr_radius_decode_abinary(fr_pair_t *vp, uint8_t const *data, size_t data_len)
Print an Ascend binary filter attribute to a string,.
Definition: abinary.c:1322
ssize_t fr_radius_decode_simple(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t *packet, size_t packet_len, uint8_t const *vector, char const *secret))
Simple wrapper for callers who just need a shared secret.
Definition: base.c:1195
bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, uint32_t max_attributes, bool require_message_authenticator, decode_fail_t *reason))
See if the data pointed to by PTR is a valid RADIUS packet.
Definition: merged_model.c:259
uint8_t const * request_authenticator
Definition: radius.h:127
unsigned int abinary
Attribute is in "abinary" format.
Definition: radius.h:157
int fr_packet_sign(fr_packet_t *packet, fr_packet_t const *original, char const *secret))
Sign a previously encoded packet.
Definition: packet.c:164
ssize_t fr_radius_ascend_secret(fr_dbuff_t *dbuff, uint8_t const *in, size_t inlen, char const *secret, uint8_t const *vector)
Do Ascend-Send / Recv-Secret calculation.
Definition: base.c:247
ssize_t fr_radius_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t *packet, size_t packet_len, fr_radius_decode_ctx_t *decode_ctx)
Definition: base.c:1087
fr_dcursor_t cursor
Definition: radius.h:91
size_t fr_radius_limit_proxy_state_table_len
Definition: base.c:99
int fr_packet_verify(fr_packet_t *packet, fr_packet_t *original, char const *secret))
Verify the Request/Response Authenticator (and Message-Authenticator if present) of a packet.
Definition: packet.c:143
int fr_radius_sign(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len))
Sign a previously encoded packet.
Definition: base.c:358
bool disallow_tunnel_passwords
not all packets can have tunnel passwords
Definition: radius.h:120
char const * secret
Definition: radius.h:95
ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx)
Convert TLVs to one or more VPs.
Definition: decode.c:647
size_t fr_radius_require_ma_table_len
Definition: base.c:90
unsigned int concat
Attribute is concatenated.
Definition: radius.h:155
uint8_t const * end
end of the packet
Definition: radius.h:130
int fr_radius_global_init(void)
Definition: base.c:1217
int fr_packet_send(fr_packet_t *packet, fr_pair_list_t *list, fr_packet_t const *original, char const *secret))
Reply to the request.
Definition: packet.c:291
bool limit_proxy_state
Don't allow Proxy-State in requests.
Definition: radius.h:137
ssize_t fr_radius_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *encode_ctx)
Encode a data structure into a RADIUS attribute.
Definition: encode.c:1517
void fr_radius_packet_header_log(fr_log_t const *log, fr_packet_t *packet, bool received)
Definition: packet.c:420
uint8_t const * request_authenticator
Definition: radius.h:106
static bool fr_radius_flag_extended(fr_dict_attr_t const *da)
Definition: radius.h:174
uint8_t tag
current tag for encoding
Definition: radius.h:112
unsigned int extended
Attribute is an extended attribute.
Definition: radius.h:154
fr_radius_attr_flags_encrypt_t encrypt
Attribute is encrypted.
Definition: radius.h:158
int fr_radius_decode_tlv_ok(uint8_t const *data, size_t length, size_t dv_type, size_t dv_length)
Check if a set of RADIUS formatted TLVs are OK.
Definition: decode.c:250
bool require_message_authenticator
Definition: radius.h:136
void _fr_packet_log_hex(fr_log_t const *log, fr_packet_t const *packet, char const *file, int line)
Definition: packet.c:349
fr_packet_t * fr_packet_recv(TALLOC_CTX *ctx, int fd, int flags, uint32_t max_attributes, bool require_message_authenticator)
Receive UDP client requests, and fill in the basics of a fr_packet_t structure.
Definition: packet.c:205
TALLOC_CTX * tag_root_ctx
Where to allocate new tag attributes.
Definition: radius.h:141
size_t secret_length
Definition: radius.h:96
size_t fr_radius_request_name_table_len
Definition: base.c:110
ssize_t fr_radius_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list)
Definition: encode.c:1682
uint8_t request_code
Definition: radius.h:114
ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *parent, uint8_t const *data, size_t const attr_len, void *packet_ctx)
Create any kind of VP from the attribute contents.
Definition: decode.c:1475
bool verify
can skip verify for dynamic clients
Definition: radius.h:135
bool fr_packet_ok(fr_packet_t *packet, uint32_t max_attributes, bool require_message_authenticator, decode_fail_t *reason))
See if the data pointed to by PTR is a valid RADIUS packet.
Definition: packet.c:119
fr_radius_ctx_t const * common
Definition: radius.h:125
int fr_radius_verify(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len, bool require_message_authenticator, bool limit_proxy_state))
Verify a request / response packet.
Definition: base.c:777
void fr_radius_global_free(void)
Definition: base.c:1240
fr_radius_limit_proxy_state_t
Control whether Proxy-State is allowed in Access-Requests.
Definition: radius.h:76
@ FR_RADIUS_LIMIT_PROXY_STATE_NO
Do not limit Proxy-State.
Definition: radius.h:77
@ FR_RADIUS_LIMIT_PROXY_STATE_AUTO
Do not allow Proxy-State unless:
Definition: radius.h:79
@ FR_RADIUS_LIMIT_PROXY_STATE_YES
Limit Proxy-State.
Definition: radius.h:84
unsigned int long_extended
Attribute is a long extended attribute.
Definition: radius.h:153
fr_table_num_sorted_t const fr_radius_limit_proxy_state_table[]
Definition: base.c:92
fr_radius_attr_flags_encrypt_t
Definition: radius.h:144
@ RADIUS_FLAG_ENCRYPT_INVALID
Invalid encryption flag.
Definition: radius.h:145
@ RADIUS_FLAG_ENCRYPT_NONE
No encryption.
Definition: radius.h:146
@ RADIUS_FLAG_ENCRYPT_USER_PASSWORD
Encrypt attribute RFC 2865 style.
Definition: radius.h:147
@ RADIUS_FLAG_ENCRYPT_ASCEND_SECRET
Encrypt attribute ascend style.
Definition: radius.h:149
@ RADIUS_FLAG_ENCRYPT_TUNNEL_PASSWORD
Encrypt attribute RFC 2868 style.
Definition: radius.h:148
ssize_t fr_radius_encode_abinary(fr_pair_t const *vp, fr_dbuff_t *dbuff)
Encode a string to abinary.
Definition: abinary.c:1198
fr_table_num_sorted_t const fr_radius_request_name_table[]
Definition: base.c:101
fr_table_num_sorted_t const fr_radius_require_ma_table[]
Definition: base.c:83
int salt_offset
for tunnel passwords
Definition: radius.h:109
ssize_t fr_radius_encode(fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_radius_encode_ctx_t *packet_ctx)
Definition: base.c:952
ssize_t fr_packet_encode(fr_packet_t *packet, fr_pair_list_t *list, fr_packet_t const *original, char const *secret))
Encode a packet.
Definition: packet.c:52
bool tunnel_password_zeros
check for trailing zeros on decode
Definition: radius.h:134
bool add_proxy_state
do we add a Proxy-State?
Definition: radius.h:119
bool seen_message_authenticator
Definition: radius.h:121
void fr_radius_packet_log(fr_log_t const *log, fr_packet_t *packet, fr_pair_list_t *list, bool received)
Definition: packet.c:491
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
Definition: base.c:112
ssize_t fr_radius_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, unsigned int *code)
Basic validation of RADIUS packet header.
Definition: base.c:285
TALLOC_CTX * tmp_ctx
for temporary things cleaned up during decoding
Definition: radius.h:129
fr_pair_list_t * tag_root
Where to insert tag attributes.
Definition: radius.h:140
int fr_radius_allow_reply(int code, bool allowed[static FR_RADIUS_CODE_MAX])
Definition: base.c:227
Smaller fast random number generator.
Definition: rand.h:54
fr_pair_t * vp
Definition: log.h:96
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
An element in a lexicographically sorted array of name to num mappings.
Definition: table.h:49
static fr_slen_t parent
Definition: pair.h:851
static fr_slen_t data
Definition: value.h:1265
static size_t char fr_sbuff_t size_t inlen
Definition: value.h:997
int nonnull(2, 5))
static size_t char ** out
Definition: value.h:997