pap.c revision 6059
1/*
2 *			PPP PAP Module
3 *
4 *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5 *
6 *   Copyright (C) 1993-94, Internet Initiative Japan, Inc.
7 *		     All rights reserverd.
8 *
9 * Redistribution and use in source and binary forms are permitted
10 * provided that the above copyright notice and this paragraph are
11 * duplicated in all such forms and that any documentation,
12 * advertising materials, and other materials related to such
13 * distribution and use acknowledge that the software was developed
14 * by the Internet Initiative Japan, Inc.  The name of the
15 * IIJ may not be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
19 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * $Id:$
22 *
23 *	TODO:
24 *		o Imprement retransmission timer.
25 */
26#include "fsm.h"
27#include "lcp.h"
28#include "pap.h"
29#include "vars.h"
30#include "hdlc.h"
31#include "lcpproto.h"
32#include "phase.h"
33
34static char *papcodes[] = {
35  "???", "REQUEST", "ACK", "NAK"
36};
37
38static int papid;
39
40void
41SendPapChallenge()
42{
43  struct fsmheader lh;
44  struct mbuf *bp;
45  u_char *cp;
46  int namelen, keylen, plen;
47
48  namelen = strlen(VarAuthName);
49  keylen = strlen(VarAuthKey);
50  plen = namelen + keylen + 2;
51#ifdef DEBUG
52  logprintf("namelen = %d, keylen = %d\n", namelen, keylen);
53  LogPrintf(LOG_PHASE, "PAP: %s (%s)\n", VarAuthName, VarAuthKey);
54#endif
55  lh.code = PAP_REQUEST;
56  lh.id = ++papid;
57  lh.length = htons(plen + sizeof(struct fsmheader));
58  bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
59  bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader));
60  cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
61  *cp++ = namelen;
62  bcopy(VarAuthName, cp, namelen);
63  cp += namelen;
64  *cp++ = keylen;
65  bcopy(VarAuthKey, cp, keylen);
66
67  HdlcOutput(PRI_NORMAL, PROTO_PAP, bp);
68}
69
70static void
71SendPapCode(id, code, message)
72int id;
73char *message;
74int code;
75{
76  struct fsmheader lh;
77  struct mbuf *bp;
78  u_char *cp;
79  int plen, mlen;
80
81  lh.code = code;
82  lh.id = id;
83  mlen = strlen(message);
84  plen = mlen + 1;
85  lh.length = htons(plen + sizeof(struct fsmheader));
86  bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
87  bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader));
88  cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
89  *cp++ = mlen;
90  bcopy(message, cp, mlen);
91  LogPrintf(LOG_PHASE, "PapOutput: %s\n", papcodes[code]);
92  HdlcOutput(PRI_NORMAL, PROTO_PAP, bp);
93}
94
95/*
96 * Validate given username and passwrd against with secret table
97 */
98static int
99PapValidate(name, key)
100u_char *name, *key;
101{
102  int nlen, klen;
103
104  nlen = *name++;
105  klen = *key;
106  *key++ = 0;
107  key[klen] = 0;
108  logprintf("name: %s (%d), key: %s (%d)\n", name, nlen, key, klen);
109  return(AuthValidate(SECRETFILE, name, key));
110}
111
112void
113PapInput(bp)
114struct mbuf *bp;
115{
116  int len = plength(bp);
117  struct fsmheader *php;
118  struct lcpstate *lcp = &LcpInfo;
119  u_char *cp;
120
121  if (len >= sizeof(struct fsmheader)) {
122    php = (struct fsmheader *)MBUF_CTOP(bp);
123    if (len >= ntohs(php->length)) {
124      if (php->code < PAP_REQUEST || php->code > PAP_NAK)
125	php->code = 0;
126      LogPrintf(LOG_PHASE, "PapInput: %s\n", papcodes[php->code]);
127
128      switch (php->code) {
129      case PAP_REQUEST:
130	cp = (u_char *) (php + 1);
131	if (PapValidate(cp, cp + *cp + 1)) {
132	  SendPapCode(php->id, PAP_ACK, "Greetings!!");
133	  lcp->auth_ineed = 0;
134	  if (lcp->auth_iwait == 0)
135	    NewPhase(PHASE_NETWORK);
136	} else {
137	  SendPapCode(php->id, PAP_NAK, "Login incorrect");
138	  LcpClose();
139	}
140	break;
141      case PAP_ACK:
142	cp = (u_char *)(php + 1);
143	len = *cp++;
144	cp[len] = 0;
145	LogPrintf(LOG_PHASE, "Received PAP_ACK (%s)\n", cp);
146	if (lcp->auth_iwait == PROTO_PAP) {
147	  lcp->auth_iwait = 0;
148	  if (lcp->auth_ineed == 0)
149	    NewPhase(PHASE_NETWORK);
150	}
151	break;
152      case PAP_NAK:
153	cp = (u_char *)(php + 1);
154	len = *cp++;
155	cp[len] = 0;
156	LogPrintf(LOG_PHASE, "Received PAP_NAK (%s)\n", cp);
157	LcpClose();
158	break;
159      }
160    }
161  }
162  pfree(bp);
163}
164