Ejemplo n.º 1
0
struct mbuf *
ipv6cp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
  /* Got PROTO_IPV6CP from link */
  m_settype(bp, MB_IPV6CPIN);
  if (bundle_Phase(bundle) == PHASE_NETWORK)
    fsm_Input(&bundle->ncp.ipv6cp.fsm, bp);
  else {
    if (bundle_Phase(bundle) < PHASE_NETWORK)
      log_Printf(LogIPV6CP, "%s: Error: Unexpected IPV6CP in phase %s"
                 " (ignored)\n", l->name, bundle_PhaseName(bundle));
    m_freem(bp);
  }
  return NULL;
}
Ejemplo n.º 2
0
extern struct mbuf *
ccp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
  /* Got PROTO_CCP from link */
  m_settype(bp, MB_CCPIN);
  if (bundle_Phase(bundle) == PHASE_NETWORK)
    fsm_Input(&l->ccp.fsm, bp);
  else {
    if (bundle_Phase(bundle) < PHASE_NETWORK)
      log_Printf(LogCCP, "%s: Error: Unexpected CCP in phase %s (ignored)\n",
                 l->ccp.fsm.link->name, bundle_PhaseName(bundle));
    m_freem(bp);
  }
  return NULL;
}
Ejemplo n.º 3
0
static void
prompt_Display(struct prompt *p)
{
  /* XXX: See Index2Nam() - should we only figure this out once ? */
  static char shostname[MAXHOSTNAMELEN];
  const char *pconnect, *pauth;

  if (p->TermMode || !p->needprompt)
    return;

  p->needprompt = 0;

  if (p->nonewline)
    p->nonewline = 0;
  else
    fprintf(p->Term, "\n");

  if (p->auth == LOCAL_AUTH)
    pauth = " ON ";
  else
    pauth = " on ";

  if (p->bundle->ncp.ipcp.fsm.state == ST_OPENED)
    pconnect = "PPP";
#ifndef NOINET6
  else if (!Enabled(p->bundle, OPT_IPCP) &&
	   p->bundle->ncp.ipv6cp.fsm.state == ST_OPENED)
    pconnect = "PPP";
#endif
  else if (bundle_Phase(p->bundle) == PHASE_NETWORK)
    pconnect = "PPp";
  else if (bundle_Phase(p->bundle) == PHASE_AUTHENTICATE)
    pconnect = "Ppp";
  else
    pconnect = "ppp";

  if (*shostname == '\0') {
    char *dot;

    if (gethostname(shostname, sizeof shostname) || *shostname == '\0')
      strcpy(shostname, "localhost");
    else if ((dot = strchr(shostname, '.')))
      *dot = '\0';
  }

  fprintf(p->Term, "%s%s%s> ", pconnect, pauth, shostname);
  fflush(p->Term);
}
Ejemplo n.º 4
0
static void
datalink_LayerUp(void *v, struct fsm *fp)
{
  /* The given fsm is now up */
  struct datalink *dl = (struct datalink *)v;
  struct lcp *lcp = &dl->physical->link.lcp;

  if (fp->proto == PROTO_LCP) {
    datalink_GotAuthname(dl, "");
    lcp->auth_ineed = lcp->want_auth;
    lcp->auth_iwait = lcp->his_auth;
    if (lcp->his_auth || lcp->want_auth) {
      if (bundle_Phase(dl->bundle) != PHASE_NETWORK)
        bundle_NewPhase(dl->bundle, PHASE_AUTHENTICATE);
      log_Printf(LogPHASE, "%s: his = %s, mine = %s\n", dl->name,
                Auth2Nam(lcp->his_auth, lcp->his_authtype),
                Auth2Nam(lcp->want_auth, lcp->want_authtype));
      if (lcp->his_auth == PROTO_PAP)
        auth_StartReq(&dl->pap);
      if (lcp->want_auth == PROTO_CHAP)
        auth_StartReq(&dl->chap.auth);
    } else
      datalink_AuthOk(dl);
  } else if (fp->proto == PROTO_CCP)
    (*dl->parent->LayerUp)(dl->parent->object, &dl->physical->link.ccp.fsm);
}
Ejemplo n.º 5
0
void
datalink_Up(struct datalink *dl, int runscripts, int packetmode)
{
  if (!Enabled(dl->bundle, OPT_FORCE_SCRIPTS) &&
      (dl->physical->type & (PHYS_DIRECT|PHYS_DEDICATED)))
    /* Ignore scripts */
    runscripts = 0;

  switch (dl->state) {
    case DATALINK_CLOSED:
      if (bundle_Phase(dl->bundle) == PHASE_DEAD ||
          bundle_Phase(dl->bundle) == PHASE_TERMINATE)
        bundle_NewPhase(dl->bundle, PHASE_ESTABLISH);
      datalink_NewState(dl, DATALINK_OPENING);
      dl->reconnect_tries =
        dl->physical->type == PHYS_DIRECT ? 0 : dl->cfg.reconnect.max;
      dl->dial.tries = dl->cfg.dial.max;
      dl->script.run = runscripts;
      dl->script.packetmode = packetmode;
      break;

    case DATALINK_OPENING:
      if (!dl->script.run && runscripts)
        dl->script.run = 1;
      /* FALLTHROUGH */

    case DATALINK_DIAL:
    case DATALINK_LOGIN:
    case DATALINK_READY:
      if (!dl->script.packetmode && packetmode) {
        dl->script.packetmode = 1;
        if (dl->state == DATALINK_READY) {
          dl->script.run = 0;
          datalink_NewState(dl, DATALINK_CARRIER);
        }
      }
      break;
  }
}
Ejemplo n.º 6
0
void
datalink_NCPUp(struct datalink *dl)
{
  int ccpok = ccp_SetOpenMode(&dl->physical->link.ccp);

  if (dl->physical->link.lcp.want_mrru && dl->physical->link.lcp.his_mrru) {
    /* we've authenticated in multilink mode ! */
    switch (mp_Up(&dl->bundle->ncp.mp, dl)) {
      case MP_LINKSENT:
        /* We've handed the link off to another ppp (well, we will soon) ! */
        return;
      case MP_UP:
        /* First link in the bundle */
        auth_Select(dl->bundle, dl->peer.authname);
        bundle_CalculateBandwidth(dl->bundle);
        /* FALLTHROUGH */
      case MP_ADDED:
        /* We're in multilink mode ! */
        dl->physical->link.ccp.fsm.open_mode = OPEN_PASSIVE;	/* override */
        bundle_CalculateBandwidth(dl->bundle);
        break;
      case MP_FAILED:
        datalink_AuthNotOk(dl);
        return;
    }
  } else if (bundle_Phase(dl->bundle) == PHASE_NETWORK) {
    log_Printf(LogPHASE, "%s: Already in NETWORK phase\n", dl->name);
    datalink_NewState(dl, DATALINK_OPEN);
    bundle_CalculateBandwidth(dl->bundle);
    (*dl->parent->LayerUp)(dl->parent->object, &dl->physical->link.lcp.fsm);
    return;
  } else {
    dl->bundle->ncp.mp.peer = dl->peer;
    ncp_SetLink(&dl->bundle->ncp, &dl->physical->link);
    auth_Select(dl->bundle, dl->peer.authname);
  }

  if (ccpok) {
    fsm_Up(&dl->physical->link.ccp.fsm);
    fsm_Open(&dl->physical->link.ccp.fsm);
  }
  datalink_NewState(dl, DATALINK_OPEN);
  bundle_NewPhase(dl->bundle, PHASE_NETWORK);
  (*dl->parent->LayerUp)(dl->parent->object, &dl->physical->link.lcp.fsm);
}
struct mbuf *
chap_Input_old(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
    struct physical *p = link2physical(l);
    struct chap *chap = &p->dl->chap;
    char *name, *key, *ans;
    int len, nlen;
    u_char alen;
#ifdef HAVE_DES
    int lanman;
#endif

    if (p == NULL) {
        log_Printf(LogERROR, "chap_Input: Not a physical link - dropped\n");
        m_freem(bp);
        return NULL;
    }

    if (bundle_Phase(bundle) != PHASE_NETWORK &&
            bundle_Phase(bundle) != PHASE_AUTHENTICATE) {
        log_Printf(LogPHASE, "Unexpected chap input - dropped !\n");
        m_freem(bp);
        return NULL;
    }

    m_settype(bp, MB_CHAPIN);
    if ((bp = auth_ReadHeader(&chap->auth, bp)) == NULL &&
            ntohs(chap->auth.in.hdr.length) == 0)
        log_Printf(LogWARN, "Chap Input: Truncated header !\n");
    else if (chap->auth.in.hdr.code == 0 || chap->auth.in.hdr.code > MAXCHAPCODE)
        log_Printf(LogPHASE, "Chap Input: %d: Bad CHAP code !\n",
                   chap->auth.in.hdr.code);
    else {
        len = m_length(bp);
        ans = NULL;

        if (chap->auth.in.hdr.code != CHAP_CHALLENGE &&
                chap->auth.id != chap->auth.in.hdr.id &&
                Enabled(bundle, OPT_IDCHECK)) {
            /* Wrong conversation dude ! */
            log_Printf(LogPHASE, "Chap Input: %s dropped (got id %d, not %d)\n",
                       chapcodes[chap->auth.in.hdr.code], chap->auth.in.hdr.id,
                       chap->auth.id);
            m_freem(bp);
            return NULL;
        }
        chap->auth.id = chap->auth.in.hdr.id;	/* We respond with this id */

#ifdef HAVE_DES
        lanman = 0;
#endif
        switch (chap->auth.in.hdr.code) {
        case CHAP_CHALLENGE:
            bp = mbuf_Read(bp, &alen, 1);
            len -= alen + 1;    /* len -= (alen + 1); */
            if (len < 0) {
                log_Printf(LogERROR, "Chap Input: Truncated challenge !\n");
                m_freem(bp);
                return NULL;
            }
            *chap->challenge.peer = alen;
            bp = mbuf_Read(bp, chap->challenge.peer + 1, alen);
            bp = auth_ReadName(&chap->auth, bp, len);
#ifdef HAVE_DES
            lanman = p->link.lcp.his_authtype == 0x80 &&
                     ((chap->NTRespSent && IsAccepted(p->link.lcp.cfg.chap80lm)) ||
                      !IsAccepted(p->link.lcp.cfg.chap80nt));
#endif
            break;

        case CHAP_RESPONSE:
            auth_StopTimer(&chap->auth);
            bp = mbuf_Read(bp, &alen, 1);    /* read HASH-Size */
            len -= alen + 1;    /* len -= (alen + 1);, len is length of Name Field */
            if (len < 0) {
                log_Printf(LogERROR, "Chap Input: Truncated response !\n");
                m_freem(bp);
                return NULL;
            }
            if ((ans = malloc(alen + 2)) == NULL) {
                log_Printf(LogERROR, "Chap Input: Out of memory !\n");
                m_freem(bp);
                return NULL;
            }
            *ans = chap->auth.id;
            bp = mbuf_Read(bp, ans + 1, alen);    /* cut HASH value */
            ans[alen+1] = '\0';    /* ans is (id, HASH, \0)*/
            bp = auth_ReadName(&chap->auth, bp, len);
#ifdef HAVE_DES
            lanman = alen == 49 && ans[alen] == 0;
#endif
            break;

        case CHAP_SUCCESS:
        case CHAP_FAILURE:
            /* chap->auth.in.name is already set up at CHALLENGE time */
            if ((ans = malloc(len + 1)) == NULL) {
                log_Printf(LogERROR, "Chap Input: Out of memory !\n");
                m_freem(bp);
                return NULL;
            }
            bp = mbuf_Read(bp, ans, len);
            ans[len] = '\0';
            break;
        }

        switch (chap->auth.in.hdr.code) {
        case CHAP_CHALLENGE:
        case CHAP_RESPONSE:
            if (*chap->auth.in.name)
                log_Printf(LogPHASE, "Chap Input: %s (%d bytes from %s%s)\n",
                           chapcodes[chap->auth.in.hdr.code], alen,
                           chap->auth.in.name,
#ifdef HAVE_DES
                           lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ?
                           " - lanman" :
#endif
                           "");
            else
                log_Printf(LogPHASE, "Chap Input: %s (%d bytes%s)\n",
                           chapcodes[chap->auth.in.hdr.code], alen,
#ifdef HAVE_DES
                           lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ?
                           " - lanman" :
#endif
                           "");
            break;

        case CHAP_SUCCESS:
        case CHAP_FAILURE:
            if (*ans)
                log_Printf(LogPHASE, "Chap Input: %s (%s)\n",
                           chapcodes[chap->auth.in.hdr.code], ans);
            else
                log_Printf(LogPHASE, "Chap Input: %s\n",
                           chapcodes[chap->auth.in.hdr.code]);
            break;
        }

        switch (chap->auth.in.hdr.code) {
        case CHAP_CHALLENGE:
            if (*bundle->cfg.auth.key == '!' && bundle->cfg.auth.key[1] != '!')
                chap_StartChild(chap, bundle->cfg.auth.key + 1,
                                bundle->cfg.auth.name);
            else
                chap_Respond(chap, bundle->cfg.auth.name, bundle->cfg.auth.key +
                             (*bundle->cfg.auth.key == '!' ? 1 : 0),
                             p->link.lcp.his_authtype
#ifdef HAVE_DES
                             , lanman
#endif
                            );
            break;

        case CHAP_RESPONSE:
            name = chap->auth.in.name;
            nlen = strlen(name);
#ifndef NORADIUS
            if (*bundle->radius.cfg.file) {
                u_char end;

                end = chap->challenge.local[*chap->challenge.local+1];
                chap->challenge.local[*chap->challenge.local+1] = '\0';
                radius_Authenticate(&bundle->radius, &chap->auth,
                                    chap->auth.in.name, ans,
                                    chap->challenge.local + 1);
                chap->challenge.local[*chap->challenge.local+1] = end;
            } else
#endif
            {
                key = auth_GetSecret(bundle, name, nlen, p);
                if (key) {
                    char *myans;
#ifdef HAVE_DES
                    if (lanman && !IsEnabled(p->link.lcp.cfg.chap80lm)) {
                        log_Printf(LogPHASE, "Auth failure: LANMan not enabled\n");
                        if (chap_HaveAnotherGo(chap))
                            break;
                        key = NULL;
                    } else if (!lanman && !IsEnabled(p->link.lcp.cfg.chap80nt) &&
                               p->link.lcp.want_authtype == 0x80) {
                        log_Printf(LogPHASE, "Auth failure: mschap not enabled\n");
                        if (chap_HaveAnotherGo(chap))
                            break;
                        key = NULL;
                    } else
#endif
                    {
                        myans = chap_BuildAnswer(name, key, chap->auth.id,
                                                 chap->challenge.local,
                                                 p->link.lcp.want_authtype
#ifdef HAVE_DES
                                                 , lanman
#endif
                                                );
                        if (myans == NULL)
                            key = NULL;
                        else {
                            if (!chap_Cmp(p->link.lcp.want_authtype, myans + 1, *myans,
                                          ans + 1, alen
#ifdef HAVE_DES
                                          , lanman
#endif
                                         ))
                                key = NULL;
                            free(myans);
                        }
                    }
                }

                if (key)
                    chap_Success(&chap->auth);
                else
                    chap_Failure(&chap->auth);
            }

            break;

        case CHAP_SUCCESS:
            if (p->link.lcp.auth_iwait == PROTO_CHAP) {
                p->link.lcp.auth_iwait = 0;
                if (p->link.lcp.auth_ineed == 0)
                    /*
                     * We've succeeded in our ``login''
                     * If we're not expecting  the peer to authenticate (or he already
                     * has), proceed to network phase.
                     */
                    datalink_AuthOk(p->dl);
            }
            break;

        case CHAP_FAILURE:
            datalink_AuthNotOk(p->dl);
            break;
        }
        free(ans);
    }

    m_freem(bp);
    return NULL;
}
Ejemplo n.º 8
0
struct mbuf *
pap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
  struct physical *p = link2physical(l);
  struct authinfo *authp = &p->dl->pap;
  u_char nlen, klen, *key;
  const char *txt;
  int txtlen;

  if (p == NULL) {
    log_Printf(LogERROR, "pap_Input: Not a physical link - dropped\n");
    m_freem(bp);
    return NULL;
  }

  if (bundle_Phase(bundle) != PHASE_NETWORK &&
      bundle_Phase(bundle) != PHASE_AUTHENTICATE) {
    log_Printf(LogPHASE, "Unexpected pap input - dropped !\n");
    m_freem(bp);
    return NULL;
  }

  if ((bp = auth_ReadHeader(authp, bp)) == NULL &&
      ntohs(authp->in.hdr.length) == 0) {
    log_Printf(LogWARN, "Pap Input: Truncated header !\n");
    return NULL;
  }

  if (authp->in.hdr.code == 0 || authp->in.hdr.code > MAXPAPCODE) {
    log_Printf(LogPHASE, "Pap Input: %d: Bad PAP code !\n", authp->in.hdr.code);
    m_freem(bp);
    return NULL;
  }

  if (authp->in.hdr.code != PAP_REQUEST && authp->id != authp->in.hdr.id &&
      Enabled(bundle, OPT_IDCHECK)) {
    /* Wrong conversation dude ! */
    log_Printf(LogPHASE, "Pap Input: %s dropped (got id %d, not %d)\n",
               papcodes[authp->in.hdr.code], authp->in.hdr.id, authp->id);
    m_freem(bp);
    return NULL;
  }
  m_settype(bp, MB_PAPIN);
  authp->id = authp->in.hdr.id;		/* We respond with this id */

  if (bp) {
    bp = mbuf_Read(bp, &nlen, 1);
    if (authp->in.hdr.code == PAP_ACK) {
      /*
       * Don't restrict the length of our acknowledgement freetext to
       * nlen (a one-byte length).  Show the rest of the ack packet
       * instead.  This isn't really part of the protocol.....
       */
      bp = m_pullup(bp);
      txt = MBUF_CTOP(bp);
      txtlen = m_length(bp);
    } else {
      bp = auth_ReadName(authp, bp, nlen);
      txt = authp->in.name;
      txtlen = strlen(authp->in.name);
    }
  } else {
    txt = "";
    txtlen = 0;
  }

  log_Printf(LogPHASE, "Pap Input: %s (%.*s)\n",
             papcodes[authp->in.hdr.code], txtlen, txt);

  switch (authp->in.hdr.code) {
    case PAP_REQUEST:
      if (bp == NULL) {
        log_Printf(LogPHASE, "Pap Input: No key given !\n");
        break;
      }
      bp = mbuf_Read(bp, &klen, 1);
      if (m_length(bp) < klen) {
        log_Printf(LogERROR, "Pap Input: Truncated key !\n");
        break;
      }
      if ((key = malloc(klen+1)) == NULL) {
        log_Printf(LogERROR, "Pap Input: Out of memory !\n");
        break;
      }
      bp = mbuf_Read(bp, key, klen);
      key[klen] = '\0';

#ifndef NORADIUS
      if (*bundle->radius.cfg.file) {
        if (!radius_Authenticate(&bundle->radius, authp, authp->in.name,
                                 key, strlen(key), NULL, 0))
          pap_Failure(authp);
      } else
#endif
      if (auth_Validate(bundle, authp->in.name, key))
        pap_Success(authp);
      else
        pap_Failure(authp);

      free(key);
      break;

    case PAP_ACK:
      auth_StopTimer(authp);
      if (p->link.lcp.auth_iwait == PROTO_PAP) {
        p->link.lcp.auth_iwait = 0;
        if (p->link.lcp.auth_ineed == 0)
          /*
           * We've succeeded in our ``login''
           * If we're not expecting  the peer to authenticate (or he already
           * has), proceed to network phase.
           */
          datalink_AuthOk(p->dl);
      }
      break;

    case PAP_NAK:
      auth_StopTimer(authp);
      datalink_AuthNotOk(p->dl);
      break;
  }

  m_freem(bp);
  return NULL;
}
Ejemplo n.º 9
0
struct mbuf *
chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
  struct physical *p = link2physical(l);
  struct chap *chap = &p->dl->chap;
  char *name, *key, *ans;
  int len, nlen;
  u_char alen;
