From Jouni Malinen: EAP-MD5, EAP-SIM, EAP-PEAP, and EAP-MSCHAPv2

support.

svn path=/trunk/; revision=11309
This commit is contained in:
Guy Harris 2004-07-04 10:26:01 +00:00
parent f4e9c4f31a
commit 466eaf20f0
2 changed files with 287 additions and 8 deletions

View File

@ -1235,7 +1235,8 @@ Jouni Malinen <jkmaline[AT]cc.hut.fi> {
802.11 authentication frame dissection bug fix
Fix offset of challenge element in 802.11 dissector
Show fragmented 802.11 frames as fragments
EAP bug fix for NAK packets.
EAP bug fix for NAK packets
EAP-MD5, EAP-SIM, EAP-PEAP, and EAP-MSCHAPv2 support
802.11g element support
802.11i enhancements
}

View File

@ -2,7 +2,7 @@
* Routines for EAP Extensible Authentication Protocol dissection
* RFC 2284, RFC 3748
*
* $Id: packet-eap.c,v 1.36 2004/06/28 05:41:50 guy Exp $
* $Id: packet-eap.c,v 1.37 2004/07/04 10:26:01 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -70,15 +70,19 @@ References:
#define EAP_TYPE_ID 1
#define EAP_TYPE_NOTIFY 2
#define EAP_TYPE_NAK 3
#define EAP_TYPE_MD5 4
#define EAP_TYPE_TLS 13
#define EAP_TYPE_LEAP 17
#define EAP_TYPE_SIM 18
#define EAP_TYPE_TTLS 21
#define EAP_TYPE_PEAP 25
#define EAP_TYPE_MSCHAPV2 26
static const value_string eap_type_vals[] = {
{EAP_TYPE_ID, "Identity [RFC3748]" },
{EAP_TYPE_NOTIFY,"Notification [RFC3748]" },
{EAP_TYPE_NAK, "Nak (Response only) [RFC3748]" },
{ 4, "MD5-Challenge [RFC3748]" },
{EAP_TYPE_MD5, "MD5-Challenge [RFC3748]" },
{ 5, "One Time Password (OTP) [RFC2289]" },
{ 6, "Generic Token Card [RFC3748]" },
{ 7, "?? RESERVED ?? " }, /* ??? */
@ -92,15 +96,15 @@ static const value_string eap_type_vals[] = {
{ 15, "RSA Security SecurID EAP [Asnes, Liberman]" },
{ 16, "Arcot Systems EAP [Jerdonek]" },
{EAP_TYPE_LEAP,"EAP-Cisco Wireless (LEAP) [Norman]" },
{ 18, "Nokia IP smart card authentication [Haverinen]" },
{EAP_TYPE_SIM, "EAP-SIM Nokia IP smart card authentication [Haverinen]" },
{ 19, "SRP-SHA1 Part 1 [Carlson]" },
{ 20, "SRP-SHA1 Part 2 [Carlson]" },
{EAP_TYPE_TTLS,"EAP-TTLS [Funk]" },
{ 22, "Remote Access Service [Fields]" },
{ 23, "UMTS Authentication and Key Agreement [Haverinen]" },
{ 24, "EAP-3Com Wireless [Young]" },
{ 25, "PEAP [Palekar]" },
{ 26, "MS-EAP-Authentication [Palekar]" },
{EAP_TYPE_PEAP,"PEAP [Palekar]" },
{EAP_TYPE_MSCHAPV2,"MS-EAP-Authentication [Palekar]" },
{ 27, "Mutual Authentication w/Key Exchange (MAKE)[Berrendonner]" },
{ 28, "CRYPTOCard [Webb]" },
{ 29, "EAP-MSCHAP-V2 [Potter]" },
@ -183,18 +187,20 @@ from RFC2716, pg 17
0 1 2 3 4 5 6 7 8
+-+-+-+-+-+-+-+-+
|L M S R R R R R|
|L M S R R Vers |
+-+-+-+-+-+-+-+-+
L = Length included
M = More fragments
S = EAP-TLS start
R = Reserved
Vers = PEAP version (Reserved for TLS and TTLS)
*/
#define EAP_TLS_FLAG_L 0x80 /* Length included */
#define EAP_TLS_FLAG_M 0x40 /* More fragments */
#define EAP_TLS_FLAG_S 0x20 /* EAP-TLS start */
#define EAP_PEAP_FLAG_VERSION 0x07 /* EAP-PEAP version */
/*
* reassembly of EAP-TLS
@ -210,6 +216,7 @@ static int hf_eaptls_fragment_too_long_fragment = -1;
static int hf_eaptls_fragment_error = -1;
static gint ett_eaptls_fragment = -1;
static gint ett_eaptls_fragments = -1;
static gint ett_eap_sim_attr = -1;
static const fragment_items eaptls_frag_items = {
&ett_eaptls_fragment,
@ -259,6 +266,231 @@ eap_init_protocol(void)
G_ALLOC_ONLY);
}
static void
dissect_eap_mschapv2(proto_tree *eap_tree, tvbuff_t *tvb, int offset,
gint size)
{
gint left = size;
gint ms_len;
guint8 value_size;
enum {
MS_CHAPv2_CHALLENGE = 1,
MS_CHAPv2_RESPONSE = 2,
MS_CHAPv2_SUCCESS = 3,
MS_CHAPv2_FAILURE = 4,
MS_CHAPv2_CHANGE_PASSWORD = 5
} opcode;
static const value_string opcodes[] = {
{ MS_CHAPv2_CHALLENGE, "Challenge" },
{ MS_CHAPv2_RESPONSE, "Response" },
{ MS_CHAPv2_SUCCESS, "Success" },
{ MS_CHAPv2_FAILURE, "Failure" },
{ MS_CHAPv2_CHANGE_PASSWORD, "Change-Password" },
{ 0, NULL }
};
/* OpCode (1 byte), MS-CHAPv2-ID (1 byte), MS-Length (2 bytes), Data */
opcode = tvb_get_guint8(tvb, offset);
proto_tree_add_text(eap_tree, tvb, offset, 1,
"OpCode: %d (%s)",
opcode, val_to_str(opcode, opcodes, "Unknown"));
offset++;
left--;
if (left <= 0)
return;
proto_tree_add_text(eap_tree, tvb, offset, 1, "MS-CHAPv2-ID: %d",
tvb_get_guint8(tvb, offset));
offset++;
left--;
if (left <= 0)
return;
ms_len = tvb_get_ntohs(tvb, offset);
proto_tree_add_text(eap_tree, tvb, offset, 2, "MS-Length: %d%s",
ms_len,
ms_len != size ? " (invalid len)" : "");
offset += 2;
left -= 2;
switch (opcode) {
case MS_CHAPv2_CHALLENGE:
if (left <= 0)
break;
value_size = tvb_get_guint8(tvb, offset);
proto_tree_add_text(eap_tree, tvb, offset, 1,
"Value-Size: %d", value_size);
offset++;
left--;
proto_tree_add_text(eap_tree, tvb, offset, value_size,
"Challenge: %s",
tvb_bytes_to_str(tvb, offset, value_size));
offset += value_size;
left -= value_size;
if (left <= 0)
break;
proto_tree_add_text(eap_tree, tvb, offset, left,
"Name: %s",
tvb_format_text(tvb, offset, left));
break;
case MS_CHAPv2_RESPONSE:
if (left <= 0)
break;
value_size = tvb_get_guint8(tvb, offset);
proto_tree_add_text(eap_tree, tvb, offset, 1,
"Value-Size: %d", value_size);
offset++;
left--;
if (value_size == 49) {
proto_tree_add_text(eap_tree, tvb, offset, 16,
"Peer-Challenge: %s",
tvb_bytes_to_str(tvb, offset, 16));
offset += 16;
proto_tree_add_text(eap_tree, tvb, offset, 8,
"Reserved, must be zero: %s",
tvb_bytes_to_str(tvb, offset, 8));
offset += 8;
proto_tree_add_text(eap_tree, tvb, offset, 24,
"NT-Response: %s",
tvb_bytes_to_str(tvb, offset, 24));
offset += 24;
proto_tree_add_text(eap_tree, tvb, offset, 1,
"Flags: %d",
tvb_get_guint8(tvb, offset));
offset++;
left -= value_size;
} else {
proto_tree_add_text(eap_tree, tvb, offset, value_size,
"Response (unknown length): %s",
tvb_bytes_to_str(tvb, offset,
value_size));
offset += value_size;
left -= value_size;
}
if (left <= 0)
break;
proto_tree_add_text(eap_tree, tvb, offset, left,
"Name: %s",
tvb_format_text(tvb, offset, left));
break;
case MS_CHAPv2_SUCCESS:
if (left <= 0)
break;
proto_tree_add_text(eap_tree, tvb, offset, left,
"Message: %s",
tvb_format_text(tvb, offset, left));
break;
case MS_CHAPv2_FAILURE:
if (left <= 0)
break;
proto_tree_add_text(eap_tree, tvb, offset, left,
"Failure Request: %s",
tvb_format_text(tvb, offset, left));
break;
default:
proto_tree_add_text(eap_tree, tvb, offset, left,
"Data (%d byte%s) Value: %s",
left, plurality(left, "", "s"),
tvb_bytes_to_str(tvb, offset, left));
break;
}
}
static void
dissect_eap_sim(proto_tree *eap_tree, tvbuff_t *tvb, int offset, gint size)
{
gint left = size;
enum {
SIM_START = 10,
SIM_CHALLENGE = 11,
SIM_NOTIFICATION = 12,
SIM_RE_AUTHENTICATION = 13,
SIM_CLIENT_ERROR = 14
} subtype;
static const value_string subtypes[] = {
{ SIM_START, "Start" },
{ SIM_CHALLENGE, "Challenge" },
{ SIM_NOTIFICATION, "Notification" },
{ SIM_RE_AUTHENTICATION, "Re-authentication" },
{ SIM_CLIENT_ERROR, "Client-Error" },
{ 0, NULL }
};
static const value_string attributes[] = {
{ 1, "AT_RAND" },
{ 6, "AT_PADDING" },
{ 7, "AT_NONCE_MT" },
{ 10, "AT_PERMANENT_ID_REQ" },
{ 11, "AT_MAC" },
{ 12, "AT_NOTIFICATION" },
{ 13, "AT_ANY_ID_REQ" },
{ 14, "AT_IDENTITY" },
{ 15, "AT_VERSION_LIST" },
{ 16, "AT_SELECTED_VERSION" },
{ 17, "AT_FULLAUTH_ID_REQ" },
{ 18, "AT_COUNTER" },
{ 19, "AT_COUNTER_TOO_SMALL" },
{ 20, "AT_NONCE_S" },
{ 21, "AT_CLIENT_ERROR_CODE" },
{ 129, "AT_IV" },
{ 130, "AT_ENCR_DATA" },
{ 132, "AT_NEXT_PSEUDONYM" },
{ 133, "AT_NEXT_REAUTH_ID" },
{ 0, NULL }
};
subtype = tvb_get_guint8(tvb, offset);
proto_tree_add_text(eap_tree, tvb, offset, 1,
"subtype: %d (%s)",
subtype, val_to_str(subtype, subtypes, "Unknown"));
offset++;
left--;
if (left < 2)
return;
proto_tree_add_text(eap_tree, tvb, offset, 2, "Reserved: %d",
tvb_get_ntohs(tvb, offset));
offset += 2;
left -= 2;
/* Rest of EAP-SIM data is in Type-Len-Value format. */
while (left >= 2) {
guint8 type, length;
proto_item *pi;
proto_tree *attr_tree;
int aoffset;
gint aleft;
aoffset = offset;
type = tvb_get_guint8(tvb, aoffset);
length = tvb_get_guint8(tvb, aoffset + 1);
aleft = 4 * length;
pi = proto_tree_add_text(eap_tree, tvb, aoffset, aleft,
"Attribute: %s",
val_to_str(type, attributes,
"Unknown %u"));
attr_tree = proto_item_add_subtree(pi, ett_eap_sim_attr);
proto_tree_add_text(attr_tree, tvb, aoffset, 1,
"Type: %u", type);
aoffset++;
aleft--;
if (aleft <= 0)
break;
proto_tree_add_text(attr_tree, tvb, aoffset, 1,
"Length: %d (%d bytes)",
length, 4 * length);
aoffset++;
aleft--;
proto_tree_add_text(attr_tree, tvb, aoffset, aleft,
"Value: %s",
tvb_bytes_to_str(tvb, aoffset, aleft));
offset += 4 * length;
left -= 4 * length;
}
}
static int
dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
gboolean fragmented)
@ -436,9 +668,34 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
offset, 1, FALSE);
}
break;
/*********************************************************************
**********************************************************************/
case EAP_TYPE_MD5:
if (tree) {
guint8 value_size = tvb_get_guint8(tvb, offset);
gint extra_len = size - 1 - value_size;
proto_tree_add_text(eap_tree, tvb, offset, 1, "Value-Size: %d%s",
value_size,
value_size > size - 1 ? " (overflow)": "");
if (value_size > size - 1)
value_size = size - 1;
offset++;
proto_tree_add_text(eap_tree, tvb, offset, value_size,
"Value: %s",
tvb_bytes_to_str(tvb, offset, value_size));
offset += value_size;
if (extra_len > 0) {
proto_tree_add_text(eap_tree, tvb, offset, extra_len,
"Extra data (%d byte%s): %s", extra_len,
plurality(extra_len, "", "s"),
tvb_bytes_to_str(tvb, offset, extra_len));
}
}
break;
/*********************************************************************
EAP-TLS
**********************************************************************/
case EAP_TYPE_PEAP:
case EAP_TYPE_TTLS:
case EAP_TYPE_TLS:
{
@ -454,12 +711,18 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
has_length = test_flag(flags,EAP_TLS_FLAG_L);
/* Flags field, 1 byte */
if (tree)
if (tree) {
proto_tree_add_text(eap_tree, tvb, offset, 1, "Flags(0x%X): %s%s%s",
flags,
has_length ? "Length ":"",
more_fragments ? "More " :"",
test_flag(flags,EAP_TLS_FLAG_S) ? "Start " :"");
if (eap_type == EAP_TYPE_PEAP) {
proto_tree_add_text(eap_tree, tvb, offset, 1,
"PEAP version %d",
flags & EAP_PEAP_FLAG_VERSION);
}
}
size--;
offset++;
@ -775,6 +1038,20 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
}
break; /* EAP_TYPE_LEAP */
/*********************************************************************
EAP-MSCHAPv2 - draft-kamath-pppext-eap-mschapv2-00.txt
**********************************************************************/
case EAP_TYPE_MSCHAPV2:
if (tree)
dissect_eap_mschapv2(eap_tree, tvb, offset, size);
break; /* EAP_TYPE_MSCHAPV2 */
/*********************************************************************
EAP-SIM - draft-haverinen-pppext-eap-sim-12.txt
**********************************************************************/
case EAP_TYPE_SIM:
if (tree)
dissect_eap_sim(eap_tree, tvb, offset, size);
break; /* EAP_TYPE_SIM */
/*********************************************************************
**********************************************************************/
default:
@ -860,6 +1137,7 @@ proto_register_eap(void)
&ett_eap,
&ett_eaptls_fragment,
&ett_eaptls_fragments,
&ett_eap_sim_attr,
};
proto_eap = proto_register_protocol("Extensible Authentication Protocol",