All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rlm_eap_pwd.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) Dan Harkins, 2012
3  *
4  * Copyright holder grants permission for redistribution and use in source
5  * and binary forms, with or without modification, provided that the
6  * following conditions are met:
7  * 1. Redistribution of source code must retain the above copyright
8  * notice, this list of conditions, and the following disclaimer
9  * in all source files.
10  * 2. Redistribution in binary form must retain the above copyright
11  * notice, this list of conditions, and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *
15  * "DISCLAIMER OF LIABILITY
16  *
17  * THIS SOFTWARE IS PROVIDED BY DAN HARKINS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INDUSTRIAL LOUNGE BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE."
28  *
29  * This license and distribution terms cannot be changed. In other words,
30  * this code cannot simply be copied and put under a different distribution
31  * license (including the GNU public license).
32  */
33 
34 RCSID("$Id: 9740e025e6fdc50972e5ce7ba8efbe8b96574f6c $")
35 USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
36 
37 #include "rlm_eap_pwd.h"
38 
39 #include "eap_pwd.h"
40 
41 #define MPPE_KEY_LEN 32
42 #define MSK_EMSK_LEN (2*MPPE_KEY_LEN)
43 
45  { FR_CONF_OFFSET("group", PW_TYPE_INTEGER, eap_pwd_t, group), .dflt = "19" },
46  { FR_CONF_OFFSET("fragment_size", PW_TYPE_INTEGER, eap_pwd_t, fragment_size), .dflt = "1020" },
47  { FR_CONF_OFFSET("server_id", PW_TYPE_STRING, eap_pwd_t, server_id) },
48  { FR_CONF_OFFSET("virtual_server", PW_TYPE_STRING, eap_pwd_t, virtual_server) },
50 };
51 
52 static int mod_detach (void *arg)
53 {
54  eap_pwd_t *inst;
55 
56  inst = (eap_pwd_t *) arg;
57 
58  if (inst->bnctx) BN_CTX_free(inst->bnctx);
59 
60  return 0;
61 }
62 
63 static int mod_instantiate (CONF_SECTION *cs, void **instance)
64 {
65  eap_pwd_t *inst;
66 
67  *instance = inst = talloc_zero(cs, eap_pwd_t);
68  if (!inst) return -1;
69 
70  if (cf_section_parse(cs, inst, pwd_module_config) < 0) return -1;
71 
72  if (inst->fragment_size < 100) {
73  cf_log_err_cs(cs, "Fragment size is too small");
74  return -1;
75  }
76 
77  if ((inst->bnctx = BN_CTX_new()) == NULL) {
78  cf_log_err_cs(cs, "Failed to get BN context");
79  return -1;
80  }
81 
82  return 0;
83 }
84 
85 static int _free_pwd_session (pwd_session_t *session)
86 {
87  BN_clear_free(session->private_value);
88  BN_clear_free(session->peer_scalar);
89  BN_clear_free(session->my_scalar);
90  BN_clear_free(session->k);
91  EC_POINT_clear_free(session->my_element);
92  EC_POINT_clear_free(session->peer_element);
93  EC_GROUP_free(session->group);
94  EC_POINT_clear_free(session->pwe);
95  BN_clear_free(session->order);
96  BN_clear_free(session->prime);
97 
98  return 0;
99 }
100 
102 {
103  size_t len;
104  uint16_t totlen;
105  pwd_hdr *hdr;
106 
107  len = (session->out_len - session->out_pos) + sizeof(pwd_hdr);
108  rad_assert(len > 0);
109  eap_round->request->code = PW_EAP_REQUEST;
110  eap_round->request->type.num = PW_EAP_PWD;
111  eap_round->request->type.length = (len > session->mtu) ? session->mtu : len;
112  eap_round->request->type.data = talloc_zero_array(eap_round->request, uint8_t, eap_round->request->type.length);
113  hdr = (pwd_hdr *)eap_round->request->type.data;
114 
115  switch (session->state) {
116  case PWD_STATE_ID_REQ:
118  break;
119 
120  case PWD_STATE_COMMIT:
122  break;
123 
124  case PWD_STATE_CONFIRM:
126  break;
127 
128  default:
129  ERROR("rlm_eap_pwd: PWD state is invalid. Can't send request");
130  return 0;
131  }
132 
133  /*
134  * are we fragmenting?
135  */
136  if (((session->out_len - session->out_pos) + sizeof(pwd_hdr)) > session->mtu) {
138  if (session->out_pos == 0) {
139 
140  /*
141  * the first fragment, add the total length
142  */
144  totlen = ntohs(session->out_len);
145  memcpy(hdr->data, (char *)&totlen, sizeof(totlen));
146  memcpy(hdr->data + sizeof(uint16_t),
147  session->out,
148  session->mtu - sizeof(pwd_hdr) - sizeof(uint16_t));
149  session->out_pos += (session->mtu - sizeof(pwd_hdr) - sizeof(uint16_t));
150  } else {
151  /*
152  * an intermediate fragment
153  */
154  memcpy(hdr->data, session->out + session->out_pos, (session->mtu - sizeof(pwd_hdr)));
155  session->out_pos += (session->mtu - sizeof(pwd_hdr));
156  }
157  } else {
158  /*
159  * either it's not a fragment or it's the last fragment.
160  * The out buffer isn't needed anymore though so get rid of it.
161  */
162  memcpy(hdr->data, session->out + session->out_pos,
163  (session->out_len - session->out_pos));
164  talloc_free(session->out);
165  session->out = NULL;
166  session->out_pos = session->out_len = 0;
167  }
168  return 1;
169 }
170 
171 static int CC_HINT(nonnull) mod_process(void *instance, eap_session_t *eap_session);
172 
173 static int mod_session_init (void *instance, eap_session_t *eap_session)
174 {
175  pwd_session_t *session;
176  eap_pwd_t *inst = (eap_pwd_t *)instance;
177  VALUE_PAIR *vp;
178  pwd_id_packet_t *packet;
179 
180  if (!inst || !eap_session) {
181  ERROR("rlm_eap_pwd: Initiate, NULL data provided");
182  return 0;
183  }
184 
185  /*
186  * make sure the server's been configured properly
187  */
188  if (!inst->server_id) {
189  ERROR("rlm_eap_pwd: Server ID is not configured");
190  return 0;
191  }
192  switch (inst->group) {
193  case 19:
194  case 20:
195  case 21:
196  case 25:
197  case 26:
198  break;
199 
200  default:
201  ERROR("rlm_eap_pwd: Group is not supported");
202  return 0;
203  }
204 
205  if ((session = talloc_zero(eap_session, pwd_session_t)) == NULL) return 0;
206  talloc_set_destructor(session, _free_pwd_session);
207  /*
208  * set things up so they can be free'd reliably
209  */
210  session->group_num = inst->group;
211  session->private_value = NULL;
212  session->peer_scalar = NULL;
213  session->my_scalar = NULL;
214  session->k = NULL;
215  session->my_element = NULL;
216  session->peer_element = NULL;
217  session->group = NULL;
218  session->pwe = NULL;
219  session->order = NULL;
220  session->prime = NULL;
221 
222  /*
223  * The admin can dynamically change the MTU.
224  */
225  session->mtu = inst->fragment_size;
226  vp = fr_pair_find_by_num(eap_session->request->packet->vps, 0, PW_FRAMED_MTU, TAG_ANY);
227 
228  /*
229  * session->mtu is *our* MTU. We need to subtract off the EAP
230  * overhead.
231  *
232  * 9 = 4 (EAPOL header) + 4 (EAP header) + 1 (EAP type)
233  *
234  * The fragmentation code deals with the included length
235  * so we don't need to subtract that here.
236  */
237  if (vp && (vp->vp_integer > 100) && (vp->vp_integer < session->mtu)) {
238  session->mtu = vp->vp_integer - 9;
239  }
240 
241  session->state = PWD_STATE_ID_REQ;
242  session->in = NULL;
243  session->out_pos = 0;
244  eap_session->opaque = session;
245 
246  /*
247  * construct an EAP-pwd-ID/Request
248  */
249  session->out_len = sizeof(pwd_id_packet_t) + strlen(inst->server_id);
250  if ((session->out = talloc_zero_array(session, uint8_t, session->out_len)) == NULL) return 0;
251 
252  packet = (pwd_id_packet_t *)session->out;
253  packet->group_num = htons(session->group_num);
254  packet->random_function = EAP_PWD_DEF_RAND_FUN;
255  packet->prf = EAP_PWD_DEF_PRF;
256  session->token = fr_rand();
257  memcpy(packet->token, (char *)&session->token, 4);
258  packet->prep = EAP_PWD_PREP_NONE;
259  memcpy(packet->identity, inst->server_id, session->out_len - sizeof(pwd_id_packet_t) );
260 
261  if (!send_pwd_request(session, eap_session->this_round)) return 0;
262 
263  eap_session->process = mod_process;
264 
265  return 1;
266 }
267 
268 static int mod_process(void *arg, eap_session_t *eap_session)
269 {
270  pwd_session_t *session;
271  pwd_hdr *hdr;
272  pwd_id_packet_t *packet;
273  eap_packet_t *response;
274  REQUEST *request, *fake;
275  VALUE_PAIR *pw, *vp;
277  size_t in_len;
278  int ret = 0;
279  eap_pwd_t *inst = (eap_pwd_t *)arg;
280  uint16_t offset;
281  uint8_t exch, *in, *ptr, msk[MSK_EMSK_LEN], emsk[MSK_EMSK_LEN];
282  uint8_t peer_confirm[SHA256_DIGEST_LENGTH];
283  BIGNUM *x = NULL, *y = NULL;
284 
285  if (((eap_round = eap_session->this_round) == NULL) || !inst) return 0;
286 
287  session = (pwd_session_t *)eap_session->opaque;
288  request = eap_session->request;
289  response = eap_session->this_round->response;
290  hdr = (pwd_hdr *)response->type.data;
291 
292  /*
293  * The header must be at least one byte.
294  */
295  if (!hdr || (response->type.length < sizeof(pwd_hdr))) {
296  RDEBUG("Packet with insufficient data");
297  return 0;
298  }
299 
300  in = hdr->data;
301  in_len = response->type.length - sizeof(pwd_hdr);
302 
303  /*
304  * see if we're fragmenting, if so continue until we're done
305  */
306  if (session->out_pos) {
307  if (in_len) RDEBUG2("pwd got something more than an ACK for a fragment");
308 
309  return send_pwd_request(session, eap_round);
310  }
311 
312  /*
313  * the first fragment will have a total length, make a
314  * buffer to hold all the fragments
315  */
316  if (EAP_PWD_GET_LENGTH_BIT(hdr)) {
317  if (session->in) {
318  RDEBUG2("pwd already alloced buffer for fragments");
319  return 0;
320  }
321 
322  if (in_len < 2) {
323  RDEBUG("Invalid packet: length bit set, but no length field");
324  return 0;
325  }
326 
327  session->in_len = ntohs(in[0] * 256 | in[1]);
328  if ((session->in = talloc_zero_array(session, uint8_t, session->in_len)) == NULL) {
329  RDEBUG2("pwd cannot allocate %zd buffer to hold fragments", session->in_len);
330  return 0;
331  }
332 
333  memset(session->in, 0, session->in_len);
334  session->in_pos = 0;
335  in += sizeof(uint16_t);
336  in_len -= sizeof(uint16_t);
337  }
338 
339  /*
340  * all fragments, including the 1st will have the M(ore) bit set,
341  * buffer those fragments!
342  */
343  if (EAP_PWD_GET_MORE_BIT(hdr)) {
344  rad_assert(session->in != NULL);
345 
346  if ((session->in_pos + in_len) > session->in_len) {
347  RDEBUG2("Fragment overflows packet.");
348  return 0;
349  }
350 
351  memcpy(session->in + session->in_pos, in, in_len);
352  session->in_pos += in_len;
353 
354  /*
355  * send back an ACK for this fragment
356  */
357  exch = EAP_PWD_GET_EXCHANGE(hdr);
358  eap_round->request->code = PW_EAP_REQUEST;
359  eap_round->request->type.num = PW_EAP_PWD;
360  eap_round->request->type.length = sizeof(pwd_hdr);
361 
362  if ((eap_round->request->type.data = talloc_array(eap_round->request, uint8_t, sizeof(pwd_hdr))) == NULL) {
363  return 0;
364  }
365  hdr = (pwd_hdr *)eap_round->request->type.data;
366  EAP_PWD_SET_EXCHANGE(hdr, exch);
367  return 1;
368  }
369 
370 
371  if (session->in) {
372  /*
373  * the last fragment...
374  */
375  if ((session->in_pos + in_len) > session->in_len) {
376  RDEBUG2("pwd will not overflow a fragment buffer. Nope, not prudent");
377  return 0;
378  }
379  memcpy(session->in + session->in_pos, in, in_len);
380  in = session->in;
381  in_len = session->in_len;
382  }
383 
384  switch (session->state) {
385  case PWD_STATE_ID_REQ:
387  RDEBUG2("pwd exchange is incorrect: not ID");
388  return 0;
389  }
390 
391  packet = (pwd_id_packet_t *) in;
392  if (in_len < sizeof(packet)) {
393  RDEBUG("Packet is too small (%zd < %zd).", in_len, sizeof(packet));
394  return 0;
395  }
396 
397  if ((packet->prf != EAP_PWD_DEF_PRF) ||
398  (packet->random_function != EAP_PWD_DEF_RAND_FUN) ||
399  (packet->prep != EAP_PWD_PREP_NONE) ||
400  (CRYPTO_memcmp(packet->token, &session->token, 4)) ||
401  (packet->group_num != ntohs(session->group_num))) {
402  RDEBUG2("pwd id response is invalid");
403  return 0;
404  }
405  /*
406  * we've agreed on the ciphersuite, record it...
407  */
408  ptr = (uint8_t *)&session->ciphersuite;
409  memcpy(ptr, (char *)&packet->group_num, sizeof(uint16_t));
410  ptr += sizeof(uint16_t);
411  *ptr = EAP_PWD_DEF_RAND_FUN;
412  ptr += sizeof(uint8_t);
413  *ptr = EAP_PWD_DEF_PRF;
414 
415  session->peer_id_len = in_len - sizeof(pwd_id_packet_t);
416  if (session->peer_id_len >= sizeof(session->peer_id)) {
417  RDEBUG2("pwd id response is malformed");
418  return 0;
419  }
420 
421  memcpy(session->peer_id, packet->identity, session->peer_id_len);
422  session->peer_id[session->peer_id_len] = '\0';
423 
424  /*
425  * make fake request to get the password for the usable ID
426  */
427  if ((fake = request_alloc_fake(eap_session->request)) == NULL) {
428  RDEBUG("pwd unable to create fake request!");
429  return 0;
430  }
431  fake->username = fr_pair_afrom_num(fake, 0, PW_USER_NAME);
432  if (!fake->username) {
433  RDEBUG("Failed creating pair for peer id");
434  talloc_free(fake);
435  return 0;
436  }
437  fr_pair_value_bstrncpy(fake->username, session->peer_id, session->peer_id_len);
438  fr_pair_add(&fake->packet->vps, fake->username);
439 
440  if ((vp = fr_pair_find_by_num(request->config, 0, PW_VIRTUAL_SERVER, TAG_ANY)) != NULL) {
441  fake->server = vp->vp_strvalue;
442  } else if (inst->virtual_server) {
443  fake->server = inst->virtual_server;
444  } /* else fake->server == request->server */
445 
446  RDEBUG("Sending tunneled request");
447  rdebug_pair_list(L_DBG_LVL_1, request, fake->packet->vps, NULL);
448 
449  if (fake->server) {
450  RDEBUG("server %s {", fake->server);
451  } else {
452  RDEBUG("server {");
453  }
454 
455  /*
456  * Call authorization recursively, which will
457  * get the password.
458  */
459  RINDENT();
460  process_authorize(0, fake);
461  REXDENT();
462 
463  /*
464  * Note that we don't do *anything* with the reply
465  * attributes.
466  */
467  if (fake->server) {
468  RDEBUG("} # server %s", fake->server);
469  } else {
470  RDEBUG("}");
471  }
472 
473  RDEBUG("Got tunneled reply code %d", fake->reply->code);
474  rdebug_pair_list(L_DBG_LVL_1, request, fake->reply->vps, NULL);
475 
476  if ((pw = fr_pair_find_by_num(fake->config, 0, PW_CLEARTEXT_PASSWORD, TAG_ANY)) == NULL) {
477  DEBUG2("failed to find password for %s to do pwd authentication", session->peer_id);
478  talloc_free(fake);
479  return 0;
480  }
481 
482  if (compute_password_element(session, session->group_num,
483  pw->data.strvalue, strlen(pw->data.strvalue),
484  inst->server_id, strlen(inst->server_id),
485  session->peer_id, strlen(session->peer_id),
486  &session->token)) {
487  DEBUG2("failed to obtain password element");
488  talloc_free(fake);
489  return 0;
490  }
491  TALLOC_FREE(fake);
492 
493  /*
494  * compute our scalar and element
495  */
496  if (compute_scalar_element(session, inst->bnctx)) {
497  DEBUG2("failed to compute server's scalar and element");
498  return 0;
499  }
500 
501  if (((x = BN_new()) == NULL) || ((y = BN_new()) == NULL)) {
502  DEBUG2("server point allocation failed");
503  return 0;
504  }
505 
506  /*
507  * element is a point, get both coordinates: x and y
508  */
509  if (!EC_POINT_get_affine_coordinates_GFp(session->group, session->my_element, x, y, inst->bnctx)) {
510  DEBUG2("server point assignment failed");
511  BN_clear_free(x);
512  BN_clear_free(y);
513  return 0;
514  }
515 
516  /*
517  * construct request
518  */
519  session->out_len = BN_num_bytes(session->order) + (2 * BN_num_bytes(session->prime));
520  if ((session->out = talloc_array(session, uint8_t, session->out_len)) == NULL) {
521  return 0;
522  }
523  memset(session->out, 0, session->out_len);
524 
525  ptr = session->out;
526  offset = BN_num_bytes(session->prime) - BN_num_bytes(x);
527  BN_bn2bin(x, ptr + offset);
528 
529  ptr += BN_num_bytes(session->prime);
530  offset = BN_num_bytes(session->prime) - BN_num_bytes(y);
531  BN_bn2bin(y, ptr + offset);
532 
533  ptr += BN_num_bytes(session->prime);
534  offset = BN_num_bytes(session->order) - BN_num_bytes(session->my_scalar);
535  BN_bn2bin(session->my_scalar, ptr + offset);
536 
537  session->state = PWD_STATE_COMMIT;
538  ret = send_pwd_request(session, eap_round);
539  break;
540 
541  case PWD_STATE_COMMIT:
543  RDEBUG2("pwd exchange is incorrect: not commit!");
544  return 0;
545  }
546 
547  /*
548  * process the peer's commit and generate the shared key, k
549  */
550  if (process_peer_commit(session, in, in_len, inst->bnctx)) {
551  RDEBUG2("failed to process peer's commit");
552  return 0;
553  }
554 
555  /*
556  * compute our confirm blob
557  */
558  if (compute_server_confirm(session, session->my_confirm, inst->bnctx)) {
559  ERROR("rlm_eap_pwd: failed to compute confirm!");
560  return 0;
561  }
562 
563  /*
564  * construct a response...which is just our confirm blob
565  */
566  session->out_len = SHA256_DIGEST_LENGTH;
567  if ((session->out = talloc_array(session, uint8_t, session->out_len)) == NULL) return 0;
568 
569  memset(session->out, 0, session->out_len);
570  memcpy(session->out, session->my_confirm, SHA256_DIGEST_LENGTH);
571 
572  session->state = PWD_STATE_CONFIRM;
573  ret = send_pwd_request(session, eap_round);
574  break;
575 
576  case PWD_STATE_CONFIRM:
577  if (in_len < SHA256_DIGEST_LENGTH) {
578  RDEBUG("Peer confirm is too short (%zd < %d)", in_len, SHA256_DIGEST_LENGTH);
579  return 0;
580  }
581 
583  RDEBUG2("pwd exchange is incorrect: not commit!");
584  return 0;
585  }
586  if (compute_peer_confirm(session, peer_confirm, inst->bnctx)) {
587  RDEBUG2("pwd exchange cannot compute peer's confirm");
588  return 0;
589  }
590  if (CRYPTO_memcmp(peer_confirm, in, SHA256_DIGEST_LENGTH)) {
591  RDEBUG2("pwd exchange fails: peer confirm is incorrect!");
592  return 0;
593  }
594  if (compute_keys(session, peer_confirm, msk, emsk)) {
595  RDEBUG2("pwd exchange cannot generate (E)MSK!");
596  return 0;
597  }
598  eap_round->request->code = PW_EAP_SUCCESS;
599  /*
600  * return the MSK (in halves)
601  */
602  eap_add_reply(eap_session->request, "MS-MPPE-Recv-Key", msk, MPPE_KEY_LEN);
603  eap_add_reply(eap_session->request, "MS-MPPE-Send-Key", msk + MPPE_KEY_LEN, MPPE_KEY_LEN);
604 
605  ret = 1;
606  break;
607 
608  default:
609  RDEBUG2("unknown PWD state");
610  return 0;
611  }
612 
613 
614  /*
615  * we processed the buffered fragments, get rid of them
616  */
617  if (session->in) {
618  talloc_free(session->in);
619  session->in = NULL;
620  }
621 
622  return ret;
623 }
624 
626 rlm_eap_module_t rlm_eap_pwd = {
627  .name = "eap_pwd",
628  .instantiate = mod_instantiate, /* Create new submodule instance */
629  .session_init = mod_session_init, /* Create the initial request */
630  .process = mod_process, /* Process next round of EAP method */
631  .detach = mod_detach /* Destroy the submodule instance */
632 };
633 
#define EAP_PWD_SET_EXCHANGE(x, y)
Definition: eap_pwd.h:60
char const * server_id
Definition: rlm_eap_pwd.h:47
VALUE_PAIR * config
VALUE_PAIR (s) used to set per request parameters for modules and the server core at runtime...
Definition: radiusd.h:227
#define RINDENT()
Indent R* messages by one level.
Definition: log.h:265
rlm_rcode_t process_authorize(int type, REQUEST *request)
Definition: modules.c:2098
static int _free_pwd_session(pwd_session_t *session)
Definition: rlm_eap_pwd.c:85
BIGNUM * k
Definition: eap_pwd.h:97
VALUE_PAIR * fr_pair_afrom_num(TALLOC_CTX *ctx, unsigned int vendor, unsigned int attr)
Create a new valuepair.
Definition: pair.c:106
uint32_t fr_rand(void)
Return a 32-bit random number.
Definition: radius.c:1621
static int mod_instantiate(CONF_SECTION *cs, void **instance)
Definition: rlm_eap_pwd.c:63
#define EAP_PWD_GET_LENGTH_BIT(x)
Definition: eap_pwd.h:55
uint32_t ciphersuite
Definition: eap_pwd.h:82
BIGNUM * peer_scalar
Definition: eap_pwd.h:99
int process_peer_commit(pwd_session_t *session, uint8_t *in, size_t in_len, BN_CTX *bnctx)
Definition: eap_pwd.c:315
BIGNUM * my_scalar
Definition: eap_pwd.h:100
VALUE_PAIR * username
Cached username VALUE_PAIR from request RADIUS_PACKET.
Definition: radiusd.h:222
#define MSK_EMSK_LEN
Definition: rlm_eap_pwd.c:42
VALUE_PAIR * vps
Result of decoding the packet into VALUE_PAIRs.
Definition: libradius.h:162
#define CONF_PARSER_TERMINATOR
Definition: conffile.h:289
int compute_scalar_element(pwd_session_t *session, BN_CTX *bnctx)
Definition: eap_pwd.c:273
static int mod_process(void *arg, eap_session_t *eap_session)
Definition: rlm_eap_pwd.c:268
int compute_password_element(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)
Definition: eap_pwd.c:103
int compute_keys(pwd_session_t *session, uint8_t *peer_confirm, uint8_t *msk, uint8_t *emsk)
Definition: eap_pwd.c:619
eap_packet_t * request
Packet we will send to the peer.
Definition: eap.h:45
#define inst
void * opaque
Opaque data used by EAP methods.
Definition: eap.h:80
size_t in_len
Definition: eap_pwd.h:89
#define EAP_PWD_GET_MORE_BIT(x)
Definition: eap_pwd.h:57
#define EAP_PWD_SET_MORE_BIT(x)
Definition: eap_pwd.h:58
REQUEST * request_alloc_fake(REQUEST *oldreq)
Definition: request.c:124
Defines a CONF_PAIR to C data type mapping.
Definition: conffile.h:267
eap_type_data_t type
Definition: eap_types.h:136
REQUEST * request
Request that contains the response we're processing.
Definition: eap.h:71
static int mod_session_init(void *instance, eap_session_t *eap_session)
Definition: rlm_eap_gtc.c:89
BIGNUM * prime
Definition: eap_pwd.h:96
#define MPPE_KEY_LEN
Definition: rlm_eap_pwd.c:41
int compute_peer_confirm(pwd_session_t *session, uint8_t *out, BN_CTX *bnctx)
Definition: eap_pwd.c:520
#define rad_assert(expr)
Definition: rad_assert.h:38
#define PWD_STATE_CONFIRM
Definition: eap_pwd.h:80
eap_type_t num
Definition: eap_types.h:122
#define EAP_PWD_PREP_NONE
Definition: eap_pwd.h:627
Highest priority debug messages (-x).
Definition: log.h:51
size_t out_len
Definition: eap_pwd.h:92
uint32_t token
Definition: eap_pwd.h:83
#define PWD_STATE_ID_REQ
Definition: eap_pwd.h:78
char peer_id[MAX_STRING_LEN]
Definition: eap_pwd.h:84
uint8_t * in
Definition: eap_pwd.h:87
void fr_pair_add(VALUE_PAIR **head, VALUE_PAIR *vp)
Add a VP to the end of the list.
Definition: pair.c:659
Tracks the progress of a single session of any EAP method.
Definition: eap.h:60
#define DEBUG2(fmt,...)
Definition: log.h:176
size_t mtu
Definition: eap_pwd.h:86
int cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables)
Parse a configuration section into user-supplied variables.
Definition: conffile.c:2234
unsigned int code
Packet code (type).
Definition: libradius.h:155
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition: eap.h:77
uint8_t my_confirm[SHA256_DIGEST_LENGTH]
Definition: eap_pwd.h:103
EC_POINT * peer_element
Definition: eap_pwd.h:102
uint32_t group
Definition: rlm_eap_pwd.h:45
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
size_t length
Definition: eap_types.h:123
RADIUS_PACKET * reply
Outgoing response.
Definition: radiusd.h:225
void void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
static int CC_HINT(nonnull)
Definition: rlm_eap_pwd.c:171
EC_POINT * my_element
Definition: eap_pwd.h:101
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition: log.h:272
static int mod_detach(void *arg)
Definition: rlm_eap_pwd.c:52
32 Bit unsigned integer.
Definition: radius.h:34
Contains a pair of request and response packets.
Definition: eap.h:43
char const * name
The name of the sub-module (without rlm_ prefix).
Definition: eap.h:96
int compute_server_confirm(pwd_session_t *session, uint8_t *out, BN_CTX *bnctx)
Definition: eap_pwd.c:421
void rdebug_pair_list(log_lvl_t level, REQUEST *, VALUE_PAIR *, char const *)
Print a list of VALUE_PAIRs.
Definition: pair.c:757
#define EAP_PWD_GET_EXCHANGE(x)
Definition: eap_pwd.h:59
BIGNUM * private_value
Definition: eap_pwd.h:98
#define RDEBUG2(fmt,...)
Definition: log.h:244
uint8_t * out
Definition: eap_pwd.h:90
#define TAG_ANY
Definition: pair.h:191
Interface to call EAP sub mdoules.
Definition: eap.h:95
static const void * fake
Definition: rlm_sql_null.c:33
#define FR_CONF_OFFSET(_n, _t, _s, _f)
Definition: conffile.h:168
#define EAP_PWD_EXCH_CONFIRM
Definition: eap_pwd.h:623
size_t in_pos
Definition: eap_pwd.h:88
uint16_t state
Definition: eap_pwd.h:77
RADIUS_PACKET * packet
Incoming request.
Definition: radiusd.h:221
#define EAP_PWD_DEF_PRF
Definition: eap_pwd.h:624
#define EAP_PWD_EXCH_COMMIT
Definition: eap_pwd.h:622
uint32_t fragment_size
Definition: rlm_eap_pwd.h:46
size_t out_pos
Definition: eap_pwd.h:91
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
Definition: pair.c:639
static CONF_PARSER pwd_module_config[]
Definition: rlm_eap_pwd.c:44
#define EAP_PWD_DEF_RAND_FUN
Definition: eap_pwd.h:622
Structure to hold EAP data.
Definition: eap_types.h:132
static int send_pwd_request(pwd_session_t *session, eap_round_t *eap_round)
Definition: rlm_eap_pwd.c:101
#define EAP_PWD_EXCH_ID
Definition: eap_pwd.h:621
void fr_pair_value_bstrncpy(VALUE_PAIR *vp, void const *src, size_t len)
Copy data into an "string" data type.
Definition: pair.c:2043
eap_packet_t * response
Packet we received from the peer.
Definition: eap.h:44
BIGNUM * order
Definition: eap_pwd.h:95
String of printable characters.
Definition: radius.h:33
uint16_t group_num
Definition: eap_pwd.h:81
#define RCSID(id)
Definition: build.h:135
#define EAP_PWD_SET_LENGTH_BIT(x)
Definition: eap_pwd.h:56
EC_POINT * pwe
Definition: eap_pwd.h:94
rlm_eap_module_t rlm_eap_pwd
Definition: rlm_eap_pwd.c:626
#define RDEBUG(fmt,...)
Definition: log.h:243
#define ERROR(fmt,...)
Definition: log.h:145
eap_code_t code
Definition: eap_types.h:133
void eap_add_reply(REQUEST *request, char const *name, uint8_t const *value, int len)
Definition: eapcommon.c:388
EC_GROUP * group
Definition: eap_pwd.h:93
char const * server
Definition: radiusd.h:289
#define USES_APPLE_DEPRECATED_API
Definition: build.h:122
BN_CTX * bnctx
Definition: rlm_eap_pwd.h:43
#define PWD_STATE_COMMIT
Definition: eap_pwd.h:79
char const * virtual_server
Definition: rlm_eap_pwd.h:48
uint8_t * data
Definition: eap_types.h:124
size_t peer_id_len
Definition: eap_pwd.h:85
value_data_t data
Definition: pair.h:133