#ifndef NODES
  int lanman;
#endif

  if (p == NULL) {
    log_Printf(LogERROR, "chap_Input: Not a physical link - dropped\n");
    m_freem(bp);
    return NULL;
  }

  if (bundle_Phase(bundle) != PHASE_NETWORK &&
      bundle_Phase(bundle) != PHASE_AUTHENTICATE) {
    log_Printf(LogPHASE, "Unexpected chap input - dropped !\n");
    m_freem(bp);
    return NULL;
  }

  m_settype(bp, MB_CHAPIN);
  if ((bp = auth_ReadHeader(&chap->auth, bp)) == NULL &&
      ntohs(chap->auth.in.hdr.length) == 0)
    log_Printf(LogWARN, "Chap Input: Truncated header !\n");
  else if (chap->auth.in.hdr.code == 0 || chap->auth.in.hdr.code > MAXCHAPCODE)
    log_Printf(LogPHASE, "Chap Input: %d: Bad CHAP code !\n",
               chap->auth.in.hdr.code);
  else {
    len = m_length(bp);
    ans = NULL;

    if (chap->auth.in.hdr.code != CHAP_CHALLENGE &&
        chap->auth.id != chap->auth.in.hdr.id &&
        Enabled(bundle, OPT_IDCHECK)) {
      /* Wrong conversation dude ! */
      log_Printf(LogPHASE, "Chap Input: %s dropped (got id %d, not %d)\n",
                 chapcodes[chap->auth.in.hdr.code], chap->auth.in.hdr.id,
                 chap->auth.id);
      m_freem(bp);
      return NULL;
    }
    chap->auth.id = chap->auth.in.hdr.id;	/* We respond with this id */

#ifndef NODES
    lanman = 0;
#endif
    switch (chap->auth.in.hdr.code) {
      case CHAP_CHALLENGE:
        bp = mbuf_Read(bp, &alen, 1);
        len -= alen + 1;
        if (len < 0) {
          log_Printf(LogERROR, "Chap Input: Truncated challenge !\n");
          m_freem(bp);
          return NULL;
        }
        *chap->challenge.peer = alen;
        bp = mbuf_Read(bp, chap->challenge.peer + 1, alen);
        bp = auth_ReadName(&chap->auth, bp, len);
#ifndef NODES
        lanman = p->link.lcp.his_authtype == 0x80 &&
                 ((chap->NTRespSent && IsAccepted(p->link.lcp.cfg.chap80lm)) ||
                  !IsAccepted(p->link.lcp.cfg.chap80nt));

        /* Generate local challenge value */
        chap_ChallengeInit(&chap->auth);
#endif
        break;

      case CHAP_RESPONSE:
        auth_StopTimer(&chap->auth);
        bp = mbuf_Read(bp, &alen, 1);
        len -= alen + 1;
        if (len < 0) {
          log_Printf(LogERROR, "Chap Input: Truncated response !\n");
          m_freem(bp);
          return NULL;
        }
        if ((ans = malloc(alen + 1)) == NULL) {
          log_Printf(LogERROR, "Chap Input: Out of memory !\n");
          m_freem(bp);
          return NULL;
        }
        *ans = chap->auth.id;
        bp = mbuf_Read(bp, ans + 1, alen);
        bp = auth_ReadName(&chap->auth, bp, len);
#ifndef NODES
        lanman = p->link.lcp.want_authtype == 0x80 &&
                 alen == 49 && ans[alen] == 0;
#endif
        break;

      case CHAP_SUCCESS:
      case CHAP_FAILURE:
        /* chap->auth.in.name is already set up at CHALLENGE time */
        if ((ans = malloc(len + 1)) == NULL) {
          log_Printf(LogERROR, "Chap Input: Out of memory !\n");
          m_freem(bp);
          return NULL;
        }
        bp = mbuf_Read(bp, ans, len);
        ans[len] = '\0';
        break;
    }

    switch (chap->auth.in.hdr.code) {
      case CHAP_CHALLENGE:
      case CHAP_RESPONSE:
        if (*chap->auth.in.name)
          log_Printf(LogPHASE, "Chap Input: %s (%d bytes from %s%s)\n",
                     chapcodes[chap->auth.in.hdr.code], alen,
                     chap->auth.in.name,
#ifndef NODES
                     lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ?
                     " - lanman" :
#endif
                     "");
        else
          log_Printf(LogPHASE, "Chap Input: %s (%d bytes%s)\n",
                     chapcodes[chap->auth.in.hdr.code], alen,
#ifndef NODES
                     lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ?
                     " - lanman" :
#endif
                     "");
        break;

      case CHAP_SUCCESS:
      case CHAP_FAILURE:
        if (*ans)
          log_Printf(LogPHASE, "Chap Input: %s (%s)\n",
                     chapcodes[chap->auth.in.hdr.code], ans);
        else
          log_Printf(LogPHASE, "Chap Input: %s\n",
                     chapcodes[chap->auth.in.hdr.code]);
        break;
    }

    switch (chap->auth.in.hdr.code) {
      case CHAP_CHALLENGE:
        if (*bundle->cfg.auth.key == '!' && bundle->cfg.auth.key[1] != '!')
          chap_StartChild(chap, bundle->cfg.auth.key + 1,
                          bundle->cfg.auth.name);
        else
          chap_Respond(chap, bundle->cfg.auth.name, bundle->cfg.auth.key +
                       (*bundle->cfg.auth.key == '!' ? 1 : 0),
                       p->link.lcp.his_authtype
#ifndef NODES
                       , lanman
#endif
                      );
        break;

      case CHAP_RESPONSE:
        name = chap->auth.in.name;
        nlen = strlen(name);
#ifndef NODES
        if (p->link.lcp.want_authtype == 0x81) {
          struct MSCHAPv2_resp *resp = (struct MSCHAPv2_resp *)(ans + 1);

          chap->challenge.peer[0] = sizeof resp->PeerChallenge;
          memcpy(chap->challenge.peer + 1, resp->PeerChallenge,
                 sizeof resp->PeerChallenge);
        }
#endif

#ifndef NORADIUS
        if (*bundle->radius.cfg.file) {
          if (!radius_Authenticate(&bundle->radius, &chap->auth,
                                   chap->auth.in.name, ans, alen + 1,
                                   chap->challenge.local + 1,
                                   *chap->challenge.local))
            chap_Failure(&chap->auth);
        } else
#endif
        {
          if (p->link.lcp.want_authtype == 0x81 && ans[alen] != '\0' &&
              alen == sizeof(struct MSCHAPv2_resp)) {
            struct MSCHAPv2_resp *resp = (struct MSCHAPv2_resp *)(ans + 1);

            log_Printf(LogWARN, "%s: Compensating for corrupt (Win98/WinME?) "
                       "CHAP81 RESPONSE\n", l->name);
            resp->Flags = '\0';	/* rfc2759 says it *MUST* be zero */
          }
          key = auth_GetSecret(bundle, name, nlen, p);
          if (key) {
#ifndef NODES
            if (p->link.lcp.want_authtype == 0x80 &&
                lanman && !IsEnabled(p->link.lcp.cfg.chap80lm)) {
              log_Printf(LogPHASE, "Auth failure: LANMan not enabled\n");
              if (chap_HaveAnotherGo(chap))
                break;
              key = NULL;
            } else if (p->link.lcp.want_authtype == 0x80 &&
                !lanman && !IsEnabled(p->link.lcp.cfg.chap80nt)) {
              log_Printf(LogPHASE, "Auth failure: mschap not enabled\n");
              if (chap_HaveAnotherGo(chap))
                break;
              key = NULL;
            } else if (p->link.lcp.want_authtype == 0x81 &&
                !IsEnabled(p->link.lcp.cfg.chap81)) {
              log_Printf(LogPHASE, "Auth failure: CHAP81 not enabled\n");
              key = NULL;
            } else
#endif
            {
              char *myans = chap_BuildAnswer(name, key, chap->auth.id,
                                             chap->challenge.local,
                                       p->link.lcp.want_authtype
#ifndef NODES
                                       , chap->challenge.peer,
                                       chap->authresponse, lanman);
              MPPE_IsServer = 1;		/* XXX Global ! */
#else
                                      );
#endif
              if (myans == NULL)
                key = NULL;
              else {
                if (!chap_Cmp(p->link.lcp.want_authtype, myans + 1, *myans,
                              ans + 1, alen
#ifndef NODES
                              , lanman
#endif
                             ))
                  key = NULL;
                free(myans);
              }
            }
          }

          if (key)
            chap_Success(&chap->auth);
          else
            chap_Failure(&chap->auth);
        }

        break;

      case CHAP_SUCCESS:
        if (p->link.lcp.auth_iwait == PROTO_CHAP) {
          p->link.lcp.auth_iwait = 0;
          if (p->link.lcp.auth_ineed == 0) {
#ifndef NODES
            if (p->link.lcp.his_authtype == 0x81) {
              if (strncasecmp(ans, chap->authresponse, 42)) {
                datalink_AuthNotOk(p->dl);
	        log_Printf(LogWARN, "CHAP81: AuthenticatorResponse: (%.42s)"
                           " != ans: (%.42s)\n", chap->authresponse, ans);

              } else {
                /* Successful login */
                MPPE_MasterKeyValid = 1;		/* XXX Global ! */
                datalink_AuthOk(p->dl);
              }
            } else
#endif
            /*
             * We've succeeded in our ``login''
             * If we're not expecting  the peer to authenticate (or he already
             * has), proceed to network phase.
             */
            datalink_AuthOk(p->dl);
          }
        }
        break;

      case CHAP_FAILURE:
        datalink_AuthNotOk(p->dl);
        break;
    }
    free(ans);
  }
