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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [ppp/] [current/] [src/] [upap.c] - Blame information for rev 868

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      src/upap.c
4
//
5
//==========================================================================
6
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
7
// -------------------------------------------                              
8
// This file is part of eCos, the Embedded Configurable Operating System.   
9
// Copyright (C) 2003 Free Software Foundation, Inc.                        
10
//
11
// eCos is free software; you can redistribute it and/or modify it under    
12
// the terms of the GNU General Public License as published by the Free     
13
// Software Foundation; either version 2 or (at your option) any later      
14
// version.                                                                 
15
//
16
// eCos is distributed in the hope that it will be useful, but WITHOUT      
17
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
18
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
19
// for more details.                                                        
20
//
21
// You should have received a copy of the GNU General Public License        
22
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
23
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
24
//
25
// As a special exception, if other files instantiate templates or use      
26
// macros or inline functions from this file, or you compile this file      
27
// and link it with other works to produce a work based on this file,       
28
// this file does not by itself cause the resulting work to be covered by   
29
// the GNU General Public License. However the source code for this file    
30
// must still be made available in accordance with section (3) of the GNU   
31
// General Public License v2.                                               
32
//
33
// This exception does not invalidate any other reasons why a work based    
34
// on this file might be covered by the GNU General Public License.         
35
// -------------------------------------------                              
36
// ####ECOSGPLCOPYRIGHTEND####                                              
37
// ####BSDALTCOPYRIGHTBEGIN####                                             
38
// -------------------------------------------                              
39
// Portions of this software may have been derived from FreeBSD, OpenBSD,   
40
// or other sources, and if so are covered by the appropriate copyright     
41
// and license included herein.                                             
42
// -------------------------------------------                              
43
// ####BSDALTCOPYRIGHTEND####                                               
44
//==========================================================================
45
 
46
/*
47
 * upap.c - User/Password Authentication Protocol.
48
 *
49
 * Copyright (c) 1989 Carnegie Mellon University.
50
 * All rights reserved.
51
 *
52
 * Redistribution and use in source and binary forms are permitted
53
 * provided that the above copyright notice and this paragraph are
54
 * duplicated in all such forms and that any documentation,
55
 * advertising materials, and other materials related to such
56
 * distribution and use acknowledge that the software was developed
57
 * by Carnegie Mellon University.  The name of the
58
 * University may not be used to endorse or promote products derived
59
 * from this software without specific prior written permission.
60
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
61
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
62
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
63
 */
64
 
65
#ifndef lint
66
//static char rcsid[] = "$FreeBSD: src/usr.sbin/pppd/upap.c,v 1.8 1999/08/28 01:19:08 peter Exp $";
67
#endif
68
 
69
/*
70
 * TODO:
71
 */
72
 
73
#include <stdio.h>
74
#include <string.h>
75
#include <sys/types.h>
76
#include <sys/time.h>
77
#include <cyg/ppp/syslog.h>
78
#include "cyg/ppp/pppd.h"
79
#include "cyg/ppp/upap.h"
80
 
81
/*
82
 * Protocol entry points.
83
 */
84
static void upap_init __P((int));
85
static void upap_lowerup __P((int));
86
static void upap_lowerdown __P((int));
87
static void upap_input __P((int, u_char *, int));
88
static void upap_protrej __P((int));
89
static int  upap_printpkt __P((u_char *, int,
90
                               void (*) __P((void *, char *, ...)), void *));
91
 
92
struct protent pap_protent = {
93
    PPP_PAP,
94
    upap_init,
95
    upap_input,
96
    upap_protrej,
97
    upap_lowerup,
98
    upap_lowerdown,
99
    NULL,
100
    NULL,
101
    upap_printpkt,
102
    NULL,
103
    1,
104
    "PAP",
105
    NULL,
106
    NULL,
107
    NULL
108
};
109
 
110
upap_state upap[NUM_PPP];               /* UPAP state; one for each unit */
111
 
