* Add a category param to the uat.
* UATify SNMP Users svn path=/trunk/; revision=20736
This commit is contained in:
parent
5ec87e6eef
commit
2006fac500
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -473,6 +473,7 @@ void dfilter_macro_init(void) {
|
|||
DFILTER_MACRO_FILENAME,
|
||||
(void**) ¯os,
|
||||
&num_macros,
|
||||
UAT_CAT_GENERAL,
|
||||
"ChDisplayFilterMacrosSection",
|
||||
macro_copy,
|
||||
macro_update,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue