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