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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [lwip_tcpip/] [current/] [src/] [netif/] [ppp/] [pap.c] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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