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