2 * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
3 * based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
4 * Internet Initiative Japan, Inc (IIJ)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $FreeBSD: src/usr.sbin/ppp/auth.c,v 1.50.2.2 2002/09/01 02:12:22 brian Exp $
29 * $DragonFly: src/usr.sbin/ppp/auth.c,v 1.2 2003/06/17 04:30:00 dillon Exp $
32 #include <sys/param.h>
33 #include <netinet/in.h>
34 #include <netinet/in_systm.h>
35 #include <netinet/ip.h>
36 #include <sys/socket.h>
52 #include "throughput.h"
53 #include "slcompress.h"
63 #include "descriptor.h"
81 Auth2Nam(u_short auth
, u_char type
)
89 snprintf(chap
, sizeof chap
, "CHAP 0x%02x", type
);
98 auth_CheckPasswd(const char *name
, const char *data
, const char *key
)
104 if (!strcmp(data
, "*")) {
105 /* Then look up the real password database */
109 cryptpw
= crypt(key
, pw
->pw_passwd
);
111 result
= (cryptpw
!= NULL
) && !strcmp(cryptpw
, pw
->pw_passwd
);
119 return !strcmp(data
, key
);
123 auth_SetPhoneList(const char *name
, char *phone
, int phonelen
)
127 char *vector
[6], buff
[LINE_LEN
];
130 fp
= OpenSecret(SECRETFILE
);
134 while (fgets(buff
, sizeof buff
, fp
)) {
138 buff
[strlen(buff
) - 1] = '\0';
139 memset(vector
, '\0', sizeof vector
);
140 if ((n
= MakeArgs(buff
, vector
, VECSIZE(vector
), PARSE_REDUCE
)) < 0)
141 log_Printf(LogWARN
, "%s: %d: Invalid line\n", SECRETFILE
, lineno
);
144 if (strcmp(vector
[0], name
) == 0) {
146 if (*vector
[4] == '\0')
148 strncpy(phone
, vector
[4], phonelen
- 1);
149 phone
[phonelen
- 1] = '\0';
150 return 1; /* Valid */
154 if ((slash
= strrchr(name
, '\\')) != NULL
&& slash
[1]) {
155 /* Look for the name without the leading domain */
168 auth_Select(struct bundle
*bundle
, const char *name
)
172 char *vector
[5], buff
[LINE_LEN
];
176 ipcp_Setup(&bundle
->ncp
.ipcp
, INADDR_NONE
);
181 if (bundle
->radius
.valid
&& bundle
->radius
.ip
.s_addr
!= INADDR_NONE
&&
182 bundle
->radius
.ip
.s_addr
!= RADIUS_INADDR_POOL
) {
183 /* We've got a radius IP - it overrides everything */
184 if (!ipcp_UseHisIPaddr(bundle
, bundle
->radius
.ip
))
186 ipcp_Setup(&bundle
->ncp
.ipcp
, bundle
->radius
.mask
.s_addr
);
187 /* Continue with ppp.secret in case we've got a new label */
191 fp
= OpenSecret(SECRETFILE
);
195 while (fgets(buff
, sizeof buff
, fp
)) {
199 buff
[strlen(buff
) - 1] = '\0';
200 memset(vector
, '\0', sizeof vector
);
201 if ((n
= MakeArgs(buff
, vector
, VECSIZE(vector
), PARSE_REDUCE
)) < 0)
202 log_Printf(LogWARN
, "%s: %d: Invalid line\n", SECRETFILE
, lineno
);
205 if (strcmp(vector
[0], name
) == 0) {
208 if (!bundle
->radius
.valid
|| bundle
->radius
.ip
.s_addr
== INADDR_NONE
) {
210 if (n
> 2 && *vector
[2] && strcmp(vector
[2], "*") &&
211 !ipcp_UseHisaddr(bundle
, vector
[2], 1))
213 ipcp_Setup(&bundle
->ncp
.ipcp
, INADDR_NONE
);
217 if (n
> 3 && *vector
[3] && strcmp(vector
[3], "*"))
218 bundle_SetLabel(bundle
, vector
[3]);
219 return 1; /* Valid */
223 if ((slash
= strrchr(name
, '\\')) != NULL
&& slash
[1]) {
224 /* Look for the name without the leading domain */
234 /* Let 'em in anyway - they must have been in the passwd file */
235 ipcp_Setup(&bundle
->ncp
.ipcp
, INADDR_NONE
);
239 if (bundle
->radius
.valid
)
243 /* Disappeared from ppp.secret ??? */
249 auth_Validate(struct bundle
*bundle
, const char *name
, const char *key
)
251 /* Used by PAP routines */
255 char *vector
[5], buff
[LINE_LEN
];
258 fp
= OpenSecret(SECRETFILE
);
262 while (fgets(buff
, sizeof buff
, fp
)) {
266 buff
[strlen(buff
) - 1] = 0;
267 memset(vector
, '\0', sizeof vector
);
268 if ((n
= MakeArgs(buff
, vector
, VECSIZE(vector
), PARSE_REDUCE
)) < 0)
269 log_Printf(LogWARN
, "%s: %d: Invalid line\n", SECRETFILE
, lineno
);
272 if (strcmp(vector
[0], name
) == 0) {
274 return auth_CheckPasswd(name
, vector
[1], key
);
279 if ((slash
= strrchr(name
, '\\')) != NULL
&& slash
[1]) {
280 /* Look for the name without the leading domain */
292 if (Enabled(bundle
, OPT_PASSWDAUTH
))
293 return auth_CheckPasswd(name
, "*", key
);
296 return 0; /* Invalid */
300 auth_GetSecret(const char *name
, size_t len
)
302 /* Used by CHAP routines */
308 static char buff
[LINE_LEN
]; /* vector[] will point here when returned */
310 fp
= OpenSecret(SECRETFILE
);
316 while (fgets(buff
, sizeof buff
, fp
)) {
320 n
= strlen(buff
) - 1;
322 buff
[n
] = '\0'; /* Trim the '\n' */
323 memset(vector
, '\0', sizeof vector
);
324 if ((n
= MakeArgs(buff
, vector
, VECSIZE(vector
), PARSE_REDUCE
)) < 0)
325 log_Printf(LogWARN
, "%s: %d: Invalid line\n", SECRETFILE
, lineno
);
328 if (strlen(vector
[0]) == len
&& strncmp(vector
[0], name
, len
) == 0) {
334 if ((slash
= strrchr(name
, '\\')) != NULL
&& slash
[1]) {
335 /* Go back and look for the name without the leading domain */
336 len
-= slash
- name
+ 1;
343 return (NULL
); /* Invalid */
347 AuthTimeout(void *vauthp
)
349 struct authinfo
*authp
= (struct authinfo
*)vauthp
;
351 timer_Stop(&authp
->authtimer
);
352 if (--authp
->retry
> 0) {
354 (*authp
->fn
.req
)(authp
);
355 timer_Start(&authp
->authtimer
);
357 log_Printf(LogPHASE
, "Auth: No response from server\n");
358 datalink_AuthNotOk(authp
->physical
->dl
);
363 auth_Init(struct authinfo
*authp
, struct physical
*p
, auth_func req
,
364 auth_func success
, auth_func failure
)
366 memset(authp
, '\0', sizeof(struct authinfo
));
367 authp
->cfg
.fsm
.timeout
= DEF_FSMRETRY
;
368 authp
->cfg
.fsm
.maxreq
= DEF_FSMAUTHTRIES
;
369 authp
->cfg
.fsm
.maxtrm
= 0; /* not used */
371 authp
->fn
.success
= success
;
372 authp
->fn
.failure
= failure
;
377 auth_StartReq(struct authinfo
*authp
)
379 timer_Stop(&authp
->authtimer
);
380 authp
->authtimer
.func
= AuthTimeout
;
381 authp
->authtimer
.name
= "auth";
382 authp
->authtimer
.load
= authp
->cfg
.fsm
.timeout
* SECTICKS
;
383 authp
->authtimer
.arg
= (void *)authp
;
384 authp
->retry
= authp
->cfg
.fsm
.maxreq
;
386 (*authp
->fn
.req
)(authp
);
387 timer_Start(&authp
->authtimer
);
391 auth_StopTimer(struct authinfo
*authp
)
393 timer_Stop(&authp
->authtimer
);
397 auth_ReadHeader(struct authinfo
*authp
, struct mbuf
*bp
)
402 if (len
>= sizeof authp
->in
.hdr
) {
403 bp
= mbuf_Read(bp
, (u_char
*)&authp
->in
.hdr
, sizeof authp
->in
.hdr
);
404 if (len
>= ntohs(authp
->in
.hdr
.length
))
406 authp
->in
.hdr
.length
= htons(0);
407 log_Printf(LogWARN
, "auth_ReadHeader: Short packet (%u > %zu) !\n",
408 ntohs(authp
->in
.hdr
.length
), len
);
410 authp
->in
.hdr
.length
= htons(0);
411 log_Printf(LogWARN
, "auth_ReadHeader: Short packet header (%u > %zu) !\n",
412 (int)(sizeof authp
->in
.hdr
), len
);
420 auth_ReadName(struct authinfo
*authp
, struct mbuf
*bp
, size_t len
)
422 if (len
> sizeof authp
->in
.name
- 1)
423 log_Printf(LogWARN
, "auth_ReadName: Name too long (%zu) !\n", len
);
425 size_t mlen
= m_length(bp
);
428 log_Printf(LogWARN
, "auth_ReadName: Short packet (%zu > %zu) !\n",
431 bp
= mbuf_Read(bp
, (u_char
*)authp
->in
.name
, len
);
432 authp
->in
.name
[len
] = '\0';
437 *authp
->in
.name
= '\0';