linux-ppp.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Adding EAP-MSCHAPv2 support
@ 2020-04-03 15:09 Eivind Naess
  2020-04-03 15:27 ` James Carlson
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Eivind Naess @ 2020-04-03 15:09 UTC (permalink / raw)
  To: linux-ppp

Implementation based on the RFC: draft-kamath-pppext-eap-mschapv2-02.
Adding support for MSCHAPv2 inside the extensible authentication protocol (EAP).

Author: Thomas Omerzu <thomas@omerzu.de>
Origin: https://w3logistics.com/blog/archives/438-EAP-MSCHAPv2-for-pppd-2-4-7.html
Bug: https://github.com/paulusmack/ppp/issues/138
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/ppp/+bug/1858349
Pull Request: https://github.com/paulusmack/ppp/pull/139
Last-Update: 2020-02-24
Signed-off-by: Thomas Omerzu <thomas@omerzu.de>.
---
 pppd/eap.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 pppd/eap.h |  12 +++++
 2 files changed, 152 insertions(+), 3 deletions(-)

diff --git a/pppd/eap.c b/pppd/eap.c
index 082e953..7b63452 100644
--- a/pppd/eap.c
+++ b/pppd/eap.c
@@ -64,6 +64,9 @@
 #include "pathnames.h"
 #include "md5.h"
 #include "eap.h"
+#ifdef CHAPMS
+#include "chap_ms.h"
+#endif

 #ifdef USE_SRP
 #include <t_pwd.h>
@@ -1302,6 +1305,47 @@ int len, id;
 }
 #endif /* USE_SRP */

+#if CHAPMS
+/*
+ * Format and send an CHAPV2-Challenge EAP Response message.
+ */
+static void
+eap_chapv2_response(esp, id, chapid, response, user, user_len)
+eap_state *esp;
+u_char id;
+u_char chapid;
+u_char *response;
+char *user;
+int user_len;
+{
+    u_char *outp;
+    int msglen;
+
+    outp = outpacket_buf;
+
+    MAKEHEADER(outp, PPP_EAP);
+
+    PUTCHAR(EAP_RESPONSE, outp);
+    PUTCHAR(id, outp);
+    esp->es_client.ea_id = id;
+    msglen = EAP_HEADERLEN + 6 * sizeof (u_char) +
MS_CHAP2_RESPONSE_LEN + user_len;
+    PUTSHORT(msglen, outp);
+    PUTCHAR(EAPT_MSCHAPV2, outp);
+    PUTCHAR(CHAP_RESPONSE, outp);
+    PUTCHAR(chapid, outp);
+    PUTCHAR(0, outp);
+    /* len */
+    PUTCHAR(5 + user_len +MS_CHAP2_RESPONSE_LEN, outp);
+    /* len response */
+    PUTCHAR(MS_CHAP2_RESPONSE_LEN, outp)
+    BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN);
+    INCPTR(MS_CHAP2_RESPONSE_LEN, outp);
+    BCOPY(user, outp, user_len);
+
+    output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
+}
+#endif
+
 /*
  * eap_request - Receive EAP Request message (client mode).
  */
@@ -1461,6 +1505,97 @@ int len;
             esp->es_client.ea_namelen);
         break;

+#ifdef CHAPMS
+    case EAPT_MSCHAPV2:
+        if (len < 1) {
+            error("EAP: received short MSCHAPv2");
+            /* Bogus request; wait for something real. */
+            return;
+        }
+        unsigned char chopcode;
+        GETCHAR(chopcode, inp);
+        len--;
+        dbglog("EAP: CHAP opcode %d", chopcode);
+
+        if (chopcode=CHAP_CHALLENGE) {
+
+            unsigned char chapid; /* Chapv2-ID */
+            GETCHAR(chapid, inp);
+            short mssize;
+            GETSHORT(mssize, inp);
+            unsigned char vsize;
+            GETCHAR(vsize, inp);
+            len-=4;
+
+            dbglog("EAP: chapid %d mssize %d vsize %d inplen %d,
challen %d", chapid, mssize, vsize, len, MS_CHAP2_PEER_CHAL_LEN);
+
+            unsigned char *rchallenge = calloc(1, MS_CHAP2_PEER_CHAL_LEN);
+            BCOPY(inp, rchallenge, MS_CHAP2_PEER_CHAL_LEN);
+            INCPTR(MS_CHAP2_PEER_CHAL_LEN,inp);
+
+            /*
+             * Get the secret for authenticating ourselves with
+             * the specified host.
+             */
+            if (!get_secret(esp->es_unit, esp->es_client.ea_name,
+                rhostname, secret, &secret_len, 0)) {
+                dbglog("EAP: no CHAP secret for auth to %q", rhostname);
+                eap_send_nak(esp, id, EAPT_SRP);
+                break;
+            }
+
+            char *user = calloc(1, esp->es_client.ea_namelen + 1);
+            memcpy(user, esp->es_client.ea_name, esp->es_client.ea_namelen);
+            *(user + esp->es_client.ea_namelen) = '\0';
+            dbglog("EAP: user %s, user_len %d", user,
esp->es_client.ea_namelen);
+
+            /* mschapv2 response */
+            unsigned char response[49];
+            unsigned char authResponse[41];
+            ChapMS2(rchallenge, NULL, user, secret, secret_len, response,
+                    authResponse, MS_CHAP2_AUTHENTICATEE);
+
+            eap_chapv2_response(esp, id, chapid, response,
esp->es_client.ea_name, esp->es_client.ea_namelen);
+
+            free(user);
+            free(rchallenge);
+
+        } else if (chopcode=CHAP_SUCCESS) {
+
+            unsigned char chapid; /* Chapv2-ID */
+            GETCHAR(chapid, inp);
+            short mssize;
+            GETSHORT(mssize, inp);
+            len-=3;
+            dbglog("EAP: chapid %d mssize %d inplen %d", chapid, mssize, len );
+            dbglog("Chap authentication succeeded: %.*v", len, inp);
+            u_char response[1];
+            response[0]=CHAP_SUCCESS;
+            eap_send_response(esp, id, EAPT_MSCHAPV2, response, 1);
+
+        } else if (chopcode=CHAP_FAILURE) {
+
+            unsigned char chapid; /* Chapv2-ID */
+            GETCHAR(chapid, inp);
+            short mssize;
+            GETSHORT(mssize, inp);
+            len-=3;
+            dbglog("EAP: chapid %d mssize %d inplen %d", chapid, mssize, len );
+            dbglog("Chap authentication failed: %.*v", len, inp);
+            u_char response[1];
+            response[0]=CHAP_FAILURE;
+            eap_send_response(esp, id, EAPT_MSCHAPV2, response, 1);
+            goto client_failure; /* force termination */
+
+        } else {
+
+            dbglog("EAP: Unknown CHAP opcode %d", chopcode);
+            eap_send_nak(esp, id, EAPT_SRP);
+        }
+
+        break;
+#endif /* CHAPMS */
+
 #ifdef USE_SRP
     case EAPT_SRP:
         if (len < 1) {
@@ -1706,16 +1841,16 @@ int len;
     }
     return;

-#ifdef USE_SRP
 client_failure:
     esp->es_client.ea_state = eapBadAuth;
     if (esp->es_client.ea_timeout > 0) {
         UNTIMEOUT(eap_client_timeout, (void *)esp);
     }
     esp->es_client.ea_session = NULL;
+#ifdef USE_SRP
     t_clientclose(tc);
-    auth_withpeer_fail(esp->es_unit, PPP_EAP);
 #endif /* USE_SRP */
+    auth_withpeer_fail(esp->es_unit, PPP_EAP);
 }

 /*
@@ -2154,7 +2289,9 @@ static char *eap_typenames[] = {
     "OTP", "Generic-Token", NULL, NULL,
     "RSA", "DSS", "KEA", "KEA-Validate",
     "TLS", "Defender", "Windows 2000", "Arcot",
-    "Cisco", "Nokia", "SRP"
+    "Cisco", "Nokia", "SRP", NULL,
+    "TTLS", "RAS", "AKA", "3COM", "PEAP",
+    "MSCHAPv2"
 };

 static int
diff --git a/pppd/eap.h b/pppd/eap.h
index 199d184..083ccfc 100644
--- a/pppd/eap.h
+++ b/pppd/eap.h
@@ -59,6 +59,18 @@ extern "C" {
 #define    EAPT_NOKIACARD        18    /* Nokia IP smart card */
 #define    EAPT_SRP        19    /* Secure Remote Password */
 /* 20 is deprecated */
+#define    EAPT_TTLS        21    /* EAP Tunneled TLS Authentication
Protocol RFC5281 */
+#define    EAPT_RAS        22    /* Remote Access Service */
+#define    EAPT_AKA        23    /* EAP method for 3rd Generation
Authentication and Key Agreement RFC4187 */
+#define    EAPT_3COM        24    /* EAP-3Com Wireless */
+#define    EAPT_PEAP        25    /* Protected EAP */
+#define    EAPT_MSCHAPV2        26    /* EAP-MSCHAPv2
RFC-draft-kamath-pppext-eap-mschapv2-02 */
+
+/* OpCodes for MSCHAPv2 */
+#define CHAP_CHALLENGE    1
+#define CHAP_RESPONSE    2
+#define CHAP_SUCCESS    3
+#define CHAP_FAILURE    4

 /* EAP SRP-SHA1 Subtypes */
 #define    EAPSRP_CHALLENGE    1    /* Request 1 - Challenge */
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] Adding EAP-MSCHAPv2 support
  2020-04-03 15:09 [PATCH] Adding EAP-MSCHAPv2 support Eivind Naess
@ 2020-04-03 15:27 ` James Carlson
  2020-04-17 20:50 ` Eivind Naess
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: James Carlson @ 2020-04-03 15:27 UTC (permalink / raw)
  To: linux-ppp

On 2020-04-03 11:09, Eivind Naess wrote:
> Implementation based on the RFC: draft-kamath-pppext-eap-mschapv2-02.
> Adding support for MSCHAPv2 inside the extensible authentication protocol (EAP).
> 
> Author: Thomas Omerzu <thomas@omerzu.de>
> Origin: https://w3logistics.com/blog/archives/438-EAP-MSCHAPv2-for-pppd-2-4-7.html
> Bug: https://github.com/paulusmack/ppp/issues/138
> Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/ppp/+bug/1858349
> Pull Request: https://github.com/paulusmack/ppp/pull/139
> Last-Update: 2020-02-24
> Signed-off-by: Thomas Omerzu <thomas@omerzu.de>.

This all seems ok to me, but I do have one nit: that document referenced
is a long-expired Internet Draft, not an RFC.  As far as I know, there
are no RFCs that cover Microsoft's foray into this area.

-- 
James Carlson         42.703N 71.076W         <carlsonj@workingcode.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Adding EAP-MSCHAPv2 support
  2020-04-03 15:09 [PATCH] Adding EAP-MSCHAPv2 support Eivind Naess
  2020-04-03 15:27 ` James Carlson
