165309e5cSBrian Somers /*- 265309e5cSBrian Somers * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 365309e5cSBrian Somers * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 465309e5cSBrian Somers * Internet Initiative Japan, Inc (IIJ) 565309e5cSBrian Somers * All rights reserved. 6af57ed9fSAtsushi Murai * 765309e5cSBrian Somers * Redistribution and use in source and binary forms, with or without 865309e5cSBrian Somers * modification, are permitted provided that the following conditions 965309e5cSBrian Somers * are met: 1065309e5cSBrian Somers * 1. Redistributions of source code must retain the above copyright 1165309e5cSBrian Somers * notice, this list of conditions and the following disclaimer. 1265309e5cSBrian Somers * 2. Redistributions in binary form must reproduce the above copyright 1365309e5cSBrian Somers * notice, this list of conditions and the following disclaimer in the 1465309e5cSBrian Somers * documentation and/or other materials provided with the distribution. 15af57ed9fSAtsushi Murai * 1665309e5cSBrian Somers * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1765309e5cSBrian Somers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1865309e5cSBrian Somers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1965309e5cSBrian Somers * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2065309e5cSBrian Somers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2165309e5cSBrian Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2265309e5cSBrian Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2365309e5cSBrian Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2465309e5cSBrian Somers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2565309e5cSBrian Somers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2665309e5cSBrian Somers * SUCH DAMAGE. 27af57ed9fSAtsushi Murai * 2897d92980SPeter Wemm * $FreeBSD$ 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> 4796fd764fSRuslan Ermilov #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 * 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 10496fd764fSRuslan Ermilov #if !defined(NOPAM) && !defined(_OPENPAM) 10596fd764fSRuslan Ermilov static int 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 } 11996fd764fSRuslan Ermilov #endif /* !defined(NOPAM) && !defined(_OPENPAM) */ 12096fd764fSRuslan Ermilov 121d5015272SBrian Somers static int 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; 128d5015272SBrian Somers int result; 129d5015272SBrian Somers 130d5015272SBrian Somers result = (pw = getpwnam(name)) && 131d5015272SBrian Somers !strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd); 132d5015272SBrian Somers endpwent(); 133d5015272SBrian Somers return result; 13496fd764fSRuslan Ermilov #else /* !NOPAM */ 13596fd764fSRuslan Ermilov /* Then consult with PAM. */ 13696fd764fSRuslan Ermilov pam_handle_t *pamh; 13796fd764fSRuslan Ermilov int status; 13896fd764fSRuslan Ermilov 13996fd764fSRuslan Ermilov struct pam_conv pamc = { 14096fd764fSRuslan Ermilov #ifdef _OPENPAM 14196fd764fSRuslan Ermilov &openpam_nullconv, NULL 14296fd764fSRuslan Ermilov #else 14396fd764fSRuslan Ermilov &pam_conv, key 14496fd764fSRuslan Ermilov #endif 14596fd764fSRuslan Ermilov }; 14696fd764fSRuslan Ermilov 14796fd764fSRuslan Ermilov if (pam_start("ppp", name, &pamc, &pamh) != PAM_SUCCESS) 14896fd764fSRuslan Ermilov return (0); 14996fd764fSRuslan Ermilov #ifdef _OPENPAM 15096fd764fSRuslan Ermilov if ((status = pam_set_item(pamh, PAM_AUTHTOK, key)) == PAM_SUCCESS) 15196fd764fSRuslan Ermilov #endif 15296fd764fSRuslan Ermilov status = pam_authenticate(pamh, 0); 15396fd764fSRuslan Ermilov pam_end(pamh, status); 15496fd764fSRuslan Ermilov return (status == PAM_SUCCESS); 15596fd764fSRuslan Ermilov #endif /* !NOPAM */ 156d5015272SBrian Somers } 157d5015272SBrian Somers 158d5015272SBrian Somers return !strcmp(data, key); 159d5015272SBrian Somers } 160d5015272SBrian Somers 1611ae349f5Scvs2svn int 16292b09558SBrian Somers auth_SetPhoneList(const char *name, char *phone, int phonelen) 16392b09558SBrian Somers { 16492b09558SBrian Somers FILE *fp; 165c39aa54eSBrian Somers int n, lineno; 166af1e7664SBrian Somers char *vector[6], buff[LINE_LEN]; 167af1e7664SBrian Somers const char *slash; 16892b09558SBrian Somers 16992b09558SBrian Somers fp = OpenSecret(SECRETFILE); 17092b09558SBrian Somers if (fp != NULL) { 171af1e7664SBrian Somers again: 172af1e7664SBrian Somers lineno = 0; 17392b09558SBrian Somers while (fgets(buff, sizeof buff, fp)) { 174c39aa54eSBrian Somers lineno++; 17592b09558SBrian Somers if (buff[0] == '#') 17692b09558SBrian Somers continue; 17792b09558SBrian Somers buff[strlen(buff) - 1] = '\0'; 17892b09558SBrian Somers memset(vector, '\0', sizeof vector); 1795b78bdf8SBrian Somers if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) 180c39aa54eSBrian Somers log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); 18192b09558SBrian Somers if (n < 5) 18292b09558SBrian Somers continue; 18392b09558SBrian Somers if (strcmp(vector[0], name) == 0) { 18492b09558SBrian Somers CloseSecret(fp); 18592b09558SBrian Somers if (*vector[4] == '\0') 18692b09558SBrian Somers return 0; 18792b09558SBrian Somers strncpy(phone, vector[4], phonelen - 1); 18892b09558SBrian Somers phone[phonelen - 1] = '\0'; 18992b09558SBrian Somers return 1; /* Valid */ 19092b09558SBrian Somers } 19192b09558SBrian Somers } 192af1e7664SBrian Somers 193af1e7664SBrian Somers if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { 194af1e7664SBrian Somers /* Look for the name without the leading domain */ 195af1e7664SBrian Somers name = slash + 1; 196af1e7664SBrian Somers rewind(fp); 197af1e7664SBrian Somers goto again; 198af1e7664SBrian Somers } 199af1e7664SBrian Somers 20092b09558SBrian Somers CloseSecret(fp); 20192b09558SBrian Somers } 20292b09558SBrian Somers *phone = '\0'; 20392b09558SBrian Somers return 0; 20492b09558SBrian Somers } 20592b09558SBrian Somers 20692b09558SBrian Somers int 20792b09558SBrian Somers auth_Select(struct bundle *bundle, const char *name) 208944f7098SBrian Somers { 20953c9f6c0SAtsushi Murai FILE *fp; 210c39aa54eSBrian Somers int n, lineno; 211af1e7664SBrian Somers char *vector[5], buff[LINE_LEN]; 212af1e7664SBrian Somers const char *slash; 21353c9f6c0SAtsushi Murai 214643f4904SBrian Somers if (*name == '\0') { 215972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); 216643f4904SBrian Somers return 1; 217643f4904SBrian Somers } 218643f4904SBrian Somers 219972a1bcfSBrian Somers #ifndef NORADIUS 22033b47634STatsumi Hosokawa if (bundle->radius.valid && bundle->radius.ip.s_addr != INADDR_NONE && 22133b47634STatsumi Hosokawa bundle->radius.ip.s_addr != RADIUS_INADDR_POOL) { 222972a1bcfSBrian Somers /* We've got a radius IP - it overrides everything */ 223972a1bcfSBrian Somers if (!ipcp_UseHisIPaddr(bundle, bundle->radius.ip)) 224972a1bcfSBrian Somers return 0; 225972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, bundle->radius.mask.s_addr); 226972a1bcfSBrian Somers /* Continue with ppp.secret in case we've got a new label */ 227972a1bcfSBrian Somers } 228972a1bcfSBrian Somers #endif 229972a1bcfSBrian Somers 230643f4904SBrian Somers fp = OpenSecret(SECRETFILE); 231d5015272SBrian Somers if (fp != NULL) { 232af1e7664SBrian Somers again: 233af1e7664SBrian Somers lineno = 0; 23470ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) { 235c39aa54eSBrian Somers lineno++; 23653c9f6c0SAtsushi Murai if (buff[0] == '#') 23753c9f6c0SAtsushi Murai continue; 238501f5480SBrian Somers buff[strlen(buff) - 1] = '\0'; 23970ee81ffSBrian Somers memset(vector, '\0', sizeof vector); 2405b78bdf8SBrian Somers if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) 241c39aa54eSBrian Somers log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); 2421ae349f5Scvs2svn if (n < 2) 24353c9f6c0SAtsushi Murai continue; 244501f5480SBrian Somers if (strcmp(vector[0], name) == 0) { 2451ae349f5Scvs2svn CloseSecret(fp); 246972a1bcfSBrian Somers #ifndef NORADIUS 247972a1bcfSBrian Somers if (!bundle->radius.valid || bundle->radius.ip.s_addr == INADDR_NONE) { 248972a1bcfSBrian Somers #endif 24992b09558SBrian Somers if (n > 2 && *vector[2] && strcmp(vector[2], "*") && 25092b09558SBrian Somers !ipcp_UseHisaddr(bundle, vector[2], 1)) 251643f4904SBrian Somers return 0; 252972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); 253972a1bcfSBrian Somers #ifndef NORADIUS 254972a1bcfSBrian Somers } 255972a1bcfSBrian Somers #endif 25692b09558SBrian Somers if (n > 3 && *vector[3] && strcmp(vector[3], "*")) 25749052c95SBrian Somers bundle_SetLabel(bundle, vector[3]); 258d5015272SBrian Somers return 1; /* Valid */ 25953c9f6c0SAtsushi Murai } 260501f5480SBrian Somers } 261af1e7664SBrian Somers 262af1e7664SBrian Somers if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { 263af1e7664SBrian Somers /* Look for the name without the leading domain */ 264af1e7664SBrian Somers name = slash + 1; 265af1e7664SBrian Somers rewind(fp); 266af1e7664SBrian Somers goto again; 267af1e7664SBrian Somers } 268af1e7664SBrian Somers 26953c9f6c0SAtsushi Murai CloseSecret(fp); 270643f4904SBrian Somers } 271643f4904SBrian Somers 272643f4904SBrian Somers #ifndef NOPASSWDAUTH 273643f4904SBrian Somers /* Let 'em in anyway - they must have been in the passwd file */ 274972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); 275643f4904SBrian Somers return 1; 276643f4904SBrian Somers #else 277972a1bcfSBrian Somers #ifndef NORADIUS 278972a1bcfSBrian Somers if (bundle->radius.valid) 279972a1bcfSBrian Somers return 1; 280972a1bcfSBrian Somers #endif 281972a1bcfSBrian Somers 282972a1bcfSBrian Somers /* Disappeared from ppp.secret ??? */ 283643f4904SBrian Somers return 0; 284643f4904SBrian Somers #endif 28553c9f6c0SAtsushi Murai } 28653c9f6c0SAtsushi Murai 287af57ed9fSAtsushi Murai int 288972a1bcfSBrian Somers auth_Validate(struct bundle *bundle, const char *name, 289643f4904SBrian Somers const char *key, struct physical *physical) 290af57ed9fSAtsushi Murai { 291643f4904SBrian Somers /* Used by PAP routines */ 292643f4904SBrian Somers 293af57ed9fSAtsushi Murai FILE *fp; 294c39aa54eSBrian Somers int n, lineno; 295af1e7664SBrian Somers char *vector[5], buff[LINE_LEN]; 296af1e7664SBrian Somers const char *slash; 297af57ed9fSAtsushi Murai 298643f4904SBrian Somers fp = OpenSecret(SECRETFILE); 299af1e7664SBrian Somers again: 300c39aa54eSBrian Somers lineno = 0; 301643f4904SBrian Somers if (fp != NULL) { 30270ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) { 303c39aa54eSBrian Somers lineno++; 304af57ed9fSAtsushi Murai if (buff[0] == '#') 305af57ed9fSAtsushi Murai continue; 306af57ed9fSAtsushi Murai buff[strlen(buff) - 1] = 0; 30770ee81ffSBrian Somers memset(vector, '\0', sizeof vector); 3085b78bdf8SBrian Somers if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) 309c39aa54eSBrian Somers log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); 310af57ed9fSAtsushi Murai if (n < 2) 311af57ed9fSAtsushi Murai continue; 312972a1bcfSBrian Somers if (strcmp(vector[0], name) == 0) { 313af57ed9fSAtsushi Murai CloseSecret(fp); 314972a1bcfSBrian Somers return auth_CheckPasswd(name, vector[1], key); 315af57ed9fSAtsushi Murai } 316af57ed9fSAtsushi Murai } 317d5015272SBrian Somers } 318d5015272SBrian Somers 319af1e7664SBrian Somers if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { 320af1e7664SBrian Somers /* Look for the name without the leading domain */ 321af1e7664SBrian Somers name = slash + 1; 322af1e7664SBrian Somers if (fp != NULL) { 323af1e7664SBrian Somers rewind(fp); 324af1e7664SBrian Somers goto again; 325af1e7664SBrian Somers } 326af1e7664SBrian Somers } 327af1e7664SBrian Somers 328af1e7664SBrian Somers if (fp != NULL) 329af1e7664SBrian Somers CloseSecret(fp); 330af1e7664SBrian Somers 331d5015272SBrian Somers #ifndef NOPASSWDAUTH 3321342caedSBrian Somers if (Enabled(bundle, OPT_PASSWDAUTH)) 333972a1bcfSBrian Somers return auth_CheckPasswd(name, "*", key); 334d5015272SBrian Somers #endif 335d5015272SBrian Somers 336d5015272SBrian Somers return 0; /* Invalid */ 337af57ed9fSAtsushi Murai } 338af57ed9fSAtsushi Murai 339af57ed9fSAtsushi Murai char * 340972a1bcfSBrian Somers auth_GetSecret(struct bundle *bundle, const char *name, int len, 341643f4904SBrian Somers struct physical *physical) 342af57ed9fSAtsushi Murai { 343d5015272SBrian Somers /* Used by CHAP routines */ 344d5015272SBrian Somers 345af57ed9fSAtsushi Murai FILE *fp; 346c39aa54eSBrian Somers int n, lineno; 3479c97abd8SBrian Somers char *vector[5]; 348af1e7664SBrian Somers const char *slash; 349c506ecd5SBrian Somers static char buff[LINE_LEN]; /* vector[] will point here when returned */ 350af57ed9fSAtsushi Murai 351643f4904SBrian Somers fp = OpenSecret(SECRETFILE); 352af57ed9fSAtsushi Murai if (fp == NULL) 353af57ed9fSAtsushi Murai return (NULL); 354d5015272SBrian Somers 355af1e7664SBrian Somers again: 356c39aa54eSBrian Somers lineno = 0; 35770ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) { 358c39aa54eSBrian Somers lineno++; 359af57ed9fSAtsushi Murai if (buff[0] == '#') 360af57ed9fSAtsushi Murai continue; 361c506ecd5SBrian Somers n = strlen(buff) - 1; 362c506ecd5SBrian Somers if (buff[n] == '\n') 363c506ecd5SBrian Somers buff[n] = '\0'; /* Trim the '\n' */ 36470ee81ffSBrian Somers memset(vector, '\0', sizeof vector); 3655b78bdf8SBrian Somers if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) 366c39aa54eSBrian Somers log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); 367af57ed9fSAtsushi Murai if (n < 2) 368af57ed9fSAtsushi Murai continue; 369972a1bcfSBrian Somers if (strlen(vector[0]) == len && strncmp(vector[0], name, len) == 0) { 370643f4904SBrian Somers CloseSecret(fp); 371d5015272SBrian Somers return vector[1]; 372af57ed9fSAtsushi Murai } 373af57ed9fSAtsushi Murai } 374af1e7664SBrian Somers 375af1e7664SBrian Somers if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { 376af1e7664SBrian Somers /* Go back and look for the name without the leading domain */ 377af1e7664SBrian Somers len -= slash - name + 1; 378af1e7664SBrian Somers name = slash + 1; 379af1e7664SBrian Somers rewind(fp); 380af1e7664SBrian Somers goto again; 381af1e7664SBrian Somers } 382af1e7664SBrian Somers 383af57ed9fSAtsushi Murai CloseSecret(fp); 384af57ed9fSAtsushi Murai return (NULL); /* Invalid */ 385af57ed9fSAtsushi Murai } 38653c9f6c0SAtsushi Murai 38753c9f6c0SAtsushi Murai static void 388b6e82f33SBrian Somers AuthTimeout(void *vauthp) 38953c9f6c0SAtsushi Murai { 390b6e82f33SBrian Somers struct authinfo *authp = (struct authinfo *)vauthp; 39153c9f6c0SAtsushi Murai 392dd7e2610SBrian Somers timer_Stop(&authp->authtimer); 39353c9f6c0SAtsushi Murai if (--authp->retry > 0) { 394f0cdd9c0SBrian Somers authp->id++; 395f0cdd9c0SBrian Somers (*authp->fn.req)(authp); 396dd7e2610SBrian Somers timer_Start(&authp->authtimer); 397aceaed92SBrian Somers } else { 398aceaed92SBrian Somers log_Printf(LogPHASE, "Auth: No response from server\n"); 399aceaed92SBrian Somers datalink_AuthNotOk(authp->physical->dl); 400aceaed92SBrian Somers } 40153c9f6c0SAtsushi Murai } 40253c9f6c0SAtsushi Murai 40353c9f6c0SAtsushi Murai void 404f0cdd9c0SBrian Somers auth_Init(struct authinfo *authp, struct physical *p, auth_func req, 405f0cdd9c0SBrian Somers auth_func success, auth_func failure) 40653c9f6c0SAtsushi Murai { 407f0cdd9c0SBrian Somers memset(authp, '\0', sizeof(struct authinfo)); 408479508cfSBrian Somers authp->cfg.fsm.timeout = DEF_FSMRETRY; 409479508cfSBrian Somers authp->cfg.fsm.maxreq = DEF_FSMAUTHTRIES; 410479508cfSBrian Somers authp->cfg.fsm.maxtrm = 0; /* not used */ 411f0cdd9c0SBrian Somers authp->fn.req = req; 412f0cdd9c0SBrian Somers authp->fn.success = success; 413f0cdd9c0SBrian Somers authp->fn.failure = failure; 414f0cdd9c0SBrian Somers authp->physical = p; 415e2ebb036SBrian Somers } 41653c9f6c0SAtsushi Murai 417e2ebb036SBrian Somers void 418f0cdd9c0SBrian Somers auth_StartReq(struct authinfo *authp) 419e2ebb036SBrian Somers { 420dd7e2610SBrian Somers timer_Stop(&authp->authtimer); 421e2ebb036SBrian Somers authp->authtimer.func = AuthTimeout; 4223b0f8d2eSBrian Somers authp->authtimer.name = "auth"; 423479508cfSBrian Somers authp->authtimer.load = authp->cfg.fsm.timeout * SECTICKS; 424e2ebb036SBrian Somers authp->authtimer.arg = (void *)authp; 425479508cfSBrian Somers authp->retry = authp->cfg.fsm.maxreq; 42653c9f6c0SAtsushi Murai authp->id = 1; 427f0cdd9c0SBrian Somers (*authp->fn.req)(authp); 428dd7e2610SBrian Somers timer_Start(&authp->authtimer); 42953c9f6c0SAtsushi Murai } 43053c9f6c0SAtsushi Murai 43153c9f6c0SAtsushi Murai void 432dd7e2610SBrian Somers auth_StopTimer(struct authinfo *authp) 43353c9f6c0SAtsushi Murai { 434dd7e2610SBrian Somers timer_Stop(&authp->authtimer); 435f0cdd9c0SBrian Somers } 436f0cdd9c0SBrian Somers 437f0cdd9c0SBrian Somers struct mbuf * 438f0cdd9c0SBrian Somers auth_ReadHeader(struct authinfo *authp, struct mbuf *bp) 439f0cdd9c0SBrian Somers { 440f0cdd9c0SBrian Somers int len; 441f0cdd9c0SBrian Somers 44226af0ae9SBrian Somers len = m_length(bp); 443f0cdd9c0SBrian Somers if (len >= sizeof authp->in.hdr) { 444f0cdd9c0SBrian Somers bp = mbuf_Read(bp, (u_char *)&authp->in.hdr, sizeof authp->in.hdr); 445f0cdd9c0SBrian Somers if (len >= ntohs(authp->in.hdr.length)) 446f0cdd9c0SBrian Somers return bp; 447b7ff18adSBrian Somers authp->in.hdr.length = htons(0); 448b31a24caSBrian Somers log_Printf(LogWARN, "auth_ReadHeader: Short packet (%d > %d) !\n", 449b31a24caSBrian Somers ntohs(authp->in.hdr.length), len); 450b7ff18adSBrian Somers } else { 451b7ff18adSBrian Somers authp->in.hdr.length = htons(0); 452b31a24caSBrian Somers log_Printf(LogWARN, "auth_ReadHeader: Short packet header (%d > %d) !\n", 453eb2d27cfSBrian Somers (int)(sizeof authp->in.hdr), len); 454b7ff18adSBrian Somers } 455f0cdd9c0SBrian Somers 45626af0ae9SBrian Somers m_freem(bp); 457f0cdd9c0SBrian Somers return NULL; 458f0cdd9c0SBrian Somers } 459f0cdd9c0SBrian Somers 460f0cdd9c0SBrian Somers struct mbuf * 461f0cdd9c0SBrian Somers auth_ReadName(struct authinfo *authp, struct mbuf *bp, int len) 462f0cdd9c0SBrian Somers { 463f0cdd9c0SBrian Somers if (len > sizeof authp->in.name - 1) 464b31a24caSBrian Somers log_Printf(LogWARN, "auth_ReadName: Name too long (%d) !\n", len); 465f0cdd9c0SBrian Somers else { 46626af0ae9SBrian Somers int mlen = m_length(bp); 467f0cdd9c0SBrian Somers 468f0cdd9c0SBrian Somers if (len > mlen) 469b31a24caSBrian Somers log_Printf(LogWARN, "auth_ReadName: Short packet (%d > %d) !\n", 470b31a24caSBrian Somers len, mlen); 471f0cdd9c0SBrian Somers else { 472f0cdd9c0SBrian Somers bp = mbuf_Read(bp, (u_char *)authp->in.name, len); 473f0cdd9c0SBrian Somers authp->in.name[len] = '\0'; 474f0cdd9c0SBrian Somers return bp; 475f0cdd9c0SBrian Somers } 476f0cdd9c0SBrian Somers } 477f0cdd9c0SBrian Somers 478f0cdd9c0SBrian Somers *authp->in.name = '\0'; 47926af0ae9SBrian Somers m_freem(bp); 480f0cdd9c0SBrian Somers return NULL; 48153c9f6c0SAtsushi Murai } 482