/* packet-radius.c
+ *
* Routines for RADIUS packet disassembly
* Copyright 1999 Johan Feyaerts
*
* RFC 2865, RFC 2866, RFC 2867, RFC 2868, RFC 2869
*
- * $Id: packet-radius.c,v 1.68 2002/08/28 21:00:28 jmayer Exp $
+ * $Id: packet-radius.c,v 1.77 2003/02/13 03:05:14 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
#include "packet-q931.h"
#include "packet-gtp.h"
+#include "prefs.h"
+#include "crypt-md5.h"
static int proto_radius = -1;
static int hf_radius_length = -1;
static int hf_radius_code = -1;
static int hf_radius_id =-1;
+static char *shared_secret = NULL;
+static gpointer authenticator = NULL;
static gint ett_radius = -1;
static gint ett_radius_avp = -1;
dest[totlen+1]=0;
}
+static void
+rddecryptpass(gchar *dest,tvbuff_t *tvb,int offset,int length)
+{
+ md5_state_t md_ctx;
+ md5_byte_t digest[16];
+ guint32 i;
+ guint32 totlen;
+ const guint8 *pd;
+ guchar c;
+
+ if (!shared_secret || !authenticator ) {
+ rdconvertbufftostr(dest,tvb,offset,length);
+ return;
+ }
+
+ dest[0] = '"';
+ dest[1] = '\0';
+ totlen = 1;
+
+ md5_init(&md_ctx);
+ md5_append(&md_ctx,shared_secret,strlen(shared_secret));
+ md5_append(&md_ctx,authenticator,16);
+ md5_finish(&md_ctx,digest);
+
+ pd = tvb_get_ptr(tvb,offset,length);
+ for( i = 0 ; i < 16 && i < (guint32)length ; i++ ) {
+ c = pd[i] ^ digest[i];
+#ifdef _WIN32
+ /*
+ * XXX - "isprint()" can return "true" for non-ASCII characters, but
+ * those don't work with GTK+ on Windows, as GTK+ on Windows assumes
+ * UTF-8 strings. Until we fix up Ethereal to properly handle
+ * non-ASCII characters in all output (both GUI displays and text
+ * printouts) on all platforms including Windows, we work around
+ * the problem by escaping all characters that aren't printable ASCII.
+ */
+ if ( c >= 0x20 && c <= 0x7f) {
+#else
+ if ( isprint(c)) {
+#endif
+ dest[totlen] = c;
+ totlen++;
+ } else {
+ sprintf(&(dest[totlen]),"\\%03o",c);
+ totlen += strlen(&(dest[totlen]));
+ }
+ }
+ while(i<(guint32)length) {
+#ifdef _WIN32
+ /*
+ * XXX - "isprint()" can return "true" for non-ASCII characters, but
+ * those don't work with GTK+ on Windows, as GTK+ on Windows assumes
+ * UTF-8 strings. Until we fix up Ethereal to properly handle
+ * non-ASCII characters in all output (both GUI displays and text
+ * printouts) on all platforms including Windows, we work around
+ * the problem by escaping all characters that aren't printable ASCII.
+ */
+ if ( pd[i] >= 0x20 && pd[i] <= 0x7f) {
+#else
+ if ( isprint(pd[i]) ) {
+#endif
+ dest[totlen] = (gchar)pd[i];
+ totlen++;
+ } else {
+ sprintf(&(dest[totlen]), "\\%03o", pd[i]);
+ totlen=totlen+strlen(&(dest[totlen]));
+ }
+ i++;
+ }
+ dest[totlen]='"';
+ dest[totlen+1] = '\0';
+}
+
static void
rdconvertbufftobinstr(gchar *dest, tvbuff_t *tvb, int offset, int length)
{
*
* At last, forgive me if I've messed up some indentation...
* */
-static gchar *rd_value_to_str_2(gchar *dest, e_avphdr *avph, tvbuff_t *tvb,
+static gchar *rd_value_to_str_2(gchar *dest, const e_avphdr *avph, tvbuff_t *tvb,
int offset, const value_value_string *vvs, proto_tree *tree)
{
int print_type;
gchar *cont;
value_string *valstrarr;
guint32 intval;
+ gint32 timeval;
const guint8 *pd;
guint8 tag;
- char *rtimestamp;
- extern char *tzname[2];
int vsa_length;
int vsa_len;
int vsa_index;
rd_vsa_table *vsa_rvt;
- e_avphdr *vsa_avph;
+ const e_avphdr *vsa_avph;
/* prints the values of the attribute value pairs into a text buffer */
print_type = match_numval(avph->avp_type, vvs);
switch(print_type)
{
case( RADIUS_STRING ):
- rdconvertbufftostr(cont,tvb,offset+2,avph->avp_length-2);
+ if ( avph->avp_type == 2 ) { /* User Password */
+ rddecryptpass(cont,tvb,offset+2,avph->avp_length-2);
+ } else {
+ rdconvertbufftostr(cont,tvb,offset+2,avph->avp_length-2);
+ }
break;
case( RADIUS_BINSTRING ):
rdconvertbufftobinstr(cont,tvb,offset+2,avph->avp_length-2);
vsa_rvt = get_vsa_table(intval);
do
{
- vsa_avph = (e_avphdr*)tvb_get_ptr(tvb, offset+vsa_len,
+ vsa_avph = (const e_avphdr*)tvb_get_ptr(tvb, offset+vsa_len,
avph->avp_length-vsa_len);
if (vsa_rvt)
next_print_type = match_numval(vsa_avph->avp_type,
break;
case( RADIUS_TIMESTAMP ):
- intval=tvb_get_ntohl(tvb,offset+2);
- rtimestamp=ctime((time_t*)&intval);
- rtimestamp[strlen(rtimestamp)-1]=0;
- sprintf(cont,"%d (%s %s)", tvb_get_ntohl(tvb,offset+2), rtimestamp, *tzname);
+ timeval=tvb_get_ntohl(tvb,offset+2);
+ sprintf(cont,"%d (%s)", timeval, abs_time_secs_to_str(timeval));
break;
case( RADIUS_INTEGER4_TAGGED ):
intval = tvb_get_ntohl(tvb,offset+2);
proto_tree_add_uint(radius_tree, hf_radius_length, tvb,
2, 2, rhlength);
+ if ( authenticator ) {
+ g_free(authenticator);
+ }
+ authenticator = g_malloc(AUTHENTICATOR_LENGTH);
+ if ( authenticator ) {
+ memcpy(authenticator,tvb_get_ptr(tvb,4,AUTHENTICATOR_LENGTH),AUTHENTICATOR_LENGTH);
+ }
proto_tree_add_text(radius_tree, tvb, 4,
AUTHENTICATOR_LENGTH,
"Authenticator");
&ett_radius_vsa,
};
+ module_t *radius_module;
+
proto_radius = proto_register_protocol("Radius Protocol", "RADIUS",
"radius");
proto_register_field_array(proto_radius, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+
+ radius_module = prefs_register_protocol(proto_radius,NULL);
+ prefs_register_string_preference(radius_module,"shared_secret","Shared Secret",
+ "Shared secret used to decode User Passwords",
+ &shared_secret);
}
void