// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
// vim: sw=8 ts=8
-char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.95 2005/05/06 23:31:50 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.96 2005/05/07 08:17:25 bodea Exp $";
#include <arpa/inet.h>
#include <assert.h>
// RADIUS Stop message
uint16_t r = sess_local[s].radius;
if (!r)
+ r = radiusnew(s);
+
+ if (r)
{
- if (!(r = radiusnew(s)))
- {
- LOG(1, s, session[s].tunnel, "No free RADIUS sessions for Stop message\n");
- STAT(radius_overflow);
- }
- else
- {
- random_data(radius[r].auth, sizeof(radius[r].auth));
- }
+ // stop, if not already trying
+ if (radius[r].state != RADIUSSTOP)
+ radiussend(r, RADIUSSTOP);
}
-
- if (r && radius[r].state != RADIUSSTOP)
- radiussend(r, RADIUSSTOP); // stop, if not already trying
+ else
+ LOG(1, s, session[s].tunnel, "No free RADIUS sessions for Stop message\n");
// Save counters to dump to accounting file
if (*config->accounting_dir && shut_acct_n < sizeof(shut_acct) / sizeof(*shut_acct))
if (!r)
r = radiusnew(s);
+ if (!r)
+ {
+ sessionshutdown(s, "No free RADIUS sessions for IPCP");
+ return;
+ }
+
if (radius[r].state != RADIUSIPCP)
{
radius[r].state = RADIUSIPCP;
}
}
+static void sessionclear(sessionidt s)
+{
+ memset(&session[s], 0, sizeof(session[s]));
+ memset(&sess_local[s], 0, sizeof(sess_local[s]));
+ memset(&cli_session_actions[s], 0, sizeof(cli_session_actions[s]));
+
+ session[s].tunnel = T_FREE; // Mark it as free.
+ session[s].next = sessionfree;
+ sessionfree = s;
+}
+
// kill a session now
void sessionkill(sessionidt s, char *reason)
{
radiusclear(sess_local[s].radius, s); // cant send clean accounting data, session is killed
LOG(2, s, session[s].tunnel, "Kill session %d (%s): %s\n", s, session[s].user, reason);
-
- memset(&session[s], 0, sizeof(session[s]));
- session[s].tunnel = T_FREE; // Mark it as free.
- session[s].next = sessionfree;
- sessionfree = s;
- cli_session_actions[s].action = 0;
+ sessionclear(s);
cluster_send_session(s);
}
// LOG(4, s, t, "Firmware revision\n");
break;
case 7: // host name
- memset(tunnel[t].hostname, 0, 128);
- memcpy(tunnel[t].hostname, b, (n >= 127) ? 127 : n);
+ memset(tunnel[t].hostname, 0, sizeof(tunnel[t].hostname));
+ memcpy(tunnel[t].hostname, b, (n < sizeof(tunnel[t].hostname)) ? n : sizeof(tunnel[t].hostname) - 1);
LOG(4, s, t, " Tunnel hostname = \"%s\"\n", tunnel[t].hostname);
// TBA - to send to RADIUS
break;
case 8: // vendor name
memset(tunnel[t].vendor, 0, sizeof(tunnel[t].vendor));
- memcpy(tunnel[t].vendor, b, (n >= sizeof(tunnel[t].vendor) - 1) ? sizeof(tunnel[t].vendor) - 1 : n);
+ memcpy(tunnel[t].vendor, b, (n < sizeof(tunnel[t].vendor)) ? n : sizeof(tunnel[t].vendor) - 1);
LOG(4, s, t, " Vendor name = \"%s\"\n", tunnel[t].vendor);
break;
case 9: // assigned tunnel
// TBA
break;
case 21: // called number
- memset(called, 0, MAXTEL);
- memcpy(called, b, (n >= MAXTEL) ? (MAXTEL-1) : n);
+ memset(called, 0, sizeof(called));
+ memcpy(called, b, (n < sizeof(called)) ? n : sizeof(called) - 1);
LOG(4, s, t, " Called <%s>\n", called);
break;
case 22: // calling number
- memset(calling, 0, MAXTEL);
- memcpy(calling, b, (n >= MAXTEL) ? (MAXTEL-1) : n);
+ memset(calling, 0, sizeof(calling));
+ memcpy(calling, b, (n < sizeof(calling)) ? n : sizeof(calling) - 1);
LOG(4, s, t, " Calling <%s>\n", calling);
break;
case 23: // subtype
else
{
// AS5300s send connect speed as a string
- char tmp[30] = {0};
- memcpy(tmp, b, (n >= 30) ? 30 : n);
+ char tmp[30];
+ memset(tmp, 0, sizeof(tmp));
+ memcpy(tmp, b, (n < sizeof(tmp)) ? n : sizeof(tmp) - 1);
session[s].tx_connect_speed = atol(tmp);
}
LOG(4, s, t, " TX connect speed <%u>\n", session[s].tx_connect_speed);
else
{
// AS5300s send connect speed as a string
- char tmp[30] = {0};
- memcpy(tmp, b, (n >= 30) ? 30 : n);
+ char tmp[30];
+ memset(tmp, 0, sizeof(tmp));
+ memcpy(tmp, b, (n < sizeof(tmp)) ? n : sizeof(tmp) - 1);
session[s].rx_connect_speed = atol(tmp);
}
LOG(4, s, t, " RX connect speed <%u>\n", session[s].rx_connect_speed);
}
case 30: // Proxy Authentication Name
{
- char authname[64] = {0};
- memcpy(authname, b, (n > 63) ? 63 : n);
+ char authname[64];
+ memset(authname, 0, sizeof(authname));
+ memcpy(authname, b, (n < sizeof(authname)) ? n : sizeof(authname) - 1);
LOG(4, s, t, " Proxy Auth Name (%s)\n",
authname);
break;
break;
}
case 33: // Proxy Authentication Response
- {
- char authresp[64] = {0};
- memcpy(authresp, b, (n > 63) ? 63 : n);
- LOG(4, s, t, " Proxy Auth Response\n");
- break;
- }
- case 27: // last send lcp
+ LOG(4, s, t, " Proxy Auth Response\n");
+ break;
+ case 27: // last sent lcp
{ // find magic number
uint8_t *p = b, *e = p + n;
while (p + 1 < e && p[1] && p + p[1] <= e)
if (!(r = radiusnew(s)))
{
LOG(1, s, t, "No free RADIUS sessions for ICRQ\n");
- sessionkill(s, "no free RADIUS sesions");
+ sessionclear(s);
return;
}
control16(c, 14, s, 1); // assigned session
controladd(c, t, s); // send the reply
- // Generate a random challenge
- random_data(radius[r].auth, sizeof(radius[r].auth));
strncpy(radius[r].calling, calling, sizeof(radius[r].calling) - 1);
strncpy(session[s].called, called, sizeof(session[s].called) - 1);
strncpy(session[s].calling, calling, sizeof(session[s].calling) - 1);
continue;
}
- random_data(radius[r].auth, sizeof(radius[r].auth));
-
LOG(3, s, session[s].tunnel, "Sending RADIUS Interim for %s (%u)\n",
session[s].user, session[s].unique_id);
// L2TPNS PPP Stuff
-char const *cvs_id_ppp = "$Id: ppp.c,v 1.48 2005/05/05 10:02:08 bodea Exp $";
+char const *cvs_id_ppp = "$Id: ppp.c,v 1.49 2005/05/07 08:17:25 bodea Exp $";
#include <stdio.h>
#include <string.h>
{
int proto = ntohs(*(uint16_t *)(o + 2));
LOG(4, 0, 0, " %s 0x%x (%s)\n", lcp_type(type), proto,
- proto == PPPCHAP ? "CHAP" :
- proto == PPPPAP ? "PAP" : "UNKNOWN");
+ proto == PPPPAP ? "PAP" : "UNSUPPORTED");
+ }
+ else if (length == 5)
+ {
+ int proto = ntohs(*(uint16_t *)(o + 2));
+ int algo = *(uint8_t *)(o + 4);
+ LOG(4, 0, 0, " %s 0x%x 0x%x (%s)\n", lcp_types[type], proto, algo,
+ (proto == PPPCHAP && algo == 5) ? "CHAP MD5" : "UNSUPPORTED");
}
else
LOG(4, 0, 0, " %s odd length %d\n", lcp_type(type), length);
case 3: // Authentication-Protocol
{
int proto = ntohs(*(uint16_t *)(o + 2));
+ uint16_t wanted_proto;
char proto_name[] = "0x0000";
+
if (proto == PPPPAP)
- break;
+ {
+ if (config->radius_authtypes & AUTHPAP)
+ break;
- if (response && *response != ConfigNak) // rej already queued
- break;
+ strcpy(proto_name, "PAP");
+ }
+ else if (proto == PPPCHAP)
+ {
+ if (config->radius_authtypes & AUTHCHAP
+ && *(o + 4) == 5) // MD5
+ break;
- if (proto == PPPCHAP)
strcpy(proto_name, "CHAP");
+ }
else
sprintf(proto_name, "%#4.4x", proto);
+ if (response && *response != ConfigNak) // rej already queued
+ break;
+
LOG(2, s, t, " Remote requesting %s authentication. Rejecting.\n", proto_name);
if (!response)
q += 4;
}
- if ((q - b + length) > sizeof(b))
+ if ((q - b + 5) > sizeof(b)) // 5 is the larger (CHAP+MD5) of the two NAKs
{
LOG(2, s, t, "LCP overflow for %s ConfigNak.\n", proto_name);
break;
}
- memcpy(q, o, length);
- *(uint16_t *)(q += 2) = htons(PPPPAP); // NAK -> Use PAP instead
- q += length;
- *((uint16_t *) (response + 2)) = htons(q - response);
+ *q++ = type;
+ if (config->radius_authprefer == AUTHCHAP)
+ {
+ *q++ = 5;
+ *(uint16_t *) q = htons(PPPCHAP); q += 2;
+ *q++ = 5; // MD5
+ }
+ else
+ {
+ *q++ = 4;
+ *(uint16_t *) q = htons(PPPPAP); q += 2;
+ }
+
+ *((uint16_t *) (response + 2)) = htons(q - response); // LCP header length
+ break;
}
break;
{
LOG(1, s, t, "Remote end sent a ConfigNak. Ignoring\n");
if (config->debug > 3) dumplcp(p, l);
- return ;
+ return;
}
else if (*p == TerminateReq)
{
LOG(1, s, t, "Send CHAP challenge\n");
- // new challenge
- random_data(radius[r].auth, sizeof(radius[r].auth));
radius[r].chap = 1; // CHAP not PAP
radius[r].id++;
if (radius[r].state != RADIUSCHAP)
void initlcp(tunnelidt t, sessionidt s)
{
char b[500], *q;
+ int size;
if (!(q = makeppp(b, sizeof(b), NULL, 0, t, s, PPPLCP)))
return;
*(uint8_t *)(q + 5) = 6;
*(uint32_t *)(q + 6) = htonl(session[s].magic);
*(uint8_t *)(q + 10) = 3;
- *(uint8_t *)(q + 11) = 4;
- *(uint16_t *)(q + 12) = htons(PPPPAP); // PAP
+ if (config->radius_authprefer == AUTHCHAP)
+ {
+ *(uint8_t *)(q + 11) = 5;
+ *(uint16_t *)(q + 12) = htons(PPPCHAP);
+ *(uint8_t *)(q + 14) = 5; // MD5
+ size = 15;
+ }
+ else
+ {
+ *(uint8_t *)(q + 11) = 4;
+ *(uint16_t *)(q + 12) = htons(PPPPAP);
+ size = 14;
+ }
- LOG_HEX(5, "PPPLCP", q, 14);
- tunnelsend(b, (q - b) + 14, t);
+ LOG_HEX(5, "PPPLCP", q, size);
+ tunnelsend(b, (q - b) + size, t);
}
// Send CCP request for no compression