The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
xlat.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  * @file src/lib/eap_aka_sim/xlat.c
19  * @brief EAP-SIM/EAP-AKA identity detection, creation, and decyption.
20  *
21  * Implements the encrypted IMSI scheme described in TS 33.402 Release 14,
22  * section 14.
23  *
24  * @copyright 2017 The FreeRADIUS server project
25  */
26 
27 #include <freeradius-devel/server/base.h>
28 #include <freeradius-devel/unlang/xlat_func.h>
29 
30 #include "base.h"
31 #include "attrs.h"
32 
33 static int aka_sim_xlat_refs = 0;
34 
35 
37  { .required = true, .single = true, .type = FR_TYPE_STRING },
39 };
40 
41 /** Returns the SIM method EAP-SIM or EAP-AKA hinted at by the user identifier
42  *
43 @verbatim
44 %aka_sim_id_method(%{id_attr})
45 @endverbatim
46  *
47  * @ingroup xlat_functions
48  */
50  UNUSED xlat_ctx_t const *xctx,
51  request_t *request,
52  fr_value_box_list_t *in)
53 {
54  char const *method;
55  fr_aka_sim_id_type_t type_hint;
56  fr_aka_sim_method_hint_t method_hint;
57  fr_value_box_t *id = fr_value_box_list_head(in);
58  fr_value_box_t *vb;
59 
60  if (fr_aka_sim_id_type(&type_hint, &method_hint, id->vb_strvalue, id->vb_length) < 0) {
61  RPEDEBUG2("AKA/SIM Id \"%pV\" has unrecognised format", id);
62  return XLAT_ACTION_FAIL;
63  }
64 
65  switch (method_hint) {
66  default:
68  return XLAT_ACTION_DONE;
69 
72  fr_box_uint32(FR_METHOD_HINT_VALUE_SIM));
73  break;
74 
77  fr_box_uint32(FR_METHOD_HINT_VALUE_AKA));
78  break;
79 
82  fr_box_uint32(FR_METHOD_HINT_VALUE_AKA_PRIME));
83  break;
84  }
85 
86  MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL));
87  fr_value_box_bstrndup(vb, vb, NULL, method, strlen(method), false);
89 
90  return XLAT_ACTION_DONE;
91 }
92 
94  { .required = true, .single = true, .type = FR_TYPE_STRING },
96 };
97 
98 /** Returns the type of identity used
99  *
100 @verbatim
101 %aka_sim_id_type(%{id_attr})
102 @endverbatim
103  *
104  * @ingroup xlat_functions
105  */
107  UNUSED xlat_ctx_t const *xctx,
108  request_t *request, fr_value_box_list_t *in)
109 {
110  char const *type;
111  fr_aka_sim_id_type_t type_hint;
112  fr_aka_sim_method_hint_t method_hint;
113  fr_value_box_t *id = fr_value_box_list_head(in);
114  fr_value_box_t *vb;
115 
116  if (fr_aka_sim_id_type(&type_hint, &method_hint, id->vb_strvalue, id->vb_length) < 0) {
117  RPEDEBUG2("AKA/AKA/SIM Id \"%pV\" has unrecognised format", id);
118  return XLAT_ACTION_FAIL;
119  }
120 
121  switch (type_hint) {
122  default:
124  return XLAT_ACTION_DONE;
125 
128  fr_box_uint32(FR_IDENTITY_TYPE_VALUE_PERMANENT));
129  break;
130 
133  fr_box_uint32(FR_IDENTITY_TYPE_VALUE_PSEUDONYM));
134  break;
135 
138  fr_box_uint32(FR_IDENTITY_TYPE_VALUE_FASTAUTH));
139  break;
140  }
141 
142  MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL));
143  fr_value_box_bstrndup(vb, vb, NULL, type, strlen(type), false);
144  fr_dcursor_append(out, vb);
145 
146  return XLAT_ACTION_DONE;
147 }
148 
150  { .required = true, .single = true, .type = FR_TYPE_STRING },
152 };
153 
154 /** Returns the key index from a 3gpp temporary id
155  *
156 @verbatim
157 %3gpp_temporary_id_key_index(%{id_attr})
158 @endverbatim
159  *
160  * @ingroup xlat_functions
161  */
163  UNUSED xlat_ctx_t const *xctx,
164  request_t *request, fr_value_box_list_t *in)
165 {
166  fr_value_box_t *id = fr_value_box_list_head(in);
167  fr_value_box_t *vb;
168 
169  if (id->vb_length != AKA_SIM_3GPP_PSEUDONYM_LEN) {
170  REDEBUG2("3gpp pseudonym incorrect length, expected %i bytes, got %zu bytes",
171  AKA_SIM_3GPP_PSEUDONYM_LEN, id->vb_length);
172  return XLAT_ACTION_FAIL;
173  }
174 
175  MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_UINT8, NULL));
176  vb->vb_uint8 = fr_aka_sim_id_3gpp_pseudonym_tag(id->vb_strvalue);
177  fr_dcursor_append(out, vb);
178 
179  return XLAT_ACTION_DONE;
180 }
181 
183  { .required = true, .concat = true, .single = false, .type = FR_TYPE_STRING,
184  .func = NULL, .uctx = NULL },
185  { .required = true, .concat = true, .single = false, .type = FR_TYPE_OCTETS,
186  .func = NULL, .uctx = NULL },
187  { .required = false, .concat = false, .single = true, .type = FR_TYPE_BOOL,
188  .func = NULL, .uctx = NULL },
190 };
191 
192 /** Decrypt a 3gpp temporary id
193  *
194  @verbatim
195  %3gpp_temporary_id_decrypt(<id> <key>)
196  @endverbatim
197  *
198  * The pseudonym is in the format
199  @verbatim
200  0 1 2 3
201  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
202  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
203  | Tag | KeyID | Encrypted IMSI
204  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
205  |
206  | Encrypted IMSI (cont) |
207  | |
208  | |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
209  +-+-+-+-+-+-+-+-+-+-+
210  @endverbatim
211  *
212  * Tag (6 bits) - Used to mark the identity as a temporary pseudonym
213  * or re-authentication identity. The idea of this being 6 bits is
214  * so that we can choose values that match base64 sextets, so the
215  * first character in the base64 output matches one of the known tags
216  * for EAP-SIM/AKA/AKA' identities.
217  *
218  * Key Indicator (4 bits) - Used to select the appropriate key from
219  * multiple keys the server may have used to encrypt IMSIs.
220  *
221  * Encrypted IMSI (128 bits) - The original IMSI encrypted with
222  * AES-128-ECB.
223  *
224  * @ingroup xlat_functions
225  */
227  UNUSED xlat_ctx_t const *xctx,
228  request_t *request, fr_value_box_list_t *in)
229 {
230  uint8_t tag;
231  char out_tag = '\0', *buff;
232 
233  char decrypted[AKA_SIM_IMSI_MAX_LEN + 1];
234 
235  fr_value_box_t *id_vb = fr_value_box_list_head(in);
236  char const *id = id_vb->vb_strvalue;
237  size_t id_len = id_vb->vb_length;
238 
239  fr_value_box_t *key_vb = fr_value_box_list_next(in, id_vb);
240  /* coverity[dereference] */
241  uint8_t const *key = key_vb->vb_octets;
242  size_t key_len = key_vb->vb_length;
243 
244  fr_value_box_t *tag_vb = fr_value_box_list_next(in, key_vb);
245  bool include_tag = true;
246 
247  fr_value_box_t *vb;
249 
250  if (tag_vb) include_tag = tag_vb->vb_bool;
251 
252  if (id_len != (AKA_SIM_3GPP_PSEUDONYM_LEN)) {
253  REDEBUG2("3gpp pseudonym incorrect length, expected %i bytes, got %zu bytes",
255  error:
256  return XLAT_ACTION_FAIL;
257  }
258 
259  if (key_len != 16) {
260  REDEBUG2("Decryption key incorrect length, expected %i bytes, got %zu bytes", 16, key_len);
261  goto error;
262  }
263 
264  if (include_tag) {
265  /*
266  * Figure out what tag we should add to the permanent id
267  */
268  eap_type = fr_pair_find_by_da(&request->request_pairs, NULL, attr_eap_type);
269  if (eap_type) {
270  if (eap_type->vp_uint32 == enum_eap_type_sim->vb_uint32) {
271  out_tag = ID_TAG_SIM_PERMANENT;
272  } else if (eap_type->vp_uint32 == enum_eap_type_aka->vb_uint32) {
273  out_tag = ID_TAG_AKA_PERMANENT;
274  } else if (eap_type->vp_uint32 == enum_eap_type_aka_prime->vb_uint32) {
275  out_tag = ID_TAG_AKA_PRIME_PERMANENT;
276  } else {
277  goto use_existing_tag;
278  }
279  } else {
280  use_existing_tag:
282  switch (tag) {
285  out_tag = ID_TAG_SIM_PERMANENT;
286  break;
287 
290  out_tag = ID_TAG_AKA_PERMANENT;
291  break;
292 
295  out_tag = ID_TAG_AKA_PRIME_PERMANENT;
296  break;
297 
298  default:
299  REDEBUG2("Unexpected tag value (%u) in AKA/SIM Id \"%pV\"", tag, fr_box_strvalue_len(id, id_len));
300  goto error;
301  }
302  }
303  }
304 
305  RDEBUG2("Decrypting \"%pV\"", fr_box_strvalue_len(id, id_len));
306  if (fr_aka_sim_id_3gpp_pseudonym_decrypt(decrypted, id, key) < 0) {
307  RPEDEBUG2("Failed decrypting AKA/SIM Id");
308  goto error;
309  }
310 
311  /*
312  * Recombine unencrypted IMSI with tag
313  */
314  MEM(vb = fr_value_box_alloc_null(ctx));
315  if (include_tag) {
316  MEM(fr_value_box_bstr_alloc(vb, &buff, vb, NULL, AKA_SIM_IMSI_MAX_LEN + 1, false) == 0);
317  *buff = out_tag;
318  strncpy(buff + 1, decrypted, AKA_SIM_IMSI_MAX_LEN + 1);
319  } else {
320  MEM(fr_value_box_bstrndup(vb, vb, NULL, decrypted, AKA_SIM_IMSI_MAX_LEN, true) == 0);
321  }
322  fr_dcursor_append(out, vb);
323 
324  return XLAT_ACTION_DONE;
325 }
326 
328  { .required = true, .concat = true, .single = false, .type = FR_TYPE_STRING },
329  { .required = true, .concat = true, .single = false, .type = FR_TYPE_OCTETS },
330  { .required = true, .concat = false, .single = true, .type = FR_TYPE_UINT8 },
331  { .required = false, .concat = false, .single = true, .type = FR_TYPE_STRING },
333 };
334 
335 /** Encrypts a 3gpp pseudonym
336  *
337 @verbatim
338 %3gpp_temporary_id_encrypt(<id>, <key>, <index>, [(pseudonym|fastauth)])
339 @endverbatim
340  *
341  * @ingroup xlat_functions
342  */
344  UNUSED xlat_ctx_t const *xctx,
345  request_t *request, fr_value_box_list_t *in)
346 {
347  char encrypted[AKA_SIM_3GPP_PSEUDONYM_LEN + 1];
348  uint8_t tag = 0;
349 
350  char const *id_p, *id_end;
351  fr_aka_sim_id_type_t type_hint;
352  fr_aka_sim_method_hint_t method_hint;
353 
354  fr_value_box_t *id_vb = fr_value_box_list_head(in);
355  char const *id = id_vb->vb_strvalue;
356  size_t id_len = id_vb->vb_length;
357 
358  fr_value_box_t *key_vb = fr_value_box_list_next(in, id_vb);
359  /* coverity[dereference] */
360  uint8_t const *key = key_vb->vb_octets;
361  size_t key_len = key_vb->vb_length;
362 
363  fr_value_box_t *index_vb = fr_value_box_list_next(in, key_vb);
364  uint8_t key_index = index_vb->vb_uint8;
365 
366  fr_value_box_t *type_vb = fr_value_box_list_next(in, index_vb);
367 
368  bool fastauth = false;
369 
370  fr_value_box_t *vb;
371 
372  /*
373  * Get the key index
374  */
375  if (key_index > 15) {
376  REDEBUG2("Key index must be between 0-15");
377  error:
378  return XLAT_ACTION_FAIL;
379  }
380 
381  if (key_len != 16) {
382  REDEBUG2("Encryption key incorrect length, expected %i bytes, got %zu bytes", 16, key_len);
383  goto error;
384  }
385 
386  /*
387  * Check for the optional type argument
388  */
389  if (type_vb) {
390  fr_dict_enum_value_t const *type_enum;
391 
393  type_vb->vb_strvalue, type_vb->vb_length);
394  if (!type_enum) {
395  bad_type:
396  REDEBUG2("Bad type %pV, must be one of 'fastauth' or 'pseudonym'", type_vb);
397  goto error;
398  }
399 
400  switch (type_enum->value->vb_uint32) {
401  case FR_IDENTITY_TYPE_VALUE_PSEUDONYM:
402  break;
403 
404  case FR_IDENTITY_TYPE_VALUE_FASTAUTH:
405  fastauth = true;
406  break;
407 
408  default:
409  goto bad_type;
410  }
411  }
412 
413  /*
414  * Determine what type/method hints are in the current ID.
415  */
416  if (id_len == (AKA_SIM_IMSI_MAX_LEN + 1)) { /* +1 for ID tag */
417  if (fr_aka_sim_id_type(&type_hint, &method_hint, id, id_len) < 0) {
418  RPEDEBUG2("ID \"%pV\" has unrecognised format", fr_box_strvalue_len(id, id_len));
419  goto error;
420  }
421 
422  if (type_hint != AKA_SIM_ID_TYPE_PERMANENT) {
423  REDEBUG2("ID \"%pV\" is not a permanent identity (IMSI)", fr_box_strvalue_len(id, id_len));
424  goto error;
425  }
426 
427  switch (method_hint) {
430  break;
431 
434  break;
435 
438  break;
439 
442  REDEBUG2("ID \"%pV\" does not contain a method hint", fr_box_strvalue_len(id, id_len));
443  goto error;
444  }
445 
446  id_p = id + 1;
447  id_end = (id_p + id_len) - 1;
448  /*
449  * ID lacks a hint byte, figure it out from &request.EAP-Type
450  */
451  } else if ((id_len >= AKA_SIM_IMSI_MIN_LEN) && (id_len <= AKA_SIM_IMSI_MAX_LEN)) {
453 
454  eap_type = fr_pair_find_by_da(&request->request_pairs, NULL, attr_eap_type);
455  if (!eap_type) {
456  REDEBUG("ID does not contain method hint, and no &request.EAP-Type found. "
457  "Don't know what tag to prepend to encrypted identity");
458  goto error;
459  }
460 
461  if (eap_type->vp_uint32 == enum_eap_type_sim->vb_uint32) {
463  } else if (eap_type->vp_uint32 == enum_eap_type_aka->vb_uint32) {
465  } else if (eap_type->vp_uint32 == enum_eap_type_aka_prime->vb_uint32) {
467  } else {
468  REDEBUG("&request.EAP-Type does not match a SIM based EAP-Type (SIM, AKA, AKA-Prime)");
469  }
470 
471  id_p = id;
472  id_end = id_p + id_len;
473  } else {
474  REDEBUG2("IMSI incorrect length, expected %i bytes, got %zu bytes", AKA_SIM_IMSI_MAX_LEN + 1,
475  id_len);
476  goto error;
477 
478  }
479 
480  /*
481  * Encrypt the IMSI
482  *
483  * Strip existing tag from the permanent id
484  */
485  if (fr_aka_sim_id_3gpp_pseudonym_encrypt(encrypted, id_p, id_end - id_p, tag, (uint8_t)key_index, key) < 0) {
486  RPEDEBUG2("Failed encrypting SIM ID \"%pV\"", fr_box_strvalue_len(id, id_len));
487  return XLAT_ACTION_FAIL;
488  }
489 
490  MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL));
491  fr_value_box_bstrndup(vb, vb, NULL, encrypted, strlen(encrypted), false);
492  fr_dcursor_append(out, vb);
493 
494  return XLAT_ACTION_DONE;
495 }
496 
498 {
499  xlat_t *xlat;
500 
501  if (aka_sim_xlat_refs) {
503  return 0;
504  }
505 
506  if (unlikely((xlat = xlat_func_register(NULL, "aka_sim_id_method", aka_sim_xlat_id_method_xlat, FR_TYPE_STRING)) == NULL)) return -1;
508  if (unlikely((xlat = xlat_func_register(NULL, "aka_sim_id_type", aka_sim_xlat_id_type_xlat, FR_TYPE_STRING)) == NULL)) return -1;
510  if (unlikely((xlat = xlat_func_register(NULL, "3gpp_temporary_id_key_index", aka_sim_id_3gpp_temporary_id_key_index_xlat, FR_TYPE_UINT8)) == NULL)) return -1;
512  if (unlikely((xlat = xlat_func_register(NULL, "3gpp_temporary_id_decrypt", aka_sim_3gpp_temporary_id_decrypt_xlat, FR_TYPE_STRING)) == NULL)) return -1;
514  if (unlikely((xlat = xlat_func_register(NULL, "3gpp_temporary_id_encrypt", aka_sim_3gpp_temporary_id_encrypt_xlat, FR_TYPE_STRING)) == NULL)) return -1;
516  aka_sim_xlat_refs = 1;
517 
518  return 0;
519 }
520 
522 {
523  if (aka_sim_xlat_refs > 1) {
525  return;
526  }
527 
528  xlat_func_unregister("aka_sim_id_method");
529  xlat_func_unregister("aka_sim_id_type");
530  xlat_func_unregister("3gpp_temporary_id_key_index");
531  xlat_func_unregister("3gpp_temporary_id_decrypt");
532  xlat_func_unregister("3gpp_temporary_id_encrypt");
533  aka_sim_xlat_refs = 0;
534 }
#define unlikely(_x)
Definition: build.h:378
#define UNUSED
Definition: build.h:313
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition: dcursor.h:405
fr_value_box_t const * value
Enum value (what name maps to).
Definition: dict.h:213
fr_dict_enum_value_t * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
Definition: dict_util.c:2992
static fr_slen_t in
Definition: dict.h:645
char const * fr_dict_enum_name_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the name of an enum value in a fr_dict_attr_t.
Definition: dict_util.c:2979
Value of an enumerated attribute.
Definition: dict.h:209
eap_type
Definition: types.h:44
static xlat_arg_parser_t aka_sim_3gpp_temporary_id_encrypt_xlat_args[]
Definition: xlat.c:327
static xlat_arg_parser_t const aka_sim_id_3gpp_temporary_id_key_index_xlat_args[]
Definition: xlat.c:149
static xlat_arg_parser_t const aka_sim_xlat_id_method_xlat_args[]
Definition: xlat.c:36
int fr_aka_sim_xlat_func_register(void)
Definition: xlat.c:497
static xlat_arg_parser_t aka_sim_3gpp_temporary_id_decrypt_xlat_args[]
Definition: xlat.c:182
static xlat_arg_parser_t const aka_sim_xlat_id_type_xlat_args[]
Definition: xlat.c:93
static int aka_sim_xlat_refs
Definition: xlat.c:33
void fr_aka_sim_xlat_func_unregister(void)
Definition: xlat.c:521
static xlat_action_t aka_sim_id_3gpp_temporary_id_key_index_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Returns the key index from a 3gpp temporary id.
Definition: xlat.c:162
static xlat_action_t aka_sim_xlat_id_method_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Returns the SIM method EAP-SIM or EAP-AKA hinted at by the user identifier.
Definition: xlat.c:49
static xlat_action_t aka_sim_xlat_id_type_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Returns the type of identity used.
Definition: xlat.c:106
static xlat_action_t aka_sim_3gpp_temporary_id_encrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Encrypts a 3gpp pseudonym.
Definition: xlat.c:343
static xlat_action_t aka_sim_3gpp_temporary_id_decrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Decrypt a 3gpp temporary id.
Definition: xlat.c:226
HIDDEN fr_dict_attr_t const * attr_eap_type
Definition: base.c:86
fr_value_box_t const * enum_eap_type_aka
Definition: base.c:186
fr_value_box_t const * enum_eap_type_sim
Definition: base.c:185
fr_value_box_t const * enum_eap_type_aka_prime
Definition: base.c:187
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_method_hint
Definition: base.c:85
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_identity_type
Definition: base.c:74
int fr_aka_sim_id_3gpp_pseudonym_decrypt(char out[AKA_SIM_IMSI_MAX_LEN+1], char const encr_id[AKA_SIM_3GPP_PSEUDONYM_LEN], uint8_t const key[16])
Decrypt the 3GPP pseudonym.
Definition: id.c:576
uint8_t fr_aka_sim_id_3gpp_pseudonym_tag(char const encr_id[AKA_SIM_3GPP_PSEUDONYM_LEN])
Return the tag from a 3gpp pseudonym.
Definition: id.c:550
int fr_aka_sim_id_3gpp_pseudonym_encrypt(char out[AKA_SIM_3GPP_PSEUDONYM_LEN+1], char const *imsi, size_t imsi_len, uint8_t tag, uint8_t key_ind, uint8_t const key[16])
Create a 3gpp pseudonym from a permanent ID.
Definition: id.c:397
int fr_aka_sim_id_type(fr_aka_sim_id_type_t *type, fr_aka_sim_method_hint_t *hint, char const *id, size_t id_len)
Determine what type of ID was provided in the initial identity response.
Definition: id.c:167
#define ID_TAG_SIM_PSEUDONYM_B64
Definition: id.h:90
#define ID_TAG_AKA_PSEUDONYM_B64
Definition: id.h:92
#define AKA_SIM_IMSI_MAX_LEN
Length of an IMSI number in ASCII.
Definition: id.h:32
#define ID_TAG_AKA_FASTAUTH_B64
Definition: id.h:93
#define ID_TAG_SIM_FASTAUTH_B64
Definition: id.h:91
#define ID_TAG_AKA_PRIME_PSEUDONYM_B64
Definition: id.h:94
@ ID_TAG_AKA_PERMANENT
IMSI, and hint that client wants to do EAP-AKA.
Definition: id.h:66
@ ID_TAG_SIM_PERMANENT
IMSI, and hint that client wants to do EAP-SIM.
Definition: id.h:62
@ ID_TAG_AKA_PRIME_PERMANENT
IMSI, and hint that client wants to do EAP-AKA-Prime.
Definition: id.h:70
fr_aka_sim_method_hint_t
SIM/AKA method hints.
Definition: id.h:39
@ AKA_SIM_METHOD_HINT_AKA
The identity hints the supplicant wants to use EAP-AKA.
Definition: id.h:43
@ AKA_SIM_METHOD_HINT_SIM
The identity hints the supplicant wants to use EAP-SIM.
Definition: id.h:41
@ AKA_SIM_METHOD_HINT_AKA_PRIME
Definition: id.h:45
@ AKA_SIM_METHOD_HINT_MAX
Definition: id.h:46
@ AKA_SIM_METHOD_HINT_UNKNOWN
We don't know what method the identity hints at.
Definition: id.h:40
#define AKA_SIM_IMSI_MIN_LEN
Minimum length of an IMSI number in ASCII.
Definition: id.h:33
#define AKA_SIM_3GPP_PSEUDONYM_LEN
Length of a base64 encoded 3gpp pseudonym.
Definition: id.h:31
fr_aka_sim_id_type_t
SIM/AKA identity type hints.
Definition: id.h:53
@ AKA_SIM_ID_TYPE_UNKNOWN
We don't know what type of identity this is.
Definition: id.h:54
@ AKA_SIM_ID_TYPE_PSEUDONYM
This is a custom pseudonym.
Definition: id.h:56
@ AKA_SIM_ID_TYPE_PERMANENT
This is a permanent identity (the IMSI of the SIM).
Definition: id.h:55
@ AKA_SIM_ID_TYPE_FASTAUTH
This is a fastauth (session-resumption) id.
Definition: id.h:57
#define ID_TAG_AKA_PRIME_FASTAUTH_B64
Definition: id.h:95
#define RPEDEBUG2(fmt,...)
Definition: log.h:377
#define REDEBUG2(fmt,...)
Definition: log.h:372
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_UINT8
8 Bit unsigned integer.
Definition: merged_model.c:97
@ FR_TYPE_BOOL
A truth value.
Definition: merged_model.c:95
@ FR_TYPE_OCTETS
Raw octets.
Definition: merged_model.c:84
unsigned char uint8_t
Definition: merged_model.c:30
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
VQP attributes.
#define REDEBUG(fmt,...)
Definition: radclient.h:52
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
static char buff[sizeof("18446744073709551615")+3]
Definition: size_tests.c:41
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
fr_aka_sim_id_type_t type
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
bool required
Argument must be present, and non-empty.
Definition: xlat.h:146
#define XLAT_ARG_PARSER_TERMINATOR
Definition: xlat.h:166
xlat_action_t
Definition: xlat.h:35
@ XLAT_ACTION_FAIL
An xlat function failed.
Definition: xlat.h:42
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition: xlat.h:41
Definition for a single argument consumend by an xlat function.
Definition: xlat.h:145
Master include file to access all functions and structures in the library.
int fr_value_box_bstr_alloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst, fr_dict_attr_t const *enumv, size_t len, bool tainted)
Alloc and assign an empty \0 terminated string to a fr_value_box_t.
Definition: value.c:4020
int fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Copy a string to to a fr_value_box_t.
Definition: value.c:4097
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
Definition: value.h:608
#define fr_box_strvalue_len(_val, _len)
Definition: value.h:279
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
Definition: value.h:619
#define fr_box_uint32(_val)
Definition: value.h:305
static size_t char ** out
Definition: value.h:984
An xlat calling ctx.
Definition: xlat_ctx.h:42
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition: xlat_func.c:360
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.
Definition: xlat_func.c:195
void xlat_func_unregister(char const *name)
Unregister an xlat function.
Definition: xlat_func.c:531