~ubuntu-branches/ubuntu/vivid/wpasupplicant/vivid

« back to all changes in this revision

Viewing changes to eap_tlv.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2008-03-12 20:03:04 UTC
  • mfrom: (1.1.10 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20080312200304-4331y9wj46pdd34z
Tags: 0.6.3-1
* New upstream release.
* Drop patches applied upstream:
  - debian/patches/30_wpa_gui_qt4_eventhistoryui_rework.patch
  - debian/patches/31_wpa_gui_qt4_eventhistory_always_scrollbar.patch
  - debian/patches/32_wpa_gui_qt4_eventhistory_scroll_with_events.patch
  - debian/patches/40_dbus_ssid_data.patch
* Tidy up the clean target of debian/rules. Now that the madwifi headers are
  handled differently we no longer need to do any cleanup.
* Fix formatting error in debian/ifupdown/wpa_action.8 to make lintian
  quieter.
* Add patch to fix formatting errors in manpages build from sgml source. Use
  <emphasis> tags to hightlight keywords instead of surrounding them in
  strong quotes.
  - debian/patches/41_manpage_format_fixes.patch
* wpasupplicant binary package no longer suggests pcscd, guessnet, iproute
  or wireless-tools, nor does it recommend dhcp3-client. These are not
  needed.
* Add debian/patches/10_silence_siocsiwauth_icotl_failure.patch to disable
  ioctl failure messages that occur under normal conditions.
* Cherry pick two upstream git commits concerning the dbus interface:
  - debian/patches/11_avoid_dbus_version_namespace.patch
  - debian/patches/12_fix_potential_use_after_free.patch
* Add debian/patches/42_manpage_explain_available_drivers.patch to explain
  that not all of the driver backends are available in the provided
  wpa_supplicant binary, and that the canonical list of supported driver
  backends can be retrieved from the wpa_supplicant -h (help) output.
  (Closes: #466910)
* Add debian/patches/20_wpa_gui_qt4_disable_link_prl.patch to remove
  link_prl CONFIG compile flag added by qmake-qt4 >= 4.3.4-2 to avoid excess
  linking.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * EAP peer method: EAP-TLV (draft-josefsson-pppext-eap-tls-eap-07.txt)
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 "eap_tlv.h"
20
 
 
21
 
 
22
 
/**
23
 
 * eap_tlv_build_nak - Build EAP-TLV NAK message
24
 
 * @id: EAP identifier for the header
25
 
 * @nak_type: TLV type (EAP_TLV_*)
26
 
 * @resp_len: Buffer for returning the response length
27
 
 * Returns: Buffer to the allocated EAP-TLV NAK message or %NULL on failure
28
 
 *
29
 
 * This funtion builds an EAP-TLV NAK message. The caller is responsible for
30
 
 * freeing the returned buffer.
31
 
 */
32
 
u8 * eap_tlv_build_nak(int id, u16 nak_type, size_t *resp_len)
33
 
{
34
 
        struct eap_hdr *hdr;
35
 
        u8 *pos;
36
 
 
37
 
        hdr = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, resp_len,
38
 
                            10, EAP_CODE_RESPONSE, id, &pos);
39
 
        if (hdr == NULL)
40
 
                return NULL;
41
 
 
42
 
        *pos++ = 0x80; /* Mandatory */
43
 
        *pos++ = EAP_TLV_NAK_TLV;
44
 
        /* Length */
45
 
        *pos++ = 0;
46
 
        *pos++ = 6;
47
 
        /* Vendor-Id */
48
 
        *pos++ = 0;
49
 
        *pos++ = 0;
50
 
        *pos++ = 0;
51
 
        *pos++ = 0;
52
 
        /* NAK-Type */
53
 
        WPA_PUT_BE16(pos, nak_type);
54
 
 
55
 
        return (u8 *) hdr;
56
 
}
57
 
 
58
 
 
59
 
/**
60
 
 * eap_tlv_build_result - Build EAP-TLV Result message
61
 
 * @id: EAP identifier for the header
62
 
 * @status: Status (EAP_TLV_RESULT_SUCCESS or EAP_TLV_RESULT_FAILURE)
63
 
 * @resp_len: Buffer for returning the response length
64
 
 * Returns: Buffer to the allocated EAP-TLV Result message or %NULL on failure
65
 
 *
66
 
 * This funtion builds an EAP-TLV Result message. The caller is responsible for
67
 
 * freeing the returned buffer.
68
 
 */
69
 
u8 * eap_tlv_build_result(int id, u16 status, size_t *resp_len)
70
 
{
71
 
        struct eap_hdr *hdr;
72
 
        u8 *pos;
73
 
 
74
 
        hdr = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, resp_len,
75
 
                            6, EAP_CODE_RESPONSE, id, &pos);
76
 
        if (hdr == NULL)
77
 
                return NULL;
78
 
 
79
 
        *pos++ = 0x80; /* Mandatory */
80
 
        *pos++ = EAP_TLV_RESULT_TLV;
81
 
        /* Length */
82
 
        *pos++ = 0;
83
 
        *pos++ = 2;
84
 
        /* Status */
85
 
        WPA_PUT_BE16(pos, status);
86
 
 
87
 
        return (u8 *) hdr;
88
 
}
89
 
 
90
 
 
91
 