@ 2020-04-17 20:50 ` Eivind Naess
  2020-04-17 21:03 ` James Carlson
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Eivind Naess @ 2020-04-17 20:50 UTC (permalink / raw)
  To: linux-ppp

The RFC draft maybe long expired, but Microsoft still has EAP-MSCHAPv2
enabled by default settings. The problem is that if EAP gets
negotiated (because the client supports it), EAP-MSCHAPv2 will
typically be selected. A workaround would be to disable EAP
negotiation on the client side to allow MSCHAPv2 to be selected and
that be only if the Microsoft server is configured to allow that. It's
mostly a compatibility problem for end-users, especially when using
SSTP.

Regards,
- Eivind


On Fri, Apr 3, 2020 at 8:27 AM James Carlson <carlsonj@workingcode.com> wrote:
>
> On 2020-04-03 11:09, Eivind Naess wrote:
> > Implementation based on the RFC: draft-kamath-pppext-eap-mschapv2-02.
> > Adding support for MSCHAPv2 inside the extensible authentication protocol (EAP).
> >
> > Author: Thomas Omerzu <thomas@omerzu.de>
> > Origin: https://w3logistics.com/blog/archives/438-EAP-MSCHAPv2-for-pppd-2-4-7.html
> > Bug: https://github.com/paulusmack/ppp/issues/138
> > Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/ppp/+bug/1858349
> > Pull Request: https://github.com/paulusmack/ppp/pull/139
> > Last-Update: 2020-02-24
> > Signed-off-by: Thomas Omerzu <thomas@omerzu.de>.
>
> This all seems ok to me, but I do have one nit: that document referenced
> is a long-expired Internet Draft, not an RFC.  As far as I know, there
> are no RFCs that cover Microsoft's foray into this area.
>
> --
> James Carlson         42.703N 71.076W         <carlsonj@workingcode.com>



