// L2TPNS Radius Stuff
-char const *cvs_id_radius = "$Id: radius.c,v 1.21 2005/01/05 13:45:49 bodea Exp $";
+char const *cvs_id_radius = "$Id: radius.c,v 1.28 2005/05/03 05:11:34 bodea Exp $";
#include <time.h>
#include <stdio.h>
if (s)
{
if (state == RADIUSAUTH)
- sessionshutdown(s, "RADIUS timeout");
+ sessionshutdown(s, "RADIUS timeout.", 3, 0);
else
{
LOG(1, s, session[s].tunnel, "RADIUS timeout, but in state %s so don't timeout session\n",
{
*p = 44; // session ID
p[1] = 18;
- sprintf(p + 2, "%08X%08X", session[s].id, session[s].opened);
+ sprintf(p + 2, "%08X%08X", session[s].unique_id, session[s].opened);
p += p[1];
if (state == RADIUSSTOP)
{ // stop
*(uint32_t *) (p + 2) = htonl(time(NULL) - session[s].opened);
p += p[1];
}
+
+ if (session[s].snoop_ip && session[s].snoop_port)
+ {
+ *p = 26; // vendor-specific
+ *(uint32_t *) (p + 2) = htonl(9); // Cisco
+ p[6] = 1; // Cisco-Avpair
+ p[7] = 2 + sprintf(p + 8, "intercept=%s:%d",
+ fmtaddr(session[s].snoop_ip, 0), session[s].snoop_port);
+
+ p[1] = p[7] + 6;
+ p += p[1];
+ }
}
}
if (s)
{
// get radius port
uint16_t port = config->radiusport[(radius[r].try - 1) % config->numradiusservers];
- // no need to define the accounting port for itself:
- // the accounting port is as far as I know always one more
- // than the auth port JK 20040713
+ // assume RADIUS accounting port is the authentication port +1
addr.sin_port = htons((state == RADIUSAUTH) ? port : port+1);
}
session[s].ip_pool_index = -1;
LOG(3, s, session[s].tunnel, " Radius reply contains IP address %s\n",
fmtaddr(htonl(session[s].ip), 0));
+
+ if (session[s].ip == 0xFFFFFFFE)
+ session[s].ip = 0; // assign from pool
}
else if (*p == 135)
{
// Vendor-Specific Attribute
int vendor = ntohl(*(int *)(p + 2));
char attrib = *(p + 6);
- char attrib_length = *(p + 7) - 2;
+ int attrib_length = *(p + 7) - 2;
char *avpair, *value, *key, *newp;
LOG(3, s, session[s].tunnel, " Radius reply contains Vendor-Specific. Vendor=%d Attrib=%d Length=%d\n", vendor, attrib, attrib_length);
} while (newp);
free(avpair);
}
+ else if (*p == 99)
+ {
+ // Framed-IPv6-Route
+ struct in6_addr r6;
+ int prefixlen;
+ uint8_t *n = p + 2;
+ uint8_t *e = p + p[1];
+ uint8_t *m = strchr(n, '/');
+
+ *m++ = 0;
+ inet_pton(AF_INET6, n, &r6);
+
+ prefixlen = 0;
+ while (m < e && isdigit(*m)) {
+ prefixlen = prefixlen * 10 + *m++ - '0';
+ }
+
+ if (prefixlen)
+ {
+ LOG(3, s, session[s].tunnel,
+ " Radius reply contains route for %s/%d\n",
+ n, prefixlen);
+ session[s].ipv6route = r6;
+ session[s].ipv6prefixlen = prefixlen;
+ }
+ }
}
}
else if (r_code == AccessReject)
{
- LOG(2, s, session[s].tunnel, " Authentication denied for %s\n", session[s].user);
-//FIXME: We should tear down the session here!
+ LOG(2, s, session[s].tunnel, " Authentication rejected for %s\n", session[s].user);
+ sessionkill(s, "Authentication rejected");
break;
}