28RCSID(
"$Id: e21119355396fc2d999f6a3bee7a0a8a0f6650c4 $")
30#include <freeradius-devel/radius/radius.h>
31#include <freeradius-devel/unlang/xlat_func.h>
88static char const hextab[] =
"0123456789abcdef";
90#define is_modhex(x) (memchr(modhextab, tolower(x), 16))
110 for (i = 0; i < len; i += 2) {
111 if (modhex[i] ==
'\0') {
118 if (modhex[i + 1] ==
'\0')
148 fr_value_box_list_t *
in)
152 char *p =
UNCONST(
char *, arg->vb_strvalue);
159 REDEBUG(
"Modhex string invalid");
173 PERROR(
"%s", __FUNCTION__);
178 PERROR(
"%s", __FUNCTION__);
227 if (!
inst->auth_type) {
228 WARN(
"Failed to find 'authenticate %s {...}' section. Yubikey authentication will likely not work",
232 if (
inst->validate) {
246 cf_log_err(
conf,
"Requires libykclient for OTP validation against Yubicloud servers");
266 for (i =
inst->id_len; i < len; i++) {
283 char const *passcode;
300 RDEBUG2(
"No cleartext password in the request. Can't do Yubikey authentication");
306 passcode = password->vp_strvalue;
307 len = password->vp_length;
317 RDEBUG2(
"User-Password value is not the correct length, expected at least %u bytes, got %zu bytes",
323 otp = passcode + password_len;
327 RDMARKER(otp, -(ret),
"User-Password (aes-block) value contains non modhex chars");
329 RDEBUG2(
"User-Password (aes-block) value contains non modhex chars");
350 RDEBUG2(
"request.%pP", password);
355 passcode =
vp->vp_strvalue;
370 if (!
inst->auth_type) {
371 WARN(
"No 'authenticate %s {...}' section or 'Auth-Type = %s' set. Cannot setup Yubikey authentication",
388 char const *passcode = NULL;
397 RDEBUG2(
"No Yubikey-OTP attribute found, falling back to User-Password");
403 REDEBUG(
"No User-Password in the request. Can't do Yubikey authentication");
408 passcode =
vp->vp_strvalue;
418 REDEBUG(
"%s value is not the correct length, expected bytes %u, got bytes %zu",
426 REMARKER(passcode, -ret,
"Passcode (aes-block) value contains non modhex chars");
428 RERROR(
"Passcode (aes-block) value contains non modhex chars");
Unlang interpreter actions.
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define CONF_PARSER_TERMINATOR
#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
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
@ CONF_FLAG_SECRET
Only print value if debug level >= 3.
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Defines a CONF_PAIR to C data type mapping.
A section grouping multiple CONF_PAIR.
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
#define cf_log_err(_cf, _fmt,...)
static int split(char **input, char **output, bool syntax_string)
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
#define fr_dict_autofree(_to_free)
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.
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
#define fr_dict_autoload(_to_load)
fr_dict_enum_value_t const * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
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.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
static xlat_action_t modhex_to_hex_xlat(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Xlat to convert Yubikey modhex to standard hex.
rlm_rcode_t rcode
The current rcode, from executing the instruction or merging the result from a frame.
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
#define REMARKER(_str, _marker_idx, _marker,...)
Output string with error marker, showing where format error occurred.
#define RDMARKER(_str, _marker_idx, _marker,...)
Output string with error marker, showing where format error occurred.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_OCTETS
Raw octets.
module_instance_t const * mi
Instance of the module being instantiated.
module_instance_t * mi
Module instance to detach.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for detach calls.
Temporary structure to hold arguments for instantiation calls.
bool module_rlm_section_type_set(request_t *request, fr_dict_attr_t const *type_da, fr_dict_enum_value_t const *enumv)
Set the next section type if it's not already set.
module_t common
Common fields presented by all modules.
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.
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
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_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
int fr_pair_value_bstr_realloc(fr_pair_t *vp, char **out, size_t size)
Change the length of a buffer for a "string" type value pair.
static const conf_parser_t config[]
#define pair_update_request(_attr, _da)
Return codes returned by modules and virtual server sections.
#define RETURN_UNLANG_INVALID
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
#define RETURN_UNLANG_NOOP
static int mod_detach(module_detach_ctx_t const *mctx)
static int instantiate(module_inst_ctx_t const *mctx)
static int mod_load(void)
fr_dict_attr_t const * attr_user_password
static xlat_arg_parser_t const modhex_to_hex_xlat_arg[]
fr_dict_attr_t const * attr_yubikey_random
fr_dict_attr_t const * attr_yubikey_counter
static ssize_t modhex2hex(char const *modhex, char *hex, size_t len)
Convert yubikey modhex to normal hex.
static char const modhextab[]
static fr_dict_t const * dict_freeradius
fr_dict_attr_t const * attr_yubikey_public_id
static fr_dict_t const * dict_radius
static int mod_bootstrap(module_inst_ctx_t const *mctx)
fr_dict_attr_t const * attr_yubikey_key
fr_dict_attr_t const * attr_auth_type
fr_dict_attr_t const * attr_yubikey_timestamp
static unlang_action_t mod_authorize(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
fr_dict_attr_t const * attr_yubikey_otp
static void mod_unload(void)
fr_dict_attr_autoload_t rlm_yubikey_dict_attr[]
static char const hextab[]
static unlang_action_t mod_authenticate(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
fr_dict_attr_t const * attr_yubikey_private_id
static const conf_parser_t module_config[]
fr_dict_autoload_t rlm_yubikey_dict[]
static int otp_string_valid(rlm_yubikey_t const *inst, char const *otp, size_t len)
static int mod_instantiate(module_inst_ctx_t const *mctx)
unlang_action_t rlm_yubikey_validate(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request, char const *passcode)
unlang_action_t rlm_yubikey_decrypt(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request, char const *passcode)
int rlm_yubikey_ykclient_init(CONF_SECTION *conf, rlm_yubikey_t *inst)
#define YUBIKEY_TOKEN_LEN
int rlm_yubikey_ykclient_detach(rlm_yubikey_t *inst)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
char const * name
Instance name e.g. user_database.
CONF_SECTION * conf
Module's instance configuration.
size_t inst_size
Size of the module's instance data.
void * data
Module's instance data.
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Named methods exported by a module.
eap_aka_sim_process_conf_t * inst
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
#define talloc_get_type_abort_const
uint8_t required
Argument must be present, and non-empty.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition for a single argument consumend by an xlat function.
static size_t char ** out
void xlat_func_flags_set(xlat_t *x, xlat_func_flags_t flags)
Specify flags that alter the xlat's behaviour.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.
void xlat_func_unregister(char const *name)
Unregister an xlat function.