The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_eap_pwd.c
Go to the documentation of this file.
1/*
2 * Copyright holder grants permission for redistribution and use in source
3 * and binary forms, with or without modification, provided that the
4 * following conditions are met:
5 * 1. Redistribution of source code must retain the above copyright
6 * notice, this list of conditions, and the following disclaimer
7 * in all source files.
8 * 2. Redistribution in binary form must retain the above copyright
9 * notice, this list of conditions, and the following disclaimer
10 * in the documentation and/or other materials provided with the
11 * distribution.
12 *
13 * "DISCLAIMER OF LIABILITY
14 *
15 * THIS SOFTWARE IS PROVIDED BY DAN HARKINS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INDUSTRIAL LOUNGE BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE."
26 *
27 * This license and distribution terms cannot be changed. In other words,
28 * this code cannot simply be copied and put under a different distribution
29 * license (including the GNU public license).
30 *
31 * @copyright (c) Dan Harkins, 2012
32 */
33RCSID("$Id: 20f7af2f132ea9bc6d3c12a6243f3ebc71d567ea $")
34USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
35
36#include <freeradius-devel/server/base.h>
37#include <freeradius-devel/server/module_rlm.h>
38#include <freeradius-devel/tls/base.h>
39
40#include "eap_pwd.h"
41
49
50typedef struct {
52 BN_CTX *bnctx;
54
55#define MPPE_KEY_LEN 32
56#define MSK_EMSK_LEN (2 * MPPE_KEY_LEN)
57
59 { FR_CONF_OFFSET("group", rlm_eap_pwd_t, group), .dflt = "19" },
60 { FR_CONF_OFFSET("fragment_size", rlm_eap_pwd_t, fragment_size), .dflt = "1020" },
61 { FR_CONF_OFFSET_FLAGS("server_id", CONF_FLAG_REQUIRED, rlm_eap_pwd_t, server_id) },
63};
64
66static fr_dict_t const *dict_radius;
67
70 { .out = &dict_freeradius, .proto = "freeradius" },
71 { .out = &dict_radius, .proto = "radius" },
73};
74
79
82 { .out = &attr_cleartext_password, .name = "Password.Cleartext", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
83 { .out = &attr_framed_mtu, .name = "Framed-MTU", .type = FR_TYPE_UINT32, .dict = &dict_radius },
84 { .out = &attr_ms_mppe_send_key, .name = "Vendor-Specific.Microsoft.MPPE-Send-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
85 { .out = &attr_ms_mppe_recv_key, .name = "Vendor-Specific.Microsoft.MPPE-Recv-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
87};
88
89static int send_pwd_request(request_t *request, pwd_session_t *session, eap_round_t *eap_round)
90{
91 size_t len;
92 uint16_t totlen;
93 pwd_hdr *hdr;
94
95 len = (session->out_len - session->out_pos) + sizeof(pwd_hdr);
96 fr_assert(len > 0);
97 eap_round->request->code = FR_EAP_CODE_REQUEST;
98 eap_round->request->type.num = FR_EAP_METHOD_PWD;
99 eap_round->request->type.length = (len > session->mtu) ? session->mtu : len;
100 eap_round->request->type.data = talloc_zero_array(eap_round->request, uint8_t, eap_round->request->type.length);
101 hdr = (pwd_hdr *)eap_round->request->type.data;
102
103 switch (session->state) {
104 case PWD_STATE_ID_REQ:
106 break;
107
108 case PWD_STATE_COMMIT:
110 break;
111
114 break;
115
116 default:
117 REDEBUG("PWD state is invalid. Can't send request");
118 return -1;
119 }
120
121 /*
122 * are we fragmenting?
123 */
124 if (((session->out_len - session->out_pos) + sizeof(pwd_hdr)) > session->mtu) {
126 if (session->out_pos == 0) {
127
128 /*
129 * the first fragment, add the total length
130 */
132 totlen = ntohs(session->out_len);
133 memcpy(hdr->data, (char *)&totlen, sizeof(totlen));
134 memcpy(hdr->data + sizeof(uint16_t),
135 session->out,
136 session->mtu - sizeof(pwd_hdr) - sizeof(uint16_t));
137 session->out_pos += (session->mtu - sizeof(pwd_hdr) - sizeof(uint16_t));
138 } else {
139 /*
140 * an intermediate fragment
141 */
142 memcpy(hdr->data, session->out + session->out_pos, (session->mtu - sizeof(pwd_hdr)));
143 session->out_pos += (session->mtu - sizeof(pwd_hdr));
144 }
145 } else {
146 /*
147 * either it's not a fragment or it's the last fragment.
148 * The out buffer isn't needed anymore though so get rid of it.
149 */
150 memcpy(hdr->data, session->out + session->out_pos,
151 (session->out_len - session->out_pos));
152 talloc_free(session->out);
153 session->out = NULL;
154 session->out_pos = session->out_len = 0;
155 }
156 return 0;
157}
158
159static unlang_action_t mod_process(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
160{
161 rlm_eap_pwd_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_eap_pwd_t);
162 rlm_eap_pwd_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_eap_pwd_thread_t);
163 eap_session_t *eap_session = eap_session_get(request->parent);
164
165 pwd_session_t *session;
166
167 pwd_hdr *hdr;
168 pwd_id_packet_t *packet;
169 eap_packet_t *response;
170
171 eap_round_t *eap_round;
172 size_t in_len;
174 uint16_t offset;
175 uint8_t exch, *in, *ptr, msk[MSK_EMSK_LEN], emsk[MSK_EMSK_LEN];
176 uint8_t peer_confirm[SHA256_DIGEST_LENGTH];
177
178 if (((eap_round = eap_session->this_round) == NULL) || !inst) RETURN_UNLANG_FAIL;
179
180 session = talloc_get_type_abort(eap_session->opaque, pwd_session_t);
181 response = eap_session->this_round->response;
182 hdr = (pwd_hdr *)response->type.data;
183
184 /*
185 * The header must be at least one byte.
186 */
187 if (!hdr || (response->type.length < sizeof(pwd_hdr))) {
188 REDEBUG("Packet with insufficient data");
190 }
191
192 in = hdr->data;
193 in_len = response->type.length - sizeof(pwd_hdr);
194
195 /*
196 * See if we're fragmenting, if so continue until we're done
197 */
198 if (session->out_pos) {
199 if (in_len) REDEBUG("PWD got something more than an ACK for a fragment");
200 if (send_pwd_request(request, session, eap_round) < 0) RETURN_UNLANG_FAIL;
201
203 }
204
205 /*
206 * The first fragment will have a total length, make a
207 * buffer to hold all the fragments
208 */
209 if (EAP_PWD_GET_LENGTH_BIT(hdr)) {
210 if (session->in) {
211 REDEBUG("PWD already alloced buffer for fragments");
213 }
214
215 if (in_len < 2) {
216 REDEBUG("Invalid packet: length bit set, but no length field");
218 }
219
220 session->in_len = in[0] * 256 | in[1];
221 if (!session->in_len) {
222 DEBUG("EAP-PWD malformed packet (input length)");
224 }
225
226 MEM(session->in = talloc_zero_array(session, uint8_t, session->in_len));
227
228 session->in_pos = 0;
229 in += sizeof(uint16_t);
230 in_len -= sizeof(uint16_t);
231 }
232
233 /*
234 * All fragments, including the 1st will have the M(ore) bit set,
235 * buffer those fragments!
236 */
237 if (EAP_PWD_GET_MORE_BIT(hdr)) {
238 if (!session->in) {
239 RDEBUG2("Unexpected fragment");
241 }
242
243 if ((session->in_pos + in_len) > session->in_len) {
244 REDEBUG("Fragment overflows packet");
246 }
247
248 memcpy(session->in + session->in_pos, in, in_len);
249 session->in_pos += in_len;
250
251 /*
252 * send back an ACK for this fragment
253 */
254 exch = EAP_PWD_GET_EXCHANGE(hdr);
255 eap_round->request->code = FR_EAP_CODE_REQUEST;
256 eap_round->request->type.num = FR_EAP_METHOD_PWD;
257 eap_round->request->type.length = sizeof(pwd_hdr);
258
259 MEM(eap_round->request->type.data = talloc_array(eap_round->request, uint8_t, sizeof(pwd_hdr)));
260
261 hdr = (pwd_hdr *)eap_round->request->type.data;
262 EAP_PWD_SET_EXCHANGE(hdr, exch);
264 }
265
266
267 if (session->in) {
268 /*
269 * The last fragment...
270 */
271 if ((session->in_pos + in_len) > session->in_len) {
272 REDEBUG("PWD will overflow a fragment buffer");
274 }
275 memcpy(session->in + session->in_pos, in, in_len);
276 in = session->in;
277 in_len = session->in_len;
278 }
279
280 switch (session->state) {
281 case PWD_STATE_ID_REQ:
282 {
283 fr_pair_t *known_good;
284 fr_dict_attr_t const *allowed_passwords[] = { attr_cleartext_password };
285 int ret;
286 bool ephemeral;
287 BIGNUM *x = NULL, *y = NULL;
288
290 REDEBUG("PWD exchange is incorrect, Not ID");
292 }
293
294 packet = (pwd_id_packet_t *) in;
295 if (in_len < sizeof(*packet)) {
296 REDEBUG("Packet is too small (%zd < %zd).", in_len, sizeof(*packet));
298 }
299
300 if ((packet->prf != EAP_PWD_DEF_PRF) ||
302 (packet->prep != EAP_PWD_PREP_NONE) ||
303 (CRYPTO_memcmp(packet->token, &session->token, 4)) ||
304 (packet->group_num != ntohs(session->group_num))) {
305 REDEBUG("PWD ID response is malformed");
307 }
308
309 /*
310 * We've agreed on the ciphersuite, record it...
311 */
312 ptr = (uint8_t *)&session->ciphersuite;
313 memcpy(ptr, (char *)&packet->group_num, sizeof(uint16_t));
314 ptr += sizeof(uint16_t);
316 ptr += sizeof(uint8_t);
317 *ptr = EAP_PWD_DEF_PRF;
318
319 session->peer_id_len = in_len - sizeof(pwd_id_packet_t);
320 if (session->peer_id_len >= sizeof(session->peer_id)) {
321 REDEBUG("PWD ID response is malformed");
323 }
324
325 memcpy(session->peer_id, packet->identity, session->peer_id_len);
326 session->peer_id[session->peer_id_len] = '\0';
327
328 known_good = password_find(&ephemeral, request, request->parent,
329 allowed_passwords, NUM_ELEMENTS(allowed_passwords), false);
330 if (!known_good) {
331 REDEBUG("No \"known good\" password found for user");
333 }
334
335 ret = compute_password_element(request, session, session->group_num,
336 known_good->vp_strvalue, known_good->vp_length,
337 inst->server_id, strlen(inst->server_id),
338 session->peer_id, strlen(session->peer_id),
339 &session->token, t->bnctx);
340 if (ephemeral) TALLOC_FREE(known_good);
341 if (ret < 0) {
342 REDEBUG("Failed to obtain password element");
344 }
345
346 /*
347 * Compute our scalar and element
348 */
349 if (compute_scalar_element(request, session, t->bnctx)) {
350 REDEBUG("Failed to compute server's scalar and element");
352 }
353
354 MEM(x = BN_new());
355 MEM(y = BN_new());
356
357 /*
358 * Element is a point, get both coordinates: x and y
359 */
360 if (!EC_POINT_get_affine_coordinates(session->group, session->my_element, x, y, t->bnctx)) {
361 REDEBUG("Server point assignment failed");
362 BN_clear_free(x);
363 BN_clear_free(y);
365 }
366
367 /*
368 * Construct request
369 */
370 session->out_len = BN_num_bytes(session->order) + (2 * BN_num_bytes(session->prime));
371 MEM(session->out = talloc_zero_array(session, uint8_t, session->out_len));
372
373 ptr = session->out;
374 offset = BN_num_bytes(session->prime) - BN_num_bytes(x);
375 BN_bn2bin(x, ptr + offset);
376 BN_clear_free(x);
377
378 ptr += BN_num_bytes(session->prime);
379 offset = BN_num_bytes(session->prime) - BN_num_bytes(y);
380 BN_bn2bin(y, ptr + offset);
381 BN_clear_free(y);
382
383 ptr += BN_num_bytes(session->prime);
384 offset = BN_num_bytes(session->order) - BN_num_bytes(session->my_scalar);
385 BN_bn2bin(session->my_scalar, ptr + offset);
386
387 session->state = PWD_STATE_COMMIT;
388 rcode = send_pwd_request(request, session, eap_round) < 0 ? RLM_MODULE_FAIL : RLM_MODULE_OK;
389 }
390 break;
391
392 case PWD_STATE_COMMIT:
394 REDEBUG("PWD exchange is incorrect, not commit!");
396 }
397
398 /*
399 * Process the peer's commit and generate the shared key, k
400 */
401 if (process_peer_commit(request, session, in, in_len, t->bnctx)) {
402 REDEBUG("Failed processing peer's commit");
404 }
405
406 /*
407 * Compute our confirm blob
408 */
409 if (compute_server_confirm(request, session, session->my_confirm, t->bnctx)) {
410 REDEBUG("Failed computing confirm");
412 }
413
414 /*
415 * Construct a response...which is just our confirm blob
416 */
417 session->out_len = SHA256_DIGEST_LENGTH;
418 MEM(session->out = talloc_array(session, uint8_t, session->out_len));
419
420 memset(session->out, 0, session->out_len);
421 memcpy(session->out, session->my_confirm, SHA256_DIGEST_LENGTH);
422
423 session->state = PWD_STATE_CONFIRM;
424 rcode = send_pwd_request(request, session, eap_round) < 0 ? RLM_MODULE_FAIL : RLM_MODULE_OK;
425 break;
426
428 if (in_len < SHA256_DIGEST_LENGTH) {
429 REDEBUG("Peer confirm is too short (%zd < %d)", in_len, SHA256_DIGEST_LENGTH);
431 }
432
434 REDEBUG("PWD exchange is incorrect, not commit");
436 }
437 if (compute_peer_confirm(request, session, peer_confirm, t->bnctx)) {
438 REDEBUG("Cannot compute peer's confirm");
440 }
441 if (CRYPTO_memcmp(peer_confirm, in, SHA256_DIGEST_LENGTH)) {
442 REDEBUG("PWD exchange failed, peer confirm is incorrect");
444 }
445 if (compute_keys(request, session, peer_confirm, msk, emsk)) {
446 REDEBUG("Failed generating (E)MSK");
448 }
449 eap_round->request->code = FR_EAP_CODE_SUCCESS;
450
451 /*
452 * Return the MSK (in halves).
453 */
454 eap_add_reply(request->parent, attr_ms_mppe_recv_key, msk, MPPE_KEY_LEN);
456
457 rcode = RLM_MODULE_OK;
458 break;
459
460 default:
461 REDEBUG("Unknown PWD state");
463 }
464
465 /*
466 * We processed the buffered fragments, get rid of them.
467 */
468 if (session->in) {
469 talloc_free(session->in);
470 session->in = NULL;
471 }
472
473 RETURN_UNLANG_RCODE(rcode);
474}
475
477{
478 BN_clear_free(session->private_value);
479 BN_clear_free(session->peer_scalar);
480 BN_clear_free(session->my_scalar);
481 BN_clear_free(session->k);
482 EC_POINT_clear_free(session->my_element);
483 EC_POINT_clear_free(session->peer_element);
484 EC_GROUP_free(session->group);
485 EC_POINT_clear_free(session->pwe);
486 BN_clear_free(session->order);
487 BN_clear_free(session->prime);
488
489 return 0;
490}
491
493{
494 rlm_eap_pwd_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_eap_pwd_t);
495 eap_session_t *eap_session = eap_session_get(request->parent);
496 pwd_session_t *session;
497 fr_pair_t *vp;
498 pwd_id_packet_t *packet;
499
500 MEM(session = talloc_zero(eap_session, pwd_session_t));
501 talloc_set_destructor(session, _free_pwd_session);
502 /*
503 * set things up so they can be free'd reliably
504 */
505 session->group_num = inst->group;
506
507 /*
508 * The admin can dynamically change the MTU.
509 */
510 session->mtu = inst->fragment_size;
511 vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_framed_mtu);
512
513 /*
514 * session->mtu is *our* MTU. We need to subtract off the EAP
515 * overhead.
516 *
517 * 9 = 4 (EAPOL header) + 4 (EAP header) + 1 (EAP type)
518 *
519 * The fragmentation code deals with the included length
520 * so we don't need to subtract that here.
521 */
522 if (vp && (vp->vp_uint32 > 100) && (vp->vp_uint32 < session->mtu)) session->mtu = vp->vp_uint32 - 9;
523
524 session->state = PWD_STATE_ID_REQ;
525 session->out_pos = 0;
526 eap_session->opaque = session;
527
528 /*
529 * construct an EAP-pwd-ID/Request
530 */
531 session->out_len = sizeof(pwd_id_packet_t) + strlen(inst->server_id);
532 MEM(session->out = talloc_zero_array(session, uint8_t, session->out_len));
533
534 packet = (pwd_id_packet_t *)session->out;
535 packet->group_num = htons(session->group_num);
537 packet->prf = EAP_PWD_DEF_PRF;
538 session->token = fr_rand();
539 memcpy(packet->token, (char *)&session->token, 4);
540 packet->prep = EAP_PWD_PREP_NONE;
541 memcpy(packet->identity, inst->server_id, session->out_len - sizeof(pwd_id_packet_t) );
542
543 if (send_pwd_request(request, session, eap_session->this_round) < 0) RETURN_UNLANG_FAIL;
544
545 eap_session->process = mod_process;
546
548}
549
550static int mod_instantiate(module_inst_ctx_t const *mctx)
551{
552 rlm_eap_pwd_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_eap_pwd_t);
553 CONF_SECTION *conf = mctx->mi->conf;
554
555 if (inst->fragment_size < 100) {
556 cf_log_err(conf, "Fragment size is too small");
557 return -1;
558 }
559
560 switch (inst->group) {
561 case 19:
562 case 20:
563 case 21:
564 case 25:
565 case 26:
566 break;
567
568 default:
569 cf_log_err_by_child(conf, "group", "Group %i is not supported", inst->group);
570 return -1;
571 }
572
573 inst->conf = conf;
574
575 return 0;
576}
577
579{
580 rlm_eap_pwd_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_eap_pwd_t);
581 rlm_eap_pwd_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_eap_pwd_thread_t);
582
583 t->inst = inst;
584
585 t->bnctx = BN_CTX_new();
586 if (!t->bnctx) {
587 cf_log_err(inst->conf, "Failed to get BN context");
588 return -1;
589 }
590
591 return 0;
592}
593
595{
596 rlm_eap_pwd_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_eap_pwd_thread_t);
597
598 if (t->bnctx) BN_CTX_free(t->bnctx);
599
600 return 0;
601}
602
605 .common = {
606 .magic = MODULE_MAGIC_INIT,
607 .name = "eap_pwd",
611 .inst_size = sizeof(rlm_eap_pwd_t),
612 .config = submodule_config,
613 .instantiate = mod_instantiate, /* Create new submodule instance */
614
615 },
616 .provides = { FR_EAP_METHOD_PWD },
617 .session_init = mod_session_init, /* Create the initial request */
618};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
#define USES_APPLE_DEPRECATED_API
Definition build.h:493
#define RCSID(id)
Definition build.h:506
#define NUM_ELEMENTS(_t)
Definition build.h:358
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:657
#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_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_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition cf_parse.h:429
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:594
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:285
#define cf_log_err_by_child(_parent, _child, _fmt,...)
Log an error message against a specified child.
Definition cf_util.h:312
eap_type_data_t type
Definition compose.h:38
eap_packet_t * response
Packet we received from the peer.
Definition compose.h:48
eap_code_t code
Definition compose.h:35
eap_packet_t * request
Packet we will send to the peer.
Definition compose.h:49
Structure to hold EAP data.
Definition compose.h:34
Contains a pair of request and response packets.
Definition compose.h:47
#define MEM(x)
Definition debug.h:46
#define DEBUG(fmt,...)
Definition dhcpclient.c:38
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
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:311
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
@ FR_EAP_CODE_REQUEST
Definition types.h:37
@ FR_EAP_CODE_SUCCESS
Definition types.h:39
eap_type_t num
Definition types.h:110
size_t length
Definition types.h:111
uint8_t * data
Definition types.h:112
@ FR_EAP_METHOD_PWD
Definition types.h:98
int compute_scalar_element(request_t *request, pwd_session_t *session, BN_CTX *bn_ctx)
Definition eap_pwd.c:524
int process_peer_commit(request_t *request, pwd_session_t *session, uint8_t *in, size_t in_len, BN_CTX *bn_ctx)
Definition eap_pwd.c:564
int compute_server_confirm(request_t *request, pwd_session_t *session, uint8_t *out, BN_CTX *bn_ctx)
Definition eap_pwd.c:690
int compute_keys(UNUSED request_t *request, pwd_session_t *session, uint8_t *peer_confirm, uint8_t *msk, uint8_t *emsk)
Definition eap_pwd.c:895
int compute_password_element(request_t *request, pwd_session_t *session, uint16_t grp_num, char const *password, int password_len, char const *id_server, int id_server_len, char const *id_peer, int id_peer_len, uint32_t *token, BN_CTX *bnctx)
Definition eap_pwd.c:256
int compute_peer_confirm(request_t *request, pwd_session_t *session, uint8_t *out, BN_CTX *bn_ctx)
Definition eap_pwd.c:793
#define PWD_STATE_ID_REQ
Definition eap_pwd.h:76
BIGNUM * private_value
Definition eap_pwd.h:96
uint8_t token[4]
Definition eap_pwd.h:66
uint16_t group_num
Definition eap_pwd.h:79
size_t in_pos
Definition eap_pwd.h:86
char peer_id[FR_MAX_STRING_LEN]
Definition eap_pwd.h:82
BIGNUM * my_scalar
Definition eap_pwd.h:98
uint32_t token
Definition eap_pwd.h:81
#define PWD_STATE_COMMIT
Definition eap_pwd.h:77
#define EAP_PWD_EXCH_COMMIT
Definition eap_pwd.h:47
uint16_t state
Definition eap_pwd.h:75
uint16_t group_num
Definition eap_pwd.h:61
#define EAP_PWD_DEF_PRF
Definition eap_pwd.h:65
#define EAP_PWD_GET_MORE_BIT(x)
Definition eap_pwd.h:55
uint8_t my_confirm[SHA256_DIGEST_LENGTH]
Definition eap_pwd.h:101
#define EAP_PWD_DEF_RAND_FUN
Definition eap_pwd.h:63
size_t out_len
Definition eap_pwd.h:90
uint8_t data[]
Definition eap_pwd.h:50
size_t peer_id_len
Definition eap_pwd.h:83
#define EAP_PWD_GET_LENGTH_BIT(x)
Definition eap_pwd.h:53
#define EAP_PWD_SET_EXCHANGE(x, y)
Definition eap_pwd.h:58
char identity[]
Definition eap_pwd.h:71
BIGNUM * prime
Definition eap_pwd.h:94
uint8_t prf
Definition eap_pwd.h:64
uint8_t prep
Definition eap_pwd.h:67
#define EAP_PWD_GET_EXCHANGE(x)
Definition eap_pwd.h:57
#define EAP_PWD_SET_LENGTH_BIT(x)
Definition eap_pwd.h:54
size_t out_pos
Definition eap_pwd.h:89
EC_GROUP * group
Definition eap_pwd.h:91
size_t in_len
Definition eap_pwd.h:87
#define EAP_PWD_EXCH_ID
Definition eap_pwd.h:46
BIGNUM * peer_scalar
Definition eap_pwd.h:97
EC_POINT * pwe
Definition eap_pwd.h:92
BIGNUM * k
Definition eap_pwd.h:95
size_t mtu
Definition eap_pwd.h:84
uint8_t * out
Definition eap_pwd.h:88
#define EAP_PWD_EXCH_CONFIRM
Definition eap_pwd.h:48
#define PWD_STATE_CONFIRM
Definition eap_pwd.h:78
uint8_t random_function
Definition eap_pwd.h:62
uint8_t * in
Definition eap_pwd.h:85
#define EAP_PWD_SET_MORE_BIT(x)
Definition eap_pwd.h:56
uint32_t ciphersuite
Definition eap_pwd.h:80
#define EAP_PWD_PREP_NONE
Definition eap_pwd.h:68
BIGNUM * order
Definition eap_pwd.h:93
EC_POINT * peer_element
Definition eap_pwd.h:100
EC_POINT * my_element
Definition eap_pwd.h:99
copyright holder grants permission for redistribution and use in source and binary forms,...
Definition eap_pwd.h:44
talloc_free(hp)
void eap_add_reply(request_t *request, fr_dict_attr_t const *da, uint8_t const *value, int len)
Definition base.c:347
static eap_session_t * eap_session_get(request_t *request)
Definition session.h:85
void * opaque
Opaque data used by EAP methods.
Definition session.h:63
module_method_t process
Callback that should be used to process the next round.
Definition session.h:65
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition session.h:60
Tracks the progress of a single session of any EAP method.
Definition session.h:41
unsigned short uint16_t
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_OCTETS
Raw octets.
unsigned int uint32_t
unsigned char uint8_t
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
void * thread
Thread specific instance data.
Definition module_ctx.h:43
void * thread
Thread instance data.
Definition module_ctx.h:67
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:64
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 instantiation calls.
Definition module_ctx.h:50
Temporary structure to hold arguments for thread_instantiation calls.
Definition module_ctx.h:63
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
fr_pair_t * password_find(bool *ephemeral, TALLOC_CTX *ctx, request_t *request, fr_dict_attr_t const *allowed_attrs[], size_t allowed_attrs_len, bool normify)
Find a "known good" password in the control list of a request.
Definition password.c:994
#define fr_assert(_expr)
Definition rad_assert.h:37
#define REDEBUG(fmt,...)
#define RDEBUG2(fmt,...)
static void thread_detach(UNUSED void *uctx)
Explicitly cleanup module/xlat resources.
Definition radiusd.c:139
static int thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el, UNUSED void *uctx)
Create module and xlat per-thread instances.
Definition radiusd.c:127
static rs_t * conf
Definition radsniff.c:52
uint32_t fr_rand(void)
Return a 32-bit random number.
Definition rand.c:104
#define RETURN_UNLANG_HANDLED
Definition rcode.h:65
#define RETURN_UNLANG_INVALID
Definition rcode.h:66
#define RETURN_UNLANG_RCODE(_rcode)
Definition rcode.h:61
#define RETURN_UNLANG_FAIL
Definition rcode.h:63
#define RETURN_UNLANG_OK
Definition rcode.h:64
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:44
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:49
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:48
static int send_pwd_request(request_t *request, pwd_session_t *session, eap_round_t *eap_round)
Definition rlm_eap_pwd.c:89
#define MSK_EMSK_LEN
Definition rlm_eap_pwd.c:56
char const * virtual_server
Definition rlm_eap_pwd.c:46
uint32_t fragment_size
Definition rlm_eap_pwd.c:44
rlm_eap_submodule_t rlm_eap_pwd
rlm_eap_pwd_t const * inst
Definition rlm_eap_pwd.c:51
char const * server_id
Definition rlm_eap_pwd.c:45
static int _free_pwd_session(pwd_session_t *session)
static fr_dict_t const * dict_freeradius
Definition rlm_eap_pwd.c:65
static unlang_action_t mod_process(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static fr_dict_t const * dict_radius
Definition rlm_eap_pwd.c:66
uint32_t group
Definition rlm_eap_pwd.c:43
static fr_dict_attr_t const * attr_ms_mppe_send_key
Definition rlm_eap_pwd.c:77
fr_dict_attr_autoload_t rlm_eap_pwd_dict_attr[]
Definition rlm_eap_pwd.c:81
fr_dict_autoload_t rlm_eap_pwd_dict[]
Definition rlm_eap_pwd.c:69
static fr_dict_attr_t const * attr_cleartext_password
Definition rlm_eap_pwd.c:75
#define MPPE_KEY_LEN
Definition rlm_eap_pwd.c:55
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
CONF_SECTION * conf
Definition rlm_eap_pwd.c:47
static fr_dict_attr_t const * attr_framed_mtu
Definition rlm_eap_pwd.c:76
static fr_dict_attr_t const * attr_ms_mppe_recv_key
Definition rlm_eap_pwd.c:78
static conf_parser_t submodule_config[]
Definition rlm_eap_pwd.c:58
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
static unlang_action_t mod_session_init(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static int mod_instantiate(module_inst_ctx_t const *mctx)
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:351
void * data
Module's instance data.
Definition module.h:293
size_t thread_inst_size
Size of the module's thread-specific instance data.
Definition module.h:246
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
module_t common
Common fields provided by all modules.
Definition submodule.h:50
Interface exported by EAP submodules.
Definition submodule.h:49