OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [ethernet/] [lwIP/] [netif/] [ppp/] [pap.c] - Blame information for rev 606

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 606 jeremybenn
/*****************************************************************************
2
* pap.c - Network Password Authentication Protocol program file.
3
*
4
* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
5
* portions Copyright (c) 1997 by Global Election Systems Inc.
6
*
7
* The authors hereby grant permission to use, copy, modify, distribute,
8
* and license this software and its documentation for any purpose, provided
9
* that existing copyright notices are retained in all copies and that this
10
* notice and the following disclaimer are included verbatim in any
11
* distributions. No written agreement, license, or royalty fee is required
12
* for any of the authorized uses.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
15
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
*
25
******************************************************************************
26
* REVISION HISTORY
27
*
28
* 03-01-01 Marc Boucher <marc@mbsi.ca>
29
*   Ported to lwIP.
30
* 97-12-12 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
31
*       Original.
32
*****************************************************************************/
33
/*
34
 * upap.c - User/Password Authentication Protocol.
35
 *
36
 * Copyright (c) 1989 Carnegie Mellon University.
37
 * All rights reserved.
38
 *
39
 * Redistribution and use in source and binary forms are permitted
40
 * provided that the above copyright notice and this paragraph are
41
 * duplicated in all such forms and that any documentation,
42
 * advertising materials, and other materials related to such
43
 * distribution and use acknowledge that the software was developed
44
 * by Carnegie Mellon University.  The name of the
45
 * University may not be used to endorse or promote products derived
46
 * from this software without specific prior written permission.
47
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
48
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
49
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
50
 */
51
 
52
#include "ppp.h"
53
#include "auth.h"
54
#include "pap.h"
55
#include "pppdebug.h"
56
 
57
 
58
#if PAP_SUPPORT > 0
59
 
60
/***********************************/
61
/*** LOCAL FUNCTION DECLARATIONS ***/
62
/***********************************/
63
/*
64
 * Protocol entry points.
65
 */
66
static void upap_init (int);
67
static void upap_lowerup (int);
68
static void upap_lowerdown (int);
69
static void upap_input (int, u_char *, int);
70
static void upap_protrej (int);
71
 
72
static void upap_timeout (void *);
73
static void upap_reqtimeout (void *);
74
static void upap_rauthreq (upap_state *, u_char *, int, int);
75
static void upap_rauthack (upap_state *, u_char *, int, int);
76
static void upap_rauthnak (upap_state *, u_char *, int, int);
77
static void upap_sauthreq (upap_state *);
78
static void upap_sresp (upap_state *, u_char, u_char, char *, int);
79
 
80
 
81
 
82
 
83
/******************************/
84
/*** PUBLIC DATA STRUCTURES ***/
85
/******************************/
86
struct protent pap_protent = {
87
    PPP_PAP,
88
    upap_init,
89
    upap_input,
90
    upap_protrej,
91
    upap_lowerup,
92
    upap_lowerdown,
93
    NULL,
94
    NULL,
95
#if 0
96
    upap_printpkt,
97
    NULL,
98
#endif
99
    1,
100
    "PAP",
101
#if 0
102
    NULL,
103
    NULL,
104
    NULL
105
#endif
106
};
107
 
108
upap_state upap[NUM_PPP];               /* UPAP state; one for each unit */
109
 
110
 
111
 
112
/***********************************/
113
/*** PUBLIC FUNCTION DEFINITIONS ***/
114
/***********************************/
115
/*
116
 *  Set the default login name and password for the pap sessions
117
 */
118
void upap_setloginpasswd(int unit, const char *luser, const char *lpassword)
119
{
120
        upap_state *u = &upap[unit];
121
 
122
        /* Save the username and password we're given */
123
        u->us_user = luser;
124
        u->us_userlen = strlen(luser);
125
        u->us_passwd = lpassword;
126
        u->us_passwdlen = strlen(lpassword);
127
}
128
 
129
 
130
/*
131
 * upap_authwithpeer - Authenticate us with our peer (start client).
132
 *
133
 * Set new state and send authenticate's.
134
 */
135
void upap_authwithpeer(int unit, char *user, char *password)
136
{
137
        upap_state *u = &upap[unit];
138
 
139
        UPAPDEBUG((LOG_INFO, "upap_authwithpeer: %d user=%s password=%s s=%d\n",
140
                                unit, user, password, u->us_clientstate));
141
 
142
        upap_setloginpasswd(unit, user, password);
143
 
144
        u->us_transmits = 0;
145
 
146
        /* Lower layer up yet? */
147
        if (u->us_clientstate == UPAPCS_INITIAL ||
148
                        u->us_clientstate == UPAPCS_PENDING) {
149
                u->us_clientstate = UPAPCS_PENDING;
150
                return;
151
        }
152
 
153
        upap_sauthreq(u);                       /* Start protocol */
154
}
155
 
156
 
157
/*
158
 * upap_authpeer - Authenticate our peer (start server).
159
 *
160
 * Set new state.
161
 */
162
void upap_authpeer(int unit)
163
{
164
        upap_state *u = &upap[unit];
165
 
166
        /* Lower layer up yet? */
167
        if (u->us_serverstate == UPAPSS_INITIAL ||
168
                        u->us_serverstate == UPAPSS_PENDING) {
169
                u->us_serverstate = UPAPSS_PENDING;
170
                return;
171
        }
172
 
173
        u->us_serverstate = UPAPSS_LISTEN;
174
        if (u->us_reqtimeout > 0)
175
                TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
176
}
177
 
178
 
179
 
180
/**********************************/
181
/*** LOCAL FUNCTION DEFINITIONS ***/
182
/**********************************/
183
/*
184
 * upap_init - Initialize a UPAP unit.
185
 */
186
static void upap_init(int unit)
187
{
188
        upap_state *u = &upap[unit];
189
 
190
        UPAPDEBUG((LOG_INFO, "upap_init: %d\n", unit));
191
        u->us_unit = unit;
192
        u->us_user = NULL;
193
        u->us_userlen = 0;
194
        u->us_passwd = NULL;
195
        u->us_passwdlen = 0;
196
        u->us_clientstate = UPAPCS_INITIAL;
197
        u->us_serverstate = UPAPSS_INITIAL;
198
        u->us_id = 0;
199
        u->us_timeouttime = UPAP_DEFTIMEOUT;
200
        u->us_maxtransmits = 10;
201
        u->us_reqtimeout = UPAP_DEFREQTIME;
202
}
203
 
204
/*
205
 * upap_timeout - Retransmission timer for sending auth-reqs expired.
206
 */
207
static void upap_timeout(void *arg)
208
{
209
        upap_state *u = (upap_state *) arg;
210
 
211
        UPAPDEBUG((LOG_INFO, "upap_timeout: %d timeout %d expired s=%d\n",
212
                                u->us_unit, u->us_timeouttime, u->us_clientstate));
213
 
214
        if (u->us_clientstate != UPAPCS_AUTHREQ)
215
                return;
216
 
217
        if (u->us_transmits >= u->us_maxtransmits) {
218
                /* give up in disgust */
219
                UPAPDEBUG((LOG_ERR, "No response to PAP authenticate-requests\n"));
220
                u->us_clientstate = UPAPCS_BADAUTH;
221
                auth_withpeer_fail(u->us_unit, PPP_PAP);
222
                return;
223
        }
224
 
225
        upap_sauthreq(u);               /* Send Authenticate-Request */
226
}
227
 
228
 
229
/*
230
 * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
231
 */
232
static void upap_reqtimeout(void *arg)
233
{
234
        upap_state *u = (upap_state *) arg;
235
 
236
        if (u->us_serverstate != UPAPSS_LISTEN)
237
                return;                 /* huh?? */
238
 
239
        auth_peer_fail(u->us_unit, PPP_PAP);
240
        u->us_serverstate = UPAPSS_BADAUTH;
241
}
242
 
243
 
244
/*
245
 * upap_lowerup - The lower layer is up.
246
 *
247
 * Start authenticating if pending.
248
 */
249
static void upap_lowerup(int unit)
250
{
251
        upap_state *u = &upap[unit];
252
 
253
        UPAPDEBUG((LOG_INFO, "upap_lowerup: %d s=%d\n", unit, u->us_clientstate));
254
 
255
        if (u->us_clientstate == UPAPCS_INITIAL)
256
                u->us_clientstate = UPAPCS_CLOSED;
257
        else if (u->us_clientstate == UPAPCS_PENDING) {
258
                upap_sauthreq(u);       /* send an auth-request */
259
        }
260
 
261
        if (u->us_serverstate == UPAPSS_INITIAL)
262
                u->us_serverstate = UPAPSS_CLOSED;
263
        else if (u->us_serverstate == UPAPSS_PENDING) {
264
                u->us_serverstate = UPAPSS_LISTEN;
265
                if (u->us_reqtimeout > 0)
266
                        TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
267
        }
268
}
269
 
270
 
271
/*
272
 * upap_lowerdown - The lower layer is down.
273
 *
274
 * Cancel all timeouts.
275
 */
