~ubuntu-branches/ubuntu/saucy/wpasupplicant/saucy

« back to all changes in this revision

Viewing changes to src/eap_server/eap_server_md5.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2010-11-22 09:43:43 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122094343-qgsxaojvmswfri77
Tags: 0.7.3-0ubuntu1
* Get wpasupplicant 0.7.3 from Debian's SVN. Leaving 0.7.3-1 as unreleased
  for now.
* Build-Depend on debhelper 8, since the packaging from Debian uses compat 8.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * hostapd / EAP-MD5 server
 
3
 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include "includes.h"
 
16
 
 
17
#include "common.h"
 
18
#include "eap_i.h"
 
19
#include "eap_common/chap.h"
 
20
 
 
21
 
 
22
#define CHALLENGE_LEN 16
 
23
 
 
24
struct eap_md5_data {
 
25
        u8 challenge[CHALLENGE_LEN];
 
26
        enum { CONTINUE, SUCCESS, FAILURE } state;
 
27
};
 
28
 
 
29
 
 
30
static void * eap_md5_init(struct eap_sm *sm)
 
31
{
 
32
        struct eap_md5_data *data;
 
33
 
 
34
        data = os_zalloc(sizeof(*data));
 
35
        if (data == NULL)
 
36
                return NULL;
 
37
        data->state = CONTINUE;
 
38
 
 
39
        return data;
 
40
}
 
41
 
 
42
 
 
43
static void eap_md5_reset(struct eap_sm *sm, void *priv)
 
44
{
 
45
        struct eap_md5_data *data = priv;
 
46
        os_free(data);
 
47
}
 
48
 
 
49
 
 
50
static struct wpabuf * eap_md5_buildReq(struct eap_sm *sm, void *priv, u8 id)
 
51
{
 
52
        struct eap_md5_data *data = priv;
 
53
        struct wpabuf *req;
 
54
 
 
55
        if (os_get_random(data->challenge, CHALLENGE_LEN)) {
 
56
                wpa_printf(MSG_ERROR, "EAP-MD5: Failed to get random data");
 
57
                data->state = FAILURE;
 
58
                return NULL;
 
59
        }
 
60
 
 
61
        req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, 1 + CHALLENGE_LEN,
 
62
                            EAP_CODE_REQUEST, id);
 
63
        if (req == NULL) {
 
64
                wpa_printf(MSG_ERROR, "EAP-MD5: Failed to allocate memory for "
 
65
                           "request");
 
66
                data->state = FAILURE;
 
67
                return NULL;
 
68
        }
 
69
 
 
70
        wpabuf_put_u8(req, CHALLENGE_LEN);
 
71
        wpabuf_put_data(req, data->challenge, CHALLENGE_LEN);
 
72
        wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge", data->challenge,
 
73
                    CHALLENGE_LEN);
 
74
 
 
75
        data->state = CONTINUE;
 
76
 
 
77
        return req;
 
78
}
 
79
 
 
80
 
 
81
static Boolean eap_md5_check(struct eap_sm *sm, void *priv,
 
82
                             struct wpabuf *respData)
 
83
{
 
84
        const u8 *pos;
 
85
        size_t len;
 
86
 
 
87
        pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5, respData, &len);
 
88
        if (pos == NULL || len < 1) {
 
89
                wpa_printf(MSG_INFO, "EAP-MD5: Invalid frame");
 
90
                return TRUE;
 
91
        }
 
92
        if (*pos != CHAP_MD5_LEN || 1 + CHAP_MD5_LEN > len) {
 
93
                wpa_printf(MSG_INFO, "EAP-MD5: Invalid response "
 
94
                           "(response_len=%d payload_len=%lu",
 
95
                           *pos, (unsigned long) len);
 
96
                return TRUE;
 
97
        }
 
98
 
 
99
        return FALSE;
 
100
}
 
101
 
 
102
 
 
103
static void eap_md5_process(struct eap_sm *sm, void *priv,
 
104
                            struct wpabuf *respData)
 
105
{
 
106
        struct eap_md5_data *data = priv;
 
107
        const u8 *pos;
 
108
        size_t plen;
 
109
        u8 hash[CHAP_MD5_LEN], id;
 
110
 
 
111
        if (sm->user == NULL || sm->user->password == NULL ||
 
112
            sm->user->password_hash) {
 
113
                wpa_printf(MSG_INFO, "EAP-MD5: Plaintext password not "
 
114
                           "configured");
 
115
                data->state = FAILURE;
 
116
                return;
 
117
        }
 
118
 
 
119
        pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5, respData, &plen);
 
120
        if (pos == NULL || *pos != CHAP_MD5_LEN || plen < 1 + CHAP_MD5_LEN)
 
121
                return; /* Should not happen - frame already validated */
 
122
 
 
123
        pos++; /* Skip response len */
 
124
        wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", pos, CHAP_MD5_LEN);
 
125
 
 
126
        id = eap_get_id(respData);
 
127
        chap_md5(id, sm->user->password, sm->user->password_len,
 
128
                 data->challenge, CHALLENGE_LEN, hash);
 
129
 
 
130
        if (os_memcmp(hash, pos, CHAP_MD5_LEN) == 0) {
 
131
                wpa_printf(MSG_DEBUG, "EAP-MD5: Done - Success");
 
132
                data->state = SUCCESS;
 
133
        } else {
 
134
                wpa_printf(MSG_DEBUG, "EAP-MD5: Done - Failure");
 
135
                data->state = FAILURE;
 
136
        }
 
137
}
 
138
 
 
139
 
 
140
static Boolean eap_md5_isDone(struct eap_sm *sm, void *priv)
 
141
{
 
142
        struct eap_md5_data *data = priv;
 
143
        return data->state != CONTINUE;
 
144
}
 
145
 
 
146
 
 
147
static Boolean eap_md5_isSuccess(struct eap_sm *sm, void *priv)
 
148
{
 
149
        struct eap_md5_data *data = priv;
 
150
        return data->state == SUCCESS;
 
151
}
 
152
 
 
153
 
 
154
int eap_server_md5_register(void)
 
155
{
 
156
        struct eap_method *eap;
 
157
        int ret;
 
158
 
 
159
        eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
 
160
                                      EAP_VENDOR_IETF, EAP_TYPE_MD5, "MD5");
 
161
        if (eap == NULL)
 
162
                return -1;
 
163
 
 
164
        eap->init = eap_md5_init;
 
165
        eap->reset = eap_md5_reset;
 
166
        eap->buildReq = eap_md5_buildReq;
 
167
        eap->check = eap_md5_check;
 
168
        eap->process = eap_md5_process;
 
169
        eap->isDone = eap_md5_isDone;
 
170
        eap->isSuccess = eap_md5_isSuccess;
 
171
 
 
172
        ret = eap_server_method_register(eap);
 
173
        if (ret)
 
174
                eap_server_method_free(eap);
 
175
        return ret;
 
176
}