* Add a category param to the uat.

* UATify SNMP Users


svn path=/trunk/; revision=20736
This commit is contained in:
Luis Ontanon 2007-02-07 14:54:35 +00:00
parent 5ec87e6eef
commit 2006fac500
13 changed files with 419 additions and 592 deletions

View File

@ -61,6 +61,7 @@
#include <epan/sminmpec.h>
#include <epan/emem.h>
#include <epan/next_tvb.h>
#include <epan/uat.h>
#include "packet-ipx.h"
#include "packet-hpext.h"
@ -147,11 +148,44 @@ static const gchar *mib_modules = DEF_MIB_MODULES;
static gboolean display_oid = TRUE;
static gboolean snmp_var_in_tree = TRUE;
static const gchar* ue_assocs_filename = "";
static const gchar* ue_assocs_filename_loaded = "";
static snmp_ue_assoc_t* ue_assocs = NULL;
static gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, guint8**, guint*, gchar const**);
static gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p, guint8**, guint*, gchar const**);
static tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t*, tvbuff_t*, gchar const**);
static tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t*, tvbuff_t*, gchar const**);
static void snmp_usm_password_to_key_md5(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key);
static void snmp_usm_password_to_key_sha1(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key);
static snmp_usm_auth_model_t model_md5 = {snmp_usm_password_to_key_md5, snmp_usm_auth_md5, 16};
static snmp_usm_auth_model_t model_sha1 = {snmp_usm_password_to_key_sha1, snmp_usm_auth_sha1, 20};
static value_string auth_types[] = {
{0,"MD5"},
{1,"SHA1"},
{0,NULL}
};
static snmp_usm_auth_model_t* auth_models[] = {&model_md5,&model_sha1};
static value_string priv_types[] = {
{0,"DES"},
{1,"AES"},
{0,NULL}
};
static snmp_usm_decoder_t priv_protos[] = {snmp_usm_priv_des, snmp_usm_priv_aes};
static snmp_ue_assoc_t* ueas = NULL;
static guint num_ueas = 0;
static uat_t* assocs_uat = NULL;
static snmp_ue_assoc_t* localized_ues = NULL;
static snmp_ue_assoc_t* unlocalized_ues = NULL;
/****/
static snmp_usm_params_t usm_p = {FALSE,FALSE,0,0,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,FALSE};
@ -1057,52 +1091,89 @@ snmp_variable_decode(tvbuff_t *tvb, proto_tree *snmp_tree, packet_info *pinfo,tv
static void set_ue_keys(snmp_ue_assoc_t* n ) {
guint key_size = n->user.authModel->key_size;
n->user.authKey.data = se_alloc(key_size);
n->user.authKey.len = key_size;
n->user.authModel->pass2key(n->user.authPassword.data,
n->user.authPassword.len,
n->engine.data,
n->engine.len,
n->user.authKey.data);
n->user.privKey.data = se_alloc(key_size);
n->user.privKey.len = key_size;
n->user.authModel->pass2key(n->user.privPassword.data,
n->user.privPassword.len,
n->engine.data,
n->engine.len,
n->user.privKey.data);
}
static snmp_ue_assoc_t* ue_se_dup(snmp_ue_assoc_t* o) {
snmp_ue_assoc_t* d = se_memdup(o,sizeof(snmp_ue_assoc_t));
d->user.authModel = o->user.authModel;
d->user.privProtocol = o->user.privProtocol;
d->user.userName.data = se_memdup(o->user.userName.data,o->user.userName.len);
d->user.userName.len = o->user.userName.len;
d->user.authPassword.data = o->user.authPassword.data ? se_memdup(o->user.authPassword.data,o->user.authPassword.len) : NULL;
d->user.authPassword.len = o->user.authPassword.len;
d->user.privPassword.data = o->user.privPassword.data ? se_memdup(o->user.privPassword.data,o->user.privPassword.len) : NULL;
d->user.privPassword.len = o->user.privPassword.len;
d->engine.len = o->engine.len;
if (d->engine.len) {
d->engine.data = se_memdup(o->engine.data,o->engine.len);
set_ue_keys(d);
}
return d;
}
#define CACHE_INSERT(c,a) if (c) { snmp_ue_assoc_t* t = c; c = a; c->next = t; } else { c = a; a->next = NULL; }
static void renew_ue_cache(void) {
if (ue_assocs) {
static snmp_ue_assoc_t* a;
if (num_ueas) {
guint i;
localized_ues = NULL;
unlocalized_ues = NULL;
for(a = ue_assocs; a->user.userName.data; a++) {
if (a->engine.data) {
for(i = 0; i < num_ueas; i++) {
snmp_ue_assoc_t* a = ue_se_dup(&(ueas[i]));
if (a->engine.len) {
CACHE_INSERT(localized_ues,a);
} else {
CACHE_INSERT(unlocalized_ues,a);
}
}
} else {
localized_ues = NULL;
unlocalized_ues = NULL;
}
}
static snmp_ue_assoc_t* localize_ue( snmp_ue_assoc_t* o, const guint8* engine, guint engine_len ) {
snmp_ue_assoc_t* n = se_memdup(o,sizeof(snmp_ue_assoc_t));
guint key_size = n->user.authModel->key_size;
n->engine.data = se_memdup(engine,engine_len);
n->engine.len = engine_len;
n->user.authKey.data = se_alloc(key_size);
n->user.authKey.len = key_size;
n->user.authModel->pass2key(n->user.authPassword.data,
n->user.authPassword.len,
engine,
engine_len,
n->user.authKey.data);
n->user.privKey.data = se_alloc(key_size);
n->user.privKey.len = key_size;
n->user.authModel->pass2key(n->user.privPassword.data,
n->user.privPassword.len,
engine,
engine_len,
n->user.privKey.data);
set_ue_keys(n);
return n;
}
@ -1149,23 +1220,7 @@ static snmp_ue_assoc_t* get_user_assoc(tvbuff_t* engine_tvb, tvbuff_t* user_tvb)
return NULL;
}
static void destroy_ue_assocs(snmp_ue_assoc_t* assocs) {
if (assocs) {
snmp_ue_assoc_t* a;
for(a = assocs; a->user.userName.data; a++) {
g_free(a->user.userName.data);
if (a->user.authKey.data) g_free(a->user.authKey.data);
if (a->user.privKey.data) g_free(a->user.privKey.data);
if (a->engine.data) g_free(a->engine.data);
}
g_free(ue_assocs);
}
}
gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, guint8** calc_auth_p, guint* calc_auth_len_p, gchar const** error) {
static gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, guint8** calc_auth_p, guint* calc_auth_len_p, gchar const** error) {
guint msg_len;
guint8* msg;
guint auth_len;
@ -1221,7 +1276,7 @@ gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, guint8** calc_auth_p, guint* ca
}
gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p _U_, guint8** calc_auth_p, guint* calc_auth_len_p, gchar const** error _U_) {
static gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p _U_, guint8** calc_auth_p, guint* calc_auth_len_p, gchar const** error _U_) {
guint msg_len;
guint8* msg;
guint auth_len;
@ -1276,7 +1331,7 @@ gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p _U_, guint8** calc_auth_p, guin
return ( memcmp(auth,calc_auth,12) != 0 ) ? FALSE : TRUE;
}
tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error _U_) {
static tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error _U_) {
#ifdef HAVE_LIBGCRYPT
gcry_error_t err;
gcry_cipher_hd_t hd = NULL;
@ -1348,7 +1403,7 @@ on_gcry_error:
#endif
}
tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error _U_) {
static tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error _U_) {
#ifdef HAVE_LIBGCRYPT
gcry_error_t err;
gcry_cipher_hd_t hd = NULL;
@ -1716,7 +1771,7 @@ dissect_smux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
MD5 Password to Key Algorithm
from RFC 3414 A.2.1
*/
void snmp_usm_password_to_key_md5(const guint8 *password,
static void snmp_usm_password_to_key_md5(const guint8 *password,
guint passwordlen,
const guint8 *engineID,
guint engineLength,
@ -1768,7 +1823,7 @@ void snmp_usm_password_to_key_md5(const guint8 *password,
SHA1 Password to Key Algorithm COPIED from RFC 3414 A.2.2
*/
void snmp_usm_password_to_key_sha1(const guint8 *password,
static void snmp_usm_password_to_key_sha1(const guint8 *password,
guint passwordlen,
const guint8 *engineID,
guint engineLength,
@ -1869,19 +1924,76 @@ process_prefs(void)
mibs_loaded = TRUE;
#endif /* HAVE_NET_SNMP */
if ( g_str_equal(ue_assocs_filename_loaded,ue_assocs_filename) ) return;
ue_assocs_filename_loaded = ue_assocs_filename;
if (ue_assocs) destroy_ue_assocs(ue_assocs);
if ( *ue_assocs_filename ) {
gchar* err = load_snmp_users_file(ue_assocs_filename,&ue_assocs);
if (err) report_failure("Error while loading SNMP's users file:\n%s",err);
} else {
ue_assocs = NULL;
}
}
static void* snmp_users_copy_cb(void* dest, const void* orig, unsigned len _U_) {
const snmp_ue_assoc_t* o = orig;
snmp_ue_assoc_t* d = dest;
d->auth_model = o->auth_model;
d->user.authModel = auth_models[o->auth_model];
d->priv_proto = o->priv_proto;
d->user.privProtocol = priv_protos[o->priv_proto];
d->user.userName.data = g_memdup(o->user.userName.data,o->user.userName.len);
d->user.userName.len = o->user.userName.len;
d->user.authPassword.data = o->user.authPassword.data ? g_memdup(o->user.authPassword.data,o->user.authPassword.len) : NULL;
d->user.authPassword.len = o->user.authPassword.len;
d->user.privPassword.data = o->user.privPassword.data ? g_memdup(o->user.privPassword.data,o->user.privPassword.len) : NULL;
d->user.privPassword.len = o->user.privPassword.len;
d->engine.len = o->engine.len;
if (o->engine.data) {
d->engine.data = g_memdup(o->engine.data,o->engine.len);
}
d->user.authKey.data = o->user.authKey.data ? g_memdup(o->user.authKey.data,o->user.authKey.len) : NULL;
d->user.authKey.len = o->user.authKey.len;
d->user.privKey.data = o->user.privKey.data ? g_memdup(o->user.privKey.data,o->user.privKey.len) : NULL;
d->user.privKey.len = o->user.privKey.len;
return d;
}
static void snmp_users_free_cb(void* p) {
snmp_ue_assoc_t* ue = p;
if (ue->user.userName.data) g_free(ue->user.userName.data);
if (ue->user.authPassword.data) g_free(ue->user.authPassword.data);
if (ue->user.privPassword.data) g_free(ue->user.privPassword.data);
if (ue->user.authKey.data) g_free(ue->user.authKey.data);
if (ue->user.privKey.data) g_free(ue->user.privKey.data);
if (ue->engine.data) g_free(ue->engine.data);
}
static void snmp_users_update_cb(void* p _U_, char** err) {
snmp_ue_assoc_t* ue = p;
*err = NULL;
GString* e = g_string_new("");
if (! ue->user.userName.len) g_string_append(e,"no userName, ");
if (ue->user.authPassword.len < 8) g_string_sprintfa(e,"short authPassword (%d), ", ue->user.authPassword.len);
if (ue->user.privPassword.len < 8) g_string_sprintfa(e,"short privPassword (%d), ", ue->user.privPassword.len);
if (e->len) {
g_string_truncate(e,e->len-2);
*err = ep_strdup(e->str);
}
g_string_free(e,TRUE);
return;
}
UAT_LSTRING_CB_DEF(snmp_users,userName,snmp_ue_assoc_t,user.userName.data,user.userName.len)
UAT_LSTRING_CB_DEF(snmp_users,authPassword,snmp_ue_assoc_t,user.authPassword.data,user.authPassword.len)
UAT_LSTRING_CB_DEF(snmp_users,privPassword,snmp_ue_assoc_t,user.privPassword.data,user.privPassword.len)
UAT_BUFFER_CB_DEF(snmp_users,engine_id,snmp_ue_assoc_t,engine.data,engine.len)
UAT_VS_DEF(snmp_users,auth_model,snmp_ue_assoc_t,0,"MD5")
UAT_VS_DEF(snmp_users,priv_proto,snmp_ue_assoc_t,0,"DES")
/*--- proto_register_snmp -------------------------------------------*/
@ -1955,8 +2067,29 @@ void proto_register_snmp(void) {
#include "packet-snmp-ettarr.c"
};
module_t *snmp_module;
module_t *snmp_module;
static uat_field_t fields[] = {
UAT_FLD_BUFFER(snmp_users,engine_id),
UAT_FLD_LSTRING(snmp_users,userName),
UAT_FLD_VS(snmp_users,auth_model,auth_types),
UAT_FLD_LSTRING(snmp_users,authPassword),
UAT_FLD_VS(snmp_users,priv_proto,priv_types),
UAT_FLD_LSTRING(snmp_users,privPassword),
UAT_END_FIELDS
};
assocs_uat = uat_new("SNMP Users",
sizeof(snmp_ue_assoc_t),
"snmp_users",
(void**)&ueas,
&num_ueas,
UAT_CAT_CRYPTO,
"ChSNMPUsersSection",
snmp_users_copy_cb,
snmp_users_update_cb,
snmp_users_free_cb,
fields);
#ifdef HAVE_NET_SNMP
#ifdef _WIN32
@ -2028,11 +2161,13 @@ void proto_register_snmp(void) {
"ON - display dissected variables inside SNMP tree, OFF - display dissected variables in root tree after SNMP",
&snmp_var_in_tree);
prefs_register_string_preference(snmp_module, "users_file",
"USMuserTable file",
"The filename of the user table used for authentication and decryption",
&ue_assocs_filename);
prefs_register_obsolete_preference(snmp_module, "users_file");
prefs_register_uat_preference(snmp_module, "users_table",
"Users Table",
"Table of engine-user associations used for authentication and decryption",
assocs_uat);
variable_oid_dissector_table =
register_dissector_table("snmp.variable_oid",
"SNMP Variable OID", FT_STRING, BASE_NONE);

View File

@ -45,7 +45,7 @@ typedef struct _snmp_usm_auth_model_t {
typedef struct _snmp_user_t {
snmp_usm_key_t userName;
snmp_usm_auth_model_t* authModel;
snmp_usm_key_t authPassword;
snmp_usm_key_t authKey;
@ -63,6 +63,8 @@ typedef struct {
struct _snmp_ue_assoc_t {
snmp_user_t user;
snmp_engine_id_t engine;
guint auth_model;
guint priv_proto;
struct _snmp_ue_assoc_t* next;
};
@ -93,24 +95,6 @@ extern guint dissect_snmp_pdu(tvbuff_t *, int, packet_info *, proto_tree *tree,
int, gint, gboolean);
extern int dissect_snmp_engineid(proto_tree *, tvbuff_t *, int, int);
/* SNMPv3 USM authentication functions */
gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, guint8**, guint*, gchar const**);
gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p, guint8**, guint*, gchar const**);
/* SNMPv3 USM privacy functions */
tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t*, tvbuff_t*, gchar const**);
tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t*, tvbuff_t*, gchar const**);
void snmp_usm_password_to_key_md5(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key);
void snmp_usm_password_to_key_sha1(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key);
/* defined in load_snmp_users_file.l */
/* returns NULL when OK or else the error string */
extern gchar* load_snmp_users_file(const char* filename, snmp_ue_assoc_t** assocs);
/*#include "packet-snmp-exp.h"*/
#endif /* PACKET_SNMP_H */

View File

@ -74,7 +74,6 @@ EXTRA_DIST = \
Makefile.nmake \
make-sminmpec.pl \
radius_dict.l \
load_snmp_users_file.l \
tvbtest.c \
uat_load.l \
exntest.c \
@ -91,7 +90,6 @@ DISTCLEANFILES = \
dtd_grammar.h \
dtd_parse.c \
dtd_preparse.c \
load_snmp_users_file.c \
radius_dict.c
@ -115,9 +113,6 @@ exntest: exntest.o except.o
radius_dict.c: radius_dict.l
$(LEX) $^
load_snmp_users_file.c: load_snmp_users_file.l
$(LEX) -oload_snmp_users_file.c $(srcdir)/load_snmp_users_file.l
uat_load.c: uat_load.l
$(LEX) -ouat_load.c $(srcdir)/uat_load.l

View File

@ -57,7 +57,6 @@ LIBWIRESHARK_SRC = \
in_cksum.c \
ipproto.c \
ipv4.c \
load_snmp_users_file.c \
next_tvb.c \
nstime.c \
oid_resolv.c \

View File

@ -121,7 +121,7 @@ clean:
distclean: clean
rm -f config.h register.c mkstemp.c strptime.c radius_dict.c \
dtd_grammar.out dtd_grammar.c dtd_grammar.h dtd_parse.c \
dtd_preparse.c load_snmp_users_file.c sminmpec.c uat_load.c
dtd_preparse.c sminmpec.c uat_load.c
cd crypt
$(MAKE) /$(MAKEFLAGS) -f Makefile.nmake distclean
cd ../ftypes
@ -207,9 +207,6 @@ dtd_parse.c : dtd_parse.l
dtd_preparse.c : dtd_preparse.l
$(LEX) -odtd_preparse.c dtd_preparse.l
load_snmp_users_file.c : load_snmp_users_file.l
$(LEX) -oload_snmp_users_file.c load_snmp_users_file.l
uat_load.c : uat_load.l
$(LEX) -ouat_load.c uat_load.l

View File

@ -473,6 +473,7 @@ void dfilter_macro_init(void) {
DFILTER_MACRO_FILENAME,
(void**) &macros,
&num_macros,
UAT_CAT_GENERAL,
"ChDisplayFilterMacrosSection",
macro_copy,
macro_update,

View File

@ -319,6 +319,7 @@ proto_register_k12(void)
"k12_protos",
(void**) &k12_handles,
&nk12_handles,
UAT_CAT_FFMT,
"ChK12ProtocolsSection",
k12_copy_cb,
k12_update_cb,

View File

@ -69,6 +69,7 @@
#include <epan/sminmpec.h>
#include <epan/emem.h>
#include <epan/next_tvb.h>
#include <epan/uat.h>
#include "packet-ipx.h"
#include "packet-hpext.h"
@ -155,11 +156,44 @@ static const gchar *mib_modules = DEF_MIB_MODULES;
static gboolean display_oid = TRUE;
static gboolean snmp_var_in_tree = TRUE;
static const gchar* ue_assocs_filename = "";
static const gchar* ue_assocs_filename_loaded = "";
static snmp_ue_assoc_t* ue_assocs = NULL;
static gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, guint8**, guint*, gchar const**);
static gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p, guint8**, guint*, gchar const**);
static tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t*, tvbuff_t*, gchar const**);
static tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t*, tvbuff_t*, gchar const**);
static void snmp_usm_password_to_key_md5(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key);
static void snmp_usm_password_to_key_sha1(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key);
static snmp_usm_auth_model_t model_md5 = {snmp_usm_password_to_key_md5, snmp_usm_auth_md5, 16};
static snmp_usm_auth_model_t model_sha1 = {snmp_usm_password_to_key_sha1, snmp_usm_auth_sha1, 20};
static value_string auth_types[] = {
{0,"MD5"},
{1,"SHA1"},
{0,NULL}
};
static snmp_usm_auth_model_t* auth_models[] = {&model_md5,&model_sha1};
static value_string priv_types[] = {
{0,"DES"},
{1,"AES"},
{0,NULL}
};
static snmp_usm_decoder_t priv_protos[] = {snmp_usm_priv_des, snmp_usm_priv_aes};
static snmp_ue_assoc_t* ueas = NULL;
static guint num_ueas = 0;
static uat_t* assocs_uat = NULL;
static snmp_ue_assoc_t* localized_ues = NULL;
static snmp_ue_assoc_t* unlocalized_ues = NULL;
/****/
static snmp_usm_params_t usm_p = {FALSE,FALSE,0,0,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,FALSE};
@ -289,7 +323,7 @@ static int hf_snmp_priority = -1; /* INTEGER_M1_2147483647 */
static int hf_snmp_operation = -1; /* T_operation */
/*--- End of included file: packet-snmp-hf.c ---*/
#line 197 "packet-snmp-template.c"
#line 231 "packet-snmp-template.c"
static int hf_smux_version = -1;
static int hf_smux_pdutype = -1;
@ -332,7 +366,7 @@ static gint ett_snmp_SimpleOpen = -1;
static gint ett_snmp_RReqPDU = -1;
/*--- End of included file: packet-snmp-ett.c ---*/
#line 211 "packet-snmp-template.c"
#line 245 "packet-snmp-template.c"
static const true_false_string auth_flags = {
@ -1182,52 +1216,89 @@ snmp_variable_decode(tvbuff_t *tvb, proto_tree *snmp_tree, packet_info *pinfo,tv
static void set_ue_keys(snmp_ue_assoc_t* n ) {
guint key_size = n->user.authModel->key_size;
n->user.authKey.data = se_alloc(key_size);
n->user.authKey.len = key_size;
n->user.authModel->pass2key(n->user.authPassword.data,
n->user.authPassword.len,
n->engine.data,
n->engine.len,
n->user.authKey.data);
n->user.privKey.data = se_alloc(key_size);
n->user.privKey.len = key_size;
n->user.authModel->pass2key(n->user.privPassword.data,
n->user.privPassword.len,
n->engine.data,
n->engine.len,
n->user.privKey.data);
}
static snmp_ue_assoc_t* ue_se_dup(snmp_ue_assoc_t* o) {
snmp_ue_assoc_t* d = se_memdup(o,sizeof(snmp_ue_assoc_t));
d->user.authModel = o->user.authModel;
d->user.privProtocol = o->user.privProtocol;
d->user.userName.data = se_memdup(o->user.userName.data,o->user.userName.len);
d->user.userName.len = o->user.userName.len;
d->user.authPassword.data = o->user.authPassword.data ? se_memdup(o->user.authPassword.data,o->user.authPassword.len) : NULL;
d->user.authPassword.len = o->user.authPassword.len;
d->user.privPassword.data = o->user.privPassword.data ? se_memdup(o->user.privPassword.data,o->user.privPassword.len) : NULL;
d->user.privPassword.len = o->user.privPassword.len;
d->engine.len = o->engine.len;
if (d->engine.len) {
d->engine.data = se_memdup(o->engine.data,o->engine.len);
set_ue_keys(d);
}
return d;
}
#define CACHE_INSERT(c,a) if (c) { snmp_ue_assoc_t* t = c; c = a; c->next = t; } else { c = a; a->next = NULL; }
static void renew_ue_cache(void) {
if (ue_assocs) {
static snmp_ue_assoc_t* a;
if (num_ueas) {
guint i;
localized_ues = NULL;
unlocalized_ues = NULL;
for(a = ue_assocs; a->user.userName.data; a++) {
if (a->engine.data) {
for(i = 0; i < num_ueas; i++) {
snmp_ue_assoc_t* a = ue_se_dup(&(ueas[i]));
if (a->engine.len) {
CACHE_INSERT(localized_ues,a);
} else {
CACHE_INSERT(unlocalized_ues,a);
}
}
} else {
localized_ues = NULL;
unlocalized_ues = NULL;
}
}
static snmp_ue_assoc_t* localize_ue( snmp_ue_assoc_t* o, const guint8* engine, guint engine_len ) {
snmp_ue_assoc_t* n = se_memdup(o,sizeof(snmp_ue_assoc_t));
guint key_size = n->user.authModel->key_size;
n->engine.data = se_memdup(engine,engine_len);
n->engine.len = engine_len;
n->user.authKey.data = se_alloc(key_size);
n->user.authKey.len = key_size;
n->user.authModel->pass2key(n->user.authPassword.data,
n->user.authPassword.len,
engine,
engine_len,
n->user.authKey.data);
n->user.privKey.data = se_alloc(key_size);
n->user.privKey.len = key_size;
n->user.authModel->pass2key(n->user.privPassword.data,
n->user.privPassword.len,
engine,
engine_len,
n->user.privKey.data);
set_ue_keys(n);
return n;
}
@ -1274,23 +1345,7 @@ static snmp_ue_assoc_t* get_user_assoc(tvbuff_t* engine_tvb, tvbuff_t* user_tvb)
return NULL;
}
static void destroy_ue_assocs(snmp_ue_assoc_t* assocs) {
if (assocs) {
snmp_ue_assoc_t* a;
for(a = assocs; a->user.userName.data; a++) {
g_free(a->user.userName.data);
if (a->user.authKey.data) g_free(a->user.authKey.data);
if (a->user.privKey.data) g_free(a->user.privKey.data);
if (a->engine.data) g_free(a->engine.data);
}
g_free(ue_assocs);
}
}
gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, guint8** calc_auth_p, guint* calc_auth_len_p, gchar const** error) {
static gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, guint8** calc_auth_p, guint* calc_auth_len_p, gchar const** error) {
guint msg_len;
guint8* msg;
guint auth_len;
@ -1346,7 +1401,7 @@ gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, guint8** calc_auth_p, guint* ca
}
gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p _U_, guint8** calc_auth_p, guint* calc_auth_len_p, gchar const** error _U_) {
static gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p _U_, guint8** calc_auth_p, guint* calc_auth_len_p, gchar const** error _U_) {
guint msg_len;
guint8* msg;
guint auth_len;
@ -1401,7 +1456,7 @@ gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p _U_, guint8** calc_auth_p, guin
return ( memcmp(auth,calc_auth,12) != 0 ) ? FALSE : TRUE;
}
tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error _U_) {
static tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error _U_) {
#ifdef HAVE_LIBGCRYPT
gcry_error_t err;
gcry_cipher_hd_t hd = NULL;
@ -1473,7 +1528,7 @@ on_gcry_error:
#endif
}
tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error _U_) {
static tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error _U_) {
#ifdef HAVE_LIBGCRYPT
gcry_error_t err;
gcry_cipher_hd_t hd = NULL;
@ -3204,7 +3259,7 @@ static void dissect_SMUX_PDUs_PDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree
/*--- End of included file: packet-snmp-fn.c ---*/
#line 1451 "packet-snmp-template.c"
#line 1506 "packet-snmp-template.c"
guint
@ -3473,7 +3528,7 @@ dissect_smux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
MD5 Password to Key Algorithm
from RFC 3414 A.2.1
*/
void snmp_usm_password_to_key_md5(const guint8 *password,
static void snmp_usm_password_to_key_md5(const guint8 *password,
guint passwordlen,
const guint8 *engineID,
guint engineLength,
@ -3525,7 +3580,7 @@ void snmp_usm_password_to_key_md5(const guint8 *password,
SHA1 Password to Key Algorithm COPIED from RFC 3414 A.2.2
*/
void snmp_usm_password_to_key_sha1(const guint8 *password,
static void snmp_usm_password_to_key_sha1(const guint8 *password,
guint passwordlen,
const guint8 *engineID,
guint engineLength,
@ -3626,19 +3681,76 @@ process_prefs(void)
mibs_loaded = TRUE;
#endif /* HAVE_NET_SNMP */
if ( g_str_equal(ue_assocs_filename_loaded,ue_assocs_filename) ) return;
ue_assocs_filename_loaded = ue_assocs_filename;
if (ue_assocs) destroy_ue_assocs(ue_assocs);
if ( *ue_assocs_filename ) {
gchar* err = load_snmp_users_file(ue_assocs_filename,&ue_assocs);
if (err) report_failure("Error while loading SNMP's users file:\n%s",err);
} else {
ue_assocs = NULL;
}
}
static void* snmp_users_copy_cb(void* dest, const void* orig, unsigned len _U_) {
const snmp_ue_assoc_t* o = orig;
snmp_ue_assoc_t* d = dest;
d->auth_model = o->auth_model;
d->user.authModel = auth_models[o->auth_model];
d->priv_proto = o->priv_proto;
d->user.privProtocol = priv_protos[o->priv_proto];
d->user.userName.data = g_memdup(o->user.userName.data,o->user.userName.len);
d->user.userName.len = o->user.userName.len;
d->user.authPassword.data = o->user.authPassword.data ? g_memdup(o->user.authPassword.data,o->user.authPassword.len) : NULL;
d->user.authPassword.len = o->user.authPassword.len;
d->user.privPassword.data = o->user.privPassword.data ? g_memdup(o->user.privPassword.data,o->user.privPassword.len) : NULL;
d->user.privPassword.len = o->user.privPassword.len;
d->engine.len = o->engine.len;
if (o->engine.data) {
d->engine.data = g_memdup(o->engine.data,o->engine.len);
}
d->user.authKey.data = o->user.authKey.data ? g_memdup(o->user.authKey.data,o->user.authKey.len) : NULL;
d->user.authKey.len = o->user.authKey.len;
d->user.privKey.data = o->user.privKey.data ? g_memdup(o->user.privKey.data,o->user.privKey.len) : NULL;
d->user.privKey.len = o->user.privKey.len;
return d;
}
static void snmp_users_free_cb(void* p) {
snmp_ue_assoc_t* ue = p;
if (ue->user.userName.data) g_free(ue->user.userName.data);
if (ue->user.authPassword.data) g_free(ue->user.authPassword.data);
if (ue->user.privPassword.data) g_free(ue->user.privPassword.data);
if (ue->user.authKey.data) g_free(ue->user.authKey.data);
if (ue->user.privKey.data) g_free(ue->user.privKey.data);
if (ue->engine.data) g_free(ue->engine.data);
}
static void snmp_users_update_cb(void* p _U_, char** err) {
snmp_ue_assoc_t* ue = p;
*err = NULL;
GString* e = g_string_new("");
if (! ue->user.userName.len) g_string_append(e,"no userName, ");
if (ue->user.authPassword.len < 8) g_string_sprintfa(e,"short authPassword (%d), ", ue->user.authPassword.len);
if (ue->user.privPassword.len < 8) g_string_sprintfa(e,"short privPassword (%d), ", ue->user.privPassword.len);
if (e->len) {
g_string_truncate(e,e->len-2);
*err = ep_strdup(e->str);
}
g_string_free(e,TRUE);
return;
}
UAT_LSTRING_CB_DEF(snmp_users,userName,snmp_ue_assoc_t,user.userName.data,user.userName.len)
UAT_LSTRING_CB_DEF(snmp_users,authPassword,snmp_ue_assoc_t,user.authPassword.data,user.authPassword.len)
UAT_LSTRING_CB_DEF(snmp_users,privPassword,snmp_ue_assoc_t,user.privPassword.data,user.privPassword.len)
UAT_BUFFER_CB_DEF(snmp_users,engine_id,snmp_ue_assoc_t,engine.data,engine.len)
UAT_VS_DEF(snmp_users,auth_model,snmp_ue_assoc_t,0,"MD5")
UAT_VS_DEF(snmp_users,priv_proto,snmp_ue_assoc_t,0,"DES")
/*--- proto_register_snmp -------------------------------------------*/
@ -4035,7 +4147,7 @@ void proto_register_snmp(void) {
"snmp.T_operation", HFILL }},
/*--- End of included file: packet-snmp-hfarr.c ---*/
#line 1945 "packet-snmp-template.c"
#line 2057 "packet-snmp-template.c"
};
/* List of subtrees */
@ -4076,10 +4188,31 @@ void proto_register_snmp(void) {
&ett_snmp_RReqPDU,
/*--- End of included file: packet-snmp-ettarr.c ---*/
#line 1957 "packet-snmp-template.c"
#line 2069 "packet-snmp-template.c"
};
module_t *snmp_module;
module_t *snmp_module;
static uat_field_t fields[] = {
UAT_FLD_BUFFER(snmp_users,engine_id),
UAT_FLD_LSTRING(snmp_users,userName),
UAT_FLD_VS(snmp_users,auth_model,auth_types),
UAT_FLD_LSTRING(snmp_users,authPassword),
UAT_FLD_VS(snmp_users,priv_proto,priv_types),
UAT_FLD_LSTRING(snmp_users,privPassword),
UAT_END_FIELDS
};
assocs_uat = uat_new("SNMP Users",
sizeof(snmp_ue_assoc_t),
"snmp_users",
(void**)&ueas,
&num_ueas,
UAT_CAT_CRYPTO,
"ChSNMPUsersSection",
snmp_users_copy_cb,
snmp_users_update_cb,
snmp_users_free_cb,
fields);
#ifdef HAVE_NET_SNMP
#ifdef _WIN32
@ -4151,11 +4284,13 @@ void proto_register_snmp(void) {
"ON - display dissected variables inside SNMP tree, OFF - display dissected variables in root tree after SNMP",
&snmp_var_in_tree);
prefs_register_string_preference(snmp_module, "users_file",
"USMuserTable file",
"The filename of the user table used for authentication and decryption",
&ue_assocs_filename);
prefs_register_obsolete_preference(snmp_module, "users_file");
prefs_register_uat_preference(snmp_module, "users_table",
"Users Table",
"Table of engine-user associations used for authentication and decryption",
assocs_uat);
variable_oid_dissector_table =
register_dissector_table("snmp.variable_oid",
"SNMP Variable OID", FT_STRING, BASE_NONE);

View File

@ -53,7 +53,7 @@ typedef struct _snmp_usm_auth_model_t {
typedef struct _snmp_user_t {
snmp_usm_key_t userName;
snmp_usm_auth_model_t* authModel;
snmp_usm_key_t authPassword;
snmp_usm_key_t authKey;
@ -71,6 +71,8 @@ typedef struct {
struct _snmp_ue_assoc_t {
snmp_user_t user;
snmp_engine_id_t engine;
guint auth_model;
guint priv_proto;
struct _snmp_ue_assoc_t* next;
};
@ -101,24 +103,6 @@ extern guint dissect_snmp_pdu(tvbuff_t *, int, packet_info *, proto_tree *tree,
int, gint, gboolean);
extern int dissect_snmp_engineid(proto_tree *, tvbuff_t *, int, int);
/* SNMPv3 USM authentication functions */
gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, guint8**, guint*, gchar const**);
gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p, guint8**, guint*, gchar const**);
/* SNMPv3 USM privacy functions */
tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t*, tvbuff_t*, gchar const**);
tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t*, tvbuff_t*, gchar const**);
void snmp_usm_password_to_key_md5(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key);
void snmp_usm_password_to_key_sha1(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key);
/* defined in load_snmp_users_file.l */
/* returns NULL when OK or else the error string */
extern gchar* load_snmp_users_file(const char* filename, snmp_ue_assoc_t** assocs);
/*#include "packet-snmp-exp.h"*/
#endif /* PACKET_SNMP_H */

View File

@ -1,411 +0,0 @@
%option noyywrap
%option nounput
%option prefix="Snmp_UE_file_"
%option never-interactive
%option caseless
%{
/*
* load_snmp_users_file.l
*
* User-based Security Model for SNMPv3
* SNMP user-engine association file parser
*
* Copyright 2007, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <glib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <epan/tvbuff.h>
#include <epan/proto.h>
#include <epan/packet_info.h>
#include <epan/emem.h>
#include <epan/dissectors/packet-snmp.h>
#define AUTH_MD5 1
#define AUTH_SHA 2
#define PRIV_DES 4
#define PRIV_AES 5
static GString* error;
static GArray* assoc_arr = NULL;
static guint8* engine = NULL;
static guint engine_len = 0;
static guint8* user = NULL;
static guint user_len = 0;
static guint8* auth_password = NULL;
static guint auth_password_len = 0;
static guint8* priv_password = NULL;
static guint priv_password_len = 0;
static int auth = AUTH_MD5;
static int enc = PRIV_DES;
static guint linenum = 0;
static const gchar* filename = "";
static guint loaded = 0;
static void add_engine(void);
static guint8* unhexbytes(const char* s, guint len, guint* len_p);
static guint8* undquote(const char* s, guint in_len, guint* len_p);
static snmp_usm_auth_model_t model_md5 = {snmp_usm_password_to_key_md5, snmp_usm_auth_md5, 16};
static snmp_usm_auth_model_t model_sha1 = {snmp_usm_password_to_key_sha1, snmp_usm_auth_sha1, 20};
#define ERR(str)
#define START_LINE() { \
linenum++; \
engine = NULL;\
engine_len = 0;\
user = NULL;\
user_len = 0;\
auth_password = NULL;\
auth_password_len = 0;\
priv_password = NULL;\
priv_password_len = 0;\
auth = AUTH_MD5;\
enc = PRIV_DES;\
BEGIN START_ENGINE;\
}
%}
hex_bytes [0-9A-Fa-f]+
quoted_string \042([^\042]|\134\042)*\042
any_engine \052
whitespace [ \t]+
newline [\r]?\n
dash -
des [dD][Ee][Ss]
aes [aA][Ee][Ss]
md5 [mM][dD]5
sha [sS][hH][aA][1]?
comment [ \t]*\043[^\n]*\n
%START START_ENGINE STOP_ENGINE
%START START_USER STOP_USER
%START START_AUTHPASSWORD STOP_AUTHPASSWORD
%START START_PRIVPASSWORD STOP_PRIVPASSWORD
%START ATTRIBUTES
%START ERRORED
%%
<ERRORED>. ;
<ERRORED>{newline} { START_LINE(); }
<START_ENGINE>{newline} { START_LINE(); }
<START_ENGINE>{comment} { START_LINE(); }
<START_ENGINE>{quoted_string} { engine = undquote(yytext, yyleng, &engine_len); BEGIN STOP_ENGINE; }
<START_ENGINE>{hex_bytes} { engine = unhexbytes(yytext, yyleng, &engine_len); BEGIN STOP_ENGINE; }
<START_ENGINE>{any_engine} { engine = NULL; engine_len = 0; BEGIN STOP_ENGINE; }
<START_ENGINE>. { ERR("Invalid engineId"); }
<STOP_ENGINE>{whitespace} { BEGIN START_USER; }
<START_USER>{quoted_string} { user = undquote(yytext, yyleng,&user_len); BEGIN STOP_USER; }
<START_USER>{hex_bytes} { user = unhexbytes(yytext, yyleng, &user_len); BEGIN STOP_USER; }
<START_USER>. { ERR("Invalid userName"); }
<STOP_USER>{whitespace} { BEGIN START_AUTHPASSWORD; }
<START_AUTHPASSWORD>{quoted_string} { auth_password = undquote(yytext, yyleng, &auth_password_len); BEGIN STOP_AUTHPASSWORD; }
<START_AUTHPASSWORD>{hex_bytes} { auth_password = unhexbytes(yytext, yyleng, &auth_password_len); BEGIN STOP_AUTHPASSWORD; }
<START_AUTHPASSWORD>. { ERR("Invalid authPassword"); }
<STOP_AUTHPASSWORD>{whitespace} { BEGIN START_PRIVPASSWORD; }
<START_PRIVPASSWORD>{quoted_string} { priv_password = undquote(yytext, yyleng, &priv_password_len); BEGIN STOP_PRIVPASSWORD; }
<START_PRIVPASSWORD>{hex_bytes} { priv_password = unhexbytes(yytext, yyleng, &priv_password_len); BEGIN STOP_PRIVPASSWORD; }
<START_PRIVPASSWORD>. { ERR("Invalid privPassword"); }
<STOP_PRIVPASSWORD>{whitespace} { BEGIN ATTRIBUTES; }
<STOP_PRIVPASSWORD>{newline} { add_engine(); START_LINE(); }
<ATTRIBUTES>{whitespace} ;
<ATTRIBUTES>{md5} { auth = AUTH_MD5; }
<ATTRIBUTES>{sha} { auth = AUTH_SHA; }
<ATTRIBUTES>{des} { enc = PRIV_DES; }
<ATTRIBUTES>{aes} { enc = PRIV_AES; }
<ATTRIBUTES>{newline} { add_engine(); START_LINE(); }
<ATTRIBUTES>. { ERR("Invalid char in attributes"); }
%%
static guint8* unhexbytes(const char* si, guint len, guint* len_p) {
guint8* buf;
guint8* p;
const guint8* s = (void*)si;
unsigned i;
if (len % 2) {
ERR("Uneven number of chars hex string");
return NULL;
}
buf = g_malloc(len);
p = buf;
for (i = 0; i<len ; i += 2) {
guint8 lo = s[i+1];
guint8 hi = s[i];
if (hi >= '0' && hi <= '9') {
hi -= '0';
} else if (hi >= 'a' && hi <= 'f') {
hi -= 'a';
hi += 0xa;
} else if (hi >= 'A' && hi <= 'F') {
hi -= 'A';
hi += 0xa;
} else {
goto on_error;
}
if (lo >= '0' && lo <= '9') {
lo -= '0';
} else if (lo >= 'a' && lo <= 'f') {
lo -= 'a';
lo += 0xa;
} else if (lo >= 'A' && lo <= 'F') {
lo -= 'A';
lo += 0xa;
} else {
goto on_error;
}
*(p++) = (hi*0x10) + lo;
}
len /= 2;
if (len_p) *len_p = len;
return buf;
on_error:
ERR("Error parsing hex string");
g_free(buf);
return NULL;
}
static guint8* undquote(const char* si, guint in_len, guint* len_p) {
guint8* buf = g_malloc(in_len); /* wastes one byte for every '\\' in text */
guint8* p = buf;
guint len = 0;
guint8* end = buf+in_len;
const guint8* s = (void*)si;
for (s++; p < end; s++) {
switch(*s) {
case '\0':
*(p-1) = '\0';
goto done;
case '\\':
switch(*(++s)) {
case 'a': *(p++) = '\a'; len++; break;
case 'b': *(p++) = '\b'; len++; break;
case 'e': *(p++) = '\e'; len++; break;
case 'f': *(p++) = '\f'; len++; break;
case 'n': *(p++) = '\n'; len++; break;
case 'r': *(p++) = '\r'; len++; break;
case 't': *(p++) = '\t'; len++; break;
case 'v': *(p++) = '\v'; len++; break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
{
int c0 = 0;
int c1 = 0;
int c2 = 0;
int c = 0;
c0 = (*s) - '0';
if ( s[1] >= '0' && s[1] <= '7' ) {
c1 = c0;
c0 = (*++s) - '0';
if ( s[1] >= '0' && s[1] <= '7' ) {
c2 = c1;
c1 = c0;
c0 = (*++s) - '0';
}
}
c = (64 * c2) + (8 * c1) + c0;
*(p++) = (char) (c > 255 ? 255 : c);
len++;
break;
}
default:
*p++ = *s;
len++;
break;
}
break;
default:
*(p++) = *s;
len++;
break;
}
}
done:
while ( p < end ) *(p++) = '\0';
buf[len] = '\0';
len--;
if (len_p) *len_p = len;
return buf;
}
static void add_engine(void) {
snmp_ue_assoc_t a;
a.user.userName.data = user;
a.user.userName.len = user_len;
a.user.authPassword.data = auth_password;
a.user.authPassword.len = auth_password_len;
a.user.privPassword.data = priv_password;
a.user.privPassword.len = priv_password_len;
switch (auth) {
case AUTH_MD5:
a.user.authModel = &model_md5;
break;
case AUTH_SHA:
a.user.authModel = &model_sha1;
break;
default:
g_assert_not_reached();
break;
}
switch(enc) {
case PRIV_DES:
a.user.privProtocol = snmp_usm_priv_des;
break;
case PRIV_AES:
a.user.privProtocol = snmp_usm_priv_aes;
break;
default:
g_assert_not_reached();
break;
}
if (engine) {
a.engine.data = engine;
a.engine.len = engine_len;
if (a.user.authModel) {
a.user.authKey.data = g_malloc(a.user.authModel->key_size);
a.user.authKey.len = a.user.authModel->key_size;
a.user.privKey.data = g_malloc(a.user.authModel->key_size);
a.user.privKey.len = a.user.authModel->key_size;
a.user.authModel->pass2key( auth_password, auth_password_len, engine, engine_len, a.user.authKey.data);
a.user.authModel->pass2key( priv_password, priv_password_len, engine, engine_len, a.user.privKey.data);
} else {
a.user.authKey.data = NULL;
a.user.authKey.len = 0;
a.user.privKey.data = NULL;
a.user.privKey.len = 0;
}
} else {
a.engine.data = NULL;
a.engine.len = 0;
a.user.authKey.data = NULL;
a.user.authKey.len = 0;
a.user.privKey.data = NULL;
a.user.privKey.len = 0;
}
a.next = NULL;
g_array_append_val(assoc_arr,a);
loaded++;
return;
}
gchar* load_snmp_users_file(const char* fname, snmp_ue_assoc_t** assocs) {
gchar* err_str = NULL;
*assocs = NULL;
assoc_arr = g_array_new(TRUE,FALSE,sizeof(snmp_ue_assoc_t));
filename = fname;
yyin = fopen(filename,"r");
if (!yyin) {
return ep_strdup_printf("Could not open file: '%s', error: %s",filename,strerror(errno));
}
error = g_string_new("");
loaded = 0;
START_LINE();
yylex();
fclose(yyin);
yyrestart(NULL);
if (loaded) {
*assocs = (snmp_ue_assoc_t*)assoc_arr->data;
g_array_free(assoc_arr,FALSE);
} else {
*assocs = NULL;
g_array_free(assoc_arr,TRUE);
}
if (error->len) {
err_str = error->str;
}
return err_str;
}

View File

@ -50,6 +50,7 @@ struct _uat_t {
size_t record_size;
char* filename;
char* help;
char* category;
void** user_ptr;
guint* nrows_p;
uat_copy_cb_t copy_cb;

View File

@ -56,6 +56,7 @@ uat_t* uat_new(const char* name,
char* filename,
void** data_ptr,
guint* numitems_ptr,
char* category,
char* help,
uat_copy_cb_t copy_cb,
uat_update_cb_t update_cb,
@ -85,6 +86,7 @@ uat_t* uat_new(const char* name,
uat->rep = NULL;
uat->free_rep = NULL;
uat->help = help;
uat->category = category;
for (i=0;flds_array[i].name;i++) {
fld_data_t* f = g_malloc(sizeof(fld_data_t));

View File

@ -201,6 +201,9 @@ typedef struct _uat_field_t {
#define UAT_END_FIELDS {0,PT_TXTMOD_NONE,{0,0,0},{0,0,0},0,FLDFILL}
#define UAT_CAT_GENERAL "General"
#define UAT_CAT_CRYPTO "Decryption"
#define UAT_CAT_FFMT "File Formats"
/*
* uat_new()
@ -230,6 +233,7 @@ uat_t* uat_new(const char* name,
char* filename,
void** data_ptr,
guint* num_items,
char* category,
char* help,
uat_copy_cb_t copy_cb,
uat_update_cb_t update_cb,