~ubuntu-branches/ubuntu/oneiric/wpasupplicant/oneiric

« back to all changes in this revision

Viewing changes to eap_gtc.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2006-10-05 08:04:01 UTC
  • mfrom: (1.2.1 upstream) (2.1.14 edgy)
  • Revision ID: james.westby@ubuntu.com-20061005080401-myfwjtq7di70dyeo
* Update madwifi headers to latest SVN. (Closes: #388316)
* Remove failed attempt at action locking. [debian/functions.sh,
  debian/wpa_action.sh]
* Add hysteresis checking functions, to avoid "event loops" while
  using wpa-roam. [debian/functions.sh, debian/wpa_action.sh]
* Change of co-maintainer email address.
* Add ishex() function to functions.sh to determine wpa-psk value type in
  plaintext or hex. This effectively eliminates the need for the bogus and
  somewhat confusing wpa-passphrase contruct specific to our scripts and
  allows wpa-psk to work with either a 8 to 63 character long plaintext
  string or 64 character long hex string.
* Adjust README.modes to not refer to the redundant wpa-passphrase stuff.
* Add big fat NOTE about acceptable wpa-psk's to top of example gallery.
* Strip surrounding quotes from wpa-ssid if present, instead of just whining
  about them.
* Update email address in copyright blurb of functions.sh, ifupdown.sh and
  wpa_action.sh.  

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * WPA Supplicant / EAP-GTC (RFC 2284)
3
 
 * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
 
2
 * EAP peer method: EAP-GTC (RFC 3748)
 
3
 * Copyright (c) 2004-2006, Jouni Malinen <jkmaline@cc.hut.fi>
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify
6
6
 * it under the terms of the GNU General Public License version 2 as
12
12
 * See README and COPYING for more details.
13
13
 */
14
14
 
15
 
#include <stdlib.h>
16
 
#include <stdio.h>
17
 
#include <string.h>
 
15
#include "includes.h"
18
16
 
19
17
#include "common.h"
20
18
#include "eap_i.h"
21
19
#include "wpa_supplicant.h"
22
 
#include "config_ssid.h"
23
20
 
24
21
 
25
22
struct eap_gtc_data {
30
27
static void * eap_gtc_init(struct eap_sm *sm)
31
28
{
32
29
        struct eap_gtc_data *data;
33
 
        data = malloc(sizeof(*data));
 
30
        data = wpa_zalloc(sizeof(*data));
34
31
        if (data == NULL)
35
32
                return NULL;
36
 
        memset(data, 0, sizeof(*data));
37
33
 
38
34
        if (sm->m && sm->m->method == EAP_TYPE_FAST) {
39
35
                wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix "
53
49
 
54
50
static u8 * eap_gtc_process(struct eap_sm *sm, void *priv,
55
51
                            struct eap_method_ret *ret,
56
 
                            u8 *reqData, size_t reqDataLen,
 
52
                            const u8 *reqData, size_t reqDataLen,
57
53
                            size_t *respDataLen)
58
54
{
59
55
        struct eap_gtc_data *data = priv;
60
 
        struct wpa_ssid *config = eap_get_config(sm);
61
 
        struct eap_hdr *req, *resp;
62
 
        u8 *pos, *password;
63
 
        size_t password_len, len, msg_len;
 
56
        const struct eap_hdr *req;
 
57
        struct eap_hdr *resp;
 
58
        const u8 *pos, *password, *identity;
 
59
        u8 *rpos;
 
60
        size_t password_len, identity_len, len, plen;
 
61
        int otp;
64
62
 
65
 
        req = (struct eap_hdr *) reqData;
66
 
        pos = (u8 *) (req + 1);
67
 
        if (reqDataLen < sizeof(*req) + 1 || *pos != EAP_TYPE_GTC ||
68
 
            (len = be_to_host16(req->length)) > reqDataLen) {
69
 
                wpa_printf(MSG_INFO, "EAP-GTC: Invalid frame");
 
63
        pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC,
 
64
                               reqData, reqDataLen, &len);
 
65
        if (pos == NULL) {
70
66
                ret->ignore = TRUE;
71
67
                return NULL;
72
68
        }
73
 
        pos++;
74
 
        msg_len = len - sizeof(*req) - 1;
75
 
        wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Request message",
76
 
                          pos, msg_len);
 
69
        req = (const struct eap_hdr *) reqData;
 
70
 
 
71
        wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Request message", pos, len);
77
72
        if (data->prefix &&
78
 
            (msg_len < 10 || memcmp(pos, "CHALLENGE=", 10) != 0)) {
 
73
            (len < 10 || memcmp(pos, "CHALLENGE=", 10) != 0)) {
79
74
                wpa_printf(MSG_DEBUG, "EAP-GTC: Challenge did not start with "
80
75
                           "expected prefix");
81
76
 
83
78
                 * acknowledgement of the failure. This will also cover the
84
79
                 * error case which seems to use EAP-MSCHAPv2 like error
85
80
                 * reporting with EAP-GTC inside EAP-FAST tunnel. */
86
 
                *respDataLen = sizeof(struct eap_hdr) + 1;
87
 
                resp = malloc(*respDataLen);
88
 
                if (resp == NULL)
89
 
                        return NULL;
90
 
                resp->code = EAP_CODE_RESPONSE;
91
 
                resp->identifier = req->identifier;
92
 
                resp->length = host_to_be16(*respDataLen);
93
 
                pos = (u8 *) (resp + 1);
94
 
                *pos++ = EAP_TYPE_GTC;
 
81
                resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC,
 
82
                                     respDataLen, 0, EAP_CODE_RESPONSE,
 
83
                                     req->identifier, NULL);
95
84
                return (u8 *) resp;
96
85
        }
97
86
 
98
 
        if (config == NULL ||
99
 
            (config->password == NULL && config->otp == NULL)) {
 
87
        password = eap_get_config_otp(sm, &password_len);
 
88
        if (password)
 
89
                otp = 1;
 
90
        else {
 
91
                password = eap_get_config_password(sm, &password_len);
 
92
                otp = 0;
 
93
        }
 
94
 
 
95
        if (password == NULL) {
100
96
                wpa_printf(MSG_INFO, "EAP-GTC: Password not configured");
101
 
                eap_sm_request_otp(sm, config, (char *) pos,
102
 
                                   len - sizeof(*req) - 1);
 
97
                eap_sm_request_otp(sm, (const char *) pos, len);
103
98
                ret->ignore = TRUE;
104
99
                return NULL;
105
100
        }
106
101
 
107
 
        if (config->otp) {
108
 
                password = config->otp;
109
 
                password_len = config->otp_len;
110
 
        } else {
111
 
                password = config->password;
112
 
                password_len = config->password_len;
113
 
        }
114
 
 
115
102
        ret->ignore = FALSE;
116
103
 
117
104
        ret->methodState = data->prefix ? METHOD_MAY_CONT : METHOD_DONE;
118
105
        ret->decision = DECISION_COND_SUCC;
119
106
        ret->allowNotifications = FALSE;
120
107
 
121
 
        *respDataLen = sizeof(struct eap_hdr) + 1 + password_len;
122
 
        if (data->prefix) {
123
 
                *respDataLen += 9 + config->identity_len + 1;
124
 
        }
125
 
        resp = malloc(*respDataLen);
 
108
        plen = password_len;
 
109
        identity = eap_get_config_identity(sm, &identity_len);
 
110
        if (data->prefix)
 
111
                plen += 9 + identity_len + 1;
 
112
        resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, respDataLen,
 
113
                             plen, EAP_CODE_RESPONSE, req->identifier, &rpos);
126
114
        if (resp == NULL)
127
115
                return NULL;
128
 
        resp->code = EAP_CODE_RESPONSE;
129
 
        resp->identifier = req->identifier;
130
 
        resp->length = host_to_be16(*respDataLen);
131
 
        pos = (u8 *) (resp + 1);
132
 
        *pos++ = EAP_TYPE_GTC;
133
116
        if (data->prefix) {
134
 
                memcpy(pos, "RESPONSE=", 9);
135
 
                pos += 9;
136
 
                memcpy(pos, config->identity, config->identity_len);
137
 
                pos += config->identity_len;
138
 
                *pos++ = '\0';
 
117
                memcpy(rpos, "RESPONSE=", 9);
 
118
                rpos += 9;
 
119
                memcpy(rpos, identity, identity_len);
 
120
                rpos += identity_len;
 
121
                *rpos++ = '\0';
139
122
        }
140
 
        memcpy(pos, password, password_len);
 
123
        memcpy(rpos, password, password_len);
141
124
        wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response",
142
 
                              (u8 *) (resp + 1) + 1,
143
 
                              *respDataLen - sizeof(struct eap_hdr) - 1);
 
125
                              (u8 *) (resp + 1) + 1, plen);
144
126
 
145
 
        if (config->otp) {
 
127
        if (otp) {
146
128
                wpa_printf(MSG_DEBUG, "EAP-GTC: Forgetting used password");
147
 
                memset(config->otp, 0, config->otp_len);
148
 
                free(config->otp);
149
 
                config->otp = NULL;
150
 
                config->otp_len = 0;
 
129
                eap_clear_config_otp(sm);
151
130
        }
152
131
 
153
132
        return (u8 *) resp;
154
133
}
155
134
 
156
135
 
157
 
const struct eap_method eap_method_gtc =
 
136
int eap_peer_gtc_register(void)
158
137
{
159
 
        .method = EAP_TYPE_GTC,
160
 
        .name = "GTC",
161
 
        .init = eap_gtc_init,
162
 
        .deinit = eap_gtc_deinit,
163
 
        .process = eap_gtc_process,
164
 
};
 
138
        struct eap_method *eap;
 
139
        int ret;
 
140
 
 
141
        eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
 
142
                                    EAP_VENDOR_IETF, EAP_TYPE_GTC, "GTC");
 
143
        if (eap == NULL)
 
144
                return -1;
 
145
 
 
146
        eap->init = eap_gtc_init;
 
147
        eap->deinit = eap_gtc_deinit;
 
148
        eap->process = eap_gtc_process;
 
149
 
 
150
        ret = eap_peer_method_register(eap);
 
151
        if (ret)
 
152
                eap_peer_method_free(eap);
 
153
        return ret;
 
154
}