Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Tassilo Schweyer 2025-05-03 10:55:58 +02:00
commit 54d36d7512
5 changed files with 548 additions and 187 deletions

126
l2tpns.c
View file

@ -159,6 +159,7 @@ config_descriptt config_values[] = {
CONFIG("ppp_max_configure", ppp_max_configure, INT),
CONFIG("ppp_max_failure", ppp_max_failure, INT),
CONFIG("ppp_keepalive", ppp_keepalive, BOOL),
CONFIG("lcp_renegotiation", lcp_renegotiation, STRING),
CONFIG("primary_dns", default_dns1, IPv4),
CONFIG("secondary_dns", default_dns2, IPv4),
CONFIG("primary_radius", radiusserver[0], IPv4),
@ -4184,9 +4185,18 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
uint16_t message = 0xFFFF; // message type
uint8_t fatal = 0;
uint8_t mandatory = 0;
uint8_t *last_sent_lcp_confreq = 0;
uint16_t last_sent_lcp_confreq_n = 0;
uint8_t *last_received_lcp_confreq = 0;
uint16_t last_received_lcp_confreq_n = 0;
uint16_t atype = 0;
uint16_t authid = 0;
char authname[MAXUSER] = "";
char authchall[MAXPASS] = "";
size_t authchalln = 0;
char authresp[MAXPASS] = "";
size_t authrespn = 0;
uint16_t asession = 0; // assigned session
uint32_t amagic = 0; // magic number
uint8_t aflags = 0; // flags from last LCF
uint16_t version = 0x0100; // protocol version (we handle 0.0 as well and send that back just in case)
char called[MAXTEL] = ""; // called number
char calling[MAXTEL] = ""; // calling number
@ -4663,50 +4673,70 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
}
case 29: // Proxy Authentication Type
{
uint16_t atype = ntohs(*(uint16_t *)b);
atype = ntohs(*(uint16_t *)b);
LOG(4, s, t, " Proxy Auth Type %u (%s)\n", atype, ppp_auth_type(atype));
break;
}
case 30: // Proxy Authentication Name
{
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);
if (n < sizeof(authname))
{
LOG(4, s, t, " Proxy Auth Name (%s)\n", authname);
}
else
{
LOG(2, s, t, " Proxy Auth Name too long (%s)\n", authname);
}
break;
}
case 31: // Proxy Authentication Challenge
{
LOG(4, s, t, " Proxy Auth Challenge\n");
if (n <= sizeof(authchall))
{
memcpy(authchall, b, n);
authchalln = n;
LOG(4, s, t, " Proxy Auth Challenge\n");
}
else
{
LOG(2, s, t, " Proxy Auth Challenge too long\n");
}
break;
}
case 32: // Proxy Authentication ID
{
uint16_t authid = ntohs(*(uint16_t *)(b));
authid = ntohs(*(uint16_t *)(b));
LOG(4, s, t, " Proxy Auth ID (%u)\n", authid);
break;
}
case 33: // Proxy Authentication Response
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 (n <= sizeof(authresp))
{
if (*p == 5 && p[1] == 6) // Magic-Number
amagic = ntohl(*(uint32_t *) (p + 2));
else if (*p == 7) // Protocol-Field-Compression
aflags |= SESSION_PFC;
else if (*p == 8) // Address-and-Control-Field-Compression
aflags |= SESSION_ACFC;
p += p[1];
memcpy(authresp, b, n);
authrespn = n;
LOG(4, s, t, " Proxy Auth Response\n");
}
else
{
LOG(2, s, t, " Proxy Auth Response too long\n");
}
break;
}
case 27: // last sent lcp
{
last_sent_lcp_confreq = b;
last_sent_lcp_confreq_n = n;
break;
}
break;
case 28: // last recv lcp confreq
break;
{
last_received_lcp_confreq = b;
last_received_lcp_confreq_n = n;
break;
}
case 26: // Initial Received LCP CONFREQ
break;
case 39: // seq required - we control it as an LNS anyway...
@ -5017,9 +5047,8 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
break;
case 12: // ICCN
LOG(3, s, t, "Received ICCN\n");
if (amagic == 0) amagic = time_now;
session[s].magic = amagic; // set magic number
session[s].flags = aflags; // set flags received
session[s].magic = time_now; // set magic number
session[s].mru = PPPoE_MRU; // default
controlnull(t); // ack
@ -5034,8 +5063,39 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
else
sess_local[s].mp_epdis = 0;
sendlcp(s, t);
change_state(s, lcp, RequestSent);
if (last_sent_lcp_confreq_n && last_received_lcp_confreq_n &&
processlcpproxy(s, t, last_sent_lcp_confreq, last_sent_lcp_confreq_n,
last_received_lcp_confreq, last_received_lcp_confreq_n)
&& ( (sess_local[s].lcp_authtype == 0)
|| (sess_local[s].lcp_authtype == AUTHPAP && authrespn)
|| (sess_local[s].lcp_authtype == AUTHCHAP && authchalln == 16 && authrespn == 16)))
{
// Could reuse the LCP negotiation and don't have empty proxy auth response or unknown challenge size, don't renegotiate
LOG(3, s, t, "Reusing LCP negotiation\n");
// Start with proxy auth id to avoid client caching challenge responses
sess_local[s].auth_id = authid;
if (!sess_local[s].lcp_authtype)
{
// No auth, open immediately
lcp_open(s, t);
}
else
{
// Process auth
session[s].ppp.phase = Authenticate;
change_state(s, lcp, Opened);
processauthproxy(s, t, atype, authname, authchalln, authchall, authrespn, authresp);
}
}
else
{
// Have to renegotiate LCP
LOG(3, s, t, "Renegotiating LCP\n");
sendlcp(s, t);
change_state(s, lcp, RequestSent);
}
break;
case 14: // CDN
@ -7446,6 +7506,16 @@ static void update_config()
MSS = MRU - TCP_HDRS;
MSS6 = MRU - TCP6_HDRS;
if (!config->lcp_renegotiation[0])
strcpy(config->lcp_renegotiation, "always");
if (strcmp(config->lcp_renegotiation, "always") &&
strcmp(config->lcp_renegotiation, "on-mismatch"))
{
LOG(0, 0, 0, "Invalid LCP renegotiation type %s, assuming 'always'\n", config->lcp_renegotiation);
strcpy(config->lcp_renegotiation, "always");
}
// Update radius
config->numradiusservers = 0;
for (i = 0; i < MAXRADSERVER; i++)