The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_yubikey.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 (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 * $Id: 8b05908172952f8a9d9319f5cbb2a6d6896fe0ae $
19 * @file rlm_yubikey.c
20 * @brief Authentication for yubikey OTP tokens.
21 *
22 * @author Arran Cudbard-Bell (a.cudbardb@networkradius.com)
23 * @copyright 2013 The FreeRADIUS server project
24 * @copyright 2013 Network RADIUS (legal@networkradius.com)
25 */
26RCSID("$Id: 8b05908172952f8a9d9319f5cbb2a6d6896fe0ae $")
27
28#include <freeradius-devel/radius/radius.h>
29#include <freeradius-devel/unlang/xlat_func.h>
30#include <freeradius-devel/server/rcode.h>
31#include "rlm_yubikey.h"
32
33#ifdef HAVE_YKCLIENT
34static const conf_parser_t validation_config[] = {
35 { FR_CONF_OFFSET("client_id", rlm_yubikey_t, client_id), .dflt = 0 },
36 { FR_CONF_OFFSET_FLAGS("api_key", CONF_FLAG_SECRET, rlm_yubikey_t, api_key) },
38};
39#endif
40
41static const conf_parser_t module_config[] = {
42 { FR_CONF_OFFSET("id_length", rlm_yubikey_t, id_len), .dflt = "12" },
43 { FR_CONF_OFFSET("split", rlm_yubikey_t, split), .dflt = "yes" },
44 { FR_CONF_OFFSET("decrypt", rlm_yubikey_t, decrypt), .dflt = "no" },
45 { FR_CONF_OFFSET("validate", rlm_yubikey_t, validate), .dflt = "no" },
46#ifdef HAVE_YKCLIENT
47 { FR_CONF_POINTER("validation", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) validation_config },
48#endif
50};
51
53static fr_dict_t const *dict_radius;
54
57 { .out = &dict_freeradius, .proto = "freeradius" },
58 { .out = &dict_radius, .proto = "radius" },
60};
61
71
74 { .out = &attr_auth_type, .name = "Auth-Type", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
75 { .out = &attr_user_password, .name = "User-Password", .type = FR_TYPE_STRING, .dict = &dict_radius },
76 { .out = &attr_yubikey_key, .name = "Vendor-Specific.Yubico.Yubikey-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
77 { .out = &attr_yubikey_public_id, .name = "Vendor-Specific.Yubico.Yubikey-Public-ID", .type = FR_TYPE_STRING, .dict = &dict_radius },
78 { .out = &attr_yubikey_private_id, .name = "Vendor-Specific.Yubico.Yubikey-Private-ID", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
79 { .out = &attr_yubikey_counter, .name = "Vendor-Specific.Yubico.Yubikey-Counter", .type = FR_TYPE_UINT32, .dict = &dict_radius },
80 { .out = &attr_yubikey_timestamp, .name = "Vendor-Specific.Yubico.Yubikey-Timestamp", .type = FR_TYPE_UINT32, .dict = &dict_radius },
81 { .out = &attr_yubikey_random, .name = "Vendor-Specific.Yubico.Yubikey-Random", .type = FR_TYPE_UINT32, .dict = &dict_radius },
82 { .out = &attr_yubikey_otp, .name = "Vendor-Specific.Yubico.Yubikey-OTP", .type = FR_TYPE_STRING, .dict = &dict_radius },
84};
85
86static char const modhextab[] = "cbdefghijklnrtuv";
87static char const hextab[] = "0123456789abcdef";
88
89#define is_modhex(x) (memchr(modhextab, tolower(x), 16))
90
91/** Convert yubikey modhex to normal hex
92 *
93 * The same buffer may be passed as modhex and hex to convert the modhex in place.
94 *
95 * Modhex and hex must be the same size.
96 *
97 * @param[in] modhex data.
98 * @param[in] len of input and output buffers.
99 * @param[out] hex where to write the standard hexits.
100 * @return
101 * - The number of bytes written to the output buffer.
102 * - -1 on failure.
103 */
104static ssize_t modhex2hex(char const *modhex, char *hex, size_t len)
105{
106 size_t i;
107 char const *c1, *c2;
108
109 for (i = 0; i < len; i += 2) {
110 if (modhex[i] == '\0') {
111 break;
112 }
113
114 /*
115 * We only deal with whole bytes
116 */
117 if (modhex[i + 1] == '\0')
118 return -1;
119
120 if (!(c1 = memchr(modhextab, tolower((uint8_t) modhex[i]), 16)) ||
121 !(c2 = memchr(modhextab, tolower((uint8_t) modhex[i + 1]), 16)))
122 return -1;
123
124 hex[i] = hextab[c1 - modhextab];
125 hex[i + 1] = hextab[c2 - modhextab];
126 }
127
128 return i;
129}
130
132 { .required = true, .concat = true, .type = FR_TYPE_STRING },
134};
135
136/** Xlat to convert Yubikey modhex to standard hex
137 *
138 * Example:
139@verbatim
140%modhextohex('vvrbuctetdhc') == "ffc1e0d3d260"
141@endverbatim
142 *
143 * @ingroup xlat_functions
144 */
146 UNUSED xlat_ctx_t const *xctx, request_t *request,
147 fr_value_box_list_t *in)
148{
149 ssize_t len;
150 fr_value_box_t *arg = fr_value_box_list_pop_head(in);
151 char *p = UNCONST(char *, arg->vb_strvalue);
152
153 /*
154 * mod2hex allows conversions in place
155 */
156 len = modhex2hex(p, p, arg->vb_length);
157 if (len <= 0) {
158 REDEBUG("Modhex string invalid");
159 talloc_free(arg);
160 return XLAT_ACTION_FAIL;
161 }
162
164 return XLAT_ACTION_DONE;
165}
166
167static int mod_load(void)
168{
169 xlat_t *xlat;
170
172 PERROR("%s", __FUNCTION__);
173 return -1;
174 }
175
177 PERROR("%s", __FUNCTION__);
179 return -1;
180 }
181
182 if (unlikely(!(xlat = xlat_func_register(NULL, "modhextohex", modhex_to_hex_xlat, FR_TYPE_STRING)))) {
184 return -1;
185 }
188
189 return 0;
190}
191
192static void mod_unload(void)
193{
194 xlat_func_unregister("modhextohex");
196}
197
198#ifndef HAVE_YUBIKEY
199static int mod_bootstrap(module_inst_ctx_t const *mctx)
200{
201 rlm_yubikey_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_yubikey_t);
202
203 if (inst->decrypt) {
204 cf_log_err(mctx->mi->conf, "Requires libyubikey for OTP decryption");
205 return -1;
206 }
207 return 0;
208}
209#endif
210
211/*
212 * Do any per-module initialization that is separate to each
213 * configured instance of the module. e.g. set up connections
214 * to external databases, read configuration files, set up
215 * dictionary entries, etc.
216 *
217 * If configuration information is given in the config section
218 * that must be referenced in later calls, store a handle to it
219 * in *instance otherwise put a null pointer there.
220 */
221static int mod_instantiate(module_inst_ctx_t const *mctx)
222{
223 rlm_yubikey_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_yubikey_t);
224 CONF_SECTION *conf = mctx->mi->conf;
225
226 inst->name = mctx->mi->name;
227
228 inst->auth_type = fr_dict_enum_by_name(attr_auth_type, inst->name, -1);
229 if (!inst->auth_type) {
230 WARN("Failed to find 'authenticate %s {...}' section. Yubikey authentication will likely not work",
231 mctx->mi->name);
232 }
233
234 if (inst->validate) {
235#ifdef HAVE_YKCLIENT
236 CONF_SECTION *cs;
237
238 cs = cf_section_find(conf, "validation", CF_IDENT_ANY);
239 if (!cs) {
240 cf_log_err(conf, "Missing validation section");
241 return -1;
242 }
243
244 if (rlm_yubikey_ykclient_init(cs, inst) < 0) {
245 return -1;
246 }
247#else
248 cf_log_err(conf, "Requires libykclient for OTP validation against Yubicloud servers");
249 return -1;
250#endif
251 }
252
253 return 0;
254}
255
256#ifdef HAVE_YKCLIENT
257static int mod_detach(module_detach_ctx_t const *mctx)
258{
259 rlm_yubikey_ykclient_detach(talloc_get_type_abort(mctx->mi->data, rlm_yubikey_t));
260 return 0;
261}
262#endif
263
264static int CC_HINT(nonnull) otp_string_valid(rlm_yubikey_t const *inst, char const *otp, size_t len)
265{
266 size_t i;
267
268 for (i = inst->id_len; i < len; i++) {
269 if (!is_modhex(otp[i])) return -i;
270 }
271
272 return 1;
273}
274
275
276/*
277 * Find the named user in this modules database. Create the set
278 * of attribute-value pairs to check and reply with for this user
279 * from the database. The authentication code only needs to check
280 * the password, the rest is done here.
281 */
282static unlang_action_t CC_HINT(nonnull) mod_authorize(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
283{
285 char const *passcode;
286 size_t len;
287 fr_pair_t *vp, *password;
288 char const *otp;
289 size_t password_len;
290 int ret;
291
292 /*
293 * Can't do yubikey auth if there's no password.
294 */
295 password = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_password);
296 if (!password) {
297 /*
298 * Don't print out debugging messages if we know
299 * they're useless.
300 */
301 if ((request->proto_dict == dict_radius) && request->packet->code != FR_RADIUS_CODE_ACCESS_CHALLENGE) {
302 RDEBUG2("No cleartext password in the request. Can't do Yubikey authentication");
303 }
304
306 }
307
308 passcode = password->vp_strvalue;
309 len = password->vp_length;
310
311 /*
312 * Now see if the passcode is the correct length (in its raw
313 * modhex encoded form).
314 *
315 * <public_id (6-16 bytes)> + <aes-block (32 bytes)>
316 *
317 */
318 if (len < (inst->id_len + YUBIKEY_TOKEN_LEN)) {
319 RDEBUG2("User-Password value is not the correct length, expected at least %u bytes, got %zu bytes",
320 inst->id_len + YUBIKEY_TOKEN_LEN, len);
322 }
323
324 password_len = (len - (inst->id_len + YUBIKEY_TOKEN_LEN));
325 otp = passcode + password_len;
326 ret = otp_string_valid(inst, otp, (inst->id_len + YUBIKEY_TOKEN_LEN));
327 if (ret <= 0) {
328 if (RDEBUG_ENABLED3) {
329 RDMARKER(otp, -(ret), "User-Password (aes-block) value contains non modhex chars");
330 } else {
331 RDEBUG2("User-Password (aes-block) value contains non modhex chars");
332 }
334 }
335
336 /* May be a concatenation, check the last 32 bytes are modhex */
337 if (inst->split) {
338 /*
339 * Insert a new request attribute just containing the OTP
340 * portion.
341 */
343 fr_pair_value_strdup(vp, otp, password->vp_tainted);
344
345 /*
346 * Replace the existing string buffer for the password
347 * attribute with one just containing the password portion.
348 */
349 MEM(fr_pair_value_bstr_realloc(password, NULL, password_len) == 0);
350
351 RDEBUG2("request.%pP", vp);
352 RDEBUG2("request.%pP", password);
353
354 /*
355 * So the ID split code works on the non password portion.
356 */
357 passcode = vp->vp_strvalue;
358 }
359
360 /*
361 * Split out the Public ID in case another module in authorize
362 * needs to verify it's associated with the user.
363 *
364 * It's left up to the user if they want to decode it or not.
365 */
366 if (inst->id_len) {
368 fr_pair_value_bstrndup(vp, passcode, inst->id_len, true);
369 RDEBUG2("request.%pP", vp);
370 }
371
372 if (!inst->auth_type) {
373 WARN("No 'authenticate %s {...}' section or 'Auth-Type = %s' set. Cannot setup Yubikey authentication",
374 mctx->mi->name, mctx->mi->name);
376 }
377
379
381}
382
383
384/*
385 * Authenticate the user with the given password.
386 */
387static unlang_action_t CC_HINT(nonnull) mod_authenticate(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
388{
390 char const *passcode = NULL;
391 fr_pair_t const *vp;
392 size_t len;
393 int ret;
394
395 p_result->rcode = RLM_MODULE_NOOP;
396
397 vp = fr_pair_find_by_da_nested(&request->request_pairs, NULL, attr_yubikey_otp);
398 if (!vp) {
399 RDEBUG2("No Yubikey-OTP attribute found, falling back to User-Password");
400 /*
401 * Can't do yubikey auth if there's no password.
402 */
403 vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_password);
404 if (!vp) {
405 REDEBUG("No User-Password in the request. Can't do Yubikey authentication");
407 }
408 }
409
410 passcode = vp->vp_strvalue;
411 len = vp->vp_length;
412
413 /*
414 * Verify the passcode is the correct length (in its raw
415 * modhex encoded form).
416 *
417 * <public_id (6-16 bytes)> + <aes-block (32 bytes)>
418 */
419 if (len != (inst->id_len + YUBIKEY_TOKEN_LEN)) {
420 REDEBUG("%s value is not the correct length, expected bytes %u, got bytes %zu",
421 vp->da->name, inst->id_len + YUBIKEY_TOKEN_LEN, len);
423 }
424
425 ret = otp_string_valid(inst, passcode, (inst->id_len + YUBIKEY_TOKEN_LEN));
426 if (ret <= 0) {
427 if (RDEBUG_ENABLED3) {
428 REMARKER(passcode, -ret, "Passcode (aes-block) value contains non modhex chars");
429 } else {
430 RERROR("Passcode (aes-block) value contains non modhex chars");
431 }
433 }
434
435#ifdef HAVE_YUBIKEY
436 if (inst->decrypt) {
437
438 rlm_yubikey_decrypt(p_result, mctx, request, passcode);
439 if (p_result->rcode != RLM_MODULE_OK) return UNLANG_ACTION_CALCULATE_RESULT;
440 /* Fall-Through to doing ykclient auth in addition to local auth */
441 }
442#endif
443
444#ifdef HAVE_YKCLIENT
445 if (inst->validate) return rlm_yubikey_validate(p_result, mctx, request, passcode);
446#endif
448}
449
450/*
451 * The module name should be the only globally exported symbol.
452 * That is, everything else should be 'static'.
453 *
454 * If the module needs to temporarily modify it's instantiation
455 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
456 * The server will then take care of ensuring that the module
457 * is single-threaded.
458 */
461 .common = {
462 .magic = MODULE_MAGIC_INIT,
463 .name = "yubikey",
464 .inst_size = sizeof(rlm_yubikey_t),
465 .onload = mod_load,
466 .unload = mod_unload,
468#ifndef HAVE_YUBIKEY
469 .bootstrap = mod_bootstrap,
470#endif
471 .instantiate = mod_instantiate,
472#ifdef HAVE_YKCLIENT
473 .detach = mod_detach,
474#endif
475 },
476 .method_group = {
477 .bindings = (module_method_binding_t[]){
478 { .section = SECTION_NAME("authenticate", CF_IDENT_ANY), .method = mod_authenticate },
479 { .section = SECTION_NAME("recv", "Access-Request"), .method = mod_authorize },
481 }
482 }
483};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
Definition action.h:37
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:186
#define RCSID(id)
Definition build.h:512
#define unlikely(_x)
Definition build.h:407
#define UNUSED
Definition build.h:336
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:669
#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:280
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
Definition cf_parse.h:334
#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
Definition cf_parse.h:268
@ CONF_FLAG_SECRET
Only print value if debug level >= 3.
Definition cf_parse.h:433
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition cf_parse.h:423
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:606
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:106
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:1194
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:345
#define CF_IDENT_ANY
Definition cf_util.h:80
static int split(char **input, char **output, bool syntax_string)
Definition command.c:393
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition dcursor.h:406
#define MEM(x)
Definition debug.h:36
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
Definition defs.h:43
#define fr_dict_autofree(_to_free)
Definition dict.h:915
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:292
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:305
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.
Definition dict_util.c:4372
#define fr_dict_autoload(_to_load)
Definition dict.h:912
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:311
fr_dict_enum_value_t const * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
Definition dict_util.c:3678
static fr_slen_t in
Definition dict.h:882
Specifies an attribute which must be present for the module to function.
Definition dict.h:291
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:304
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
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.
talloc_free(hp)
rlm_rcode_t rcode
The current rcode, from executing the instruction or merging the result from a frame.
Definition interpret.h:139
#define PERROR(_fmt,...)
Definition log.h:228
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Definition log.h:347
#define RERROR(fmt,...)
Definition log.h:310
#define REMARKER(_str, _marker_idx, _marker,...)
Output string with error marker, showing where format error occurred.
Definition log.h:510
#define RDMARKER(_str, _marker_idx, _marker,...)
Output string with error marker, showing where format error occurred.
Definition log.h:528
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_OCTETS
Raw octets.
long int ssize_t
unsigned char uint8_t
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
module_instance_t * mi
Module instance to detach.
Definition module_ctx.h:57
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 detach calls.
Definition module_ctx.h:56
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
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.
Definition module_rlm.c:403
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
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:784
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition pair.c:2663
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:707
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.
Definition pair.c:2812
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.
Definition pair.c:2784
static const conf_parser_t config[]
Definition base.c:163
#define pair_update_request(_attr, _da)
#define REDEBUG(fmt,...)
#define RDEBUG2(fmt,...)
#define WARN(fmt,...)
static rs_t * conf
Definition radsniff.c:52
#define RETURN_UNLANG_INVALID
Definition rcode.h:66
#define RETURN_UNLANG_OK
Definition rcode.h:64
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:49
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:54
#define RETURN_UNLANG_NOOP
Definition rcode.h:69
static int mod_detach(module_detach_ctx_t const *mctx)
Definition rlm_always.c:136
static int mod_load(void)
fr_dict_attr_t const * attr_user_password
Definition rlm_yubikey.c:63
static xlat_arg_parser_t const modhex_to_hex_xlat_arg[]
fr_dict_attr_t const * attr_yubikey_random
Definition rlm_yubikey.c:69
fr_dict_attr_t const * attr_yubikey_counter
Definition rlm_yubikey.c:67
static ssize_t modhex2hex(char const *modhex, char *hex, size_t len)
Convert yubikey modhex to normal hex.
static char const modhextab[]
Definition rlm_yubikey.c:86
#define is_modhex(x)
Definition rlm_yubikey.c:89
static fr_dict_t const * dict_freeradius
Definition rlm_yubikey.c:52
fr_dict_attr_t const * attr_yubikey_public_id
Definition rlm_yubikey.c:65
module_rlm_t rlm_yubikey
static fr_dict_t const * dict_radius
Definition rlm_yubikey.c:53
static int mod_bootstrap(module_inst_ctx_t const *mctx)
fr_dict_attr_t const * attr_yubikey_key
Definition rlm_yubikey.c:64
fr_dict_attr_t const * attr_auth_type
Definition rlm_yubikey.c:62
fr_dict_attr_t const * attr_yubikey_timestamp
Definition rlm_yubikey.c:68
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
Definition rlm_yubikey.c:70
static void mod_unload(void)
fr_dict_attr_autoload_t rlm_yubikey_dict_attr[]
Definition rlm_yubikey.c:73
static char const hextab[]
Definition rlm_yubikey.c:87
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
Definition rlm_yubikey.c:66
static const conf_parser_t module_config[]
Definition rlm_yubikey.c:41
fr_dict_autoload_t rlm_yubikey_dict[]
Definition rlm_yubikey.c:56
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
Definition rlm_yubikey.h:31
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.
Definition section.h:39
char const * name
Instance name e.g. user_database.
Definition module.h:357
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:351
size_t inst_size
Size of the module's instance data.
Definition module.h:212
void * data
Module's instance data.
Definition module.h:293
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:152
Named methods exported by a module.
Definition module.h:174
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 talloc_get_type_abort_const
Definition talloc.h:117
unsigned int required
Argument must be present, and non-empty.
Definition xlat.h:146
#define XLAT_ARG_PARSER_TERMINATOR
Definition xlat.h:170
xlat_action_t
Definition xlat.h:37
@ XLAT_ACTION_FAIL
An xlat function failed.
Definition xlat.h:44
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition xlat.h:43
Definition for a single argument consumed by an xlat function.
Definition xlat.h:145
int nonnull(2, 5))
static size_t char ** out
Definition value.h:1030
An xlat calling ctx.
Definition xlat_ctx.h:49
void xlat_func_flags_set(xlat_t *x, xlat_func_flags_t flags)
Specify flags that alter the xlat's behaviour.
Definition xlat_func.c:392
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition xlat_func.c:365
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.
Definition xlat_func.c:216
void xlat_func_unregister(char const *name)
Unregister an xlat function.
Definition xlat_func.c:509
@ XLAT_FUNC_FLAG_PURE
Definition xlat_func.h:38