27 #include <freeradius-devel/server/protocol.h>
28 #include <freeradius-devel/server/pair.h>
29 #include <freeradius-devel/util/debug.h>
30 #include <freeradius-devel/util/pair.h>
31 #include <freeradius-devel/unlang/interpret.h>
32 #include <freeradius-devel/dns/dns.h>
33 #include <freeradius-devel/protocol/dns/rfc1034.h>
37 #define FR_DNS_RCODE_MAX FR_RCODE_VALUE_BAD_COOKIE
120 #define PROCESS_PACKET_TYPE fr_dns_packet_code_t
121 #define PROCESS_CODE_MAX FR_DNS_CODE_MAX
122 #define PROCESS_CODE_DO_NOT_RESPOND FR_DNS_DO_NOT_RESPOND
123 #define PROCESS_PACKET_CODE_VALID FR_DNS_PACKET_CODE_VALID
124 #define PROCESS_INST process_dns_t
128 #define PROCESS_STATE_EXTRA_FIELDS fr_value_box_t const **dns_rcode[RLM_MODULE_NUMCODES];
130 #include <freeradius-devel/server/process.h>
137 .offset = PROCESS_CONF_OFFSET(query),
141 .name2 =
"Query-Response",
143 .offset = PROCESS_CONF_OFFSET(query_response),
147 .name2 =
"Inverse-Query",
149 .offset = PROCESS_CONF_OFFSET(inverse_query),
153 .name2 =
"Inverse-Query-Response",
155 .offset = PROCESS_CONF_OFFSET(inverse_query_response),
161 .offset = PROCESS_CONF_OFFSET(status),
165 .name2 =
"Status-Response",
167 .offset = PROCESS_CONF_OFFSET(status_response),
173 .offset = PROCESS_CONF_OFFSET(update),
177 .name2 =
"Update-Response",
179 .offset = PROCESS_CONF_OFFSET(update_response),
183 .name2 =
"Stateful-Operation",
185 .offset = PROCESS_CONF_OFFSET(stateful_operation),
189 .name2 =
"Stateful-Operation-Response",
191 .offset = PROCESS_CONF_OFFSET(stateful_operation_response),
195 .name2 =
"Do-Not-Respond",
197 .offset = PROCESS_CONF_OFFSET(do_not_respond),
200 #define ERROR_SECTION(_name, _number) \
204 .component = MOD_POST_AUTH, \
205 .offset = PROCESS_CONF_OFFSET(rcode[_number]), \
213 ERROR_SECTION(
"Server-Failure", FR_RCODE_VALUE_SERVER_FAILURE),
215 ERROR_SECTION(
"Not-Implemented", FR_RCODE_VALUE_NOT_IMPLEMENTED),
218 ERROR_SECTION(
"YX-Resource-Record-Set", FR_RCODE_VALUE_YX_RESOURCE_RECORD_SET),
219 ERROR_SECTION(
"NX-Resource-Record-Set", FR_RCODE_VALUE_NX_RESOURCE_RECORD_SET),
222 ERROR_SECTION(
"DSO-Type-Not-Implemented", FR_RCODE_VALUE_DSO_TYPE_NOT_IMPLEMENTED),
223 ERROR_SECTION(
"Bad-Signature", FR_RCODE_VALUE_BAD_SIGNATURE),
228 ERROR_SECTION(
"Bad-Algorithm", FR_RCODE_VALUE_BAD_ALGORITHM),
229 ERROR_SECTION(
"Bad-Truncation", FR_RCODE_VALUE_BAD_TRUNCATION),
245 received ?
"Received" :
"Sending",
248 if (received || request->parent) {
258 static inline CC_HINT(always_inline)
272 REDEBUG(
"Missing Header attribute");
278 REDEBUG(
"Missing ID attribute");
284 REDEBUG(
"Missing Opcode attribute");
289 rctx->
id =
id->vp_uint16;
290 rctx->
opcode = opcode->vp_uint8;
299 static inline CC_HINT(always_inline)
317 if (ret == 0)
id->vp_uint16 = rctx->id;
325 if (ret == 0) response->vp_bool =
true;
333 if (ret == 0) opcode->vp_uint8 = rctx->opcode;
341 if (ret == 0) authoritative->vp_bool =
true;
349 static inline CC_HINT(always_inline)
355 if (!code || !*code)
return;
366 (*rcode)->data.enumv = (*rcode)->da;
382 return CALL_RECV_RCTX(
generic, rctx);
392 fr_process_state_t
const *state;
413 #ifdef __clang_analyzer__
423 (
inst->sections.rcode[rcode->vp_uint8])) {
425 inst->sections.rcode[rcode->vp_uint8],
434 NULL, 0, mctx->rctx);
440 return CALL_RESUME(recv_generic);
448 fr_process_state_t
const *state;
478 request->reply->code =
vp->vp_uint8 = state->default_reply;
480 return CALL_RESUME(send_generic);
487 fr_process_state_t
const *state;
494 request->component =
"dns";
495 request->module = NULL;
498 UPDATE_STATE(packet);
501 REDEBUG(
"Invalid packet type (%u)", request->packet->code);
507 return state->recv(p_result, mctx, request);
510 #define DNS_RCODE_COMMON \
512 [RLM_MODULE_NOOP] = &enum_rcode_no_error, \
513 [RLM_MODULE_OK] = &enum_rcode_no_error, \
514 [RLM_MODULE_UPDATED] = &enum_rcode_no_error, \
515 [RLM_MODULE_HANDLED] = &enum_rcode_no_error, \
516 [RLM_MODULE_REJECT] = &enum_rcode_refused, \
517 [RLM_MODULE_FAIL] = &enum_rcode_server_failure, \
518 [RLM_MODULE_INVALID] = &enum_rcode_format_error, \
519 [RLM_MODULE_DISALLOW] = &enum_rcode_refused, \
520 [RLM_MODULE_NOTFOUND] = &enum_rcode_name_error \
528 .recv = recv_request,
529 .resume = resume_recv_request,
530 .section_offset = PROCESS_CONF_OFFSET(query),
536 .recv = recv_request,
537 .resume = resume_recv_request,
538 .section_offset = PROCESS_CONF_OFFSET(inverse_query),
544 .recv = recv_request,
545 .resume = resume_recv_request,
546 .section_offset = PROCESS_CONF_OFFSET(status),
552 .recv = recv_request,
553 .resume = resume_recv_request,
554 .section_offset = PROCESS_CONF_OFFSET(update),
560 .recv = recv_request,
561 .resume = resume_recv_request,
562 .section_offset = PROCESS_CONF_OFFSET(stateful_operation),
567 .send = send_generic,
568 .resume = resume_send_response,
569 .section_offset = PROCESS_CONF_OFFSET(query_response),
575 .send = send_generic,
576 .resume = resume_send_response,
577 .section_offset = PROCESS_CONF_OFFSET(inverse_query_response),
583 .send = send_generic,
584 .resume = resume_send_response,
585 .section_offset = PROCESS_CONF_OFFSET(status_response),
591 .send = send_generic,
592 .resume = resume_send_response,
593 .section_offset = PROCESS_CONF_OFFSET(update_response),
599 .send = send_generic,
600 .resume = resume_send_response,
601 .section_offset = PROCESS_CONF_OFFSET(stateful_operation_response),
617 .send = send_generic,
618 .resume = resume_send_response,
619 .section_offset = PROCESS_CONF_OFFSET(do_not_respond),
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
A section grouping multiple CONF_PAIR.
@ MOD_POST_AUTH
7 methods index for postauth section.
@ MOD_AUTHORIZE
1 methods index for authorize section.
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
fr_value_box_t const ** out
Enumeration value.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
Specifies a value which must be present for the module to function.
void *_CONST data
Module instance's parsed configuration.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
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.
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.
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.
@ L_DBG_LVL_1
Highest priority debug messages (-x).
@ L_DBG
Only displayed when debugging is enabled.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_BOOL
A truth value.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Temporary structure to hold arguments for module calls.
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.
int fr_pair_update_by_da_parent(fr_pair_t *parent, fr_pair_t **out, fr_dict_attr_t const *da)
Return the first fr_pair_t matching the fr_dict_attr_t or alloc a new fr_pair_t and its subtree (and ...
RECV(for_any_server)
Validate a solicit/rebind/confirm message.
fr_dict_attr_autoload_t process_dns_dict_attr[]
CONF_SECTION * stateful_operation_response
fr_dict_autoload_t process_dns_dict[]
static void dns_packet_debug(request_t *request, fr_packet_t const *packet, fr_pair_list_t const *list, bool received)
static fr_dict_attr_t const * attr_packet_type
#define ERROR_SECTION(_name, _number)
static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Entry point into the state machine.
static fr_value_box_t const * enum_rcode_server_failure
static fr_dict_attr_t const * attr_authoritative_bit
static void dns_rcode_add(fr_pair_t **rcode, request_t *request, fr_value_box_t const **code)
Add/update the rcode attribute based on the last rlm_rcode value.
static process_dns_fields_t * dns_fields_store(request_t *request)
Keep a copy of header fields to prevent them being tampered with.
CONF_SECTION * inverse_query_response
CONF_SECTION * query_response
CONF_SECTION * stateful_operation
static fr_dict_attr_t const * attr_opcode
static fr_value_box_t const * enum_rcode_refused
static fr_dict_attr_t const * attr_response_bit
static fr_value_box_t const * enum_rcode_no_error
CONF_SECTION * query
Request/response sections.
uint8_t opcode
Opcode, what type of query this is.
static fr_dict_attr_t const * attr_id
static const virtual_server_compile_t compile_list[]
CONF_SECTION * inverse_query
static fr_process_state_t const process_state[]
#define FR_DNS_RCODE_MAX
Update this if new rcodes are added.
fr_dict_enum_autoload_t process_dns_dict_enum[]
process_dns_sections_t sections
static fr_value_box_t const * enum_rcode_name_error
uint16_t id
Identity of the request.
static fr_dict_t const * dict_dns
CONF_SECTION * update_response
static fr_value_box_t const * enum_rcode_format_error
static fr_dict_attr_t const * attr_header
CONF_SECTION * status_response
static int dns_fields_restore(request_t *request, process_dns_fields_t *rctx)
Copy values from the request header back into the response.
CONF_SECTION * do_not_respond
#define PROCESS_PACKET_CODE_VALID
fr_process_module_t process_dns
static fr_dict_attr_t const * attr_rcode
Records fields from the original request so we have a known good copy.
#define PROCESS_TRACE
Trace each state function as it's entered.
module_t common
Common fields for all loadable modules.
Common public symbol definition for all process modules.
char const * fr_dns_packet_names[FR_DNS_CODE_MAX]
@ FR_DNS_STATEFUL_OPERATION_RESPONSE
@ FR_DNS_STATEFUL_OPERATION
@ FR_DNS_INVERSE_QUERY_RESPONSE
Return codes returned by modules and virtual server sections.
#define RETURN_MODULE_INVALID
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_INVALID
The module considers the request invalid.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
@ RLM_MODULE_REJECT
Immediately reject the request.
@ RLM_MODULE_NOTFOUND
User not found.
@ RLM_MODULE_UPDATED
OK (pairs modified).
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
#define pair_update_reply(_attr, _da)
Return or allocate a fr_pair_t in the reply list.
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)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
Stores an attribute, a value and various bits of other data.
#define talloc_get_type_abort_const
unsigned int code
Packet code (type).
char const * fr_strerror(void)
Get the last library error.
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
#define COMPILE_TERMINATOR
char const * name
Name of the processing section, such as "recv" or "send".
Processing sections which are allowed in this virtual server.