276
static void upap_lowerdown(int unit)
277
{
278
        upap_state *u = &upap[unit];
279
 
280
        UPAPDEBUG((LOG_INFO, "upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
281
 
282
        if (u->us_clientstate == UPAPCS_AUTHREQ)        /* Timeout pending? */
283
                UNTIMEOUT(upap_timeout, u);             /* Cancel timeout */
284
        if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)
285
                UNTIMEOUT(upap_reqtimeout, u);
286
 
287
        u->us_clientstate = UPAPCS_INITIAL;
288
        u->us_serverstate = UPAPSS_INITIAL;
289
}
290
 
291
 
292
/*
293
 * upap_protrej - Peer doesn't speak this protocol.
294
 *
295
 * This shouldn't happen.  In any case, pretend lower layer went down.
296
 */
297
static void upap_protrej(int unit)
298
{
299
        upap_state *u = &upap[unit];
300
 
301
        if (u->us_clientstate == UPAPCS_AUTHREQ) {
302
                UPAPDEBUG((LOG_ERR, "PAP authentication failed due to protocol-reject\n"));
303
                auth_withpeer_fail(unit, PPP_PAP);
304
        }
305
        if (u->us_serverstate == UPAPSS_LISTEN) {
306
                UPAPDEBUG((LOG_ERR, "PAP authentication of peer failed (protocol-reject)\n"));
307
                auth_peer_fail(unit, PPP_PAP);
308
        }
309
        upap_lowerdown(unit);
310
}
311
 
312
 
313
/*
314
 * upap_input - Input UPAP packet.
315
 */
316
static void upap_input(int unit, u_char *inpacket, int l)
317
{
318
        upap_state *u = &upap[unit];
319
        u_char *inp;
320
        u_char code, id;
321
        int len;
322
 
323
        /*
324
         * Parse header (code, id and length).
325
         * If packet too short, drop it.
326
         */
327
        inp = inpacket;
328
        if (l < UPAP_HEADERLEN) {
329
                UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header.\n"));
330
                return;
331
        }
332
        GETCHAR(code, inp);
333
        GETCHAR(id, inp);
334
        GETSHORT(len, inp);
335
        if (len < UPAP_HEADERLEN) {
336
                UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length.\n"));
337
                return;
338
        }
339
        if (len > l) {
340
                UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet.\n"));
341
                return;
342
        }
343
        len -= UPAP_HEADERLEN;
344
 
345
        /*
346
         * Action depends on code.
347
         */
348
        switch (code) {
349
        case UPAP_AUTHREQ:
350
                upap_rauthreq(u, inp, id, len);
351
                break;
352
 
353
        case UPAP_AUTHACK:
354
                upap_rauthack(u, inp, id, len);
355
                break;
356
 
357
        case UPAP_AUTHNAK:
358
                upap_rauthnak(u, inp, id, len);
359
                break;
360
 
361
        default:                                /* XXX Need code reject */
362
                break;
363
        }
364
}
365
 
366
 
367
/*
368
 * upap_rauth - Receive Authenticate.
369
 */
370
static void upap_rauthreq(
371
        upap_state *u,
372
        u_char *inp,
373
        int id,
374
        int len
375
)
376
{
377
        u_char ruserlen, rpasswdlen;
378
        char *ruser, *rpasswd;
379
        int retcode;
380
        char *msg;
381
        int msglen;
382
 
383
        UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.\n", id));
384
 
385
        if (u->us_serverstate < UPAPSS_LISTEN)
386
                return;
387
 
388
        /*
389
         * If we receive a duplicate authenticate-request, we are
390
         * supposed to return the same status as for the first request.
391
         */
392
        if (u->us_serverstate == UPAPSS_OPEN) {
393
                upap_sresp(u, UPAP_AUTHACK, id, "", 0);  /* return auth-ack */
394
                return;
395
        }
396
        if (u->us_serverstate == UPAPSS_BADAUTH) {
397
                upap_sresp(u, UPAP_AUTHNAK, id, "", 0);  /* return auth-nak */
398
                return;
399
        }
400
 
401
        /*
402
         * Parse user/passwd.
403
         */
404
        if (len < sizeof (u_char)) {
405
                UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
406
                return;
407
        }
408
        GETCHAR(ruserlen, inp);
409
        len -= sizeof (u_char) + ruserlen + sizeof (u_char);
410
        if (len < 0) {
411
                UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
412
                return;
413
        }
414
        ruser = (char *) inp;
415
        INCPTR(ruserlen, inp);
416
        GETCHAR(rpasswdlen, inp);
417
        if (len < rpasswdlen) {
418
                UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
419
                return;
420
        }
421
        rpasswd = (char *) inp;
422
 
423
        /*
424
         * Check the username and password given.
425
         */
426
        retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,
427
                           rpasswdlen, &msg, &msglen);
428
        BZERO(rpasswd, rpasswdlen);
429
 
430
        upap_sresp(u, retcode, id, msg, msglen);
431
 
432
        if (retcode == UPAP_AUTHACK) {
433
                u->us_serverstate = UPAPSS_OPEN;
434
                auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
435
        } else {
436
                u->us_serverstate = UPAPSS_BADAUTH;
437
                auth_peer_fail(u->us_unit, PPP_PAP);
438
        }
439
 
440
        if (u->us_reqtimeout > 0)
441
                UNTIMEOUT(upap_reqtimeout, u);
442
}
443
 
