xref: /freebsd/usr.sbin/ppp/auth.c (revision 4d846d260e2b9a3d4d0a701462568268cbfe7a5b)
165309e5cSBrian Somers /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
465309e5cSBrian Somers  * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
565309e5cSBrian Somers  *          based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
665309e5cSBrian Somers  *                           Internet Initiative Japan, Inc (IIJ)
765309e5cSBrian Somers  * All rights reserved.
8af57ed9fSAtsushi Murai  *
965309e5cSBrian Somers  * Redistribution and use in source and binary forms, with or without
1065309e5cSBrian Somers  * modification, are permitted provided that the following conditions
1165309e5cSBrian Somers  * are met:
1265309e5cSBrian Somers  * 1. Redistributions of source code must retain the above copyright
1365309e5cSBrian Somers  *    notice, this list of conditions and the following disclaimer.
1465309e5cSBrian Somers  * 2. Redistributions in binary form must reproduce the above copyright
1565309e5cSBrian Somers  *    notice, this list of conditions and the following disclaimer in the
1665309e5cSBrian Somers  *    documentation and/or other materials provided with the distribution.
17af57ed9fSAtsushi Murai  *
1865309e5cSBrian Somers  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1965309e5cSBrian Somers  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2065309e5cSBrian Somers  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2165309e5cSBrian Somers  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2265309e5cSBrian Somers  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2365309e5cSBrian Somers  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2465309e5cSBrian Somers  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2565309e5cSBrian Somers  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2665309e5cSBrian Somers  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2765309e5cSBrian Somers  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2865309e5cSBrian Somers  * SUCH DAMAGE.
29af57ed9fSAtsushi Murai  *
3097d92980SPeter Wemm  * $FreeBSD$
31af57ed9fSAtsushi Murai  */
3265309e5cSBrian Somers 
33972a1bcfSBrian Somers #include <sys/param.h>
3475240ed1SBrian Somers #include <netinet/in.h>
35eaa4df37SBrian Somers #include <netinet/in_systm.h>
36eaa4df37SBrian Somers #include <netinet/ip.h>
3730949fd4SBrian Somers #include <sys/socket.h>
381fa665f5SBrian Somers #include <sys/un.h>
3975240ed1SBrian Somers 
40d5015272SBrian Somers #include <pwd.h>
4175240ed1SBrian Somers #include <stdio.h>
4296fd764fSRuslan Ermilov #include <stdlib.h>
4375240ed1SBrian Somers #include <string.h>
44aceaed92SBrian Somers #include <termios.h>
4575240ed1SBrian Somers #include <unistd.h>
4675240ed1SBrian Somers 
4796fd764fSRuslan Ermilov #ifndef NOPAM
4896fd764fSRuslan Ermilov #include <security/pam_appl.h>
4929476579SDag-Erling Smørgrav #ifdef OPENPAM
5096fd764fSRuslan Ermilov #include <security/openpam.h>
5196fd764fSRuslan Ermilov #endif
5296fd764fSRuslan Ermilov #endif /* !NOPAM */
5396fd764fSRuslan Ermilov 
545d9e6103SBrian Somers #include "layer.h"
5575240ed1SBrian Somers #include "mbuf.h"
5675240ed1SBrian Somers #include "defs.h"
57aceaed92SBrian Somers #include "log.h"
5875240ed1SBrian Somers #include "timer.h"
59af57ed9fSAtsushi Murai #include "fsm.h"
6029e275ceSBrian Somers #include "iplist.h"
6129e275ceSBrian Somers #include "throughput.h"
62eaa4df37SBrian Somers #include "slcompress.h"
635a72b6edSBrian Somers #include "lqr.h"
645a72b6edSBrian Somers #include "hdlc.h"
6530949fd4SBrian Somers #include "ncpaddr.h"
66af57ed9fSAtsushi Murai #include "ipcp.h"
6753c9f6c0SAtsushi Murai #include "auth.h"
6875240ed1SBrian Somers #include "systems.h"
696140ba11SBrian Somers #include "lcp.h"
703b0f8d2eSBrian Somers #include "ccp.h"
716140ba11SBrian Somers #include "link.h"
7242d4d396SBrian Somers #include "descriptor.h"
73b6dec9f0SBrian Somers #include "chat.h"
745d9e6103SBrian Somers #include "proto.h"
755ca5389aSBrian Somers #include "filter.h"
763b0f8d2eSBrian Somers #include "mp.h"
77972a1bcfSBrian Somers #ifndef NORADIUS
78972a1bcfSBrian Somers #include "radius.h"
79972a1bcfSBrian Somers #endif
80aceaed92SBrian Somers #include "cbcp.h"
81aceaed92SBrian Somers #include "chap.h"
82aceaed92SBrian Somers #include "async.h"
83aceaed92SBrian Somers #include "physical.h"
84aceaed92SBrian Somers #include "datalink.h"
8530949fd4SBrian Somers #include "ipv6cp.h"
8630949fd4SBrian Somers #include "ncp.h"
875828db6dSBrian Somers #include "bundle.h"
88af57ed9fSAtsushi Murai 
89455aabc3SBrian Somers const char *
905e315498SBrian Somers Auth2Nam(u_short auth, u_char type)
91ed6a16c1SPoul-Henning Kamp {
925e315498SBrian Somers   static char chap[10];
935e315498SBrian Somers 
94455aabc3SBrian Somers   switch (auth) {
95455aabc3SBrian Somers   case PROTO_PAP:
96455aabc3SBrian Somers     return "PAP";
97455aabc3SBrian Somers   case PROTO_CHAP:
985e315498SBrian Somers     snprintf(chap, sizeof chap, "CHAP 0x%02x", type);
995e315498SBrian Somers     return chap;
100455aabc3SBrian Somers   case 0:
101455aabc3SBrian Somers     return "none";
102d025849cSBrian Somers   }
103455aabc3SBrian Somers   return "unknown";
10453c9f6c0SAtsushi Murai }
10553c9f6c0SAtsushi Murai 
10629476579SDag-Erling Smørgrav #if !defined(NOPAM) && !defined(OPENPAM)
10796fd764fSRuslan Ermilov static int
10896fd764fSRuslan Ermilov pam_conv(int n, const struct pam_message **msg, struct pam_response **resp,
10996fd764fSRuslan Ermilov   void *data)
11096fd764fSRuslan Ermilov {
11196fd764fSRuslan Ermilov 
11296fd764fSRuslan Ermilov   if (n != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF)
11396fd764fSRuslan Ermilov     return (PAM_CONV_ERR);
11496fd764fSRuslan Ermilov   if ((*resp = malloc(sizeof(struct pam_response))) == NULL)
11596fd764fSRuslan Ermilov     return (PAM_CONV_ERR);
11696fd764fSRuslan Ermilov   (*resp)[0].resp = strdup((const char *)data);
11796fd764fSRuslan Ermilov   (*resp)[0].resp_retcode = 0;
11896fd764fSRuslan Ermilov 
11996fd764fSRuslan Ermilov   return ((*resp)[0].resp != NULL ? PAM_SUCCESS : PAM_CONV_ERR);
12096fd764fSRuslan Ermilov }
12129476579SDag-Erling Smørgrav #endif /* !defined(NOPAM) && !defined(OPENPAM) */
12296fd764fSRuslan Ermilov 
123d5015272SBrian Somers static int
124d5015272SBrian Somers auth_CheckPasswd(const char *name, const char *data, const char *key)
125d5015272SBrian Somers {
126d5015272SBrian Somers   if (!strcmp(data, "*")) {
12796fd764fSRuslan Ermilov #ifdef NOPAM
128d5015272SBrian Somers     /* Then look up the real password database */
129d5015272SBrian Somers     struct passwd *pw;
130af3b49efSConrad Meyer     int result = 0;
13129dcf726SKevin Lo     char *cryptpw;
132d5015272SBrian Somers 
133af3b49efSConrad Meyer     pw = getpwnam(name);
134af3b49efSConrad Meyer 
135af3b49efSConrad Meyer     if (pw) {
13629dcf726SKevin Lo       cryptpw = crypt(key, pw->pw_passwd);
137af3b49efSConrad Meyer 
138af3b49efSConrad Meyer       result = (cryptpw != NULL) && !strcmp(cryptpw, pw->pw_passwd);
139af3b49efSConrad Meyer     }
140af3b49efSConrad Meyer 
141d5015272SBrian Somers     endpwent();
142af3b49efSConrad Meyer 
143d5015272SBrian Somers     return result;
14496fd764fSRuslan Ermilov #else /* !NOPAM */
14596fd764fSRuslan Ermilov     /* Then consult with PAM. */
14696fd764fSRuslan Ermilov     pam_handle_t *pamh;
14796fd764fSRuslan Ermilov     int status;
14896fd764fSRuslan Ermilov 
14996fd764fSRuslan Ermilov     struct pam_conv pamc = {
15029476579SDag-Erling Smørgrav #ifdef OPENPAM
15196fd764fSRuslan Ermilov       &openpam_nullconv, NULL
15296fd764fSRuslan Ermilov #else
15329476579SDag-Erling Smørgrav       &pam_conv, key
15496fd764fSRuslan Ermilov #endif
15596fd764fSRuslan Ermilov     };
15696fd764fSRuslan Ermilov 
15796fd764fSRuslan Ermilov     if (pam_start("ppp", name, &pamc, &pamh) != PAM_SUCCESS)
15896fd764fSRuslan Ermilov       return (0);
15929476579SDag-Erling Smørgrav #ifdef OPENPAM
16096fd764fSRuslan Ermilov     if ((status = pam_set_item(pamh, PAM_AUTHTOK, key)) == PAM_SUCCESS)
16196fd764fSRuslan Ermilov #endif
16296fd764fSRuslan Ermilov       status = pam_authenticate(pamh, 0);
16396fd764fSRuslan Ermilov     pam_end(pamh, status);
16496fd764fSRuslan Ermilov     return (status == PAM_SUCCESS);
16596fd764fSRuslan Ermilov #endif /* !NOPAM */
166d5015272SBrian Somers   }
167d5015272SBrian Somers 
168d5015272SBrian Somers   return !strcmp(data, key);
169d5015272SBrian Somers }
170d5015272SBrian Somers 
1711ae349f5Scvs2svn int
17292b09558SBrian Somers auth_SetPhoneList(const char *name, char *phone, int phonelen)
17392b09558SBrian Somers {
17492b09558SBrian Somers   FILE *fp;
175c39aa54eSBrian Somers   int n, lineno;
176af1e7664SBrian Somers   char *vector[6], buff[LINE_LEN];
177af1e7664SBrian Somers   const char *slash;
17892b09558SBrian Somers 
17992b09558SBrian Somers   fp = OpenSecret(SECRETFILE);
18092b09558SBrian Somers   if (fp != NULL) {
181af1e7664SBrian Somers again:
182af1e7664SBrian Somers     lineno = 0;
18392b09558SBrian Somers     while (fgets(buff, sizeof buff, fp)) {
184c39aa54eSBrian Somers       lineno++;
18592b09558SBrian Somers       if (buff[0] == '#')
18692b09558SBrian Somers         continue;
18792b09558SBrian Somers       buff[strlen(buff) - 1] = '\0';
18892b09558SBrian Somers       memset(vector, '\0', sizeof vector);
1895b78bdf8SBrian Somers       if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0)
190c39aa54eSBrian Somers         log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno);
19192b09558SBrian Somers       if (n < 5)
19292b09558SBrian Somers         continue;
19392b09558SBrian Somers       if (strcmp(vector[0], name) == 0) {
19492b09558SBrian Somers         CloseSecret(fp);
19592b09558SBrian Somers         if (*vector[4] == '\0')
19692b09558SBrian Somers           return 0;
19792b09558SBrian Somers         strncpy(phone, vector[4], phonelen - 1);
19892b09558SBrian Somers         phone[phonelen - 1] = '\0';
19992b09558SBrian Somers         return 1;		/* Valid */
20092b09558SBrian Somers       }
20192b09558SBrian Somers     }
202af1e7664SBrian Somers 
203af1e7664SBrian Somers     if ((slash = strrchr(name, '\\')) != NULL && slash[1]) {
204af1e7664SBrian Somers       /* Look for the name without the leading domain */
205af1e7664SBrian Somers       name = slash + 1;
206af1e7664SBrian Somers       rewind(fp);
207af1e7664SBrian Somers       goto again;
208af1e7664SBrian Somers     }
209af1e7664SBrian Somers 
21092b09558SBrian Somers     CloseSecret(fp);
21192b09558SBrian Somers   }
21292b09558SBrian Somers   *phone = '\0';
21392b09558SBrian Somers   return 0;
21492b09558SBrian Somers }
21592b09558SBrian Somers 
21692b09558SBrian Somers int
21792b09558SBrian Somers auth_Select(struct bundle *bundle, const char *name)
218944f7098SBrian Somers {
21953c9f6c0SAtsushi Murai   FILE *fp;
220c39aa54eSBrian Somers   int n, lineno;
221af1e7664SBrian Somers   char *vector[5], buff[LINE_LEN];
222af1e7664SBrian Somers   const char *slash;
22353c9f6c0SAtsushi Murai 
224643f4904SBrian Somers   if (*name == '\0') {
225972a1bcfSBrian Somers     ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE);
226643f4904SBrian Somers     return 1;
227643f4904SBrian Somers   }
228643f4904SBrian Somers 
229972a1bcfSBrian Somers #ifndef NORADIUS
23033b47634STatsumi Hosokawa   if (bundle->radius.valid && bundle->radius.ip.s_addr != INADDR_NONE &&
23133b47634STatsumi Hosokawa 	bundle->radius.ip.s_addr != RADIUS_INADDR_POOL) {
232972a1bcfSBrian Somers     /* We've got a radius IP - it overrides everything */
233972a1bcfSBrian Somers     if (!ipcp_UseHisIPaddr(bundle, bundle->radius.ip))
234972a1bcfSBrian Somers       return 0;
235972a1bcfSBrian Somers     ipcp_Setup(&bundle->ncp.ipcp, bundle->radius.mask.s_addr);
236972a1bcfSBrian Somers     /* Continue with ppp.secret in case we've got a new label */
237972a1bcfSBrian Somers   }
238972a1bcfSBrian Somers #endif
239972a1bcfSBrian Somers 
240643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
241d5015272SBrian Somers   if (fp != NULL) {
242af1e7664SBrian Somers again:
243af1e7664SBrian Somers     lineno = 0;
24470ee81ffSBrian Somers     while (fgets(buff, sizeof buff, fp)) {
245c39aa54eSBrian Somers       lineno++;
24653c9f6c0SAtsushi Murai       if (buff[0] == '#')
24753c9f6c0SAtsushi Murai         continue;
248501f5480SBrian Somers       buff[strlen(buff) - 1] = '\0';
24970ee81ffSBrian Somers       memset(vector, '\0', sizeof vector);
2505b78bdf8SBrian Somers       if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0)
251c39aa54eSBrian Somers         log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno);
2521ae349f5Scvs2svn       if (n < 2)
25353c9f6c0SAtsushi Murai         continue;
254501f5480SBrian Somers       if (strcmp(vector[0], name) == 0) {
2551ae349f5Scvs2svn         CloseSecret(fp);
256972a1bcfSBrian Somers #ifndef NORADIUS
257972a1bcfSBrian Somers         if (!bundle->radius.valid || bundle->radius.ip.s_addr == INADDR_NONE) {
258972a1bcfSBrian Somers #endif
25992b09558SBrian Somers           if (n > 2 && *vector[2] && strcmp(vector[2], "*") &&
26092b09558SBrian Somers               !ipcp_UseHisaddr(bundle, vector[2], 1))
261643f4904SBrian Somers             return 0;
262972a1bcfSBrian Somers           ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE);
263972a1bcfSBrian Somers #ifndef NORADIUS
264972a1bcfSBrian Somers         }
265972a1bcfSBrian Somers #endif
26692b09558SBrian Somers         if (n > 3 && *vector[3] && strcmp(vector[3], "*"))
26749052c95SBrian Somers           bundle_SetLabel(bundle, vector[3]);
268d5015272SBrian Somers         return 1;		/* Valid */
26953c9f6c0SAtsushi Murai       }
270501f5480SBrian Somers     }
271af1e7664SBrian Somers 
272af1e7664SBrian Somers     if ((slash = strrchr(name, '\\')) != NULL && slash[1]) {
273af1e7664SBrian Somers       /* Look for the name without the leading domain */
274af1e7664SBrian Somers       name = slash + 1;
275af1e7664SBrian Somers       rewind(fp);
276af1e7664SBrian Somers       goto again;
277af1e7664SBrian Somers     }
278af1e7664SBrian Somers 
27953c9f6c0SAtsushi Murai     CloseSecret(fp);
280643f4904SBrian Somers   }
281643f4904SBrian Somers 
282643f4904SBrian Somers #ifndef NOPASSWDAUTH
283643f4904SBrian Somers   /* Let 'em in anyway - they must have been in the passwd file */
284972a1bcfSBrian Somers   ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE);
285643f4904SBrian Somers   return 1;
286643f4904SBrian Somers #else
287972a1bcfSBrian Somers #ifndef NORADIUS
288972a1bcfSBrian Somers   if (bundle->radius.valid)
289972a1bcfSBrian Somers     return 1;
290972a1bcfSBrian Somers #endif
291972a1bcfSBrian Somers 
292972a1bcfSBrian Somers   /* Disappeared from ppp.secret ??? */
293643f4904SBrian Somers   return 0;
294643f4904SBrian Somers #endif
29553c9f6c0SAtsushi Murai }
29653c9f6c0SAtsushi Murai 
297af57ed9fSAtsushi Murai int
298057f1760SBrian Somers auth_Validate(struct bundle *bundle, const char *name, const char *key)
299af57ed9fSAtsushi Murai {
300643f4904SBrian Somers   /* Used by PAP routines */
301643f4904SBrian Somers 
302af57ed9fSAtsushi Murai   FILE *fp;
303c39aa54eSBrian Somers   int n, lineno;
304af1e7664SBrian Somers   char *vector[5], buff[LINE_LEN];
305af1e7664SBrian Somers   const char *slash;
306af57ed9fSAtsushi Murai 
307643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
308af1e7664SBrian Somers again:
309c39aa54eSBrian Somers   lineno = 0;
310643f4904SBrian Somers   if (fp != NULL) {
31170ee81ffSBrian Somers     while (fgets(buff, sizeof buff, fp)) {
312c39aa54eSBrian Somers       lineno++;
313af57ed9fSAtsushi Murai       if (buff[0] == '#')
314af57ed9fSAtsushi Murai         continue;
315af57ed9fSAtsushi Murai       buff[strlen(buff) - 1] = 0;
31670ee81ffSBrian Somers       memset(vector, '\0', sizeof vector);
3175b78bdf8SBrian Somers       if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0)
318c39aa54eSBrian Somers         log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno);
319af57ed9fSAtsushi Murai       if (n < 2)
320af57ed9fSAtsushi Murai         continue;
321972a1bcfSBrian Somers       if (strcmp(vector[0], name) == 0) {
322af57ed9fSAtsushi Murai         CloseSecret(fp);
323972a1bcfSBrian Somers         return auth_CheckPasswd(name, vector[1], key);
324af57ed9fSAtsushi Murai       }
325af57ed9fSAtsushi Murai     }
326d5015272SBrian Somers   }
327d5015272SBrian Somers 
328af1e7664SBrian Somers   if ((slash = strrchr(name, '\\')) != NULL && slash[1]) {
329af1e7664SBrian Somers     /* Look for the name without the leading domain */
330af1e7664SBrian Somers     name = slash + 1;
331af1e7664SBrian Somers     if (fp != NULL) {
332af1e7664SBrian Somers       rewind(fp);
333af1e7664SBrian Somers       goto again;
334af1e7664SBrian Somers     }
335af1e7664SBrian Somers   }
336af1e7664SBrian Somers 
337af1e7664SBrian Somers   if (fp != NULL)
338af1e7664SBrian Somers     CloseSecret(fp);
339af1e7664SBrian Somers 
340d5015272SBrian Somers #ifndef NOPASSWDAUTH
3411342caedSBrian Somers   if (Enabled(bundle, OPT_PASSWDAUTH))
342972a1bcfSBrian Somers     return auth_CheckPasswd(name, "*", key);
343d5015272SBrian Somers #endif
344d5015272SBrian Somers 
345d5015272SBrian Somers   return 0;			/* Invalid */
346af57ed9fSAtsushi Murai }
347af57ed9fSAtsushi Murai 
348af57ed9fSAtsushi Murai char *
349057f1760SBrian Somers auth_GetSecret(const char *name, size_t len)
350af57ed9fSAtsushi Murai {
351d5015272SBrian Somers   /* Used by CHAP routines */
352d5015272SBrian Somers 
353af57ed9fSAtsushi Murai   FILE *fp;
354c39aa54eSBrian Somers   int n, lineno;
3559c97abd8SBrian Somers   char *vector[5];
356af1e7664SBrian Somers   const char *slash;
357c506ecd5SBrian Somers   static char buff[LINE_LEN];	/* vector[] will point here when returned */
358af57ed9fSAtsushi Murai 
359643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
360af57ed9fSAtsushi Murai   if (fp == NULL)
361af57ed9fSAtsushi Murai     return (NULL);
362d5015272SBrian Somers 
363af1e7664SBrian Somers again:
364c39aa54eSBrian Somers   lineno = 0;
36570ee81ffSBrian Somers   while (fgets(buff, sizeof buff, fp)) {
366c39aa54eSBrian Somers     lineno++;
367af57ed9fSAtsushi Murai     if (buff[0] == '#')
368af57ed9fSAtsushi Murai       continue;
369c506ecd5SBrian Somers     n = strlen(buff) - 1;
370c506ecd5SBrian Somers     if (buff[n] == '\n')
371c506ecd5SBrian Somers       buff[n] = '\0';	/* Trim the '\n' */
37270ee81ffSBrian Somers     memset(vector, '\0', sizeof vector);
3735b78bdf8SBrian Somers     if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0)
374c39aa54eSBrian Somers       log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno);
375af57ed9fSAtsushi Murai     if (n < 2)
376af57ed9fSAtsushi Murai       continue;
377972a1bcfSBrian Somers     if (strlen(vector[0]) == len && strncmp(vector[0], name, len) == 0) {
378643f4904SBrian Somers       CloseSecret(fp);
379d5015272SBrian Somers       return vector[1];
380af57ed9fSAtsushi Murai     }
381af57ed9fSAtsushi Murai   }
382af1e7664SBrian Somers 
383af1e7664SBrian Somers   if ((slash = strrchr(name, '\\')) != NULL && slash[1]) {
384af1e7664SBrian Somers     /* Go back and look for the name without the leading domain */
385af1e7664SBrian Somers     len -= slash - name + 1;
386af1e7664SBrian Somers     name = slash + 1;
387af1e7664SBrian Somers     rewind(fp);
388af1e7664SBrian Somers     goto again;
389af1e7664SBrian Somers   }
390af1e7664SBrian Somers 
391af57ed9fSAtsushi Murai   CloseSecret(fp);
392af57ed9fSAtsushi Murai   return (NULL);		/* Invalid */
393af57ed9fSAtsushi Murai }
39453c9f6c0SAtsushi Murai 
39553c9f6c0SAtsushi Murai static void
396b6e82f33SBrian Somers AuthTimeout(void *vauthp)
39753c9f6c0SAtsushi Murai {
398b6e82f33SBrian Somers   struct authinfo *authp = (struct authinfo *)vauthp;
39953c9f6c0SAtsushi Murai 
400dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
40153c9f6c0SAtsushi Murai   if (--authp->retry > 0) {
402f0cdd9c0SBrian Somers     authp->id++;
403f0cdd9c0SBrian Somers     (*authp->fn.req)(authp);
404dd7e2610SBrian Somers     timer_Start(&authp->authtimer);
405aceaed92SBrian Somers   } else {
406aceaed92SBrian Somers     log_Printf(LogPHASE, "Auth: No response from server\n");
407aceaed92SBrian Somers     datalink_AuthNotOk(authp->physical->dl);
408aceaed92SBrian Somers   }
40953c9f6c0SAtsushi Murai }
41053c9f6c0SAtsushi Murai 
41153c9f6c0SAtsushi Murai void
412f0cdd9c0SBrian Somers auth_Init(struct authinfo *authp, struct physical *p, auth_func req,
413f0cdd9c0SBrian Somers           auth_func success, auth_func failure)
41453c9f6c0SAtsushi Murai {
415f0cdd9c0SBrian Somers   memset(authp, '\0', sizeof(struct authinfo));
416479508cfSBrian Somers   authp->cfg.fsm.timeout = DEF_FSMRETRY;
417479508cfSBrian Somers   authp->cfg.fsm.maxreq = DEF_FSMAUTHTRIES;
418479508cfSBrian Somers   authp->cfg.fsm.maxtrm = 0;	/* not used */
419f0cdd9c0SBrian Somers   authp->fn.req = req;
420f0cdd9c0SBrian Somers   authp->fn.success = success;
421f0cdd9c0SBrian Somers   authp->fn.failure = failure;
422f0cdd9c0SBrian Somers   authp->physical = p;
423e2ebb036SBrian Somers }
42453c9f6c0SAtsushi Murai 
425e2ebb036SBrian Somers void
426f0cdd9c0SBrian Somers auth_StartReq(struct authinfo *authp)
427e2ebb036SBrian Somers {
428dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
429e2ebb036SBrian Somers   authp->authtimer.func = AuthTimeout;
4303b0f8d2eSBrian Somers   authp->authtimer.name = "auth";
431479508cfSBrian Somers   authp->authtimer.load = authp->cfg.fsm.timeout * SECTICKS;
432e2ebb036SBrian Somers   authp->authtimer.arg = (void *)authp;
433479508cfSBrian Somers   authp->retry = authp->cfg.fsm.maxreq;
43453c9f6c0SAtsushi Murai   authp->id = 1;
435f0cdd9c0SBrian Somers   (*authp->fn.req)(authp);
436dd7e2610SBrian Somers   timer_Start(&authp->authtimer);
43753c9f6c0SAtsushi Murai }
43853c9f6c0SAtsushi Murai 
43953c9f6c0SAtsushi Murai void
440dd7e2610SBrian Somers auth_StopTimer(struct authinfo *authp)
44153c9f6c0SAtsushi Murai {
442dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
443f0cdd9c0SBrian Somers }
444f0cdd9c0SBrian Somers 
445f0cdd9c0SBrian Somers struct mbuf *
446f0cdd9c0SBrian Somers auth_ReadHeader(struct authinfo *authp, struct mbuf *bp)
447f0cdd9c0SBrian Somers {
448057f1760SBrian Somers   size_t len;
449f0cdd9c0SBrian Somers 
45026af0ae9SBrian Somers   len = m_length(bp);
451f0cdd9c0SBrian Somers   if (len >= sizeof authp->in.hdr) {
452f0cdd9c0SBrian Somers     bp = mbuf_Read(bp, (u_char *)&authp->in.hdr, sizeof authp->in.hdr);
453f0cdd9c0SBrian Somers     if (len >= ntohs(authp->in.hdr.length))
454f0cdd9c0SBrian Somers       return bp;
455b7ff18adSBrian Somers     authp->in.hdr.length = htons(0);
4561814213eSMarcel Moolenaar     log_Printf(LogWARN, "auth_ReadHeader: Short packet (%u > %zu) !\n",
457b31a24caSBrian Somers                ntohs(authp->in.hdr.length), len);
458b7ff18adSBrian Somers   } else {
459b7ff18adSBrian Somers     authp->in.hdr.length = htons(0);
4601814213eSMarcel Moolenaar     log_Printf(LogWARN, "auth_ReadHeader: Short packet header (%u > %zu) !\n",
461eb2d27cfSBrian Somers                (int)(sizeof authp->in.hdr), len);
462b7ff18adSBrian Somers   }
463f0cdd9c0SBrian Somers 
46426af0ae9SBrian Somers   m_freem(bp);
465f0cdd9c0SBrian Somers   return NULL;
466f0cdd9c0SBrian Somers }
467f0cdd9c0SBrian Somers 
468f0cdd9c0SBrian Somers struct mbuf *
469057f1760SBrian Somers auth_ReadName(struct authinfo *authp, struct mbuf *bp, size_t len)
470f0cdd9c0SBrian Somers {
471f0cdd9c0SBrian Somers   if (len > sizeof authp->in.name - 1)
4721814213eSMarcel Moolenaar     log_Printf(LogWARN, "auth_ReadName: Name too long (%zu) !\n", len);
473f0cdd9c0SBrian Somers   else {
474057f1760SBrian Somers     size_t mlen = m_length(bp);
475f0cdd9c0SBrian Somers 
476f0cdd9c0SBrian Somers     if (len > mlen)
4771814213eSMarcel Moolenaar       log_Printf(LogWARN, "auth_ReadName: Short packet (%zu > %zu) !\n",
478b31a24caSBrian Somers                  len, mlen);
479f0cdd9c0SBrian Somers     else {
480f0cdd9c0SBrian Somers       bp = mbuf_Read(bp, (u_char *)authp->in.name, len);
481f0cdd9c0SBrian Somers       authp->in.name[len] = '\0';
482f0cdd9c0SBrian Somers       return bp;
483f0cdd9c0SBrian Somers     }
484f0cdd9c0SBrian Somers   }
485f0cdd9c0SBrian Somers 
486f0cdd9c0SBrian Somers   *authp->in.name = '\0';
48726af0ae9SBrian Somers   m_freem(bp);
488f0cdd9c0SBrian Somers   return NULL;
48953c9f6c0SAtsushi Murai }
490