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