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 */
3065309e5cSBrian Somers
31972a1bcfSBrian Somers #include <sys/param.h>
3275240ed1SBrian Somers #include <netinet/in.h>
33eaa4df37SBrian Somers #include <netinet/in_systm.h>
34eaa4df37SBrian Somers #include <netinet/ip.h>
3530949fd4SBrian Somers #include <sys/socket.h>
361fa665f5SBrian Somers #include <sys/un.h>
3775240ed1SBrian Somers
38d5015272SBrian Somers #include <pwd.h>
3975240ed1SBrian Somers #include <stdio.h>
4096fd764fSRuslan Ermilov #include <stdlib.h>
4175240ed1SBrian Somers #include <string.h>
42aceaed92SBrian Somers #include <termios.h>
4375240ed1SBrian Somers #include <unistd.h>
4475240ed1SBrian Somers
4596fd764fSRuslan Ermilov #ifndef NOPAM
4696fd764fSRuslan Ermilov #include <security/pam_appl.h>
4729476579SDag-Erling Smørgrav #ifdef OPENPAM
4896fd764fSRuslan Ermilov #include <security/openpam.h>
4996fd764fSRuslan Ermilov #endif
5096fd764fSRuslan Ermilov #endif /* !NOPAM */
5196fd764fSRuslan Ermilov
525d9e6103SBrian Somers #include "layer.h"
5375240ed1SBrian Somers #include "mbuf.h"
5475240ed1SBrian Somers #include "defs.h"
55aceaed92SBrian Somers #include "log.h"
5675240ed1SBrian Somers #include "timer.h"
57af57ed9fSAtsushi Murai #include "fsm.h"
5829e275ceSBrian Somers #include "iplist.h"
5929e275ceSBrian Somers #include "throughput.h"
60eaa4df37SBrian Somers #include "slcompress.h"
615a72b6edSBrian Somers #include "lqr.h"
625a72b6edSBrian Somers #include "hdlc.h"
6330949fd4SBrian Somers #include "ncpaddr.h"
64af57ed9fSAtsushi Murai #include "ipcp.h"
6553c9f6c0SAtsushi Murai #include "auth.h"
6675240ed1SBrian Somers #include "systems.h"
676140ba11SBrian Somers #include "lcp.h"
683b0f8d2eSBrian Somers #include "ccp.h"
696140ba11SBrian Somers #include "link.h"
7042d4d396SBrian Somers #include "descriptor.h"
71b6dec9f0SBrian Somers #include "chat.h"
725d9e6103SBrian Somers #include "proto.h"
735ca5389aSBrian Somers #include "filter.h"
743b0f8d2eSBrian Somers #include "mp.h"
75972a1bcfSBrian Somers #ifndef NORADIUS
76972a1bcfSBrian Somers #include "radius.h"
77972a1bcfSBrian Somers #endif
78aceaed92SBrian Somers #include "cbcp.h"
79aceaed92SBrian Somers #include "chap.h"
80aceaed92SBrian Somers #include "async.h"
81aceaed92SBrian Somers #include "physical.h"
82aceaed92SBrian Somers #include "datalink.h"
8330949fd4SBrian Somers #include "ipv6cp.h"
8430949fd4SBrian Somers #include "ncp.h"
855828db6dSBrian Somers #include "bundle.h"
86af57ed9fSAtsushi Murai
87455aabc3SBrian Somers const char *
Auth2Nam(u_short auth,u_char type)885e315498SBrian Somers Auth2Nam(u_short auth, u_char type)
89ed6a16c1SPoul-Henning Kamp {
905e315498SBrian Somers static char chap[10];
915e315498SBrian Somers
92455aabc3SBrian Somers switch (auth) {
93455aabc3SBrian Somers case PROTO_PAP:
94455aabc3SBrian Somers return "PAP";
95455aabc3SBrian Somers case PROTO_CHAP:
965e315498SBrian Somers snprintf(chap, sizeof chap, "CHAP 0x%02x", type);
975e315498SBrian Somers return chap;
98455aabc3SBrian Somers case 0:
99455aabc3SBrian Somers return "none";
100d025849cSBrian Somers }
101455aabc3SBrian Somers return "unknown";
10253c9f6c0SAtsushi Murai }
10353c9f6c0SAtsushi Murai
10429476579SDag-Erling Smørgrav #if !defined(NOPAM) && !defined(OPENPAM)
10596fd764fSRuslan Ermilov static int
pam_conv(int n,const struct pam_message ** msg,struct pam_response ** resp,void * data)10696fd764fSRuslan Ermilov pam_conv(int n, const struct pam_message **msg, struct pam_response **resp,
10796fd764fSRuslan Ermilov void *data)
10896fd764fSRuslan Ermilov {
10996fd764fSRuslan Ermilov
11096fd764fSRuslan Ermilov if (n != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF)
11196fd764fSRuslan Ermilov return (PAM_CONV_ERR);
11296fd764fSRuslan Ermilov if ((*resp = malloc(sizeof(struct pam_response))) == NULL)
11396fd764fSRuslan Ermilov return (PAM_CONV_ERR);
11496fd764fSRuslan Ermilov (*resp)[0].resp = strdup((const char *)data);
11596fd764fSRuslan Ermilov (*resp)[0].resp_retcode = 0;
11696fd764fSRuslan Ermilov
11796fd764fSRuslan Ermilov return ((*resp)[0].resp != NULL ? PAM_SUCCESS : PAM_CONV_ERR);
11896fd764fSRuslan Ermilov }
11929476579SDag-Erling Smørgrav #endif /* !defined(NOPAM) && !defined(OPENPAM) */
12096fd764fSRuslan Ermilov
121d5015272SBrian Somers static int
auth_CheckPasswd(const char * name,const char * data,const char * key)122d5015272SBrian Somers auth_CheckPasswd(const char *name, const char *data, const char *key)
123d5015272SBrian Somers {
124d5015272SBrian Somers if (!strcmp(data, "*")) {
12596fd764fSRuslan Ermilov #ifdef NOPAM
126d5015272SBrian Somers /* Then look up the real password database */
127d5015272SBrian Somers struct passwd *pw;
128af3b49efSConrad Meyer int result = 0;
12929dcf726SKevin Lo char *cryptpw;
130d5015272SBrian Somers
131af3b49efSConrad Meyer pw = getpwnam(name);
132af3b49efSConrad Meyer
133af3b49efSConrad Meyer if (pw) {
13429dcf726SKevin Lo cryptpw = crypt(key, pw->pw_passwd);
135af3b49efSConrad Meyer
136af3b49efSConrad Meyer result = (cryptpw != NULL) && !strcmp(cryptpw, pw->pw_passwd);
137af3b49efSConrad Meyer }
138af3b49efSConrad Meyer
139d5015272SBrian Somers endpwent();
140af3b49efSConrad Meyer
141d5015272SBrian Somers return result;
14296fd764fSRuslan Ermilov #else /* !NOPAM */
14396fd764fSRuslan Ermilov /* Then consult with PAM. */
14496fd764fSRuslan Ermilov pam_handle_t *pamh;
14596fd764fSRuslan Ermilov int status;
14696fd764fSRuslan Ermilov
14796fd764fSRuslan Ermilov struct pam_conv pamc = {
14829476579SDag-Erling Smørgrav #ifdef OPENPAM
14996fd764fSRuslan Ermilov &openpam_nullconv, NULL
15096fd764fSRuslan Ermilov #else
15129476579SDag-Erling Smørgrav &pam_conv, key
15296fd764fSRuslan Ermilov #endif
15396fd764fSRuslan Ermilov };
15496fd764fSRuslan Ermilov
15596fd764fSRuslan Ermilov if (pam_start("ppp", name, &pamc, &pamh) != PAM_SUCCESS)
15696fd764fSRuslan Ermilov return (0);
15729476579SDag-Erling Smørgrav #ifdef OPENPAM
15896fd764fSRuslan Ermilov if ((status = pam_set_item(pamh, PAM_AUTHTOK, key)) == PAM_SUCCESS)
15996fd764fSRuslan Ermilov #endif
16096fd764fSRuslan Ermilov status = pam_authenticate(pamh, 0);
16196fd764fSRuslan Ermilov pam_end(pamh, status);
16296fd764fSRuslan Ermilov return (status == PAM_SUCCESS);
16396fd764fSRuslan Ermilov #endif /* !NOPAM */
164d5015272SBrian Somers }
165d5015272SBrian Somers
166d5015272SBrian Somers return !strcmp(data, key);
167d5015272SBrian Somers }
168d5015272SBrian Somers
1691ae349f5Scvs2svn int
auth_SetPhoneList(const char * name,char * phone,int phonelen)17092b09558SBrian Somers auth_SetPhoneList(const char *name, char *phone, int phonelen)
17192b09558SBrian Somers {
17292b09558SBrian Somers FILE *fp;
173c39aa54eSBrian Somers int n, lineno;
174af1e7664SBrian Somers char *vector[6], buff[LINE_LEN];
175af1e7664SBrian Somers const char *slash;
17692b09558SBrian Somers
17792b09558SBrian Somers fp = OpenSecret(SECRETFILE);
17892b09558SBrian Somers if (fp != NULL) {
179af1e7664SBrian Somers again:
180af1e7664SBrian Somers lineno = 0;
18192b09558SBrian Somers while (fgets(buff, sizeof buff, fp)) {
182c39aa54eSBrian Somers lineno++;
18392b09558SBrian Somers if (buff[0] == '#')
18492b09558SBrian Somers continue;
18592b09558SBrian Somers buff[strlen(buff) - 1] = '\0';
18692b09558SBrian Somers memset(vector, '\0', sizeof vector);
1875b78bdf8SBrian Somers if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0)
188c39aa54eSBrian Somers log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno);
18992b09558SBrian Somers if (n < 5)
19092b09558SBrian Somers continue;
19192b09558SBrian Somers if (strcmp(vector[0], name) == 0) {
19292b09558SBrian Somers CloseSecret(fp);
19392b09558SBrian Somers if (*vector[4] == '\0')
19492b09558SBrian Somers return 0;
19592b09558SBrian Somers strncpy(phone, vector[4], phonelen - 1);
19692b09558SBrian Somers phone[phonelen - 1] = '\0';
19792b09558SBrian Somers return 1; /* Valid */
19892b09558SBrian Somers }
19992b09558SBrian Somers }
200af1e7664SBrian Somers
201af1e7664SBrian Somers if ((slash = strrchr(name, '\\')) != NULL && slash[1]) {
202af1e7664SBrian Somers /* Look for the name without the leading domain */
203af1e7664SBrian Somers name = slash + 1;
204af1e7664SBrian Somers rewind(fp);
205af1e7664SBrian Somers goto again;
206af1e7664SBrian Somers }
207af1e7664SBrian Somers
20892b09558SBrian Somers CloseSecret(fp);
20992b09558SBrian Somers }
21092b09558SBrian Somers *phone = '\0';
21192b09558SBrian Somers return 0;
21292b09558SBrian Somers }
21392b09558SBrian Somers
21492b09558SBrian Somers int
auth_Select(struct bundle * bundle,const char * name)21592b09558SBrian Somers auth_Select(struct bundle *bundle, const char *name)
216944f7098SBrian Somers {
21753c9f6c0SAtsushi Murai FILE *fp;
218c39aa54eSBrian Somers int n, lineno;
219af1e7664SBrian Somers char *vector[5], buff[LINE_LEN];
220af1e7664SBrian Somers const char *slash;
22153c9f6c0SAtsushi Murai
222643f4904SBrian Somers if (*name == '\0') {
223972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE);
224643f4904SBrian Somers return 1;
225643f4904SBrian Somers }
226643f4904SBrian Somers
227972a1bcfSBrian Somers #ifndef NORADIUS
22833b47634STatsumi Hosokawa if (bundle->radius.valid && bundle->radius.ip.s_addr != INADDR_NONE &&
22933b47634STatsumi Hosokawa bundle->radius.ip.s_addr != RADIUS_INADDR_POOL) {
230972a1bcfSBrian Somers /* We've got a radius IP - it overrides everything */
231972a1bcfSBrian Somers if (!ipcp_UseHisIPaddr(bundle, bundle->radius.ip))
232972a1bcfSBrian Somers return 0;
233972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, bundle->radius.mask.s_addr);
234972a1bcfSBrian Somers /* Continue with ppp.secret in case we've got a new label */
235972a1bcfSBrian Somers }
236972a1bcfSBrian Somers #endif
237972a1bcfSBrian Somers
238643f4904SBrian Somers fp = OpenSecret(SECRETFILE);
239d5015272SBrian Somers if (fp != NULL) {
240af1e7664SBrian Somers again:
241af1e7664SBrian Somers lineno = 0;
24270ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) {
243c39aa54eSBrian Somers lineno++;
24453c9f6c0SAtsushi Murai if (buff[0] == '#')
24553c9f6c0SAtsushi Murai continue;
246501f5480SBrian Somers buff[strlen(buff) - 1] = '\0';
24770ee81ffSBrian Somers memset(vector, '\0', sizeof vector);
2485b78bdf8SBrian Somers if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0)
249c39aa54eSBrian Somers log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno);
2501ae349f5Scvs2svn if (n < 2)
25153c9f6c0SAtsushi Murai continue;
252501f5480SBrian Somers if (strcmp(vector[0], name) == 0) {
2531ae349f5Scvs2svn CloseSecret(fp);
254972a1bcfSBrian Somers #ifndef NORADIUS
255972a1bcfSBrian Somers if (!bundle->radius.valid || bundle->radius.ip.s_addr == INADDR_NONE) {
256972a1bcfSBrian Somers #endif
25792b09558SBrian Somers if (n > 2 && *vector[2] && strcmp(vector[2], "*") &&
25892b09558SBrian Somers !ipcp_UseHisaddr(bundle, vector[2], 1))
259643f4904SBrian Somers return 0;
260972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE);
261972a1bcfSBrian Somers #ifndef NORADIUS
262972a1bcfSBrian Somers }
263972a1bcfSBrian Somers #endif
26492b09558SBrian Somers if (n > 3 && *vector[3] && strcmp(vector[3], "*"))
26549052c95SBrian Somers bundle_SetLabel(bundle, vector[3]);
266d5015272SBrian Somers return 1; /* Valid */
26753c9f6c0SAtsushi Murai }
268501f5480SBrian Somers }
269af1e7664SBrian Somers
270af1e7664SBrian Somers if ((slash = strrchr(name, '\\')) != NULL && slash[1]) {
271af1e7664SBrian Somers /* Look for the name without the leading domain */
272af1e7664SBrian Somers name = slash + 1;
273af1e7664SBrian Somers rewind(fp);
274af1e7664SBrian Somers goto again;
275af1e7664SBrian Somers }
276af1e7664SBrian Somers
27753c9f6c0SAtsushi Murai CloseSecret(fp);
278643f4904SBrian Somers }
279643f4904SBrian Somers
280643f4904SBrian Somers #ifndef NOPASSWDAUTH
281643f4904SBrian Somers /* Let 'em in anyway - they must have been in the passwd file */
282972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE);
283643f4904SBrian Somers return 1;
284643f4904SBrian Somers #else
285972a1bcfSBrian Somers #ifndef NORADIUS
286972a1bcfSBrian Somers if (bundle->radius.valid)
287972a1bcfSBrian Somers return 1;
288972a1bcfSBrian Somers #endif
289972a1bcfSBrian Somers
290972a1bcfSBrian Somers /* Disappeared from ppp.secret ??? */
291643f4904SBrian Somers return 0;
292643f4904SBrian Somers #endif
29353c9f6c0SAtsushi Murai }
29453c9f6c0SAtsushi Murai
295af57ed9fSAtsushi Murai int
auth_Validate(struct bundle * bundle,const char * name,const char * key)296057f1760SBrian Somers auth_Validate(struct bundle *bundle, const char *name, const char *key)
297af57ed9fSAtsushi Murai {
298643f4904SBrian Somers /* Used by PAP routines */
299643f4904SBrian Somers
300af57ed9fSAtsushi Murai FILE *fp;
301c39aa54eSBrian Somers int n, lineno;
302af1e7664SBrian Somers char *vector[5], buff[LINE_LEN];
303af1e7664SBrian Somers const char *slash;
304af57ed9fSAtsushi Murai
305643f4904SBrian Somers fp = OpenSecret(SECRETFILE);
306af1e7664SBrian Somers again:
307c39aa54eSBrian Somers lineno = 0;
308643f4904SBrian Somers if (fp != NULL) {
30970ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) {
310c39aa54eSBrian Somers lineno++;
311af57ed9fSAtsushi Murai if (buff[0] == '#')
312af57ed9fSAtsushi Murai continue;
313af57ed9fSAtsushi Murai buff[strlen(buff) - 1] = 0;
31470ee81ffSBrian Somers memset(vector, '\0', sizeof vector);
3155b78bdf8SBrian Somers if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0)
316c39aa54eSBrian Somers log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno);
317af57ed9fSAtsushi Murai if (n < 2)
318af57ed9fSAtsushi Murai continue;
319972a1bcfSBrian Somers if (strcmp(vector[0], name) == 0) {
320af57ed9fSAtsushi Murai CloseSecret(fp);
321972a1bcfSBrian Somers return auth_CheckPasswd(name, vector[1], key);
322af57ed9fSAtsushi Murai }
323af57ed9fSAtsushi Murai }
324d5015272SBrian Somers }
325d5015272SBrian Somers
326af1e7664SBrian Somers if ((slash = strrchr(name, '\\')) != NULL && slash[1]) {
327af1e7664SBrian Somers /* Look for the name without the leading domain */
328af1e7664SBrian Somers name = slash + 1;
329af1e7664SBrian Somers if (fp != NULL) {
330af1e7664SBrian Somers rewind(fp);
331af1e7664SBrian Somers goto again;
332af1e7664SBrian Somers }
333af1e7664SBrian Somers }
334af1e7664SBrian Somers
335af1e7664SBrian Somers if (fp != NULL)
336af1e7664SBrian Somers CloseSecret(fp);
337af1e7664SBrian Somers
338d5015272SBrian Somers #ifndef NOPASSWDAUTH
3391342caedSBrian Somers if (Enabled(bundle, OPT_PASSWDAUTH))
340972a1bcfSBrian Somers return auth_CheckPasswd(name, "*", key);
341d5015272SBrian Somers #endif
342d5015272SBrian Somers
343d5015272SBrian Somers return 0; /* Invalid */
344af57ed9fSAtsushi Murai }
345af57ed9fSAtsushi Murai
346af57ed9fSAtsushi Murai char *
auth_GetSecret(const char * name,size_t len)347057f1760SBrian Somers auth_GetSecret(const char *name, size_t len)
348af57ed9fSAtsushi Murai {
349d5015272SBrian Somers /* Used by CHAP routines */
350d5015272SBrian Somers
351af57ed9fSAtsushi Murai FILE *fp;
352c39aa54eSBrian Somers int n, lineno;
3539c97abd8SBrian Somers char *vector[5];
354af1e7664SBrian Somers const char *slash;
355c506ecd5SBrian Somers static char buff[LINE_LEN]; /* vector[] will point here when returned */
356af57ed9fSAtsushi Murai
357643f4904SBrian Somers fp = OpenSecret(SECRETFILE);
358af57ed9fSAtsushi Murai if (fp == NULL)
359af57ed9fSAtsushi Murai return (NULL);
360d5015272SBrian Somers
361af1e7664SBrian Somers again:
362c39aa54eSBrian Somers lineno = 0;
36370ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) {
364c39aa54eSBrian Somers lineno++;
365af57ed9fSAtsushi Murai if (buff[0] == '#')
366af57ed9fSAtsushi Murai continue;
367c506ecd5SBrian Somers n = strlen(buff) - 1;
368c506ecd5SBrian Somers if (buff[n] == '\n')
369c506ecd5SBrian Somers buff[n] = '\0'; /* Trim the '\n' */
37070ee81ffSBrian Somers memset(vector, '\0', sizeof vector);
3715b78bdf8SBrian Somers if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0)
372c39aa54eSBrian Somers log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno);
373af57ed9fSAtsushi Murai if (n < 2)
374af57ed9fSAtsushi Murai continue;
375972a1bcfSBrian Somers if (strlen(vector[0]) == len && strncmp(vector[0], name, len) == 0) {
376643f4904SBrian Somers CloseSecret(fp);
377d5015272SBrian Somers return vector[1];
378af57ed9fSAtsushi Murai }
379af57ed9fSAtsushi Murai }
380af1e7664SBrian Somers
381af1e7664SBrian Somers if ((slash = strrchr(name, '\\')) != NULL && slash[1]) {
382af1e7664SBrian Somers /* Go back and look for the name without the leading domain */
383af1e7664SBrian Somers len -= slash - name + 1;
384af1e7664SBrian Somers name = slash + 1;
385af1e7664SBrian Somers rewind(fp);
386af1e7664SBrian Somers goto again;
387af1e7664SBrian Somers }
388af1e7664SBrian Somers
389af57ed9fSAtsushi Murai CloseSecret(fp);
390af57ed9fSAtsushi Murai return (NULL); /* Invalid */
391af57ed9fSAtsushi Murai }
39253c9f6c0SAtsushi Murai
39353c9f6c0SAtsushi Murai static void
AuthTimeout(void * vauthp)394b6e82f33SBrian Somers AuthTimeout(void *vauthp)
39553c9f6c0SAtsushi Murai {
396b6e82f33SBrian Somers struct authinfo *authp = (struct authinfo *)vauthp;
39753c9f6c0SAtsushi Murai
398dd7e2610SBrian Somers timer_Stop(&authp->authtimer);
39953c9f6c0SAtsushi Murai if (--authp->retry > 0) {
400f0cdd9c0SBrian Somers authp->id++;
401f0cdd9c0SBrian Somers (*authp->fn.req)(authp);
402dd7e2610SBrian Somers timer_Start(&authp->authtimer);
403aceaed92SBrian Somers } else {
404aceaed92SBrian Somers log_Printf(LogPHASE, "Auth: No response from server\n");
405aceaed92SBrian Somers datalink_AuthNotOk(authp->physical->dl);
406aceaed92SBrian Somers }
40753c9f6c0SAtsushi Murai }
40853c9f6c0SAtsushi Murai
40953c9f6c0SAtsushi Murai void
auth_Init(struct authinfo * authp,struct physical * p,auth_func req,auth_func success,auth_func failure)410f0cdd9c0SBrian Somers auth_Init(struct authinfo *authp, struct physical *p, auth_func req,
411f0cdd9c0SBrian Somers auth_func success, auth_func failure)
41253c9f6c0SAtsushi Murai {
413f0cdd9c0SBrian Somers memset(authp, '\0', sizeof(struct authinfo));
414479508cfSBrian Somers authp->cfg.fsm.timeout = DEF_FSMRETRY;
415479508cfSBrian Somers authp->cfg.fsm.maxreq = DEF_FSMAUTHTRIES;
416479508cfSBrian Somers authp->cfg.fsm.maxtrm = 0; /* not used */
417f0cdd9c0SBrian Somers authp->fn.req = req;
418f0cdd9c0SBrian Somers authp->fn.success = success;
419f0cdd9c0SBrian Somers authp->fn.failure = failure;
420f0cdd9c0SBrian Somers authp->physical = p;
421e2ebb036SBrian Somers }
42253c9f6c0SAtsushi Murai
423e2ebb036SBrian Somers void
auth_StartReq(struct authinfo * authp)424f0cdd9c0SBrian Somers auth_StartReq(struct authinfo *authp)
425e2ebb036SBrian Somers {
426dd7e2610SBrian Somers timer_Stop(&authp->authtimer);
427e2ebb036SBrian Somers authp->authtimer.func = AuthTimeout;
4283b0f8d2eSBrian Somers authp->authtimer.name = "auth";
429479508cfSBrian Somers authp->authtimer.load = authp->cfg.fsm.timeout * SECTICKS;
430e2ebb036SBrian Somers authp->authtimer.arg = (void *)authp;
431479508cfSBrian Somers authp->retry = authp->cfg.fsm.maxreq;
43253c9f6c0SAtsushi Murai authp->id = 1;
433f0cdd9c0SBrian Somers (*authp->fn.req)(authp);
434dd7e2610SBrian Somers timer_Start(&authp->authtimer);
43553c9f6c0SAtsushi Murai }
43653c9f6c0SAtsushi Murai
43753c9f6c0SAtsushi Murai void
auth_StopTimer(struct authinfo * authp)438dd7e2610SBrian Somers auth_StopTimer(struct authinfo *authp)
43953c9f6c0SAtsushi Murai {
440dd7e2610SBrian Somers timer_Stop(&authp->authtimer);
441f0cdd9c0SBrian Somers }
442f0cdd9c0SBrian Somers
443f0cdd9c0SBrian Somers struct mbuf *
auth_ReadHeader(struct authinfo * authp,struct mbuf * bp)444f0cdd9c0SBrian Somers auth_ReadHeader(struct authinfo *authp, struct mbuf *bp)
445f0cdd9c0SBrian Somers {
446057f1760SBrian Somers size_t len;
447f0cdd9c0SBrian Somers
44826af0ae9SBrian Somers len = m_length(bp);
449f0cdd9c0SBrian Somers if (len >= sizeof authp->in.hdr) {
450f0cdd9c0SBrian Somers bp = mbuf_Read(bp, (u_char *)&authp->in.hdr, sizeof authp->in.hdr);
451f0cdd9c0SBrian Somers if (len >= ntohs(authp->in.hdr.length))
452f0cdd9c0SBrian Somers return bp;
453b7ff18adSBrian Somers authp->in.hdr.length = htons(0);
4541814213eSMarcel Moolenaar log_Printf(LogWARN, "auth_ReadHeader: Short packet (%u > %zu) !\n",
455b31a24caSBrian Somers ntohs(authp->in.hdr.length), len);
456b7ff18adSBrian Somers } else {
457b7ff18adSBrian Somers authp->in.hdr.length = htons(0);
4581814213eSMarcel Moolenaar log_Printf(LogWARN, "auth_ReadHeader: Short packet header (%u > %zu) !\n",
459eb2d27cfSBrian Somers (int)(sizeof authp->in.hdr), len);
460b7ff18adSBrian Somers }
461f0cdd9c0SBrian Somers
46226af0ae9SBrian Somers m_freem(bp);
463f0cdd9c0SBrian Somers return NULL;
464f0cdd9c0SBrian Somers }
465f0cdd9c0SBrian Somers
466f0cdd9c0SBrian Somers struct mbuf *
auth_ReadName(struct authinfo * authp,struct mbuf * bp,size_t len)467057f1760SBrian Somers auth_ReadName(struct authinfo *authp, struct mbuf *bp, size_t len)
468f0cdd9c0SBrian Somers {
469f0cdd9c0SBrian Somers if (len > sizeof authp->in.name - 1)
4701814213eSMarcel Moolenaar log_Printf(LogWARN, "auth_ReadName: Name too long (%zu) !\n", len);
471f0cdd9c0SBrian Somers else {
472057f1760SBrian Somers size_t mlen = m_length(bp);
473f0cdd9c0SBrian Somers
474f0cdd9c0SBrian Somers if (len > mlen)
4751814213eSMarcel Moolenaar log_Printf(LogWARN, "auth_ReadName: Short packet (%zu > %zu) !\n",
476b31a24caSBrian Somers len, mlen);
477f0cdd9c0SBrian Somers else {
478f0cdd9c0SBrian Somers bp = mbuf_Read(bp, (u_char *)authp->in.name, len);
479f0cdd9c0SBrian Somers authp->in.name[len] = '\0';
480f0cdd9c0SBrian Somers return bp;
481f0cdd9c0SBrian Somers }
482f0cdd9c0SBrian Somers }
483f0cdd9c0SBrian Somers
484f0cdd9c0SBrian Somers *authp->in.name = '\0';
48526af0ae9SBrian Somers m_freem(bp);
486f0cdd9c0SBrian Somers return NULL;
48753c9f6c0SAtsushi Murai }
488