~ubuntu-branches/ubuntu/gutsy/wpasupplicant/gutsy

« back to all changes in this revision

Viewing changes to src/eap_server/eap_md5.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler, Alexander Sack
  • Date: 2007-08-26 16:06:57 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20070826160657-2m8pxoweuxe8f93t
Tags: 0.6.0+0.5.8-0ubuntu1
* New upstream release
* remove patch 11_erroneous_manpage_ref, applied upstream
* remove patch 25_wpas_dbus_unregister_iface_fix, applied upstream

[ Alexander Sack ]
* bumping upstream version to replace development version 0.6.0 with
  this package from stable release branch.
* attempt to fix wierd timeout and high latency issues by going
  back to stable upstream version (0.5.9) (LP: #140763,
  LP: #141233).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * hostapd / EAP-MD5 server
3
 
 * Copyright (c) 2004-2006, 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 "md5.h"
20
 
#include "crypto.h"
21
 
 
22
 
 
23
 
#define CHALLENGE_LEN 16
24
 
 
25
 
struct eap_md5_data {
26
 
        u8 challenge[CHALLENGE_LEN];
27
 
        enum { CONTINUE, SUCCESS, FAILURE } state;
28
 
};
29
 
 
30
 
 
31
 
static void * eap_md5_init(struct eap_sm *sm)
32
 
{
33
 
        struct eap_md5_data *data;
34
 
 
35
 
        data = os_zalloc(sizeof(*data));
36
 
        if (data == NULL)
37
 
                return NULL;
38
 
        data->state = CONTINUE;
39
 
 
40
 
        return data;
41
 
}
42
 
 
43
 
 
44
 
static void eap_md5_reset(struct eap_sm *sm, void *priv)
45
 
{
46
 
        struct eap_md5_data *data = priv;
47
 
        free(data);
48
 
}
49
 
 
50
 
 
51
 
static u8 * eap_md5_buildReq(struct eap_sm *sm, void *priv, int id,
52
 
                             size_t *reqDataLen)
53
 
{
54
 
        struct eap_md5_data *data = priv;
55
 
        struct eap_hdr *req;
56
 
        u8 *pos;
57
 
 
58
 
        if (hostapd_get_rand(data->challenge, CHALLENGE_LEN)) {
59
 
                wpa_printf(MSG_ERROR, "EAP-MD5: Failed to get random data");
60
 
                data->state = FAILURE;
61
 
                return NULL;
62
 
        }
63
 
 
64
 
        req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, reqDataLen,
65
 
                            1 + CHALLENGE_LEN, EAP_CODE_REQUEST, id, &pos);
66
 
        if (req == NULL) {
67
 
                wpa_printf(MSG_ERROR, "EAP-MD5: Failed to allocate memory for "
68
 
                           "request");
69
 
                data->state = FAILURE;
70
 
                return NULL;
71
 
        }
72
 
 
73
 
        *pos++ = CHALLENGE_LEN;
74
 
        memcpy(pos, data->challenge, CHALLENGE_LEN);
75
 
        wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge", pos, CHALLENGE_LEN);
76
 
 
77
 
        data->state = CONTINUE;
78
 
 
79
 
        return (u8 *) req;
80
 
}
81
 
 
82
 
 
83
 
static Boolean eap_md5_check(struct eap_sm *sm, void *priv,
84
 
                             u8 *respData, size_t respDataLen)
85
 
{
86
 
        const u8 *pos;
87
 
        size_t len;
88
 
 
89
 
        pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5,
90
 
                               respData, respDataLen, &len);
91
 
        if (pos == NULL || len < 1) {
92
 
                wpa_printf(MSG_INFO, "EAP-MD5: Invalid frame");
93
 
                return TRUE;
94
 
        }
95
 
        if (*pos != MD5_MAC_LEN || 1 + MD5_MAC_LEN > len) {
96
 
                wpa_printf(MSG_INFO, "EAP-MD5: Invalid response "
97
 
                           "(response_len=%d payload_len=%lu",
98
 
                           *pos, (unsigned long) len);
99
 
                return TRUE;
100
 
        }
101
 
 
102
 
        return FALSE;
103
 
}
104
 
 
105
 
 
106
 
static void eap_md5_process(struct eap_sm *sm, void *priv,
107
 
                            u8 *respData, size_t respDataLen)
108
 
{
109
 
        struct eap_md5_data *data = priv;
110
 
        struct eap_hdr *resp;
111
 
        const u8 *pos;
112
 
        const u8 *addr[3];
113
 
        size_t len[3], plen;
114
 
        u8 hash[MD5_MAC_LEN];
115
 
 
116
 
        if (sm->user == NULL || sm->user->password == NULL ||
117
 
            sm->user->password_hash) {
118
 
                wpa_printf(MSG_INFO, "EAP-MD5: Plaintext password not "
119
 
                           "configured");
120
 
                data->state = FAILURE;
121
 
                return;
122
 
        }
123
 
 
124
 
        pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5,
125
 
                               respData, respDataLen, &plen);
126
 
        if (pos == NULL || *pos != MD5_MAC_LEN || plen < 1 + MD5_MAC_LEN)
127
 
                return; /* Should not happen - frame already validated */
128
 
 
129
 
        pos++; /* Skip response len */
130
 
        wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", pos, MD5_MAC_LEN);
131
 
 
132
 
        resp = (struct eap_hdr *) respData;
133
 
        addr[0] = &resp->identifier;
134
 
        len[0] = 1;
135
 
        addr[1] = sm->user->password;
136
 
        len[1] = sm->user->password_len;
137
 
        addr[2] = data->challenge;
138
 
        len[2] = CHALLENGE_LEN;
139
 
        md5_vector(3, addr, len, hash);
140
 
 
141
 
        if (memcmp(hash, pos, MD5_MAC_LEN) == 0) {
142
 
                wpa_printf(MSG_DEBUG, "EAP-MD5: Done - Success");
143
 
                data->state = SUCCESS;
144
 
        } else {
145
 
                wpa_printf(MSG_DEBUG, "EAP-MD5: Done - Failure");
146
 
                data->state = FAILURE;
147
 
        }
148
 
}
149
 
 
150
 
 
151
 
static Boolean eap_md5_isDone(struct eap_sm *sm, void *priv)
152
 
{
153
 
        struct eap_md5_data *data = priv;
154
 
        return data->state != CONTINUE;
155
 
}
156
 
 
157
 
 
158
 
static Boolean eap_md5_isSuccess(struct eap_sm *sm, void *priv)
159
 
{
160
 
        struct eap_md5_data *data = priv;
161
 
        return data->state == SUCCESS;
162
 
}
163
 
 
164
 
 
165
 
int eap_server_md5_register(void)
166
 
{
167
 
        struct eap_method *eap;
168
 
        int ret;
169
 
 
170
 
        eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
171
 
                                      EAP_VENDOR_IETF, EAP_TYPE_MD5, "MD5");
172
 
        if (eap == NULL)
173
 
                return -1;
174
 
 
175
 
        eap->init = eap_md5_init;
176
 
        eap->reset = eap_md5_reset;
177
 
        eap->buildReq = eap_md5_buildReq;
178
 
        eap->check = eap_md5_check;
179
 
        eap->process = eap_md5_process;
180
 
        eap->isDone = eap_md5_isDone;
181
 
        eap->isSuccess = eap_md5_isSuccess;
182
 
 
183
 
        ret = eap_server_method_register(eap);
184
 
        if (ret)
185
 
                eap_server_method_free(eap);
186
 
        return ret;
187
 
}