The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_wimax.c
Go to the documentation of this file.
1/*
2 * This program is 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: 856d8f7e893e873ec02f6bd23194dcfc0f1414c8 $
19 * @file rlm_wimax.c
20 * @brief Supports various WiMax functionality.
21 *
22 * @copyright 2008 Alan DeKok (aland@networkradius.com)
23 */
24RCSID("$Id: 856d8f7e893e873ec02f6bd23194dcfc0f1414c8 $")
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 <freeradius-devel/tls/openssl_user_macros.h>
38#include <openssl/hmac.h>
39
40/*
41 * FIXME: Fix the build system to create definitions from names.
42 */
43typedef struct {
46
47static const conf_parser_t module_config[] = {
48 { FR_CONF_OFFSET("delete_mppe_keys", rlm_wimax_t, delete_mppe_keys), .dflt = "no" },
50};
51
52static fr_dict_t const *dict_radius;
54
57 { .out = &dict_radius, .proto = "radius" },
58 { .out = &dict_freeradius, .proto = "freeradius" },
59 { NULL }
60};
61
65
67
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 { .out = &attr_wimax_msk, .name = "Vendor-Specific.WiMAX.MSK", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
94 { .out = &attr_wimax_ip_technology, .name = "Vendor-Specific.WiMAX.IP-Technology", .type = FR_TYPE_UINT32, .dict = &dict_radius },
95 { .out = &attr_wimax_mn_hha_mip4_key, .name = "Vendor-Specific.WiMAX.MN-hHA-MIP4-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
96 { .out = &attr_wimax_mn_hha_mip4_spi, .name = "Vendor-Specific.WiMAX.MN-hHA-MIP4-SPI", .type = FR_TYPE_UINT32, .dict = &dict_radius },
97 { .out = &attr_wimax_hha_ip_mip4, .name = "Vendor-Specific.WiMAX.hHA-IP-MIP4", .type = FR_TYPE_IPV4_ADDR, .dict = &dict_radius },
98 { .out = &attr_wimax_hha_ip_mip6, .name = "Vendor-Specific.WiMAX.hHA-IP-MIP6", .type = FR_TYPE_IPV6_ADDR, .dict = &dict_radius },
99 { .out = &attr_wimax_mn_hha_mip6_key, .name = "Vendor-Specific.WiMAX.MN-hHA-MIP6-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
100 { .out = &attr_wimax_mn_hha_mip6_spi, .name = "Vendor-Specific.WiMAX.MN-hHA-MIP6-SPI", .type = FR_TYPE_UINT32, .dict = &dict_radius },
101 { .out = &attr_wimax_fa_rk_key, .name = "Vendor-Specific.WiMAX.FA-RK-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
102 { .out = &attr_wimax_fa_rk_spi, .name = "Vendor-Specific.WiMAX.FA-RK-SPI", .type = FR_TYPE_UINT32, .dict = &dict_radius },
103 { .out = &attr_wimax_rrq_mn_ha_spi, .name = "Vendor-Specific.WiMAX.RRQ-MN-HA-SPI", .type = FR_TYPE_UINT32, .dict = &dict_radius },
104 { .out = &attr_wimax_rrq_ha_ip, .name = "Vendor-Specific.WiMAX.RRQ-HA-IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_radius },
105 { .out = &attr_wimax_ha_rk_key_requested, .name = "Vendor-Specific.WiMAX.HA-RK-Key-Requested", .type = FR_TYPE_UINT32, .dict = &dict_radius },
106
107 { .out = &attr_ms_mppe_send_key, .name = "Vendor-Specific.Microsoft.MPPE-Send-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
108 { .out = &attr_ms_mppe_recv_key, .name = "Vendor-Specific.Microsoft.MPPE-Recv-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
109
110 { NULL }
111};
112
113/*
114 * Find the named user in this modules database. Create the set
115 * of attribute-value pairs to check and reply with for this user
116 * from the database. The authentication code only needs to check
117 * the password, the rest is done here.
118 */
119static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
120{
121 fr_pair_t *vp;
122
123 /*
124 * Fix Calling-Station-Id. Damn you, WiMAX!
125 */
126 vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_calling_station_id);
127 if (vp && (vp->vp_length == 6)) {
128 int i;
129 char *p;
130 uint8_t buffer[6];
131
132 memcpy(buffer, vp->vp_strvalue, 6);
133
134 MEM(fr_pair_value_bstr_realloc(vp, &p, (5 * 3) + 2) == 0);
135
136 /*
137 * RFC 3580 Section 3.20 says this is the preferred
138 * format. Everyone *SANE* is using this format,
139 * so we fix it here.
140 */
141 for (i = 0; i < 6; i++) {
142 fr_base16_encode(&FR_SBUFF_OUT(&p[i * 3], 2 + 1), &FR_DBUFF_TMP(&buffer[i], 1));
143 p[(i * 3) + 2] = '-';
144 }
145
146 DEBUG2("Fixing WiMAX binary Calling-Station-Id to %pV", &vp->data);
148 }
149
151}
152
153/*
154 * Massage the request before recording it or proxying it
155 */
156static unlang_action_t CC_HINT(nonnull) mod_preacct(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
157{
158 return mod_authorize(p_result, mctx, request);
159}
160
161/*
162 * Generate the keys after the user has been authenticated.
163 */
164static unlang_action_t CC_HINT(nonnull) mod_post_auth(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
165{
167 fr_pair_t *msk, *emsk, *vp;
168 fr_pair_t *mn_nai, *ip, *fa_rk;
169 EVP_MD_CTX *hmac_ctx;
170 EVP_PKEY *hmac_pkey;
171 uint32_t mip_spi;
172 uint8_t usage_data[24];
173 uint8_t mip_rk_1[EVP_MAX_MD_SIZE], mip_rk_2[EVP_MAX_MD_SIZE];
174 uint8_t mip_rk[2 * EVP_MAX_MD_SIZE];
175 size_t rk1_len = sizeof(mip_rk_1), rk2_len = sizeof(mip_rk_2), rk_len = sizeof(mip_rk);
176
177 msk = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_eap_msk);
178 emsk = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_eap_emsk);
179 if (!msk || !emsk) {
180 REDEBUG2("No EAP-MSK or EAP-EMSK. Cannot create WiMAX keys");
182 }
183
184 /*
185 * If we delete the MS-MPPE-*-Key attributes, then add in
186 * the WiMAX-MSK so that the client has a key available.
187 */
188 if (inst->delete_mppe_keys) {
191
193 fr_pair_value_memdup(vp, msk->vp_octets, msk->vp_length, false);
194 }
195
196 /*
197 * Initialize usage data.
198 */
199 memcpy(usage_data, "miprk@wimaxforum.org", 21); /* with trailing \0 */
200 usage_data[21] = 0x02;
201 usage_data[22] = 0x00;
202 usage_data[23] = 0x01;
203
204 /*
205 * MIP-RK-1 = HMAC-SSHA256(EMSK, usage-data | 0x01)
206 */
207 MEM(hmac_ctx = EVP_MD_CTX_new());
208 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, emsk->vp_octets, emsk->vp_length));
209 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
210
211 EVP_DigestSignUpdate(hmac_ctx, &usage_data[0], sizeof(usage_data));
212 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
213
214 /*
215 * MIP-RK-2 = HMAC-SSHA256(EMSK, MIP-RK-1 | usage-data | 0x01)
216 */
217 EVP_MD_CTX_reset(hmac_ctx);
218 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
219
220 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &mip_rk_1, rk1_len);
221 EVP_DigestSignUpdate(hmac_ctx, &usage_data[0], sizeof(usage_data));
222 EVP_DigestSignFinal(hmac_ctx, &mip_rk_2[0], &rk2_len);
223
224 memcpy(mip_rk, mip_rk_1, rk1_len);
225 memcpy(mip_rk + rk1_len, mip_rk_2, rk2_len);
226 rk_len = rk1_len + rk2_len;
227
228 /*
229 * MIP-SPI = HMAC-SSHA256(MIP-RK, "SPI CMIP PMIP");
230 */
231 EVP_MD_CTX_reset(hmac_ctx);
232 EVP_PKEY_free(hmac_pkey); /* No way to reset ? */
233 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, mip_rk, rk_len));
234 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
235
236 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) "SPI CMIP PMIP", 12);
237 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
238
239 /*
240 * Take the 4 most significant octets.
241 * If less than 256, add 256.
242 */
243 mip_spi = fr_nbo_to_uint32(mip_rk_1);
244 if (mip_spi < 256) mip_spi += 256;
245
246 REDEBUG2("MIP-RK = 0x%pH", fr_box_octets(mip_rk, rk_len));
247 REDEBUG2("MIP-SPI = %08x", ntohl(mip_spi));
248
249 /*
250 * FIXME: Perform SPI collision prevention
251 */
252
253 /*
254 * Calculate mobility keys
255 */
256 mn_nai = fr_pair_find_by_da(&request->request_pairs, NULL, attr_wimax_mn_nai);
257 if (!mn_nai) mn_nai = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_wimax_mn_nai);
258 if (!mn_nai) {
259 RWDEBUG("%s was not found in the request or in the reply", attr_wimax_mn_nai->name);
260 RWDEBUG("We cannot calculate MN-HA keys");
261 }
262
263 /*
264 * WiMAX-IP-Technology
265 */
266 vp = NULL;
267 if (mn_nai) vp = fr_pair_find_by_da_nested(&request->reply_pairs, NULL, attr_wimax_ip_technology);
268 if (!vp) {
269 RWDEBUG("%s not found in reply", attr_wimax_ip_technology->name);
270 RWDEBUG("Not calculating MN-HA keys");
271 }
272
273 if (vp) switch (vp->vp_uint32) {
274 case 2: /* PMIP4 */
275 /*
276 * Look for WiMAX-hHA-IP-MIP4
277 */
278 ip = fr_pair_find_by_da_nested(&request->reply_pairs, NULL, attr_wimax_hha_ip_mip4);
279 if (!ip) {
280 RWDEBUG("%s not found. Cannot calculate MN-HA-PMIP4 key", attr_wimax_hha_ip_mip4->name);
281 break;
282 }
283
284 /*
285 * MN-HA-PMIP4 =
286 * H(MIP-RK, "PMIP4 MN HA" | HA-IPv4 | MN-NAI);
287 */
288 EVP_MD_CTX_reset(hmac_ctx);
289 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha1(), NULL, hmac_pkey);
290
291 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) "PMIP4 MN HA", 11);
292 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &ip->vp_ipv4addr, 4);
293 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &mn_nai->vp_strvalue, mn_nai->vp_length);
294 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
295
296 /*
297 * Put MN-HA-PMIP4 into WiMAX-MN-hHA-MIP4-Key
298 */
300 fr_pair_value_memdup(vp, &mip_rk_1[0], rk1_len, false);
301
302 /*
303 * Put MN-HA-PMIP4-SPI into WiMAX-MN-hHA-MIP4-SPI
304 */
306 vp->vp_uint32 = mip_spi + 1;
307 break;
308
309 case 3: /* CMIP4 */
310 /*
311 * Look for WiMAX-hHA-IP-MIP4
312 */
313 ip = fr_pair_find_by_da_nested(&request->reply_pairs, NULL, attr_wimax_hha_ip_mip4);
314 if (!ip) {
315 RWDEBUG("%s not found. Cannot calculate MN-HA-CMIP4 key", attr_wimax_hha_ip_mip4->name);
316 break;
317 }
318
319 /*
320 * MN-HA-CMIP4 =
321 * H(MIP-RK, "CMIP4 MN HA" | HA-IPv4 | MN-NAI);
322 */
323 EVP_MD_CTX_reset(hmac_ctx);
324 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha1(), NULL, hmac_pkey);
325
326 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) "CMIP4 MN HA", 11);
327 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &ip->vp_ipv4addr, 4);
328 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &mn_nai->vp_strvalue, mn_nai->vp_length);
329 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
330
331 /*
332 * Put MN-HA-CMIP4 into WiMAX-MN-hHA-MIP4-Key
333 */
335 fr_pair_value_memdup(vp, &mip_rk_1[0], rk1_len, false);
336
337 /*
338 * Put MN-HA-CMIP4-SPI into WiMAX-MN-hHA-MIP4-SPI
339 */
341 vp->vp_uint32 = mip_spi;
342 break;
343
344 case 4: /* CMIP6 */
345 /*
346 * Look for WiMAX-hHA-IP-MIP6
347 */
348 ip = fr_pair_find_by_da_nested(&request->reply_pairs, NULL, attr_wimax_hha_ip_mip6);
349 if (!ip) {
350 RWDEBUG("%s not found. Cannot calculate MN-HA-CMIP6 key", attr_wimax_hha_ip_mip6->name);
351 break;
352 }
353
354 /*
355 * MN-HA-CMIP6 =
356 * H(MIP-RK, "CMIP6 MN HA" | HA-IPv6 | MN-NAI);
357 */
358 EVP_MD_CTX_reset(hmac_ctx);
359 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha1(), NULL, hmac_pkey);
360
361 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) "CMIP6 MN HA", 11);
362 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &ip->vp_ipv6addr, 16);
363 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) &mn_nai->vp_strvalue, mn_nai->vp_length);
364 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
365
366 /*
367 * Put MN-HA-CMIP6 into WiMAX-MN-hHA-MIP6-Key
368 */
370 fr_pair_value_memdup(vp, &mip_rk_1[0], rk1_len, false);
371
372 /*
373 * Put MN-HA-CMIP6-SPI into WiMAX-MN-hHA-MIP6-SPI
374 */
376 vp->vp_uint32 = mip_spi + 2;
377 break;
378
379 default:
380 break; /* do nothing */
381 }
382
383 /*
384 * Generate FA-RK, if requested.
385 *
386 * FA-RK= H(MIP-RK, "FA-RK")
387 */
388 fa_rk = fr_pair_find_by_da_nested(&request->reply_pairs, NULL, attr_wimax_fa_rk_key);
389 if (fa_rk && (fa_rk->vp_length <= 1)) {
390 EVP_MD_CTX_reset(hmac_ctx);
391 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha1(), NULL, hmac_pkey);
392
393 EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *) "FA-RK", 5);
394
395 EVP_DigestSignFinal(hmac_ctx, &mip_rk_1[0], &rk1_len);
396
397 fr_pair_value_memdup(fa_rk, &mip_rk_1[0], rk1_len, false);
398 }
399
400 /*
401 * Create FA-RK-SPI, which is really SPI-CMIP4, which is
402 * really MIP-SPI. Clear? Of course. This is WiMAX.
403 */
404 if (fa_rk) {
406 vp->vp_uint32 = mip_spi;
407 }
408
409 /*
410 * Give additional information about requests && responses
411 *
412 * WiMAX-RRQ-MN-HA-SPI
413 */
414 vp = fr_pair_find_by_da_nested(&request->request_pairs, NULL, attr_wimax_rrq_mn_ha_spi);
415 if (vp) {
416 REDEBUG2("Client requested MN-HA key: Should use SPI to look up key from storage");
417 if (!mn_nai) {
418 RWDEBUG("MN-NAI was not found!");
419 }
420
421 /*
422 * WiMAX-RRQ-HA-IP
423 */
424 if (!fr_pair_find_by_da_nested(&request->request_pairs, NULL, attr_wimax_rrq_ha_ip)) {
425 RWDEBUG("HA-IP was not found!");
426 }
427
428 /*
429 * WiMAX-HA-RK-Key-Requested
430 */
431 vp = fr_pair_find_by_da_nested(&request->request_pairs, NULL, attr_wimax_ha_rk_key_requested);
432 if (vp && (vp->vp_uint32 == 1)) {
433 REDEBUG2("Client requested HA-RK: Should use IP to look it up from storage");
434 }
435 }
436
437 /*
438 * Wipe the context of all sensitive information.
439 */
440 EVP_MD_CTX_free(hmac_ctx);
441 EVP_PKEY_free(hmac_pkey);
442
444}
445
446/*
447 * The module name should be the only globally exported symbol.
448 * That is, everything else should be 'static'.
449 *
450 * If the module needs to temporarily modify it's instantiation
451 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
452 * The server will then take care of ensuring that the module
453 * is single-threaded.
454 */
457 .common = {
458 .magic = MODULE_MAGIC_INIT,
459 .name = "wimax",
460 .inst_size = sizeof(rlm_wimax_t),
462 },
463 .method_group = {
464 .bindings = (module_method_binding_t[]){
465 { .section = SECTION_NAME("recv", "accounting-request"), .method = mod_preacct },
466 { .section = SECTION_NAME("recv", CF_IDENT_ANY), .method = mod_authorize },
467 { .section = SECTION_NAME("send", CF_IDENT_ANY), .method = mod_post_auth },
469 }
470 }
471};
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:57
#define USES_APPLE_DEPRECATED_API
Definition build.h:470
#define RCSID(id)
Definition build.h:483
#define UNUSED
Definition build.h:315
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:658
#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:284
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:595
#define CF_IDENT_ANY
Definition cf_util.h:78
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
Definition dbuff.h:514
#define MEM(x)
Definition debug.h:36
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:268
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:281
Specifies an attribute which must be present for the module to function.
Definition dict.h:267
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:280
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
#define RWDEBUG(fmt,...)
Definition log.h:361
#define REDEBUG2(fmt,...)
Definition log.h:372
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ 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:2981
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, 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:770
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:693
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:2755
static const conf_parser_t config[]
Definition base.c:183
#define DEBUG2(fmt,...)
Definition radclient.h:43
#define RETURN_MODULE_NOOP
Definition rcode.h:62
#define RETURN_MODULE_OK
Definition rcode.h:57
#define RETURN_MODULE_UPDATED
Definition rcode.h:63
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
fr_dict_autoload_t rlm_wimax_dict[]
Definition rlm_wimax.c:56
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
bool delete_mppe_keys
Definition rlm_wimax.c:44
static fr_dict_attr_t const * attr_eap_msk
Definition rlm_wimax.c:63
static fr_dict_t const * dict_freeradius
Definition rlm_wimax.c:53
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:66
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:52
static unlang_action_t mod_preacct(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_wimax.c:156
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:64
static fr_dict_attr_t const * attr_eap_emsk
Definition rlm_wimax.c:62
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
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:456
static const conf_parser_t module_config[]
Definition rlm_wimax.c:47
static unlang_action_t mod_authorize(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
Definition rlm_wimax.c:119
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
static unlang_action_t mod_post_auth(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_wimax.c:164
#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:40
size_t inst_size
Size of the module's instance data.
Definition module.h:203
void * data
Module's instance data.
Definition module.h:271
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:151
Named methods exported by a module.
Definition module.h:173
#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:282
int nonnull(2, 5))
#define fr_box_octets(_val, _len)
Definition value.h:288