112
static void upap_timeout __P((void *));
113
static void upap_reqtimeout __P((void *));
114
static void upap_rauthreq __P((upap_state *, u_char *, int, int));
115
static void upap_rauthack __P((upap_state *, u_char *, int, int));
116
static void upap_rauthnak __P((upap_state *, u_char *, int, int));
117
static void upap_sauthreq __P((upap_state *));
118
static void upap_sresp __P((upap_state *, int, int, char *, int));
119
 
120
 
121
/*
122
 * upap_init - Initialize a UPAP unit.
123
 */
124
static void
125
upap_init(unit)
126
    int unit;
127
{
128
    upap_state *u = &upap[unit];
129
 
130
    u->us_unit = unit;
131
    u->us_user = NULL;
132
    u->us_userlen = 0;
133
    u->us_passwd = NULL;
134
    u->us_passwdlen = 0;
135
    u->us_clientstate = UPAPCS_INITIAL;
136
    u->us_serverstate = UPAPSS_INITIAL;
137
    u->us_id = 0;
138
    u->us_timeouttime = UPAP_DEFTIMEOUT;
139
    u->us_maxtransmits = 10;
140
    u->us_reqtimeout = UPAP_DEFREQTIME;
141
}
142
 
143
 
144
/*
145
 * upap_authwithpeer - Authenticate us with our peer (start client).
146
 *
147
 * Set new state and send authenticate's.
148
 */
149
void
150
upap_authwithpeer(unit, user, password)
151
    int unit;
152
    char *user, *password;
153
{
154
    upap_state *u = &upap[unit];
155
 
156
    /* Save the username and password we're given */
157
    u->us_user = user;
158
    u->us_userlen = strlen(user);
159
    u->us_passwd = password;
160
    u->us_passwdlen = strlen(password);
161
    u->us_transmits = 0;
162
 
163
    /* Lower layer up yet? */
164
    if (u->us_clientstate == UPAPCS_INITIAL ||
165
        u->us_clientstate == UPAPCS_PENDING) {
166
        u->us_clientstate = UPAPCS_PENDING;
167
        return;
168
    }
169
 
170
    upap_sauthreq(u);                   /* Start protocol */
171
}
172
 
173
 
174
/*
175
 * upap_authpeer - Authenticate our peer (start server).
176
 *
177
 * Set new state.
178
 */
179
void
180
upap_authpeer(unit)
181
    int unit;
182
{
183
    upap_state *u = &upap[unit];
184
 
185
    /* Lower layer up yet? */
186
    if (u->us_serverstate == UPAPSS_INITIAL ||
187
        u->us_serverstate == UPAPSS_PENDING) {
188
        u->us_serverstate = UPAPSS_PENDING;
189
        return;
190
    }
191
 
192
    u->us_serverstate = UPAPSS_LISTEN;
193
    if (u->us_reqtimeout > 0)
194
        TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
195
}
196
 
197
 
198
/*
199
 * upap_timeout - Retransmission timer for sending auth-reqs expired.
200
 */
201
static void
202
upap_timeout(arg)
203
    void *arg;
204
{
205
    upap_state *u = (upap_state *) arg;
206
 
207
    if (u->us_clientstate != UPAPCS_AUTHREQ)
208
        return;
209
 
210
    if (u->us_transmits >= u->us_maxtransmits) {
211
        /* give up in disgust */
212
        syslog(LOG_ERR, "No response to PAP authenticate-requests");
213
        u->us_clientstate = UPAPCS_BADAUTH;
214
        auth_withpeer_fail(u->us_unit, PPP_PAP);
215
        return;
216
    }
217
 
218
    upap_sauthreq(u);           /* Send Authenticate-Request */
219
}
220
 
221
 
222
/*
223
 * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
224
 */
225
static void
226
upap_reqtimeout(arg)
227
    void *arg;
228
{
229
    upap_state *u = (upap_state *) arg;
230
 
231
    if (u->us_serverstate != UPAPSS_LISTEN)
232
        return;                 /* huh?? */
233
 
234
    auth_peer_fail(u->us_unit, PPP_PAP);
235
    u->us_serverstate = UPAPSS_BADAUTH;
236
}
237
 
