The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
module.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/module.c
19  * @brief Common encode/decode functions for EAP subtype modules
20  *
21  * @author Arran Cudbard-Bell (a.cudbardb@freeradius.org)
22  *
23  * @copyright 2021 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24  */
25 RCSID("$Id: 4b58fc6d0d803fc119d4df8dc25c89e4be5d25c6 $")
26 
27 #include <freeradius-devel/eap/types.h>
28 #include <freeradius-devel/server/module.h>
29 #include <freeradius-devel/server/pair.h>
30 #include <freeradius-devel/server/virtual_servers.h>
31 #include <freeradius-devel/unlang/interpret.h>
32 #include <freeradius-devel/unlang/module.h>
33 #include <freeradius-devel/util/rand.h>
34 
35 #include "attrs.h"
36 #include "base.h"
37 #include "module.h"
38 
39 /** Encode EAP session data from attributes
40  *
41  */
42 static unlang_action_t mod_encode(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
43 {
44  eap_aka_sim_module_conf_t *inst = talloc_get_type_abort(mctx->mi->data, eap_aka_sim_module_conf_t);
45  eap_session_t *eap_session = eap_session_get(request->parent);
46  eap_aka_sim_mod_session_t *mod_session = talloc_get_type_abort(eap_session->opaque,
49 
50  static eap_code_t rcode_to_eap_code[RLM_MODULE_NUMCODES] = {
60  };
61  eap_code_t code;
64  uint8_t const *request_hmac_extra = NULL;
65  size_t request_hmac_extra_len = 0;
66  fr_pair_t *vp;
67  int ret;
68 
69  /*
70  * If there's no subtype vp, we look at the rcode
71  * from the virtual server to determine what kind
72  * of EAP response to send.
73  */
74  subtype_vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_eap_aka_sim_subtype);
75  if (!subtype_vp) {
76  eap_session->this_round->request->code = (rcode == RLM_MODULE_OK) ?
78  /*
79  * RFC 3748 requires the request and response
80  * IDs to be identical for EAP-SUCCESS and
81  * EAP-FAILURE.
82  *
83  * The EAP common code will do the right thing
84  * here if we just tell it we haven't se the
85  * request ID.
86  */
87  eap_session->this_round->set_request_id = false;
88  eap_session->finished = true;
89  TALLOC_FREE(eap_session->opaque);
90 
92  }
93 
95 
96  /*
97  * If there is a subtype vp, verify the return
98  * code allows us send EAP-SIM/AKA/AKA' data back.
99  */
100  code = rcode_to_eap_code[rcode];
101  if (code != FR_EAP_CODE_REQUEST) {
102  eap_session->this_round->request->code = code;
103  eap_session->this_round->set_request_id = false;
104  eap_session->finished = true;
105  TALLOC_FREE(eap_session->opaque);
106 
108  }
109 
110  /*
111  * It's not an EAP-Success or an EAP-Failure
112  * it's a real EAP-SIM/AKA/AKA' response.
113  */
114  eap_session->this_round->request->type.num = inst->type;
115  eap_session->this_round->request->code = code;
116  eap_session->this_round->set_request_id = true;
117 
118  /*
119  * RFC 3748 says this ID need only be different to
120  * the previous ID.
121  *
122  * We need to set the type, code, id here as the
123  * HMAC operates on the complete packet we're
124  * returning including the EAP headers, so the packet
125  * fields must be filled in before we call encode.
126  */
127  eap_session->this_round->request->id = mod_session->id++;
128 
129  /*
130  * Perform different actions depending on the type
131  * of request we're sending.
132  */
133  switch (subtype_vp->vp_uint16) {
134  case FR_SUBTYPE_VALUE_AKA_IDENTITY:
135  case FR_SUBTYPE_VALUE_SIM_START:
136  if (RDEBUG_ENABLED2) break;
137 
138  /*
139  * Figure out if the state machine is
140  * requesting an ID.
141  */
142  if ((vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_eap_aka_sim_any_id_req)) ||
143  (vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_eap_aka_sim_fullauth_id_req)) ||
144  (vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_eap_aka_sim_permanent_id_req))) {
145  RDEBUG2("Sending EAP-Request/%pV (%s)", &subtype_vp->data, vp->da->name);
146  } else {
147  RDEBUG2("Sending EAP-Request/%pV", &subtype_vp->data);
148  }
149  break;
150 
151  /*
152  * Deal with sending bidding VP
153  *
154  * This can either come from policy or be set by the default
155  * virtual server.
156  *
157  * We send AT_BIDDING in our EAP-Request/AKA-Challenge message
158  * to tell the supplicant that if it has AKA' available/enabled
159  * it should have used that.
160  */
161  case FR_SUBTYPE_VALUE_AKA_CHALLENGE:
162  vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_eap_aka_sim_bidding);
163 
164  /*
165  * Explicit NO
166  */
167  if (inst->aka.send_at_bidding_prefer_prime_is_set &&
168  !inst->aka.send_at_bidding_prefer_prime) {
170  /*
171  * Implicit or explicit YES
172  */
173  } else if (inst->aka.send_at_bidding_prefer_prime) {
175  vp->vp_uint16 = FR_BIDDING_VALUE_PREFER_AKA_PRIME;
176  }
177  FALL_THROUGH;
178 
179  case FR_SUBTYPE_VALUE_SIM_CHALLENGE:
180  case FR_SUBTYPE_VALUE_AKA_SIM_REAUTHENTICATION:
181  /*
182  * Include our copy of the checkcode if we've been
183  * calculating it.
184  */
185  if (mod_session->checkcode_state) {
186  uint8_t *checkcode;
187 
189  if (fr_aka_sim_crypto_finalise_checkcode(vp, &checkcode, mod_session->checkcode_state) < 0) {
190  RPWDEBUG("Failed calculating checkcode");
192  }
193  fr_pair_value_memdup_buffer_shallow(vp, checkcode, false); /* Buffer already in the correct ctx */
194  }
195 
196  /*
197  * Extra data to append to the packet when signing.
198  */
199  vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_eap_aka_sim_hmac_extra_request);
200  if (vp) {
201  request_hmac_extra = vp->vp_octets;
202  request_hmac_extra_len = vp->vp_length;
203  }
204 
205  /*
206  * Extra data to append to the response packet when
207  * validating the signature.
208  */
209  vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_eap_aka_sim_hmac_extra_response);
210  if (vp) {
211  /*
212  * We may attempt to challenge the supplicant
213  * twice when performing a resynchronisation.
214  *
215  * We previously asserted that the following were NULL:
216  *
217  * mod_session->response_hmac_extra
218  * mod_session->ctx.k_encr
219  * mod_session->ctx.k_aut
220  *
221  * but that is incorrect, as these fields need to be
222  * updated if new vectors are available.
223  */
224  talloc_free(mod_session->response_hmac_extra);
225  MEM(mod_session->response_hmac_extra = talloc_memdup(mod_session,
226  vp->vp_octets, vp->vp_length));
227  mod_session->response_hmac_extra_len = vp->vp_length;
228  }
229  /*
230  * Key we use for encrypting and decrypting attributes.
231  */
232  vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_eap_aka_sim_k_encr);
233  if (vp) {
234  talloc_const_free(mod_session->ctx.k_encr);
235  MEM(mod_session->ctx.k_encr = talloc_memdup(mod_session, vp->vp_octets, vp->vp_length));
236  }
237 
238  /*
239  * Key we use for signing and validating mac values.
240  */
241  vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_eap_aka_sim_k_aut);
242  if (vp) {
243  talloc_const_free(mod_session->ctx.k_aut);
244  MEM(mod_session->ctx.k_aut = talloc_memdup(mod_session, vp->vp_octets, vp->vp_length));
245  mod_session->ctx.k_aut_len = vp->vp_length;
246  }
247 
248  fr_assert(mod_session->ctx.k_encr && mod_session->ctx.k_aut);
249  FALL_THROUGH;
250 
251  default:
252  RDEBUG2("Sending EAP-Request/%pV", &subtype_vp->data);
253  break;
254  }
255 
256  encode_ctx = mod_session->ctx;
257  encode_ctx.eap_packet = eap_session->this_round->request;
258  encode_ctx.hmac_extra = request_hmac_extra;
259  encode_ctx.hmac_extra_len = request_hmac_extra_len;
260 
261  RDEBUG2("Encoding attributes");
262  log_request_pair_list(L_DBG_LVL_2, request, NULL, &request->reply_pairs, NULL);
263  ret = fr_aka_sim_encode(request, &request->reply_pairs, &encode_ctx);
264  if (ret <= 0) RETURN_MODULE_FAIL;
265 
266  switch (subtype_vp->vp_uint16) {
267  case FR_SUBTYPE_VALUE_AKA_IDENTITY:
268  /*
269  * Ingest the identity message into the checkcode
270  */
271  if (mod_session->ctx.checkcode_md) {
272  RDEBUG2("Updating checkcode");
273  if (!mod_session->checkcode_state &&
274  (fr_aka_sim_crypto_init_checkcode(mod_session, &mod_session->checkcode_state,
275  mod_session->ctx.checkcode_md) < 0)) {
276  RPWDEBUG("Failed initialising checkcode");
277  break;
278  }
279 
281  eap_session->this_round->request) < 0) {
282  RPWDEBUG("Failed updating checkcode");
283  }
284  }
285  break;
286 
287  default:
288  break;
289  }
290 
291  return UNLANG_ACTION_CALCULATE_RESULT; /* rcode is already correct */
292 }
293 
294 /** Decode EAP session data into attribute
295  *
296  */
298 {
299  eap_aka_sim_module_conf_t *inst = talloc_get_type_abort(mctx->mi->data, eap_aka_sim_module_conf_t);
300  eap_session_t *eap_session = eap_session_get(request->parent);
301  eap_aka_sim_mod_session_t *mod_session = talloc_get_type_abort(eap_session->opaque,
304  fr_dcursor_t cursor;
305  int ret;
306  fr_aka_sim_ctx_t decode_ctx;
307 
308  switch (eap_session->this_round->response->type.num) {
309  default:
310  REDEBUG2("Unsupported EAP type (%u)", eap_session->this_round->response->type.num);
312 
314  case FR_EAP_METHOD_NAK: /* Peer NAK'd our original suggestion */
315  break;
316 
317  /*
318  * Only decode data for EAP-SIM/AKA/AKA' responses
319  */
320  case FR_EAP_METHOD_SIM:
321  case FR_EAP_METHOD_AKA:
323  fr_pair_dcursor_init(&cursor, &request->request_pairs);
324 
325  decode_ctx = mod_session->ctx;
326  decode_ctx.hmac_extra = mod_session->response_hmac_extra;
327  decode_ctx.hmac_extra_len = mod_session->response_hmac_extra_len;
328  decode_ctx.eap_packet = eap_session->this_round->response;
329 
330  ret = fr_aka_sim_decode(request->request_ctx,
331  &request->request_pairs,
333  eap_session->this_round->response->type.data,
334  eap_session->this_round->response->type.length,
335  &decode_ctx);
336 
337  /*
338  * Only good for one response packet
339  */
340  TALLOC_FREE(mod_session->response_hmac_extra);
341  mod_session->response_hmac_extra_len = 0;
342 
343  /*
344  * RFC 4187 says we *MUST* notify, not just send
345  * an EAP-Failure in this case where we cannot
346  * decode an EAP-AKA packet.
347  *
348  * We instead call the state machine and allow it
349  * to fail when it can't find the necessary
350  * attributes.
351  */
352  if (ret < 0) {
353  RPEDEBUG2("Failed decoding attributes");
354  goto done;
355  }
356 
357  if (!fr_pair_list_empty(&request->request_pairs) && RDEBUG_ENABLED2) {
358  RDEBUG2("Decoded attributes");
359  log_request_pair_list(L_DBG_LVL_2, request, NULL, &request->request_pairs, NULL);
360  }
361 
362  subtype_vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_eap_aka_sim_subtype);
363  if (!subtype_vp) {
364  REDEBUG2("Missing Sub-Type"); /* Let the state machine enter the right state */
365  break;
366  }
367 
368  RDEBUG2("Received EAP-Response/%pV", &(subtype_vp)->data);
369 
370  switch (subtype_vp->vp_uint16) {
371  /*
372  * Ingest the identity message into the checkcode
373  */
374  case FR_SUBTYPE_VALUE_AKA_IDENTITY:
375  if (mod_session->checkcode_state) {
376  RDEBUG2("Updating checkcode");
378  eap_session->this_round->response) < 0) {
379  RPWDEBUG("Failed updating checkcode");
380  }
381  }
382  break;
383 
384  case FR_SUBTYPE_VALUE_AKA_SIM_REAUTHENTICATION:
385  case FR_SUBTYPE_VALUE_AKA_CHALLENGE:
386  /*
387  * Include our copy of the checkcode if we've been
388  * calculating it. This is put in the control list
389  * so the state machine can check they're identical.
390  *
391  * This lets us simulate checkcode failures easily
392  * when testing the state machine.
393  */
394  if (mod_session->checkcode_state) {
395  uint8_t *checkcode;
396  fr_pair_t *vp;
397 
399  if (fr_aka_sim_crypto_finalise_checkcode(vp, &checkcode, mod_session->checkcode_state) < 0) {
400  RPWDEBUG("Failed calculating checkcode");
402  } else {
403  fr_pair_value_memdup_buffer_shallow(vp, checkcode, false); /* Buffer already in the correct ctx */
404  }
405  }
406  FALL_THROUGH;
407 
408  case FR_SUBTYPE_VALUE_SIM_CHALLENGE:
409  {
410  fr_pair_t *vp;
411  ssize_t slen;
412  uint8_t *buff;
413 
416 
417  slen = fr_aka_sim_crypto_sign_packet(buff, eap_session->this_round->response, true,
418  mod_session->ctx.hmac_md,
419  mod_session->ctx.k_aut,
420  mod_session->ctx.k_aut_len,
421  mod_session->response_hmac_extra,
422  mod_session->response_hmac_extra_len);
423  if (slen <= 0) {
424  RPEDEBUG("AT_MAC calculation failed");
427  }
428  }
429  break;
430 
431  default:
432  break;
433  }
434  break;
435  }
436 
437 done:
438  /*
439  * Setup our encode function as the resumption
440  * frame when the state machine finishes with
441  * this round.
442  */
443  (void)unlang_module_yield(request, mod_encode, NULL, 0, NULL);
444 
445  if (virtual_server_push(request, inst->virtual_server, UNLANG_SUB_FRAME) < 0) {
448  }
449 
451 }
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition: action.h:35
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
Definition: action.h:39
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
Definition: action.h:37
#define RCSID(id)
Definition: build.h:481
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
Definition: build.h:320
eap_type_data_t type
Definition: compose.h:39
bool set_request_id
Whether the EAP-Method already set the next request ID.
Definition: compose.h:51
eap_packet_t * response
Packet we received from the peer.
Definition: compose.h:49
eap_code_t code
Definition: compose.h:36
uint8_t id
Definition: compose.h:37
eap_packet_t * request
Packet we will send to the peer.
Definition: compose.h:50
@ FR_EAP_CODE_FAILURE
Definition: types.h:40
@ FR_EAP_CODE_REQUEST
Definition: types.h:37
@ FR_EAP_CODE_SUCCESS
Definition: types.h:39
eap_type_t num
Definition: types.h:110
size_t length
Definition: types.h:111
uint8_t * data
Definition: types.h:112
enum eap_code eap_code_t
@ FR_EAP_METHOD_SIM
Definition: types.h:63
@ FR_EAP_METHOD_NAK
Definition: types.h:48
@ FR_EAP_METHOD_AKA
Definition: types.h:68
@ FR_EAP_METHOD_AKA_PRIME
Definition: types.h:96
@ FR_EAP_METHOD_IDENTITY
Definition: types.h:46
size_t hmac_extra_len
Definition: base.h:244
ssize_t fr_aka_sim_crypto_sign_packet(uint8_t out[static AKA_SIM_MAC_DIGEST_SIZE], eap_packet_t *eap_packet, bool zero_mac, EVP_MD const *md, uint8_t const *key, size_t const key_len, uint8_t const *hmac_extra, size_t const hmac_extra_len)
Calculate the digest value for a packet.
Definition: crypto.c:284
uint8_t const * k_aut
The authentication key used for signing.
Definition: base.h:249
int fr_aka_sim_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict, uint8_t const *data, size_t data_len, fr_aka_sim_ctx_t *decode_ctx)
Decode SIM/AKA/AKA' specific packet data.
Definition: decode.c:942
ssize_t fr_aka_sim_crypto_finalise_checkcode(TALLOC_CTX *ctx, uint8_t **out, fr_aka_sim_checkcode_t *checkcode)
Write out the final checkcode value.
Definition: crypto.c:196
EVP_MD const * hmac_md
HMAC digest algorithm, usually EVP_sha1().
Definition: base.h:240
eap_packet_t * eap_packet
Needed for validating AT_MAC.
Definition: base.h:238
EVP_MD const * checkcode_md
HMAC we use for calculating the checkcode.
Definition: base.h:241
uint8_t const * k_encr
The encryption key used for encrypting.
Definition: base.h:246
uint8_t const * hmac_extra
Extra data for the HMAC function.
Definition: base.h:243
#define AKA_SIM_MAC_DIGEST_SIZE
Length of MAC used to prevent packet modification.
Definition: base.h:42
int fr_aka_sim_crypto_update_checkcode(fr_aka_sim_checkcode_t *checkcode, eap_packet_t *eap_packet)
Digest a packet, updating the checkcode.
Definition: crypto.c:152
ssize_t fr_aka_sim_encode(request_t *request, fr_pair_list_t *to_encode, void *encode_ctx)
Definition: encode.c:867
size_t k_aut_len
Definition: base.h:250
int fr_aka_sim_crypto_init_checkcode(TALLOC_CTX *ctx, fr_aka_sim_checkcode_t **checkcode, EVP_MD const *md)
Initialise checkcode message digest.
Definition: crypto.c:114
Encoder/decoder ctx.
Definition: base.h:234
uint8_t * response_hmac_extra
Data to concatenate to response packet before validating.
Definition: module.h:74
size_t response_hmac_extra_len
Definition: module.h:76
fr_aka_sim_ctx_t ctx
Definition: module.h:79
uint8_t id
Last ID used, monotonically increments.
Definition: module.h:72
fr_aka_sim_checkcode_t * checkcode_state
Digest of all identity packets we've seen.
Definition: module.h:78
Structure used to track session state at the module level.
Definition: module.h:71
void unlang_interpet_frame_discard(request_t *request)
Discard the bottom most frame on the request's stack.
Definition: interpret.c:1737
rlm_rcode_t unlang_interpret_stack_result(request_t *request)
Get the current rcode for the frame.
Definition: interpret.c:1290
#define UNLANG_SUB_FRAME
Definition: interpret.h:36
void * opaque
Opaque data used by EAP methods.
Definition: session.h:62
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition: session.h:59
static eap_session_t * eap_session_get(request_t *request)
Definition: session.h:82
bool finished
Whether we consider this session complete.
Definition: session.h:71
Tracks the progress of a single session of any EAP method.
Definition: session.h:40
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_bidding
Definition: base.c:63
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_permanent_id_req
Definition: base.c:92
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_k_encr
Definition: base.c:78
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_checkcode
Definition: base.c:64
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_k_aut
Definition: base.c:77
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_any_id_req
Definition: base.c:60
fr_dict_t const * dict_eap_aka_sim
Definition: base.c:48
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_mac
Definition: base.c:84
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_fullauth_id_req
Definition: base.c:70
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_subtype
Definition: base.c:99
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_hmac_extra_request
Definition: base.c:71
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_hmac_extra_response
Definition: base.c:72
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
Definition: log.c:830
#define RPEDEBUG(fmt,...)
Definition: log.h:376
#define RPWDEBUG(fmt,...)
Definition: log.h:366
#define RPEDEBUG2(fmt,...)
Definition: log.h:377
#define REDEBUG2(fmt,...)
Definition: log.h:372
talloc_free(reap)
@ L_DBG_LVL_2
2nd highest priority debug messages (-xx | -X).
Definition: log.h:71
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
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
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_mem_alloc(fr_pair_t *vp, uint8_t **out, size_t size, bool tainted)
Pre-allocate a memory buffer for a "octets" type value pair.
Definition: pair.c:2930
int fr_pair_value_memdup_buffer_shallow(fr_pair_t *vp, uint8_t const *src, bool tainted)
Assign a talloced buffer to a "octets" type value pair.
Definition: pair.c:3056
static fr_internal_encode_ctx_t encode_ctx
VQP attributes.
static bool done
Definition: radclient.c:80
#define RDEBUG_ENABLED2()
Definition: radclient.h:50
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
#define RETURN_MODULE_REJECT
Definition: rcode.h:55
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
@ RLM_MODULE_INVALID
The module considers the request invalid.
Definition: rcode.h:45
@ RLM_MODULE_OK
The module is OK, continue.
Definition: rcode.h:43
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition: rcode.h:42
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
Definition: rcode.h:46
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition: rcode.h:41
@ RLM_MODULE_NOTFOUND
User not found.
Definition: rcode.h:47
@ RLM_MODULE_UPDATED
OK (pairs modified).
Definition: rcode.h:49
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition: rcode.h:48
@ RLM_MODULE_NUMCODES
How many valid return codes there are.
Definition: rcode.h:50
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition: rcode.h:44
void * data
Module's instance data.
Definition: module.h:271
#define pair_append_control(_attr, _da)
Allocate and append a fr_pair_t to the control list.
Definition: pair.h:57
#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
#define pair_append_reply(_attr, _da)
Allocate and append a fr_pair_t to reply list.
Definition: pair.h:47
#define pair_delete_control(_pair_or_da)
Delete a fr_pair_t in the control list.
Definition: pair.h:190
static char buff[sizeof("18446744073709551615")+3]
Definition: size_tests.c:41
static unlang_action_t mod_encode(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Encode EAP session data from attributes.
Definition: module.c:42
unlang_action_t eap_aka_sim_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Decode EAP session data into attribute.
Definition: module.c:297
unlang_action_t unlang_module_yield(request_t *request, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
Definition: module.c:419
RETURN_MODULE_FAIL
fr_assert(0)
fr_pair_t * subtype_vp
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
eap_type_t type
The preferred EAP-Type of this instance of the EAP-SIM/AKA/AKA' state machine.
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition: pair.h:69
static int talloc_const_free(void const *ptr)
Free const'd memory.
Definition: talloc.h:224
Functions to allow modules to push resumption frames onto the stack and inform the interpreter about ...
Master include file to access all functions and structures in the library.
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
Definition: pair_inline.c:125
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
Definition: pair.h:591
static fr_slen_t data
Definition: value.h:1265
unlang_action_t virtual_server_push(request_t *request, CONF_SECTION *server_cs, bool top_frame)
Set the request processing function.