/**
92
 
 * eap_tlv_process - Process a received EAP-TLV message and generate a response
93
 
 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
94
 
 * @ret: Return values from EAP request validation and processing
95
 
 * @hdr: EAP-TLV request to be processed. The caller must have validated that
96
 
 * the buffer is large enough to contain full request (hdr->length bytes) and
97
 
 * that the EAP type is EAP_TYPE_TLV.
98
 
 * @resp: Buffer to return a pointer to the allocated response message. This
99
 
 * field should be initialized to %NULL before the call. The value will be
100
 
 * updated if a response message is generated. The caller is responsible for
101
 
 * freeing the allocated message.
102
 
 * @resp_len: Buffer for returning the response length
103
 
 * Returns: 0 on success, -1 on failure
104
 
 */
105
 
int eap_tlv_process(struct eap_sm *sm, struct eap_method_ret *ret,
106
 
                    const struct eap_hdr *hdr, u8 **resp, size_t *resp_len)
107
 
{
108
 
        size_t left, tlv_len;
109
 
        const u8 *pos;
110
 
        const u8 *result_tlv = NULL;
111
 
        size_t result_tlv_len = 0;
112
 
        int tlv_type, mandatory;
113
 
 
114
 
        /* Parse TLVs */
115
 
        left = be_to_host16(hdr->length) - sizeof(struct eap_hdr) - 1;
116
 
        pos = (const u8 *) (hdr + 1);
117
 
        pos++;
118
 
        wpa_hexdump(MSG_DEBUG, "EAP-TLV: Received TLVs", pos, left);
119
 
        while (left >= 4) {
120
 
                mandatory = !!(pos[0] & 0x80);
121
 
                tlv_type = WPA_GET_BE16(pos) & 0x3fff;
122
 
                pos += 2;
123
 
                tlv_len = WPA_GET_BE16(pos);
124
 
                pos += 2;
125
 
                left -= 4;
126
 
                if (tlv_len > left) {
127
 
                        wpa_printf(MSG_DEBUG, "EAP-TLV: TLV underrun "
128
 
                                   "(tlv_len=%lu left=%lu)",
129
 
                                   (unsigned long) tlv_len,
130
 
                                   (unsigned long) left);
131
 
                        return -1;
132
 
                }
133
 
                switch (tlv_type) {
134
 
                case EAP_TLV_RESULT_TLV:
135
 
                        result_tlv = pos;
136
 
                        result_tlv_len = tlv_len;
137
 
                        break;
138
 
                default:
139
 
                        wpa_printf(MSG_DEBUG, "EAP-TLV: Unsupported TLV Type "
140
 
                                   "%d%s", tlv_type,
141
 
                                   mandatory ? " (mandatory)" : "");
142
 
                        if (mandatory) {
143
 
                                /* NAK TLV and ignore all TLVs in this packet.
144
 
                                 */
145
 
                                *resp = eap_tlv_build_nak(hdr->identifier,
146
 
                                                          tlv_type, resp_len);
147
 
                                return *resp == NULL ? -1 : 0;
148
 
                        }
149
 
                        /* Ignore this TLV, but process other TLVs */
150
 
                        break;
151
 
                }
152
 
 
153
 
                pos += tlv_len;
154
 
                left -= tlv_len;
155
 
        }
156
 
        if (left) {
157
 
                wpa_printf(MSG_DEBUG, "EAP-TLV: Last TLV too short in "
158
 
                           "Request (left=%lu)", (unsigned long) left);
159
 
                return -1;
160
 
        }
161
 
 
162
 
        /* Process supported TLVs */
163
 
        if (result_tlv) {
164
 
                int status, resp_status;
165
 
                wpa_hexdump(MSG_DEBUG, "EAP-TLV: Result TLV",
166
 
                            result_tlv, result_tlv_len);
167
 
                if (result_tlv_len < 2) {
168
 
                        wpa_printf(MSG_INFO, "EAP-TLV: Too short Result TLV "
169
 
                                   "(len=%lu)",
170
 
                                   (unsigned long) result_tlv_len);
171
 
                        return -1;
172
 
                }
173
 
                status = WPA_GET_BE16(result_tlv);
174
 
                if (status == EAP_TLV_RESULT_SUCCESS) {
175
 
                        wpa_printf(MSG_INFO, "EAP-TLV: TLV Result - Success "
176
 
                                   "- EAP-TLV/Phase2 Completed");
177
 
                        resp_status = EAP_TLV_RESULT_SUCCESS;
178
 
                        ret->decision = DECISION_UNCOND_SUCC;
179
 
                } else if (status == EAP_TLV_RESULT_FAILURE) {
180
 
                        wpa_printf(MSG_INFO, "EAP-TLV: TLV Result - Failure");
181
 
                        resp_status = EAP_TLV_RESULT_FAILURE;
182
 
                        ret->decision = DECISION_FAIL;
183
 
                } else {
184
 
                        wpa_printf(MSG_INFO, "EAP-TLV: Unknown TLV Result "
185
 
                                   "Status %d", status);
186
 
                        resp_status = EAP_TLV_RESULT_FAILURE;
187
 
                        ret->decision = DECISION_FAIL;
188
 
                }
189
 
                ret->methodState = METHOD_DONE;
190
 
 
191
 
                *resp = eap_tlv_build_result(hdr->identifier, resp_status,
192
 
                                             resp_len);
193
 
        }
194
 
 
195
 
        return 0;
196
 
}