- Replace flags used for LCP/IPCP with state machine.
- Use openssl MD5, fix DAE vector (Alex Kiernan).
This commit is contained in:
parent
e2a3f0371e
commit
aabf1d3fe9
27 changed files with 1399 additions and 1120 deletions
389
l2tpns.c
389
l2tpns.c
|
|
@ -4,7 +4,7 @@
|
|||
// 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.114 2005-07-04 05:49:46 bodea Exp $";
|
||||
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.115 2005-07-31 10:04:10 bodea Exp $";
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
|
|
@ -38,9 +38,9 @@ char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.114 2005-07-04 05:49:46 bodea Exp
|
|||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <libcli.h>
|
||||
|
||||
#include "md5.h"
|
||||
#include "l2tpns.h"
|
||||
#include "cluster.h"
|
||||
#include "plugin.h"
|
||||
|
|
@ -105,6 +105,9 @@ config_descriptt config_values[] = {
|
|||
CONFIG("pid_file", pid_file, STRING),
|
||||
CONFIG("random_device", random_device, STRING),
|
||||
CONFIG("l2tp_secret", l2tpsecret, STRING),
|
||||
CONFIG("ppp_restart_time", ppp_restart_time, INT),
|
||||
CONFIG("ppp_max_configure", ppp_max_configure, INT),
|
||||
CONFIG("ppp_max_failure", ppp_max_failure, INT),
|
||||
CONFIG("primary_dns", default_dns1, IPv4),
|
||||
CONFIG("secondary_dns", default_dns2, IPv4),
|
||||
CONFIG("primary_radius", radiusserver[0], IPv4),
|
||||
|
|
@ -182,7 +185,7 @@ static void sighup_handler(int sig);
|
|||
static void sigalrm_handler(int sig);
|
||||
static void shutdown_handler(int sig);
|
||||
static void sigchild_handler(int sig);
|
||||
static void build_chap_response(char *challenge, uint8_t id, uint16_t challenge_length, char **challenge_response);
|
||||
static void build_chap_response(uint8_t *challenge, uint8_t id, uint16_t challenge_length, uint8_t **challenge_response);
|
||||
static void update_config(void);
|
||||
static void read_config_file(void);
|
||||
static void initplugins(void);
|
||||
|
|
@ -258,10 +261,10 @@ void _log(int level, sessionidt s, tunnelidt t, const char *format, ...)
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
void _log_hex(int level, const char *title, const char *data, int maxsize)
|
||||
void _log_hex(int level, const char *title, const uint8_t *data, int maxsize)
|
||||
{
|
||||
int i, j;
|
||||
const uint8_t *d = (const uint8_t *) data;
|
||||
const uint8_t *d = data;
|
||||
|
||||
if (config->debug < level) return;
|
||||
|
||||
|
|
@ -551,7 +554,7 @@ static void inittun(void)
|
|||
tunidx = ifr.ifr_ifindex;
|
||||
|
||||
// Only setup IPv6 on the tun device if we have a configured prefix
|
||||
if (config->ipv6_prefix.s6_addr[0] > 0) {
|
||||
if (config->ipv6_prefix.s6_addr[0]) {
|
||||
ifr6fd = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
|
||||
// Link local address is FE80::1
|
||||
|
|
@ -702,8 +705,11 @@ sessionidt sessionbyipv6(struct in6_addr ip)
|
|||
CSTAT(sessionbyipv6);
|
||||
|
||||
if (!memcmp(&config->ipv6_prefix, &ip, 8) ||
|
||||
(ip.s6_addr[0] == 0xFE && ip.s6_addr[1] == 0x80 &&
|
||||
(ip.s6_addr16[1] == ip.s6_addr16[2] == ip.s6_addr16[3] == 0))) {
|
||||
(ip.s6_addr[0] == 0xFE &&
|
||||
ip.s6_addr[1] == 0x80 &&
|
||||
ip.s6_addr16[1] == 0 &&
|
||||
ip.s6_addr16[2] == 0 &&
|
||||
ip.s6_addr16[3] == 0)) {
|
||||
s = lookup_ipmap(*(in_addr_t *) &ip.s6_addr[8]);
|
||||
} else {
|
||||
s = lookup_ipv6map(ip);
|
||||
|
|
@ -973,14 +979,14 @@ int tun_write(uint8_t * data, int size)
|
|||
|
||||
// process outgoing (to tunnel) IP
|
||||
//
|
||||
static void processipout(uint8_t * buf, int len)
|
||||
static void processipout(uint8_t *buf, int len)
|
||||
{
|
||||
sessionidt s;
|
||||
sessiont *sp;
|
||||
tunnelidt t;
|
||||
in_addr_t ip;
|
||||
|
||||
char *data = buf; // Keep a copy of the originals.
|
||||
uint8_t *data = buf; // Keep a copy of the originals.
|
||||
int size = len;
|
||||
|
||||
uint8_t b[MAXETHER + 20];
|
||||
|
|
@ -1126,7 +1132,7 @@ static void processipv6out(uint8_t * buf, int len)
|
|||
in_addr_t ip;
|
||||
struct in6_addr ip6;
|
||||
|
||||
char *data = buf; // Keep a copy of the originals.
|
||||
uint8_t *data = buf; // Keep a copy of the originals.
|
||||
int size = len;
|
||||
|
||||
uint8_t b[MAXETHER + 20];
|
||||
|
|
@ -1313,7 +1319,7 @@ static void controls(controlt * c, uint16_t avp, char *val, uint8_t m)
|
|||
}
|
||||
|
||||
// add a binary AVP
|
||||
static void controlb(controlt * c, uint16_t avp, char *val, unsigned int len, uint8_t m)
|
||||
static void controlb(controlt * c, uint16_t avp, uint8_t *val, unsigned int len, uint8_t m)
|
||||
{
|
||||
uint16_t l = ((m ? 0x8000 : 0) + len + 6);
|
||||
*(uint16_t *) (c->buf + c->length + 0) = htons(l);
|
||||
|
|
@ -1493,10 +1499,7 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error)
|
|||
if (session[s].ip && !walled_garden && !session[s].die)
|
||||
{
|
||||
// RADIUS Stop message
|
||||
uint16_t r = sess_local[s].radius;
|
||||
if (!r)
|
||||
r = radiusnew(s);
|
||||
|
||||
uint16_t r = radiusnew(s);
|
||||
if (r)
|
||||
{
|
||||
// stop, if not already trying
|
||||
|
|
@ -1534,7 +1537,7 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error)
|
|||
free_ip_address(s);
|
||||
|
||||
// unroute IPv6, if setup
|
||||
if (session[s].flags & SF_IPV6_ROUTED)
|
||||
if (session[s].ppp.ipv6cp == Opened && session[s].ipv6prefixlen)
|
||||
route6set(s, session[s].ipv6route, session[s].ipv6prefixlen, 0);
|
||||
}
|
||||
|
||||
|
|
@ -1546,7 +1549,7 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error)
|
|||
controlt *c = controlnew(14); // sending CDN
|
||||
if (error)
|
||||
{
|
||||
char buf[4];
|
||||
uint8_t buf[4];
|
||||
*(uint16_t *) buf = htons(result);
|
||||
*(uint16_t *) (buf+2) = htons(error);
|
||||
controlb(c, 1, buf, 4, 1);
|
||||
|
|
@ -1565,78 +1568,66 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error)
|
|||
if (session[s].filter_in) ip_filters[session[s].filter_in - 1].used--;
|
||||
if (session[s].filter_out) ip_filters[session[s].filter_out - 1].used--;
|
||||
|
||||
// clear PPP state
|
||||
memset(&session[s].ppp, 0, sizeof(session[s].ppp));
|
||||
sess_local[s].lcp.restart = 0;
|
||||
sess_local[s].ipcp.restart = 0;
|
||||
sess_local[s].ipv6cp.restart = 0;
|
||||
sess_local[s].ccp.restart = 0;
|
||||
|
||||
cluster_send_session(s);
|
||||
}
|
||||
|
||||
void sendipcp(tunnelidt t, sessionidt s)
|
||||
{
|
||||
uint8_t buf[MAXCONTROL];
|
||||
uint16_t r = sess_local[s].radius;
|
||||
uint8_t *q;
|
||||
|
||||
CSTAT(sendipcp);
|
||||
|
||||
if (!r)
|
||||
r = radiusnew(s);
|
||||
|
||||
if (!r)
|
||||
if (!session[s].unique_id)
|
||||
{
|
||||
sessionshutdown(s, "No free RADIUS sessions for IPCP", 3, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (radius[r].state != RADIUSIPCP)
|
||||
{
|
||||
radius[r].state = RADIUSIPCP;
|
||||
radius[r].try = 0;
|
||||
}
|
||||
|
||||
radius[r].retry = backoff(radius[r].try++);
|
||||
if (radius[r].try > 10)
|
||||
{
|
||||
radiusclear(r, s); // Clear radius session.
|
||||
sessionshutdown(s, "No reply to IPCP.", 3, 0);
|
||||
return;
|
||||
if (!++last_id) ++last_id; // skip zero
|
||||
session[s].unique_id = last_id;
|
||||
}
|
||||
|
||||
q = makeppp(buf,sizeof(buf), 0, 0, t, s, PPPIPCP);
|
||||
if (!q) return;
|
||||
|
||||
*q = ConfigReq;
|
||||
q[1] = r >> RADIUS_SHIFT; // ID, dont care, we only send one type of request
|
||||
*(uint16_t *) (q + 2) = htons(10);
|
||||
q[4] = 3;
|
||||
q[5] = 6;
|
||||
q[1] = session[s].unique_id & 0xf; // ID, dont care, we only send one type of request
|
||||
*(uint16_t *) (q + 2) = htons(10); // packet length
|
||||
q[4] = 3; // ip address option
|
||||
q[5] = 6; // option length
|
||||
*(in_addr_t *) (q + 6) = config->peer_address ? config->peer_address :
|
||||
config->bind_address ? config->bind_address :
|
||||
my_address; // send my IP
|
||||
|
||||
tunnelsend(buf, 10 + (q - buf), t); // send it
|
||||
session[s].flags &= ~SF_IPCP_ACKED; // Clear flag.
|
||||
}
|
||||
|
||||
// If we have an IPv6 prefix length configured, assume we should
|
||||
// try to negotiate an IPv6 session as well. Unless we've had a
|
||||
// (N)ACK for IPV6CP.
|
||||
if (config->ipv6_prefix.s6_addr[0] > 0 &&
|
||||
!(session[s].flags & SF_IPV6CP_ACKED) &&
|
||||
!(session[s].flags & SF_IPV6_NACKED))
|
||||
{
|
||||
q = makeppp(buf,sizeof(buf), 0, 0, t, s, PPPIPV6CP);
|
||||
if (!q) return;
|
||||
void sendipv6cp(tunnelidt t, sessionidt s)
|
||||
{
|
||||
uint8_t buf[MAXCONTROL];
|
||||
uint8_t *q;
|
||||
|
||||
*q = ConfigReq;
|
||||
q[1] = r >> RADIUS_SHIFT; // ID, don't care, we
|
||||
// only send one type
|
||||
// of request
|
||||
*(uint16_t *) (q + 2) = htons(14);
|
||||
q[4] = 1;
|
||||
q[5] = 10;
|
||||
*(uint32_t *) (q + 6) = 0; // We'll be prefix::1
|
||||
*(uint32_t *) (q + 10) = 0;
|
||||
q[13] = 1;
|
||||
CSTAT(sendipv6cp);
|
||||
|
||||
tunnelsend(buf, 14 + (q - buf), t); // send it
|
||||
}
|
||||
q = makeppp(buf,sizeof(buf), 0, 0, t, s, PPPIPV6CP);
|
||||
if (!q) return;
|
||||
|
||||
*q = ConfigReq;
|
||||
q[1] = session[s].unique_id & 0xf; // ID, don't care, we
|
||||
// only send one type
|
||||
// of request
|
||||
*(uint16_t *) (q + 2) = htons(14);
|
||||
q[4] = 1; // interface identifier option
|
||||
q[5] = 10; // option length
|
||||
*(uint32_t *) (q + 6) = 0; // We'll be prefix::1
|
||||
*(uint32_t *) (q + 10) = 0;
|
||||
q[13] = 1;
|
||||
|
||||
tunnelsend(buf, 14 + (q - buf), t); // send it
|
||||
}
|
||||
|
||||
static void sessionclear(sessionidt s)
|
||||
|
|
@ -1742,7 +1733,7 @@ static void tunnelshutdown(tunnelidt t, char *reason, int result, int error, cha
|
|||
controlt *c = controlnew(4); // sending StopCCN
|
||||
if (error)
|
||||
{
|
||||
char buf[64];
|
||||
uint8_t buf[64];
|
||||
int l = 4;
|
||||
*(uint16_t *) buf = htons(result);
|
||||
*(uint16_t *) (buf+2) = htons(error);
|
||||
|
|
@ -1767,9 +1758,9 @@ static void tunnelshutdown(tunnelidt t, char *reason, int result, int error, cha
|
|||
}
|
||||
|
||||
// read and process packet on tunnel (UDP)
|
||||
void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
||||
void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||
{
|
||||
char *chapresponse = NULL;
|
||||
uint8_t *chapresponse = NULL;
|
||||
uint16_t l = len, t = 0, s = 0, ns = 0, nr = 0;
|
||||
uint8_t *p = buf + 2;
|
||||
|
||||
|
|
@ -2061,7 +2052,7 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
|||
n = orig_len;
|
||||
}
|
||||
|
||||
LOG(4, s, t, " AVP %d (%s) len %d%s%s\n", mtype, avp_name(mtype), n,
|
||||
LOG(4, s, t, " AVP %d (%s) len %d%s%s\n", mtype, l2tp_avp_name(mtype), n,
|
||||
flags & 0x40 ? ", hidden" : "", flags & 0x80 ? ", mandatory" : "");
|
||||
|
||||
switch (mtype)
|
||||
|
|
@ -2069,7 +2060,7 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
|||
case 0: // message type
|
||||
message = ntohs(*(uint16_t *) b);
|
||||
mandatory = flags & 0x80;
|
||||
LOG(4, s, t, " Message type = %d (%s)\n", *b, l2tp_message_type(message));
|
||||
LOG(4, s, t, " Message type = %d (%s)\n", *b, l2tp_code(message));
|
||||
break;
|
||||
case 1: // result code
|
||||
{
|
||||
|
|
@ -2077,18 +2068,18 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
|||
const char* resdesc = "(unknown)";
|
||||
if (message == 4)
|
||||
{ /* StopCCN */
|
||||
resdesc = stopccn_result_code(rescode);
|
||||
resdesc = l2tp_stopccn_result_code(rescode);
|
||||
}
|
||||
else if (message == 14)
|
||||
{ /* CDN */
|
||||
resdesc = cdn_result_code(rescode);
|
||||
resdesc = l2tp_cdn_result_code(rescode);
|
||||
}
|
||||
|
||||
LOG(4, s, t, " Result Code %d: %s\n", rescode, resdesc);
|
||||
if (n >= 4)
|
||||
{
|
||||
uint16_t errcode = ntohs(*(uint16_t *)(b + 2));
|
||||
LOG(4, s, t, " Error Code %d: %s\n", errcode, error_code(errcode));
|
||||
LOG(4, s, t, " Error Code %d: %s\n", errcode, l2tp_error_code(errcode));
|
||||
}
|
||||
if (n > 4)
|
||||
LOG(4, s, t, " Error String: %.*s\n", n-4, b+4);
|
||||
|
|
@ -2222,7 +2213,7 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
|||
case 29: // Proxy Authentication Type
|
||||
{
|
||||
uint16_t atype = ntohs(*(uint16_t *)b);
|
||||
LOG(4, s, t, " Proxy Auth Type %d (%s)\n", atype, auth_type(atype));
|
||||
LOG(4, s, t, " Proxy Auth Type %d (%s)\n", atype, ppp_auth_type(atype));
|
||||
if (atype == 2)
|
||||
authtype = AUTHCHAP;
|
||||
else if (atype == 3)
|
||||
|
|
@ -2351,7 +2342,7 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
|||
case 10: // ICRQ
|
||||
if (sessionfree && main_quit != QUIT_SHUTDOWN)
|
||||
{
|
||||
uint16_t r;
|
||||
controlt *c = controlnew(11); // ICRP
|
||||
|
||||
s = sessionfree;
|
||||
sessionfree = session[s].next;
|
||||
|
|
@ -2360,41 +2351,34 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
|||
if (s > config->cluster_highest_sessionid)
|
||||
config->cluster_highest_sessionid = s;
|
||||
|
||||
// make a RADIUS session
|
||||
if ((r = radiusnew(s)))
|
||||
{
|
||||
controlt *c = controlnew(11); // sending ICRP
|
||||
session[s].opened = time_now;
|
||||
session[s].tunnel = t;
|
||||
session[s].far = asession;
|
||||
session[s].last_packet = time_now;
|
||||
LOG(3, s, t, "New session (%d/%d)\n", tunnel[t].far, session[s].far);
|
||||
control16(c, 14, s, 1); // assigned session
|
||||
controladd(c, t, asession); // send the reply
|
||||
session[s].opened = time_now;
|
||||
session[s].tunnel = t;
|
||||
session[s].far = asession;
|
||||
session[s].last_packet = time_now;
|
||||
LOG(3, s, t, "New session (%d/%d)\n", tunnel[t].far, session[s].far);
|
||||
control16(c, 14, s, 1); // assigned session
|
||||
controladd(c, t, asession); // send the reply
|
||||
|
||||
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);
|
||||
STAT(session_created);
|
||||
break;
|
||||
}
|
||||
strncpy(session[s].called, called, sizeof(session[s].called) - 1);
|
||||
strncpy(session[s].calling, calling, sizeof(session[s].calling) - 1);
|
||||
|
||||
session[s].ppp.phase = Establish;
|
||||
session[s].ppp.lcp = Starting;
|
||||
|
||||
LOG(1, s, t, "No free RADIUS sessions for ICRQ\n");
|
||||
sessionclear(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
STAT(session_overflow);
|
||||
LOG(1, 0, t, "No free sessions\n");
|
||||
STAT(session_created);
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
controlt *c = controlnew(14); // CDN
|
||||
if (main_quit == QUIT_SHUTDOWN)
|
||||
control16(c, 1, 2, 7); // try another
|
||||
else
|
||||
if (!sessionfree)
|
||||
{
|
||||
STAT(session_overflow);
|
||||
LOG(1, 0, t, "No free sessions\n");
|
||||
control16(c, 1, 4, 0); // temporary lack of resources
|
||||
}
|
||||
else
|
||||
control16(c, 1, 2, 7); // shutting down, try another
|
||||
|
||||
controladd(c, t, asession); // send the message
|
||||
}
|
||||
|
|
@ -2408,12 +2392,19 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
|||
session[s].l2tp_flags = aflags; // set flags received
|
||||
LOG(3, s, t, "Magic %X Flags %X\n", amagic, aflags);
|
||||
controlnull(t); // ack
|
||||
|
||||
// proxy authentication type is not supported
|
||||
if (!(config->radius_authtypes & authtype))
|
||||
authtype = config->radius_authprefer;
|
||||
|
||||
// start LCP
|
||||
sendlcp(t, s, authtype);
|
||||
sess_local[s].lcp.restart = time_now + config->ppp_restart_time;
|
||||
sess_local[s].lcp.conf_sent = 1;
|
||||
sess_local[s].lcp.nak_sent = 0;
|
||||
sess_local[s].lcp_authtype = authtype;
|
||||
session[s].ppp.lcp = RequestSent;
|
||||
|
||||
break;
|
||||
case 14: // CDN
|
||||
controlnull(t); // ack
|
||||
|
|
@ -2507,16 +2498,9 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
|||
}
|
||||
else if (prot == PPPIPV6CP)
|
||||
{
|
||||
if (config->ipv6_prefix.s6_addr[0] > 0)
|
||||
{
|
||||
session[s].last_packet = time_now;
|
||||
if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port); return; }
|
||||
processipv6cp(t, s, p, l);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(1, s, t, "IPv6 not configured; ignoring IPv6CP\n");
|
||||
}
|
||||
session[s].last_packet = time_now;
|
||||
if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port); return; }
|
||||
processipv6cp(t, s, p, l);
|
||||
}
|
||||
else if (prot == PPPCCP)
|
||||
{
|
||||
|
|
@ -2543,7 +2527,7 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
|
|||
}
|
||||
else if (prot == PPPIPV6)
|
||||
{
|
||||
if (!config->ipv6_prefix.s6_addr[0] > 0)
|
||||
if (!config->ipv6_prefix.s6_addr[0])
|
||||
{
|
||||
LOG(1, s, t, "IPv6 not configured; yet received IPv6 packet. Ignoring.\n");
|
||||
return;
|
||||
|
|
@ -2592,7 +2576,7 @@ static void processtun(uint8_t * buf, int len)
|
|||
if (*(uint16_t *) (buf + 2) == htons(PKTIP)) // IPv4
|
||||
processipout(buf, len);
|
||||
else if (*(uint16_t *) (buf + 2) == htons(PKTIPV6) // IPV6
|
||||
&& config->ipv6_prefix.s6_addr[0] > 0)
|
||||
&& config->ipv6_prefix.s6_addr[0])
|
||||
processipv6out(buf, len);
|
||||
|
||||
// Else discard.
|
||||
|
|
@ -2734,13 +2718,123 @@ static void regular_cleanups(double period)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (session[s].ip && !(session[s].flags & SF_IPCP_ACKED)
|
||||
&& !(sess_local[s].radius && radius[sess_local[s].radius].state == RADIUSIPCP))
|
||||
// PPP timeouts
|
||||
if (sess_local[s].lcp.restart >= time_now)
|
||||
{
|
||||
// IPCP has not completed yet. Resend
|
||||
LOG(3, s, session[s].tunnel, "No ACK for initial IPCP ConfigReq... resending\n");
|
||||
sendipcp(session[s].tunnel, s);
|
||||
s_actions++;
|
||||
int next_state = session[s].ppp.lcp;
|
||||
switch (session[s].ppp.lcp)
|
||||
{
|
||||
case RequestSent:
|
||||
case AckReceived:
|
||||
next_state = RequestSent;
|
||||
|
||||
case AckSent:
|
||||
if (sess_local[s].lcp.conf_sent < config->ppp_max_configure)
|
||||
{
|
||||
LOG(3, s, session[s].tunnel, "No ACK for LCP ConfigReq... resending\n");
|
||||
sess_local[s].lcp.restart = time_now + config->ppp_restart_time;
|
||||
sess_local[s].lcp.conf_sent++;
|
||||
sendlcp(t, s, sess_local[s].lcp_authtype);
|
||||
change_state(s, lcp, next_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
sessionshutdown(s, "No response to LCP ConfigReq.", 3, 0);
|
||||
STAT(session_timeout);
|
||||
}
|
||||
|
||||
s_actions++;
|
||||
}
|
||||
|
||||
if (session[s].die)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sess_local[s].ipcp.restart >= time_now)
|
||||
{
|
||||
int next_state = session[s].ppp.ipcp;
|
||||
switch (session[s].ppp.ipcp)
|
||||
{
|
||||
case RequestSent:
|
||||
case AckReceived:
|
||||
next_state = RequestSent;
|
||||
|
||||
case AckSent:
|
||||
if (sess_local[s].ipcp.conf_sent < config->ppp_max_configure)
|
||||
{
|
||||
LOG(3, s, session[s].tunnel, "No ACK for IPCP ConfigReq... resending\n");
|
||||
sess_local[s].ipcp.restart = time_now + config->ppp_restart_time;
|
||||
sess_local[s].ipcp.conf_sent++;
|
||||
sendipcp(t, s);
|
||||
change_state(s, ipcp, next_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
sessionshutdown(s, "No response to IPCP ConfigReq.", 3, 0);
|
||||
STAT(session_timeout);
|
||||
}
|
||||
|
||||
s_actions++;
|
||||
}
|
||||
|
||||
if (session[s].die)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sess_local[s].ipv6cp.restart >= time_now)
|
||||
{
|
||||
int next_state = session[s].ppp.ipv6cp;
|
||||
switch (session[s].ppp.ipv6cp)
|
||||
{
|
||||
case RequestSent:
|
||||
case AckReceived:
|
||||
next_state = RequestSent;
|
||||
|
||||
case AckSent:
|
||||
if (sess_local[s].ipv6cp.conf_sent < config->ppp_max_configure)
|
||||
{
|
||||
LOG(3, s, session[s].tunnel, "No ACK for IPV6CP ConfigReq... resending\n");
|
||||
sess_local[s].ipv6cp.restart = time_now + config->ppp_restart_time;
|
||||
sess_local[s].ipv6cp.conf_sent++;
|
||||
sendipv6cp(t, s);
|
||||
change_state(s, ipv6cp, next_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(3, s, session[s].tunnel, "No ACK for IPV6CP ConfigReq\n");
|
||||
change_state(s, ipv6cp, Stopped);
|
||||
}
|
||||
|
||||
s_actions++;
|
||||
}
|
||||
}
|
||||
|
||||
if (sess_local[s].ccp.restart >= time_now)
|
||||
{
|
||||
int next_state = session[s].ppp.ccp;
|
||||
switch (session[s].ppp.ccp)
|
||||
{
|
||||
case RequestSent:
|
||||
case AckReceived:
|
||||
next_state = RequestSent;
|
||||
|
||||
case AckSent:
|
||||
if (sess_local[s].ccp.conf_sent < config->ppp_max_configure)
|
||||
{
|
||||
LOG(3, s, session[s].tunnel, "No ACK for CCP ConfigReq... resending\n");
|
||||
sess_local[s].ccp.restart = time_now + config->ppp_restart_time;
|
||||
sess_local[s].ccp.conf_sent++;
|
||||
sendccp(t, s);
|
||||
change_state(s, ccp, next_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(3, s, session[s].tunnel, "No ACK for CCP ConfigReq\n");
|
||||
change_state(s, ccp, Stopped);
|
||||
}
|
||||
|
||||
s_actions++;
|
||||
}
|
||||
}
|
||||
|
||||
// Drop sessions who have not responded within IDLE_TIMEOUT seconds
|
||||
|
|
@ -2753,7 +2847,7 @@ static void regular_cleanups(double period)
|
|||
}
|
||||
|
||||
// No data in ECHO_TIMEOUT seconds, send LCP ECHO
|
||||
if (session[s].user[0] && (time_now - session[s].last_packet >= ECHO_TIMEOUT))
|
||||
if (session[s].ppp.phase >= Establish && (time_now - session[s].last_packet >= ECHO_TIMEOUT))
|
||||
{
|
||||
uint8_t b[MAXCONTROL] = {0};
|
||||
|
||||
|
|
@ -3084,7 +3178,8 @@ static void mainloop(void)
|
|||
if (n)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int alen, c, s;
|
||||
socklen_t alen;
|
||||
int c, s;
|
||||
int udp_ready = 0;
|
||||
int tun_ready = 0;
|
||||
int cluster_ready = 0;
|
||||
|
|
@ -3391,6 +3486,9 @@ static void initdata(int optdebug, char *optconfig)
|
|||
config->num_tbfs = MAXTBFS;
|
||||
config->rl_rate = 28; // 28kbps
|
||||
config->cluster_master_min_adv = 1;
|
||||
config->ppp_restart_time = 3;
|
||||
config->ppp_max_configure = 10;
|
||||
config->ppp_max_failure = 5;
|
||||
strcpy(config->random_device, RANDOMDEVICE);
|
||||
|
||||
log_stream = stderr;
|
||||
|
|
@ -3758,7 +3856,7 @@ static void initippool()
|
|||
LOG(1, 0, 0, "IP address pool is %d addresses\n", ip_pool_size - 1);
|
||||
}
|
||||
|
||||
void snoop_send_packet(char *packet, uint16_t size, in_addr_t destination, uint16_t port)
|
||||
void snoop_send_packet(uint8_t *packet, uint16_t size, in_addr_t destination, uint16_t port)
|
||||
{
|
||||
struct sockaddr_in snoop_addr = {0};
|
||||
if (!destination || !port || snoopfd <= 0 || size <= 0 || !packet)
|
||||
|
|
@ -4055,7 +4153,7 @@ static void sigchild_handler(int sig)
|
|||
;
|
||||
}
|
||||
|
||||
static void build_chap_response(char *challenge, uint8_t id, uint16_t challenge_length, char **challenge_response)
|
||||
static void build_chap_response(uint8_t *challenge, uint8_t id, uint16_t challenge_length, uint8_t **challenge_response)
|
||||
{
|
||||
MD5_CTX ctx;
|
||||
*challenge_response = NULL;
|
||||
|
|
@ -4068,13 +4166,13 @@ static void build_chap_response(char *challenge, uint8_t id, uint16_t challenge_
|
|||
|
||||
LOG(4, 0, 0, " Building challenge response for CHAP request\n");
|
||||
|
||||
*challenge_response = (char *)calloc(17, 1);
|
||||
*challenge_response = calloc(17, 1);
|
||||
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, &id, 1);
|
||||
MD5Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
||||
MD5Update(&ctx, challenge, challenge_length);
|
||||
MD5Final(*challenge_response, &ctx);
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, &id, 1);
|
||||
MD5_Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
||||
MD5_Update(&ctx, challenge, challenge_length);
|
||||
MD5_Final(*challenge_response, &ctx);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -4384,13 +4482,8 @@ int sessionsetup(tunnelidt t, sessionidt s)
|
|||
cache_ipmap(session[s].ip, s);
|
||||
}
|
||||
|
||||
if (!session[s].unique_id)
|
||||
{
|
||||
// did this session just finish radius?
|
||||
LOG(3, s, t, "Sending initial IPCP to client\n");
|
||||
sendipcp(t, s);
|
||||
session[s].unique_id = ++last_id;
|
||||
}
|
||||
sess_local[s].lcp_authtype = 0; // RADIUS authentication complete
|
||||
lcp_open(t, s); // transition to Network phase and send initial IPCP
|
||||
|
||||
// Run the plugin's against this new session.
|
||||
{
|
||||
|
|
@ -4499,7 +4592,7 @@ int load_session(sessionidt s, sessiont *new)
|
|||
}
|
||||
|
||||
// check v6 routing
|
||||
if (new->flags & SF_IPV6_ROUTED && !(session[s].flags & SF_IPV6_ROUTED))
|
||||
if (new->ipv6prefixlen && new->ppp.ipv6cp == Opened && session[s].ppp.ipv6cp != Opened)
|
||||
route6set(s, new->ipv6route, new->ipv6prefixlen, 1);
|
||||
|
||||
// check filters
|
||||
|
|
@ -4716,7 +4809,7 @@ static void plugins_done()
|
|||
run_plugin_done(p);
|
||||
}
|
||||
|
||||
static void processcontrol(uint8_t * buf, int len, struct sockaddr_in *addr, int alen)
|
||||
static void processcontrol(uint8_t *buf, int len, struct sockaddr_in *addr, int alen)
|
||||
{
|
||||
struct nsctl request;
|
||||
struct nsctl response;
|
||||
|
|
@ -5040,11 +5133,11 @@ static void unhide_value(uint8_t *value, size_t len, uint16_t type, uint8_t *vec
|
|||
uint16_t m = htons(type);
|
||||
|
||||
// Compute initial pad
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, (unsigned char *) &m, 2);
|
||||
MD5Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
||||
MD5Update(&ctx, vector, vec_len);
|
||||
MD5Final(digest, &ctx);
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, (unsigned char *) &m, 2);
|
||||
MD5_Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
||||
MD5_Update(&ctx, vector, vec_len);
|
||||
MD5_Final(digest, &ctx);
|
||||
|
||||
// pointer to last decoded 16 octets
|
||||
last = value;
|
||||
|
|
@ -5054,10 +5147,10 @@ static void unhide_value(uint8_t *value, size_t len, uint16_t type, uint8_t *vec
|
|||
// calculate a new pad based on the last decoded block
|
||||
if (d >= sizeof(digest))
|
||||
{
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
||||
MD5Update(&ctx, last, sizeof(digest));
|
||||
MD5Final(digest, &ctx);
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, config->l2tpsecret, strlen(config->l2tpsecret));
|
||||
MD5_Update(&ctx, last, sizeof(digest));
|
||||
MD5_Final(digest, &ctx);
|
||||
|
||||
d = 0;
|
||||
last = value;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue