User | Revision | Line number | New contents of line |
mbed714 |
0:d616ece2d859
|
1
|
/*** WARNING - THIS HAS NEVER BEEN FINISHED ***/
|
mbed714 |
0:d616ece2d859
|
2
|
/*****************************************************************************
|
mbed714 |
0:d616ece2d859
|
3
|
* chap.c - Network Challenge Handshake Authentication Protocol program file.
|
mbed714 |
0:d616ece2d859
|
4
|
*
|
mbed714 |
0:d616ece2d859
|
5
|
* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
|
mbed714 |
0:d616ece2d859
|
6
|
* portions Copyright (c) 1997 by Global Election Systems Inc.
|
mbed714 |
0:d616ece2d859
|
7
|
*
|
mbed714 |
0:d616ece2d859
|
8
|
* The authors hereby grant permission to use, copy, modify, distribute,
|
mbed714 |
0:d616ece2d859
|
9
|
* and license this software and its documentation for any purpose, provided
|
mbed714 |
0:d616ece2d859
|
10
|
* that existing copyright notices are retained in all copies and that this
|
mbed714 |
0:d616ece2d859
|
11
|
* notice and the following disclaimer are included verbatim in any
|
mbed714 |
0:d616ece2d859
|
12
|
* distributions. No written agreement, license, or royalty fee is required
|
mbed714 |
0:d616ece2d859
|
13
|
* for any of the authorized uses.
|
mbed714 |
0:d616ece2d859
|
14
|
*
|
mbed714 |
0:d616ece2d859
|
15
|
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
|
mbed714 |
0:d616ece2d859
|
16
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
mbed714 |
0:d616ece2d859
|
17
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
mbed714 |
0:d616ece2d859
|
18
|
* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
mbed714 |
0:d616ece2d859
|
19
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
mbed714 |
0:d616ece2d859
|
20
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
mbed714 |
0:d616ece2d859
|
21
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
mbed714 |
0:d616ece2d859
|
22
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
mbed714 |
0:d616ece2d859
|
23
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
mbed714 |
0:d616ece2d859
|
24
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
mbed714 |
0:d616ece2d859
|
25
|
*
|
mbed714 |
0:d616ece2d859
|
26
|
******************************************************************************
|
mbed714 |
0:d616ece2d859
|
27
|
* REVISION HISTORY
|
mbed714 |
0:d616ece2d859
|
28
|
*
|
mbed714 |
0:d616ece2d859
|
29
|
* 03-01-01 Marc Boucher <marc@mbsi.ca>
|
mbed714 |
0:d616ece2d859
|
30
|
* Ported to lwIP.
|
mbed714 |
0:d616ece2d859
|
31
|
* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
|
mbed714 |
0:d616ece2d859
|
32
|
* Original based on BSD chap.c.
|
mbed714 |
0:d616ece2d859
|
33
|
*****************************************************************************/
|
mbed714 |
0:d616ece2d859
|
34
|
/*
|
mbed714 |
0:d616ece2d859
|
35
|
* chap.c - Challenge Handshake Authentication Protocol.
|
mbed714 |
0:d616ece2d859
|
36
|
*
|
mbed714 |
0:d616ece2d859
|
37
|
* Copyright (c) 1993 The Australian National University.
|
mbed714 |
0:d616ece2d859
|
38
|
* All rights reserved.
|
mbed714 |
0:d616ece2d859
|
39
|
*
|
mbed714 |
0:d616ece2d859
|
40
|
* Redistribution and use in source and binary forms are permitted
|
mbed714 |
0:d616ece2d859
|
41
|
* provided that the above copyright notice and this paragraph are
|
mbed714 |
0:d616ece2d859
|
42
|
* duplicated in all such forms and that any documentation,
|
mbed714 |
0:d616ece2d859
|
43
|
* advertising materials, and other materials related to such
|
mbed714 |
0:d616ece2d859
|
44
|
* distribution and use acknowledge that the software was developed
|
mbed714 |
0:d616ece2d859
|
45
|
* by the Australian National University. The name of the University
|
mbed714 |
0:d616ece2d859
|
46
|
* may not be used to endorse or promote products derived from this
|
mbed714 |
0:d616ece2d859
|
47
|
* software without specific prior written permission.
|
mbed714 |
0:d616ece2d859
|
48
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
mbed714 |
0:d616ece2d859
|
49
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
mbed714 |
0:d616ece2d859
|
50
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
mbed714 |
0:d616ece2d859
|
51
|
*
|
mbed714 |
0:d616ece2d859
|
52
|
* Copyright (c) 1991 Gregory M. Christy.
|
mbed714 |
0:d616ece2d859
|
53
|
* All rights reserved.
|
mbed714 |
0:d616ece2d859
|
54
|
*
|
mbed714 |
0:d616ece2d859
|
55
|
* Redistribution and use in source and binary forms are permitted
|
mbed714 |
0:d616ece2d859
|
56
|
* provided that the above copyright notice and this paragraph are
|
mbed714 |
0:d616ece2d859
|
57
|
* duplicated in all such forms and that any documentation,
|
mbed714 |
0:d616ece2d859
|
58
|
* advertising materials, and other materials related to such
|
mbed714 |
0:d616ece2d859
|
59
|
* distribution and use acknowledge that the software was developed
|
mbed714 |
0:d616ece2d859
|
60
|
* by Gregory M. Christy. The name of the author may not be used to
|
mbed714 |
0:d616ece2d859
|
61
|
* endorse or promote products derived from this software without
|
mbed714 |
0:d616ece2d859
|
62
|
* specific prior written permission.
|
mbed714 |
0:d616ece2d859
|
63
|
*
|
mbed714 |
0:d616ece2d859
|
64
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
mbed714 |
0:d616ece2d859
|
65
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
mbed714 |
0:d616ece2d859
|
66
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
mbed714 |
0:d616ece2d859
|
67
|
*/
|
mbed714 |
0:d616ece2d859
|
68
|
|
mbed714 |
0:d616ece2d859
|
69
|
#include "lwip/opt.h"
|
mbed714 |
0:d616ece2d859
|
70
|
|
mbed714 |
0:d616ece2d859
|
71
|
#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
|
mbed714 |
0:d616ece2d859
|
72
|
|
mbed714 |
0:d616ece2d859
|
73
|
#if CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
|
mbed714 |
0:d616ece2d859
|
74
|
|
mbed714 |
0:d616ece2d859
|
75
|
#include "ppp.h"
|
mbed714 |
0:d616ece2d859
|
76
|
#include "pppdebug.h"
|
mbed714 |
0:d616ece2d859
|
77
|
|
mbed714 |
0:d616ece2d859
|
78
|
#include "magic.h"
|
mbed714 |
0:d616ece2d859
|
79
|
#include "randm.h"
|
mbed714 |
0:d616ece2d859
|
80
|
#include "auth.h"
|
mbed714 |
0:d616ece2d859
|
81
|
#include "md5.h"
|
mbed714 |
0:d616ece2d859
|
82
|
#include "chap.h"
|
mbed714 |
0:d616ece2d859
|
83
|
#include "chpms.h"
|
mbed714 |
0:d616ece2d859
|
84
|
|
mbed714 |
0:d616ece2d859
|
85
|
#include <string.h>
|
mbed714 |
0:d616ece2d859
|
86
|
|
mbed714 |
0:d616ece2d859
|
87
|
#if 0 /* UNUSED */
|
mbed714 |
0:d616ece2d859
|
88
|
/*
|
mbed714 |
0:d616ece2d859
|
89
|
* Command-line options.
|
mbed714 |
0:d616ece2d859
|
90
|
*/
|
mbed714 |
0:d616ece2d859
|
91
|
static option_t chap_option_list[] = {
|
mbed714 |
0:d616ece2d859
|
92
|
{ "chap-restart", o_int, &chap[0].timeouttime,
|
mbed714 |
0:d616ece2d859
|
93
|
"Set timeout for CHAP" },
|
mbed714 |
0:d616ece2d859
|
94
|
{ "chap-max-challenge", o_int, &chap[0].max_transmits,
|
mbed714 |
0:d616ece2d859
|
95
|
"Set max #xmits for challenge" },
|
mbed714 |
0:d616ece2d859
|
96
|
{ "chap-interval", o_int, &chap[0].chal_interval,
|
mbed714 |
0:d616ece2d859
|
97
|
"Set interval for rechallenge" },
|
mbed714 |
0:d616ece2d859
|
98
|
#ifdef MSLANMAN
|
mbed714 |
0:d616ece2d859
|
99
|
{ "ms-lanman", o_bool, &ms_lanman,
|
mbed714 |
0:d616ece2d859
|
100
|
"Use LanMan passwd when using MS-CHAP", 1 },
|
mbed714 |
0:d616ece2d859
|
101
|
#endif
|
mbed714 |
0:d616ece2d859
|
102
|
{ NULL }
|
mbed714 |
0:d616ece2d859
|
103
|
};
|
mbed714 |
0:d616ece2d859
|
104
|
#endif /* UNUSED */
|
mbed714 |
0:d616ece2d859
|
105
|
|
mbed714 |
0:d616ece2d859
|
106
|
/*
|
mbed714 |
0:d616ece2d859
|
107
|
* Protocol entry points.
|
mbed714 |
0:d616ece2d859
|
108
|
*/
|
mbed714 |
0:d616ece2d859
|
109
|
static void ChapInit (int);
|
mbed714 |
0:d616ece2d859
|
110
|
static void ChapLowerUp (int);
|
mbed714 |
0:d616ece2d859
|
111
|
static void ChapLowerDown (int);
|
mbed714 |
0:d616ece2d859
|
112
|
static void ChapInput (int, u_char *, int);
|
mbed714 |
0:d616ece2d859
|
113
|
static void ChapProtocolReject (int);
|
mbed714 |
0:d616ece2d859
|
114
|
#if PPP_ADDITIONAL_CALLBACKS
|
mbed714 |
0:d616ece2d859
|
115
|
static int ChapPrintPkt (u_char *, int, void (*) (void *, char *, ...), void *);
|
mbed714 |
0:d616ece2d859
|
116
|
#endif
|
mbed714 |
0:d616ece2d859
|
117
|
|
mbed714 |
0:d616ece2d859
|
118
|
struct protent chap_protent = {
|
mbed714 |
0:d616ece2d859
|
119
|
PPP_CHAP,
|
mbed714 |
0:d616ece2d859
|
120
|
ChapInit,
|
mbed714 |
0:d616ece2d859
|
121
|
ChapInput,
|
mbed714 |
0:d616ece2d859
|
122
|
ChapProtocolReject,
|
mbed714 |
0:d616ece2d859
|
123
|
ChapLowerUp,
|
mbed714 |
0:d616ece2d859
|
124
|
ChapLowerDown,
|
mbed714 |
0:d616ece2d859
|
125
|
NULL,
|
mbed714 |
0:d616ece2d859
|
126
|
NULL,
|
mbed714 |
0:d616ece2d859
|
127
|
#if PPP_ADDITIONAL_CALLBACKS
|
mbed714 |
0:d616ece2d859
|
128
|
ChapPrintPkt,
|
mbed714 |
0:d616ece2d859
|
129
|
NULL,
|
mbed714 |
0:d616ece2d859
|
130
|
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
mbed714 |
0:d616ece2d859
|
131
|
1,
|
mbed714 |
0:d616ece2d859
|
132
|
"CHAP",
|
mbed714 |
0:d616ece2d859
|
133
|
#if PPP_ADDITIONAL_CALLBACKS
|
mbed714 |
0:d616ece2d859
|
134
|
NULL,
|
mbed714 |
0:d616ece2d859
|
135
|
NULL,
|
mbed714 |
0:d616ece2d859
|
136
|
NULL
|
mbed714 |
0:d616ece2d859
|
137
|
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
mbed714 |
0:d616ece2d859
|
138
|
};
|
mbed714 |
0:d616ece2d859
|
139
|
|
mbed714 |
0:d616ece2d859
|
140
|
chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
|
mbed714 |
0:d616ece2d859
|
141
|
|
mbed714 |
0:d616ece2d859
|
142
|
static void ChapChallengeTimeout (void *);
|
mbed714 |
0:d616ece2d859
|
143
|
static void ChapResponseTimeout (void *);
|
mbed714 |
0:d616ece2d859
|
144
|
static void ChapReceiveChallenge (chap_state *, u_char *, u_char, int);
|
mbed714 |
0:d616ece2d859
|
145
|
static void ChapRechallenge (void *);
|
mbed714 |
0:d616ece2d859
|
146
|
static void ChapReceiveResponse (chap_state *, u_char *, int, int);
|
mbed714 |
0:d616ece2d859
|
147
|
static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len);
|
mbed714 |
0:d616ece2d859
|
148
|
static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len);
|
mbed714 |
0:d616ece2d859
|
149
|
static void ChapSendStatus (chap_state *, int);
|
mbed714 |
0:d616ece2d859
|
150
|
static void ChapSendChallenge (chap_state *);
|
mbed714 |
0:d616ece2d859
|
151
|
static void ChapSendResponse (chap_state *);
|
mbed714 |
0:d616ece2d859
|
152
|
static void ChapGenChallenge (chap_state *);
|
mbed714 |
0:d616ece2d859
|
153
|
|
mbed714 |
0:d616ece2d859
|
154
|
/*
|
mbed714 |
0:d616ece2d859
|
155
|
* ChapInit - Initialize a CHAP unit.
|
mbed714 |
0:d616ece2d859
|
156
|
*/
|
mbed714 |
0:d616ece2d859
|
157
|
static void
|
mbed714 |
0:d616ece2d859
|
158
|
ChapInit(int unit)
|
mbed714 |
0:d616ece2d859
|
159
|
{
|
mbed714 |
0:d616ece2d859
|
160
|
chap_state *cstate = &chap[unit];
|
mbed714 |
0:d616ece2d859
|
161
|
|
mbed714 |
0:d616ece2d859
|
162
|
BZERO(cstate, sizeof(*cstate));
|
mbed714 |
0:d616ece2d859
|
163
|
cstate->unit = unit;
|
mbed714 |
0:d616ece2d859
|
164
|
cstate->clientstate = CHAPCS_INITIAL;
|
mbed714 |
0:d616ece2d859
|
165
|
cstate->serverstate = CHAPSS_INITIAL;
|
mbed714 |
0:d616ece2d859
|
166
|
cstate->timeouttime = CHAP_DEFTIMEOUT;
|
mbed714 |
0:d616ece2d859
|
167
|
cstate->max_transmits = CHAP_DEFTRANSMITS;
|
mbed714 |
0:d616ece2d859
|
168
|
/* random number generator is initialized in magic_init */
|
mbed714 |
0:d616ece2d859
|
169
|
}
|
mbed714 |
0:d616ece2d859
|
170
|
|
mbed714 |
0:d616ece2d859
|
171
|
|
mbed714 |
0:d616ece2d859
|
172
|
/*
|
mbed714 |
0:d616ece2d859
|
173
|
* ChapAuthWithPeer - Authenticate us with our peer (start client).
|
mbed714 |
0:d616ece2d859
|
174
|
*
|
mbed714 |
0:d616ece2d859
|
175
|
*/
|
mbed714 |
0:d616ece2d859
|
176
|
void
|
mbed714 |
0:d616ece2d859
|
177
|
ChapAuthWithPeer(int unit, char *our_name, u_char digest)
|
mbed714 |
0:d616ece2d859
|
178
|
{
|
mbed714 |
0:d616ece2d859
|
179
|
chap_state *cstate = &chap[unit];
|
mbed714 |
0:d616ece2d859
|
180
|
|
mbed714 |
0:d616ece2d859
|
181
|
cstate->resp_name = our_name;
|
mbed714 |
0:d616ece2d859
|
182
|
cstate->resp_type = digest;
|
mbed714 |
0:d616ece2d859
|
183
|
|
mbed714 |
0:d616ece2d859
|
184
|
if (cstate->clientstate == CHAPCS_INITIAL ||
|
mbed714 |
0:d616ece2d859
|
185
|
cstate->clientstate == CHAPCS_PENDING) {
|
mbed714 |
0:d616ece2d859
|
186
|
/* lower layer isn't up - wait until later */
|
mbed714 |
0:d616ece2d859
|
187
|
cstate->clientstate = CHAPCS_PENDING;
|
mbed714 |
0:d616ece2d859
|
188
|
return;
|
mbed714 |
0:d616ece2d859
|
189
|
}
|
mbed714 |
0:d616ece2d859
|
190
|
|
mbed714 |
0:d616ece2d859
|
191
|
/*
|
mbed714 |
0:d616ece2d859
|
192
|
* We get here as a result of LCP coming up.
|
mbed714 |
0:d616ece2d859
|
193
|
* So even if CHAP was open before, we will
|
mbed714 |
0:d616ece2d859
|
194
|
* have to re-authenticate ourselves.
|
mbed714 |
0:d616ece2d859
|
195
|
*/
|
mbed714 |
0:d616ece2d859
|
196
|
cstate->clientstate = CHAPCS_LISTEN;
|
mbed714 |
0:d616ece2d859
|
197
|
}
|
mbed714 |
0:d616ece2d859
|
198
|
|
mbed714 |
0:d616ece2d859
|
199
|
|
mbed714 |
0:d616ece2d859
|
200
|
/*
|
mbed714 |
0:d616ece2d859
|
201
|
* ChapAuthPeer - Authenticate our peer (start server).
|
mbed714 |
0:d616ece2d859
|
202
|
*/
|
mbed714 |
0:d616ece2d859
|
203
|
void
|
mbed714 |
0:d616ece2d859
|
204
|
ChapAuthPeer(int unit, char *our_name, u_char digest)
|
mbed714 |
0:d616ece2d859
|
205
|
{
|
mbed714 |
0:d616ece2d859
|
206
|
chap_state *cstate = &chap[unit];
|
mbed714 |
0:d616ece2d859
|
207
|
|
mbed714 |
0:d616ece2d859
|
208
|
cstate->chal_name = our_name;
|
mbed714 |
0:d616ece2d859
|
209
|
cstate->chal_type = digest;
|
mbed714 |
0:d616ece2d859
|
210
|
|
mbed714 |
0:d616ece2d859
|
211
|
if (cstate->serverstate == CHAPSS_INITIAL ||
|
mbed714 |
0:d616ece2d859
|
212
|
cstate->serverstate == CHAPSS_PENDING) {
|
mbed714 |
0:d616ece2d859
|
213
|
/* lower layer isn't up - wait until later */
|
mbed714 |
0:d616ece2d859
|
214
|
cstate->serverstate = CHAPSS_PENDING;
|
mbed714 |
0:d616ece2d859
|
215
|
return;
|
mbed714 |
0:d616ece2d859
|
216
|
}
|
mbed714 |
0:d616ece2d859
|
217
|
|
mbed714 |
0:d616ece2d859
|
218
|
ChapGenChallenge(cstate);
|
mbed714 |
0:d616ece2d859
|
219
|
ChapSendChallenge(cstate); /* crank it up dude! */
|
mbed714 |
0:d616ece2d859
|
220
|
cstate->serverstate = CHAPSS_INITIAL_CHAL;
|
mbed714 |
0:d616ece2d859
|
221
|
}
|
mbed714 |
0:d616ece2d859
|
222
|
|
mbed714 |
0:d616ece2d859
|
223
|
|
mbed714 |
0:d616ece2d859
|
224
|
/*
|
mbed714 |
0:d616ece2d859
|
225
|
* ChapChallengeTimeout - Timeout expired on sending challenge.
|
mbed714 |
0:d616ece2d859
|
226
|
*/
|
mbed714 |
0:d616ece2d859
|
227
|
static void
|
mbed714 |
0:d616ece2d859
|
228
|
ChapChallengeTimeout(void *arg)
|
mbed714 |
0:d616ece2d859
|
229
|
{
|
mbed714 |
0:d616ece2d859
|
230
|
chap_state *cstate = (chap_state *) arg;
|
mbed714 |
0:d616ece2d859
|
231
|
|
mbed714 |
0:d616ece2d859
|
232
|
/* if we aren't sending challenges, don't worry. then again we */
|
mbed714 |
0:d616ece2d859
|
233
|
/* probably shouldn't be here either */
|
mbed714 |
0:d616ece2d859
|
234
|
if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&
|
mbed714 |
0:d616ece2d859
|
235
|
cstate->serverstate != CHAPSS_RECHALLENGE) {
|
mbed714 |
0:d616ece2d859
|
236
|
return;
|
mbed714 |
0:d616ece2d859
|
237
|
}
|
mbed714 |
0:d616ece2d859
|
238
|
|
mbed714 |
0:d616ece2d859
|
239
|
if (cstate->chal_transmits >= cstate->max_transmits) {
|
mbed714 |
0:d616ece2d859
|
240
|
/* give up on peer */
|
mbed714 |
0:d616ece2d859
|
241
|
CHAPDEBUG(LOG_ERR, ("Peer failed to respond to CHAP challenge\n"));
|
mbed714 |
0:d616ece2d859
|
242
|
cstate->serverstate = CHAPSS_BADAUTH;
|
mbed714 |
0:d616ece2d859
|
243
|
auth_peer_fail(cstate->unit, PPP_CHAP);
|
mbed714 |
0:d616ece2d859
|
244
|
return;
|
mbed714 |
0:d616ece2d859
|
245
|
}
|
mbed714 |
0:d616ece2d859
|
246
|
|
mbed714 |
0:d616ece2d859
|
247
|
ChapSendChallenge(cstate); /* Re-send challenge */
|
mbed714 |
0:d616ece2d859
|
248
|
}
|
mbed714 |
0:d616ece2d859
|
249
|
|
mbed714 |
0:d616ece2d859
|
250
|
|
mbed714 |
0:d616ece2d859
|
251
|
/*
|
mbed714 |
0:d616ece2d859
|
252
|
* ChapResponseTimeout - Timeout expired on sending response.
|
mbed714 |
0:d616ece2d859
|
253
|
*/
|
mbed714 |
0:d616ece2d859
|
254
|
static void
|
mbed714 |
0:d616ece2d859
|
255
|
ChapResponseTimeout(void *arg)
|
mbed714 |
0:d616ece2d859
|
256
|
{
|
mbed714 |
0:d616ece2d859
|
257
|
chap_state *cstate = (chap_state *) arg;
|
mbed714 |
0:d616ece2d859
|
258
|
|
mbed714 |
0:d616ece2d859
|
259
|
/* if we aren't sending a response, don't worry. */
|
mbed714 |
0:d616ece2d859
|
260
|
if (cstate->clientstate != CHAPCS_RESPONSE) {
|
mbed714 |
0:d616ece2d859
|
261
|
return;
|
mbed714 |
0:d616ece2d859
|
262
|
}
|
mbed714 |
0:d616ece2d859
|
263
|
|
mbed714 |
0:d616ece2d859
|
264
|
ChapSendResponse(cstate); /* re-send response */
|
mbed714 |
0:d616ece2d859
|
265
|
}
|
mbed714 |
0:d616ece2d859
|
266
|
|
mbed714 |
0:d616ece2d859
|
267
|
|
mbed714 |
0:d616ece2d859
|
268
|
/*
|
mbed714 |
0:d616ece2d859
|
269
|
* ChapRechallenge - Time to challenge the peer again.
|
mbed714 |
0:d616ece2d859
|
270
|
*/
|
mbed714 |
0:d616ece2d859
|
271
|
static void
|
mbed714 |
0:d616ece2d859
|
272
|
ChapRechallenge(void *arg)
|
mbed714 |
0:d616ece2d859
|
273
|
{
|
mbed714 |
0:d616ece2d859
|
274
|
chap_state *cstate = (chap_state *) arg;
|
mbed714 |
0:d616ece2d859
|
275
|
|
mbed714 |
0:d616ece2d859
|
276
|
/* if we aren't sending a response, don't worry. */
|
mbed714 |
0:d616ece2d859
|
277
|
if (cstate->serverstate != CHAPSS_OPEN) {
|
mbed714 |
0:d616ece2d859
|
278
|
return;
|
mbed714 |
0:d616ece2d859
|
279
|
}
|
mbed714 |
0:d616ece2d859
|
280
|
|
mbed714 |
0:d616ece2d859
|
281
|
ChapGenChallenge(cstate);
|
mbed714 |
0:d616ece2d859
|
282
|
ChapSendChallenge(cstate);
|
mbed714 |
0:d616ece2d859
|
283
|
cstate->serverstate = CHAPSS_RECHALLENGE;
|
mbed714 |
0:d616ece2d859
|
284
|
}
|
mbed714 |
0:d616ece2d859
|
285
|
|
mbed714 |
0:d616ece2d859
|
286
|
|
mbed714 |
0:d616ece2d859
|
287
|
/*
|
mbed714 |
0:d616ece2d859
|
288
|
* ChapLowerUp - The lower layer is up.
|
mbed714 |
0:d616ece2d859
|
289
|
*
|
mbed714 |
0:d616ece2d859
|
290
|
* Start up if we have pending requests.
|
mbed714 |
0:d616ece2d859
|
291
|
*/
|
mbed714 |
0:d616ece2d859
|
292
|
static void
|
mbed714 |
0:d616ece2d859
|
293
|
ChapLowerUp(int unit)
|
mbed714 |
0:d616ece2d859
|
294
|
{
|
mbed714 |
0:d616ece2d859
|
295
|
chap_state *cstate = &chap[unit];
|
mbed714 |
0:d616ece2d859
|
296
|
|
mbed714 |
0:d616ece2d859
|
297
|
if (cstate->clientstate == CHAPCS_INITIAL) {
|
mbed714 |
0:d616ece2d859
|
298
|
cstate->clientstate = CHAPCS_CLOSED;
|
mbed714 |
0:d616ece2d859
|
299
|
} else if (cstate->clientstate == CHAPCS_PENDING) {
|
mbed714 |
0:d616ece2d859
|
300
|
cstate->clientstate = CHAPCS_LISTEN;
|
mbed714 |
0:d616ece2d859
|
301
|
}
|
mbed714 |
0:d616ece2d859
|
302
|
|
mbed714 |
0:d616ece2d859
|
303
|
if (cstate->serverstate == CHAPSS_INITIAL) {
|
mbed714 |
0:d616ece2d859
|
304
|
cstate->serverstate = CHAPSS_CLOSED;
|
mbed714 |
0:d616ece2d859
|
305
|
} else if (cstate->serverstate == CHAPSS_PENDING) {
|
mbed714 |
0:d616ece2d859
|
306
|
ChapGenChallenge(cstate);
|
mbed714 |
0:d616ece2d859
|
307
|
ChapSendChallenge(cstate);
|
mbed714 |
0:d616ece2d859
|
308
|
cstate->serverstate = CHAPSS_INITIAL_CHAL;
|
mbed714 |
0:d616ece2d859
|
309
|
}
|
mbed714 |
0:d616ece2d859
|
310
|
}
|
mbed714 |
0:d616ece2d859
|
311
|
|
mbed714 |
0:d616ece2d859
|
312
|
|
mbed714 |
0:d616ece2d859
|
313
|
/*
|
mbed714 |
0:d616ece2d859
|
314
|
* ChapLowerDown - The lower layer is down.
|
mbed714 |
0:d616ece2d859
|
315
|
*
|
mbed714 |
0:d616ece2d859
|
316
|
* Cancel all timeouts.
|
mbed714 |
0:d616ece2d859
|
317
|
*/
|
mbed714 |
0:d616ece2d859
|
318
|
static void
|
mbed714 |
0:d616ece2d859
|
319
|
ChapLowerDown(int unit)
|
mbed714 |
0:d616ece2d859
|
320
|
{
|
mbed714 |
0:d616ece2d859
|
321
|
chap_state *cstate = &chap[unit];
|
mbed714 |
0:d616ece2d859
|
322
|
|
mbed714 |
0:d616ece2d859
|
323
|
/* Timeout(s) pending? Cancel if so. */
|
mbed714 |
0:d616ece2d859
|
324
|
if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||
|
mbed714 |
0:d616ece2d859
|
325
|
cstate->serverstate == CHAPSS_RECHALLENGE) {
|
mbed714 |
0:d616ece2d859
|
326
|
UNTIMEOUT(ChapChallengeTimeout, cstate);
|
mbed714 |
0:d616ece2d859
|
327
|
} else if (cstate->serverstate == CHAPSS_OPEN
|
mbed714 |
0:d616ece2d859
|
328
|
&& cstate->chal_interval != 0) {
|
mbed714 |
0:d616ece2d859
|
329
|
UNTIMEOUT(ChapRechallenge, cstate);
|
mbed714 |
0:d616ece2d859
|
330
|
}
|
mbed714 |
0:d616ece2d859
|
331
|
if (cstate->clientstate == CHAPCS_RESPONSE) {
|
mbed714 |
0:d616ece2d859
|
332
|
UNTIMEOUT(ChapResponseTimeout, cstate);
|
mbed714 |
0:d616ece2d859
|
333
|
}
|
mbed714 |
0:d616ece2d859
|
334
|
cstate->clientstate = CHAPCS_INITIAL;
|
mbed714 |
0:d616ece2d859
|
335
|
cstate->serverstate = CHAPSS_INITIAL;
|
mbed714 |
0:d616ece2d859
|
336
|
}
|
mbed714 |
0:d616ece2d859
|
337
|
|
mbed714 |
0:d616ece2d859
|
338
|
|
mbed714 |
0:d616ece2d859
|
339
|
/*
|
mbed714 |
0:d616ece2d859
|
340
|
* ChapProtocolReject - Peer doesn't grok CHAP.
|
mbed714 |
0:d616ece2d859
|
341
|
*/
|
mbed714 |
0:d616ece2d859
|
342
|
static void
|
mbed714 |
0:d616ece2d859
|
343
|
ChapProtocolReject(int unit)
|
mbed714 |
0:d616ece2d859
|
344
|
{
|
mbed714 |
0:d616ece2d859
|
345
|
chap_state *cstate = &chap[unit];
|
mbed714 |
0:d616ece2d859
|
346
|
|
mbed714 |
0:d616ece2d859
|
347
|
if (cstate->serverstate != CHAPSS_INITIAL &&
|
mbed714 |
0:d616ece2d859
|
348
|
cstate->serverstate != CHAPSS_CLOSED) {
|
mbed714 |
0:d616ece2d859
|
349
|
auth_peer_fail(unit, PPP_CHAP);
|
mbed714 |
0:d616ece2d859
|
350
|
}
|
mbed714 |
0:d616ece2d859
|
351
|
if (cstate->clientstate != CHAPCS_INITIAL &&
|
mbed714 |
0:d616ece2d859
|
352
|
cstate->clientstate != CHAPCS_CLOSED) {
|
mbed714 |
0:d616ece2d859
|
353
|
auth_withpeer_fail(unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */
|
mbed714 |
0:d616ece2d859
|
354
|
}
|
mbed714 |
0:d616ece2d859
|
355
|
ChapLowerDown(unit); /* shutdown chap */
|
mbed714 |
0:d616ece2d859
|
356
|
}
|
mbed714 |
0:d616ece2d859
|
357
|
|
mbed714 |
0:d616ece2d859
|
358
|
|
mbed714 |
0:d616ece2d859
|
359
|
/*
|
mbed714 |
0:d616ece2d859
|
360
|
* ChapInput - Input CHAP packet.
|
mbed714 |
0:d616ece2d859
|
361
|
*/
|
mbed714 |
0:d616ece2d859
|
362
|
static void
|
mbed714 |
0:d616ece2d859
|
363
|
ChapInput(int unit, u_char *inpacket, int packet_len)
|
mbed714 |
0:d616ece2d859
|
364
|
{
|
mbed714 |
0:d616ece2d859
|
365
|
chap_state *cstate = &chap[unit];
|
mbed714 |
0:d616ece2d859
|
366
|
u_char *inp;
|
mbed714 |
0:d616ece2d859
|
367
|
u_char code, id;
|
mbed714 |
0:d616ece2d859
|
368
|
int len;
|
mbed714 |
0:d616ece2d859
|
369
|
|
mbed714 |
0:d616ece2d859
|
370
|
/*
|
mbed714 |
0:d616ece2d859
|
371
|
* Parse header (code, id and length).
|
mbed714 |
0:d616ece2d859
|
372
|
* If packet too short, drop it.
|
mbed714 |
0:d616ece2d859
|
373
|
*/
|
mbed714 |
0:d616ece2d859
|
374
|
inp = inpacket;
|
mbed714 |
0:d616ece2d859
|
375
|
if (packet_len < CHAP_HEADERLEN) {
|
mbed714 |
0:d616ece2d859
|
376
|
CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short header.\n"));
|
mbed714 |
0:d616ece2d859
|
377
|
return;
|
mbed714 |
0:d616ece2d859
|
378
|
}
|
mbed714 |
0:d616ece2d859
|
379
|
GETCHAR(code, inp);
|
mbed714 |
0:d616ece2d859
|
380
|
GETCHAR(id, inp);
|
mbed714 |
0:d616ece2d859
|
381
|
GETSHORT(len, inp);
|
mbed714 |
0:d616ece2d859
|
382
|
if (len < CHAP_HEADERLEN) {
|
mbed714 |
0:d616ece2d859
|
383
|
CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd illegal length.\n"));
|
mbed714 |
0:d616ece2d859
|
384
|
return;
|
mbed714 |
0:d616ece2d859
|
385
|
}
|
mbed714 |
0:d616ece2d859
|
386
|
if (len > packet_len) {
|
mbed714 |
0:d616ece2d859
|
387
|
CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short packet.\n"));
|
mbed714 |
0:d616ece2d859
|
388
|
return;
|
mbed714 |
0:d616ece2d859
|
389
|
}
|
mbed714 |
0:d616ece2d859
|
390
|
len -= CHAP_HEADERLEN;
|
mbed714 |
0:d616ece2d859
|
391
|
|
mbed714 |
0:d616ece2d859
|
392
|
/*
|
mbed714 |
0:d616ece2d859
|
393
|
* Action depends on code (as in fact it usually does :-).
|
mbed714 |
0:d616ece2d859
|
394
|
*/
|
mbed714 |
0:d616ece2d859
|
395
|
switch (code) {
|
mbed714 |
0:d616ece2d859
|
396
|
case CHAP_CHALLENGE:
|
mbed714 |
0:d616ece2d859
|
397
|
ChapReceiveChallenge(cstate, inp, id, len);
|
mbed714 |
0:d616ece2d859
|
398
|
break;
|
mbed714 |
0:d616ece2d859
|
399
|
|
mbed714 |
0:d616ece2d859
|
400
|
case CHAP_RESPONSE:
|
mbed714 |
0:d616ece2d859
|
401
|
ChapReceiveResponse(cstate, inp, id, len);
|
mbed714 |
0:d616ece2d859
|
402
|
break;
|
mbed714 |
0:d616ece2d859
|
403
|
|
mbed714 |
0:d616ece2d859
|
404
|
case CHAP_FAILURE:
|
mbed714 |
0:d616ece2d859
|
405
|
ChapReceiveFailure(cstate, inp, id, len);
|
mbed714 |
0:d616ece2d859
|
406
|
break;
|
mbed714 |
0:d616ece2d859
|
407
|
|
mbed714 |
0:d616ece2d859
|
408
|
case CHAP_SUCCESS:
|
mbed714 |
0:d616ece2d859
|
409
|
ChapReceiveSuccess(cstate, inp, id, len);
|
mbed714 |
0:d616ece2d859
|
410
|
break;
|
mbed714 |
0:d616ece2d859
|
411
|
|
mbed714 |
0:d616ece2d859
|
412
|
default: /* Need code reject? */
|
mbed714 |
0:d616ece2d859
|
413
|
CHAPDEBUG(LOG_WARNING, ("Unknown CHAP code (%d) received.\n", code));
|
mbed714 |
0:d616ece2d859
|
414
|
break;
|
mbed714 |
0:d616ece2d859
|
415
|
}
|
mbed714 |
0:d616ece2d859
|
416
|
}
|
mbed714 |
0:d616ece2d859
|
417
|
|
mbed714 |
0:d616ece2d859
|
418
|
|
mbed714 |
0:d616ece2d859
|
419
|
/*
|
mbed714 |
0:d616ece2d859
|
420
|
* ChapReceiveChallenge - Receive Challenge and send Response.
|
mbed714 |
0:d616ece2d859
|
421
|
*/
|
mbed714 |
0:d616ece2d859
|
422
|
static void
|
mbed714 |
0:d616ece2d859
|
423
|
ChapReceiveChallenge(chap_state *cstate, u_char *inp, u_char id, int len)
|
mbed714 |
0:d616ece2d859
|
424
|
{
|
mbed714 |
0:d616ece2d859
|
425
|
int rchallenge_len;
|
mbed714 |
0:d616ece2d859
|
426
|
u_char *rchallenge;
|
mbed714 |
0:d616ece2d859
|
427
|
int secret_len;
|
mbed714 |
0:d616ece2d859
|
428
|
char secret[MAXSECRETLEN];
|
mbed714 |
0:d616ece2d859
|
429
|
char rhostname[256];
|
mbed714 |
0:d616ece2d859
|
430
|
MD5_CTX mdContext;
|
mbed714 |
0:d616ece2d859
|
431
|
u_char hash[MD5_SIGNATURE_SIZE];
|
mbed714 |
0:d616ece2d859
|
432
|
|
mbed714 |
0:d616ece2d859
|
433
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: Rcvd id %d.\n", id));
|
mbed714 |
0:d616ece2d859
|
434
|
if (cstate->clientstate == CHAPCS_CLOSED ||
|
mbed714 |
0:d616ece2d859
|
435
|
cstate->clientstate == CHAPCS_PENDING) {
|
mbed714 |
0:d616ece2d859
|
436
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: in state %d\n",
|
mbed714 |
0:d616ece2d859
|
437
|
cstate->clientstate));
|
mbed714 |
0:d616ece2d859
|
438
|
return;
|
mbed714 |
0:d616ece2d859
|
439
|
}
|
mbed714 |
0:d616ece2d859
|
440
|
|
mbed714 |
0:d616ece2d859
|
441
|
if (len < 2) {
|
mbed714 |
0:d616ece2d859
|
442
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n"));
|
mbed714 |
0:d616ece2d859
|
443
|
return;
|
mbed714 |
0:d616ece2d859
|
444
|
}
|
mbed714 |
0:d616ece2d859
|
445
|
|
mbed714 |
0:d616ece2d859
|
446
|
GETCHAR(rchallenge_len, inp);
|
mbed714 |
0:d616ece2d859
|
447
|
len -= sizeof (u_char) + rchallenge_len; /* now name field length */
|
mbed714 |
0:d616ece2d859
|
448
|
if (len < 0) {
|
mbed714 |
0:d616ece2d859
|
449
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n"));
|
mbed714 |
0:d616ece2d859
|
450
|
return;
|
mbed714 |
0:d616ece2d859
|
451
|
}
|
mbed714 |
0:d616ece2d859
|
452
|
rchallenge = inp;
|
mbed714 |
0:d616ece2d859
|
453
|
INCPTR(rchallenge_len, inp);
|
mbed714 |
0:d616ece2d859
|
454
|
|
mbed714 |
0:d616ece2d859
|
455
|
if (len >= (int)sizeof(rhostname)) {
|
mbed714 |
0:d616ece2d859
|
456
|
len = sizeof(rhostname) - 1;
|
mbed714 |
0:d616ece2d859
|
457
|
}
|
mbed714 |
0:d616ece2d859
|
458
|
BCOPY(inp, rhostname, len);
|
mbed714 |
0:d616ece2d859
|
459
|
rhostname[len] = '\000';
|
mbed714 |
0:d616ece2d859
|
460
|
|
mbed714 |
0:d616ece2d859
|
461
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: received name field '%s'\n",
|
mbed714 |
0:d616ece2d859
|
462
|
rhostname));
|
mbed714 |
0:d616ece2d859
|
463
|
|
mbed714 |
0:d616ece2d859
|
464
|
/* Microsoft doesn't send their name back in the PPP packet */
|
mbed714 |
0:d616ece2d859
|
465
|
if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) {
|
mbed714 |
0:d616ece2d859
|
466
|
strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname));
|
mbed714 |
0:d616ece2d859
|
467
|
rhostname[sizeof(rhostname) - 1] = 0;
|
mbed714 |
0:d616ece2d859
|
468
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: using '%s' as remote name\n",
|
mbed714 |
0:d616ece2d859
|
469
|
rhostname));
|
mbed714 |
0:d616ece2d859
|
470
|
}
|
mbed714 |
0:d616ece2d859
|
471
|
|
mbed714 |
0:d616ece2d859
|
472
|
/* get secret for authenticating ourselves with the specified host */
|
mbed714 |
0:d616ece2d859
|
473
|
if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
|
mbed714 |
0:d616ece2d859
|
474
|
secret, &secret_len, 0)) {
|
mbed714 |
0:d616ece2d859
|
475
|
secret_len = 0; /* assume null secret if can't find one */
|
mbed714 |
0:d616ece2d859
|
476
|
CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating us to %s\n",
|
mbed714 |
0:d616ece2d859
|
477
|
rhostname));
|
mbed714 |
0:d616ece2d859
|
478
|
}
|
mbed714 |
0:d616ece2d859
|
479
|
|
mbed714 |
0:d616ece2d859
|
480
|
/* cancel response send timeout if necessary */
|
mbed714 |
0:d616ece2d859
|
481
|
if (cstate->clientstate == CHAPCS_RESPONSE) {
|
mbed714 |
0:d616ece2d859
|
482
|
UNTIMEOUT(ChapResponseTimeout, cstate);
|
mbed714 |
0:d616ece2d859
|
483
|
}
|
mbed714 |
0:d616ece2d859
|
484
|
|
mbed714 |
0:d616ece2d859
|
485
|
cstate->resp_id = id;
|
mbed714 |
0:d616ece2d859
|
486
|
cstate->resp_transmits = 0;
|
mbed714 |
0:d616ece2d859
|
487
|
|
mbed714 |
0:d616ece2d859
|
488
|
/* generate MD based on negotiated type */
|
mbed714 |
0:d616ece2d859
|
489
|
switch (cstate->resp_type) {
|
mbed714 |
0:d616ece2d859
|
490
|
|
mbed714 |
0:d616ece2d859
|
491
|
case CHAP_DIGEST_MD5:
|
mbed714 |
0:d616ece2d859
|
492
|
MD5Init(&mdContext);
|
mbed714 |
0:d616ece2d859
|
493
|
MD5Update(&mdContext, &cstate->resp_id, 1);
|
mbed714 |
0:d616ece2d859
|
494
|
MD5Update(&mdContext, (u_char*)secret, secret_len);
|
mbed714 |
0:d616ece2d859
|
495
|
MD5Update(&mdContext, rchallenge, rchallenge_len);
|
mbed714 |
0:d616ece2d859
|
496
|
MD5Final(hash, &mdContext);
|
mbed714 |
0:d616ece2d859
|
497
|
BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE);
|
mbed714 |
0:d616ece2d859
|
498
|
cstate->resp_length = MD5_SIGNATURE_SIZE;
|
mbed714 |
0:d616ece2d859
|
499
|
break;
|
mbed714 |
0:d616ece2d859
|
500
|
|
mbed714 |
0:d616ece2d859
|
501
|
#if MSCHAP_SUPPORT
|
mbed714 |
0:d616ece2d859
|
502
|
case CHAP_MICROSOFT:
|
mbed714 |
0:d616ece2d859
|
503
|
ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
|
mbed714 |
0:d616ece2d859
|
504
|
break;
|
mbed714 |
0:d616ece2d859
|
505
|
#endif
|
mbed714 |
0:d616ece2d859
|
506
|
|
mbed714 |
0:d616ece2d859
|
507
|
default:
|
mbed714 |
0:d616ece2d859
|
508
|
CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->resp_type));
|
mbed714 |
0:d616ece2d859
|
509
|
return;
|
mbed714 |
0:d616ece2d859
|
510
|
}
|
mbed714 |
0:d616ece2d859
|
511
|
|
mbed714 |
0:d616ece2d859
|
512
|
BZERO(secret, sizeof(secret));
|
mbed714 |
0:d616ece2d859
|
513
|
ChapSendResponse(cstate);
|
mbed714 |
0:d616ece2d859
|
514
|
}
|
mbed714 |
0:d616ece2d859
|
515
|
|
mbed714 |
0:d616ece2d859
|
516
|
|
mbed714 |
0:d616ece2d859
|
517
|
/*
|
mbed714 |
0:d616ece2d859
|
518
|
* ChapReceiveResponse - Receive and process response.
|
mbed714 |
0:d616ece2d859
|
519
|
*/
|
mbed714 |
0:d616ece2d859
|
520
|
static void
|
mbed714 |
0:d616ece2d859
|
521
|
ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)
|
mbed714 |
0:d616ece2d859
|
522
|
{
|
mbed714 |
0:d616ece2d859
|
523
|
u_char *remmd, remmd_len;
|
mbed714 |
0:d616ece2d859
|
524
|
int secret_len, old_state;
|
mbed714 |
0:d616ece2d859
|
525
|
int code;
|
mbed714 |
0:d616ece2d859
|
526
|
char rhostname[256];
|
mbed714 |
0:d616ece2d859
|
527
|
MD5_CTX mdContext;
|
mbed714 |
0:d616ece2d859
|
528
|
char secret[MAXSECRETLEN];
|
mbed714 |
0:d616ece2d859
|
529
|
u_char hash[MD5_SIGNATURE_SIZE];
|
mbed714 |
0:d616ece2d859
|
530
|
|
mbed714 |
0:d616ece2d859
|
531
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: Rcvd id %d.\n", id));
|
mbed714 |
0:d616ece2d859
|
532
|
|
mbed714 |
0:d616ece2d859
|
533
|
if (cstate->serverstate == CHAPSS_CLOSED ||
|
mbed714 |
0:d616ece2d859
|
534
|
cstate->serverstate == CHAPSS_PENDING) {
|
mbed714 |
0:d616ece2d859
|
535
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: in state %d\n",
|
mbed714 |
0:d616ece2d859
|
536
|
cstate->serverstate));
|
mbed714 |
0:d616ece2d859
|
537
|
return;
|
mbed714 |
0:d616ece2d859
|
538
|
}
|
mbed714 |
0:d616ece2d859
|
539
|
|
mbed714 |
0:d616ece2d859
|
540
|
if (id != cstate->chal_id) {
|
mbed714 |
0:d616ece2d859
|
541
|
return; /* doesn't match ID of last challenge */
|
mbed714 |
0:d616ece2d859
|
542
|
}
|
mbed714 |
0:d616ece2d859
|
543
|
|
mbed714 |
0:d616ece2d859
|
544
|
/*
|
mbed714 |
0:d616ece2d859
|
545
|
* If we have received a duplicate or bogus Response,
|
mbed714 |
0:d616ece2d859
|
546
|
* we have to send the same answer (Success/Failure)
|
mbed714 |
0:d616ece2d859
|
547
|
* as we did for the first Response we saw.
|
mbed714 |
0:d616ece2d859
|
548
|
*/
|
mbed714 |
0:d616ece2d859
|
549
|
if (cstate->serverstate == CHAPSS_OPEN) {
|
mbed714 |
0:d616ece2d859
|
550
|
ChapSendStatus(cstate, CHAP_SUCCESS);
|
mbed714 |
0:d616ece2d859
|
551
|
return;
|
mbed714 |
0:d616ece2d859
|
552
|
}
|
mbed714 |
0:d616ece2d859
|
553
|
if (cstate->serverstate == CHAPSS_BADAUTH) {
|
mbed714 |
0:d616ece2d859
|
554
|
ChapSendStatus(cstate, CHAP_FAILURE);
|
mbed714 |
0:d616ece2d859
|
555
|
return;
|
mbed714 |
0:d616ece2d859
|
556
|
}
|
mbed714 |
0:d616ece2d859
|
557
|
|
mbed714 |
0:d616ece2d859
|
558
|
if (len < 2) {
|
mbed714 |
0:d616ece2d859
|
559
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n"));
|
mbed714 |
0:d616ece2d859
|
560
|
return;
|
mbed714 |
0:d616ece2d859
|
561
|
}
|
mbed714 |
0:d616ece2d859
|
562
|
GETCHAR(remmd_len, inp); /* get length of MD */
|
mbed714 |
0:d616ece2d859
|
563
|
remmd = inp; /* get pointer to MD */
|
mbed714 |
0:d616ece2d859
|
564
|
INCPTR(remmd_len, inp);
|
mbed714 |
0:d616ece2d859
|
565
|
|
mbed714 |
0:d616ece2d859
|
566
|
len -= sizeof (u_char) + remmd_len;
|
mbed714 |
0:d616ece2d859
|
567
|
if (len < 0) {
|
mbed714 |
0:d616ece2d859
|
568
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n"));
|
mbed714 |
0:d616ece2d859
|
569
|
return;
|
mbed714 |
0:d616ece2d859
|
570
|
}
|
mbed714 |
0:d616ece2d859
|
571
|
|
mbed714 |
0:d616ece2d859
|
572
|
UNTIMEOUT(ChapChallengeTimeout, cstate);
|
mbed714 |
0:d616ece2d859
|
573
|
|
mbed714 |
0:d616ece2d859
|
574
|
if (len >= (int)sizeof(rhostname)) {
|
mbed714 |
0:d616ece2d859
|
575
|
len = sizeof(rhostname) - 1;
|
mbed714 |
0:d616ece2d859
|
576
|
}
|
mbed714 |
0:d616ece2d859
|
577
|
BCOPY(inp, rhostname, len);
|
mbed714 |
0:d616ece2d859
|
578
|
rhostname[len] = '\000';
|
mbed714 |
0:d616ece2d859
|
579
|
|
mbed714 |
0:d616ece2d859
|
580
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: received name field: %s\n",
|
mbed714 |
0:d616ece2d859
|
581
|
rhostname));
|
mbed714 |
0:d616ece2d859
|
582
|
|
mbed714 |
0:d616ece2d859
|
583
|
/*
|
mbed714 |
0:d616ece2d859
|
584
|
* Get secret for authenticating them with us,
|
mbed714 |
0:d616ece2d859
|
585
|
* do the hash ourselves, and compare the result.
|
mbed714 |
0:d616ece2d859
|
586
|
*/
|
mbed714 |
0:d616ece2d859
|
587
|
code = CHAP_FAILURE;
|
mbed714 |
0:d616ece2d859
|
588
|
if (!get_secret(cstate->unit, rhostname, cstate->chal_name,
|
mbed714 |
0:d616ece2d859
|
589
|
secret, &secret_len, 1)) {
|
mbed714 |
0:d616ece2d859
|
590
|
CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating %s\n",
|
mbed714 |
0:d616ece2d859
|
591
|
rhostname));
|
mbed714 |
0:d616ece2d859
|
592
|
} else {
|
mbed714 |
0:d616ece2d859
|
593
|
/* generate MD based on negotiated type */
|
mbed714 |
0:d616ece2d859
|
594
|
switch (cstate->chal_type) {
|
mbed714 |
0:d616ece2d859
|
595
|
|
mbed714 |
0:d616ece2d859
|
596
|
case CHAP_DIGEST_MD5: /* only MD5 is defined for now */
|
mbed714 |
0:d616ece2d859
|
597
|
if (remmd_len != MD5_SIGNATURE_SIZE) {
|
mbed714 |
0:d616ece2d859
|
598
|
break; /* it's not even the right length */
|
mbed714 |
0:d616ece2d859
|
599
|
}
|
mbed714 |
0:d616ece2d859
|
600
|
MD5Init(&mdContext);
|
mbed714 |
0:d616ece2d859
|
601
|
MD5Update(&mdContext, &cstate->chal_id, 1);
|
mbed714 |
0:d616ece2d859
|
602
|
MD5Update(&mdContext, (u_char*)secret, secret_len);
|
mbed714 |
0:d616ece2d859
|
603
|
MD5Update(&mdContext, cstate->challenge, cstate->chal_len);
|
mbed714 |
0:d616ece2d859
|
604
|
MD5Final(hash, &mdContext);
|
mbed714 |
0:d616ece2d859
|
605
|
|
mbed714 |
0:d616ece2d859
|
606
|
/* compare local and remote MDs and send the appropriate status */
|
mbed714 |
0:d616ece2d859
|
607
|
if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) {
|
mbed714 |
0:d616ece2d859
|
608
|
code = CHAP_SUCCESS; /* they are the same! */
|
mbed714 |
0:d616ece2d859
|
609
|
}
|
mbed714 |
0:d616ece2d859
|
610
|
break;
|
mbed714 |
0:d616ece2d859
|
611
|
|
mbed714 |
0:d616ece2d859
|
612
|
default:
|
mbed714 |
0:d616ece2d859
|
613
|
CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->chal_type));
|
mbed714 |
0:d616ece2d859
|
614
|
}
|
mbed714 |
0:d616ece2d859
|
615
|
}
|
mbed714 |
0:d616ece2d859
|
616
|
|
mbed714 |
0:d616ece2d859
|
617
|
BZERO(secret, sizeof(secret));
|
mbed714 |
0:d616ece2d859
|
618
|
ChapSendStatus(cstate, code);
|
mbed714 |
0:d616ece2d859
|
619
|
|
mbed714 |
0:d616ece2d859
|
620
|
if (code == CHAP_SUCCESS) {
|
mbed714 |
0:d616ece2d859
|
621
|
old_state = cstate->serverstate;
|
mbed714 |
0:d616ece2d859
|
622
|
cstate->serverstate = CHAPSS_OPEN;
|
mbed714 |
0:d616ece2d859
|
623
|
if (old_state == CHAPSS_INITIAL_CHAL) {
|
mbed714 |
0:d616ece2d859
|
624
|
auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);
|
mbed714 |
0:d616ece2d859
|
625
|
}
|
mbed714 |
0:d616ece2d859
|
626
|
if (cstate->chal_interval != 0) {
|
mbed714 |
0:d616ece2d859
|
627
|
TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
|
mbed714 |
0:d616ece2d859
|
628
|
}
|
mbed714 |
0:d616ece2d859
|
629
|
} else {
|
mbed714 |
0:d616ece2d859
|
630
|
CHAPDEBUG(LOG_ERR, ("CHAP peer authentication failed\n"));
|
mbed714 |
0:d616ece2d859
|
631
|
cstate->serverstate = CHAPSS_BADAUTH;
|
mbed714 |
0:d616ece2d859
|
632
|
auth_peer_fail(cstate->unit, PPP_CHAP);
|
mbed714 |
0:d616ece2d859
|
633
|
}
|
mbed714 |
0:d616ece2d859
|
634
|
}
|
mbed714 |
0:d616ece2d859
|
635
|
|
mbed714 |
0:d616ece2d859
|
636
|
/*
|
mbed714 |
0:d616ece2d859
|
637
|
* ChapReceiveSuccess - Receive Success
|
mbed714 |
0:d616ece2d859
|
638
|
*/
|
mbed714 |
0:d616ece2d859
|
639
|
static void
|
mbed714 |
0:d616ece2d859
|
640
|
ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len)
|
mbed714 |
0:d616ece2d859
|
641
|
{
|
mbed714 |
0:d616ece2d859
|
642
|
LWIP_UNUSED_ARG(id);
|
mbed714 |
0:d616ece2d859
|
643
|
LWIP_UNUSED_ARG(inp);
|
mbed714 |
0:d616ece2d859
|
644
|
|
mbed714 |
0:d616ece2d859
|
645
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: Rcvd id %d.\n", id));
|
mbed714 |
0:d616ece2d859
|
646
|
|
mbed714 |
0:d616ece2d859
|
647
|
if (cstate->clientstate == CHAPCS_OPEN) {
|
mbed714 |
0:d616ece2d859
|
648
|
/* presumably an answer to a duplicate response */
|
mbed714 |
0:d616ece2d859
|
649
|
return;
|
mbed714 |
0:d616ece2d859
|
650
|
}
|
mbed714 |
0:d616ece2d859
|
651
|
|
mbed714 |
0:d616ece2d859
|
652
|
if (cstate->clientstate != CHAPCS_RESPONSE) {
|
mbed714 |
0:d616ece2d859
|
653
|
/* don't know what this is */
|
mbed714 |
0:d616ece2d859
|
654
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: in state %d\n",
|
mbed714 |
0:d616ece2d859
|
655
|
cstate->clientstate));
|
mbed714 |
0:d616ece2d859
|
656
|
return;
|
mbed714 |
0:d616ece2d859
|
657
|
}
|
mbed714 |
0:d616ece2d859
|
658
|
|
mbed714 |
0:d616ece2d859
|
659
|
UNTIMEOUT(ChapResponseTimeout, cstate);
|
mbed714 |
0:d616ece2d859
|
660
|
|
mbed714 |
0:d616ece2d859
|
661
|
/*
|
mbed714 |
0:d616ece2d859
|
662
|
* Print message.
|
mbed714 |
0:d616ece2d859
|
663
|
*/
|
mbed714 |
0:d616ece2d859
|
664
|
if (len > 0) {
|
mbed714 |
0:d616ece2d859
|
665
|
PRINTMSG(inp, len);
|
mbed714 |
0:d616ece2d859
|
666
|
}
|
mbed714 |
0:d616ece2d859
|
667
|
|
mbed714 |
0:d616ece2d859
|
668
|
cstate->clientstate = CHAPCS_OPEN;
|
mbed714 |
0:d616ece2d859
|
669
|
|
mbed714 |
0:d616ece2d859
|
670
|
auth_withpeer_success(cstate->unit, PPP_CHAP);
|
mbed714 |
0:d616ece2d859
|
671
|
}
|
mbed714 |
0:d616ece2d859
|
672
|
|
mbed714 |
0:d616ece2d859
|
673
|
|
mbed714 |
0:d616ece2d859
|
674
|
/*
|
mbed714 |
0:d616ece2d859
|
675
|
* ChapReceiveFailure - Receive failure.
|
mbed714 |
0:d616ece2d859
|
676
|
*/
|
mbed714 |
0:d616ece2d859
|
677
|
static void
|
mbed714 |
0:d616ece2d859
|
678
|
ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len)
|
mbed714 |
0:d616ece2d859
|
679
|
{
|
mbed714 |
0:d616ece2d859
|
680
|
LWIP_UNUSED_ARG(id);
|
mbed714 |
0:d616ece2d859
|
681
|
LWIP_UNUSED_ARG(inp);
|
mbed714 |
0:d616ece2d859
|
682
|
|
mbed714 |
0:d616ece2d859
|
683
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: Rcvd id %d.\n", id));
|
mbed714 |
0:d616ece2d859
|
684
|
|
mbed714 |
0:d616ece2d859
|
685
|
if (cstate->clientstate != CHAPCS_RESPONSE) {
|
mbed714 |
0:d616ece2d859
|
686
|
/* don't know what this is */
|
mbed714 |
0:d616ece2d859
|
687
|
CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: in state %d\n",
|
mbed714 |
0:d616ece2d859
|
688
|
cstate->clientstate));
|
mbed714 |
0:d616ece2d859
|
689
|
return;
|
mbed714 |
0:d616ece2d859
|
690
|
}
|
mbed714 |
0:d616ece2d859
|
691
|
|
mbed714 |
0:d616ece2d859
|
692
|
UNTIMEOUT(ChapResponseTimeout, cstate);
|
mbed714 |
0:d616ece2d859
|
693
|
|
mbed714 |
0:d616ece2d859
|
694
|
/*
|
mbed714 |
0:d616ece2d859
|
695
|
* Print message.
|
mbed714 |
0:d616ece2d859
|
696
|
*/
|
mbed714 |
0:d616ece2d859
|
697
|
if (len > 0) {
|
mbed714 |
0:d616ece2d859
|
698
|
PRINTMSG(inp, len);
|
mbed714 |
0:d616ece2d859
|
699
|
}
|
mbed714 |
0:d616ece2d859
|
700
|
|
mbed714 |
0:d616ece2d859
|
701
|
CHAPDEBUG(LOG_ERR, ("CHAP authentication failed\n"));
|
mbed714 |
0:d616ece2d859
|
702
|
auth_withpeer_fail(cstate->unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */
|
mbed714 |
0:d616ece2d859
|
703
|
}
|
mbed714 |
0:d616ece2d859
|
704
|
|
mbed714 |
0:d616ece2d859
|
705
|
|
mbed714 |
0:d616ece2d859
|
706
|
/*
|
mbed714 |
0:d616ece2d859
|
707
|
* ChapSendChallenge - Send an Authenticate challenge.
|
mbed714 |
0:d616ece2d859
|
708
|
*/
|
mbed714 |
0:d616ece2d859
|
709
|
static void
|
mbed714 |
0:d616ece2d859
|
710
|
ChapSendChallenge(chap_state *cstate)
|
mbed714 |
0:d616ece2d859
|
711
|
{
|
mbed714 |
0:d616ece2d859
|
712
|
u_char *outp;
|
mbed714 |
0:d616ece2d859
|
713
|
int chal_len, name_len;
|
mbed714 |
0:d616ece2d859
|
714
|
int outlen;
|
mbed714 |
0:d616ece2d859
|
715
|
|
mbed714 |
0:d616ece2d859
|
716
|
chal_len = cstate->chal_len;
|
mbed714 |
0:d616ece2d859
|
717
|
name_len = (int)strlen(cstate->chal_name);
|
mbed714 |
0:d616ece2d859
|
718
|
outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
|
mbed714 |
0:d616ece2d859
|
719
|
outp = outpacket_buf[cstate->unit];
|
mbed714 |
0:d616ece2d859
|
720
|
|
mbed714 |
0:d616ece2d859
|
721
|
MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */
|
mbed714 |
0:d616ece2d859
|
722
|
|
mbed714 |
0:d616ece2d859
|
723
|
PUTCHAR(CHAP_CHALLENGE, outp);
|
mbed714 |
0:d616ece2d859
|
724
|
PUTCHAR(cstate->chal_id, outp);
|
mbed714 |
0:d616ece2d859
|
725
|
PUTSHORT(outlen, outp);
|
mbed714 |
0:d616ece2d859
|
726
|
|
mbed714 |
0:d616ece2d859
|
727
|
PUTCHAR(chal_len, outp); /* put length of challenge */
|
mbed714 |
0:d616ece2d859
|
728
|
BCOPY(cstate->challenge, outp, chal_len);
|
mbed714 |
0:d616ece2d859
|
729
|
INCPTR(chal_len, outp);
|
mbed714 |
0:d616ece2d859
|
730
|
|
mbed714 |
0:d616ece2d859
|
731
|
BCOPY(cstate->chal_name, outp, name_len); /* append hostname */
|
mbed714 |
0:d616ece2d859
|
732
|
|
mbed714 |
0:d616ece2d859
|
733
|
pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
|
mbed714 |
0:d616ece2d859
|
734
|
|
mbed714 |
0:d616ece2d859
|
735
|
CHAPDEBUG(LOG_INFO, ("ChapSendChallenge: Sent id %d.\n", cstate->chal_id));
|
mbed714 |
0:d616ece2d859
|
736
|
|
mbed714 |
0:d616ece2d859
|
737
|
TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);
|
mbed714 |
0:d616ece2d859
|
738
|
++cstate->chal_transmits;
|
mbed714 |
0:d616ece2d859
|
739
|
}
|
mbed714 |
0:d616ece2d859
|
740
|
|
mbed714 |
0:d616ece2d859
|
741
|
|
mbed714 |
0:d616ece2d859
|
742
|
/*
|
mbed714 |
0:d616ece2d859
|
743
|
* ChapSendStatus - Send a status response (ack or nak).
|
mbed714 |
0:d616ece2d859
|
744
|
*/
|
mbed714 |
0:d616ece2d859
|
745
|
static void
|
mbed714 |
0:d616ece2d859
|
746
|
ChapSendStatus(chap_state *cstate, int code)
|
mbed714 |
0:d616ece2d859
|
747
|
{
|
mbed714 |
0:d616ece2d859
|
748
|
u_char *outp;
|
mbed714 |
0:d616ece2d859
|
749
|
int outlen, msglen;
|
mbed714 |
0:d616ece2d859
|
750
|
char msg[256]; /* @todo: this can be a char*, no strcpy needed */
|
mbed714 |
0:d616ece2d859
|
751
|
|
mbed714 |
0:d616ece2d859
|
752
|
if (code == CHAP_SUCCESS) {
|
mbed714 |
0:d616ece2d859
|
753
|
strcpy(msg, "Welcome!");
|
mbed714 |
0:d616ece2d859
|
754
|
} else {
|
mbed714 |
0:d616ece2d859
|
755
|
strcpy(msg, "I don't like you. Go 'way.");
|
mbed714 |
0:d616ece2d859
|
756
|
}
|
mbed714 |
0:d616ece2d859
|
757
|
msglen = (int)strlen(msg);
|
mbed714 |
0:d616ece2d859
|
758
|
|
mbed714 |
0:d616ece2d859
|
759
|
outlen = CHAP_HEADERLEN + msglen;
|
mbed714 |
0:d616ece2d859
|
760
|
outp = outpacket_buf[cstate->unit];
|
mbed714 |
0:d616ece2d859
|
761
|
|
mbed714 |
0:d616ece2d859
|
762
|
MAKEHEADER(outp, PPP_CHAP); /* paste in a header */
|
mbed714 |
0:d616ece2d859
|
763
|
|
mbed714 |
0:d616ece2d859
|
764
|
PUTCHAR(code, outp);
|
mbed714 |
0:d616ece2d859
|
765
|
PUTCHAR(cstate->chal_id, outp);
|
mbed714 |
0:d616ece2d859
|
766
|
PUTSHORT(outlen, outp);
|
mbed714 |
0:d616ece2d859
|
767
|
BCOPY(msg, outp, msglen);
|
mbed714 |
0:d616ece2d859
|
768
|
pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
|
mbed714 |
0:d616ece2d859
|
769
|
|
mbed714 |
0:d616ece2d859
|
770
|
CHAPDEBUG(LOG_INFO, ("ChapSendStatus: Sent code %d, id %d.\n", code,
|
mbed714 |
0:d616ece2d859
|
771
|
cstate->chal_id));
|
mbed714 |
0:d616ece2d859
|
772
|
}
|
mbed714 |
0:d616ece2d859
|
773
|
|
mbed714 |
0:d616ece2d859
|
774
|
/*
|
mbed714 |
0:d616ece2d859
|
775
|
* ChapGenChallenge is used to generate a pseudo-random challenge string of
|
mbed714 |
0:d616ece2d859
|
776
|
* a pseudo-random length between min_len and max_len. The challenge
|
mbed714 |
0:d616ece2d859
|
777
|
* string and its length are stored in *cstate, and various other fields of
|
mbed714 |
0:d616ece2d859
|
778
|
* *cstate are initialized.
|
mbed714 |
0:d616ece2d859
|
779
|
*/
|
mbed714 |
0:d616ece2d859
|
780
|
|
mbed714 |
0:d616ece2d859
|
781
|
static void
|
mbed714 |
0:d616ece2d859
|
782
|
ChapGenChallenge(chap_state *cstate)
|
mbed714 |
0:d616ece2d859
|
783
|
{
|
mbed714 |
0:d616ece2d859
|
784
|
int chal_len;
|
mbed714 |
0:d616ece2d859
|
785
|
u_char *ptr = cstate->challenge;
|
mbed714 |
0:d616ece2d859
|
786
|
int i;
|
mbed714 |
0:d616ece2d859
|
787
|
|
mbed714 |
0:d616ece2d859
|
788
|
/* pick a random challenge length between MIN_CHALLENGE_LENGTH and
|
mbed714 |
0:d616ece2d859
|
789
|
MAX_CHALLENGE_LENGTH */
|
mbed714 |
0:d616ece2d859
|
790
|
chal_len = (unsigned)
|
mbed714 |
0:d616ece2d859
|
791
|
((((magic() >> 16) *
|
mbed714 |
0:d616ece2d859
|
792
|
(MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16)
|
mbed714 |
0:d616ece2d859
|
793
|
+ MIN_CHALLENGE_LENGTH);
|
mbed714 |
0:d616ece2d859
|
794
|
LWIP_ASSERT("chal_len <= 0xff", chal_len <= 0xffff);
|
mbed714 |
0:d616ece2d859
|
795
|
cstate->chal_len = (u_char)chal_len;
|
mbed714 |
0:d616ece2d859
|
796
|
cstate->chal_id = ++cstate->id;
|
mbed714 |
0:d616ece2d859
|
797
|
cstate->chal_transmits = 0;
|
mbed714 |
0:d616ece2d859
|
798
|
|
mbed714 |
0:d616ece2d859
|
799
|
/* generate a random string */
|
mbed714 |
0:d616ece2d859
|
800
|
for (i = 0; i < chal_len; i++ ) {
|
mbed714 |
0:d616ece2d859
|
801
|
*ptr++ = (char) (magic() & 0xff);
|
mbed714 |
0:d616ece2d859
|
802
|
}
|
mbed714 |
0:d616ece2d859
|
803
|
}
|
mbed714 |
0:d616ece2d859
|
804
|
|
mbed714 |
0:d616ece2d859
|
805
|
/*
|
mbed714 |
0:d616ece2d859
|
806
|
* ChapSendResponse - send a response packet with values as specified
|
mbed714 |
0:d616ece2d859
|
807
|
* in *cstate.
|
mbed714 |
0:d616ece2d859
|
808
|
*/
|
mbed714 |
0:d616ece2d859
|
809
|
/* ARGSUSED */
|
mbed714 |
0:d616ece2d859
|
810
|
static void
|
mbed714 |
0:d616ece2d859
|
811
|
ChapSendResponse(chap_state *cstate)
|
mbed714 |
0:d616ece2d859
|
812
|
{
|
mbed714 |
0:d616ece2d859
|
813
|
u_char *outp;
|
mbed714 |
0:d616ece2d859
|
814
|
int outlen, md_len, name_len;
|
mbed714 |
0:d616ece2d859
|
815
|
|
mbed714 |
0:d616ece2d859
|
816
|
md_len = cstate->resp_length;
|
mbed714 |
0:d616ece2d859
|
817
|
name_len = (int)strlen(cstate->resp_name);
|
mbed714 |
0:d616ece2d859
|
818
|
outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
|
mbed714 |
0:d616ece2d859
|
819
|
outp = outpacket_buf[cstate->unit];
|
mbed714 |
0:d616ece2d859
|
820
|
|
mbed714 |
0:d616ece2d859
|
821
|
MAKEHEADER(outp, PPP_CHAP);
|
mbed714 |
0:d616ece2d859
|
822
|
|
mbed714 |
0:d616ece2d859
|
823
|
PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */
|
mbed714 |
0:d616ece2d859
|
824
|
PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */
|
mbed714 |
0:d616ece2d859
|
825
|
PUTSHORT(outlen, outp); /* packet length */
|
mbed714 |
0:d616ece2d859
|
826
|
|
mbed714 |
0:d616ece2d859
|
827
|
PUTCHAR(md_len, outp); /* length of MD */
|
mbed714 |
0:d616ece2d859
|
828
|
BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */
|
mbed714 |
0:d616ece2d859
|
829
|
INCPTR(md_len, outp);
|
mbed714 |
0:d616ece2d859
|
830
|
|
mbed714 |
0:d616ece2d859
|
831
|
BCOPY(cstate->resp_name, outp, name_len); /* append our name */
|
mbed714 |
0:d616ece2d859
|
832
|
|
mbed714 |
0:d616ece2d859
|
833
|
/* send the packet */
|
mbed714 |
0:d616ece2d859
|
834
|
pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
|
mbed714 |
0:d616ece2d859
|
835
|
|
mbed714 |
0:d616ece2d859
|
836
|
cstate->clientstate = CHAPCS_RESPONSE;
|
mbed714 |
0:d616ece2d859
|
837
|
TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);
|
mbed714 |
0:d616ece2d859
|
838
|
++cstate->resp_transmits;
|
mbed714 |
0:d616ece2d859
|
839
|
}
|
mbed714 |
0:d616ece2d859
|
840
|
|
mbed714 |
0:d616ece2d859
|
841
|
#if PPP_ADDITIONAL_CALLBACKS
|
mbed714 |
0:d616ece2d859
|
842
|
static char *ChapCodenames[] = {
|
mbed714 |
0:d616ece2d859
|
843
|
"Challenge", "Response", "Success", "Failure"
|
mbed714 |
0:d616ece2d859
|
844
|
};
|
mbed714 |
0:d616ece2d859
|
845
|
/*
|
mbed714 |
0:d616ece2d859
|
846
|
* ChapPrintPkt - print the contents of a CHAP packet.
|
mbed714 |
0:d616ece2d859
|
847
|
*/
|
mbed714 |
0:d616ece2d859
|
848
|
static int
|
mbed714 |
0:d616ece2d859
|
849
|
ChapPrintPkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg)
|
mbed714 |
0:d616ece2d859
|
850
|
{
|
mbed714 |
0:d616ece2d859
|
851
|
int code, id, len;
|
mbed714 |
0:d616ece2d859
|
852
|
int clen, nlen;
|
mbed714 |
0:d616ece2d859
|
853
|
u_char x;
|
mbed714 |
0:d616ece2d859
|
854
|
|
mbed714 |
0:d616ece2d859
|
855
|
if (plen < CHAP_HEADERLEN) {
|
mbed714 |
0:d616ece2d859
|
856
|
return 0;
|
mbed714 |
0:d616ece2d859
|
857
|
}
|
mbed714 |
0:d616ece2d859
|
858
|
GETCHAR(code, p);
|
mbed714 |
0:d616ece2d859
|
859
|
GETCHAR(id, p);
|
mbed714 |
0:d616ece2d859
|
860
|
GETSHORT(len, p);
|
mbed714 |
0:d616ece2d859
|
861
|
if (len < CHAP_HEADERLEN || len > plen) {
|
mbed714 |
0:d616ece2d859
|
862
|
return 0;
|
mbed714 |
0:d616ece2d859
|
863
|
}
|
mbed714 |
0:d616ece2d859
|
864
|
|
mbed714 |
0:d616ece2d859
|
865
|
if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) {
|
mbed714 |
0:d616ece2d859
|
866
|
printer(arg, " %s", ChapCodenames[code-1]);
|
mbed714 |
0:d616ece2d859
|
867
|
} else {
|
mbed714 |
0:d616ece2d859
|
868
|
printer(arg, " code=0x%x", code);
|
mbed714 |
0:d616ece2d859
|
869
|
}
|
mbed714 |
0:d616ece2d859
|
870
|
printer(arg, " id=0x%x", id);
|
mbed714 |
0:d616ece2d859
|
871
|
len -= CHAP_HEADERLEN;
|
mbed714 |
0:d616ece2d859
|
872
|
switch (code) {
|
mbed714 |
0:d616ece2d859
|
873
|
case CHAP_CHALLENGE:
|
mbed714 |
0:d616ece2d859
|
874
|
case CHAP_RESPONSE:
|
mbed714 |
0:d616ece2d859
|
875
|
if (len < 1) {
|
mbed714 |
0:d616ece2d859
|
876
|
break;
|
mbed714 |
0:d616ece2d859
|
877
|
}
|
mbed714 |
0:d616ece2d859
|
878
|
clen = p[0];
|
mbed714 |
0:d616ece2d859
|
879
|
if (len < clen + 1) {
|
mbed714 |
0:d616ece2d859
|
880
|
break;
|
mbed714 |
0:d616ece2d859
|
881
|
}
|
mbed714 |
0:d616ece2d859
|
882
|
++p;
|
mbed714 |
0:d616ece2d859
|
883
|
nlen = len - clen - 1;
|
mbed714 |
0:d616ece2d859
|
884
|
printer(arg, " <");
|
mbed714 |
0:d616ece2d859
|
885
|
for (; clen > 0; --clen) {
|
mbed714 |
0:d616ece2d859
|
886
|
GETCHAR(x, p);
|
mbed714 |
0:d616ece2d859
|
887
|
printer(arg, "%.2x", x);
|
mbed714 |
0:d616ece2d859
|
888
|
}
|
mbed714 |
0:d616ece2d859
|
889
|
printer(arg, ">, name = %.*Z", nlen, p);
|
mbed714 |
0:d616ece2d859
|
890
|
break;
|
mbed714 |
0:d616ece2d859
|
891
|
case CHAP_FAILURE:
|
mbed714 |
0:d616ece2d859
|
892
|
case CHAP_SUCCESS:
|
mbed714 |
0:d616ece2d859
|
893
|
printer(arg, " %.*Z", len, p);
|
mbed714 |
0:d616ece2d859
|
894
|
break;
|
mbed714 |
0:d616ece2d859
|
895
|
default:
|
mbed714 |
0:d616ece2d859
|
896
|
for (clen = len; clen > 0; --clen) {
|
mbed714 |
0:d616ece2d859
|
897
|
GETCHAR(x, p);
|
mbed714 |
0:d616ece2d859
|
898
|
printer(arg, " %.2x", x);
|
mbed714 |
0:d616ece2d859
|
899
|
}
|
mbed714 |
0:d616ece2d859
|
900
|
}
|
mbed714 |
0:d616ece2d859
|
901
|
|
mbed714 |
0:d616ece2d859
|
902
|
return len + CHAP_HEADERLEN;
|
mbed714 |
0:d616ece2d859
|
903
|
}
|
mbed714 |
0:d616ece2d859
|
904
|
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
mbed714 |
0:d616ece2d859
|
905
|
|
mbed714 |
0:d616ece2d859
|
906
|
#endif /* CHAP_SUPPORT */
|
mbed714 |
0:d616ece2d859
|
907
|
|
mbed714 |
0:d616ece2d859
|
908
|
#endif /* PPP_SUPPORT */
|