Get rid of the MS_ChapResponse and MS_Chap2Response structures.
authorPaul Mackerras <paulus@samba.org>
Mon, 15 Nov 2004 22:13:26 +0000 (22:13 +0000)
committerPaul Mackerras <paulus@samba.org>
Mon, 15 Nov 2004 22:13:26 +0000 (22:13 +0000)
Using a struct to represent an on-the-wire format is basically
broken, since the compiler can add padding between members or
assume alignment for the struct.  Instead we just use arrays
of unsigned char and define offsets in the arrays for the various
fields.

pppd/chap_ms.c
pppd/chap_ms.h
pppd/plugins/radius/radius.c
pppd/plugins/winbind.c

index 9a87122f3451e6de051cbe0f3e0818b502b4cbd7..05c6225a720612fe01afc43c917c59dd58a37ea3 100644 (file)
@@ -74,7 +74,7 @@
  *
  */
 
-#define RCSID  "$Id: chap_ms.c,v 1.33 2004/11/12 09:57:43 paulus Exp $"
+#define RCSID  "$Id: chap_ms.c,v 1.34 2004/11/15 22:13:26 paulus Exp $"
 
 #ifdef CHAPMS
 
@@ -101,13 +101,13 @@ static void       ascii2unicode __P((char[], int, u_char[]));
 static void    NTPasswordHash __P((char *, int, u_char[MD4_SIGNATURE_SIZE]));
 static void    ChallengeResponse __P((u_char *, u_char *, u_char[24]));
 static void    ChapMS_NT __P((u_char *, char *, int, u_char[24]));
-static void    ChapMS2_NT __P((char *, u_char[16], char *, char *, int,
+static void    ChapMS2_NT __P((u_char *, u_char[16], char *, char *, int,
                                u_char[24]));
 static void    GenerateAuthenticatorResponsePlain
                        __P((char*, int, u_char[24], u_char[16], u_char *,
                             char *, u_char[41]));
 #ifdef MSLANMAN
-static void    ChapMS_LANMan __P((u_char *, char *, int, MS_ChapResponse *));
+static void    ChapMS_LANMan __P((u_char *, char *, int, u_char *));
 #endif
 
 #ifdef MPPE
@@ -191,8 +191,7 @@ chapms_verify_response(int id, char *name,
                       unsigned char *challenge, unsigned char *response,
                       char *message, int message_space)
 {
-       MS_ChapResponse *rmd;
-       MS_ChapResponse md;
+       unsigned char md[MS_CHAP_RESPONSE_LEN];
        int diff;
        int challenge_len, response_len;
 
@@ -201,10 +200,8 @@ chapms_verify_response(int id, char *name,
        if (response_len != MS_CHAP_RESPONSE_LEN)
                goto bad;
 
-       rmd = (MS_ChapResponse *) response;
-
 #ifndef MSLANMAN
-       if (!rmd->UseNT[0]) {
+       if (!response[MS_CHAP_USENT]) {
                /* Should really propagate this into the error packet. */
                notice("Peer request for LANMAN auth not supported");
                goto bad;
@@ -212,16 +209,17 @@ chapms_verify_response(int id, char *name,
 #endif
 
        /* Generate the expected response. */
-       ChapMS(challenge, (char *)secret, secret_len, &md);
+       ChapMS(challenge, (char *)secret, secret_len, md);
 
 #ifdef MSLANMAN
        /* Determine which part of response to verify against */
-       if (!rmd->UseNT[0])
-               diff = memcmp(&rmd->LANManResp, &md.LANManResp,
-                             sizeof(md.LANManResp));
+       if (!response[MS_CHAP_USENT])
+               diff = memcmp(&response[MS_CHAP_LANMANRESP],
+                             &md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN);
        else
 #endif
-               diff = memcmp(&rmd->NTResp, &md.NTResp, sizeof(md.NTResp));
+               diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP],
+                             MS_CHAP_NTRESP_LEN);
 
        if (diff == 0) {
                slprintf(message, message_space, "Access granted");
@@ -241,8 +239,7 @@ chapms2_verify_response(int id, char *name,
                        unsigned char *challenge, unsigned char *response,
                        char *message, int message_space)
 {
-       MS_Chap2Response *rmd;
-       MS_Chap2Response md;
+       unsigned char md[MS_CHAP2_RESPONSE_LEN];
        char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
        int challenge_len, response_len;
 
@@ -251,11 +248,9 @@ chapms2_verify_response(int id, char *name,
        if (response_len != MS_CHAP2_RESPONSE_LEN)
                goto bad;       /* not even the right length */
 
-       rmd = (MS_Chap2Response *) response;
-
        /* Generate the expected response and our mutual auth. */
-       ChapMS2(challenge, rmd->PeerChallenge, name,
-               (char *)secret, secret_len, &md,
+       ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name,
+               (char *)secret, secret_len, md,
                (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
 
        /* compare MDs and send the appropriate status */
@@ -278,8 +273,9 @@ chapms2_verify_response(int id, char *name,
         * Special thanks to Alex Swiridov <say@real.kharkov.ua> for
         * help debugging this.
         */
-       if (memcmp(md.NTResp, rmd->NTResp, sizeof(md.NTResp)) == 0) {
-               if (rmd->Flags[0])
+       if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP],
+                  MS_CHAP2_NTRESP_LEN) == 0) {
+               if (response[MS_CHAP2_FLAGS])
                        slprintf(message, message_space, "S=%s", saresponse);
                else
                        slprintf(message, message_space, "S=%s M=%s",
@@ -321,7 +317,7 @@ chapms_make_response(unsigned char *response, int id, char *our_name,
 {
        challenge++;    /* skip length, should be 8 */
        *response++ = MS_CHAP_RESPONSE_LEN;
-       ChapMS(challenge, secret, secret_len, (MS_ChapResponse *) response);
+       ChapMS(challenge, secret, secret_len, response);
 }
 
 static void
@@ -337,8 +333,7 @@ chapms2_make_response(unsigned char *response, int id, char *our_name,
 #else
                NULL,
 #endif
-               our_name, secret, secret_len,
-               (MS_Chap2Response *) response, private,
+               our_name, secret, secret_len, response, private,
                MS_CHAP2_AUTHENTICATEE);
 }
 
@@ -543,15 +538,14 @@ ChapMS_NT(u_char *rchallenge, char *secret, int secret_len,
 }
 
 static void
-ChapMS2_NT(char *rchallenge, u_char PeerChallenge[16], char *username,
+ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username,
           char *secret, int secret_len, u_char NTResponse[24])
 {
     u_char     unicodePassword[MAX_NT_PASSWORD * 2];
     u_char     PasswordHash[MD4_SIGNATURE_SIZE];
     u_char     Challenge[8];
 
-    ChallengeHash(PeerChallenge, (unsigned char *)rchallenge, username,
-                 Challenge);
+    ChallengeHash(PeerChallenge, rchallenge, username, Challenge);
 
     /* Hash the Unicode version of the secret (== password). */
     ascii2unicode(secret, secret_len, unicodePassword);
@@ -565,7 +559,7 @@ static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
 
 static void
 ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len,
-             MS_ChapResponse *response)
+             unsigned char *response)
 {
     int                        i;
     u_char             UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
@@ -579,7 +573,7 @@ ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len,
     DesEncrypt( StdText, PasswordHash + 0 );
     (void) DesSetkey(UcasePassword + 7);
     DesEncrypt( StdText, PasswordHash + 8 );
-    ChallengeResponse(rchallenge, PasswordHash, response->LANManResp);
+    ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]);
 }
 #endif
 
@@ -812,19 +806,19 @@ SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer)
 
 void
 ChapMS(u_char *rchallenge, char *secret, int secret_len,
-       MS_ChapResponse *response)
+       unsigned char *response)
 {
-    BZERO(response, sizeof(*response));
+    BZERO(response, MS_CHAP_RESPONSE_LEN);
 
-    ChapMS_NT(rchallenge, secret, secret_len, response->NTResp);
+    ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]);
 
 #ifdef MSLANMAN
-    ChapMS_LANMan(rchallenge, secret, secret_len, response);
+    ChapMS_LANMan(rchallenge, secret, secret_len, &response);
 
     /* preferred method is set by option  */
-    response->UseNT[0] = !ms_lanman;
+    response[MS_CHAP_USENT] = !ms_lanman;
 #else
-    response->UseNT[0] = 1;
+    response[MS_CHAP_USENT] = 1;
 #endif
 
 #ifdef MPPE
@@ -834,45 +828,47 @@ ChapMS(u_char *rchallenge, char *secret, int secret_len,
 
 
 /*
- * If PeerChallenge is NULL, one is generated and response->PeerChallenge
- * is filled in.  Call this way when generating a response.
- * If PeerChallenge is supplied, it is copied into response->PeerChallenge.
+ * If PeerChallenge is NULL, one is generated and the PeerChallenge
+ * field of response is filled in.  Call this way when generating a response.
+ * If PeerChallenge is supplied, it is copied into the PeerChallenge field.
  * Call this way when verifying a response (or debugging).
- * Do not call with PeerChallenge = response->PeerChallenge.
+ * Do not call with PeerChallenge = response.
  *
- * response->PeerChallenge is then used for calculation of the
+ * The PeerChallenge field of response is then used for calculation of the
  * Authenticator Response.
  */
 void
 ChapMS2(u_char *rchallenge, u_char *PeerChallenge,
-       char *user, char *secret, int secret_len, MS_Chap2Response *response,
+       char *user, char *secret, int secret_len, unsigned char *response,
        u_char authResponse[], int authenticator)
 {
     /* ARGSUSED */
-    u_char *p = response->PeerChallenge;
+    u_char *p = &response[MS_CHAP2_PEER_CHALLENGE];
     int i;
 
     BZERO(response, sizeof(*response));
 
     /* Generate the Peer-Challenge if requested, or copy it if supplied. */
     if (!PeerChallenge)
-       for (i = 0; i < sizeof(response->PeerChallenge); i++)
+       for (i = 0; i < MS_CHAP2_PEER_CHAL_LEN; i++)
            *p++ = (u_char) (drand48() * 0xff);
     else
-       BCOPY(PeerChallenge, response->PeerChallenge,
-             sizeof(response->PeerChallenge));
+       BCOPY(PeerChallenge, &response[MS_CHAP2_PEER_CHALLENGE],
+             MS_CHAP2_PEER_CHAL_LEN);
 
     /* Generate the NT-Response */
-    ChapMS2_NT((char *)rchallenge, response->PeerChallenge, user,
-              secret, secret_len, response->NTResp);
+    ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user,
+              secret, secret_len, &response[MS_CHAP2_NTRESP]);
 
     /* Generate the Authenticator Response. */
-    GenerateAuthenticatorResponsePlain(secret, secret_len, response->NTResp,
-                                      response->PeerChallenge, rchallenge,
-                                      user, authResponse);
+    GenerateAuthenticatorResponsePlain(secret, secret_len,
+                                      &response[MS_CHAP2_NTRESP],
+                                      &response[MS_CHAP2_PEER_CHALLENGE],
+                                      rchallenge, user, authResponse);
 
 #ifdef MPPE
-    SetMasterKeys(secret, secret_len, response->NTResp, authenticator);
+    SetMasterKeys(secret, secret_len,
+                 &response[MS_CHAP2_NTRESP], authenticator);
 #endif
 }
 
index 168c0be2f4748268bd7870516858b5ab2e706dd6..57e2929373695159be2baa1622f1675b75081fbf 100644 (file)
@@ -27,7 +27,7 @@
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $Id: chap_ms.h,v 1.12 2004/11/09 22:49:05 paulus Exp $
+ * $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $
  */
 
 #ifndef __CHAPMS_INCLUDE__
 #define MS_CHAP_ERROR_CHANGING_PASSWORD                709
 
 /*
- * Apparently gcc on ARM gives all structures 4-byte alignment
- * by default.  This tells gcc that these structures may be
- * unaligned and may not have extra padding inside them.
+ * Offsets within the response field for MS-CHAP
  */
-#ifdef __GNUC__
-#define PACKED __attribute__((__packed__))
-#else
-#define PACKED
-#endif
-
-/*
- * Use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),
- * in case this struct gets padded.
- */
-typedef struct {
-    u_char LANManResp[24];
-    u_char NTResp[24];
-    u_char UseNT[1];           /* If 1, ignore the LANMan response field */
-} MS_ChapResponse PACKED;
+#define MS_CHAP_LANMANRESP     0
+#define MS_CHAP_LANMANRESP_LEN 24
+#define MS_CHAP_NTRESP         24
+#define MS_CHAP_NTRESP_LEN     24
+#define MS_CHAP_USENT          48
 
 /*
- * Use MS_CHAP2_RESPONSE_LEN, rather than sizeof(MS_Chap2Response),
- * in case this struct gets padded.
+ * Offsets within the response field for MS-CHAP2
  */
-typedef struct {
-    u_char PeerChallenge[16];
-    u_char Reserved[8];                /* Must be zero */
-    u_char NTResp[24];
-    u_char Flags[1];           /* Must be zero */
-} MS_Chap2Response PACKED;
+#define MS_CHAP2_PEER_CHALLENGE        0
+#define MS_CHAP2_PEER_CHAL_LEN 16
+#define MS_CHAP2_RESERVED_LEN  8
+#define MS_CHAP2_NTRESP                24
+#define MS_CHAP2_NTRESP_LEN    24
+#define MS_CHAP2_FLAGS         48
 
 #ifdef MPPE
 #include <net/ppp-comp.h>      /* MPPE_MAX_KEY_LEN */
@@ -100,9 +87,9 @@ extern void set_mppe_enc_types(int, int);
 #define MS_CHAP2_AUTHENTICATEE 0
 #define MS_CHAP2_AUTHENTICATOR 1
 
-void ChapMS __P((u_char *, char *, int, MS_ChapResponse *));
+void ChapMS __P((u_char *, char *, int, u_char *));
 void ChapMS2 __P((u_char *, u_char *, char *, char *, int,
-                 MS_Chap2Response *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int));
+                 u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int));
 #ifdef MPPE
 void mppe_set_keys __P((u_char *, u_char[MD4_SIGNATURE_SIZE]));
 void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
index 932c89aaec389ec5577d5c01c5afd186321d30e6..c4ef0a5cae4a14df4695e9c5c5b4220fc22869b0 100644 (file)
@@ -24,7 +24,7 @@
 *
 ***********************************************************************/
 static char const RCSID[] =
-"$Id: radius.c,v 1.28 2004/11/14 10:27:57 paulus Exp $";
+"$Id: radius.c,v 1.29 2004/11/15 22:13:26 paulus Exp $";
 
 #include "pppd.h"
 #include "chap-new.h"
@@ -410,18 +410,14 @@ radius_chap_verify(char *user, char *ourname, int id,
     case CHAP_MICROSOFT:
     {
        /* MS-CHAP-Challenge and MS-CHAP-Response */
-       MS_ChapResponse *rmd = (MS_ChapResponse *) response;
        u_char *p = cpassword;
 
        if (response_len != MS_CHAP_RESPONSE_LEN)
            return 0;
        *p++ = id;
        /* The idiots use a different field order in RADIUS than PPP */
-       memcpy(p, rmd->UseNT, sizeof(rmd->UseNT));
-       p += sizeof(rmd->UseNT);
-       memcpy(p, rmd->LANManResp, sizeof(rmd->LANManResp));
-       p += sizeof(rmd->LANManResp);
-       memcpy(p, rmd->NTResp, sizeof(rmd->NTResp));
+       *p++ = response[MS_CHAP_USENT];
+       memcpy(p, response, MS_CHAP_LANMANRESP_LEN + MS_CHAP_NTRESP_LEN);
 
        rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE,
                      challenge, challenge_len, VENDOR_MICROSOFT);
@@ -433,20 +429,15 @@ radius_chap_verify(char *user, char *ourname, int id,
     case CHAP_MICROSOFT_V2:
     {
        /* MS-CHAP-Challenge and MS-CHAP2-Response */
-       MS_Chap2Response *rmd = (MS_Chap2Response *) response;
        u_char *p = cpassword;
 
        if (response_len != MS_CHAP2_RESPONSE_LEN)
            return 0;
        *p++ = id;
        /* The idiots use a different field order in RADIUS than PPP */
-       memcpy(p, rmd->Flags, sizeof(rmd->Flags));
-       p += sizeof(rmd->Flags);
-       memcpy(p, rmd->PeerChallenge, sizeof(rmd->PeerChallenge));
-       p += sizeof(rmd->PeerChallenge);
-       memcpy(p, rmd->Reserved, sizeof(rmd->Reserved));
-       p += sizeof(rmd->Reserved);
-       memcpy(p, rmd->NTResp, sizeof(rmd->NTResp));
+       *p++ = response[MS_CHAP2_FLAGS];
+       memcpy(p, response, (MS_CHAP2_PEER_CHAL_LEN + MS_CHAP2_RESERVED_LEN
+                            + MS_CHAP2_NTRESP_LEN));
 
        rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE,
                      challenge, challenge_len, VENDOR_MICROSOFT);
index 3041f17af8f496a352627f6d28931a434623ec86..2bcb83dfff614eb4b0e850598455a090bfdfcfdc 100644 (file)
@@ -557,20 +557,19 @@ winbind_chap_verify(char *user, char *ourname, int id,
                u_char *lm_response = NULL;
                int nt_response_size = 0;
                int lm_response_size = 0;
-               MS_ChapResponse *rmd = (MS_ChapResponse *) response;
                u_char session_key[16];
                
                if (response_len != MS_CHAP_RESPONSE_LEN)
                        break;                  /* not even the right length */
                
                /* Determine which part of response to verify against */
-               if (rmd->UseNT[0]) {
-                       nt_response = rmd->NTResp;
-                       nt_response_size = sizeof(rmd->NTResp);
+               if (response[MS_CHAP_USENT]) {
+                       nt_response = &response[MS_CHAP_NTRESP];
+                       nt_response_size = MS_CHAP_NTRESP_LEN;
                } else {
 #ifdef MSLANMAN
-                       lm_response = rmd->LANManResp;
-                       lm_response_size = sizeof(rmd->LANManResp);
+                       lm_response = &response[MS_CHAP_LANMANRESP];
+                       lm_response_size = MS_CHAP_LANMANRESP_LEN;
 #else
                        /* Should really propagate this into the error packet. */
                        notice("Peer request for LANMAN auth not supported");
@@ -584,12 +583,9 @@ winbind_chap_verify(char *user, char *ourname, int id,
                                  domain,
                                  NULL,
                                  NULL,
-                                 challenge,
-                                 challenge_len,
-                                 lm_response,
-                                 lm_response ? lm_response_size: 0,
-                                 nt_response,
-                                 nt_response ? nt_response_size: 0,
+                                 challenge, challenge_len,
+                                 lm_response, lm_response_size,
+                                 nt_response, nt_response_size,
                                  session_key,
                                  &error_string) == AUTHENTICATED) {
                        mppe_set_keys(challenge, session_key);
@@ -610,7 +606,6 @@ winbind_chap_verify(char *user, char *ourname, int id,
        
        case CHAP_MICROSOFT_V2:
        {
-               MS_Chap2Response *rmd = (MS_Chap2Response *) response;
                u_char Challenge[8];
                u_char session_key[MD4_SIGNATURE_SIZE];
                char *error_string = NULL;
@@ -618,7 +613,8 @@ winbind_chap_verify(char *user, char *ourname, int id,
                if (response_len != MS_CHAP2_RESPONSE_LEN)
                        break;                  /* not even the right length */
                
-               ChallengeHash(rmd->PeerChallenge, challenge, user, Challenge);
+               ChallengeHash(&response[MS_CHAP2_PEER_CHALLENGE], challenge,
+                             user, Challenge);
                
                /* ship off to winbind, and check */
                
@@ -626,22 +622,20 @@ winbind_chap_verify(char *user, char *ourname, int id,
                                  domain, 
                                  NULL,
                                  NULL,
-                                 Challenge,
-                                 8,
-                                 NULL, 
-                                 0,
-                                 rmd->NTResp,
-                                 sizeof(rmd->NTResp),
-                                 
+                                 Challenge, 8,
+                                 NULL, 0,
+                                 &response[MS_CHAP2_NTRESP],
+                                 MS_CHAP2_NTRESP_LEN,
                                  session_key,
                                  &error_string) == AUTHENTICATED) {
                        
                        GenerateAuthenticatorResponse(session_key,
-                                                     rmd->NTResp, rmd->PeerChallenge,
-                                                     challenge, user,
-                                                     saresponse);
-                       mppe_set_keys2(session_key, rmd->NTResp, MS_CHAP2_AUTHENTICATOR);
-                       if (rmd->Flags[0]) {
+                               &response[MS_CHAP2_NTRESP],
+                               &response[MS_CHAP2_PEER_CHALLENGE],
+                               challenge, user, saresponse);
+                       mppe_set_keys2(session_key, &response[MS_CHAP2_NTRESP],
+                                      MS_CHAP2_AUTHENTICATOR);
+                       if (response[MS_CHAP2_FLAGS]) {
                                slprintf(message, message_space, "S=%s", saresponse);
                        } else {
                                slprintf(message, message_space, "S=%s M=%s",