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

« back to all changes in this revision

Viewing changes to src/eap_peer/eap_tnc.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2007-08-26 16:06:57 UTC
  • mto: This revision was merged to the branch mainline in revision 26.
  • Revision ID: james.westby@ubuntu.com-20070826160657-mxk5ivjjh65ptxlr
Tags: upstream-0.6.0+0.5.8
ImportĀ upstreamĀ versionĀ 0.6.0+0.5.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * EAP peer method: EAP-TNC (Trusted Network Connect)
3
 
 * Copyright (c) 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 "base64.h"
19
 
#include "eap_i.h"
20
 
#include "tncc.h"
21
 
 
22
 
 
23
 
struct eap_tnc_data {
24
 
        EapMethodState state;
25
 
        struct tncc_data *tncc;
26
 
};
27
 
 
28
 
 
29
 
/* EAP-TNC Flags */
30
 
#define EAP_TNC_FLAGS_LENGTH_INCLUDED 0x80
31
 
#define EAP_TNC_FLAGS_MORE_FRAGMENTS 0x40
32
 
#define EAP_TNC_FLAGS_START 0x20
33
 
#define EAP_TNC_VERSION_MASK 0x07
34
 
 
35
 
#define EAP_TNC_VERSION 1
36
 
 
37
 
 
38
 
static void * eap_tnc_init(struct eap_sm *sm)
39
 
{
40
 
        struct eap_tnc_data *data;
41
 
 
42
 
        data = os_zalloc(sizeof(*data));
43
 
        if (data == NULL)
44
 
                return NULL;
45
 
        data->state = METHOD_INIT;
46
 
        data->tncc = tncc_init();
47
 
        if (data->tncc == NULL) {
48
 
                os_free(data);
49
 
                return NULL;
50
 
        }
51
 
 
52
 
        return data;
53
 
}
54
 
 
55
 
 
56
 
static void eap_tnc_deinit(struct eap_sm *sm, void *priv)
57
 
{
58
 
        struct eap_tnc_data *data = priv;
59
 
 
60
 
        tncc_deinit(data->tncc);
61
 
        os_free(data);
62
 
}
63
 
 
64
 
 
65
 
static u8 * eap_tnc_process(struct eap_sm *sm, void *priv,
66
 
                            struct eap_method_ret *ret,
67
 
                            const u8 *reqData, size_t reqDataLen,
68
 
                            size_t *respDataLen)
69
 
{
70
 
        struct eap_tnc_data *data = priv;
71
 
        const struct eap_hdr *req;
72
 
        struct eap_hdr *resp;
73
 
        const u8 *pos;
74
 
        u8 *rpos, *start;
75
 
        size_t len, rlen;
76
 
        size_t imc_len;
77
 
        char *start_buf, *end_buf;
78
 
        size_t start_len, end_len;
79
 
 
80
 
        pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TNC,
81
 
                               reqData, reqDataLen, &len);
82
 
        if (pos == NULL || len == 0) {
83
 
                wpa_printf(MSG_INFO, "EAP-TNC: Invalid frame (pos=%p len=%lu)",
84
 
                           pos, (unsigned long) len);
85
 
                ret->ignore = TRUE;
86
 
                return NULL;
87
 
        }
88
 
 
89
 
        req = (const struct eap_hdr *) reqData;
90
 
        wpa_hexdump(MSG_MSGDUMP, "EAP-TNC: Received payload", pos, len);
91
 
        wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TNC: Received payload", pos, len);
92
 
 
93
 
        if ((*pos & EAP_TNC_VERSION_MASK) != EAP_TNC_VERSION) {
94
 
                wpa_printf(MSG_DEBUG, "EAP-TNC: Unsupported version %d",
95
 
                           *pos & EAP_TNC_VERSION_MASK);
96
 
                ret->ignore = TRUE;
97
 
                return NULL;
98
 
        }
99
 
 
100
 
        if (data->state == METHOD_INIT) {
101
 
                if (!(*pos & EAP_TNC_FLAGS_START)) {
102
 
                        wpa_printf(MSG_DEBUG, "EAP-TNC: Server did not use "
103
 
                                   "start flag in the first message");
104
 
                        ret->ignore = TRUE;
105
 
                        return NULL;
106
 
                }
107
 
 
108
 
                tncc_init_connection(data->tncc);
109
 
 
110
 
                data->state = METHOD_MAY_CONT;
111
 
        } else {
112
 
                if (*pos & EAP_TNC_FLAGS_START) {
113
 
                        wpa_printf(MSG_DEBUG, "EAP-TNC: Server used start "
114
 
                                   "flag again");
115
 
                        ret->ignore = TRUE;
116
 
                        return NULL;
117
 
                }
118
 
 
119
 
                if (tncc_process_if_tnccs(data->tncc, pos + 1, len - 1)) {
120
 
                        ret->ignore = TRUE;
121
 
                        return NULL;
122
 
                }
123
 
        }
124
 
 
125
 
        ret->ignore = FALSE;
126
 
        ret->methodState = data->state;
127
 
        ret->decision = DECISION_UNCOND_SUCC;
128
 
        ret->allowNotifications = TRUE;
129
 
 
130
 
        imc_len = tncc_total_send_len(data->tncc);
131
 
 
132
 
        start_buf = tncc_if_tnccs_start(data->tncc);
133
 
        if (start_buf == NULL)
134
 
                return NULL;
135
 
        start_len = os_strlen(start_buf);
136
 
        end_buf = tncc_if_tnccs_end();
137
 
        if (end_buf == NULL) {
138
 
                os_free(start_buf);
139
 
                return NULL;
140
 
        }
141
 
        end_len = os_strlen(end_buf);
142
 
 
143
 
        rlen = 1 + start_len + imc_len + end_len;
144
 
        resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, respDataLen,
145
 
                             rlen, EAP_CODE_RESPONSE,
146
 
                             req->identifier, &rpos);
147
 
        if (resp == NULL) {
148
 
                os_free(start_buf);
149
 
                os_free(end_buf);
150
 
                return NULL;
151
 
        }
152
 
 
153
 
        start = rpos;
154
 
        *rpos++ = EAP_TNC_VERSION;
155
 
        os_memcpy(rpos, start_buf, start_len);
156
 
        os_free(start_buf);
157
 
        rpos += start_len;
158
 
 
159
 
        rpos = tncc_copy_send_buf(data->tncc, rpos);
160
 
 
161
 
        os_memcpy(rpos, end_buf, end_len);
162
 
        os_free(end_buf);
163
 
 
164
 
        wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TNC: Response", start, rlen);
165
 
 
166
 
        return (u8 *) resp;
167
 
}
168
 
 
169
 
 
170
 
int eap_peer_tnc_register(void)
171
 
{
172
 
        struct eap_method *eap;
173
 
        int ret;
174
 
 
175
 
        eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
176
 
                                    EAP_VENDOR_IETF, EAP_TYPE_TNC, "TNC");
177
 
        if (eap == NULL)
178
 
                return -1;
179
 
 
180
 
        eap->init = eap_tnc_init;
181
 
        eap->deinit = eap_tnc_deinit;
182
 
        eap->process = eap_tnc_process;
183
 
 
184
 
        ret = eap_peer_method_register(eap);
185
 
        if (ret)
186
 
                eap_peer_method_free(eap);
187
 
        return ret;
188
 
}