More changes to make a common naming scheme. This breaks
[freeradius.git] / src / modules / rlm_eap / types / rlm_eap_md5 / rlm_eap_md5.c
1 /*
2  * rlm_eap_md5.c    Handles that are called from eap
3  *
4  * Version:     $Id$
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 #include <freeradius-devel/ident.h>
25 RCSID("$Id$")
26
27 #include <freeradius-devel/autoconf.h>
28
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include "eap_md5.h"
33
34 #include <freeradius-devel/rad_assert.h>
35
36 /*
37  *      Initiate the EAP-MD5 session by sending a challenge to the peer.
38  */
39 static int md5_initiate(void *type_data, EAP_HANDLER *handler)
40 {
41         int             i;
42         MD5_PACKET      *reply;
43
44         type_data = type_data;  /* -Wunused */
45
46         /*
47          *      Allocate an EAP-MD5 packet.
48          */
49         reply = eapmd5_alloc();
50         if (reply == NULL)  {
51                 radlog(L_ERR, "rlm_eap_md5: out of memory");
52                 return 0;
53         }
54
55         /*
56          *      Fill it with data.
57          */
58         reply->code = PW_MD5_CHALLENGE;
59         reply->length = 1 + MD5_CHALLENGE_LEN; /* one byte of value size */
60         reply->value_size = MD5_CHALLENGE_LEN;
61
62         /*
63          *      Allocate user data.
64          */
65         reply->value = malloc(reply->value_size);
66         if (reply->value == NULL) {
67                 radlog(L_ERR, "rlm_eap_md5: out of memory");
68                 eapmd5_free(&reply);
69                 return 0;
70         }
71
72         /*
73          *      Get a random challenge.
74          */
75         for (i = 0; i < reply->value_size; i++) {
76                 reply->value[i] = fr_rand();
77         }
78         radlog(L_INFO, "rlm_eap_md5: Issuing Challenge");
79
80         /*
81          *      Keep track of the challenge.
82          */
83         handler->opaque = malloc(reply->value_size);
84         rad_assert(handler->opaque != NULL);
85         memcpy(handler->opaque, reply->value, reply->value_size);
86         handler->free_opaque = free;
87
88         /*
89          *      Compose the EAP-MD5 packet out of the data structure,
90          *      and free it.
91          */
92         eapmd5_compose(handler->eap_ds, reply);
93
94         /*
95          *      We don't need to authorize the user at this point.
96          *
97          *      We also don't need to keep the challenge, as it's
98          *      stored in 'handler->eap_ds', which will be given back
99          *      to us...
100          */
101         handler->stage = AUTHENTICATE;
102
103         return 1;
104 }
105
106
107 /*
108  *      Authenticate a previously sent challenge.
109  */
110 static int md5_authenticate(UNUSED void *arg, EAP_HANDLER *handler)
111 {
112         MD5_PACKET      *packet;
113         MD5_PACKET      *reply;
114         VALUE_PAIR      *password;
115
116         /*
117          *      Get the Cleartext-Password for this user.
118          */
119         rad_assert(handler->request != NULL);
120         rad_assert(handler->stage == AUTHENTICATE);
121
122         password = pairfind(handler->request->config_items, PW_CLEARTEXT_PASSWORD);
123         if (password == NULL) {
124                 radlog(L_INFO, "rlm_eap_md5: Cleartext-Password is required for EAP-MD5 authentication");
125                 return 0;
126         }
127
128         /*
129          *      Extract the EAP-MD5 packet.
130          */
131         if (!(packet = eapmd5_extract(handler->eap_ds)))
132                 return 0;
133
134         /*
135          *      Create a reply, and initialize it.
136          */
137         reply = eapmd5_alloc();
138         if (!reply) {
139                 return 0;
140         }
141         reply->id = handler->eap_ds->request->id;
142         reply->length = 0;
143
144         /*
145          *      Verify the received packet against the previous packet
146          *      (i.e. challenge) which we sent out.
147          */
148         if (eapmd5_verify(packet, password, handler->opaque)) {
149                 reply->code = PW_MD5_SUCCESS;
150         } else {
151                 reply->code = PW_MD5_FAILURE;
152         }
153
154         /*
155          *      Compose the EAP-MD5 packet out of the data structure,
156          *      and free it.
157          */
158         eapmd5_compose(handler->eap_ds, reply);
159
160         eapmd5_free(&packet);
161         return 1;
162 }
163
164 /*
165  *      The module name should be the only globally exported symbol.
166  *      That is, everything else should be 'static'.
167  */
168 EAP_TYPE rlm_eap_md5 = {
169         "eap_md5",
170         NULL,                           /* attach */
171         md5_initiate,                   /* Start the initial request */
172         NULL,                           /* authorization */
173         md5_authenticate,               /* authentication */
174         NULL                            /* detach */
175 };