4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
6 * Copyright (C) 1993-94, Internet Initiative Japan, Inc.
7 * All rights reserverd.
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.
21 * $Id: pap.c,v 1.26 1998/08/07 18:42:50 brian Exp $
25 #include <sys/types.h>
26 #include <netinet/in.h>
27 #include <netinet/in_systm.h>
28 #include <netinet/ip.h>
46 #include "throughput.h"
49 #include "descriptor.h"
52 #include "slcompress.h"
62 static const char *papcodes[] = { "???", "REQUEST", "SUCCESS", "FAILURE" };
65 pap_SendChallenge(struct authinfo *auth, int papid, struct physical *physical)
70 int namelen, keylen, plen;
72 namelen = strlen(physical->dl->bundle->cfg.auth.name);
73 keylen = strlen(physical->dl->bundle->cfg.auth.key);
74 plen = namelen + keylen + 2;
75 log_Printf(LogDEBUG, "pap_SendChallenge: namelen = %d, keylen = %d\n",
77 log_Printf(LogPHASE, "Pap Output: %s ********\n",
78 physical->dl->bundle->cfg.auth.name);
79 if (*physical->dl->bundle->cfg.auth.name == '\0')
80 log_Printf(LogWARN, "Sending empty PAP authname!\n");
81 lh.code = PAP_REQUEST;
83 lh.length = htons(plen + sizeof(struct fsmheader));
84 bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_FSM);
85 memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
86 cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
88 memcpy(cp, physical->dl->bundle->cfg.auth.name, namelen);
91 memcpy(cp, physical->dl->bundle->cfg.auth.key, keylen);
93 hdlc_Output(&physical->link, PRI_LINK, PROTO_PAP, bp);
97 SendPapCode(int id, int code, const char *message, struct physical *physical)
106 mlen = strlen(message);
108 lh.length = htons(plen + sizeof(struct fsmheader));
109 bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_FSM);
110 memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
111 cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
113 memcpy(cp, message, mlen);
114 log_Printf(LogPHASE, "Pap Output: %s\n", papcodes[code]);
115 hdlc_Output(&physical->link, PRI_LINK, PROTO_PAP, bp);
119 * Validate given username and passwrd against with secret table
122 PapValidate(struct bundle *bundle, u_char *name, u_char *key,
123 struct physical *physical)
131 log_Printf(LogDEBUG, "PapValidate: name %s (%d), key %s (%d)\n",
132 name, nlen, key, klen);
134 return auth_Validate(bundle, name, key, physical);
138 pap_Input(struct bundle *bundle, struct mbuf *bp, struct physical *physical)
140 int len = mbuf_Length(bp);
141 struct fsmheader *php;
144 if (len >= sizeof(struct fsmheader)) {
145 php = (struct fsmheader *) MBUF_CTOP(bp);
146 if (len >= ntohs(php->length)) {
147 if (php->code < PAP_REQUEST || php->code > PAP_NAK)
151 cp = (u_char *) (php + 1);
152 log_Printf(LogPHASE, "Pap Input: %s (%.*s)\n",
153 papcodes[php->code], *cp, cp + 1);
154 if (PapValidate(bundle, cp, cp + *cp + 1, physical)) {
155 datalink_GotAuthname(physical->dl, cp+1, *cp);
156 SendPapCode(php->id, PAP_ACK, "Greetings!!", physical);
157 physical->link.lcp.auth_ineed = 0;
158 if (Enabled(bundle, OPT_UTMP))
159 physical_Login(physical, cp + 1);
161 if (physical->link.lcp.auth_iwait == 0)
163 * Either I didn't need to authenticate, or I've already been
164 * told that I got the answer right.
166 datalink_AuthOk(physical->dl);
169 SendPapCode(php->id, PAP_NAK, "Login incorrect", physical);
170 datalink_AuthNotOk(physical->dl);
174 auth_StopTimer(&physical->dl->pap);
175 cp = (u_char *) (php + 1);
178 log_Printf(LogPHASE, "Pap Input: %s (%s)\n", papcodes[php->code], cp);
179 if (physical->link.lcp.auth_iwait == PROTO_PAP) {
180 physical->link.lcp.auth_iwait = 0;
181 if (physical->link.lcp.auth_ineed == 0)
183 * We've succeeded in our ``login''
184 * If we're not expecting the peer to authenticate (or he already
185 * has), proceed to network phase.
187 datalink_AuthOk(physical->dl);
191 auth_StopTimer(&physical->dl->pap);
192 cp = (u_char *) (php + 1);
195 log_Printf(LogPHASE, "Pap Input: %s (%s)\n", papcodes[php->code], cp);
196 datalink_AuthNotOk(physical->dl);