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