]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/ppp/pap.c
This commit was generated by cvs2svn to compensate for changes in r33011,
[FreeBSD/FreeBSD.git] / usr.sbin / ppp / pap.c
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.19 1997/11/22 03:37:43 brian Exp $
22  *
23  *      TODO:
24  */
25 #include <sys/param.h>
26 #include <netinet/in.h>
27
28 #include <pwd.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <time.h>
32 #include <unistd.h>
33 #ifdef __OpenBSD__
34 #include <util.h>
35 #else
36 #include <libutil.h>
37 #endif
38 #include <utmp.h>
39
40 #include "command.h"
41 #include "mbuf.h"
42 #include "log.h"
43 #include "defs.h"
44 #include "timer.h"
45 #include "fsm.h"
46 #include "lcp.h"
47 #include "pap.h"
48 #include "loadalias.h"
49 #include "vars.h"
50 #include "hdlc.h"
51 #include "lcpproto.h"
52 #include "phase.h"
53 #include "auth.h"
54
55 static const char *papcodes[] = { "???", "REQUEST", "ACK", "NAK" };
56
57 static void
58 SendPapChallenge(int papid)
59 {
60   struct fsmheader lh;
61   struct mbuf *bp;
62   u_char *cp;
63   int namelen, keylen, plen;
64
65   namelen = strlen(VarAuthName);
66   keylen = strlen(VarAuthKey);
67   plen = namelen + keylen + 2;
68   LogPrintf(LogDEBUG, "SendPapChallenge: namelen = %d, keylen = %d\n",
69             namelen, keylen);
70   if (LogIsKept(LogDEBUG))
71     LogPrintf(LogPHASE, "PAP: %s (%s)\n", VarAuthName, VarAuthKey);
72   else
73     LogPrintf(LogPHASE, "PAP: %s\n", VarAuthName);
74   lh.code = PAP_REQUEST;
75   lh.id = papid;
76   lh.length = htons(plen + sizeof(struct fsmheader));
77   bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
78   memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
79   cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
80   *cp++ = namelen;
81   memcpy(cp, VarAuthName, namelen);
82   cp += namelen;
83   *cp++ = keylen;
84   memcpy(cp, VarAuthKey, keylen);
85
86   HdlcOutput(PRI_LINK, PROTO_PAP, bp);
87 }
88
89 struct authinfo AuthPapInfo = {
90   SendPapChallenge,
91 };
92
93 static void
94 SendPapCode(int id, int code, const char *message)
95 {
96   struct fsmheader lh;
97   struct mbuf *bp;
98   u_char *cp;
99   int plen, mlen;
100
101   lh.code = code;
102   lh.id = id;
103   mlen = strlen(message);
104   plen = mlen + 1;
105   lh.length = htons(plen + sizeof(struct fsmheader));
106   bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
107   memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
108   cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
109   *cp++ = mlen;
110   memcpy(cp, message, mlen);
111   LogPrintf(LogPHASE, "PapOutput: %s\n", papcodes[code]);
112   HdlcOutput(PRI_LINK, PROTO_PAP, bp);
113 }
114
115 /*
116  * Validate given username and passwrd against with secret table
117  */
118 static int
119 PapValidate(u_char * name, u_char * key)
120 {
121   int nlen, klen;
122
123   nlen = *name++;
124   klen = *key;
125   *key++ = 0;
126   key[klen] = 0;
127   LogPrintf(LogDEBUG, "PapValidate: name %s (%d), key %s (%d)\n",
128             name, nlen, key, klen);
129
130 #ifndef NOPASSWDAUTH
131   if (Enabled(ConfPasswdAuth)) {
132     struct passwd *pwd;
133     int result;
134
135     LogPrintf(LogLCP, "Using PasswdAuth\n");
136     result = (pwd = getpwnam(name)) &&
137              !strcmp(crypt(key, pwd->pw_passwd), pwd->pw_passwd);
138     endpwent();
139     return result;
140   }
141 #endif
142
143   return (AuthValidate(SECRETFILE, name, key));
144 }
145
146 void
147 PapInput(struct mbuf * bp)
148 {
149   int len = plength(bp);
150   struct fsmheader *php;
151   struct lcpstate *lcp = &LcpInfo;
152   u_char *cp;
153
154   if (len >= sizeof(struct fsmheader)) {
155     php = (struct fsmheader *) MBUF_CTOP(bp);
156     if (len >= ntohs(php->length)) {
157       if (php->code < PAP_REQUEST || php->code > PAP_NAK)
158         php->code = 0;
159       LogPrintf(LogPHASE, "PapInput: %s\n", papcodes[php->code]);
160
161       switch (php->code) {
162       case PAP_REQUEST:
163         cp = (u_char *) (php + 1);
164         if (PapValidate(cp, cp + *cp + 1)) {
165           SendPapCode(php->id, PAP_ACK, "Greetings!!");
166           lcp->auth_ineed = 0;
167           if (lcp->auth_iwait == 0) {
168             if ((mode & MODE_DIRECT) && isatty(modem) && Enabled(ConfUtmp))
169               if (Utmp)
170                 LogPrintf(LogERROR, "Oops, already logged in on %s\n",
171                           VarBaseDevice);
172               else {
173                 struct utmp ut;
174                 memset(&ut, 0, sizeof ut);
175                 time(&ut.ut_time);
176                 strncpy(ut.ut_name, cp+1, sizeof ut.ut_name - 1);
177                 strncpy(ut.ut_line, VarBaseDevice, sizeof ut.ut_line - 1);
178                 if (logout(ut.ut_line))
179                   logwtmp(ut.ut_line, "", "");
180                 login(&ut);
181                 Utmp = 1;
182               }
183             NewPhase(PHASE_NETWORK);
184           }
185         } else {
186           SendPapCode(php->id, PAP_NAK, "Login incorrect");
187           reconnect(RECON_FALSE);
188           LcpClose();
189         }
190         break;
191       case PAP_ACK:
192         StopAuthTimer(&AuthPapInfo);
193         cp = (u_char *) (php + 1);
194         len = *cp++;
195         cp[len] = 0;
196         LogPrintf(LogPHASE, "Received PAP_ACK (%s)\n", cp);
197         if (lcp->auth_iwait == PROTO_PAP) {
198           lcp->auth_iwait = 0;
199           if (lcp->auth_ineed == 0)
200             NewPhase(PHASE_NETWORK);
201         }
202         break;
203       case PAP_NAK:
204         StopAuthTimer(&AuthPapInfo);
205         cp = (u_char *) (php + 1);
206         len = *cp++;
207         cp[len] = 0;
208         LogPrintf(LogPHASE, "Received PAP_NAK (%s)\n", cp);
209         reconnect(RECON_FALSE);
210         LcpClose();
211         break;
212       }
213     }
214   }
215   pfree(bp);
216 }