pap.c revision 15738
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: pap.c,v 1.4 1996/01/30 11:08:45 dfr Exp $
22 *
23 *	TODO:
24 */
25#include "fsm.h"
26#include "lcp.h"
27#include "pap.h"
28#include "vars.h"
29#include "hdlc.h"
30#include "lcpproto.h"
31#include "phase.h"
32#include "auth.h"
33
34static char *papcodes[] = {
35  "???", "REQUEST", "ACK", "NAK"
36};
37
38struct authinfo AuthPapInfo  = {
39  SendPapChallenge,
40};
41
42void
43SendPapChallenge(papid)
44int papid;
45{
46  struct fsmheader lh;
47  struct mbuf *bp;
48  u_char *cp;
49  int namelen, keylen, plen;
50
51  namelen = strlen(VarAuthName);
52  keylen = strlen(VarAuthKey);
53  plen = namelen + keylen + 2;
54#ifdef DEBUG
55  logprintf("namelen = %d, keylen = %d\n", namelen, keylen);
56#endif
57  LogPrintf(LOG_PHASE_BIT, "PAP: %s (%s)\n", VarAuthName, VarAuthKey);
58  lh.code = PAP_REQUEST;
59  lh.id = papid;
60  lh.length = htons(plen + sizeof(struct fsmheader));
61  bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
62  bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader));
63  cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
64  *cp++ = namelen;
65  bcopy(VarAuthName, cp, namelen);
66  cp += namelen;
67  *cp++ = keylen;
68  bcopy(VarAuthKey, cp, keylen);
69
70  HdlcOutput(PRI_LINK, PROTO_PAP, bp);
71}
72
73static void
74SendPapCode(id, code, message)
75int id;
76char *message;
77int code;
78{
79  struct fsmheader lh;
80  struct mbuf *bp;
81  u_char *cp;
82  int plen, mlen;
83
84  lh.code = code;
85  lh.id = id;
86  mlen = strlen(message);
87  plen = mlen + 1;
88  lh.length = htons(plen + sizeof(struct fsmheader));
89  bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
90  bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader));
91  cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
92  *cp++ = mlen;
93  bcopy(message, cp, mlen);
94  LogPrintf(LOG_PHASE_BIT, "PapOutput: %s\n", papcodes[code]);
95  HdlcOutput(PRI_LINK, PROTO_PAP, bp);
96}
97
98/*
99 * Validate given username and passwrd against with secret table
100 */
101static int
102PapValidate(name, key)
103u_char *name, *key;
104{
105  int nlen, klen;
106
107  nlen = *name++;
108  klen = *key;
109  *key++ = 0;
110  key[klen] = 0;
111#ifdef DEBUG
112  logprintf("name: %s (%d), key: %s (%d)\n", name, nlen, key, klen);
113#endif
114  return(AuthValidate(SECRETFILE, name, key));
115}
116
117void
118PapInput(bp)
119struct mbuf *bp;
120{
121  int len = plength(bp);
122  struct fsmheader *php;
123  struct lcpstate *lcp = &LcpInfo;
124  u_char *cp;
125
126  if (len >= sizeof(struct fsmheader)) {
127    php = (struct fsmheader *)MBUF_CTOP(bp);
128    if (len >= ntohs(php->length)) {
129      if (php->code < PAP_REQUEST || php->code > PAP_NAK)
130	php->code = 0;
131      LogPrintf(LOG_PHASE_BIT, "PapInput: %s\n", papcodes[php->code]);
132
133      switch (php->code) {
134      case PAP_REQUEST:
135	cp = (u_char *) (php + 1);
136	if (PapValidate(cp, cp + *cp + 1)) {
137	  SendPapCode(php->id, PAP_ACK, "Greetings!!");
138	  lcp->auth_ineed = 0;
139	  if (lcp->auth_iwait == 0)
140	    NewPhase(PHASE_NETWORK);
141	} else {
142	  SendPapCode(php->id, PAP_NAK, "Login incorrect");
143	  LcpClose();
144	}
145	break;
146      case PAP_ACK:
147	StopAuthTimer(&AuthPapInfo);
148	cp = (u_char *)(php + 1);
149	len = *cp++;
150	cp[len] = 0;
151	LogPrintf(LOG_PHASE_BIT, "Received PAP_ACK (%s)\n", cp);
152	if (lcp->auth_iwait == PROTO_PAP) {
153	  lcp->auth_iwait = 0;
154	  if (lcp->auth_ineed == 0)
155	    NewPhase(PHASE_NETWORK);
156	}
157	break;
158      case PAP_NAK:
159	StopAuthTimer(&AuthPapInfo);
160	cp = (u_char *)(php + 1);
161	len = *cp++;
162	cp[len] = 0;
163	LogPrintf(LOG_PHASE_BIT, "Received PAP_NAK (%s)\n", cp);
164	LcpClose();
165	break;
166      }
167    }
168  }
169  pfree(bp);
170}
171