Ejemplo n.º 10
0
static void
datalink_HangupDone(struct datalink *dl)
{
  if (dl->physical->type == PHYS_DEDICATED && !dl->bundle->CleaningUp &&
      dl->physical->fd != -1) {
    /* Don't close our device if the link is dedicated */
    datalink_LoginDone(dl);
    return;
  }

  chat_Finish(&dl->chat);
  physical_Close(dl->physical);
  dl->phone.chosen = "N/A";

  if (dl->cbcp.required) {
    log_Printf(LogPHASE, "Call peer back on %s\n", dl->cbcp.fsm.phone);
    dl->cfg.callback.opmask = 0;
    strncpy(dl->cfg.phone.list, dl->cbcp.fsm.phone,
            sizeof dl->cfg.phone.list - 1);
    dl->cfg.phone.list[sizeof dl->cfg.phone.list - 1] = '\0';
    dl->phone.alt = dl->phone.next = NULL;
    dl->reconnect_tries = dl->cfg.reconnect.max;
    dl->dial.tries = dl->cfg.dial.max;
    dl->dial.incs = 0;
    dl->script.run = 1;
    dl->script.packetmode = 1;
    if (!physical_SetMode(dl->physical, PHYS_BACKGROUND))
      log_Printf(LogERROR, "Oops - can't change mode to BACKGROUND (gulp) !\n");
    bundle_LinksRemoved(dl->bundle);
    /* if dial.timeout is < 0 (random), we don't override fsm.delay */
    if (dl->cbcp.fsm.delay < dl->cfg.dial.timeout)
      dl->cbcp.fsm.delay = dl->cfg.dial.timeout;
    datalink_StartDialTimer(dl, dl->cbcp.fsm.delay);
    cbcp_Down(&dl->cbcp);
    datalink_NewState(dl, DATALINK_OPENING);
    if (bundle_Phase(dl->bundle) == PHASE_DEAD ||
        bundle_Phase(dl->bundle) == PHASE_TERMINATE)
      bundle_NewPhase(dl->bundle, PHASE_ESTABLISH);
  } else if (dl->bundle->CleaningUp ||
      (dl->physical->type == PHYS_DIRECT) ||
      ((!dl->dial.tries || (dl->dial.tries < 0 && !dl->reconnect_tries)) &&
       !(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)))) {
    datalink_NewState(dl, DATALINK_CLOSED);
    dl->dial.tries = -1;
    dl->dial.incs = 0;
    dl->reconnect_tries = 0;
    bundle_LinkClosed(dl->bundle, dl);
    if (!dl->bundle->CleaningUp &&
        !(dl->physical->type & (PHYS_DIRECT|PHYS_BACKGROUND|PHYS_FOREGROUND)))
      datalink_StartDialTimer(dl, datalink_GetDialTimeout(dl));
  } else {
    datalink_NewState(dl, DATALINK_OPENING);
    if (bundle_Phase(dl->bundle) == PHASE_DEAD ||
        bundle_Phase(dl->bundle) == PHASE_TERMINATE)
      bundle_NewPhase(dl->bundle, PHASE_ESTABLISH);
    if (dl->dial.tries < 0) {
      datalink_StartDialTimer(dl, dl->cfg.reconnect.timeout);
      dl->dial.tries = dl->cfg.dial.max;
      dl->dial.incs = 0;
      dl->reconnect_tries--;
      log_Printf(LogCHAT, "%s: Reconnect try %d of %d\n",
                 dl->name, dl->cfg.reconnect.max - dl->reconnect_tries,
                 dl->cfg.reconnect.max);
      bundle_Notify(dl->bundle, EX_RECONNECT);
    } else {
      if (dl->phone.next == NULL)
        datalink_StartDialTimer(dl, datalink_GetDialTimeout(dl));
      else
        datalink_StartDialTimer(dl, dl->cfg.dial.next_timeout);
      bundle_Notify(dl->bundle, EX_REDIAL);
    }
  }
}