xref: /freebsd/usr.sbin/ppp/pap.c (revision e627b39baccd1ec9129690167cf5e6d860509655)
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 
34 static char *papcodes[] = {
35   "???", "REQUEST", "ACK", "NAK"
36 };
37 
38 struct authinfo AuthPapInfo  = {
39   SendPapChallenge,
40 };
41 
42 void
43 SendPapChallenge(papid)
44 int 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 
73 static void
74 SendPapCode(id, code, message)
75 int id;
76 char *message;
77 int 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  */
101 static int
102 PapValidate(name, key)
103 u_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 
117 void
118 PapInput(bp)
119 struct 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