blob: d21c9ce2fe97037b9add8519700a644039379c88 [file] [log] [blame]
Brian Waters13d96012017-12-08 16:53:31 -06001/*****************************************************************************************************
2 * Software License Agreement (BSD License)
3 * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
4 *
5 * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
6 * All rights reserved.
7 *
8 * Redistribution and use of this software in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
21 *
22 * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
23 * names of its contributors may be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY
27 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
30 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *****************************************************************************************************/
37
38
39#include "../../plugins.h"
40GCC_DIAG_OFF("-Wdeprecated-declarations")
41#include <gcrypt.h>
42GCC_DIAG_ON("-Wdeprecated-declarations")
43
44#define CHALLENGE_LEN 16
45
46struct eap_md5_data
47{
48 enum
49 {
50 EAP_MD5_CONTINUE, EAP_MD5_SUCCESS, EAP_MD5_FAILURE
51 } state;
52 u8 * challenge;
53};
54
55int eap_md5_configure(char * configfile);
56int eap_md5_init(struct eap_state_machine *smd);
57int eap_md5_initPickUp(struct eap_state_machine *smd);
58int eap_md5_buildReq(struct eap_state_machine *smd, u8 eap_md5,
59 struct eap_packet * eapPacket);
60boolean eap_md5_check(struct eap_state_machine *smd, struct eap_packet *eapRespData);
61int eap_md5_process(struct eap_state_machine *smd, struct eap_packet *eapRespData);
62boolean eap_md5_isDone(struct eap_state_machine *smd);
63void eap_md5_free(void * data);
64
65REGISTER_METHOD("eap_md5", "eap_md5_configure", "eap_md5_init", "eap_md5_initPickUp", "eap_md5_buildReq", NULL, "eap_md5_check", "eap_md5_process", "eap_md5_isDone", NULL, NULL, "eap_md5_free")
66;
67
68int eap_md5_configure(char * configfile)
69{
70 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
71
72 return 0;
73}
74
75int eap_md5_init(struct eap_state_machine *smd)
76{
77 struct eap_md5_data *data = NULL;
78 CHECK_MALLOC(data = malloc(sizeof(struct eap_md5_data)));
79 memset(data, 0, sizeof(struct eap_md5_data));
80 data->state = EAP_MD5_CONTINUE;
81 data->challenge = NULL;
82 smd->methodData = (struct eap_md5_data*) data;
83 return 0;
84}
85
86
87int eap_md5_buildReq(struct eap_state_machine *smd, u8 id,
88 struct eap_packet * eapPacket)
89{
90 struct eap_md5_data * data;
91 u8 *payload, *challenge;
92
93 data = (struct eap_md5_data *) smd->methodData;
94 CHECK_MALLOC( challenge=malloc(sizeof(u8)*CHALLENGE_LEN));
95 CHECK_MALLOC( payload=malloc(sizeof(u8)*(CHALLENGE_LEN+1)));
96 memset(payload, 0, sizeof(u8) * (CHALLENGE_LEN + 1));
97
98 gcry_create_nonce(challenge,CHALLENGE_LEN);
99 U8COPY(payload, 1, CHALLENGE_LEN, challenge);
100 payload[0] = (u8) CHALLENGE_LEN;
101 CHECK_FCT(diameap_eap_new(EAP_REQUEST, id, TYPE_EAP_MD5, payload, CHALLENGE_LEN
102 + 1,eapPacket));
103 CHECK_MALLOC(data->challenge=realloc(data->challenge,sizeof(u8)*CHALLENGE_LEN));
104 U8COPY(data->challenge,0,CHALLENGE_LEN,challenge);
105
106 smd->methodData = data;
107
108 free(challenge);
109 challenge=NULL;
110 free(payload);
111 payload=NULL;
112
113 return 0;
114}
115
116
117boolean eap_md5_check(struct eap_state_machine *smd, struct eap_packet *eapRespData)
118{
119 eap_type type;
120 if(diameap_eap_get_type(eapRespData,&type)!=0){
121 return FALSE;
122 }
123 if (type == TYPE_EAP_MD5)
124 {
125 u16 length;
126 CHECK_FCT(diameap_eap_get_length(eapRespData,&length));
127 if ((int) length < 6)
128 {
129 TRACE_DEBUG(INFO,"%s[EAP MD5 plugin] Incorrect EAP packet received (length = %d ).",DIAMEAP_EXTENSION,length);
130 return FALSE;
131 }
132 return TRUE;
133 }
134 return FALSE;
135}
136
137
138
139int eap_md5_process(struct eap_state_machine *smd, struct eap_packet *eapRespData)
140{
141
142 struct eap_md5_data * data;
143 int wordlen = 0, i = 0;
144 u8 * word, *hash, id;
145 data = (struct eap_md5_data*) smd->methodData;
146 wordlen = 1 + smd->user.passwordLength + CHALLENGE_LEN;
147 CHECK_MALLOC(word = malloc(sizeof(u8)*wordlen));
148 memset(word, 0, sizeof(u8) * wordlen);
149 CHECK_FCT(diameap_eap_get_identifier(eapRespData,&id));
150 *word = id;
151 U8COPY(word,1,smd->user.passwordLength,smd->user.password);
152 U8COPY(word,1+smd->user.passwordLength,CHALLENGE_LEN,data->challenge);
153 CHECK_MALLOC(hash = malloc(sizeof(u8)*16));
154
155 md5hash(word, wordlen, hash);
156
157
158 for (i = 0; i < CHALLENGE_LEN; i++)
159 {
160 if (G8(hash + i) != G8(eapRespData->data + 6 + i))
161 {
162 data->state = EAP_MD5_FAILURE;
163 }
164 }
165
166 if (data->state != EAP_MD5_FAILURE)
167 {
168 data->state = EAP_MD5_SUCCESS;
169 smd->user.success = TRUE;
170 }
171
172 smd->methodData = data;
173 free(hash);
174 hash=NULL;
175 free(word);
176 word=NULL;
177 return 0;
178}
179
180boolean eap_md5_isDone(struct eap_state_machine *smd)
181{
182 struct eap_md5_data *data;
183 data = (struct eap_md5_data*) smd->methodData;
184 if (data->state != EAP_MD5_CONTINUE)
185 {
186 return TRUE;
187 }
188 return FALSE;
189}
190
191
192void eap_md5_free(void * mdata)
193{
194 struct eap_md5_data *data;
195 data = (struct eap_md5_data*) mdata;
196 free(data->challenge);
197 data->challenge=NULL;
198 free(data);
199 data=NULL;
200}