From: Paul Mackerras Date: Mon, 15 Nov 2004 22:13:26 +0000 (+0000) Subject: Get rid of the MS_ChapResponse and MS_Chap2Response structures. X-Git-Tag: ppp-2.4.7~165 X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=6bd2208f408588cab66a4da26ebee1159840db81 Get rid of the MS_ChapResponse and MS_Chap2Response structures. 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. --- diff --git a/pppd/chap_ms.c b/pppd/chap_ms.c index 9a87122..05c6225 100644 --- a/pppd/chap_ms.c +++ b/pppd/chap_ms.c @@ -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 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 } diff --git a/pppd/chap_ms.h b/pppd/chap_ms.h index 168c0be..57e2929 100644 --- a/pppd/chap_ms.h +++ b/pppd/chap_ms.h @@ -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__ @@ -49,36 +49,23 @@ #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 /* 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], diff --git a/pppd/plugins/radius/radius.c b/pppd/plugins/radius/radius.c index 932c89a..c4ef0a5 100644 --- a/pppd/plugins/radius/radius.c +++ b/pppd/plugins/radius/radius.c @@ -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); diff --git a/pppd/plugins/winbind.c b/pppd/plugins/winbind.c index 3041f17..2bcb83d 100644 --- a/pppd/plugins/winbind.c +++ b/pppd/plugins/winbind.c @@ -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",