-- 
Cheers,
- Eivind

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Adding EAP-MSCHAPv2 support
  2020-04-03 15:09 [PATCH] Adding EAP-MSCHAPv2 support Eivind Naess
  2020-04-03 15:27 ` James Carlson
  2020-04-17 20:50 ` Eivind Naess
@ 2020-04-17 21:03 ` James Carlson
  2020-04-17 21:13 ` Eivind Naess
  2020-04-17 23:17 ` James Carlson
  4 siblings, 0 replies; 6+ messages in thread
From: James Carlson @ 2020-04-17 21:03 UTC (permalink / raw)
  To: linux-ppp

On 2020-04-17 16:50, Eivind Naess wrote:
> The RFC draft maybe long expired, but Microsoft still has EAP-MSCHAPv2
> enabled by default settings. The problem is that if EAP gets
> negotiated (because the client supports it), EAP-MSCHAPv2 will
> typically be selected. A workaround would be to disable EAP
> negotiation on the client side to allow MSCHAPv2 to be selected and
> that be only if the Microsoft server is configured to allow that. It's
> mostly a compatibility problem for end-users, especially when using
> SSTP.

Oh, I have no doubt that they're using it, and that users will want a
feature like this.  I was only pointing out that the submission comment
was slightly inaccurate.  There is, as far as I know, no published RFC
describing this protocol.

The document you're citing is an Internet-Draft, not an RFC.  There's no
such thing as an "RFC draft."

The difference is important to folks in the IETF (at least).  An RFC
goes through a documented review and acceptance process and never
expires.  An I-D is a temporary document that has no necessary review
whatsoever and expires after a few months.  It's not correct to refer to
an I-D as any sort of RFC.

-- 
James Carlson         42.703N 71.076W         <carlsonj@workingcode.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Adding EAP-MSCHAPv2 support
  2020-04-03 15:09 [PATCH] Adding EAP-MSCHAPv2 support Eivind Naess
                   ` (2 preceding siblings ...)
  2020-04-17 21:03 ` James Carlson
@ 2020-04-17 21:13 ` Eivind Naess
  2020-04-17 23:17 ` James Carlson
  4 siblings, 0 replies; 6+ messages in thread
From: Eivind Naess @ 2020-04-17 21:13 UTC (permalink / raw)
  To: linux-ppp

Ok, thanks for the clarification. Is there anything that needs to be
done then? Can this be applied?

On Fri, Apr 17, 2020 at 2:03 PM James Carlson <carlsonj@workingcode.com> wrote:
>
> On 2020-04-17 16:50, Eivind Naess wrote:
> > The RFC draft maybe long expired, but Microsoft still has EAP-MSCHAPv2
> > enabled by default settings. The problem is that if EAP gets
> > negotiated (because the client supports it), EAP-MSCHAPv2 will
> > typically be selected. A workaround would be to disable EAP
> > negotiation on the client side to allow MSCHAPv2 to be selected and
> > that be only if the Microsoft server is configured to allow that. It's
> > mostly a compatibility problem for end-users, especially when using
> > SSTP.
>
> Oh, I have no doubt that they're using it, and that users will want a
> feature like this.  I was only pointing out that the submission comment
> was slightly inaccurate.  There is, as far as I know, no published RFC
> describing this protocol.
>
> The document you're citing is an Internet-Draft, not an RFC.  There's no
> such thing as an "RFC draft."
>
> The difference is important to folks in the IETF (at least).  An RFC
> goes through a documented review and acceptance process and never
> expires.  An I-D is a temporary document that has no necessary review
> whatsoever and expires after a few months.  It's not correct to refer to
> an I-D as any sort of RFC.
>
> --
> James Carlson         42.703N 71.076W         <carlsonj@workingcode.com>



-- 
Cheers,
- Eivind

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Adding EAP-MSCHAPv2 support
  2020-04-03 15:09 [PATCH] Adding EAP-MSCHAPv2 support Eivind Naess
                   ` (3 preceding siblings ...)
  2020-04-17 21:13 ` Eivind Naess
@ 2020-04-17 23:17 ` James Carlson
  4 siblings, 0 replies; 6+ messages in thread