444
 
445
/*
446
 * upap_rauthack - Receive Authenticate-Ack.
447
 */
448
static void upap_rauthack(
449
        upap_state *u,
450
        u_char *inp,
451
        int id,
452
        int len
453
)
454
{
455
        u_char msglen;
456
        char *msg;
457
 
458
        UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
459
 
460
        if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
461
                return;
462
 
463
        /*
464
         * Parse message.
465
         */
466
        if (len < sizeof (u_char)) {
467
                UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));
468
                return;
469
        }
470
        GETCHAR(msglen, inp);
471
        len -= sizeof (u_char);
472
        if (len < msglen) {
473
                UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));
474
                return;
475
        }
476
        msg = (char *) inp;
477
        PRINTMSG(msg, msglen);
478
 
479
        u->us_clientstate = UPAPCS_OPEN;
480
 
481
        auth_withpeer_success(u->us_unit, PPP_PAP);
482
}
483
 
484
 
485
/*
486
 * upap_rauthnak - Receive Authenticate-Nakk.
487
 */
488
static void upap_rauthnak(
489
        upap_state *u,
490
        u_char *inp,
491
        int id,
492
        int len
493
)
494
{
495
        u_char msglen;
496
        char *msg;
497
 
498
        UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
499
 
500
        if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
501
                return;
502
 
503
        /*
504
         * Parse message.
505
         */
506
        if (len < sizeof (u_char)) {
507
                UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));
508
                return;
509
        }
510
        GETCHAR(msglen, inp);
511
        len -= sizeof (u_char);
512
        if (len < msglen) {
513
                UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));
514
                return;
515
        }
516
        msg = (char *) inp;
517
        PRINTMSG(msg, msglen);
518
 
519
        u->us_clientstate = UPAPCS_BADAUTH;
520
 
521
        UPAPDEBUG((LOG_ERR, "PAP authentication failed\n"));
522
        auth_withpeer_fail(u->us_unit, PPP_PAP);
523
}
524
 
525
 
526
/*
527
 * upap_sauthreq - Send an Authenticate-Request.
528
 */
529
static void upap_sauthreq(upap_state *u)
530
{
531
        u_char *outp;
532
        int outlen;
533
 
534
        outlen = UPAP_HEADERLEN + 2 * sizeof (u_char)
535
                        + u->us_userlen + u->us_passwdlen;
536
        outp = outpacket_buf[u->us_unit];
537
 
538
        MAKEHEADER(outp, PPP_PAP);
539
 
540
        PUTCHAR(UPAP_AUTHREQ, outp);
541
        PUTCHAR(++u->us_id, outp);
542
        PUTSHORT(outlen, outp);
543
        PUTCHAR(u->us_userlen, outp);
544
        BCOPY(u->us_user, outp, u->us_userlen);
545
        INCPTR(u->us_userlen, outp);
546
        PUTCHAR(u->us_passwdlen, outp);
547
        BCOPY(u->us_passwd, outp, u->us_passwdlen);
548
 
549
        pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
550
 
551
        UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d\n", u->us_id));
552
 
553
        TIMEOUT(upap_timeout, u, u->us_timeouttime);
554
        ++u->us_transmits;
555
        u->us_clientstate = UPAPCS_AUTHREQ;
556
}
557
 
558
 
559
/*
560
 * upap_sresp - Send a response (ack or nak).
561
 */
562
static void upap_sresp(
563
        upap_state *u,
564
        u_char code,
565
        u_char id,
566
        char *msg,
567
        int msglen
568
)
569
{
570
        u_char *outp;
571
        int outlen;
572
 
573
        outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
574
        outp = outpacket_buf[u->us_unit];
575
        MAKEHEADER(outp, PPP_PAP);
576
 
577
        PUTCHAR(code, outp);
578
        PUTCHAR(id, outp);
579
        PUTSHORT(outlen, outp);
580
        PUTCHAR(msglen, outp);
581
        BCOPY(msg, outp, msglen);
582
        pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
583
 
584
        UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d s=%d\n",
585
                                code, id, u->us_clientstate));
586
}
587
 
588
#if 0
589
/*
590
 * upap_printpkt - print the contents of a PAP packet.
591
 */
592
static int upap_printpkt(
593
        u_char *p,
594
        int plen,
595
        void (*printer) (void *, char *, ...),
596
        void *arg
597
)
598
{
599
        (void)p;
600
        (void)plen;
601
        (void)printer;
602
        (void)arg;
603
        return 0;
604
}
605
#endif
606
 
607
#endif /* PAP_SUPPORT */
608
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.