238
 
239
/*
240
 * upap_lowerup - The lower layer is up.
241
 *
242
 * Start authenticating if pending.
243
 */
244
static void
245
upap_lowerup(unit)
246
    int unit;
247
{
248
    upap_state *u = &upap[unit];
249
 
250
    if (u->us_clientstate == UPAPCS_INITIAL)
251
        u->us_clientstate = UPAPCS_CLOSED;
252
    else if (u->us_clientstate == UPAPCS_PENDING) {
253
        upap_sauthreq(u);       /* send an auth-request */
254
    }
255
 
256
    if (u->us_serverstate == UPAPSS_INITIAL)
257
        u->us_serverstate = UPAPSS_CLOSED;
258
    else if (u->us_serverstate == UPAPSS_PENDING) {
259
        u->us_serverstate = UPAPSS_LISTEN;
260
        if (u->us_reqtimeout > 0)
261
            TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
262
    }
263
}
264
 
265
 
266
/*
267
 * upap_lowerdown - The lower layer is down.
268
 *
269
 * Cancel all timeouts.
270
 */
271
static void
272
upap_lowerdown(unit)
273
    int unit;
274
{
275
    upap_state *u = &upap[unit];
276
 
277
    if (u->us_clientstate == UPAPCS_AUTHREQ)    /* Timeout pending? */
278
        UNTIMEOUT(upap_timeout, u);             /* Cancel timeout */
279
    if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)
280
        UNTIMEOUT(upap_reqtimeout, u);
281
 
282
    u->us_clientstate = UPAPCS_INITIAL;
283
    u->us_serverstate = UPAPSS_INITIAL;
284
}
285
 
286
 
287
/*
288
 * upap_protrej - Peer doesn't speak this protocol.
289
 *
290
 * This shouldn't happen.  In any case, pretend lower layer went down.
291
 */
292
static void
293
upap_protrej(unit)
294
    int unit;
295
{
296
    upap_state *u = &upap[unit];
297
 
298
    if (u->us_clientstate == UPAPCS_AUTHREQ) {
299
        syslog(LOG_ERR, "PAP authentication failed due to protocol-reject");
300
        auth_withpeer_fail(unit, PPP_PAP);
301
    }
302
    if (u->us_serverstate == UPAPSS_LISTEN) {
303
        syslog(LOG_ERR, "PAP authentication of peer failed (protocol-reject)");
304
        auth_peer_fail(unit, PPP_PAP);
305
    }
306
    upap_lowerdown(unit);
307
}
308
 
309
 
310
/*
311
 * upap_input - Input UPAP packet.
312
 */
313
static void
314
upap_input(unit, inpacket, l)
315
    int unit;
316
    u_char *inpacket;
317
    int l;
318
{
319
    upap_state *u = &upap[unit];
320
    u_char *inp;
321
    u_char code, id;
322
    int len;
323
 
324
    /*
325
     * Parse header (code, id and length).
326
     * If packet too short, drop it.
327
     */
328
    inp = inpacket;
329
    if (l < UPAP_HEADERLEN) {
330
        UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header."));
331
        return;
332
    }
333
    GETCHAR(code, inp);
334
    GETCHAR(id, inp);
335
    GETSHORT(len, inp);
336
    if (len < UPAP_HEADERLEN) {
337
        UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length."));
338
        return;
339
    }
340
    if (len > l) {
341
        UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet."));
342
        return;
343
    }
344
    len -= UPAP_HEADERLEN;
345
 
346
    /*
347
     * Action depends on code.
348
     */
349
    switch (code) {
350
    case UPAP_AUTHREQ:
351
        upap_rauthreq(u, inp, id, len);
352
        break;
353
 
354
    case UPAP_AUTHACK:
355
        upap_rauthack(u, inp, id, len);
356
        break;
357
 
358
    case UPAP_AUTHNAK:
359
        upap_rauthnak(u, inp, id, len);
360
        break;
361
 
362
    default:                            /* XXX Need code reject */
363
        break;
364
    }
365
}
366
 
