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