The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
rlm_eap_md5.c
Go to the documentation of this file.
1 /*
2  * rlm_eap_md5.c Handles that are called from eap
3  *
4  * Version: $Id: 8aff65ee19d9605cdc242fc709bdf934bfb61dc9 $
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * @copyright 2000,2001,2006 The FreeRADIUS server project
21  * @copyright 2001 hereUare Communications, Inc. (raghud@hereuare.com)
22  */
23 
24 RCSID("$Id: 8aff65ee19d9605cdc242fc709bdf934bfb61dc9 $")
25 
26 #include <freeradius-devel/server/password.h>
27 #include <freeradius-devel/util/debug.h>
28 #include <freeradius-devel/util/md5.h>
29 #include <freeradius-devel/util/rand.h>
30 
31 #include "eap_md5.h"
32 
33 static fr_dict_t const *dict_freeradius;
34 
37  { .out = &dict_freeradius, .proto = "freeradius" },
38  { NULL }
39 };
40 
42 
45  { .out = &attr_cleartext_password, .name = "Password.Cleartext", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
46  { NULL }
47 };
48 
49 /*
50  * Authenticate a previously sent challenge.
51  */
52 static unlang_action_t mod_process(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
53 {
54  eap_session_t *eap_session = eap_session_get(request->parent);
55  MD5_PACKET *packet;
56  MD5_PACKET *reply;
57  fr_pair_t *known_good;
58  fr_dict_attr_t const *allowed_passwords[] = { attr_cleartext_password };
59  bool ephemeral;
60 
61  /*
62  * Get the Password.Cleartext for this user.
63  */
64  fr_assert(eap_session->request != NULL);
65 
66  known_good = password_find(&ephemeral, request, request->parent,
67  allowed_passwords, NUM_ELEMENTS(allowed_passwords),
68  false);
69  if (!known_good) {
70  REDEBUG("No \"known good\" password found for user");
72  }
73 
74  /*
75  * Extract the EAP-MD5 packet.
76  */
77  packet = eap_md5_extract(request, eap_session->this_round);
78  if (!packet) {
79  if (ephemeral) TALLOC_FREE(known_good);
81  }
82 
83  /*
84  * Create a reply, and initialize it.
85  */
86  MEM(reply = talloc(packet, MD5_PACKET));
87  reply->id = eap_session->this_round->request->id;
88  reply->length = 0;
89 
90  /*
91  * Verify the received packet against the previous packet
92  * (i.e. challenge) which we sent out.
93  */
94  if (eap_md5_verify(request, packet, known_good, eap_session->opaque)) {
95  reply->code = FR_MD5_SUCCESS;
96  } else {
97  reply->code = FR_MD5_FAILURE;
98  }
99 
100  /*
101  * Compose the EAP-MD5 packet out of the data structure,
102  * and free it.
103  */
104  eap_md5_compose(eap_session->this_round, reply);
105  talloc_free(packet);
106 
107  if (ephemeral) TALLOC_FREE(known_good);
108 
110 }
111 
112 /*
113  * Initiate the EAP-MD5 session by sending a challenge to the peer.
114  */
116 {
117  eap_session_t *eap_session = eap_session_get(request->parent);
118  MD5_PACKET *reply;
119  int i;
120 
121  fr_assert(eap_session != NULL);
122 
123  /*
124  * Allocate an EAP-MD5 packet.
125  */
126  MEM(reply = talloc(eap_session, MD5_PACKET));
127 
128  /*
129  * Fill it with data.
130  */
131  reply->code = FR_MD5_CHALLENGE;
132  reply->length = 1 + MD5_CHALLENGE_LEN; /* one byte of value size */
133  reply->value_size = MD5_CHALLENGE_LEN;
134 
135  /*
136  * Allocate user data.
137  */
138  MEM(reply->value = talloc_array(reply, uint8_t, reply->value_size));
139  /*
140  * Get a random challenge.
141  */
142  for (i = 0; i < reply->value_size; i++) reply->value[i] = fr_rand();
143  RDEBUG2("Issuing MD5 Challenge");
144 
145  /*
146  * Keep track of the challenge.
147  */
148  MEM(eap_session->opaque = talloc_array(eap_session, uint8_t, reply->value_size));
149  memcpy(eap_session->opaque, reply->value, reply->value_size);
150 
151  /*
152  * Compose the EAP-MD5 packet out of the data structure,
153  * and free it.
154  */
155  eap_md5_compose(eap_session->this_round, reply);
156 
157  /*
158  * We don't need to authorize the user at this point.
159  *
160  * We also don't need to keep the challenge, as it's
161  * stored in 'eap_session->this_round', which will be given back
162  * to us...
163  */
164  eap_session->process = mod_process;
165 
167 }
168 
169 /*
170  * The module name should be the only globally exported symbol.
171  * That is, everything else should be 'static'.
172  */
175  .common = {
176  .magic = MODULE_MAGIC_INIT,
177  .name = "eap_md5"
178  },
179  .provides = { FR_EAP_METHOD_MD5 },
180  .session_init = mod_session_init, /* Initialise a new EAP session */
181 };
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition: action.h:35
#define RCSID(id)
Definition: build.h:444
#define UNUSED
Definition: build.h:313
#define NUM_ELEMENTS(_t)
Definition: build.h:335
uint8_t id
Definition: compose.h:37
eap_packet_t * request
Packet we will send to the peer.
Definition: compose.h:50
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:250
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:263
Specifies an attribute which must be present for the module to function.
Definition: dict.h:249
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:262
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:65
@ FR_EAP_METHOD_MD5
Definition: types.h:49
MD5_PACKET * eap_md5_extract(request_t *request, eap_round_t *eap_round)
Definition: eap_md5.c:49
int eap_md5_verify(request_t *request, MD5_PACKET *packet, fr_pair_t *password, uint8_t *challenge)
Definition: eap_md5.c:129
int eap_md5_compose(eap_round_t *eap_round, MD5_PACKET *reply)
Definition: eap_md5.c:179
#define FR_MD5_FAILURE
Definition: eap_md5.h:9
unsigned char id
Definition: eap_md5.h:38
#define MD5_CHALLENGE_LEN
Definition: eap_md5.h:13
unsigned short length
Definition: eap_md5.h:39
unsigned char code
Definition: eap_md5.h:37
unsigned char * value
Definition: eap_md5.h:41
unsigned char value_size
Definition: eap_md5.h:40
#define FR_MD5_SUCCESS
Definition: eap_md5.h:8
#define FR_MD5_CHALLENGE
Definition: eap_md5.h:6
void * opaque
Opaque data used by EAP methods.
Definition: session.h:62
module_method_t process
Callback that should be used to process the next round.
Definition: session.h:64
request_t * request
Current request.
Definition: session.h:51
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition: session.h:59
static eap_session_t * eap_session_get(request_t *request)
Definition: session.h:82
Tracks the progress of a single session of any EAP method.
Definition: session.h:40
talloc_free(reap)
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
unsigned char uint8_t
Definition: merged_model.c:30
Temporary structure to hold arguments for module calls.
Definition: module_ctx.h:41
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:963
#define REDEBUG(fmt,...)
Definition: radclient.h:52
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
uint32_t fr_rand(void)
Return a 32-bit random number.
Definition: rand.c:106
#define RETURN_MODULE_HANDLED
Definition: rcode.h:58
#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
fr_dict_autoload_t rlm_eap_md5_dict[]
Definition: rlm_eap_md5.c:36
static fr_dict_t const * dict_freeradius
Definition: rlm_eap_md5.c:33
static unlang_action_t mod_session_init(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
Definition: rlm_eap_md5.c:115
rlm_eap_submodule_t rlm_eap_md5
Definition: rlm_eap_md5.c:174
static fr_dict_attr_t const * attr_cleartext_password
Definition: rlm_eap_md5.c:41
fr_dict_attr_autoload_t rlm_eap_md5_dict_attr[]
Definition: rlm_eap_md5.c:44
static unlang_action_t mod_process(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
Definition: rlm_eap_md5.c:52
RETURN_MODULE_FAIL
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
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