All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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: 47383f30d2699cc813bf2e703b23ab196abeb036 $
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: 47383f30d2699cc813bf2e703b23ab196abeb036 $")
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 
29 #include "eap_md5.h"
30 
31 #include <freeradius-devel/rad_assert.h>
32 #include <freeradius-devel/md5.h>
33 
34 static int mod_process(UNUSED void *arg, eap_session_t *eap_session);
35 
36 /*
37  * Initiate the EAP-MD5 session by sending a challenge to the peer.
38  */
39 static int mod_session_init(UNUSED void *instance, eap_session_t *eap_session)
40 {
41  int i;
42  MD5_PACKET *reply;
43  REQUEST *request = eap_session->request;
44 
45  /*
46  * Allocate an EAP-MD5 packet.
47  */
48  reply = talloc(eap_session, MD5_PACKET);
49  if (!reply) {
50  return 0;
51  }
52 
53  /*
54  * Fill it with data.
55  */
56  reply->code = PW_MD5_CHALLENGE;
57  reply->length = 1 + MD5_CHALLENGE_LEN; /* one byte of value size */
59 
60  /*
61  * Allocate user data.
62  */
63  reply->value = talloc_array(reply, uint8_t, reply->value_size);
64  if (!reply->value) {
65  talloc_free(reply);
66  return 0;
67  }
68 
69  /*
70  * Get a random challenge.
71  */
72  for (i = 0; i < reply->value_size; i++) {
73  reply->value[i] = fr_rand();
74  }
75  RDEBUG2("Issuing MD5 Challenge");
76 
77  /*
78  * Keep track of the challenge.
79  */
80  eap_session->opaque = talloc_array(eap_session, uint8_t, reply->value_size);
81  rad_assert(eap_session->opaque != NULL);
82  memcpy(eap_session->opaque, reply->value, reply->value_size);
83 
84  /*
85  * Compose the EAP-MD5 packet out of the data structure,
86  * and free it.
87  */
88  eapmd5_compose(eap_session->this_round, reply);
89 
90  /*
91  * We don't need to authorize the user at this point.
92  *
93  * We also don't need to keep the challenge, as it's
94  * stored in 'eap_session->this_round', which will be given back
95  * to us...
96  */
97  eap_session->process = mod_process;
98 
99  return 1;
100 }
101 
102 /*
103  * Authenticate a previously sent challenge.
104  */
105 static int mod_process(UNUSED void *arg, eap_session_t *eap_session)
106 {
107  MD5_PACKET *packet;
108  MD5_PACKET *reply;
109  VALUE_PAIR *password;
110  REQUEST *request = eap_session->request;
111 
112  /*
113  * Get the Cleartext-Password for this user.
114  */
115  rad_assert(eap_session->request != NULL);
116 
117  password = fr_pair_find_by_num(eap_session->request->config, 0, PW_CLEARTEXT_PASSWORD, TAG_ANY);
118  if (!password) {
119  RDEBUG2("Cleartext-Password is required for EAP-MD5 authentication");
120  return 0;
121  }
122 
123  /*
124  * Extract the EAP-MD5 packet.
125  */
126  if (!(packet = eapmd5_extract(eap_session->this_round)))
127  return 0;
128 
129  /*
130  * Create a reply, and initialize it.
131  */
132  reply = talloc(packet, MD5_PACKET);
133  if (!reply) {
134  talloc_free(packet);
135  return 0;
136  }
137  reply->id = eap_session->this_round->request->id;
138  reply->length = 0;
139 
140  /*
141  * Verify the received packet against the previous packet
142  * (i.e. challenge) which we sent out.
143  */
144  if (eapmd5_verify(packet, password, eap_session->opaque)) {
145  reply->code = PW_MD5_SUCCESS;
146  } else {
147  reply->code = PW_MD5_FAILURE;
148  }
149 
150  /*
151  * Compose the EAP-MD5 packet out of the data structure,
152  * and free it.
153  */
154  eapmd5_compose(eap_session->this_round, reply);
155  talloc_free(packet);
156  return 1;
157 }
158 
159 /*
160  * The module name should be the only globally exported symbol.
161  * That is, everything else should be 'static'.
162  */
164 rlm_eap_module_t rlm_eap_md5 = {
165  .name = "eap_md5",
166  .session_init = mod_session_init, /* Initialise a new EAP session */
167  .process = mod_process /* Process next round of EAP method */
168 };
VALUE_PAIR * config
VALUE_PAIR (s) used to set per request parameters for modules and the server core at runtime...
Definition: radiusd.h:227
int eapmd5_verify(MD5_PACKET *packet, VALUE_PAIR *password, uint8_t *challenge)
Definition: eap_md5.c:130
uint32_t fr_rand(void)
Return a 32-bit random number.
Definition: radius.c:1621
unsigned char id
Definition: eap_md5.h:40
eap_process_t process
Callback that should be used to process the next round.
Definition: eap.h:82
#define UNUSED
Definition: libradius.h:134
static int mod_session_init(UNUSED void *instance, eap_session_t *eap_session)
Definition: rlm_eap_md5.c:39
unsigned char code
Definition: eap_md5.h:39
eap_packet_t * request
Packet we will send to the peer.
Definition: eap.h:45
void * opaque
Opaque data used by EAP methods.
Definition: eap.h:80
MD5_PACKET * eapmd5_extract(eap_round_t *eap_round)
Definition: eap_md5.c:50
REQUEST * request
Request that contains the response we're processing.
Definition: eap.h:71
#define PW_MD5_CHALLENGE
Definition: eap_md5.h:8
rlm_eap_module_t rlm_eap_md5
Definition: rlm_eap_md5.c:164
#define rad_assert(expr)
Definition: rad_assert.h:38
uint8_t id
Definition: eap_types.h:134
#define PW_MD5_FAILURE
Definition: eap_md5.h:11
Tracks the progress of a single session of any EAP method.
Definition: eap.h:60
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition: eap.h:77
static int mod_process(UNUSED void *arg, eap_session_t *eap_session)
Definition: rlm_eap_md5.c:105
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
unsigned short length
Definition: eap_md5.h:41
char const * name
The name of the sub-module (without rlm_ prefix).
Definition: eap.h:96
#define RDEBUG2(fmt,...)
Definition: log.h:244
#define TAG_ANY
Definition: pair.h:191
Interface to call EAP sub mdoules.
Definition: eap.h:95
#define MD5_CHALLENGE_LEN
Definition: eap_md5.h:15
#define PW_MD5_SUCCESS
Definition: eap_md5.h:10
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
int eapmd5_compose(eap_round_t *eap_round, MD5_PACKET *reply)
Definition: eap_md5.c:180
unsigned char value_size
Definition: eap_md5.h:42
unsigned char * value
Definition: eap_md5.h:43
#define RCSID(id)
Definition: build.h:135