auth.c revision 41888
16059Samurai/*
26059Samurai *			PPP Secret Key Module
36059Samurai *
46059Samurai *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
56059Samurai *
66059Samurai *   Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd.
76059Samurai *
86059Samurai * Redistribution and use in source and binary forms are permitted
96059Samurai * provided that the above copyright notice and this paragraph are
106059Samurai * duplicated in all such forms and that any documentation,
116059Samurai * advertising materials, and other materials related to such
126059Samurai * distribution and use acknowledge that the software was developed
136059Samurai * by the Internet Initiative Japan, Inc.  The name of the
146059Samurai * IIJ may not be used to endorse or promote products derived
156059Samurai * from this software without specific prior written permission.
166059Samurai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
176059Samurai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
186059Samurai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
198857Srgrimes *
2041888Sbrian * $Id: auth.c,v 1.33 1998/08/26 17:39:36 brian Exp $
218857Srgrimes *
226059Samurai *	TODO:
2310528Samurai *		o Implement check against with registered IP addresses.
246059Samurai */
2536285Sbrian#include <sys/types.h>
2630715Sbrian#include <netinet/in.h>
2736285Sbrian#include <netinet/in_systm.h>
2836285Sbrian#include <netinet/ip.h>
2936285Sbrian#include <sys/un.h>
3030715Sbrian
3136285Sbrian#include <pwd.h>
3230715Sbrian#include <stdio.h>
3330715Sbrian#include <string.h>
3430715Sbrian#include <unistd.h>
3530715Sbrian
3630715Sbrian#include "mbuf.h"
3730715Sbrian#include "defs.h"
3830715Sbrian#include "timer.h"
396059Samurai#include "fsm.h"
4036285Sbrian#include "iplist.h"
4136285Sbrian#include "throughput.h"
4236285Sbrian#include "slcompress.h"
4338557Sbrian#include "lqr.h"
4438557Sbrian#include "hdlc.h"
456059Samurai#include "ipcp.h"
466735Samurai#include "auth.h"
4736285Sbrian#include "systems.h"
4836285Sbrian#include "lcp.h"
4936285Sbrian#include "ccp.h"
5036285Sbrian#include "link.h"
5136285Sbrian#include "descriptor.h"
5213389Sphk#include "chat.h"
5336285Sbrian#include "lcpproto.h"
5436285Sbrian#include "filter.h"
5536285Sbrian#include "mp.h"
5636285Sbrian#include "bundle.h"
576059Samurai
5836285Sbrianconst char *
5936285SbrianAuth2Nam(u_short auth)
6013389Sphk{
6136285Sbrian  switch (auth) {
6236285Sbrian  case PROTO_PAP:
6336285Sbrian    return "PAP";
6436285Sbrian  case PROTO_CHAP:
6536285Sbrian    return "CHAP";
6636285Sbrian  case 0:
6736285Sbrian    return "none";
6836285Sbrian  }
6936285Sbrian  return "unknown";
706735Samurai}
716735Samurai
7236285Sbrianstatic int
7336285Sbrianauth_CheckPasswd(const char *name, const char *data, const char *key)
7428679Sbrian{
7536285Sbrian  if (!strcmp(data, "*")) {
7636285Sbrian    /* Then look up the real password database */
7736285Sbrian    struct passwd *pw;
7836285Sbrian    int result;
7936285Sbrian
8036285Sbrian    result = (pw = getpwnam(name)) &&
8136285Sbrian             !strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd);
8236285Sbrian    endpwent();
8336285Sbrian    return result;
8436285Sbrian  }
8536285Sbrian
8636285Sbrian  return !strcmp(data, key);
8736285Sbrian}
8836285Sbrian
8936285Sbrianint
9038174Sbrianauth_SetPhoneList(const char *name, char *phone, int phonelen)
9136285Sbrian{
926735Samurai  FILE *fp;
936735Samurai  int n;
9438174Sbrian  char *vector[6];
9538174Sbrian  char buff[LINE_LEN];
9638174Sbrian
9738174Sbrian  fp = OpenSecret(SECRETFILE);
9838174Sbrian  if (fp != NULL) {
9938174Sbrian    while (fgets(buff, sizeof buff, fp)) {
10038174Sbrian      if (buff[0] == '#')
10138174Sbrian        continue;
10238174Sbrian      buff[strlen(buff) - 1] = '\0';
10338174Sbrian      memset(vector, '\0', sizeof vector);
10438174Sbrian      n = MakeArgs(buff, vector, VECSIZE(vector));
10538174Sbrian      if (n < 5)
10638174Sbrian        continue;
10738174Sbrian      if (strcmp(vector[0], name) == 0) {
10838174Sbrian	CloseSecret(fp);
10938174Sbrian	if (*vector[4] == '\0')
11038174Sbrian          return 0;
11138174Sbrian        strncpy(phone, vector[4], phonelen - 1);
11238174Sbrian        phone[phonelen - 1] = '\0';
11338174Sbrian	return 1;		/* Valid */
11438174Sbrian      }
11538174Sbrian    }
11638174Sbrian    CloseSecret(fp);
11738174Sbrian  }
11838174Sbrian  *phone = '\0';
11938174Sbrian  return 0;
12038174Sbrian}
12138174Sbrian
12238174Sbrianint
12338174Sbrianauth_Select(struct bundle *bundle, const char *name)
12438174Sbrian{
12538174Sbrian  FILE *fp;
12638174Sbrian  int n;
12736285Sbrian  char *vector[5];
12831070Sbrian  char buff[LINE_LEN];
1296735Samurai
13036285Sbrian  if (*name == '\0') {
13136285Sbrian    ipcp_Setup(&bundle->ncp.ipcp);
13236285Sbrian    return 1;
13336285Sbrian  }
13436285Sbrian
13536285Sbrian  fp = OpenSecret(SECRETFILE);
13636285Sbrian  if (fp != NULL) {
13736285Sbrian    while (fgets(buff, sizeof buff, fp)) {
13836285Sbrian      if (buff[0] == '#')
13936285Sbrian        continue;
14037763Sbrian      buff[strlen(buff) - 1] = '\0';
14136285Sbrian      memset(vector, '\0', sizeof vector);
14236285Sbrian      n = MakeArgs(buff, vector, VECSIZE(vector));
14336285Sbrian      if (n < 2)
14436285Sbrian        continue;
14537763Sbrian      if (strcmp(vector[0], name) == 0) {
14636285Sbrian	CloseSecret(fp);
14738174Sbrian	if (n > 2 && *vector[2] && strcmp(vector[2], "*") &&
14838174Sbrian            !ipcp_UseHisaddr(bundle, vector[2], 1))
14936285Sbrian	  return 0;
15036285Sbrian	ipcp_Setup(&bundle->ncp.ipcp);
15138174Sbrian	if (n > 3 && *vector[3] && strcmp(vector[3], "*"))
15236285Sbrian	  bundle_SetLabel(bundle, vector[3]);
15336285Sbrian	return 1;		/* Valid */
15437763Sbrian      }
1556735Samurai    }
15636285Sbrian    CloseSecret(fp);
1576735Samurai  }
15836285Sbrian
15936285Sbrian#ifndef NOPASSWDAUTH
16036285Sbrian  /* Let 'em in anyway - they must have been in the passwd file */
16136285Sbrian  ipcp_Setup(&bundle->ncp.ipcp);
16236285Sbrian  return 1;
16336285Sbrian#else
16436285Sbrian  /* Disappeared from ppp.secret ? */
16536285Sbrian  return 0;
16636285Sbrian#endif
1676735Samurai}
1686735Samurai
1696059Samuraiint
17036285Sbrianauth_Validate(struct bundle *bundle, const char *system,
17136285Sbrian             const char *key, struct physical *physical)
1726059Samurai{
17336285Sbrian  /* Used by PAP routines */
17436285Sbrian
1756059Samurai  FILE *fp;
1766059Samurai  int n;
17732267Sbrian  char *vector[5];
17831070Sbrian  char buff[LINE_LEN];
1796059Samurai
18036285Sbrian  fp = OpenSecret(SECRETFILE);
18136285Sbrian  if (fp != NULL) {
18236285Sbrian    while (fgets(buff, sizeof buff, fp)) {
18336285Sbrian      if (buff[0] == '#')
18436285Sbrian        continue;
18536285Sbrian      buff[strlen(buff) - 1] = 0;
18636285Sbrian      memset(vector, '\0', sizeof vector);
18736285Sbrian      n = MakeArgs(buff, vector, VECSIZE(vector));
18836285Sbrian      if (n < 2)
18936285Sbrian        continue;
19036285Sbrian      if (strcmp(vector[0], system) == 0) {
1916059Samurai	CloseSecret(fp);
19236285Sbrian        return auth_CheckPasswd(vector[0], vector[1], key);
1936059Samurai      }
1946059Samurai    }
19536285Sbrian    CloseSecret(fp);
1966059Samurai  }
19736285Sbrian
19836285Sbrian#ifndef NOPASSWDAUTH
19936285Sbrian  if (Enabled(bundle, OPT_PASSWDAUTH))
20036285Sbrian    return auth_CheckPasswd(system, "*", key);
20136285Sbrian#endif
20236285Sbrian
20336285Sbrian  return 0;			/* Invalid */
2046059Samurai}
2056059Samurai
2066059Samuraichar *
20736285Sbrianauth_GetSecret(struct bundle *bundle, const char *system, int len,
20836285Sbrian              struct physical *physical)
2096059Samurai{
21036285Sbrian  /* Used by CHAP routines */
21136285Sbrian
2126059Samurai  FILE *fp;
2136059Samurai  int n;
21432267Sbrian  char *vector[5];
21541888Sbrian  static char buff[LINE_LEN];
2166059Samurai
21736285Sbrian  fp = OpenSecret(SECRETFILE);
2186059Samurai  if (fp == NULL)
21928679Sbrian    return (NULL);
22036285Sbrian
22131962Sbrian  while (fgets(buff, sizeof buff, fp)) {
2226059Samurai    if (buff[0] == '#')
2236059Samurai      continue;
22428679Sbrian    buff[strlen(buff) - 1] = 0;
22531962Sbrian    memset(vector, '\0', sizeof vector);
22625560Sbrian    n = MakeArgs(buff, vector, VECSIZE(vector));
2276059Samurai    if (n < 2)
2286059Samurai      continue;
2296059Samurai    if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) {
23036285Sbrian      CloseSecret(fp);
23136285Sbrian      return vector[1];
2326059Samurai    }
2336059Samurai  }
2346059Samurai  CloseSecret(fp);
23528679Sbrian  return (NULL);		/* Invalid */
2366059Samurai}
2376735Samurai
2386735Samuraistatic void
23931343SbrianAuthTimeout(void *vauthp)
2406735Samurai{
24131343Sbrian  struct authinfo *authp = (struct authinfo *)vauthp;
2426735Samurai
24336285Sbrian  timer_Stop(&authp->authtimer);
2446735Samurai  if (--authp->retry > 0) {
24536285Sbrian    timer_Start(&authp->authtimer);
24636285Sbrian    (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical);
2476735Samurai  }
2486735Samurai}
2496735Samurai
2506735Samuraivoid
25136285Sbrianauth_Init(struct authinfo *authinfo)
2526735Samurai{
25336285Sbrian  memset(authinfo, '\0', sizeof(struct authinfo));
25436285Sbrian  authinfo->cfg.fsmretry = DEF_FSMRETRY;
25536285Sbrian}
2566735Samurai
25736285Sbrianvoid
25836285Sbrianauth_StartChallenge(struct authinfo *authp, struct physical *physical,
25936285Sbrian                   void (*fn)(struct authinfo *, int, struct physical *))
26036285Sbrian{
26136285Sbrian  authp->ChallengeFunc = fn;
26236285Sbrian  authp->physical = physical;
26336285Sbrian  timer_Stop(&authp->authtimer);
26436285Sbrian  authp->authtimer.func = AuthTimeout;
26536285Sbrian  authp->authtimer.name = "auth";
26636285Sbrian  authp->authtimer.load = authp->cfg.fsmretry * SECTICKS;
26736285Sbrian  authp->authtimer.arg = (void *) authp;
2686735Samurai  authp->retry = 3;
2696735Samurai  authp->id = 1;
27036285Sbrian  (*authp->ChallengeFunc)(authp, authp->id, physical);
27136285Sbrian  timer_Start(&authp->authtimer);
2726735Samurai}
2736735Samurai
2746735Samuraivoid
27536285Sbrianauth_StopTimer(struct authinfo *authp)
2766735Samurai{
27736285Sbrian  timer_Stop(&authp->authtimer);
27836285Sbrian  authp->physical = NULL;
2796735Samurai}
280