pap.c revision 37210
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.23 1998/05/21 21:47:18 brian Exp $
22 *
23 *	TODO:
24 */
25#include <sys/types.h>
26#include <netinet/in.h>
27#include <netinet/in_systm.h>
28#include <netinet/ip.h>
29#include <sys/un.h>
30
31#include <string.h>
32#include <termios.h>
33
34#include "mbuf.h"
35#include "log.h"
36#include "defs.h"
37#include "timer.h"
38#include "fsm.h"
39#include "lcp.h"
40#include "auth.h"
41#include "pap.h"
42#include "lqr.h"
43#include "hdlc.h"
44#include "lcpproto.h"
45#include "async.h"
46#include "throughput.h"
47#include "ccp.h"
48#include "link.h"
49#include "descriptor.h"
50#include "physical.h"
51#include "iplist.h"
52#include "slcompress.h"
53#include "ipcp.h"
54#include "filter.h"
55#include "mp.h"
56#include "bundle.h"
57#include "chat.h"
58#include "chap.h"
59#include "datalink.h"
60
61static const char *papcodes[] = { "???", "REQUEST", "ACK", "NAK" };
62
63void
64pap_SendChallenge(struct authinfo *auth, int papid, struct physical *physical)
65{
66  struct fsmheader lh;
67  struct mbuf *bp;
68  u_char *cp;
69  int namelen, keylen, plen;
70
71  namelen = strlen(physical->dl->bundle->cfg.auth.name);
72  keylen = strlen(physical->dl->bundle->cfg.auth.key);
73  plen = namelen + keylen + 2;
74  log_Printf(LogDEBUG, "pap_SendChallenge: namelen = %d, keylen = %d\n",
75	    namelen, keylen);
76  log_Printf(LogPHASE, "PAP: %s\n", physical->dl->bundle->cfg.auth.name);
77  lh.code = PAP_REQUEST;
78  lh.id = papid;
79  lh.length = htons(plen + sizeof(struct fsmheader));
80  bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_FSM);
81  memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
82  cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
83  *cp++ = namelen;
84  memcpy(cp, physical->dl->bundle->cfg.auth.name, namelen);
85  cp += namelen;
86  *cp++ = keylen;
87  memcpy(cp, physical->dl->bundle->cfg.auth.key, keylen);
88
89  hdlc_Output(&physical->link, PRI_LINK, PROTO_PAP, bp);
90}
91
92static void
93SendPapCode(int id, int code, const char *message, struct physical *physical)
94{
95  struct fsmheader lh;
96  struct mbuf *bp;
97  u_char *cp;
98  int plen, mlen;
99
100  lh.code = code;
101  lh.id = id;
102  mlen = strlen(message);
103  plen = mlen + 1;
104  lh.length = htons(plen + sizeof(struct fsmheader));
105  bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_FSM);
106  memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
107  cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
108  *cp++ = mlen;
109  memcpy(cp, message, mlen);
110  log_Printf(LogPHASE, "PapOutput: %s\n", papcodes[code]);
111  hdlc_Output(&physical->link, PRI_LINK, PROTO_PAP, bp);
112}
113
114/*
115 * Validate given username and passwrd against with secret table
116 */
117static int
118PapValidate(struct bundle *bundle, u_char *name, u_char *key,
119            struct physical *physical)
120{
121  int nlen, klen;
122
123  nlen = *name++;
124  klen = *key;
125  *key++ = 0;
126  key[klen] = 0;
127  log_Printf(LogDEBUG, "PapValidate: name %s (%d), key %s (%d)\n",
128	    name, nlen, key, klen);
129
130  return auth_Validate(bundle, name, key, physical);
131}
132
133void
134pap_Input(struct bundle *bundle, struct mbuf *bp, struct physical *physical)
135{
136  int len = mbuf_Length(bp);
137  struct fsmheader *php;
138  u_char *cp;
139
140  if (len >= sizeof(struct fsmheader)) {
141    php = (struct fsmheader *) MBUF_CTOP(bp);
142    if (len >= ntohs(php->length)) {
143      if (php->code < PAP_REQUEST || php->code > PAP_NAK)
144	php->code = 0;
145      log_Printf(LogPHASE, "pap_Input: %s\n", papcodes[php->code]);
146
147      switch (php->code) {
148      case PAP_REQUEST:
149	cp = (u_char *) (php + 1);
150	if (PapValidate(bundle, cp, cp + *cp + 1, physical)) {
151          datalink_GotAuthname(physical->dl, cp+1, *cp);
152	  SendPapCode(php->id, PAP_ACK, "Greetings!!", physical);
153	  physical->link.lcp.auth_ineed = 0;
154          if (Enabled(bundle, OPT_UTMP))
155            physical_Login(physical, cp + 1);
156
157          if (physical->link.lcp.auth_iwait == 0)
158            /*
159             * Either I didn't need to authenticate, or I've already been
160             * told that I got the answer right.
161             */
162            datalink_AuthOk(physical->dl);
163
164	} else {
165	  SendPapCode(php->id, PAP_NAK, "Login incorrect", physical);
166          datalink_AuthNotOk(physical->dl);
167	}
168	break;
169      case PAP_ACK:
170	auth_StopTimer(&physical->dl->pap);
171	cp = (u_char *) (php + 1);
172	len = *cp++;
173	cp[len] = 0;
174	log_Printf(LogPHASE, "Received PAP_ACK (%s)\n", cp);
175	if (physical->link.lcp.auth_iwait == PROTO_PAP) {
176	  physical->link.lcp.auth_iwait = 0;
177	  if (physical->link.lcp.auth_ineed == 0)
178            /*
179             * We've succeeded in our ``login''
180             * If we're not expecting  the peer to authenticate (or he already
181             * has), proceed to network phase.
182             */
183            datalink_AuthOk(physical->dl);
184	}
185	break;
186      case PAP_NAK:
187	auth_StopTimer(&physical->dl->pap);
188	cp = (u_char *) (php + 1);
189	len = *cp++;
190	cp[len] = 0;
191	log_Printf(LogPHASE, "Received PAP_NAK (%s)\n", cp);
192        datalink_AuthNotOk(physical->dl);
193	break;
194      }
195    }
196  }
197  mbuf_Free(bp);
198}
199