The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 28727dc05649d26d0b59680a85ace3ceae8fcf92 $
19  * @file rlm_wimax.c
20  * @brief Supports various WiMax functionality.
21  *
22  * @copyright 2008 Alan DeKok (aland@networkradius.com)
23  */
24 RCSID("$Id: 28727dc05649d26d0b59680a85ace3ceae8fcf92 $")
25 USES_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  */
43 typedef struct {
45 } rlm_wimax_t;
46 
47 static const conf_parser_t module_config[] = {
48  { FR_CONF_OFFSET("delete_mppe_keys", rlm_wimax_t, delete_mppe_keys), .dflt = "no" },
50 };
51 
52 static fr_dict_t const *dict_radius;
53 static fr_dict_t const *dict_freeradius;
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  */
119 static 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  */
156 static 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  */
164 static 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  */
455 extern module_rlm_t rlm_wimax;
457  .common = {
458  .magic = MODULE_MAGIC_INIT,
459  .name = "wimax",
460  .flags = MODULE_TYPE_THREAD_SAFE,
461  .inst_size = sizeof(rlm_wimax_t),
463  },
464  .dict = &dict_radius,
465  .method_names = (module_method_name_t[]){
466  { .name1 = "recv", .name2 = "accounting-request", .method = mod_preacct },
467  { .name1 = "recv", .name2 = CF_IDENT_ANY, .method = mod_authorize },
468  { .name1 = "send", .name2 = CF_IDENT_ANY, .method = mod_post_auth },
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:574
#define fr_base16_encode(_out, _in)
Definition: base16.h:57
#define USES_APPLE_DEPRECATED_API
Definition: build.h:431
#define RCSID(id)
Definition: build.h:444
#define UNUSED
Definition: build.h:313
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:626
#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:268
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:563
#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:509
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:250
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:263
Specifies an attribute which must be present for the module to function.
Definition: dict.h:249
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:262
void *_CONST data
Module instance's parsed configuration.
Definition: dl_module.h:165
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:65
#define RWDEBUG(fmt,...)
Definition: log.h:361
#define REDEBUG2(fmt,...)
Definition: log.h:372
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
Definition: merged_model.c:86
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
Definition: merged_model.c:88
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
Definition: merged_model.c:91
@ FR_TYPE_OCTETS
Raw octets.
Definition: merged_model.c:84
unsigned int uint32_t
Definition: merged_model.c:33
unsigned char uint8_t
Definition: merged_model.c:30
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Definition: module_ctx.h:42
Temporary structure to hold arguments for module calls.
Definition: module_ctx.h:41
Specifies a module method identifier.
Definition: module_method.c:36
module_t common
Common fields presented by all modules.
Definition: module_rlm.h:37
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:158
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:688
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:2978
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:2752
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:765
static const conf_parser_t config[]
Definition: base.c:188
#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)
@ MODULE_TYPE_THREAD_SAFE
Module is threadsafe.
Definition: module.h:49
#define MODULE_NAME_TERMINATOR
Definition: module.h:135
#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
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
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:270
int nonnull(2, 5))
#define fr_box_octets(_val, _len)
Definition: value.h:281