1706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
2706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Copyright 1999 Internet Business Solutions Ltd., Switzerland
3706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * All rights reserved.
4706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
5706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Redistribution and use in source and binary forms, with or without
6706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * modification, are permitted provided that the following conditions
7706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * are met:
8706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 1. Redistributions of source code must retain the above copyright
9706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    notice, this list of conditions and the following disclaimer.
10706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 2. Redistributions in binary form must reproduce the above copyright
11706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    notice, this list of conditions and the following disclaimer in the
12706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    documentation and/or other materials provided with the distribution.
13706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
14706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * SUCH DAMAGE.
25706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
26706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * $FreeBSD: src/usr.sbin/ppp/radius.c,v 1.54.14.1 2010/12/21 17:10:29 kensmith Exp $
27706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
28706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
29706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
30706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdint.h>
31706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/param.h>
32706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
33706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/select.h>
34706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/socket.h>
35706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in_systm.h>
36706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in.h>
37706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/ip.h>
38706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <arpa/inet.h>
39706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/un.h>
40706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <net/route.h>
41706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
42706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifdef LOCALRAD
43706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "radlib.h"
44706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "radlib_vs.h"
45706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#else
46706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <radlib.h>
47706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <radlib_vs.h>
48706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
49706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
50706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <errno.h>
51706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
52706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <md5.h>
53706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
54706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdarg.h>
55706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdio.h>
56706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdlib.h>
57706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <string.h>
58706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/time.h>
59706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <termios.h>
60706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <unistd.h>
61706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netdb.h>
62706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
63706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "layer.h"
64706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "defs.h"
65706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "log.h"
66706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "descriptor.h"
67706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "prompt.h"
68706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "timer.h"
69706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "fsm.h"
70706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "iplist.h"
71706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "slcompress.h"
72706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "throughput.h"
73706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lqr.h"
74706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "hdlc.h"
75706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mbuf.h"
76706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncpaddr.h"
77706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ip.h"
78706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipcp.h"
79706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipv6cp.h"
80706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "route.h"
81706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "command.h"
82706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "filter.h"
83706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lcp.h"
84706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ccp.h"
85706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "link.h"
86706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mp.h"
87706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "radius.h"
88706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "auth.h"
89706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "async.h"
90706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "physical.h"
91706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "chat.h"
92706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "cbcp.h"
93706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "chap.h"
94706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "datalink.h"
95706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncp.h"
96706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "bundle.h"
97706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "proto.h"
98706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "iface.h"
99706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mschap_response {
102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char ident;
103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char flags;
104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char lm_response[24];
105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char nt_response[24];
106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh};
107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mschap2_response {
109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char ident;
110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char flags;
111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char pchallenge[16];
112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char reserved[8];
113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char response[24];
114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh};
115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define	AUTH_LEN	16
117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define	SALT_LEN	2
118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic const char *
121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_policyname(int policy)
122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  switch(policy) {
124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  case MPPE_POLICY_ALLOWED:
125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return "Allowed";
126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  case MPPE_POLICY_REQUIRED:
127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return "Required";
128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return NumStr(policy, NULL, 0);
130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic const char *
133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_typesname(int types)
134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  switch(types) {
136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  case MPPE_TYPE_40BIT:
137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return "40 bit";
138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  case MPPE_TYPE_128BIT:
139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return "128 bit";
140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  case MPPE_TYPE_40BIT|MPPE_TYPE_128BIT:
141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return "40 or 128 bit";
142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return NumStr(types, NULL, 0);
144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehdemangle(struct radius *r, const void *mangled, size_t mlen,
149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         char **buf, size_t *len)
150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char R[AUTH_LEN];		/* variable names as per rfc2548 */
152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  const char *S;
153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char b[16];
154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  const u_char *A, *C;
155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  MD5_CTX Context;
156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int Slen, i, Clen, Ppos;
157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char *P;
158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (mlen % 16 != SALT_LEN) {
160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogWARN, "Cannot interpret mangled data of length %ld\n",
161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               (u_long)mlen);
162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *buf = NULL;
163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *len = 0;
164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* We need the RADIUS Request-Authenticator */
168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (rad_request_authenticator(r->cx.rad, R, sizeof R) != AUTH_LEN) {
169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogWARN, "Cannot obtain the RADIUS request authenticator\n");
170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *buf = NULL;
171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *len = 0;
172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  A = (const u_char *)mangled;			/* Salt comes first */
176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  C = (const u_char *)mangled + SALT_LEN;	/* Then the ciphertext */
177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  Clen = mlen - SALT_LEN;
178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  S = rad_server_secret(r->cx.rad);		/* We need the RADIUS secret */
179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  Slen = strlen(S);
180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  P = alloca(Clen);				/* We derive our plaintext */
181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  MD5Init(&Context);
183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  MD5Update(&Context, S, Slen);
184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  MD5Update(&Context, R, AUTH_LEN);
185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  MD5Update(&Context, A, SALT_LEN);
186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  MD5Final(b, &Context);
187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  Ppos = 0;
188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  while (Clen) {
190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    Clen -= 16;
191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    for (i = 0; i < 16; i++)
193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      P[Ppos++] = C[i] ^ b[i];
194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (Clen) {
196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      MD5Init(&Context);
197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      MD5Update(&Context, S, Slen);
198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      MD5Update(&Context, C, 16);
199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      MD5Final(b, &Context);
200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    C += 16;
203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /*
206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh   * The resulting plain text consists of a one-byte length, the text and
207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh   * maybe some padding.
208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh   */
209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  *len = *P;
210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (*len > mlen - 1) {
211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogWARN, "Mangled data seems to be garbage\n");
212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *buf = NULL;
213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *len = 0;
214706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
215706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
216706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
217706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((*buf = malloc(*len)) == NULL) {
218706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogWARN, "demangle: Out of memory (%lu bytes)\n", (u_long)*len);
219706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *len = 0;
220706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else
221706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(*buf, P + 1, *len);
222706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
223706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
224706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
225706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* XXX: This should go into librarius. */
226706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOINET6
227706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic uint8_t *
228706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehrad_cvt_ipv6prefix(const void *data, size_t len)
229706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
230706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	const size_t ipv6len = sizeof(struct in6_addr) + 2;
231706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	uint8_t *s;
232706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
233706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	if (len > ipv6len)
234706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		return NULL;
235706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	s = malloc(ipv6len);
236706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	if (s != NULL) {
237706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		memset(s, 0, ipv6len);
238706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		memcpy(s, data, len);
239706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	}
240706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	return s;
241706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
242706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
243706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
244706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
245706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * rad_continue_send_request() has given us `got' (non-zero).  Deal with it.
246706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
247706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
248706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Process(struct radius *r, int got)
249706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
250706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char *argv[MAXARGS], *nuke;
251706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct bundle *bundle;
252706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int argc, addrs, res, width;
253706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size_t len;
254706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct ncprange dest;
255706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct ncpaddr gw;
256706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  const void *data;
257706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  const char *stype;
258706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_int32_t ipaddr, vendor;
259706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct in_addr ip;
260706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOINET6
261706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  uint8_t ipv6addr[INET6_ADDRSTRLEN];
262706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct in6_addr ip6;
263706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
264706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
265706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->cx.fd = -1;		/* Stop select()ing */
266706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  stype = r->cx.auth ? "auth" : "acct";
267706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
268706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  switch (got) {
269706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case RAD_ACCESS_ACCEPT:
270706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
271706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		 "Radius(%s): ACCEPT received\n", stype);
272706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (!r->cx.auth) {
273706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_close(r->cx.rad);
274706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        return;
275706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
276706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
277706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
278706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case RAD_ACCESS_REJECT:
279706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
280706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		 "Radius(%s): REJECT received\n", stype);
281706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (!r->cx.auth) {
282706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_close(r->cx.rad);
283706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        return;
284706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
285706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
286706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
287706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case RAD_ACCESS_CHALLENGE:
288706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      /* we can't deal with this (for now) ! */
289706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
290706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		 "Radius: CHALLENGE received (can't handle yet)\n");
291706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (r->cx.auth)
292706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        auth_Failure(r->cx.auth);
293706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(r->cx.rad);
294706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return;
295706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
296706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case RAD_ACCOUNTING_RESPONSE:
297706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      /*
298706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       * It's probably not ideal to log this at PHASE level as we'll see
299706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       * too much stuff going to the log when ``set rad_alive'' is used.
300706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       * So we differ from older behaviour (ppp version 3.1 and before)
301706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       * and just log accounting responses to LogRADIUS.
302706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       */
303706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogRADIUS, "Radius(%s): Accounting response received\n",
304706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		 stype);
305706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (r->cx.auth)
306706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        auth_Failure(r->cx.auth);		/* unexpected !!! */
307706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
308706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      /* No further processing for accounting requests, please */
309706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(r->cx.rad);
310706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return;
311706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
312706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case -1:
313706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
314706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		 "radius(%s): %s\n", stype, rad_strerror(r->cx.rad));
315706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (r->cx.auth)
316706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        auth_Failure(r->cx.auth);
317706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(r->cx.rad);
318706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return;
319706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
320706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    default:
321706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "rad_send_request(%s): Failed %d: %s\n", stype,
322706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 got, rad_strerror(r->cx.rad));
323706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (r->cx.auth)
324706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        auth_Failure(r->cx.auth);
325706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(r->cx.rad);
326706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return;
327706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
328706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
329706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Let's see what we've got in our reply */
330706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->ip.s_addr = r->mask.s_addr = INADDR_NONE;
331706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mtu = 0;
332706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->vj = 0;
333706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  while ((res = rad_get_attr(r->cx.rad, &data, &len)) > 0) {
334706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    switch (res) {
335706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_FRAMED_IP_ADDRESS:
336706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        r->ip = rad_cvt_addr(data);
337706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
338706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		   " IP %s\n", inet_ntoa(r->ip));
339706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
340706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
341706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_FILTER_ID:
342706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        free(r->filterid);
343706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if ((r->filterid = rad_cvt_string(data, len)) == NULL) {
344706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogERROR, "rad_cvt_string: %s\n", rad_strerror(r->cx.rad));
345706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          auth_Failure(r->cx.auth);
346706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          rad_close(r->cx.rad);
347706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          return;
348706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
349706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
350706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		   " Filter \"%s\"\n", r->filterid);
351706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
352706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
353706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_SESSION_TIMEOUT:
354706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        r->sessiontime = rad_cvt_int(data);
355706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
356706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		   " Session-Timeout %lu\n", r->sessiontime);
357706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
358706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
359706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_FRAMED_IP_NETMASK:
360706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        r->mask = rad_cvt_addr(data);
361706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
362706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		   " Netmask %s\n", inet_ntoa(r->mask));
363706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
364706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
365706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_FRAMED_MTU:
366706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        r->mtu = rad_cvt_int(data);
367706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
368706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		   " MTU %lu\n", r->mtu);
369706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
370706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
371706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_FRAMED_ROUTING:
372706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /* Disabled for now - should we automatically set up some filters ? */
373706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /* rad_cvt_int(data); */
374706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /* bit 1 = Send routing packets */
375706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /* bit 2 = Receive routing packets */
376706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
377706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
378706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_FRAMED_COMPRESSION:
379706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        r->vj = rad_cvt_int(data) == 1 ? 1 : 0;
380706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
381706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		   " VJ %sabled\n", r->vj ? "en" : "dis");
382706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
383706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
384706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_FRAMED_ROUTE:
385706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /*
386706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         * We expect a string of the format ``dest[/bits] gw [metrics]''
387706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         * Any specified metrics are ignored.  MYADDR and HISADDR are
388706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         * understood for ``dest'' and ``gw'' and ``0.0.0.0'' is the same
389706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         * as ``HISADDR''.
390706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         */
391706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
392706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if ((nuke = rad_cvt_string(data, len)) == NULL) {
393706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogERROR, "rad_cvt_string: %s\n", rad_strerror(r->cx.rad));
394706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          auth_Failure(r->cx.auth);
395706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          rad_close(r->cx.rad);
396706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          return;
397706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
398706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
399706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
400706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		   " Route: %s\n", nuke);
401706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bundle = r->cx.auth->physical->dl->bundle;
402706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        ip.s_addr = INADDR_ANY;
403706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        ncpaddr_setip4(&gw, ip);
404706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        ncprange_setip4host(&dest, ip);
405706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        argc = command_Interpret(nuke, strlen(nuke), argv);
406706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (argc < 0)
407706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogWARN, "radius: %s: Syntax error\n",
408706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     argc == 1 ? argv[0] : "\"\"");
409706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else if (argc < 2)
410706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogWARN, "radius: %s: Invalid route\n",
411706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     argc == 1 ? argv[0] : "\"\"");
412706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else if ((strcasecmp(argv[0], "default") != 0 &&
413706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  !ncprange_aton(&dest, &bundle->ncp, argv[0])) ||
414706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 !ncpaddr_aton(&gw, &bundle->ncp, argv[1]))
415706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogWARN, "radius: %s %s: Invalid route\n",
416706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     argv[0], argv[1]);
417706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else {
418706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          ncprange_getwidth(&dest, &width);
419706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (width == 32 && strchr(argv[0], '/') == NULL) {
420706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            /* No mask specified - use the natural mask */
421706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            ncprange_getip4addr(&dest, &ip);
422706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            ncprange_setip4mask(&dest, addr2mask(ip));
423706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
424706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          addrs = 0;
425706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
426706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (!strncasecmp(argv[0], "HISADDR", 7))
427706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            addrs = ROUTE_DSTHISADDR;
428706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          else if (!strncasecmp(argv[0], "MYADDR", 6))
429706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            addrs = ROUTE_DSTMYADDR;
430706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
431706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (ncpaddr_getip4addr(&gw, &ipaddr) && ipaddr == INADDR_ANY) {
432706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            addrs |= ROUTE_GWHISADDR;
433706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            ncpaddr_setip4(&gw, bundle->ncp.ipcp.peer_ip);
434706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          } else if (strcasecmp(argv[1], "HISADDR") == 0)
435706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            addrs |= ROUTE_GWHISADDR;
436706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
437706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          route_Add(&r->routes, addrs, &dest, &gw);
438706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
439706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        free(nuke);
440706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
441706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
442706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_REPLY_MESSAGE:
443706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        free(r->repstr);
444706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if ((r->repstr = rad_cvt_string(data, len)) == NULL) {
445706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogERROR, "rad_cvt_string: %s\n", rad_strerror(r->cx.rad));
446706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          auth_Failure(r->cx.auth);
447706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          rad_close(r->cx.rad);
448706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          return;
449706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
450706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
451706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		   " Reply-Message \"%s\"\n", r->repstr);
452706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
453706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
454706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOINET6
455706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_FRAMED_IPV6_PREFIX:
456706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	free(r->ipv6prefix);
457706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	if ((r->ipv6prefix = rad_cvt_ipv6prefix(data, len)) == NULL) {
458706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	  log_Printf(LogERROR, "rad_cvt_ipv6prefix: %s\n",
459706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		     "Malformed attribute in response");
460706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	  auth_Failure(r->cx.auth);
461706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	  rad_close(r->cx.rad);
462706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	  return;
463706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	}
464706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	inet_ntop(AF_INET6, &r->ipv6prefix[2], ipv6addr, sizeof(ipv6addr));
465706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
466706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		   " IPv6 %s/%d\n", ipv6addr, r->ipv6prefix[1]);
467706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
468706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
469706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_FRAMED_IPV6_ROUTE:
470706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /*
471706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         * We expect a string of the format ``dest[/bits] gw [metrics]''
472706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         * Any specified metrics are ignored.  MYADDR6 and HISADDR6 are
473706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         * understood for ``dest'' and ``gw'' and ``::'' is the same
474706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         * as ``HISADDR6''.
475706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         */
476706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
477706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if ((nuke = rad_cvt_string(data, len)) == NULL) {
478706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogERROR, "rad_cvt_string: %s\n", rad_strerror(r->cx.rad));
479706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          auth_Failure(r->cx.auth);
480706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          rad_close(r->cx.rad);
481706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          return;
482706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
483706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
484706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
485706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		   " IPv6 Route: %s\n", nuke);
486706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bundle = r->cx.auth->physical->dl->bundle;
487706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	ncpaddr_setip6(&gw, &in6addr_any);
488706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	ncprange_set(&dest, &gw, 0);
489706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        argc = command_Interpret(nuke, strlen(nuke), argv);
490706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (argc < 0)
491706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogWARN, "radius: %s: Syntax error\n",
492706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     argc == 1 ? argv[0] : "\"\"");
493706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else if (argc < 2)
494706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogWARN, "radius: %s: Invalid route\n",
495706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     argc == 1 ? argv[0] : "\"\"");
496706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else if ((strcasecmp(argv[0], "default") != 0 &&
497706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  !ncprange_aton(&dest, &bundle->ncp, argv[0])) ||
498706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 !ncpaddr_aton(&gw, &bundle->ncp, argv[1]))
499706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogWARN, "radius: %s %s: Invalid route\n",
500706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     argv[0], argv[1]);
501706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else {
502706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          addrs = 0;
503706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
504706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (!strncasecmp(argv[0], "HISADDR6", 8))
505706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            addrs = ROUTE_DSTHISADDR6;
506706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          else if (!strncasecmp(argv[0], "MYADDR6", 7))
507706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            addrs = ROUTE_DSTMYADDR6;
508706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
509706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (ncpaddr_getip6(&gw, &ip6) && IN6_IS_ADDR_UNSPECIFIED(&ip6)) {
510706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            addrs |= ROUTE_GWHISADDR6;
511706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            ncpaddr_copy(&gw, &bundle->ncp.ipv6cp.hisaddr);
512706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          } else if (strcasecmp(argv[1], "HISADDR6") == 0)
513706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            addrs |= ROUTE_GWHISADDR6;
514706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
515706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          route_Add(&r->ipv6routes, addrs, &dest, &gw);
516706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
517706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        free(nuke);
518706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
519706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
520706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
521706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case RAD_VENDOR_SPECIFIC:
522706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if ((res = rad_get_vendor_attr(&vendor, &data, &len)) <= 0) {
523706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogERROR, "rad_get_vendor_attr: %s (failing!)\n",
524706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     rad_strerror(r->cx.rad));
525706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          auth_Failure(r->cx.auth);
526706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          rad_close(r->cx.rad);
527706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          return;
528706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
529706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
530706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	switch (vendor) {
531706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          case RAD_VENDOR_MICROSOFT:
532706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            switch (res) {
533706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
534706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              case RAD_MICROSOFT_MS_CHAP_ERROR:
535706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                free(r->errstr);
536706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                if (len == 0)
537706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  r->errstr = NULL;
538706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                else {
539706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  if (len < 3 || ((const char *)data)[1] != '=') {
540706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    /*
541706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     * Only point at the String field if we don't think the
542706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     * peer has misformatted the response.
543706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     */
544706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    data = (const char *)data + 1;
545706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    len--;
546706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  } else
547706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    log_Printf(LogWARN, "Warning: The MS-CHAP-Error "
548706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                               "attribute is mis-formatted.  Compensating\n");
549706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  if ((r->errstr = rad_cvt_string((const char *)data,
550706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                                                  len)) == NULL) {
551706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    log_Printf(LogERROR, "rad_cvt_string: %s\n",
552706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                               rad_strerror(r->cx.rad));
553706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    auth_Failure(r->cx.auth);
554706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    rad_close(r->cx.rad);
555706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    return;
556706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  }
557706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		  log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
558706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh			     " MS-CHAP-Error \"%s\"\n", r->errstr);
559706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                }
560706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                break;
561706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
562706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              case RAD_MICROSOFT_MS_CHAP2_SUCCESS:
563706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                free(r->msrepstr);
564706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                if (len == 0)
565706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  r->msrepstr = NULL;
566706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                else {
567706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  if (len < 3 || ((const char *)data)[1] != '=') {
568706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    /*
569706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     * Only point at the String field if we don't think the
570706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     * peer has misformatted the response.
571706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     */
572706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    data = (const char *)data + 1;
573706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    len--;
574706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  } else
575706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    log_Printf(LogWARN, "Warning: The MS-CHAP2-Success "
576706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                               "attribute is mis-formatted.  Compensating\n");
577706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  if ((r->msrepstr = rad_cvt_string((const char *)data,
578706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                                                    len)) == NULL) {
579706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    log_Printf(LogERROR, "rad_cvt_string: %s\n",
580706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                               rad_strerror(r->cx.rad));
581706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    auth_Failure(r->cx.auth);
582706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    rad_close(r->cx.rad);
583706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    return;
584706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  }
585706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		  log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
586706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh			     " MS-CHAP2-Success \"%s\"\n", r->msrepstr);
587706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                }
588706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                break;
589706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
590706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              case RAD_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY:
591706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                r->mppe.policy = rad_cvt_int(data);
592706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
593706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh			   " MS-MPPE-Encryption-Policy %s\n",
594706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                           radius_policyname(r->mppe.policy));
595706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                break;
596706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
597706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              case RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES:
598706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                r->mppe.types = rad_cvt_int(data);
599706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
600706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh			   " MS-MPPE-Encryption-Types %s\n",
601706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                           radius_typesname(r->mppe.types));
602706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                break;
603706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
604706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              case RAD_MICROSOFT_MS_MPPE_RECV_KEY:
605706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                free(r->mppe.recvkey);
606706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		demangle(r, data, len, &r->mppe.recvkey, &r->mppe.recvkeylen);
607706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
608706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh			   " MS-MPPE-Recv-Key ********\n");
609706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                break;
610706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
611706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              case RAD_MICROSOFT_MS_MPPE_SEND_KEY:
612706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		demangle(r, data, len, &r->mppe.sendkey, &r->mppe.sendkeylen);
613706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
614706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh			   " MS-MPPE-Send-Key ********\n");
615706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                break;
616706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
617706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
618706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              default:
619706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                log_Printf(LogDEBUG, "Dropping MICROSOFT vendor specific "
620706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                           "RADIUS attribute %d\n", res);
621706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                break;
622706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            }
623706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            break;
624706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
625706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          default:
626706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            log_Printf(LogDEBUG, "Dropping vendor %lu RADIUS attribute %d\n",
627706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                       (unsigned long)vendor, res);
628706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            break;
629706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
630706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
631706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
632706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      default:
633706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogDEBUG, "Dropping RADIUS attribute %d\n", res);
634706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
635706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
636706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
637706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
638706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (res == -1) {
639706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_get_attr: %s (failing!)\n",
640706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               rad_strerror(r->cx.rad));
641706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    auth_Failure(r->cx.auth);
642706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else if (got == RAD_ACCESS_REJECT)
643706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    auth_Failure(r->cx.auth);
644706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else {
645706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    r->valid = 1;
646706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    auth_Success(r->cx.auth);
647706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
648706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  rad_close(r->cx.rad);
649706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
650706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
651706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
652706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * We've either timed out or select()ed on the read descriptor
653706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
654706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
655706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Continue(struct radius *r, int sel)
656706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
657706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct timeval tv;
658706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int got;
659706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
660706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  timer_Stop(&r->cx.timer);
661706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((got = rad_continue_send_request(r->cx.rad, sel, &r->cx.fd, &tv)) == 0) {
662706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
663706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	       "Radius: Request re-sent\n");
664706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    r->cx.timer.load = tv.tv_usec / TICKUNIT + tv.tv_sec * SECTICKS;
665706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    timer_Start(&r->cx.timer);
666706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
667706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
668706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
669706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  radius_Process(r, got);
670706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
671706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
672706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
673706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Time to call rad_continue_send_request() - timed out.
674706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
675706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
676706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Timeout(void *v)
677706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
678706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  radius_Continue((struct radius *)v, 0);
679706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
680706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
681706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
682706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Time to call rad_continue_send_request() - something to read.
683706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
684706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
685706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Read(struct fdescriptor *d, struct bundle *bundle __unused,
686706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	    const fd_set *fdset __unused)
687706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
688706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  radius_Continue(descriptor2radius(d), 1);
689706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
690706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
691706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
692706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Flush any pending transactions
693706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
694706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
695706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Flush(struct radius *r)
696706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
697706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct timeval tv;
698706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fd_set s;
699706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
700706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  while (r->cx.fd != -1) {
701706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    FD_ZERO(&s);
702706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    FD_SET(r->cx.fd, &s);
703706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    tv.tv_sec = 0;
704706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    tv.tv_usec = TICKUNIT;
705706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    select(r->cx.fd + 1, &s, NULL, NULL, &tv);
706706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    radius_Continue(r, 1);
707706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
708706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
709706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
710706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
711706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Behave as a struct fdescriptor (descriptor.h)
712706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
713706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
714706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w __unused,
715706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		 fd_set *e __unused, int *n)
716706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
717706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct radius *rad = descriptor2radius(d);
718706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
719706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (r && rad->cx.fd != -1) {
720706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    FD_SET(rad->cx.fd, r);
721706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (*n < rad->cx.fd + 1)
722706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      *n = rad->cx.fd + 1;
723706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogTIMER, "Radius: fdset(r) %d\n", rad->cx.fd);
724706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 1;
725706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
726706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
727706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 0;
728706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
729706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
730706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
731706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Behave as a struct fdescriptor (descriptor.h)
732706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
733706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
734706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_IsSet(struct fdescriptor *d, const fd_set *fdset)
735706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
736706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct radius *r = descriptor2radius(d);
737706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
738706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return r && r->cx.fd != -1 && FD_ISSET(r->cx.fd, fdset);
739706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
740706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
741706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
742706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Behave as a struct fdescriptor (descriptor.h)
743706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
744706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
745706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Write(struct fdescriptor *d __unused, struct bundle *bundle __unused,
746706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	     const fd_set *fdset __unused)
747706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
748706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* We never want to write here ! */
749706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogALERT, "radius_Write: Internal error: Bad call !\n");
750706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 0;
751706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
752706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
753706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
754706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Initialise ourselves
755706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
756706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
757706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Init(struct radius *r)
758706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
759706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->desc.type = RADIUS_DESCRIPTOR;
760706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->desc.UpdateSet = radius_UpdateSet;
761706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->desc.IsSet = radius_IsSet;
762706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->desc.Read = radius_Read;
763706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->desc.Write = radius_Write;
764706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->cx.fd = -1;
765706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->cx.rad = NULL;
766706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  memset(&r->cx.timer, '\0', sizeof r->cx.timer);
767706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->cx.auth = NULL;
768706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->valid = 0;
769706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->vj = 0;
770706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->ip.s_addr = INADDR_ANY;
771706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mask.s_addr = INADDR_NONE;
772706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->routes = NULL;
773706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mtu = DEF_MTU;
774706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->msrepstr = NULL;
775706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->repstr = NULL;
776706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOINET6
777706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->ipv6prefix = NULL;
778706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->ipv6routes = NULL;
779706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
780706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->errstr = NULL;
781706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mppe.policy = 0;
782706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mppe.types = 0;
783706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mppe.recvkey = NULL;
784706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mppe.recvkeylen = 0;
785706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mppe.sendkey = NULL;
786706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mppe.sendkeylen = 0;
787706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  *r->cfg.file = '\0';;
788706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogDEBUG, "Radius: radius_Init\n");
789706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
790706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
791706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
792706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Forget everything and go back to initialised state.
793706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
794706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
795706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Destroy(struct radius *r)
796706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
797706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->valid = 0;
798706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogDEBUG, "Radius: radius_Destroy\n");
799706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  timer_Stop(&r->cx.timer);
800706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  route_DeleteAll(&r->routes);
801706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOINET6
802706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  route_DeleteAll(&r->ipv6routes);
803706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
804706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  free(r->filterid);
805706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->filterid = NULL;
806706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  free(r->msrepstr);
807706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->msrepstr = NULL;
808706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  free(r->repstr);
809706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->repstr = NULL;
810706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOINET6
811706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  free(r->ipv6prefix);
812706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->ipv6prefix = NULL;
813706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
814706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  free(r->errstr);
815706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->errstr = NULL;
816706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  free(r->mppe.recvkey);
817706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mppe.recvkey = NULL;
818706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mppe.recvkeylen = 0;
819706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  free(r->mppe.sendkey);
820706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mppe.sendkey = NULL;
821706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->mppe.sendkeylen = 0;
822706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (r->cx.fd != -1) {
823706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    r->cx.fd = -1;
824706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    rad_close(r->cx.rad);
825706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
826706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
827706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
828706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
829706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_put_physical_details(struct radius *rad, struct physical *p)
830706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
831706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int slot, type;
832706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
833706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  type = RAD_VIRTUAL;
834706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (p->handler)
835706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    switch (p->handler->type) {
836706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case I4B_DEVICE:
837706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        type = RAD_ISDN_SYNC;
838706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
839706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
840706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case TTY_DEVICE:
841706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        type = RAD_ASYNC;
842706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
843706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
844706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case ETHER_DEVICE:
845706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        type = RAD_ETHERNET;
846706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
847706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
848706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case TCP_DEVICE:
849706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case UDP_DEVICE:
850706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case EXEC_DEVICE:
851706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case ATM_DEVICE:
852706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case NG_DEVICE:
853706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        type = RAD_VIRTUAL;
854706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
855706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
856706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
857706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (rad_put_int(rad->cx.rad, RAD_NAS_PORT_TYPE, type) != 0) {
858706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_put: rad_put_int: %s\n", rad_strerror(rad->cx.rad));
859706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    rad_close(rad->cx.rad);
860706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 0;
861706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
862706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
863706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  switch (rad->port_id_type) {
864706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case RPI_PID:
865706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      slot = (int)getpid();
866706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
867706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case RPI_IFNUM:
868706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      slot = p->dl->bundle->iface->index;
869706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
870706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case RPI_TUNNUM:
871706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      slot = p->dl->bundle->unit;
872706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
873706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case RPI_DEFAULT:
874706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    default:
875706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      slot = physical_Slot(p);
876706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
877706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
878706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
879706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (slot >= 0)
880706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (rad_put_int(rad->cx.rad, RAD_NAS_PORT, slot) != 0) {
881706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "rad_put: rad_put_int: %s\n", rad_strerror(rad->cx.rad));
882706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(rad->cx.rad);
883706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return 0;
884706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
885706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
886706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 1;
887706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
888706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
889706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
890706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Start an authentication request to the RADIUS server.
891706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
892706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint
893706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Authenticate(struct radius *r, struct authinfo *authp, const char *name,
894706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    const char *key, int klen, const char *nchallenge,
895706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    int nclen)
896706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
897706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char hostname[MAXHOSTNAMELEN];
898706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct timeval tv;
899706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  const char *what = "questionable";	/* silence warnings! */
900706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char *mac_addr;
901706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int got;
902706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct hostent *hp;
903706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct in_addr hostaddr;
904706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
905706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mschap_response msresp;
906706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mschap2_response msresp2;
907706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  const struct MSCHAPv2_resp *keyv2;
908706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
909706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
910706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (!*r->cfg.file)
911706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 0;
912706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
913706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (r->cx.fd != -1)
914706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /*
915706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     * We assume that our name/key/challenge is the same as last time,
916706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     * and just continue to wait for the RADIUS server(s).
917706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     */
918706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 1;
919706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
920706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  radius_Destroy(r);
921706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
922706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((r->cx.rad = rad_auth_open()) == NULL) {
923706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno));
924706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 0;
925706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
926706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
927706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (rad_config(r->cx.rad, r->cfg.file) != 0) {
928706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_config: %s\n", rad_strerror(r->cx.rad));
929706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    rad_close(r->cx.rad);
930706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 0;
931706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
932706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
933706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (rad_create_request(r->cx.rad, RAD_ACCESS_REQUEST) != 0) {
934706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_create_request: %s\n", rad_strerror(r->cx.rad));
935706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    rad_close(r->cx.rad);
936706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 0;
937706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
938706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
939706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (rad_put_string(r->cx.rad, RAD_USER_NAME, name) != 0 ||
940706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_int(r->cx.rad, RAD_SERVICE_TYPE, RAD_FRAMED) != 0 ||
941706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_int(r->cx.rad, RAD_FRAMED_PROTOCOL, RAD_PPP) != 0) {
942706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad));
943706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    rad_close(r->cx.rad);
944706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 0;
945706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
946706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
947706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  switch (authp->physical->link.lcp.want_auth) {
948706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  case PROTO_PAP:
949706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* We're talking PAP */
950706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (rad_put_attr(r->cx.rad, RAD_USER_PASSWORD, key, klen) != 0) {
951706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "PAP: rad_put_string: %s\n",
952706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 rad_strerror(r->cx.rad));
953706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(r->cx.rad);
954706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return 0;
955706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
956706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    what = "PAP";
957706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    break;
958706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
959706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  case PROTO_CHAP:
960706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    switch (authp->physical->link.lcp.want_authtype) {
961706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case 0x5:
962706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (rad_put_attr(r->cx.rad, RAD_CHAP_PASSWORD, key, klen) != 0 ||
963706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          rad_put_attr(r->cx.rad, RAD_CHAP_CHALLENGE, nchallenge, nclen) != 0) {
964706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogERROR, "CHAP: rad_put_string: %s\n",
965706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                   rad_strerror(r->cx.rad));
966706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_close(r->cx.rad);
967706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        return 0;
968706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
969706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      what = "CHAP";
970706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
971706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
972706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
973706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case 0x80:
974706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (klen != 50) {
975706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogERROR, "CHAP80: Unrecognised key length %d\n", klen);
976706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_close(r->cx.rad);
977706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        return 0;
978706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
979706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
980706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT,
981706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                          RAD_MICROSOFT_MS_CHAP_CHALLENGE, nchallenge, nclen);
982706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      msresp.ident = *key;
983706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      msresp.flags = 0x01;
984706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memcpy(msresp.lm_response, key + 1, 24);
985706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memcpy(msresp.nt_response, key + 25, 24);
986706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT,
987706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                          RAD_MICROSOFT_MS_CHAP_RESPONSE, &msresp,
988706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                          sizeof msresp);
989706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      what = "MSCHAP";
990706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
991706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
992706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case 0x81:
993706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (klen != sizeof(*keyv2) + 1) {
994706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogERROR, "CHAP81: Unrecognised key length %d\n", klen);
995706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_close(r->cx.rad);
996706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        return 0;
997706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
998706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
999706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      keyv2 = (const struct MSCHAPv2_resp *)(key + 1);
1000706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT,
1001706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                          RAD_MICROSOFT_MS_CHAP_CHALLENGE, nchallenge, nclen);
1002706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      msresp2.ident = *key;
1003706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      msresp2.flags = keyv2->Flags;
1004706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memcpy(msresp2.response, keyv2->NTResponse, sizeof msresp2.response);
1005706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memset(msresp2.reserved, '\0', sizeof msresp2.reserved);
1006706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memcpy(msresp2.pchallenge, keyv2->PeerChallenge,
1007706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             sizeof msresp2.pchallenge);
1008706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT,
1009706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                          RAD_MICROSOFT_MS_CHAP2_RESPONSE, &msresp2,
1010706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                          sizeof msresp2);
1011706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      what = "MSCHAPv2";
1012706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1013706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
1014706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    default:
1015706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "CHAP: Unrecognised type 0x%02x\n",
1016706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 authp->physical->link.lcp.want_authtype);
1017706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(r->cx.rad);
1018706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return 0;
1019706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1020706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1021706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1022706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (gethostname(hostname, sizeof hostname) != 0)
1023706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_put: gethostname(): %s\n", strerror(errno));
1024706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else {
1025706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (Enabled(authp->physical->dl->bundle, OPT_NAS_IP_ADDRESS) &&
1026706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        (hp = gethostbyname(hostname)) != NULL) {
1027706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      hostaddr.s_addr = *(u_long *)hp->h_addr;
1028706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (rad_put_addr(r->cx.rad, RAD_NAS_IP_ADDRESS, hostaddr) != 0) {
1029706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogERROR, "rad_put: rad_put_string: %s\n",
1030706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                   rad_strerror(r->cx.rad));
1031706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_close(r->cx.rad);
1032706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        return 0;
1033706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1034706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1035706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (Enabled(authp->physical->dl->bundle, OPT_NAS_IDENTIFIER) &&
1036706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_put_string(r->cx.rad, RAD_NAS_IDENTIFIER, hostname) != 0) {
1037706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "rad_put: rad_put_string: %s\n",
1038706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 rad_strerror(r->cx.rad));
1039706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(r->cx.rad);
1040706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return 0;
1041706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1042706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1043706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1044706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((mac_addr = getenv("HISMACADDR")) != NULL &&
1045706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_string(r->cx.rad, RAD_CALLING_STATION_ID, mac_addr) != 0) {
1046706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad));
1047706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    rad_close(r->cx.rad);
1048706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 0;
1049706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1050706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1051706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  radius_put_physical_details(r, authp->physical);
1052706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1053706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogRADIUS, "Radius(auth): %s data sent for %s\n", what, name);
1054706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1055706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->cx.auth = authp;
1056706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((got = rad_init_send_request(r->cx.rad, &r->cx.fd, &tv)))
1057706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    radius_Process(r, got);
1058706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else {
1059706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE,
1060706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	       "Radius: Request sent\n");
1061706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogDEBUG, "Using radius_Timeout [%p]\n", radius_Timeout);
1062706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    r->cx.timer.load = tv.tv_usec / TICKUNIT + tv.tv_sec * SECTICKS;
1063706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    r->cx.timer.func = radius_Timeout;
1064706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    r->cx.timer.name = "radius auth";
1065706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    r->cx.timer.arg = r;
1066706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    timer_Start(&r->cx.timer);
1067706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1068706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1069706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 1;
1070706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
1071706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1072706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* Fetch IP, netmask from IPCP */
1073706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
1074706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Account_Set_Ip(struct radacct *ac, struct in_addr *peer_ip,
1075706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		      struct in_addr *netmask)
1076706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
1077706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  ac->proto = PROTO_IPCP;
1078706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  memcpy(&ac->peer.ip.addr, peer_ip, sizeof(ac->peer.ip.addr));
1079706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  memcpy(&ac->peer.ip.mask, netmask, sizeof(ac->peer.ip.mask));
1080706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
1081706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1082706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOINET6
1083706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* Fetch interface-id from IPV6CP */
1084706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
1085706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Account_Set_Ipv6(struct radacct *ac, u_char *ifid)
1086706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
1087706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  ac->proto = PROTO_IPV6CP;
1088706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  memcpy(&ac->peer.ipv6.ifid, ifid, sizeof(ac->peer.ipv6.ifid));
1089706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
1090706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
1091706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1092706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
1093706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Send an accounting request to the RADIUS server
1094706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
1095706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
1096706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Account(struct radius *r, struct radacct *ac, struct datalink *dl,
1097706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               int acct_type, struct pppThroughput *stats)
1098706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
1099706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct timeval tv;
1100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int got;
1101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char hostname[MAXHOSTNAMELEN];
1102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char *mac_addr;
1103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct hostent *hp;
1104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct in_addr hostaddr;
1105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (!*r->cfg.file)
1107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
1108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (r->cx.fd != -1)
1110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /*
1111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     * We assume that our name/key/challenge is the same as last time,
1112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     * and just continue to wait for the RADIUS server(s).
1113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     */
1114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
1115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  timer_Stop(&r->cx.timer);
1117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((r->cx.rad = rad_acct_open()) == NULL) {
1119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno));
1120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
1121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (rad_config(r->cx.rad, r->cfg.file) != 0) {
1124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_config: %s\n", rad_strerror(r->cx.rad));
1125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    rad_close(r->cx.rad);
1126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
1127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (rad_create_request(r->cx.rad, RAD_ACCOUNTING_REQUEST) != 0) {
1130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_create_request: %s\n", rad_strerror(r->cx.rad));
1131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    rad_close(r->cx.rad);
1132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
1133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Grab some accounting data and initialize structure */
1136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (acct_type == RAD_START) {
1137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ac->rad_parent = r;
1138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Fetch username from datalink */
1139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    strncpy(ac->user_name, dl->peer.authname, sizeof ac->user_name);
1140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ac->user_name[AUTHLEN-1] = '\0';
1141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ac->authentic = 2;		/* Assume RADIUS verified auth data */
1143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Generate a session ID */
1145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    snprintf(ac->session_id, sizeof ac->session_id, "%s%ld-%s%lu",
1146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             dl->bundle->cfg.auth.name, (long)getpid(),
1147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             dl->peer.authname, (unsigned long)stats->uptime);
1148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* And grab our MP socket name */
1150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    snprintf(ac->multi_session_id, sizeof ac->multi_session_id, "%s",
1151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             dl->bundle->ncp.mp.active ?
1152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             dl->bundle->ncp.mp.server.socket.sun_path : "");
1153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  };
1154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (rad_put_string(r->cx.rad, RAD_USER_NAME, ac->user_name) != 0 ||
1156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_int(r->cx.rad, RAD_SERVICE_TYPE, RAD_FRAMED) != 0 ||
1157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_int(r->cx.rad, RAD_FRAMED_PROTOCOL, RAD_PPP) != 0) {
1158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad));
1159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    rad_close(r->cx.rad);
1160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
1161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  switch (ac->proto) {
1163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  case PROTO_IPCP:
1164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (rad_put_addr(r->cx.rad, RAD_FRAMED_IP_ADDRESS,
1165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		     ac->peer.ip.addr) != 0 ||
1166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	rad_put_addr(r->cx.rad, RAD_FRAMED_IP_NETMASK,
1167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		     ac->peer.ip.mask) != 0) {
1168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad));
1169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(r->cx.rad);
1170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return;
1171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    break;
1173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOINET6
1174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  case PROTO_IPV6CP:
1175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (rad_put_attr(r->cx.rad, RAD_FRAMED_INTERFACE_ID, ac->peer.ipv6.ifid,
1176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		     sizeof(ac->peer.ipv6.ifid)) != 0) {
1177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "rad_put_attr: %s\n", rad_strerror(r->cx.rad));
1178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(r->cx.rad);
1179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return;
1180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (r->ipv6prefix) {
1182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      /*
1183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       * Since PPP doesn't delegate an IPv6 prefix to a peer,
1184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       * Framed-IPv6-Prefix may be not used, actually.
1185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh       */
1186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (rad_put_attr(r->cx.rad, RAD_FRAMED_IPV6_PREFIX, r->ipv6prefix,
1187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		       sizeof(struct in6_addr) + 2) != 0) {
1188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(LogERROR, "rad_put_attr: %s\n", rad_strerror(r->cx.rad));
1189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	rad_close(r->cx.rad);
1190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	return;
1191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    break;
1194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
1195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  default:
1196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* We don't log any protocol specific information */
1197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    break;
1198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((mac_addr = getenv("HISMACADDR")) != NULL &&
1201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_string(r->cx.rad, RAD_CALLING_STATION_ID, mac_addr) != 0) {
1202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad));
1203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    rad_close(r->cx.rad);
1204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
1205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (gethostname(hostname, sizeof hostname) != 0)
1208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_put: gethostname(): %s\n", strerror(errno));
1209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else {
1210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (Enabled(dl->bundle, OPT_NAS_IP_ADDRESS) &&
1211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        (hp = gethostbyname(hostname)) != NULL) {
1212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      hostaddr.s_addr = *(u_long *)hp->h_addr;
1213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (rad_put_addr(r->cx.rad, RAD_NAS_IP_ADDRESS, hostaddr) != 0) {
1214706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogERROR, "rad_put: rad_put_string: %s\n",
1215706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                   rad_strerror(r->cx.rad));
1216706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_close(r->cx.rad);
1217706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        return;
1218706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1219706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1220706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (Enabled(dl->bundle, OPT_NAS_IDENTIFIER) &&
1221706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_put_string(r->cx.rad, RAD_NAS_IDENTIFIER, hostname) != 0) {
1222706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "rad_put: rad_put_string: %s\n",
1223706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 rad_strerror(r->cx.rad));
1224706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(r->cx.rad);
1225706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return;
1226706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1227706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1228706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1229706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  radius_put_physical_details(r, dl->physical);
1230706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1231706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (rad_put_int(r->cx.rad, RAD_ACCT_STATUS_TYPE, acct_type) != 0 ||
1232706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_string(r->cx.rad, RAD_ACCT_SESSION_ID, ac->session_id) != 0 ||
1233706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_string(r->cx.rad, RAD_ACCT_MULTI_SESSION_ID,
1234706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     ac->multi_session_id) != 0 ||
1235706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_put_int(r->cx.rad, RAD_ACCT_DELAY_TIME, 0) != 0) {
1236706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* XXX ACCT_DELAY_TIME should be increased each time a packet is waiting */
1237706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad));
1238706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    rad_close(r->cx.rad);
1239706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
1240706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1241706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1242706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (acct_type == RAD_STOP || acct_type == RAD_ALIVE)
1243706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Show some statistics */
1244706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (rad_put_int(r->cx.rad, RAD_ACCT_INPUT_OCTETS, stats->OctetsIn % UINT32_MAX) != 0 ||
1245706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_put_int(r->cx.rad, RAD_ACCT_INPUT_GIGAWORDS, stats->OctetsIn / UINT32_MAX) != 0 ||
1246706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_put_int(r->cx.rad, RAD_ACCT_INPUT_PACKETS, stats->PacketsIn) != 0 ||
1247706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_put_int(r->cx.rad, RAD_ACCT_OUTPUT_OCTETS, stats->OctetsOut % UINT32_MAX) != 0 ||
1248706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_put_int(r->cx.rad, RAD_ACCT_OUTPUT_GIGAWORDS, stats->OctetsOut / UINT32_MAX) != 0 ||
1249706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_put_int(r->cx.rad, RAD_ACCT_OUTPUT_PACKETS, stats->PacketsOut)
1250706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        != 0 ||
1251706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        rad_put_int(r->cx.rad, RAD_ACCT_SESSION_TIME, throughput_uptime(stats))
1252706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        != 0) {
1253706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad));
1254706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      rad_close(r->cx.rad);
1255706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return;
1256706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1257706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1258706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (log_IsKept(LogPHASE) || log_IsKept(LogRADIUS)) {
1259706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    const char *what;
1260706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    int level;
1261706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1262706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    switch (acct_type) {
1263706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case RAD_START:
1264706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      what = "START";
1265706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      level = log_IsKept(LogPHASE) ? LogPHASE : LogRADIUS;
1266706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1267706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case RAD_STOP:
1268706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      what = "STOP";
1269706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      level = log_IsKept(LogPHASE) ? LogPHASE : LogRADIUS;
1270706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1271706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case RAD_ALIVE:
1272706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      what = "ALIVE";
1273706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      level = LogRADIUS;
1274706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1275706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    default:
1276706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      what = "<unknown>";
1277706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      level = log_IsKept(LogPHASE) ? LogPHASE : LogRADIUS;
1278706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1279706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1280706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(level, "Radius(acct): %s data sent\n", what);
1281706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1282706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1283706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  r->cx.auth = NULL;			/* Not valid for accounting requests */
1284706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((got = rad_init_send_request(r->cx.rad, &r->cx.fd, &tv)))
1285706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    radius_Process(r, got);
1286706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else {
1287706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogDEBUG, "Using radius_Timeout [%p]\n", radius_Timeout);
1288706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    r->cx.timer.load = tv.tv_usec / TICKUNIT + tv.tv_sec * SECTICKS;
1289706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    r->cx.timer.func = radius_Timeout;
1290706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    r->cx.timer.name = "radius acct";
1291706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    r->cx.timer.arg = r;
1292706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    timer_Start(&r->cx.timer);
1293706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1294706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
1295706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1296706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*
1297706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * How do things look at the moment ?
1298706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
1299706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
1300706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_Show(struct radius *r, struct prompt *p)
1301706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
1302706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(p, " Radius config:     %s",
1303706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                *r->cfg.file ? r->cfg.file : "none");
1304706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (r->valid) {
1305706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, "\n                IP: %s\n", inet_ntoa(r->ip));
1306706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, "           Netmask: %s\n", inet_ntoa(r->mask));
1307706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, "               MTU: %lu\n", r->mtu);
1308706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, "                VJ: %sabled\n", r->vj ? "en" : "dis");
1309706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, "           Message: %s\n", r->repstr ? r->repstr : "");
1310706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, "   MPPE Enc Policy: %s\n",
1311706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  radius_policyname(r->mppe.policy));
1312706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, "    MPPE Enc Types: %s\n",
1313706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  radius_typesname(r->mppe.types));
1314706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, "     MPPE Recv Key: %seceived\n",
1315706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  r->mppe.recvkey ? "R" : "Not r");
1316706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, "     MPPE Send Key: %seceived\n",
1317706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  r->mppe.sendkey ? "R" : "Not r");
1318706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, " MS-CHAP2-Response: %s\n",
1319706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  r->msrepstr ? r->msrepstr : "");
1320706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, "     Error Message: %s\n", r->errstr ? r->errstr : "");
1321706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (r->routes)
1322706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      route_ShowSticky(p, r->routes, "            Routes", 16);
1323706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOINET6
1324706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (r->ipv6routes)
1325706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      route_ShowSticky(p, r->ipv6routes, "            IPv6 Routes", 16);
1326706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
1327706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else
1328706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(p, " (not authenticated)\n");
1329706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
1330706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1331706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
1332706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_alive(void *v)
1333706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
1334706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct bundle *bundle = (struct bundle *)v;
1335706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1336706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  timer_Stop(&bundle->radius.alive.timer);
1337706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  bundle->radius.alive.timer.load = bundle->radius.alive.interval * SECTICKS;
1338706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (bundle->radius.alive.timer.load) {
1339706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    radius_Account(&bundle->radius, &bundle->radacct,
1340706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                   bundle->links, RAD_ALIVE, &bundle->ncp.ipcp.throughput);
1341706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    timer_Start(&bundle->radius.alive.timer);
1342706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1343706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
1344706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1345706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
1346706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_StartTimer(struct bundle *bundle)
1347706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
1348706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (bundle->radius.cfg.file && bundle->radius.alive.interval) {
1349706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bundle->radius.alive.timer.func = radius_alive;
1350706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bundle->radius.alive.timer.name = "radius alive";
1351706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bundle->radius.alive.timer.load = bundle->radius.alive.interval * SECTICKS;
1352706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bundle->radius.alive.timer.arg = bundle;
1353706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    radius_alive(bundle);
1354706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1355706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
1356706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1357706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
1358706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehradius_StopTimer(struct radius *r)
1359706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
1360706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  timer_Stop(&r->alive.timer);
1361706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
1362