more chap
authorBrendan O'Dea <bod@optus.net>
Sun, 8 May 2005 06:28:12 +0000 (06:28 +0000)
committerBrendan O'Dea <bod@optus.net>
Sun, 8 May 2005 06:28:12 +0000 (06:28 +0000)
Changes
l2tpns.spec
ppp.c

diff --git a/Changes b/Changes
index b4d9f9a..3d6cc27 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,7 +1,8 @@
-* Sat May 7 2005 Brendan O'Dea <bod@optusnet.com.au> 2.1.0
+* Sun May 8 2005 Brendan O'Dea <bod@optusnet.com.au> 2.1.0
 - Add IPv6 support from Jonathan McDowell.
 - Add IPv6 support from Jonathan McDowell.
-- Add CHAP support from Jordan Hrycaj (work in progress).
+- Add CHAP support from Jordan Hrycaj.
 - Add interim accounting support from Vladislav Bjelic.
 - Add interim accounting support from Vladislav Bjelic.
+- Negotiate MRU, default 1458 to avoid fragmentation.
 - Sanity check that cluster_send_session is not called from a child
   process.
 - Throttle outgoing LASTSEEN packets to at most one per second for a
 - Sanity check that cluster_send_session is not called from a child
   process.
 - Throttle outgoing LASTSEEN packets to at most one per second for a
index 3a3d47c..883f14a 100644 (file)
@@ -43,5 +43,5 @@ rm -rf %{buildroot}
 %attr(644,root,root) /usr/share/man/man[58]/*
 
 %changelog
 %attr(644,root,root) /usr/share/man/man[58]/*
 
 %changelog
-* Sat May 7 2005 Brendan O'Dea <bod@optusnet.com.au> 2.1.0-1
+* Sun May 8 2005 Brendan O'Dea <bod@optusnet.com.au> 2.1.0-1
 - 2.1.0 release, see /usr/share/doc/l2tpns-2.1.0/Changes
 - 2.1.0 release, see /usr/share/doc/l2tpns-2.1.0/Changes
diff --git a/ppp.c b/ppp.c
index 08351e5..cb1b1f8 100644 (file)
--- a/ppp.c
+++ b/ppp.c
@@ -1,6 +1,6 @@
 // L2TPNS PPP Stuff
 
 // L2TPNS PPP Stuff
 
-char const *cvs_id_ppp = "$Id: ppp.c,v 1.52 2005-05-07 13:12:26 bodea Exp $";
+char const *cvs_id_ppp = "$Id: ppp.c,v 1.53 2005-05-08 06:28:12 bodea Exp $";
 
 #include <stdio.h>
 #include <string.h>
 
 #include <stdio.h>
 #include <string.h>
@@ -41,7 +41,7 @@ void processpap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
                LOG(1, s, t, "Short PAP %u bytes\n", l);
                STAT(tunnel_rx_errors);
                sessionshutdown(s, "Short PAP packet.", 3, 0);
                LOG(1, s, t, "Short PAP %u bytes\n", l);
                STAT(tunnel_rx_errors);
                sessionshutdown(s, "Short PAP packet.", 3, 0);
-               return ;
+               return;
        }
 
        if ((hl = ntohs(*(uint16_t *) (p + 2))) > l)
        }
 
        if ((hl = ntohs(*(uint16_t *) (p + 2))) > l)
@@ -49,7 +49,7 @@ void processpap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
                LOG(1, s, t, "Length mismatch PAP %u/%u\n", hl, l);
                STAT(tunnel_rx_errors);
                sessionshutdown(s, "PAP length mismatch.", 3, 0);
                LOG(1, s, t, "Length mismatch PAP %u/%u\n", hl, l);
                STAT(tunnel_rx_errors);
                sessionshutdown(s, "PAP length mismatch.", 3, 0);
-               return ;
+               return;
        }
        l = hl;
 
        }
        l = hl;
 
@@ -58,7 +58,7 @@ void processpap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
                LOG(1, s, t, "Unexpected PAP code %d\n", *p);
                STAT(tunnel_rx_errors);
                sessionshutdown(s, "Unexpected PAP code.", 3, 0);
                LOG(1, s, t, "Unexpected PAP code %d\n", *p);
                STAT(tunnel_rx_errors);
                sessionshutdown(s, "Unexpected PAP code.", 3, 0);
-               return ;
+               return;
        }
 
        {
        }
 
        {
@@ -150,6 +150,7 @@ void processchap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
        {
                LOG(1, s, t, "Unexpected CHAP message\n");
                STAT(tunnel_rx_errors);
        {
                LOG(1, s, t, "Unexpected CHAP message\n");
                STAT(tunnel_rx_errors);
+               sessionshutdown(s, "Unexpected CHAP message.", 3, 0);
                return;
        }
 
                return;
        }
 
@@ -157,14 +158,16 @@ void processchap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
        {
                LOG(1, s, t, "Short CHAP %u bytes\n", l);
                STAT(tunnel_rx_errors);
        {
                LOG(1, s, t, "Short CHAP %u bytes\n", l);
                STAT(tunnel_rx_errors);
-               return ;
+               sessionshutdown(s, "Short CHAP packet.", 3, 0);
+               return;
        }
 
        if ((hl = ntohs(*(uint16_t *) (p + 2))) > l)
        {
                LOG(1, s, t, "Length mismatch CHAP %u/%u\n", hl, l);
                STAT(tunnel_rx_errors);
        }
 
        if ((hl = ntohs(*(uint16_t *) (p + 2))) > l)
        {
                LOG(1, s, t, "Length mismatch CHAP %u/%u\n", hl, l);
                STAT(tunnel_rx_errors);
-               return ;
+               sessionshutdown(s, "CHAP length mismatch.", 3, 0);
+               return;
        }
        l = hl;
 
        }
        l = hl;
 
@@ -172,20 +175,23 @@ void processchap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
        {
                LOG(1, s, t, "Unexpected CHAP response code %d\n", *p);
                STAT(tunnel_rx_errors);
        {
                LOG(1, s, t, "Unexpected CHAP response code %d\n", *p);
                STAT(tunnel_rx_errors);
+               sessionshutdown(s, "CHAP length mismatch.", 3, 0);
                return;
        }
        if (p[1] != radius[r].id)
        {
                LOG(1, s, t, "Wrong CHAP response ID %d (should be %d) (%d)\n", p[1], radius[r].id, r);
                STAT(tunnel_rx_errors);
                return;
        }
        if (p[1] != radius[r].id)
        {
                LOG(1, s, t, "Wrong CHAP response ID %d (should be %d) (%d)\n", p[1], radius[r].id, r);
                STAT(tunnel_rx_errors);
-               return ;
+               sessionshutdown(s, "Unexpected CHAP response ID.", 3, 0);
+               return;
        }
 
        if (l < 5 || p[4] != 16)
        {
                LOG(1, s, t, "Bad CHAP response length %d\n", l < 5 ? -1 : p[4]);
                STAT(tunnel_rx_errors);
        }
 
        if (l < 5 || p[4] != 16)
        {
                LOG(1, s, t, "Bad CHAP response length %d\n", l < 5 ? -1 : p[4]);
                STAT(tunnel_rx_errors);
-               return ;
+               sessionshutdown(s, "Bad CHAP response length.", 3, 0);
+               return;
        }
 
        l -= 5;
        }
 
        l -= 5;
@@ -194,7 +200,8 @@ void processchap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
        {
                LOG(1, s, t, "CHAP user too long %d\n", l - 16);
                STAT(tunnel_rx_errors);
        {
                LOG(1, s, t, "CHAP user too long %d\n", l - 16);
                STAT(tunnel_rx_errors);
-               return ;
+               sessionshutdown(s, "CHAP username too long.", 3, 0);
+               return;
        }
 
        // Run PRE_AUTH plugins
        }
 
        // Run PRE_AUTH plugins
@@ -513,10 +520,69 @@ void processlcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
        }
        else if (*p == ConfigNak)
        {
        }
        else if (*p == ConfigNak)
        {
-               LOG(1, s, t, "Remote end sent a ConfigNak.  Ignoring\n");
+               int x = l - 4;
+               uint8_t *o = (p + 4);
+               int authtype = 0;
+
+               LOG(3, s, t, "LCP: ConfigNak (%d bytes)...\n", l);
                if (config->debug > 3) dumplcp(p, l);
                if (config->debug > 3) dumplcp(p, l);
-               // FIXME: handle MRU, authentication type
-               return;
+
+               while (x > 2)
+               {
+                       int type = o[0];
+                       int length = o[1];
+
+                       if (length == 0 || type == 0 || x < length) break;
+                       switch (type)
+                       {
+                               case 1: // Maximum-Receive-Unit
+                                       session[s].mru = ntohs(*(uint16_t *)(o + 2));
+                                       LOG(3, s, t, "    Remote requested MRU of %u\n", session[s].mru);
+                                       break;
+
+                               case 3: // Authentication-Protocol
+                                       if (authtype)
+                                               break;
+
+                                       {
+                                               int proto = ntohs(*(uint16_t *)(o + 2));
+                                               if (proto == PPPPAP)
+                                               {
+                                                       authtype = config->radius_authtypes & AUTHPAP;
+                                                       LOG(3, s, t, "    Remote requested PAP authentication...%sing\n",
+                                                               authtype ? "accept" : "reject");
+                                               }
+                                               else if (proto == PPPCHAP && *(o + 4) == 5)
+                                               {
+                                                       authtype = config->radius_authtypes & AUTHCHAP;
+                                                       LOG(3, s, t, "    Remote requested CHAP authentication...%sing\n",
+                                                               authtype ? "accept" : "reject");
+                                               }
+                                               else
+                                               {
+                                                       LOG(3, s, t, "    Rejecting unsupported authentication %#4x\n",
+                                                               proto);
+                                               }
+                                       }
+
+                                       if (!authtype)
+                                       {
+                                               sessionshutdown(s, "Unsupported authentication.", 3, 0);
+                                               return;
+                                       }
+
+                                       break;
+
+                               default:
+                                       LOG(2, s, t, "    Remote NAKed LCP type %u?\n", type);
+                                       break;
+                       }
+               }
+
+               if (!authtype)
+                       authtype = config->radius_authprefer;
+
+               sendlcp(t, s, authtype);
        }
        else if (*p == TerminateReq)
        {
        }
        else if (*p == TerminateReq)
        {
@@ -575,7 +641,6 @@ void processlcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
        {
                LOG(1, s, t, "Unexpected LCP code %d\n", *p);
                STAT(tunnel_rx_errors);
        {
                LOG(1, s, t, "Unexpected LCP code %d\n", *p);
                STAT(tunnel_rx_errors);
-               return ;
        }
 }
 
        }
 }