The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
base.c
Go to the documentation of this file.
1 /*
2  * This program 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
5  * (at 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: cb0dcbfc38de1331d02d83a20ffa17c2b63c98a1 $
19  * @file src/process/ttls/base.c
20  * @brief TTLS process module
21  *
22  * @copyright 2021 The FreeRADIUS server project.
23  * @copyright 2021 Network RADIUS SAS (legal@networkradius.com)
24  */
25 #include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
26 
27 #include <freeradius-devel/radius/radius.h>
28 
29 #include <freeradius-devel/server/main_config.h>
30 #include <freeradius-devel/server/module.h>
31 #include <freeradius-devel/server/pair.h>
32 #include <freeradius-devel/server/protocol.h>
33 #include <freeradius-devel/server/state.h>
34 
35 #include <freeradius-devel/unlang/module.h>
36 
37 #include <freeradius-devel/util/debug.h>
38 
39 static fr_dict_t const *dict_freeradius;
40 static fr_dict_t const *dict_radius;
41 
44  { .out = &dict_freeradius, .proto = "freeradius" },
45  { .out = &dict_radius, .proto = "radius" },
46  { NULL }
47 };
48 
53 
59 static fr_dict_attr_t const *attr_state;
64 
67  { .out = &attr_auth_type, .name = "Auth-Type", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
68  { .out = &attr_module_failure_message, .name = "Module-Failure-Message", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
69  { .out = &attr_module_success_message, .name = "Module-Success-Message", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
70  { .out = &attr_stripped_user_name, .name = "Stripped-User-Name", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
71 
72  { .out = &attr_calling_station_id, .name = "Calling-Station-Id", .type = FR_TYPE_STRING, .dict = &dict_radius },
73  { .out = &attr_chap_password, .name = "CHAP-Password", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
74  { .out = &attr_nas_port, .name = "NAS-Port", .type = FR_TYPE_UINT32, .dict = &dict_radius },
75  { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_radius },
76  { .out = &attr_service_type, .name = "Service-Type", .type = FR_TYPE_UINT32, .dict = &dict_radius },
77  { .out = &attr_state, .name = "State", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
78  { .out = &attr_user_name, .name = "User-Name", .type = FR_TYPE_STRING, .dict = &dict_radius },
79  { .out = &attr_user_password, .name = "User-Password", .type = FR_TYPE_STRING, .dict = &dict_radius },
80 
81  { .out = &attr_original_packet_code, .name = "Extended-Attribute-1.Original-Packet-Code", .type = FR_TYPE_UINT32, .dict = &dict_radius },
82  { .out = &attr_error_cause, .name = "Error-Cause", .type = FR_TYPE_UINT32, .dict = &dict_radius },
83 
84  { NULL }
85 };
86 
89 
92  { .out = &enum_auth_type_accept, .name = "Accept", .attr = &attr_auth_type },
93  { .out = &enum_auth_type_reject, .name = "Reject", .attr = &attr_auth_type },
94  { NULL }
95 };
96 
97 /*
98  * RADIUS state machine configuration
99  */
100 typedef struct {
101  uint64_t nothing; // so that "access_request" isn't at offset 0
102 
107 
110 
112 
116 
120 
122  CONF_SECTION *protocol_error; /* @todo - allow protocol error as a reject reply? */
124 
125 typedef struct {
126  fr_time_delta_t timeout; //!< Maximum time between the last response and next request.
127  uint32_t max; //!< Maximum ongoing session allowed.
128 
129  uint8_t state_server_id; //!< Sets a specific byte in the state to allow the
130  //!< authenticating server to be identified in packet
131  //!<captures.
133 
134 typedef struct {
135  process_ttls_session_t session; //!< Session settings.
136 
137  fr_state_tree_t *state_tree; //!< State tree to link multiple requests/responses.
139 
140 typedef struct {
141  CONF_SECTION *server_cs; //!< Our virtual server.
142  process_ttls_sections_t sections; //!< Pointers to various config sections
143  ///< we need to execute.
144  process_ttls_auth_t auth; //!< Authentication configuration.
146 
147 #define PROCESS_PACKET_TYPE fr_radius_packet_code_t
148 #define PROCESS_CODE_MAX FR_RADIUS_CODE_MAX
149 #define PROCESS_CODE_DO_NOT_RESPOND FR_RADIUS_CODE_DO_NOT_RESPOND
150 #define PROCESS_PACKET_CODE_VALID FR_RADIUS_PACKET_CODE_VALID
151 #define PROCESS_INST process_ttls_t
152 #include <freeradius-devel/server/process.h>
153 
154 static const conf_parser_t session_config[] = {
155  { FR_CONF_OFFSET("timeout", process_ttls_session_t, timeout), .dflt = "15" },
156  { FR_CONF_OFFSET("max", process_ttls_session_t, max), .dflt = "4096" },
157  { FR_CONF_OFFSET("state_server_id", process_ttls_session_t, state_server_id) },
158 
160 };
161 
162 static const conf_parser_t auth_config[] = {
163  { FR_CONF_OFFSET_SUBSECTION("session", 0, process_ttls_auth_t, session, session_config )},
164 
166 };
167 
168 static const conf_parser_t config[] = {
169  { FR_CONF_OFFSET_SUBSECTION("Access-Request", 0, process_ttls_t, auth, auth_config) },
170 
172 };
173 
174 /*
175  * Debug the packet if requested.
176  */
177 static void radius_packet_debug(request_t *request, fr_packet_t *packet, fr_pair_list_t *list, bool received)
178 {
179 #ifdef WITH_IFINDEX_NAME_RESOLUTION
180  char if_name[IFNAMSIZ];
181 #endif
182 
183  if (!packet) return;
184  if (!RDEBUG_ENABLED) return;
185 
186  log_request(L_DBG, L_DBG_LVL_1, request, __FILE__, __LINE__, "%s %s ID %d from %s%pV%s:%i to %s%pV%s:%i "
187 #ifdef WITH_IFINDEX_NAME_RESOLUTION
188  "%s%s%s"
189 #endif
190  "",
191  received ? "Received" : "Sending",
192  fr_radius_packet_name[packet->code],
193  packet->id,
194  packet->socket.inet.src_ipaddr.af == AF_INET6 ? "[" : "",
195  fr_box_ipaddr(packet->socket.inet.src_ipaddr),
196  packet->socket.inet.src_ipaddr.af == AF_INET6 ? "]" : "",
197  packet->socket.inet.src_port,
198  packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "[" : "",
199  fr_box_ipaddr(packet->socket.inet.dst_ipaddr),
200  packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "]" : "",
201  packet->socket.inet.dst_port
202 #ifdef WITH_IFINDEX_NAME_RESOLUTION
203  , packet->socket.inet.ifindex ? "via " : "",
204  packet->socket.inet.ifindex ? fr_ifname_from_ifindex(if_name, packet->socket.inet.ifindex) : "",
205  packet->socket.inet.ifindex ? " " : ""
206 #endif
207  );
208 
209  if (received || request->parent) {
210  log_request_pair_list(L_DBG_LVL_1, request, NULL, list, NULL);
211  } else {
212  log_request_proto_pair_list(L_DBG_LVL_1, request, NULL, list, NULL);
213  }
214 }
215 
216 RESUME(auth_type);
217 
218 RESUME(access_request)
219 {
220  rlm_rcode_t rcode = *p_result;
221  fr_pair_t *vp;
222  CONF_SECTION *cs;
223  fr_dict_enum_value_t const *dv;
224  fr_process_state_t const *state;
226 
228 
230 
231  UPDATE_STATE(packet);
232 
233  request->reply->code = state->packet_type[rcode];
234  if (!request->reply->code) request->reply->code = state->default_reply;
235  if (!request->reply->code) request->reply->code = PROCESS_CODE_DO_NOT_RESPOND;
236  UPDATE_STATE_CS(reply);
237 
238  if (request->reply->code == FR_RADIUS_CODE_DO_NOT_RESPOND) {
239  RDEBUG("The 'recv Access-Request' section returned %s - not sending a response",
240  fr_table_str_by_value(rcode_table, rcode, "<INVALID>"));
241 
242  send_reply:
243  fr_assert(state->send != NULL);
244  return CALL_SEND_STATE(state);
245  }
246 
247  /*
248  * Run authenticate foo { ... }
249  */
250  vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_auth_type);
251  if (!vp) goto send_reply;
252 
253  dv = fr_dict_enum_by_value(vp->da, &vp->data);
254  if (!dv) goto send_reply;
255 
256  /*
257  * The magic Auth-Type accept value
258  * which means skip the authenticate
259  * section...
260  */
262  request->reply->code = FR_RADIUS_CODE_ACCESS_ACCEPT;
263  goto send_reply;
264  } else if (fr_value_box_cmp(enum_auth_type_reject, dv->value) == 0) {
265  request->reply->code = FR_RADIUS_CODE_ACCESS_REJECT;
266  goto send_reply;
267  }
268 
269  cs = cf_section_find(inst->server_cs, "authenticate", dv->name);
270  if (!cs) {
271  RDEBUG2("No 'authenticate %s { ... }' section found - skipping...", dv->name);
272  goto send_reply;
273  }
274 
275  /*
276  * Run the "Authenticate = foo" section.
277  *
278  * And continue with sending the generic reply.
279  */
280  RDEBUG("Running 'authenticate %s' from file %s", cf_section_name2(cs), cf_filename(cs));
281  return unlang_module_yield_to_section(p_result, request,
282  cs, RLM_MODULE_NOOP, resume_auth_type,
283  NULL, 0, mctx->rctx);
284 }
285 
286 RESUME(auth_type)
287 {
288  static const fr_process_rcode_t auth_type_rcode = {
297  };
298 
299  rlm_rcode_t rcode = *p_result;
300  fr_pair_t *vp;
301  fr_process_state_t const *state;
302 
304 
306  fr_assert(FR_RADIUS_PACKET_CODE_VALID(request->reply->code));
307 
308  if (auth_type_rcode[rcode] == FR_RADIUS_CODE_DO_NOT_RESPOND) {
309  request->reply->code = auth_type_rcode[rcode];
310  UPDATE_STATE(reply);
311 
312  RDEBUG("The 'authenticate' section returned %s - not sending a response",
313  fr_table_str_by_value(rcode_table, rcode, "<INVALID>"));
314 
315  fr_assert(state->send != NULL);
316  return state->send(p_result, mctx, request);
317  }
318 
319  /*
320  * Most cases except handled...
321  */
322  if (auth_type_rcode[rcode]) request->reply->code = auth_type_rcode[rcode];
323 
324  switch (request->reply->code) {
325  case 0:
326  RDEBUG("No reply code was set. Forcing to Access-Reject");
327  request->reply->code = FR_RADIUS_CODE_ACCESS_REJECT;
328  FALL_THROUGH;
329 
330  /*
331  * Print complaints before running "send Access-Reject"
332  */
334  RDEBUG2("Failed to authenticate the user");
335 
336  /*
337  * Maybe the shared secret is wrong?
338  */
339  vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_password);
340  if (vp) {
341  if (RDEBUG_ENABLED2) {
342  uint8_t const *p;
343 
344  p = (uint8_t const *) vp->vp_strvalue;
345  while (*p) {
346  int size;
347 
348  size = fr_utf8_char(p, -1);
349  if (!size) {
350  RWDEBUG("Unprintable characters in the password. "
351  "Double-check the shared secret on the server "
352  "and the NAS!");
353  break;
354  }
355  p += size;
356  }
357  }
358  }
359  break;
360 
361  /*
362  * Access-Challenge sections require a State. If there is
363  * none, create one here. This is so that the State
364  * attribute is accessible in the "send Access-Challenge"
365  * section.
366  */
368  if ((vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_state)) != NULL) {
369  uint8_t buffer[16];
370 
371  fr_rand_buffer(buffer, sizeof(buffer));
372 
374  fr_pair_value_memdup(vp, buffer, sizeof(buffer), false);
375  }
376  break;
377 
378  default:
379  break;
380 
381  }
382  UPDATE_STATE(reply);
383 
384  fr_assert(state->send != NULL);
385  return state->send(p_result, mctx, request);
386 }
387 
388 RESUME(access_accept)
389 {
390  fr_pair_t *vp;
392 
394 
395  /*
396  * Check that there is a name which can be used to
397  * identify the user. The configuration depends on
398  * User-Name or Stripped-User-Name existing, and being
399  * (mostly) unique to that user.
400  */
401  if (!request->parent &&
402  ((vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_name)) != NULL) &&
403  (vp->vp_strvalue[0] == '@') &&
404  !fr_pair_find_by_da(&request->request_pairs, NULL, attr_stripped_user_name)) {
405  RWDEBUG("User-Name is anonymized, and no Stripped-User-Name exists.");
406  RWDEBUG("It may be difficult or impossible to identify the user.");
407  RWDEBUG("Please update Stripped-User-Name with information which identifies the user.");
408  }
409 
410  fr_state_discard(inst->auth.state_tree, request);
412 }
413 
414 RESUME(access_reject)
415 {
417 
419 
420  fr_state_discard(inst->auth.state_tree, request);
422 }
423 
424 RESUME(access_challenge)
425 {
426  CONF_SECTION *cs;
427  fr_process_state_t const *state;
429 
431 
432  /*
433  * Cache the state context.
434  *
435  * If this fails, don't respond to the request.
436  */
437  if (fr_request_to_state(inst->auth.state_tree, request) < 0) {
438  request->reply->code = FR_RADIUS_CODE_DO_NOT_RESPOND;
439  UPDATE_STATE_CS(reply);
440  return CALL_SEND_STATE(state);
441  }
442 
443  fr_assert(request->reply->code == FR_RADIUS_CODE_ACCESS_CHALLENGE);
445 }
446 
447 RESUME(protocol_error)
448 {
449  fr_pair_t *vp;
450 
452 
453  fr_assert(FR_RADIUS_PACKET_CODE_VALID(request->reply->code));
454 
455  /*
456  * https://tools.ietf.org/html/rfc7930#section-4
457  */
458  vp = fr_pair_find_by_da_nested(&request->reply_pairs, NULL, attr_original_packet_code);
459  if (!vp) {
460  vp = fr_pair_afrom_da(request->reply_ctx, attr_original_packet_code);
461  if (vp) {
462  vp->vp_uint32 = request->packet->code;
463  fr_pair_append(&request->reply_pairs, vp);
464  }
465  }
466 
467  /*
468  * If there's no Error-Cause, then include a generic 404.
469  */
470  vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_error_cause);
471  if (!vp) {
472  vp = fr_pair_afrom_da(request->reply_ctx, attr_error_cause);
473  if (vp) {
474  vp->vp_uint32 = FR_ERROR_CAUSE_VALUE_INVALID_REQUEST;
475  fr_pair_append(&request->reply_pairs, vp);
476  }
477  }
478 
479  /*
480  * And do the generic processing after running a "send" section.
481  */
482  return CALL_RESUME(send_generic);
483 }
484 
485 static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
486 {
487  fr_process_state_t const *state;
488 
490 
492 
493  fr_assert(FR_RADIUS_PACKET_CODE_VALID(request->packet->code));
494 
495  request->component = "radius";
496  request->module = NULL;
497  fr_assert(request->dict == dict_radius);
498 
499  UPDATE_STATE(packet);
500 
501  radius_packet_debug(request, request->packet, &request->request_pairs, true);
502 
503  return state->recv(p_result, mctx, request);
504 }
505 
506 static int mod_instantiate(module_inst_ctx_t const *mctx)
507 {
508  process_ttls_t *inst = talloc_get_type_abort(mctx->mi->data, process_ttls_t);
509 
510  inst->server_cs = cf_item_to_section(cf_parent(mctx->mi->conf));
511 
512  inst->auth.state_tree = fr_state_tree_init(inst, attr_state, main_config->spawn_workers, inst->auth.session.max,
513  inst->auth.session.timeout, inst->auth.session.state_server_id,
514  fr_hash_string(cf_section_name2(inst->server_cs)));
515 
516  return 0;
517 }
518 
519 static int mod_bootstrap(module_inst_ctx_t const *mctx)
520 {
521  CONF_SECTION *server_cs = cf_item_to_section(cf_parent(mctx->mi->conf));
522 
523  if (virtual_server_section_attribute_define(server_cs, "authenticate", attr_auth_type) < 0) return -1;
524 
525  return 0;
526 }
527 
528 /*
529  * rcodes not listed under a packet_type
530  * mean that the packet code will not be
531  * changed.
532  */
533 static fr_process_state_t const process_state[] = {
535  .packet_type = {
539 
545  },
546  .rcode = RLM_MODULE_NOOP,
547  .recv = recv_generic,
548  .resume = resume_access_request,
549  .section_offset = offsetof(process_ttls_sections_t, access_request),
550  },
552  .packet_type = {
557  },
558  .rcode = RLM_MODULE_NOOP,
559  .send = send_generic,
560  .resume = resume_access_accept,
561  .section_offset = offsetof(process_ttls_sections_t, access_accept),
562  },
564  .packet_type = {
569  },
570  .rcode = RLM_MODULE_NOOP,
571  .send = send_generic,
572  .resume = resume_access_reject,
573  .section_offset = offsetof(process_ttls_sections_t, access_reject),
574  },
576  .packet_type = {
581  },
582  .rcode = RLM_MODULE_NOOP,
583  .send = send_generic,
584  .resume = resume_access_challenge,
585  .section_offset = offsetof(process_ttls_sections_t, access_challenge),
586  },
587 
588 
589  [ FR_RADIUS_CODE_PROTOCOL_ERROR ] = { /* @todo - fill out required fields */
590  .packet_type = {
595  },
596  .rcode = RLM_MODULE_NOOP,
597  .send = send_generic,
598  .resume = resume_protocol_error,
599  .section_offset = offsetof(process_ttls_sections_t, protocol_error),
600  },
602  .packet_type = {
607 
613  },
614  .rcode = RLM_MODULE_NOOP,
615  .send = send_generic,
616  .resume = resume_send_generic,
617  .section_offset = offsetof(process_ttls_sections_t, do_not_respond),
618  }
619 };
620 
622  {
623  .section = SECTION_NAME("recv", "Access-Request"),
624  .actions = &mod_actions_authorize,
625  .offset = PROCESS_CONF_OFFSET(access_request),
626  },
627  {
628  .section = SECTION_NAME("send", "Access-Accept"),
629  .actions = &mod_actions_postauth,
630  .offset = PROCESS_CONF_OFFSET(access_accept),
631  },
632  {
633  .section = SECTION_NAME("send", "Access-Challenge"),
634  .actions = &mod_actions_postauth,
635  .offset = PROCESS_CONF_OFFSET(access_challenge),
636  },
637  {
638  .section = SECTION_NAME("send", "Access-Reject"),
639  .actions = &mod_actions_postauth,
640  .offset = PROCESS_CONF_OFFSET(access_reject),
641  },
642 
643  {
644  .section = SECTION_NAME("send", "Protocol-Error"),
645  .actions = &mod_actions_postauth,
646  .offset = PROCESS_CONF_OFFSET(protocol_error),
647  },
648  {
649  .section = SECTION_NAME("send", "Do-Not-Respond"),
650  .actions = &mod_actions_postauth,
651  .offset = PROCESS_CONF_OFFSET(do_not_respond),
652  },
653  {
654  .section = SECTION_NAME("authenticate", CF_IDENT_ANY),
655  .actions = &mod_actions_authenticate
656  },
658 };
659 
662  .common = {
663  .magic = MODULE_MAGIC_INIT,
664  .name = "ttls",
665  .config = config,
666  .inst_size = sizeof(process_ttls_t),
667 
668  .bootstrap = mod_bootstrap,
670  },
671  .process = mod_process,
672  .compile_list = compile_list,
673  .dict = &dict_radius
674 };
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
while(1)
Definition: acutest.h:856
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
Definition: build.h:320
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:627
#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
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
Definition: cf_parse.h:297
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:564
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:101
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
Definition: cf_util.c:1028
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1185
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition: cf_util.c:684
#define cf_parent(_cf)
Definition: cf_util.h:101
#define cf_filename(_cf)
Definition: cf_util.h:107
#define CF_IDENT_ANY
Definition: cf_util.h:78
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
Definition: defs.h:43
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
Definition: defs.h:33
@ FR_RADIUS_CODE_DO_NOT_RESPOND
Special rcode to indicate we will not respond.
Definition: defs.h:54
@ FR_RADIUS_CODE_ACCESS_ACCEPT
RFC2865 - Access-Accept.
Definition: defs.h:34
@ FR_RADIUS_CODE_PROTOCOL_ERROR
RFC7930 - Protocol-Error (generic NAK)
Definition: defs.h:52
@ FR_RADIUS_CODE_ACCESS_REJECT
RFC2865 - Access-Reject.
Definition: defs.h:35
static fr_time_delta_t timeout
Definition: dhcpclient.c:54
fr_value_box_t const ** out
Enumeration value.
Definition: dict.h:256
fr_dict_enum_value_t * fr_dict_enum_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the structure representing an enum value in a fr_dict_attr_t.
Definition: dict_util.c:3349
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:267
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:280
fr_value_box_t const * value
Enum value (what name maps to).
Definition: dict.h:230
char const * name
Enum name.
Definition: dict.h:227
Specifies an attribute which must be present for the module to function.
Definition: dict.h:266
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:279
Specifies a value which must be present for the module to function.
Definition: dict.h:255
Value of an enumerated attribute.
Definition: dict.h:226
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:63
uint32_t fr_hash_string(char const *p)
Definition: hash.c:865
fr_dict_attr_t const * attr_packet_type
Definition: base.c:91
fr_dict_attr_t const * attr_state
Definition: base.c:101
fr_dict_t const * dict_freeradius
Definition: base.c:77
fr_dict_t const * dict_radius
Definition: base.c:78
fr_dict_attr_t const * attr_user_name
Definition: base.c:102
void log_request_proto_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 list of protocol fr_pair_ts.
Definition: log.c:854
void log_request(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to normal logging functions.
Definition: log.c:612
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 RWDEBUG(fmt,...)
Definition: log.h:361
@ L_DBG_LVL_1
Highest priority debug messages (-x).
Definition: log.h:70
@ L_DBG
Only displayed when debugging is enabled.
Definition: log.h:59
main_config_t const * main_config
Main server configuration.
Definition: main_config.c:69
bool spawn_workers
Should the server spawn threads.
Definition: main_config.h:58
@ 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_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
unlang_mod_actions_t const mod_actions_authenticate
Definition: mod_action.c:29
unlang_mod_actions_t const mod_actions_authorize
Definition: mod_action.c:44
unlang_mod_actions_t const mod_actions_postauth
Definition: mod_action.c:88
module_instance_t const * mi
Instance of the module being instantiated.
Definition: module_ctx.h:42
module_instance_t * mi
Instance of the module being instantiated.
Definition: module_ctx.h:51
Temporary structure to hold arguments for module calls.
Definition: module_ctx.h:41
Temporary structure to hold arguments for instantiation calls.
Definition: module_ctx.h:50
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
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
Definition: pair.c:283
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
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition: pair.c:1345
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
size_t fr_utf8_char(uint8_t const *str, ssize_t inlen)
Checks for utf-8, taken from http://www.w3.org/International/questions/qa-forms-utf-8.
Definition: print.c:39
RESUME(check_yiaddr)
Definition: base.c:133
CONF_SECTION * disconnect_nak
Definition: base.c:119
fr_state_tree_t * state_tree
State tree to link multiple requests/responses.
Definition: base.c:137
CONF_SECTION * access_request
Definition: base.c:103
CONF_SECTION * coa_ack
Definition: base.c:114
static fr_dict_attr_t const * attr_user_password
Definition: base.c:61
static fr_dict_attr_t const * attr_module_failure_message
Definition: base.c:50
CONF_SECTION * access_reject
Definition: base.c:105
CONF_SECTION * access_accept
Definition: base.c:104
CONF_SECTION * status_server
Definition: base.c:111
static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition: base.c:485
static virtual_server_compile_t const compile_list[]
Definition: base.c:621
process_ttls_session_t session
Session settings.
Definition: base.c:135
fr_time_delta_t timeout
Maximum time between the last response and next request.
Definition: base.c:126
fr_dict_autoload_t process_ttls_dict[]
Definition: base.c:43
process_ttls_sections_t sections
Pointers to various config sections we need to execute.
Definition: base.c:142
CONF_SECTION * do_not_respond
Definition: base.c:121
static fr_dict_attr_t const * attr_stripped_user_name
Definition: base.c:52
static fr_dict_attr_t const * attr_chap_password
Definition: base.c:55
static const conf_parser_t session_config[]
Definition: base.c:154
CONF_SECTION * accounting_request
Definition: base.c:108
static fr_dict_attr_t const * attr_calling_station_id
Definition: base.c:54
CONF_SECTION * server_cs
Our virtual server.
Definition: base.c:141
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Definition: base.c:519
static fr_dict_attr_t const * attr_auth_type
Definition: base.c:49
CONF_SECTION * coa_nak
Definition: base.c:115
static fr_value_box_t const * enum_auth_type_reject
Definition: base.c:88
static fr_dict_attr_t const * attr_error_cause
Definition: base.c:63
CONF_SECTION * protocol_error
Definition: base.c:122
static const conf_parser_t auth_config[]
Definition: base.c:162
static fr_process_state_t const process_state[]
Definition: base.c:533
CONF_SECTION * accounting_response
Definition: base.c:109
uint32_t max
Maximum ongoing session allowed.
Definition: base.c:127
process_ttls_auth_t auth
Authentication configuration.
Definition: base.c:144
CONF_SECTION * disconnect_request
Definition: base.c:117
static void radius_packet_debug(request_t *request, fr_packet_t *packet, fr_pair_list_t *list, bool received)
Definition: base.c:177
uint64_t nothing
Definition: base.c:101
static fr_value_box_t const * enum_auth_type_accept
Definition: base.c:87
static fr_dict_attr_t const * attr_nas_port
Definition: base.c:56
CONF_SECTION * disconnect_ack
Definition: base.c:118
CONF_SECTION * coa_request
Definition: base.c:113
fr_dict_attr_autoload_t process_ttls_dict_attr[]
Definition: base.c:66
uint8_t state_server_id
Sets a specific byte in the state to allow the authenticating server to be identified in packet captu...
Definition: base.c:129
static fr_dict_attr_t const * attr_service_type
Definition: base.c:58
static fr_dict_attr_t const * attr_original_packet_code
Definition: base.c:62
static const conf_parser_t config[]
Definition: base.c:168
CONF_SECTION * access_challenge
Definition: base.c:106
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition: base.c:506
static fr_dict_attr_t const * attr_module_success_message
Definition: base.c:51
fr_dict_enum_autoload_t process_ttls_dict_enum[]
Definition: base.c:91
#define PROCESS_CODE_DO_NOT_RESPOND
Definition: base.c:149
fr_process_module_t process_ttls
Definition: base.c:661
#define PROCESS_TRACE
Trace each state function as it's entered.
Definition: process.h:65
module_t common
Common fields for all loadable modules.
Definition: process.h:55
Common public symbol definition for all process modules.
Definition: process.h:54
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
Definition: base.c:112
#define RDEBUG_ENABLED2()
Definition: radclient.h:50
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
#define RDEBUG(fmt,...)
Definition: radclient.h:53
#define RDEBUG_ENABLED()
Definition: radclient.h:49
static void send_reply(int sockfd, fr_channel_data_t *reply)
Definition: radius1_test.c:190
#define FR_RADIUS_PACKET_CODE_VALID(_x)
Definition: radius.h:52
void fr_rand_buffer(void *start, size_t length)
Definition: rand.c:126
fr_table_num_sorted_t const rcode_table[]
Definition: rcode.c:35
#define RETURN_MODULE_OK
Definition: rcode.h:57
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
static int instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_rest.c:1302
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition: section.h:40
CONF_SECTION * conf
Module's instance configuration.
Definition: module.h:329
void * data
Module's instance data.
Definition: module.h:271
#define pair_update_reply(_attr, _da)
Return or allocate a fr_pair_t in the reply list.
Definition: pair.h:129
fr_state_tree_t * fr_state_tree_init(TALLOC_CTX *ctx, fr_dict_attr_t const *da, bool thread_safe, uint32_t max_sessions, fr_time_delta_t timeout, uint8_t server_id, uint32_t context_id)
Initialise a new state tree.
Definition: state.c:222
void fr_state_discard(fr_state_tree_t *state, request_t *request)
Called when sending an Access-Accept/Access-Reject to discard state information.
Definition: state.c:606
int fr_request_to_state(fr_state_tree_t *state, request_t *request)
Transfer ownership of the state fr_pair_ts and ctx, back to a state entry.
Definition: state.c:737
unlang_action_t unlang_module_yield_to_section(rlm_rcode_t *p_result, request_t *request, CONF_SECTION *subcs, rlm_rcode_t default_rcode, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Definition: module.c:248
fr_assert(0)
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
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition: pair.h:69
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:772
#define talloc_get_type_abort_const
Definition: talloc.h:282
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
unsigned int code
Packet code (type).
Definition: packet.h:61
fr_socket_t socket
This packet was received on.
Definition: packet.h:57
int id
Packet ID (used to link requests/responses).
Definition: packet.h:60
int af
AF_INET, AF_INET6, or AF_UNIX.
Definition: socket.h:78
int8_t fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b)
Compare two values.
Definition: value.c:676
#define fr_box_ipaddr(_val)
Definition: value.h:294
int virtual_server_section_attribute_define(CONF_SECTION *server_cs, char const *subcs_name, fr_dict_attr_t const *da)
Define a values for Auth-Type attributes by the sections present in a virtual-server.
#define COMPILE_TERMINATOR
section_name_t const * section
Identifier for the section.
Processing sections which are allowed in this virtual server.