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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libnetworking/] [pppd/] [upap.c] - Blame information for rev 173

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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