367
 
368
/*
369
 * upap_rauth - Receive Authenticate.
370
 */
371
static void
372
upap_rauthreq(u, inp, id, len)
373
    upap_state *u;
374
    u_char *inp;
375
    int id;
376
    int len;
377
{
378
    u_char ruserlen, rpasswdlen;
379
    char *ruser, *rpasswd;
380
    int retcode;
381
    char *msg;
382
    int msglen;
383
 
384
    UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.", id));
385
 
386
    if (u->us_serverstate < UPAPSS_LISTEN)
387
        return;
388
 
389
    /*
390
     * If we receive a duplicate authenticate-request, we are
391
     * supposed to return the same status as for the first request.
392
     */
393
    if (u->us_serverstate == UPAPSS_OPEN) {
394
        upap_sresp(u, UPAP_AUTHACK, id, "", 0);  /* return auth-ack */
395
        return;
396
    }
397
    if (u->us_serverstate == UPAPSS_BADAUTH) {
398
        upap_sresp(u, UPAP_AUTHNAK, id, "", 0);  /* return auth-nak */
399
        return;
400
    }
401
 
402
    /*
403
     * Parse user/passwd.
404
     */
405
    if (len < sizeof (u_char)) {
406
        UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet."));
407
        return;
408
    }
409
    GETCHAR(ruserlen, inp);
410
    len -= sizeof (u_char) + ruserlen + sizeof (u_char);
411
    if (len < 0) {
412
        UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet."));
413
        return;
414
    }
415
    ruser = (char *) inp;
416
    INCPTR(ruserlen, inp);
417
    GETCHAR(rpasswdlen, inp);
418
    if (len < rpasswdlen) {
419
        UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet."));
420
        return;
421
    }
422
    rpasswd = (char *) inp;
423
 
424
    /*
425
     * Check the username and password given.
426
     */
427
    retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,
428
                           rpasswdlen, &msg, &msglen);
429
    BZERO(rpasswd, rpasswdlen);
430
 
431
    upap_sresp(u, retcode, id, msg, msglen);
432
 
433
    if (retcode == UPAP_AUTHACK) {
434
        u->us_serverstate = UPAPSS_OPEN;
435
        auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
436
    } else {
437
        u->us_serverstate = UPAPSS_BADAUTH;
438
        auth_peer_fail(u->us_unit, PPP_PAP);
439
    }
440
 
441
    if (u->us_reqtimeout > 0)
442
        UNTIMEOUT(upap_reqtimeout, u);
443
}
444
 
445
 
446
/*
447
 * upap_rauthack - Receive Authenticate-Ack.
448
 */
449
static void
450
upap_rauthack(u, inp, id, len)
451
    upap_state *u;
452
    u_char *inp;
453
    int id;
454
    int len;
455
{
456
    u_char msglen;
457
    char *msg;
458
 
459
    UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d.", id));
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."));
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."));
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
489
upap_rauthnak(u, inp, id, len)
490
    upap_state *u;
491
    u_char *inp;
492
    int id;
493
    int len;
494
{
495
    u_char msglen;
496
    char *msg;
497
 
498
    UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d.", id));
499
    if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
500
        return;
501
 
502
    /*
503
     * Parse message.
504
     */
505
    if (len < sizeof (u_char)) {
506
        UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet."));
507
        return;
508
    }
509
    GETCHAR(msglen, inp);
510
    len -= sizeof (u_char);
511
    if (len < msglen) {
512
        UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet."));
513
        return;
514
    }
515
    msg = (char *) inp;
516
    PRINTMSG(msg, msglen);
517
 
518
    u->us_clientstate = UPAPCS_BADAUTH;
519
 
520
    syslog(LOG_ERR, "PAP authentication failed");
521
    auth_withpeer_fail(u->us_unit, PPP_PAP);
522
}
523
 
524
 
525
/*
526
 * upap_sauthreq - Send an Authenticate-Request.
527
 */
528
static void
529
upap_sauthreq(u)
530
    upap_state *u;
531
{
532
    u_char *outp;
533
    int outlen;
534
 
535
    outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) +
536
        u->us_userlen + u->us_passwdlen;
537
    outp = outpacket_buf;
538
 
539
    MAKEHEADER(outp, PPP_PAP);
540
 
541
    PUTCHAR(UPAP_AUTHREQ, outp);
542
    PUTCHAR(++u->us_id, outp);
543
    PUTSHORT(outlen, outp);
544
    PUTCHAR(u->us_userlen, outp);
545
    BCOPY(u->us_user, outp, u->us_userlen);
546
    INCPTR(u->us_userlen, outp);
547
    PUTCHAR(u->us_passwdlen, outp);
548
    BCOPY(u->us_passwd, outp, u->us_passwdlen);
549
 
550
    output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
551
 
552
    UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d.", u->us_id));
553
 
554
    TIMEOUT(upap_timeout, u, u->us_timeouttime);
555
    ++u->us_transmits;
556
    u->us_clientstate = UPAPCS_AUTHREQ;
557
}
558
 
