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