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
)
100 if (!strcmp(data
, "*")) {
101 /* Then look up the real password database */
105 result
= (pw
= getpwnam(name
)) &&
106 !strcmp(crypt(key
, pw
->pw_passwd
), pw
->pw_passwd
);
111 return !strcmp(data
, key
);
115 auth_SetPhoneList(const char *name
, char *phone
, int phonelen
)
119 char *vector
[6], buff
[LINE_LEN
];
122 fp
= OpenSecret(SECRETFILE
);
126 while (fgets(buff
, sizeof buff
, fp
)) {
130 buff
[strlen(buff
) - 1] = '\0';
131 memset(vector
, '\0', sizeof vector
);
132 if ((n
= MakeArgs(buff
, vector
, VECSIZE(vector
), PARSE_REDUCE
)) < 0)
133 log_Printf(LogWARN
, "%s: %d: Invalid line\n", SECRETFILE
, lineno
);
136 if (strcmp(vector
[0], name
) == 0) {
138 if (*vector
[4] == '\0')
140 strncpy(phone
, vector
[4], phonelen
- 1);
141 phone
[phonelen
- 1] = '\0';
142 return 1; /* Valid */
146 if ((slash
= strrchr(name
, '\\')) != NULL
&& slash
[1]) {
147 /* Look for the name without the leading domain */
160 auth_Select(struct bundle
*bundle
, const char *name
)
164 char *vector
[5], buff
[LINE_LEN
];
168 ipcp_Setup(&bundle
->ncp
.ipcp
, INADDR_NONE
);
173 if (bundle
->radius
.valid
&& bundle
->radius
.ip
.s_addr
!= INADDR_NONE
&&
174 bundle
->radius
.ip
.s_addr
!= RADIUS_INADDR_POOL
) {
175 /* We've got a radius IP - it overrides everything */
176 if (!ipcp_UseHisIPaddr(bundle
, bundle
->radius
.ip
))
178 ipcp_Setup(&bundle
->ncp
.ipcp
, bundle
->radius
.mask
.s_addr
);
179 /* Continue with ppp.secret in case we've got a new label */
183 fp
= OpenSecret(SECRETFILE
);
187 while (fgets(buff
, sizeof buff
, fp
)) {
191 buff
[strlen(buff
) - 1] = '\0';
192 memset(vector
, '\0', sizeof vector
);
193 if ((n
= MakeArgs(buff
, vector
, VECSIZE(vector
), PARSE_REDUCE
)) < 0)
194 log_Printf(LogWARN
, "%s: %d: Invalid line\n", SECRETFILE
, lineno
);
197 if (strcmp(vector
[0], name
) == 0) {
200 if (!bundle
->radius
.valid
|| bundle
->radius
.ip
.s_addr
== INADDR_NONE
) {
202 if (n
> 2 && *vector
[2] && strcmp(vector
[2], "*") &&
203 !ipcp_UseHisaddr(bundle
, vector
[2], 1))
205 ipcp_Setup(&bundle
->ncp
.ipcp
, INADDR_NONE
);
209 if (n
> 3 && *vector
[3] && strcmp(vector
[3], "*"))
210 bundle_SetLabel(bundle
, vector
[3]);
211 return 1; /* Valid */
215 if ((slash
= strrchr(name
, '\\')) != NULL
&& slash
[1]) {
216 /* Look for the name without the leading domain */
226 /* Let 'em in anyway - they must have been in the passwd file */
227 ipcp_Setup(&bundle
->ncp
.ipcp
, INADDR_NONE
);
231 if (bundle
->radius
.valid
)
235 /* Disappeared from ppp.secret ??? */
241 auth_Validate(struct bundle
*bundle
, const char *name
, const char *key
)
243 /* Used by PAP routines */
247 char *vector
[5], buff
[LINE_LEN
];
250 fp
= OpenSecret(SECRETFILE
);
254 while (fgets(buff
, sizeof buff
, fp
)) {
258 buff
[strlen(buff
) - 1] = 0;
259 memset(vector
, '\0', sizeof vector
);
260 if ((n
= MakeArgs(buff
, vector
, VECSIZE(vector
), PARSE_REDUCE
)) < 0)
261 log_Printf(LogWARN
, "%s: %d: Invalid line\n", SECRETFILE
, lineno
);
264 if (strcmp(vector
[0], name
) == 0) {
266 return auth_CheckPasswd(name
, vector
[1], key
);
271 if ((slash
= strrchr(name
, '\\')) != NULL
&& slash
[1]) {
272 /* Look for the name without the leading domain */
284 if (Enabled(bundle
, OPT_PASSWDAUTH
))
285 return auth_CheckPasswd(name
, "*", key
);
288 return 0; /* Invalid */
292 auth_GetSecret(const char *name
, size_t len
)
294 /* Used by CHAP routines */
300 static char buff
[LINE_LEN
]; /* vector[] will point here when returned */
302 fp
= OpenSecret(SECRETFILE
);
308 while (fgets(buff
, sizeof buff
, fp
)) {
312 n
= strlen(buff
) - 1;
314 buff
[n
] = '\0'; /* Trim the '\n' */
315 memset(vector
, '\0', sizeof vector
);
316 if ((n
= MakeArgs(buff
, vector
, VECSIZE(vector
), PARSE_REDUCE
)) < 0)
317 log_Printf(LogWARN
, "%s: %d: Invalid line\n", SECRETFILE
, lineno
);
320 if (strlen(vector
[0]) == len
&& strncmp(vector
[0], name
, len
) == 0) {
326 if ((slash
= strrchr(name
, '\\')) != NULL
&& slash
[1]) {
327 /* Go back and look for the name without the leading domain */
328 len
-= slash
- name
+ 1;
335 return (NULL
); /* Invalid */
339 AuthTimeout(void *vauthp
)
341 struct authinfo
*authp
= (struct authinfo
*)vauthp
;
343 timer_Stop(&authp
->authtimer
);
344 if (--authp
->retry
> 0) {
346 (*authp
->fn
.req
)(authp
);
347 timer_Start(&authp
->authtimer
);
349 log_Printf(LogPHASE
, "Auth: No response from server\n");
350 datalink_AuthNotOk(authp
->physical
->dl
);
355 auth_Init(struct authinfo
*authp
, struct physical
*p
, auth_func req
,
356 auth_func success
, auth_func failure
)
358 memset(authp
, '\0', sizeof(struct authinfo
));
359 authp
->cfg
.fsm
.timeout
= DEF_FSMRETRY
;
360 authp
->cfg
.fsm
.maxreq
= DEF_FSMAUTHTRIES
;
361 authp
->cfg
.fsm
.maxtrm
= 0; /* not used */
363 authp
->fn
.success
= success
;
364 authp
->fn
.failure
= failure
;
369 auth_StartReq(struct authinfo
*authp
)
371 timer_Stop(&authp
->authtimer
);
372 authp
->authtimer
.func
= AuthTimeout
;
373 authp
->authtimer
.name
= "auth";
374 authp
->authtimer
.load
= authp
->cfg
.fsm
.timeout
* SECTICKS
;
375 authp
->authtimer
.arg
= (void *)authp
;
376 authp
->retry
= authp
->cfg
.fsm
.maxreq
;
378 (*authp
->fn
.req
)(authp
);
379 timer_Start(&authp
->authtimer
);
383 auth_StopTimer(struct authinfo
*authp
)
385 timer_Stop(&authp
->authtimer
);
389 auth_ReadHeader(struct authinfo
*authp
, struct mbuf
*bp
)
394 if (len
>= sizeof authp
->in
.hdr
) {
395 bp
= mbuf_Read(bp
, (u_char
*)&authp
->in
.hdr
, sizeof authp
->in
.hdr
);
396 if (len
>= ntohs(authp
->in
.hdr
.length
))
398 authp
->in
.hdr
.length
= htons(0);
399 log_Printf(LogWARN
, "auth_ReadHeader: Short packet (%u > %zu) !\n",
400 ntohs(authp
->in
.hdr
.length
), len
);
402 authp
->in
.hdr
.length
= htons(0);
403 log_Printf(LogWARN
, "auth_ReadHeader: Short packet header (%u > %zu) !\n",
404 (int)(sizeof authp
->in
.hdr
), len
);
412 auth_ReadName(struct authinfo
*authp
, struct mbuf
*bp
, size_t len
)
414 if (len
> sizeof authp
->in
.name
- 1)
415 log_Printf(LogWARN
, "auth_ReadName: Name too long (%zu) !\n", len
);
417 size_t mlen
= m_length(bp
);
420 log_Printf(LogWARN
, "auth_ReadName: Short packet (%zu > %zu) !\n",
423 bp
= mbuf_Read(bp
, (u_char
*)authp
->in
.name
, len
);
424 authp
->in
.name
[len
] = '\0';
429 *authp
->in
.name
= '\0';