The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
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
33static 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);
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);
145
146 return XLAT_ACTION_DONE;
147}
148
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 %u 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);
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 %u 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) {
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
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 }
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 %u 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);
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;
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");
534}
#define unlikely(_x)
Definition build.h:381
#define UNUSED
Definition build.h:315
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition dcursor.h:406
#define MEM(x)
Definition debug.h:36
fr_value_box_t const * value
Enum value (what name maps to).
Definition dict.h:231
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:3382
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:3395
static fr_slen_t in
Definition dict.h:824
Value of an enumerated attribute.
Definition dict.h:227
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:92
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.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
unsigned char uint8_t
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
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
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:148
#define XLAT_ARG_PARSER_TERMINATOR
Definition xlat.h:168
xlat_action_t
Definition xlat.h:37
@ XLAT_ACTION_FAIL
An xlat function failed.
Definition xlat.h:44
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition xlat.h:43
Definition for a single argument consumend by an xlat function.
Definition xlat.h:147
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:4071
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:4148
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
Definition value.h:621
#define fr_box_strvalue_len(_val, _len)
Definition value.h:286
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
Definition value.h:632
#define fr_box_uint32(_val)
Definition value.h:312
static size_t char ** out
Definition value.h:997
An xlat calling ctx.
Definition xlat_ctx.h:49
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition xlat_func.c:365
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:218
void xlat_func_unregister(char const *name)
Unregister an xlat function.
Definition xlat_func.c:519