26 RCSID(
"$Id: 5806b080de1f9d079885f4c026342b0eb945fb8e $")
28 #include <freeradius-devel/radius/radius.h>
29 #include <freeradius-devel/unlang/xlat_func.h>
86 static char const hextab[] =
"0123456789abcdef";
88 #define is_modhex(x) (memchr(modhextab, tolower(x), 16))
108 for (i = 0; i < len; i += 2) {
109 if (modhex[i] ==
'\0') {
116 if (modhex[i + 1] ==
'\0')
146 fr_value_box_list_t *
in)
150 char *p =
UNCONST(
char *, arg->vb_strvalue);
157 REDEBUG(
"Modhex string invalid");
171 PERROR(
"%s", __FUNCTION__);
176 PERROR(
"%s", __FUNCTION__);
225 if (!
inst->auth_type) {
226 WARN(
"Failed to find 'authenticate %s {...}' section. Yubikey authentication will likely not work",
230 if (
inst->validate) {
244 cf_log_err(
conf,
"Requires libykclient for OTP validation against Yubicloud servers");
264 for (i =
inst->id_len; i < len; i++) {
281 char const *passcode;
298 RDEBUG2(
"No cleartext password in the request. Can't do Yubikey authentication");
304 passcode = password->vp_strvalue;
305 len = password->vp_length;
315 RDEBUG2(
"User-Password value is not the correct length, expected at least %u bytes, got %zu bytes",
321 otp = passcode + password_len;
325 RDMARKER(otp, -(ret),
"User-Password (aes-block) value contains non modhex chars");
327 RDEBUG2(
"User-Password (aes-block) value contains non modhex chars");
348 RDEBUG2(
"&request.%pP", password);
353 passcode =
vp->vp_strvalue;
368 if (!
inst->auth_type) {
369 WARN(
"No 'authenticate %s {...}' section or 'Auth-Type = %s' set. Cannot setup Yubikey authentication",
387 char const *passcode = NULL;
394 RDEBUG2(
"No Yubikey-OTP attribute found, falling back to User-Password");
400 REDEBUG(
"No User-Password in the request. Can't do Yubikey authentication");
405 passcode =
vp->vp_strvalue;
415 REDEBUG(
"%s value is not the correct length, expected bytes %u, got bytes %zu",
423 REMARKER(passcode, -ret,
"Passcode (aes-block) value contains non modhex chars");
425 RERROR(
"Passcode (aes-block) value contains non modhex chars");
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
#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.
fr_dict_enum_value_t * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
#define fr_dict_autoload(_to_load)
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.
#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(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_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
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.
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.
static const conf_parser_t config[]
#define pair_update_request(_attr, _da)
#define RETURN_MODULE_NOOP
#define RETURN_MODULE_RCODE(_rcode)
#define RETURN_MODULE_INVALID
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
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 unlang_action_t mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
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
fr_dict_attr_t const * attr_yubikey_otp
static void mod_unload(void)
fr_dict_attr_autoload_t rlm_yubikey_dict_attr[]
static unlang_action_t mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static char const hextab[]
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)
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)
unlang_action_t rlm_yubikey_decrypt(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request, char const *passcode)
unlang_action_t rlm_yubikey_validate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request, char const *passcode)
#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.
void * data
Module's instance data.
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Named methods exported by a module.
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.
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
bool 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.