The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
rlm_wimax.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 5ff45d12dab4104b139d6caf044223b201523da0 $
19 * @file rlm_wimax.c
20 * @brief Supports various WiMax functionality.
21 *
22 * @copyright 2008 Alan DeKok (aland@networkradius.com)
23 */
24RCSID("$Id: 5ff45d12dab4104b139d6caf044223b201523da0 $")
25USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
26
27#define LOG_PREFIX "wimax"
28
29#include <freeradius-devel/server/base.h>
30#include <freeradius-devel/server/module_rlm.h>
31#include <freeradius-devel/tls/base.h>
32#include <freeradius-devel/util/base16.h>
33
34/*
35 * FIXME: Add check for this header to configure.ac
36 */
37#include <openssl/hmac.h>
38
39/*
40 * FIXME: Fix the build system to create definitions from names.
41 */
42typedef struct {
45
46static const conf_parser_t module_config[] = {
47 { FR_CONF_OFFSET("delete_mppe_keys", rlm_wimax_t, delete_mppe_keys), .dflt = "no" },
49};
50
51static fr_dict_t const *dict_radius;
53
56 { .out = &dict_radius, .proto = "radius" },
57 { .out = &dict_freeradius, .proto = "freeradius" },
59};
60
64
66
81
84
87 { .out = &attr_eap_emsk, .name = "EAP-EMSK", .type = FR_TYPE_OCTETS, .dict = &dict_freeradius },
88 { .out = &attr_eap_msk, .name = "EAP-MSK", .type = FR_TYPE_OCTETS, .dict = &dict_freeradius },
89 { .out = &attr_wimax_mn_nai, .name = "WiMAX-MN-NAI", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
90
91 { .out = &attr_calling_station_id, .name = "Calling-Station-ID", .type = FR_TYPE_STRING, .dict = &dict_radius },
92
93 /*
94 * Load the WiMAX VSA. The children are all found under this root.
95 */
96 { .out = &attr_wimax, .name = "Vendor-Specific.WiMAX", .type = FR_TYPE_VENDOR, .dict = &dict_radius },
97
98 /*
99 * Relative names are shorter.
100 */
101 { .out = &attr_wimax_msk, .name = ".MSK", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
102 { .out = &attr_wimax_ip_technology, .name = ".IP-Technology", .type = FR_TYPE_UINT32, .dict = &dict_radius },
103 { .out = &attr_wimax_mn_hha_mip4_key, .name = ".MN-hHA-MIP4-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
104 { .out = &attr_wimax_mn_hha_mip4_spi, .name = ".MN-hHA-MIP4-SPI", .type = FR_TYPE_UINT32, .dict = &dict_radius },
105 { .out = &attr_wimax_hha_ip_mip4, .name = ".hHA-IP-MIP4", .type = FR_TYPE_IPV4_ADDR, .dict = &dict_radius },
106 { .out = &attr_wimax_hha_ip_mip6, .name = ".hHA-IP-MIP6", .type = FR_TYPE_IPV6_ADDR, .dict = &dict_radius },
107 { .out = &attr_wimax_mn_hha_mip6_key, .name = ".MN-hHA-MIP6-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
108 { .out = &attr_wimax_mn_hha_mip6_spi, .name = ".MN-hHA-MIP6-SPI", .type = FR_TYPE_UINT32, .dict = &dict_radius },
109 { .out = &attr_wimax_fa_rk_key, .name = ".FA-RK-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
110 { .out = &attr_wimax_fa_rk_spi, .name = ".FA-RK-SPI", .type = FR_TYPE_UINT32, .dict = &dict_radius },
111 { .out = &attr_wimax_rrq_mn_ha_spi, .name = ".RRQ-MN-HA-SPI", .type = FR_TYPE_UINT32, .dict = &dict_radius },
112 { .out = &attr_wimax_rrq_ha_ip, .name = ".RRQ-HA-IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_radius },
113 { .out = &attr_wimax_ha_rk_key_requested, .name = ".HA-RK-Key-Requested", .type = FR_TYPE_UINT32, .dict = &dict_radius },
114
115 { .out = &attr_ms_mppe_send_key, .name = "Vendor-Specific.Microsoft.MPPE-Send-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
116 { .out = &attr_ms_mppe_recv_key, .name = "Vendor-Specific.Microsoft.MPPE-Recv-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
117
119};
120
121/*
122 * Find the named user in this modules database. Create the set
123 * of attribute-value pairs to check and reply with for this user
124 * from the database. The authentication code only needs to check
125 * the password, the rest is done here.
126 */
127static unlang_action_t CC_HINT(nonnull) mod_authorize(unlang_result_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
128{
129 fr_pair_t *vp;
130
131 /*
132 * Fix Calling-Station-Id. Damn you, WiMAX!
133 */
134 vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_calling_station_id);
135 if (vp && (vp->vp_length == 6)) {
136 int i;
137 char *p;
138 uint8_t buffer[6];
139
140 memcpy(buffer, vp->vp_strvalue, 6);
141
142 MEM(fr_pair_value_bstr_realloc(vp, &p, (5 * 3) + 2) == 0);
143
144 /*
145 * RFC 3580 Section 3.20 says this is the preferred
146 * format. Everyone *SANE* is using this format,
147 * so we fix it here.
148 */
149 for (i = 0; i < 6; i++) {
150 fr_base16_encode(&FR_SBUFF_OUT(&p[i * 3], 2 + 1), &FR_DBUFF_TMP(&buffer[i], 1));
151 if (i < 5) p[(i * 3) + 2] = '-';
152 }
153
154 DEBUG2("Fixing WiMAX binary Calling-Station-Id to %pV", &vp->data);
156 }
157
159}
160
161/*
162 * Massage the request before recording it or proxying it
163 */
164static unlang_action_t CC_HINT(nonnull) mod_preacct(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
165{
166 return mod_authorize(p_result, mctx, request);
167}
168
169/*
170 * Generate the keys after the user has been authenticated.
171 */
172static unlang_action_t CC_HINT(nonnull) mod_post_auth(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
173{
175 fr_pair_t *msk, *emsk, *vp;
176 fr_pair_t *mn_nai, *ip, *fa_rk;
177 fr_pair_t *vsa_request, *vsa_reply;
178 EVP_MD_CTX *hmac_ctx;
179 EVP_PKEY *hmac_pkey;
180 uint32_t mip_spi;
181 uint8_t usage_data[24];
182 uint8_t mip_rk_1[EVP_MAX_MD_SIZE], mip_rk_2[EVP_MAX_MD_SIZE];
183 uint8_t mip_rk[2 * EVP_MAX_MD_SIZE];
184 size_t rk1_len = sizeof(mip_rk_1), rk2_len = sizeof(mip_rk_2), rk_len = sizeof(mip_rk);
185
186 msk = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_eap_msk);
187 emsk = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_eap_emsk);
188 if (!msk || !emsk) {
189 REDEBUG2("No EAP-MSK or EAP-EMSK. Cannot create WiMAX keys");
191 }
192
193 /*
194 * If there's no WiMAX VSAs on input or output, we do nothing.
195 */
196 vsa_request = fr_pair_find_by_da_nested(&request->reply_pairs, attr_wimax);
197 vsa_reply = fr_pair_find_by_da_nested(&request->reply_pairs, attr_wimax);
198 if (!vsa_request && !vsa_reply) {
199 RWDEBUG("Vendor-Specific.WiMAX not found in request or reply list, skipping all WiMAX calculations");
201 }
202
203 /*
204 * If we delete the MS-MPPE-*-Key attributes, then add in
205 * the WiMAX-MSK so that the client has a key available.
206 */
207 if (inst->delete_mppe_keys) {
210
212 fr_pair_value_memdup(vp, msk->vp_octets, msk->vp_length, false);
213 }
214
215 /*
216 * Initialize usage data.
217 */
218 memcpy(usage_data, "miprk@wimaxforum.org", 21); /* with trailing \0 */
219 usage_data[21] = 0x02;
220 usage_data[22] = 0x00;
221 usage_data[23] = 0x01;
222
223 /*
224 * MIP-RK-1 = HMAC-SSHA256(EMSK, usage-data | 0x01)
225 */
226 MEM(hmac_ctx = EVP_MD_CTX_new());
227 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, emsk->vp_octets, emsk->vp_length));
228 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
229
230 EVP_DigestSignUpdate(hmac_ctx, &usage_data[0], sizeof(usage_data));
231 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
232
233 /*
234 * MIP-RK-2 = HMAC-SSHA256(EMSK, MIP-RK-1 | usage-data | 0x01)
235 */
236 EVP_MD_CTX_reset(hmac_ctx);
237 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
238
239 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &mip_rk_1, rk1_len);
240 EVP_DigestSignUpdate(hmac_ctx, &usage_data[0], sizeof(usage_data));
241 EVP_DigestSignFinal(hmac_ctx, &mip_rk_2[0], &rk2_len);
242
243 memcpy(mip_rk, mip_rk_1, rk1_len);
244 memcpy(mip_rk + rk1_len, mip_rk_2, rk2_len);
245 rk_len = rk1_len + rk2_len;
246
247 /*
248 * MIP-SPI = HMAC-SSHA256(MIP-RK, "SPI CMIP PMIP");
249 */
250 EVP_MD_CTX_reset(hmac_ctx);
251 EVP_PKEY_free(hmac_pkey); /* No way to reset ? */
252 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, mip_rk, rk_len));
253 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
254
255 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) "SPI CMIP PMIP", 13);
256 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
257
258 /*
259 * Take the 4 most significant octets.
260 * If less than 256, add 256.
261 */
262 mip_spi = fr_nbo_to_uint32(mip_rk_1);
263 if (mip_spi < 256) mip_spi += 256;
264
265 REDEBUG2("MIP-RK = 0x%pH", fr_box_octets(mip_rk, rk_len));
266 REDEBUG2("MIP-SPI = %08x", ntohl(mip_spi));
267
268 /*
269 * FIXME: Perform SPI collision prevention
270 */
271
272 /*
273 * Calculate mobility keys
274 */
275 mn_nai = fr_pair_find_by_da(&request->request_pairs, NULL, attr_wimax_mn_nai);
276 if (!mn_nai) mn_nai = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_wimax_mn_nai);
277 if (!mn_nai) {
278 RWDEBUG("%s was not found in the request or in the reply", attr_wimax_mn_nai->name);
279 RWDEBUG("We cannot calculate MN-HA keys");
280 }
281
282 if (!vsa_reply) {
283 RWDEBUG("reply.Vendor-Specific.WiMAX was not found - not calculating WiMAX keys");
284 goto check_request;
285 }
286
287 /*
288 * WiMAX-IP-Technology
289 */
290 vp = NULL;
291 if (mn_nai) vp = fr_pair_find_by_da(&vsa_reply->vp_group, NULL, attr_wimax_ip_technology);
292 if (!vp) {
293 RWDEBUG("%s not found in reply", attr_wimax_ip_technology->name);
294 RWDEBUG("Not calculating MN-HA keys");
295 }
296
297 if (vp) switch (vp->vp_uint32) {
298 case 2: /* PMIP4 */
299 /*
300 * Look for WiMAX-hHA-IP-MIP4
301 */
302 ip = fr_pair_find_by_da(&vsa_reply->vp_group, NULL, attr_wimax_hha_ip_mip4);
303 if (!ip) {
304 RWDEBUG("%s not found. Cannot calculate MN-HA-PMIP4 key", attr_wimax_hha_ip_mip4->name);
305 break;
306 }
307
308 /*
309 * MN-HA-PMIP4 =
310 * H(MIP-RK, "PMIP4 MN HA" | HA-IPv4 | MN-NAI);
311 */
312 EVP_MD_CTX_reset(hmac_ctx);
313 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha1(), NULL, hmac_pkey);
314
315 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) "PMIP4 MN HA", 11);
316 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &ip->vp_ipv4addr, 4);
317 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &mn_nai->vp_strvalue, mn_nai->vp_length);
318 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
319
320 /*
321 * Put MN-HA-PMIP4 into WiMAX-MN-hHA-MIP4-Key
322 */
324 fr_pair_value_memdup(vp, &mip_rk_1[0], rk1_len, false);
325
326 /*
327 * Put MN-HA-PMIP4-SPI into WiMAX-MN-hHA-MIP4-SPI
328 */
330 vp->vp_uint32 = mip_spi + 1;
331 break;
332
333 case 3: /* CMIP4 */
334 /*
335 * Look for WiMAX-hHA-IP-MIP4
336 */
337 ip = fr_pair_find_by_da(&vsa_reply->vp_group, NULL, attr_wimax_hha_ip_mip4);
338 if (!ip) {
339 RWDEBUG("%s not found. Cannot calculate MN-HA-CMIP4 key", attr_wimax_hha_ip_mip4->name);
340 break;
341 }
342
343 /*
344 * MN-HA-CMIP4 =
345 * H(MIP-RK, "CMIP4 MN HA" | HA-IPv4 | MN-NAI);
346 */
347 EVP_MD_CTX_reset(hmac_ctx);
348 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha1(), NULL, hmac_pkey);
349
350 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) "CMIP4 MN HA", 11);
351 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &ip->vp_ipv4addr, 4);
352 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &mn_nai->vp_strvalue, mn_nai->vp_length);
353 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
354
355 /*
356 * Put MN-HA-CMIP4 into WiMAX-MN-hHA-MIP4-Key
357 */
359 fr_pair_value_memdup(vp, &mip_rk_1[0], rk1_len, false);
360
361 /*
362 * Put MN-HA-CMIP4-SPI into WiMAX-MN-hHA-MIP4-SPI
363 */
365 vp->vp_uint32 = mip_spi;
366 break;
367
368 case 4: /* CMIP6 */
369 /*
370 * Look for WiMAX-hHA-IP-MIP6
371 */
372 ip = fr_pair_find_by_da(&vsa_reply->vp_group, NULL, attr_wimax_hha_ip_mip6);
373 if (!ip) {
374 RWDEBUG("%s not found. Cannot calculate MN-HA-CMIP6 key", attr_wimax_hha_ip_mip6->name);
375 break;
376 }
377
378 /*
379 * MN-HA-CMIP6 =
380 * H(MIP-RK, "CMIP6 MN HA" | HA-IPv6 | MN-NAI);
381 */
382 EVP_MD_CTX_reset(hmac_ctx);
383 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha1(), NULL, hmac_pkey);
384
385 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) "CMIP6 MN HA", 11);
386 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &ip->vp_ipv6addr, 16);
387 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &mn_nai->vp_strvalue, mn_nai->vp_length);
388 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
389
390 /*
391 * Put MN-HA-CMIP6 into WiMAX-MN-hHA-MIP6-Key
392 */
394 fr_pair_value_memdup(vp, &mip_rk_1[0], rk1_len, false);
395
396 /*
397 * Put MN-HA-CMIP6-SPI into WiMAX-MN-hHA-MIP6-SPI
398 */
400 vp->vp_uint32 = mip_spi + 2;
401 break;
402
403 default:
404 break; /* do nothing */
405 }
406
407 /*
408 * Generate FA-RK, if requested.
409 *
410 * FA-RK= H(MIP-RK, "FA-RK")
411 */
412 fa_rk = fr_pair_find_by_da(&vsa_reply->vp_group, NULL, attr_wimax_fa_rk_key);
413 if (fa_rk && (fa_rk->vp_length <= 1)) {
414 EVP_MD_CTX_reset(hmac_ctx);
415 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha1(), NULL, hmac_pkey);
416
417 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) "FA-RK", 5);
418
419 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
420
421 fr_pair_value_memdup(fa_rk, &mip_rk_1[0], rk1_len, false);
422 }
423
424 /*
425 * Create FA-RK-SPI, which is really SPI-CMIP4, which is
426 * really MIP-SPI. Clear? Of course. This is WiMAX.
427 */
428 if (fa_rk) {
430 vp->vp_uint32 = mip_spi;
431 }
432
433 /*
434 * Give additional information about requests && responses
435 *
436 * WiMAX-RRQ-MN-HA-SPI
437 */
438check_request:
439 if (vsa_request) {
440 vp = fr_pair_find_by_da(&vsa_request->vp_group, NULL, attr_wimax_rrq_mn_ha_spi);
441 if (vp) {
442 REDEBUG2("Client requested MN-HA key: Should use SPI to look up key from storage");
443 if (!mn_nai) {
444 RWDEBUG("MN-NAI was not found!");
445 }
446
447 /*
448 * WiMAX-RRQ-HA-IP
449 */
450 if (!fr_pair_find_by_da(&vsa_request->vp_group, NULL, attr_wimax_rrq_ha_ip)) {
451 RWDEBUG("HA-IP was not found!");
452 }
453
454 /*
455 * WiMAX-HA-RK-Key-Requested
456 */
457 vp = fr_pair_find_by_da(&vsa_request->vp_group, NULL, attr_wimax_ha_rk_key_requested);
458 if (vp && (vp->vp_uint32 == 1)) {
459 REDEBUG2("Client requested HA-RK: Should use IP to look it up from storage");
460 }
461 }
462 }
463
464 /*
465 * Wipe the context of all sensitive information.
466 */
467 EVP_MD_CTX_free(hmac_ctx);
468 EVP_PKEY_free(hmac_pkey);
469
471}
472
473/*
474 * The module name should be the only globally exported symbol.
475 * That is, everything else should be 'static'.
476 *
477 * If the module needs to temporarily modify it's instantiation
478 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
479 * The server will then take care of ensuring that the module
480 * is single-threaded.
481 */
484 .common = {
485 .magic = MODULE_MAGIC_INIT,
486 .name = "wimax",
487 .inst_size = sizeof(rlm_wimax_t),
489 },
490 .method_group = {
491 .bindings = (module_method_binding_t[]){
492 { .section = SECTION_NAME("recv", "Accounting-Request"), .method = mod_preacct },
493 { .section = SECTION_NAME("recv", CF_IDENT_ANY), .method = mod_authorize },
494 { .section = SECTION_NAME("send", CF_IDENT_ANY), .method = mod_post_auth },
496 }
497 }
498};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
static int const char char buffer[256]
Definition acutest.h:576
#define fr_base16_encode(_out, _in)
Definition base16.h:71
#define USES_APPLE_DEPRECATED_API
Definition build.h:547
#define RCSID(id)
Definition build.h:560
#define UNUSED
Definition build.h:384
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:669
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:280
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:606
#define CF_IDENT_ANY
Definition cf_util.h:80
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
Definition dbuff.h:522
#define MEM(x)
Definition debug.h:38
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:316
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:329
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:335
Specifies an attribute which must be present for the module to function.
Definition dict.h:315
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:328
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
#define RWDEBUG(fmt,...)
Definition log.h:378
#define REDEBUG2(fmt,...)
Definition log.h:389
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_VENDOR
Attribute that represents a vendor in the attribute tree.
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
@ FR_TYPE_OCTETS
Raw octets.
unsigned int uint32_t
unsigned char uint8_t
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
static uint32_t fr_nbo_to_uint32(uint8_t const data[static sizeof(uint32_t)])
Read an unsigned 32bit integer from wire format (big endian)
Definition nbo.h:167
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
Definition pair.c:2894
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_dict_attr_t const *da)
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
Definition pair.c:783
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition pair.c:708
int fr_pair_value_bstr_realloc(fr_pair_t *vp, char **out, size_t size)
Change the length of a buffer for a "string" type value pair.
Definition pair.c:2716
static const conf_parser_t config[]
Definition base.c:162
#define DEBUG2(fmt,...)
#define RETURN_UNLANG_UPDATED
Definition rcode.h:70
#define RETURN_UNLANG_OK
Definition rcode.h:64
#define RETURN_UNLANG_NOOP
Definition rcode.h:69
fr_dict_autoload_t rlm_wimax_dict[]
Definition rlm_wimax.c:55
static fr_dict_attr_t const * attr_wimax_fa_rk_key
Definition rlm_wimax.c:76
static fr_dict_attr_t const * attr_wimax_fa_rk_spi
Definition rlm_wimax.c:77
static fr_dict_attr_t const * attr_wimax_rrq_ha_ip
Definition rlm_wimax.c:79
static fr_dict_attr_t const * attr_wimax_hha_ip_mip4
Definition rlm_wimax.c:72
static unlang_action_t mod_post_auth(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_wimax.c:172
bool delete_mppe_keys
Definition rlm_wimax.c:43
static unlang_action_t mod_authorize(unlang_result_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
Definition rlm_wimax.c:127
static fr_dict_attr_t const * attr_eap_msk
Definition rlm_wimax.c:62
static fr_dict_t const * dict_freeradius
Definition rlm_wimax.c:52
static fr_dict_attr_t const * attr_wimax
Definition rlm_wimax.c:67
static fr_dict_attr_t const * attr_wimax_mn_hha_mip4_spi
Definition rlm_wimax.c:71
static fr_dict_attr_t const * attr_calling_station_id
Definition rlm_wimax.c:65
static fr_dict_attr_t const * attr_wimax_hha_ip_mip6
Definition rlm_wimax.c:73
static fr_dict_t const * dict_radius
Definition rlm_wimax.c:51
static fr_dict_attr_t const * attr_wimax_mn_hha_mip6_key
Definition rlm_wimax.c:74
static fr_dict_attr_t const * attr_wimax_mn_nai
Definition rlm_wimax.c:63
static fr_dict_attr_t const * attr_eap_emsk
Definition rlm_wimax.c:61
static fr_dict_attr_t const * attr_wimax_mn_hha_mip4_key
Definition rlm_wimax.c:70
static fr_dict_attr_t const * attr_ms_mppe_send_key
Definition rlm_wimax.c:82
static unlang_action_t mod_preacct(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_wimax.c:164
fr_dict_attr_autoload_t rlm_wimax_dict_attr[]
Definition rlm_wimax.c:86
static fr_dict_attr_t const * attr_wimax_rrq_mn_ha_spi
Definition rlm_wimax.c:78
static fr_dict_attr_t const * attr_wimax_msk
Definition rlm_wimax.c:68
static fr_dict_attr_t const * attr_ms_mppe_recv_key
Definition rlm_wimax.c:83
module_rlm_t rlm_wimax
Definition rlm_wimax.c:483
static const conf_parser_t module_config[]
Definition rlm_wimax.c:46
static fr_dict_attr_t const * attr_wimax_ip_technology
Definition rlm_wimax.c:69
static fr_dict_attr_t const * attr_wimax_ha_rk_key_requested
Definition rlm_wimax.c:80
static fr_dict_attr_t const * attr_wimax_mn_hha_mip6_spi
Definition rlm_wimax.c:75
#define FR_SBUFF_OUT(_start, _len_or_end)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:39
size_t inst_size
Size of the module's instance data.
Definition module.h:212
void * data
Module's instance data.
Definition module.h:295
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:152
Named methods exported by a module.
Definition module.h:174
#define pair_update_reply(_attr, _da)
Return or allocate a fr_pair_t in the reply list.
Definition pair.h:129
#define pair_delete_reply(_pair_or_da)
Delete a fr_pair_t in the reply list.
Definition pair.h:181
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
#define talloc_get_type_abort_const
Definition talloc.h:117
int nonnull(2, 5))
#define fr_box_octets(_val, _len)
Definition value.h:336