From: James Carlson @ 2020-04-17 23:17 UTC (permalink / raw)
  To: linux-ppp

I looked over the code, and it looked fine to me.

<carlsonj@workingcode.com>

> On Apr 17, 2020, at 5:13 PM, Eivind Naess <enaess@gmail.com> wrote:
> 
> Ok, thanks for the clarification. Is there anything that needs to be
> done then? Can this be applied?
> 
>> On Fri, Apr 17, 2020 at 2:03 PM James Carlson <carlsonj@workingcode.com> wrote:
>> 
>>> On 2020-04-17 16:50, Eivind Naess wrote:
>>> The RFC draft maybe long expired, but Microsoft still has EAP-MSCHAPv2
>>> enabled by default settings. The problem is that if EAP gets
>>> negotiated (because the client supports it), EAP-MSCHAPv2 will
>>> typically be selected. A workaround would be to disable EAP
>>> negotiation on the client side to allow MSCHAPv2 to be selected and
>>> that be only if the Microsoft server is configured to allow that. It's
>>> mostly a compatibility problem for end-users, especially when using
>>> SSTP.
>> 
>> Oh, I have no doubt that they're using it, and that users will want a
>> feature like this.  I was only pointing out that the submission comment
>> was slightly inaccurate.  There is, as far as I know, no published RFC
>> describing this protocol.
>> 
>> The document you're citing is an Internet-Draft, not an RFC.  There's no
>> such thing as an "RFC draft."
>> 
>> The difference is important to folks in the IETF (at least).  An RFC
>> goes through a documented review and acceptance process and never
>> expires.  An I-D is a temporary document that has no necessary review
>> whatsoever and expires after a few months.  It's not correct to refer to
>> an I-D as any sort of RFC.
>> 
>> --
>> James Carlson         42.703N 71.076W         <carlsonj@workingcode.com>
> 
> 
> 
> -- 
> Cheers,
> - Eivind

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-04-17 23:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-03 15:09 [PATCH] Adding EAP-MSCHAPv2 support Eivind Naess
2020-04-03 15:27 ` James Carlson
2020-04-17 20:50 ` Eivind Naess
2020-04-17 21:03 ` James Carlson
2020-04-17 21:13 ` Eivind Naess
2020-04-17 23:17 ` James Carlson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).