Hello!

Full disclosure: this took place over the course of about a month, and
I've done my best to include the relevant info..

Unsure if this is really a bug, and I don't have a real diff for a fix, just a
work-around, so misc it is.

This is done with OpenBSD 6.8-stable, syspatch 001 through 012 installed.
We considered trying -current, but noticed no activity in the npppd tree
that might make a difference.

'old' and 'new' equipment types from upstream are both Juniper, though
unsure of exact models.  Old  should be Juniper ERX of some type, new
I only know this from packet capture: Juniper Networks/Unisphere(4874).

I work for a small ISP and we are exploring the use of npppd(8) for
termination of L2TP with incumbent for xDSL connections. 

Working with the provider, their 'old' equipment works fine[1], however,
the 'new' network would always cause these errors upon receipt of Proxy AVP:

Feb  5 14:13:13 edge9 npppd[86416]: l2tpd ctrl=2359 call=2685 Received bad 
ICCN: Attribute value is too long PROXY_AUTHEN_CHALLENGE 33 > 24
Feb  5 14:13:13 edge9 npppd[86416]: l2tpd ctrl=2359 call=2685 SendCDN 
result=ERROR_CODE/2 error=WRONG_LENGTH/2 messsage=none

Looking at RFC 2661, I can't actually figure where a limit of 24 is imposed,
though I was tricked as I counted the bits on top of their chart which does
hit 32, nothing in the surrounding text actually dictates this size limit:

>From RFC 2661, "Proxy Authen Challenge (ICCN)" near page 37:

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      | Challenge... (arbitrary number of octets)                     |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Looking at npppd's l2tp_subr.h where the error above comes from:

#define AVP_MAXLEN_CHECK(_avp, _maxlen)                                 \
        do {                                                            \
                if ((_avp)->length > (_maxlen) + 6) {                   \
                        snprintf(emes, sizeof(emes),                    \
                            "Attribute value is too long %s %d > %d",   \
                            avp_attr_type_string((_avp)->attr_type),    \
                            (_avp)->length - 6, (int)(_maxlen));        \
                        goto size_check_failed;                         \
                }                                                       \
        } while (/* CONSTCOND */0)

I drew wild conclusions that perhaps 24 + 6, which lines up with counting
the bits on the RFC chart above, is how the limit was chosen.

After many more days of packet captures and head scratching, I specifically
saw that in the RADIUS packet, within the Attribute Value Pairs, it was
CHAP-Challenge, type 60, that was overflowing this size check.

On to RFC 2865, page 59: https://tools.ietf.org/html/rfc2865#page-59

    0                   1                   2
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
   |     Type      |    Length     |    String...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

Aha, this chart actually hits exactly 24.  Still no mention of a hard
size limit, the only thing it dictates is:

   Length
      >= 7

Ultimately we managed to get this working by simply omitting the size check
as such:

Index: l2tp/l2tp_call.c
===================================================================
RCS file: /cvs/src/usr.sbin/npppd/l2tp/l2tp_call.c,v
retrieving revision 1.19
diff -u -p -r1.19 l2tp_call.c
--- l2tp/l2tp_call.c    5 Dec 2015 16:10:31 -0000       1.19
+++ l2tp/l2tp_call.c    5 Mar 2021 17:46:12 -0000
@@ -546,7 +546,8 @@ l2tp_call_recv_ICCN(l2tp_call *_this, u_
                        dpi->last_recv_lcp.ldata = avp_attr_length(avp);
                        break;
                case L2TP_AVP_TYPE_PROXY_AUTHEN_CHALLENGE:
-                       AVP_MAXLEN_CHECK(avp, sizeof(dpi->auth_chall));
+                       /* XXX: disable to try and skirt 'too long' errors */
+                       /* AVP_MAXLEN_CHECK(avp, sizeof(dpi->auth_chall)); */
                        memcpy(dpi->auth_chall, avp->attr_value,
                            avp_attr_length(avp));
                        dpi->lauth_chall = avp_attr_length(avp);

We've been running this modified npppd for a week now, our upstream is happy
that they can continue phasing out their 'old' gear, and our endusers are
able to get online.

Neither myself nor my colleague can figure out how '24' is chosen for _maxlen,
but as this finally got us moving forward, wanted to share what we had and see
if we are on the right track.

I am thinking that we would want a maximum length set there still, but perhaps
it can be pushed up?  I've seen many of those error types, all seem to stay
below 100:

Feb  8 11:42:53 edge9 npppd[86416]: l2tpd ctrl=5477 call=32713 Received bad 
ICCN: Attribute value is too long PROXY_AUTHEN_CHALLENGE 40 > 24
Feb  8 11:42:53 edge9 npppd[86416]: l2tpd ctrl=5477 call=32713 SendCDN 
result=ERROR_CODE/2 error=WRONG_LENGTH/2 messsage=none
Feb  8 11:42:54 edge9 npppd[86416]: l2tpd ctrl=5477 call=29504 Received bad 
ICCN: Attribute value is too long PROXY_AUTHEN_CHALLENGE 62 > 24
Feb  8 11:42:54 edge9 npppd[86416]: l2tpd ctrl=5477 call=29504 SendCDN 
result=ERROR_CODE/2 error=WRONG_LENGTH/2 messsage=none
Feb  8 11:43:01 edge9 npppd[86416]: l2tpd ctrl=5477 call=31527 Received bad 
ICCN: Attribute value is too long PROXY_AUTHEN_CHALLENGE 46 > 24
Feb  8 11:43:01 edge9 npppd[86416]: l2tpd ctrl=5477 call=31527 SendCDN 
result=ERROR_CODE/2 error=WRONG_LENGTH/2 messsage=none
Feb  8 11:43:06 edge9 npppd[86416]: l2tpd ctrl=5477 call=1626 Received bad 
ICCN: Attribute value is too long PROXY_AUTHEN_CHALLENGE 63 > 24
Feb  8 11:43:06 edge9 npppd[86416]: l2tpd ctrl=5477 call=1626 SendCDN 
result=ERROR_CODE/2 error=WRONG_LENGTH/2 messsage=none

[1] at some point over the course of debugging, I did notice that this
error would /sometimes/ print on the connections from the 'old' equipment,
but would continue to work anyway:

Mar  5 10:21:44 edge9 npppd[35209]: ppp id=4108 layer=chap proto=unknown "Proxy 
Authen Challenge" is too long.

This now also prints on all the 'new equipment' successful connections since
disabling the AVP_MAXLEN_CHECK.

-ryan

Reply via email to