1706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*-
2706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
3706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *          based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
4706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *                           Internet Initiative Japan, Inc (IIJ)
5706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * All rights reserved.
6706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
7706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Redistribution and use in source and binary forms, with or without
8706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * modification, are permitted provided that the following conditions
9706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * are met:
10706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 1. Redistributions of source code must retain the above copyright
11706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    notice, this list of conditions and the following disclaimer.
12706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 2. Redistributions in binary form must reproduce the above copyright
13706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    notice, this list of conditions and the following disclaimer in the
14706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    documentation and/or other materials provided with the distribution.
15706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
16706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * SUCH DAMAGE.
27706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
28706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * $FreeBSD: src/usr.sbin/ppp/chap.c,v 1.86.26.1 2010/12/21 17:10:29 kensmith Exp $
29706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
30706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
31706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/param.h>
32706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in.h>
33706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in_systm.h>
34706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/ip.h>
35706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/socket.h>
36706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/un.h>
37706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
38706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <ctype.h>
39706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <errno.h>
40706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <fcntl.h>
41706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
42706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <md4.h>
43706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
44706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <md5.h>
45706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <paths.h>
46706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <signal.h>
47706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdio.h>
48706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdlib.h>
49706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <string.h>
50706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/wait.h>
51706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <termios.h>
52706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <unistd.h>
53706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
54706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "layer.h"
55706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mbuf.h"
56706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "log.h"
57706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "defs.h"
58706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "timer.h"
59706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "fsm.h"
60706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "proto.h"
61706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lqr.h"
62706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "hdlc.h"
63706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lcp.h"
64706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "auth.h"
65706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "async.h"
66706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "throughput.h"
67706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "descriptor.h"
68706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "chap.h"
69706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "iplist.h"
70706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "slcompress.h"
71706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncpaddr.h"
72706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipcp.h"
73706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "filter.h"
74706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ccp.h"
75706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "link.h"
76706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "physical.h"
77706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mp.h"
78706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS
79706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "radius.h"
80706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
81706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipv6cp.h"
82706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncp.h"
83706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "bundle.h"
84706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "chat.h"
85706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "cbcp.h"
86706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "command.h"
87706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "datalink.h"
88706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
89706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "chap_ms.h"
90706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mppe.h"
91706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
92706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "id.h"
93706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
94706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic const char * const chapcodes[] = {
95706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  "???", "CHALLENGE", "RESPONSE", "SUCCESS", "FAILURE"
96706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh};
97706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define MAXCHAPCODE (sizeof chapcodes / sizeof chapcodes[0] - 1)
98706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
99706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehChapOutput(struct physical *physical, u_int code, u_int id,
101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	   const u_char *ptr, int count, const char *text)
102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int plen;
104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct fsmheader lh;
105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mbuf *bp;
106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  plen = sizeof(struct fsmheader) + count;
108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lh.code = code;
109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lh.id = id;
110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lh.length = htons(plen);
111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  bp = m_get(plen, MB_CHAPOUT);
112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (count)
114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count);
115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_DumpBp(LogDEBUG, "ChapOutput", bp);
116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (text == NULL)
117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogPHASE, "Chap Output: %s\n", chapcodes[code]);
118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else
119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogPHASE, "Chap Output: %s (%s)\n", chapcodes[code], text);
120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  link_PushPacket(&physical->link, bp, physical->dl->bundle,
121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  LINK_QUEUES(&physical->link) - 1, PROTO_CHAP);
122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic char *
125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_BuildAnswer(char *name, char *key, u_char id, char *challenge
126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		 , u_char type, char *peerchallenge, char *authresponse,
128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		 int lanman
129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                )
131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char *result, *digest;
133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size_t nlen, klen;
134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  nlen = strlen(name);
136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  klen = strlen(key);
137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (type == 0x80) {
140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    char expkey[AUTHLEN << 2];
141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    MD4_CTX MD4context;
142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    size_t f;
143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if ((result = malloc(1 + nlen + MS_CHAP_RESPONSE_LEN)) == NULL)
145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return result;
146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    digest = result;					/* the response */
148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *digest++ = MS_CHAP_RESPONSE_LEN;			/* 49 */
149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(digest + MS_CHAP_RESPONSE_LEN, name, nlen);
150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (lanman) {
151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memset(digest + 24, '\0', 25);
152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      mschap_LANMan(digest, challenge + 1, key);	/* LANMan response */
153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else {
154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memset(digest, '\0', 25);
155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      digest += 24;
156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      for (f = 0; f < klen; f++) {
158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        expkey[2*f] = key[f];
159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        expkey[2*f+1] = '\0';
160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      /*
162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       *           -----------
163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       * expkey = | k\0e\0y\0 |
164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       *           -----------
165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       */
166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      MD4Init(&MD4context);
167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      MD4Update(&MD4context, expkey, klen << 1);
168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      MD4Final(digest, &MD4context);
169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      /*
171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       *           ---- -------- ---------------- ------- ------
172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       * result = | 49 | LANMan | 16 byte digest | 9 * ? | name |
173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       *           ---- -------- ---------------- ------- ------
174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       */
175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      mschap_NT(digest, challenge + 1);
176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /*
178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     *           ---- -------- ------------- ----- ------
179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     *          |    |  struct MS_ChapResponse24  |      |
180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     * result = | 49 | LANMan  |  NT digest | 0/1 | name |
181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     *           ---- -------- ------------- ----- ------
182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     * where only one of LANMan & NT digest are set.
183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     */
184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else if (type == 0x81) {
185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    char expkey[AUTHLEN << 2];
186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    char pwdhash[CHAP81_HASH_LEN];
187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    char pwdhashhash[CHAP81_HASH_LEN];
188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    char *ntresponse;
189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    size_t f;
190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if ((result = malloc(1 + nlen + CHAP81_RESPONSE_LEN)) == NULL)
192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return result;
193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memset(result, 0, 1 + nlen + CHAP81_RESPONSE_LEN);
195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    digest = result;
197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *digest++ = CHAP81_RESPONSE_LEN;		/* value size */
198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Copy our challenge */
200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(digest, peerchallenge + 1, CHAP81_CHALLENGE_LEN);
201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Expand password to Unicode XXX */
203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    for (f = 0; f < klen; f++) {
204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      expkey[2*f] = key[f];
205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      expkey[2*f+1] = '\0';
206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ntresponse = digest + CHAP81_NTRESPONSE_OFF;
209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Get some needed hashes */
211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    NtPasswordHash(expkey, klen * 2, pwdhash);
212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    HashNtPasswordHash(pwdhash, pwdhashhash);
213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
214706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Generate NTRESPONSE to respond on challenge call */
215706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    GenerateNTResponse(challenge + 1, peerchallenge + 1, name,
216706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                       expkey, klen * 2, ntresponse);
217706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
218706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Generate MPPE MASTERKEY */
219706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    GetMasterKey(pwdhashhash, ntresponse, MPPE_MasterKey);    /* XXX Global ! */
220706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
221706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Generate AUTHRESPONSE to verify on auth success */
222706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    GenerateAuthenticatorResponse(expkey, klen * 2, ntresponse,
223706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                                  peerchallenge + 1, challenge + 1, name,
224706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                                  authresponse);
225706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
226706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    authresponse[CHAP81_AUTHRESPONSE_LEN] = 0;
227706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
228706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(digest + CHAP81_RESPONSE_LEN, name, nlen);
229706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else
230706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
231706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((result = malloc(nlen + 17)) != NULL) {
232706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Normal MD5 stuff */
233706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    MD5_CTX MD5context;
234706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
235706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    digest = result;
236706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *digest++ = 16;				/* value size */
237706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
238706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    MD5Init(&MD5context);
239706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    MD5Update(&MD5context, &id, 1);
240706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    MD5Update(&MD5context, key, klen);
241706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    MD5Update(&MD5context, challenge + 1, *challenge);
242706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    MD5Final(digest, &MD5context);
243706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
244706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(digest + 16, name, nlen);
245706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /*
246706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     *           ---- -------- ------
247706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     * result = | 16 | digest | name |
248706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     *           ---- -------- ------
249706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     */
250706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
251706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
252706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return result;
253706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
254706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
255706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
256706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_StartChild(struct chap *chap, char *prog, const char *name)
257706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
258706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char *argv[MAXARGS], *nargv[MAXARGS];
259706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int argc, fd;
260706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int in[2], out[2];
261706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  pid_t pid;
262706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
263706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (chap->child.fd != -1) {
264706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogWARN, "Chap: %s: Program already running\n", prog);
265706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
266706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
267706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
268706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (pipe(in) == -1) {
269706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "Chap: pipe: %s\n", strerror(errno));
270706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
271706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
272706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
273706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (pipe(out) == -1) {
274706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "Chap: pipe: %s\n", strerror(errno));
275706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    close(in[0]);
276706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    close(in[1]);
277706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
278706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
279706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
280706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  pid = getpid();
281706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  switch ((chap->child.pid = fork())) {
282706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case -1:
283706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "Chap: fork: %s\n", strerror(errno));
284706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      close(in[0]);
285706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      close(in[1]);
286706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      close(out[0]);
287706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      close(out[1]);
288706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      chap->child.pid = 0;
289706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return;
290706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
291706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case 0:
292706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      timer_TermService();
293706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
294706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if ((argc = command_Interpret(prog, strlen(prog), argv)) <= 0) {
295706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (argc < 0) {
296706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogWARN, "CHAP: Invalid command syntax\n");
297706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          _exit(255);
298706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
299706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        _exit(0);
300706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
301706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
302706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      close(in[1]);
303706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      close(out[0]);
304706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (out[1] == STDIN_FILENO)
305706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        out[1] = dup(out[1]);
306706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      dup2(in[0], STDIN_FILENO);
307706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      dup2(out[1], STDOUT_FILENO);
308706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      close(STDERR_FILENO);
309706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (open(_PATH_DEVNULL, O_RDWR) != STDERR_FILENO) {
310706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogALERT, "Chap: Failed to open %s: %s\n",
311706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  _PATH_DEVNULL, strerror(errno));
312706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        exit(1);
313706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
314706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      for (fd = getdtablesize(); fd > STDERR_FILENO; fd--)
315706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        fcntl(fd, F_SETFD, 1);
316706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOSUID
317706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      setuid(ID0realuid());
318706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
319706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      command_Expand(nargv, argc, (char const *const *)argv,
320706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     chap->auth.physical->dl->bundle, 0, pid);
321706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      execvp(nargv[0], nargv);
322706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      printf("exec() of %s failed: %s\n", nargv[0], strerror(errno));
323706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      _exit(255);
324706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
325706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    default:
326706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      close(in[0]);
327706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      close(out[1]);
328706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      chap->child.fd = out[0];
329706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      chap->child.buf.len = 0;
330706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      write(in[1], chap->auth.in.name, strlen(chap->auth.in.name));
331706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      write(in[1], "\n", 1);
332706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      write(in[1], chap->challenge.peer + 1, *chap->challenge.peer);
333706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      write(in[1], "\n", 1);
334706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      write(in[1], name, strlen(name));
335706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      write(in[1], "\n", 1);
336706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      close(in[1]);
337706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
338706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
339706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
340706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
341706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
342706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_Cleanup(struct chap *chap, int sig)
343706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
344706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (chap->child.pid) {
345706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    int status;
346706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
347706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    close(chap->child.fd);
348706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    chap->child.fd = -1;
349706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (sig)
350706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      kill(chap->child.pid, SIGTERM);
351706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    chap->child.pid = 0;
352706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    chap->child.buf.len = 0;
353706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
354706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (wait(&status) == -1)
355706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "Chap: wait: %s\n", strerror(errno));
356706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    else if (WIFSIGNALED(status))
357706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogWARN, "Chap: Child received signal %d\n", WTERMSIG(status));
358706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    else if (WIFEXITED(status) && WEXITSTATUS(status))
359706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "Chap: Child exited %d\n", WEXITSTATUS(status));
360706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
361706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  *chap->challenge.local = *chap->challenge.peer = '\0';
362706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
363706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  chap->peertries = 0;
364706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
365706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
366706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
367706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
368706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_Respond(struct chap *chap, char *name, char *key
369706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
370706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             , u_char type, int lm
371706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
372706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            )
373706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
374706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char *ans;
375706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
376706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  ans = chap_BuildAnswer(name, key, chap->auth.id, chap->challenge.peer
377706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
378706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                         , type, chap->challenge.local, chap->authresponse, lm
379706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
380706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                        );
381706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
382706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (ans) {
383706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ChapOutput(chap->auth.physical, CHAP_RESPONSE, chap->auth.id,
384706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               ans, *ans + 1 + strlen(name), name);
385706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
386706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    chap->NTRespSent = !lm;
387706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    MPPE_IsServer = 0;		/* XXX Global ! */
388706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
389706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    free(ans);
390706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else
391706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ChapOutput(chap->auth.physical, CHAP_FAILURE, chap->auth.id,
392706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               "Out of memory!", 14, NULL);
393706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
394706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
395706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
396706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w __unused,
397706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	       fd_set *e __unused, int *n)
398706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
399706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct chap *chap = descriptor2chap(d);
400706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
401706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (r && chap && chap->child.fd != -1) {
402706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    FD_SET(chap->child.fd, r);
403706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (*n < chap->child.fd + 1)
404706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      *n = chap->child.fd + 1;
405706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogTIMER, "Chap: fdset(r) %d\n", chap->child.fd);
406706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 1;
407706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
408706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
409706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 0;
410706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
411706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
412706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
413706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_IsSet(struct fdescriptor *d, const fd_set *fdset)
414706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
415706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct chap *chap = descriptor2chap(d);
416706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
417706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return chap && chap->child.fd != -1 && FD_ISSET(chap->child.fd, fdset);
418706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
419706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
420706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
421706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_Read(struct fdescriptor *d, struct bundle *bundle __unused,
422706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	  const fd_set *fdset __unused)
423706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
424706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct chap *chap = descriptor2chap(d);
425706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int got;
426706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
427706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  got = read(chap->child.fd, chap->child.buf.ptr + chap->child.buf.len,
428706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             sizeof chap->child.buf.ptr - chap->child.buf.len - 1);
429706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (got == -1) {
430706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "Chap: Read: %s\n", strerror(errno));
431706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    chap_Cleanup(chap, SIGTERM);
432706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else if (got == 0) {
433706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogWARN, "Chap: Read: Child terminated connection\n");
434706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    chap_Cleanup(chap, SIGTERM);
435706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else {
436706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    char *name, *key, *end;
437706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
438706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    chap->child.buf.len += got;
439706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    chap->child.buf.ptr[chap->child.buf.len] = '\0';
440706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    name = chap->child.buf.ptr;
441706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    name += strspn(name, " \t");
442706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if ((key = strchr(name, '\n')) == NULL)
443706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      end = NULL;
444706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    else
445706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      end = strchr(++key, '\n');
446706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
447706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (end == NULL) {
448706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (chap->child.buf.len == sizeof chap->child.buf.ptr - 1) {
449706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogWARN, "Chap: Read: Input buffer overflow\n");
450706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        chap_Cleanup(chap, SIGTERM);
451706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
452706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else {
453706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
454706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      int lanman = chap->auth.physical->link.lcp.his_authtype == 0x80 &&
455706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                   ((chap->NTRespSent &&
456706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     IsAccepted(chap->auth.physical->link.lcp.cfg.chap80lm)) ||
457706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    !IsAccepted(chap->auth.physical->link.lcp.cfg.chap80nt));
458706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
459706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
460706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      while (end >= name && strchr(" \t\r\n", *end))
461706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        *end-- = '\0';
462706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      end = key - 1;
463706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      while (end >= name && strchr(" \t\r\n", *end))
464706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        *end-- = '\0';
465706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      key += strspn(key, " \t");
466706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
467706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      chap_Respond(chap, name, key
468706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
469706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                   , chap->auth.physical->link.lcp.his_authtype, lanman
470706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
471706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  );
472706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      chap_Cleanup(chap, 0);
473706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
474706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
475706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
476706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
477706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
478706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_Write(struct fdescriptor *d __unused, struct bundle *bundle __unused,
479706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	   const fd_set *fdset __unused)
480706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
481706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* We never want to write here ! */
482706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogALERT, "chap_Write: Internal error: Bad call !\n");
483706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 0;
484706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
485706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
486706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
487706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_ChallengeInit(struct authinfo *authp)
488706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
489706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct chap *chap = auth2chap(authp);
490706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int len, i;
491706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char *cp;
492706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
493706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  len = strlen(authp->physical->dl->bundle->cfg.auth.name);
494706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
495706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (!*chap->challenge.local) {
496706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    randinit();
497706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    cp = chap->challenge.local;
498706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
499706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS
500706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (*authp->physical->dl->bundle->radius.cfg.file) {
501706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      /* For radius, our challenge is 16 readable NUL terminated bytes :*/
502706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      *cp++ = 16;
503706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      for (i = 0; i < 16; i++)
504706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        *cp++ = (random() % 10) + '0';
505706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else
506706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
507706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    {
508706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
509706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (authp->physical->link.lcp.want_authtype == 0x80)
510706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        *cp++ = 8;	/* MS does 8 byte callenges :-/ */
511706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      else if (authp->physical->link.lcp.want_authtype == 0x81)
512706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        *cp++ = 16;	/* MS-CHAP-V2 does 16 bytes challenges */
513706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      else
514706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
515706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        *cp++ = random() % (CHAPCHALLENGELEN-16) + 16;
516706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      for (i = 0; i < *chap->challenge.local; i++)
517706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        *cp++ = random() & 0xff;
518706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
519706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(cp, authp->physical->dl->bundle->cfg.auth.name, len);
520706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
521706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
522706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
523706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
524706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_Challenge(struct authinfo *authp)
525706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
526706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct chap *chap = auth2chap(authp);
527706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int len;
528706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
529706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogDEBUG, "CHAP%02X: Challenge\n",
530706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             authp->physical->link.lcp.want_authtype);
531706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
532706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  len = strlen(authp->physical->dl->bundle->cfg.auth.name);
533706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
534706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Generate new local challenge value */
535706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (!*chap->challenge.local)
536706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    chap_ChallengeInit(authp);
537706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
538706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
539706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (authp->physical->link.lcp.want_authtype == 0x81)
540706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ChapOutput(authp->physical, CHAP_CHALLENGE, authp->id,
541706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             chap->challenge.local, 1 + *chap->challenge.local, NULL);
542706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else
543706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
544706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ChapOutput(authp->physical, CHAP_CHALLENGE, authp->id,
545706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             chap->challenge.local, 1 + *chap->challenge.local + len, NULL);
546706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
547706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
548706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
549706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_Success(struct authinfo *authp)
550706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
551706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct bundle *bundle = authp->physical->dl->bundle;
552706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  const char *msg;
553706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
554706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  datalink_GotAuthname(authp->physical->dl, authp->in.name);
555706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
556706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (authp->physical->link.lcp.want_authtype == 0x81) {
557706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS
558706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (*bundle->radius.cfg.file && bundle->radius.msrepstr)
559706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      msg = bundle->radius.msrepstr;
560706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    else
561706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
562706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      msg = auth2chap(authp)->authresponse;
563706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    MPPE_MasterKeyValid = 1;		/* XXX Global ! */
564706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else
565706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
566706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS
567706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (*bundle->radius.cfg.file && bundle->radius.repstr)
568706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    msg = bundle->radius.repstr;
569706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else
570706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
571706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    msg = "Welcome!!";
572706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
573706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  ChapOutput(authp->physical, CHAP_SUCCESS, authp->id, msg, strlen(msg),
574706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             NULL);
575706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
576706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  authp->physical->link.lcp.auth_ineed = 0;
577706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (Enabled(bundle, OPT_UTMP))
578706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    physical_Login(authp->physical, authp->in.name);
579706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
580706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (authp->physical->link.lcp.auth_iwait == 0)
581706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /*
582706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     * Either I didn't need to authenticate, or I've already been
583706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     * told that I got the answer right.
584706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     */
585706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    datalink_AuthOk(authp->physical->dl);
586706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
587706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
588706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
589706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_Failure(struct authinfo *authp)
590706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
591706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
592706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char buf[1024], *ptr;
593706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
594706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  const char *msg;
595706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
596706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS
597706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct bundle *bundle = authp->physical->link.lcp.fsm.bundle;
598706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (*bundle->radius.cfg.file && bundle->radius.errstr)
599706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    msg = bundle->radius.errstr;
600706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else
601706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
602706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
603706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (authp->physical->link.lcp.want_authtype == 0x80) {
604706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    sprintf(buf, "E=691 R=1 M=Invalid!");
605706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    msg = buf;
606706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else if (authp->physical->link.lcp.want_authtype == 0x81) {
607706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    int i;
608706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
609706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ptr = buf;
610706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ptr += sprintf(buf, "E=691 R=0 C=");
611706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    for (i=0; i<16; i++)
612706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      ptr += sprintf(ptr, "%02X", *(auth2chap(authp)->challenge.local+1+i));
613706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
614706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    sprintf(ptr, " V=3 M=Invalid!");
615706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    msg = buf;
616706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else
617706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
618706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    msg = "Invalid!!";
619706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
620706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  ChapOutput(authp->physical, CHAP_FAILURE, authp->id, msg, strlen(msg) + 1,
621706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             NULL);
622706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  datalink_AuthNotOk(authp->physical->dl);
623706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
624706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
625706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
626706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_Cmp(char *myans, int mylen, char *hisans, int hislen
627706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
628706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         , u_char type, int lm
629706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
630706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        )
631706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
632706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int off;
633706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
634706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (mylen != hislen)
635706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 0;
636706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
637706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  off = 0;
638706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
639706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
640706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (type == 0x80) {
641706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    off = lm ? 0 : 24;
642706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    mylen = 24;
643706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
644706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
645706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
646706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  for (; mylen; off++, mylen--)
647706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (toupper(myans[off]) != toupper(hisans[off]))
648706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return 0;
649706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
650706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 1;
651706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
652706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
653706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
654706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
655706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_HaveAnotherGo(struct chap *chap)
656706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
657706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (++chap->peertries < 3) {
658706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Give the peer another shot */
659706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *chap->challenge.local = '\0';
660706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    chap_Challenge(&chap->auth);
661706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 1;
662706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
663706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
664706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 0;
665706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
666706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
667706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
668706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
669706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_Init(struct chap *chap, struct physical *p)
670706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
671706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  chap->desc.type = CHAP_DESCRIPTOR;
672706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  chap->desc.UpdateSet = chap_UpdateSet;
673706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  chap->desc.IsSet = chap_IsSet;
674706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  chap->desc.Read = chap_Read;
675706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  chap->desc.Write = chap_Write;
676706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  chap->child.pid = 0;
677706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  chap->child.fd = -1;
678706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  auth_Init(&chap->auth, p, chap_Challenge, chap_Success, chap_Failure);
679706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  *chap->challenge.local = *chap->challenge.peer = '\0';
680706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
681706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  chap->NTRespSent = 0;
682706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  chap->peertries = 0;
683706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
684706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
685706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
686706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
687706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_ReInit(struct chap *chap)
688706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
689706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  chap_Cleanup(chap, SIGTERM);
690706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
691706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
692706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbuf *
693706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehchap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
694706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
695706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct physical *p = link2physical(l);
696706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct chap *chap = &p->dl->chap;
697706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char *name, *key, *ans;
698706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int len;
699706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size_t nlen;
700706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char alen;
701706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
702706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int lanman;
703706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
704706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
705706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (p == NULL) {
706706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "chap_Input: Not a physical link - dropped\n");
707706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    m_freem(bp);
708706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return NULL;
709706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
710706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
711706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (bundle_Phase(bundle) != PHASE_NETWORK &&
712706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      bundle_Phase(bundle) != PHASE_AUTHENTICATE) {
713706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogPHASE, "Unexpected chap input - dropped !\n");
714706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    m_freem(bp);
715706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return NULL;
716706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
717706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
718706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  m_settype(bp, MB_CHAPIN);
719706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((bp = auth_ReadHeader(&chap->auth, bp)) == NULL &&
720706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      ntohs(chap->auth.in.hdr.length) == 0)
721706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogWARN, "Chap Input: Truncated header !\n");
722706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else if (chap->auth.in.hdr.code == 0 || chap->auth.in.hdr.code > MAXCHAPCODE)
723706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogPHASE, "Chap Input: %d: Bad CHAP code !\n",
724706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               chap->auth.in.hdr.code);
725706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else {
726706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    len = m_length(bp);
727706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ans = NULL;
728706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
729706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (chap->auth.in.hdr.code != CHAP_CHALLENGE &&
730706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        chap->auth.id != chap->auth.in.hdr.id &&
731706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        Enabled(bundle, OPT_IDCHECK)) {
732706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      /* Wrong conversation dude ! */
733706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogPHASE, "Chap Input: %s dropped (got id %d, not %d)\n",
734706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 chapcodes[chap->auth.in.hdr.code], chap->auth.in.hdr.id,
735706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 chap->auth.id);
736706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      m_freem(bp);
737706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return NULL;
738706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
739706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    chap->auth.id = chap->auth.in.hdr.id;	/* We respond with this id */
740706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
741706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
742706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lanman = 0;
743706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
744706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    switch (chap->auth.in.hdr.code) {
745706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_CHALLENGE:
746706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bp = mbuf_Read(bp, &alen, 1);
747706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        len -= alen + 1;
748706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (len < 0) {
749706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogERROR, "Chap Input: Truncated challenge !\n");
750706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          m_freem(bp);
751706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          return NULL;
752706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
753706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        *chap->challenge.peer = alen;
754706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bp = mbuf_Read(bp, chap->challenge.peer + 1, alen);
755706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bp = auth_ReadName(&chap->auth, bp, len);
756706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
757706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lanman = p->link.lcp.his_authtype == 0x80 &&
758706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 ((chap->NTRespSent && IsAccepted(p->link.lcp.cfg.chap80lm)) ||
759706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  !IsAccepted(p->link.lcp.cfg.chap80nt));
760706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
761706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /* Generate local challenge value */
762706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        chap_ChallengeInit(&chap->auth);
763706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
764706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
765706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
766706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_RESPONSE:
767706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        auth_StopTimer(&chap->auth);
768706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bp = mbuf_Read(bp, &alen, 1);
769706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        len -= alen + 1;
770706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (len < 0) {
771706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogERROR, "Chap Input: Truncated response !\n");
772706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          m_freem(bp);
773706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          return NULL;
774706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
775706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if ((ans = malloc(alen + 1)) == NULL) {
776706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogERROR, "Chap Input: Out of memory !\n");
777706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          m_freem(bp);
778706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          return NULL;
779706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
780706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        *ans = chap->auth.id;
781706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bp = mbuf_Read(bp, ans + 1, alen);
782706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bp = auth_ReadName(&chap->auth, bp, len);
783706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
784706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lanman = p->link.lcp.want_authtype == 0x80 &&
785706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 alen == 49 && ans[alen] == 0;
786706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
787706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
788706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
789706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_SUCCESS:
790706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_FAILURE:
791706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /* chap->auth.in.name is already set up at CHALLENGE time */
792706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if ((ans = malloc(len + 1)) == NULL) {
793706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogERROR, "Chap Input: Out of memory !\n");
794706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          m_freem(bp);
795706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          return NULL;
796706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
797706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bp = mbuf_Read(bp, ans, len);
798706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        ans[len] = '\0';
799706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
800706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
801706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
802706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    switch (chap->auth.in.hdr.code) {
803706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_CHALLENGE:
804706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_RESPONSE:
805706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (*chap->auth.in.name)
806706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogPHASE, "Chap Input: %s (%d bytes from %s%s)\n",
807706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     chapcodes[chap->auth.in.hdr.code], alen,
808706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     chap->auth.in.name,
809706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
810706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ?
811706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     " - lanman" :
812706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
813706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     "");
814706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else
815706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogPHASE, "Chap Input: %s (%d bytes%s)\n",
816706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     chapcodes[chap->auth.in.hdr.code], alen,
817706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
818706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ?
819706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     " - lanman" :
820706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
821706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     "");
822706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
823706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
824706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_SUCCESS:
825706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_FAILURE:
826706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (*ans)
827706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogPHASE, "Chap Input: %s (%s)\n",
828706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     chapcodes[chap->auth.in.hdr.code], ans);
829706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else
830706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogPHASE, "Chap Input: %s\n",
831706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     chapcodes[chap->auth.in.hdr.code]);
832706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
833706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
834706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
835706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    switch (chap->auth.in.hdr.code) {
836706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_CHALLENGE:
837706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (*bundle->cfg.auth.key == '!' && bundle->cfg.auth.key[1] != '!')
838706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          chap_StartChild(chap, bundle->cfg.auth.key + 1,
839706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                          bundle->cfg.auth.name);
840706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else
841706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          chap_Respond(chap, bundle->cfg.auth.name, bundle->cfg.auth.key +
842706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                       (*bundle->cfg.auth.key == '!' ? 1 : 0)
843706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
844706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
845706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                       , p->link.lcp.his_authtype, lanman
846706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
847706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                      );
848706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
849706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
850706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_RESPONSE:
851706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        name = chap->auth.in.name;
852706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        nlen = strlen(name);
853706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
854706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (p->link.lcp.want_authtype == 0x81) {
855706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          struct MSCHAPv2_resp *resp = (struct MSCHAPv2_resp *)(ans + 1);
856706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
857706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          chap->challenge.peer[0] = sizeof resp->PeerChallenge;
858706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          memcpy(chap->challenge.peer + 1, resp->PeerChallenge,
859706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 sizeof resp->PeerChallenge);
860706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
861706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
862706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
863706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS
864706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (*bundle->radius.cfg.file) {
865706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (!radius_Authenticate(&bundle->radius, &chap->auth,
866706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                                   chap->auth.in.name, ans, alen + 1,
867706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                                   chap->challenge.local + 1,
868706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                                   *chap->challenge.local))
869706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            chap_Failure(&chap->auth);
870706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else
871706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
872706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        {
873706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (p->link.lcp.want_authtype == 0x81 && ans[alen] != '\0' &&
874706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              alen == sizeof(struct MSCHAPv2_resp)) {
875706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            struct MSCHAPv2_resp *resp = (struct MSCHAPv2_resp *)(ans + 1);
876706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
877706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            log_Printf(LogWARN, "%s: Compensating for corrupt (Win98/WinME?) "
878706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                       "CHAP81 RESPONSE\n", l->name);
879706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            resp->Flags = '\0';	/* rfc2759 says it *MUST* be zero */
880706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
881706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          key = auth_GetSecret(name, nlen);
882706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (key) {
883706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
884706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            if (p->link.lcp.want_authtype == 0x80 &&
885706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lanman && !IsEnabled(p->link.lcp.cfg.chap80lm)) {
886706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              log_Printf(LogPHASE, "Auth failure: LANMan not enabled\n");
887706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              if (chap_HaveAnotherGo(chap))
888706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                break;
889706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              key = NULL;
890706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            } else if (p->link.lcp.want_authtype == 0x80 &&
891706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                !lanman && !IsEnabled(p->link.lcp.cfg.chap80nt)) {
892706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              log_Printf(LogPHASE, "Auth failure: mschap not enabled\n");
893706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              if (chap_HaveAnotherGo(chap))
894706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                break;
895706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              key = NULL;
896706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            } else if (p->link.lcp.want_authtype == 0x81 &&
897706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                !IsEnabled(p->link.lcp.cfg.chap81)) {
898706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              log_Printf(LogPHASE, "Auth failure: CHAP81 not enabled\n");
899706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              key = NULL;
900706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            } else
901706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
902706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            {
903706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              char *myans = chap_BuildAnswer(name, key, chap->auth.id,
904706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                                             chap->challenge.local
905706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
906706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh					     , p->link.lcp.want_authtype,
907706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh					     chap->challenge.peer,
908706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh					     chap->authresponse, lanman);
909706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              MPPE_IsServer = 1;		/* XXX Global ! */
910706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#else
911706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                                      );
912706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
913706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              if (myans == NULL)
914706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                key = NULL;
915706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              else {
916706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                if (!chap_Cmp(myans + 1, *myans, ans + 1, alen
917706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
918706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                              , p->link.lcp.want_authtype, lanman
919706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
920706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                             ))
921706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  key = NULL;
922706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                free(myans);
923706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              }
924706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            }
925706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
926706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
927706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (key)
928706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            chap_Success(&chap->auth);
929706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          else
930706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            chap_Failure(&chap->auth);
931706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
932706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
933706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
934706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
935706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_SUCCESS:
936706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (p->link.lcp.auth_iwait == PROTO_CHAP) {
937706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          p->link.lcp.auth_iwait = 0;
938706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (p->link.lcp.auth_ineed == 0) {
939706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
940706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            if (p->link.lcp.his_authtype == 0x81) {
941706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              if (strncasecmp(ans, chap->authresponse, 42)) {
942706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                datalink_AuthNotOk(p->dl);
943706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	        log_Printf(LogWARN, "CHAP81: AuthenticatorResponse: (%.42s)"
944706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                           " != ans: (%.42s)\n", chap->authresponse, ans);
945706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
946706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              } else {
947706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                /* Successful login */
948706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                MPPE_MasterKeyValid = 1;		/* XXX Global ! */
949706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                datalink_AuthOk(p->dl);
950706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              }
951706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            } else
952706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
953706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            /*
954706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             * We've succeeded in our ``login''
955706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             * If we're not expecting  the peer to authenticate (or he already
956706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             * has), proceed to network phase.
957706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             */
958706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            datalink_AuthOk(p->dl);
959706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
960706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
961706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
962706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
963706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case CHAP_FAILURE:
964706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        datalink_AuthNotOk(p->dl);
965706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
966706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
967706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    free(ans);
968706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
969706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
970706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  m_freem(bp);
971706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return NULL;
972706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
973