559
 
560
/*
561
 * upap_sresp - Send a response (ack or nak).
562
 */
563
static void
564
upap_sresp(u, code, id, msg, msglen)
565
    upap_state *u;
566
    u_char code, id;
567
    char *msg;
568
    int msglen;
569
{
570
    u_char *outp;
571
    int outlen;
572
 
573
    outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
574
    outp = outpacket_buf;
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
    output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
583
 
584
    UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d.", code, id));
585
}
586
 
587
/*
588
 * upap_printpkt - print the contents of a PAP packet.
589
 */
590
static char *upap_codenames[] = {
591
    "AuthReq", "AuthAck", "AuthNak"
592
};
593
 
594
static int
595
upap_printpkt(p, plen, printer, arg)
596
    u_char *p;
597
    int plen;
598
    void (*printer) __P((void *, char *, ...));
599
    void *arg;
600
{
601
    int code, id, len;
602
    int mlen, ulen, wlen;
603
    u_char *user, *pwd, *msg;
604
    u_char *pstart;
605
 
606
    if (plen < UPAP_HEADERLEN)
607
        return 0;
608
    pstart = p;
609
    GETCHAR(code, p);
610
    GETCHAR(id, p);
611
    GETSHORT(len, p);
612
    if (len < UPAP_HEADERLEN || len > plen)
613
        return 0;
614
 
615
    if (code >= 1 && code <= sizeof(upap_codenames) / sizeof(char *))
616
        printer(arg, " %s", upap_codenames[code-1]);
617
    else
618
        printer(arg, " code=0x%x", code);
619
    printer(arg, " id=0x%x", id);
620
    len -= UPAP_HEADERLEN;
621
    switch (code) {
622
    case UPAP_AUTHREQ:
623
        if (len < 1)
624
            break;
625
        ulen = p[0];
626
        if (len < ulen + 2)
627
            break;
628
        wlen = p[ulen + 1];
629
        if (len < ulen + wlen + 2)
630
            break;
631
        user = (p + 1);
632
        pwd =  (p + ulen + 2);
633
        p += ulen + wlen + 2;
634
        len -= ulen + wlen + 2;
635
        printer(arg, " user=");
636
        print_string(user, ulen, printer, arg);
637
        printer(arg, " password=");
638
        print_string(pwd, wlen, printer, arg);
639
        break;
640
    case UPAP_AUTHACK:
641
    case UPAP_AUTHNAK:
642
        if (len < 1)
643
            break;
644
        mlen = p[0];
645
        if (len < mlen + 1)
646
            break;
647
        msg = (p + 1);
648
        p += mlen + 1;
649
        len -= mlen + 1;
650
        printer(arg, " ");
651
        print_string(msg, mlen, printer, arg);
652
        break;
653
    }
654
 
655
    /* print the rest of the bytes in the packet */
656
    for (; len > 0; --len) {
657
        GETCHAR(code, p);
658
        printer(arg, " %.2x", code);
659
    }
660
 
661
    return p - pstart;
662
}

powered by: WebSVN 2.1.0

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