forked from osmocom/wireshark
SNMPv3 USM decryption/authentication phase 1
svn path=/trunk/; revision=20353
This commit is contained in:
parent
d9465f6b12
commit
f7a79f43e7
|
@ -12,6 +12,8 @@
|
|||
* Updated to use the asn2wrs compiler made by Tomas Kukosa
|
||||
* Copyright (C) 2005 - 2006 Anders Broman [AT] ericsson.com
|
||||
*
|
||||
* See RFC 3414 for User-based Security Model for SNMPv3
|
||||
* Copyright (C) 2007 Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
|
@ -58,8 +60,13 @@
|
|||
#include <epan/sminmpec.h>
|
||||
#include <epan/emem.h>
|
||||
#include <epan/next_tvb.h>
|
||||
#include <epan/crypt/hmac.h>
|
||||
#include <epan/expert.h>
|
||||
#include <epan/report_err.h>
|
||||
#include "packet-ipx.h"
|
||||
#include "packet-hpext.h"
|
||||
#include <epan/crypt/airpdcap_sha1.h>
|
||||
#include <epan/crypt/crypt-md5.h>
|
||||
|
||||
|
||||
#include "packet-ber.h"
|
||||
|
@ -90,10 +97,14 @@
|
|||
# define VALTYPE_COUNTER64 ASN_COUNTER64
|
||||
|
||||
#endif /* HAVE_NET_SNMP */
|
||||
|
||||
#include "packet-snmp.h"
|
||||
#include "format-oid.h"
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Take a pointer that may be null and return a pointer that's not null
|
||||
by turning null pointers into pointers to the above null string,
|
||||
and, if the argument pointer wasn't null, make sure we handle
|
||||
|
@ -131,6 +142,11 @@ 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 snmp_usm_params_t usm_p = {FALSE,FALSE,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
|
||||
|
||||
/* Subdissector tables */
|
||||
static dissector_table_t variable_oid_dissector_table;
|
||||
|
||||
|
@ -166,6 +182,8 @@ static int hf_snmp_engineid_text = -1;
|
|||
static int hf_snmp_engineid_time = -1;
|
||||
static int hf_snmp_engineid_data = -1;
|
||||
static int hf_snmp_counter64 = -1;
|
||||
static int hf_snmp_decryptedPDU = -1;
|
||||
static int hf_snmp_msgAuthentication = -1;
|
||||
|
||||
#include "packet-snmp-hf.c"
|
||||
|
||||
|
@ -177,9 +195,18 @@ static gint ett_smux = -1;
|
|||
static gint ett_snmp = -1;
|
||||
static gint ett_engineid = -1;
|
||||
static gint ett_msgFlags = -1;
|
||||
static gint ett_encryptedPDU = -1;
|
||||
static gint ett_decrypted = -1;
|
||||
static gint ett_authParameters = -1;
|
||||
|
||||
#include "packet-snmp-ett.c"
|
||||
|
||||
|
||||
static const true_false_string auth_flags = {
|
||||
"OK",
|
||||
"Failed"
|
||||
};
|
||||
|
||||
/* defined in net-SNMP; include/net-snmp/library/snmp.h */
|
||||
#undef SNMP_MSG_GET
|
||||
#undef SNMP_MSG_SET
|
||||
|
@ -822,7 +849,7 @@ snmp_variable_decode(tvbuff_t *tvb, proto_tree *snmp_tree, packet_info *pinfo,tv
|
|||
switch (vb_type) {
|
||||
|
||||
case SNMP_INTEGER:
|
||||
offset = dissect_ber_integer(FALSE, pinfo, NULL, tvb, start, -1, &vb_integer_value);
|
||||
offset = dissect_ber_integer(FALSE, pinfo, NULL, tvb, start, -1, &(vb_integer_value));
|
||||
length = offset - vb_value_start;
|
||||
if (snmp_tree) {
|
||||
#ifdef HAVE_NET_SNMP
|
||||
|
@ -1020,8 +1047,219 @@ snmp_variable_decode(tvbuff_t *tvb, proto_tree *snmp_tree, packet_info *pinfo,tv
|
|||
return;
|
||||
}
|
||||
|
||||
static snmp_ue_assoc_t* get_user_assoc(tvbuff_t* engine_tvb, tvbuff_t* user_tvb) {
|
||||
static snmp_ue_assoc_t* a;
|
||||
guint given_username_len;
|
||||
guint8* given_username;
|
||||
guint given_engine_len;
|
||||
guint8* given_engine;
|
||||
|
||||
if ( ! ue_assocs ) return NULL;
|
||||
|
||||
if (! ( user_tvb && engine_tvb ) ) return NULL;
|
||||
|
||||
given_username_len = tvb_length_remaining(user_tvb,0);
|
||||
given_username = ep_tvb_memdup(user_tvb,0,-1);
|
||||
given_engine_len = tvb_length_remaining(engine_tvb,0);
|
||||
given_engine = ep_tvb_memdup(engine_tvb,0,-1);
|
||||
|
||||
for(a = ue_assocs; a->user.userName.data; a++) {
|
||||
guint username_len = a->user.userName.len;
|
||||
|
||||
if ( given_username_len == username_len
|
||||
&& memcmp(a->user.userName.data, given_username, given_username_len) == 0 ) {
|
||||
|
||||
const guint8* engine_data = a->engine.data;
|
||||
guint engine_len = a->engine.len;
|
||||
|
||||
if ( engine_data ) {
|
||||
if ( engine_len == given_engine_len
|
||||
&& memcmp(given_engine,engine_data,engine_len) == 0 ) {
|
||||
return a;
|
||||
}
|
||||
} else {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_USM
|
||||
#define DUMP_DATA(n,b,l) { unsigned i; printf("%s: ",n); for (i=0;i<(unsigned)l;i++) printf("%.2x",b[i]); printf("\n"); }
|
||||
#define D(p) printf p
|
||||
#else
|
||||
#define DUMP_DATA(n,b,l)
|
||||
#define D(p)
|
||||
#endif
|
||||
|
||||
gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, gchar** error) {
|
||||
guint msg_len;
|
||||
guint8* msg;
|
||||
guint auth_len;
|
||||
guint8* auth;
|
||||
guint8* key;
|
||||
guint key_len;
|
||||
guint8 calc_auth[16];
|
||||
guint start;
|
||||
guint end;
|
||||
guint i;
|
||||
|
||||
if (!p->auth_tvb) {
|
||||
*error = "No Authenticator";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
key = p->user_assoc->user.authKey.data;
|
||||
key_len = p->user_assoc->user.authKey.len;
|
||||
|
||||
if (! key ) {
|
||||
*error = "User has no authKey";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
auth_len = tvb_length_remaining(p->auth_tvb,0);
|
||||
|
||||
if (auth_len != 12) {
|
||||
*error = "Authenticator length wrong";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
msg_len = tvb_length_remaining(p->msg_tvb,0);
|
||||
msg = ep_tvb_memdup(p->msg_tvb,0,msg_len);
|
||||
|
||||
|
||||
auth = ep_tvb_memdup(p->auth_tvb,0,auth_len);
|
||||
|
||||
start = p->auth_offset - p->start_offset;
|
||||
end = start + auth_len;
|
||||
|
||||
/* fill the authenticator with zeros */
|
||||
for ( i = start ; i < end ; i++ ) {
|
||||
msg[i] = '\0';
|
||||
}
|
||||
|
||||
md5_hmac(msg, msg_len, key, key_len, calc_auth);
|
||||
|
||||
return ( memcmp(auth,calc_auth,12) != 0 ) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
|
||||
gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p _U_, gchar** error _U_) {
|
||||
*error = "SHA1 authentication Not Yet Implemented";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar** error _U_) {
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_error_t err;
|
||||
gcry_cipher_hd_t hd = NULL;
|
||||
|
||||
guint8* cleartext;
|
||||
guint8* des_key = p->user_assoc->user.privKey.data; /* first 8 bytes */
|
||||
guint8* pre_iv = &(p->user_assoc->user.privKey.data[8]); /* last 8 bytes */
|
||||
guint8* salt;
|
||||
gint salt_len;
|
||||
gint cryptgrm_len;
|
||||
guint8* cryptgrm;
|
||||
tvbuff_t* clear_tvb;
|
||||
guint8 iv[8];;
|
||||
guint i;
|
||||
|
||||
|
||||
salt_len = tvb_length_remaining(p->priv_tvb,0);
|
||||
D(("salt_len=%d\n",salt_len));
|
||||
|
||||
if (salt_len != 8) {
|
||||
*error = "msgPrivacyParameters lenght != 8";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
salt = ep_tvb_memdup(p->priv_tvb,0,salt_len);
|
||||
|
||||
DUMP_DATA("salt",salt,salt_len);
|
||||
DUMP_DATA("pre_iv",iv,8);
|
||||
|
||||
/*
|
||||
The resulting "salt" is XOR-ed with the pre-IV to obtain the IV.
|
||||
*/
|
||||
for (i=0; i<8; i++) {
|
||||
iv[i] = pre_iv[i] ^ salt[i];
|
||||
}
|
||||
|
||||
DUMP_DATA("iv",iv,8);
|
||||
DUMP_DATA("des_key",des_key,8);
|
||||
|
||||
cryptgrm_len = tvb_length_remaining(encryptedData,0);
|
||||
D(("cryptgrm_len=%d\n",cryptgrm_len));
|
||||
|
||||
if (cryptgrm_len % 8) {
|
||||
*error = "the length of the encrypted data is noty a mutiple of 8";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cryptgrm = ep_tvb_memdup(encryptedData,0,-1);
|
||||
DUMP_DATA("cryptgrm",cryptgrm,cryptgrm_len);
|
||||
|
||||
cleartext = ep_alloc(cryptgrm_len);
|
||||
|
||||
err = gcry_cipher_open(&hd, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, 0);
|
||||
if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
|
||||
|
||||
err = gcry_cipher_setiv(hd, iv, 8);
|
||||
if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
|
||||
|
||||
err = gcry_cipher_setkey(hd,des_key,8);
|
||||
if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
|
||||
|
||||
err = gcry_cipher_decrypt(hd, cleartext, cryptgrm_len, cryptgrm, cryptgrm_len);
|
||||
if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
|
||||
|
||||
gcry_cipher_close(hd);
|
||||
|
||||
DUMP_DATA("cleartext",cryptgrm,cryptgrm_len);
|
||||
|
||||
/*
|
||||
???
|
||||
The first ciphertext block is decrypted, the decryption output is
|
||||
XOR-ed with the Initialization Vector, and the result is the first
|
||||
plaintext block.
|
||||
|
||||
For each subsequent block, the ciphertext block is decrypted, the
|
||||
decryption output is XOR-ed with the previous ciphertext block and
|
||||
the result is the plaintext block.
|
||||
*/
|
||||
|
||||
|
||||
clear_tvb = tvb_new_real_data(cleartext, cryptgrm_len, cryptgrm_len);
|
||||
|
||||
return clear_tvb;
|
||||
|
||||
on_gcry_error:
|
||||
*error = (void*)gpg_strerror(err);
|
||||
if (hd) gcry_cipher_close(hd);
|
||||
return NULL;
|
||||
#else
|
||||
*error = "libgcrypt not present, cannot decrypt";
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar** error _U_) {
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
*error = "AES decryption Not Yet Implemented";
|
||||
return NULL;
|
||||
#else
|
||||
*error = "libgcrypt not present, cannot decrypt";
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "packet-snmp-fn.c"
|
||||
|
||||
|
||||
guint
|
||||
dissect_snmp_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||
proto_tree *tree, int proto, gint ett, gboolean is_tcp)
|
||||
|
@ -1039,6 +1277,18 @@ dissect_snmp_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
proto_tree *snmp_tree = NULL;
|
||||
proto_item *item = NULL;
|
||||
|
||||
usm_p.msg_tvb = tvb;
|
||||
usm_p.start_offset = offset_from_real_beginning(tvb,0) ;
|
||||
usm_p.engine_tvb = NULL;
|
||||
usm_p.user_tvb = NULL;
|
||||
usm_p.auth_item = NULL;
|
||||
usm_p.auth_tvb = NULL;
|
||||
usm_p.auth_offset = 0;
|
||||
usm_p.priv_tvb = NULL;
|
||||
usm_p.user_assoc = NULL;
|
||||
usm_p.authenticated = FALSE;
|
||||
usm_p.encrypted = FALSE;
|
||||
|
||||
/*
|
||||
* This will throw an exception if we don't have any data left.
|
||||
* That's what we want. (See "tcp_dissect_pdus()", which is
|
||||
|
@ -1268,6 +1518,132 @@ dissect_smux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
dissect_SMUX_PDUs_PDU(tvb, pinfo, tree);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
MD5 Password to Key Algorithm
|
||||
from RFC 3414 A.2.1
|
||||
*/
|
||||
void snmp_usm_password_to_key_md5(
|
||||
guint8 *password, /* IN */
|
||||
guint passwordlen, /* IN */
|
||||
guint8 *engineID, /* IN - pointer to snmpEngineID */
|
||||
guint engineLength,/* IN - length of snmpEngineID */
|
||||
guint8 *key) /* OUT - pointer to caller 16-octet buffer */
|
||||
|
||||
{
|
||||
md5_state_t MD;
|
||||
guint8 *cp, password_buf[64];
|
||||
guint32 password_index = 0;
|
||||
guint32 count = 0, i;
|
||||
guint8 key1[16];
|
||||
md5_init(&MD); /* initialize MD5 */
|
||||
|
||||
/**********************************************/
|
||||
/* Use while loop until we've done 1 Megabyte */
|
||||
/**********************************************/
|
||||
while (count < 1048576) {
|
||||
cp = password_buf;
|
||||
for (i = 0; i < 64; i++) {
|
||||
/*************************************************/
|
||||
/* Take the next octet of the password, wrapping */
|
||||
/* to the beginning of the password as necessary.*/
|
||||
/*************************************************/
|
||||
*cp++ = password[password_index++ % passwordlen];
|
||||
}
|
||||
md5_append(&MD, password_buf, 64);
|
||||
count += 64;
|
||||
}
|
||||
md5_finish(&MD, key1); /* tell MD5 we're done */
|
||||
|
||||
/*****************************************************/
|
||||
/* Now localize the key with the engineID and pass */
|
||||
/* through MD5 to produce final key */
|
||||
/* May want to ensure that engineLength <= 32, */
|
||||
/* otherwise need to use a buffer larger than 64 */
|
||||
/*****************************************************/
|
||||
|
||||
md5_init(&MD);
|
||||
md5_append(&MD, key1, 16);
|
||||
md5_append(&MD, engineID, engineLength);
|
||||
md5_append(&MD, key1, 16);
|
||||
md5_finish(&MD, key);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
SHA1 Password to Key Algorithm COPIED from RFC 3414 A.2.2
|
||||
*/
|
||||
#define SHAUpdate(c,b,l) sha1_loop((c),(b),(l))
|
||||
#define SHAFinal(d,c) sha1_result((c),(d))
|
||||
|
||||
void snmp_usm_password_to_key_sha1(
|
||||
guint8 *password, /* IN */
|
||||
guint passwordlen, /* IN */
|
||||
guint8 *engineID, /* IN - pointer to snmpEngineID */
|
||||
guint engineLength,/* IN - length of snmpEngineID */
|
||||
guint8 *key) /* OUT - pointer to caller 20-octet buffer */
|
||||
{
|
||||
SHA1_CONTEXT SH;
|
||||
guint8 *cp, password_buf[72];
|
||||
guint32 password_index = 0;
|
||||
guint32 count = 0, i;
|
||||
|
||||
sha1_init (&SH); /* initialize SHA */
|
||||
|
||||
/**********************************************/
|
||||
/* Use while loop until we've done 1 Megabyte */
|
||||
/**********************************************/
|
||||
while (count < 1048576) {
|
||||
cp = password_buf;
|
||||
for (i = 0; i < 64; i++) {
|
||||
/*************************************************/
|
||||
/* Take the next octet of the password, wrapping */
|
||||
/* to the beginning of the password as necessary.*/
|
||||
/*************************************************/
|
||||
*cp++ = password[password_index++ % passwordlen];
|
||||
}
|
||||
SHAUpdate (&SH, password_buf, 64);
|
||||
count += 64;
|
||||
}
|
||||
SHAFinal (key, &SH); /* tell SHA we're done */
|
||||
|
||||
/*****************************************************/
|
||||
/* Now localize the key with the engineID and pass */
|
||||
/* through SHA to produce final key */
|
||||
/* May want to ensure that engineLength <= 32, */
|
||||
/* otherwise need to use a buffer larger than 72 */
|
||||
/*****************************************************/
|
||||
memcpy(password_buf, key, 20);
|
||||
memcpy(password_buf+20, engineID, engineLength);
|
||||
memcpy(password_buf+20+engineLength, key, 20);
|
||||
|
||||
sha1_init(&SH);
|
||||
SHAUpdate(&SH, password_buf, 40+engineLength);
|
||||
SHAFinal(key, &SH);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_prefs(void)
|
||||
{
|
||||
|
@ -1322,17 +1698,55 @@ process_prefs(void)
|
|||
read_configs();
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef DUMP_USMDATA
|
||||
{
|
||||
GString* s = g_string_new(">>");
|
||||
g_string_sprintfa(s,"File: %s\n",ue_assocs_filename);
|
||||
|
||||
#define DUMP(s,n,b,l) { unsigned i; g_string_sprintfa(s,"%s: ",n); for (i=0;i<l;i++) g_string_sprintfa(s,"%.2x",b[i]); g_string_sprintfa(s,"\n"); }
|
||||
if (ue_assocs) {
|
||||
snmp_ue_assoc_t* a;
|
||||
|
||||
for(a = ue_assocs; a->user.userName.data; a++) {
|
||||
if (a->engine.data) DUMP(s,"engine",a->engine.data,a->engine.len);
|
||||
DUMP(s,"userName",a->user.userName.data,a->user.userName.len);
|
||||
DUMP(s,"authPassword",a->user.authPassword.data,a->user.authPassword.len);
|
||||
if (a->user.authKey.data) DUMP(s,"authKey",a->user.authKey.data,a->user.authKey.len);
|
||||
DUMP(s,"privPassword",a->user.privPassword.data,a->user.privPassword.len);
|
||||
if (a->user.privKey.data) DUMP(s,"privKey",a->user.privKey.data,a->user.privKey.len);
|
||||
g_string_sprintfa(s,"\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
report_failure("%s",s->str);
|
||||
g_string_free(s,TRUE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*--- proto_register_snmp -------------------------------------------*/
|
||||
void proto_register_snmp(void) {
|
||||
|
||||
|
||||
|
||||
|
||||
/*--- proto_register_snmp -------------------------------------------*/
|
||||
void proto_register_snmp(void) {
|
||||
#if defined(_WIN32) && defined(HAVE_NET_SNMP)
|
||||
char *mib_path;
|
||||
int mib_path_len;
|
||||
#define MIB_PATH_APPEND "snmp\\mibs"
|
||||
#endif
|
||||
gchar *tmp_mib_modules;
|
||||
|
||||
|
||||
/* List of fields */
|
||||
static hf_register_info hf[] = {
|
||||
{ &hf_snmp_v3_flags_auth,
|
||||
|
@ -1374,7 +1788,13 @@ void proto_register_snmp(void) {
|
|||
{ &hf_snmp_counter64, {
|
||||
"Value", "snmp.counter64", FT_INT64, BASE_DEC,
|
||||
NULL, 0, "A counter64 value", HFILL }},
|
||||
|
||||
{ &hf_snmp_msgAuthentication,
|
||||
{ "Authentication OK", "snmp.v3.authOK", FT_BOOLEAN, 8,
|
||||
TFS(&auth_flags), 0, "", HFILL }},
|
||||
{ &hf_snmp_decryptedPDU, {
|
||||
"Decrypted PDU", "snmp.decryptedPdu", FT_BYTES, BASE_HEX,
|
||||
NULL, 0, "Decrypted PDU", HFILL }},
|
||||
|
||||
#include "packet-snmp-hfarr.c"
|
||||
};
|
||||
|
||||
|
@ -1383,7 +1803,10 @@ void proto_register_snmp(void) {
|
|||
&ett_snmp,
|
||||
&ett_engineid,
|
||||
&ett_msgFlags,
|
||||
|
||||
&ett_encryptedPDU,
|
||||
&ett_decrypted,
|
||||
&ett_authParameters,
|
||||
|
||||
#include "packet-snmp-ettarr.c"
|
||||
};
|
||||
module_t *snmp_module;
|
||||
|
@ -1459,6 +1882,11 @@ 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",
|
||||
"The filename of the user table used for authentication/decryption",
|
||||
&ue_assocs_filename);
|
||||
|
||||
variable_oid_dissector_table =
|
||||
register_dissector_table("snmp.variable_oid",
|
||||
"SNMP Variable OID", FT_STRING, BASE_NONE);
|
||||
|
|
|
@ -25,6 +25,61 @@
|
|||
#ifndef PACKET_SNMP_H
|
||||
#define PACKET_SNMP_H
|
||||
|
||||
typedef struct _snmp_usm_key {
|
||||
guint8* data;
|
||||
guint len;
|
||||
} snmp_usm_key_t;
|
||||
|
||||
typedef struct _snmp_ue_assoc_t snmp_ue_assoc_t;
|
||||
typedef struct _snmp_usm_params_t snmp_usm_params_t;
|
||||
|
||||
typedef gboolean (*snmp_usm_authenticator_t)(snmp_usm_params_t*, gchar** error);
|
||||
typedef tvbuff_t* (*snmp_usm_decoder_t)(snmp_usm_params_t*, tvbuff_t* encryptedData, gchar** error);
|
||||
typedef void (*snmp_usm_password_to_key_t)(guint8 *password, guint passwordlen, guint8 *engineID, guint engineLength, guint8 *key);
|
||||
|
||||
typedef struct _snmp_usm_auth_model_t {
|
||||
snmp_usm_password_to_key_t pass2key;
|
||||
snmp_usm_authenticator_t authenticate;
|
||||
guint key_size;
|
||||
} 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;
|
||||
|
||||
snmp_usm_decoder_t privProtocol;
|
||||
snmp_usm_key_t privPassword;
|
||||
snmp_usm_key_t privKey;
|
||||
} snmp_user_t;
|
||||
|
||||
typedef struct {
|
||||
guint8* data;
|
||||
guint len;
|
||||
} snmp_engine_id_t;
|
||||
|
||||
struct _snmp_ue_assoc_t {
|
||||
snmp_user_t user;
|
||||
snmp_engine_id_t engine;
|
||||
};
|
||||
|
||||
struct _snmp_usm_params_t {
|
||||
gboolean authenticated;
|
||||
gboolean encrypted;
|
||||
guint start_offset;
|
||||
guint auth_offset;
|
||||
|
||||
tvbuff_t* engine_tvb;
|
||||
tvbuff_t* user_tvb;
|
||||
proto_item* auth_item;
|
||||
tvbuff_t* auth_tvb;
|
||||
tvbuff_t* priv_tvb;
|
||||
tvbuff_t* msg_tvb;
|
||||
snmp_ue_assoc_t* user_assoc;
|
||||
};
|
||||
|
||||
/*
|
||||
* Guts of the SNMP dissector - exported for use by protocols such as
|
||||
* ILMI.
|
||||
|
@ -33,6 +88,24 @@ 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, gchar**);
|
||||
gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p, gchar**);
|
||||
|
||||
/* SNMPv3 USM privacy functions */
|
||||
tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t*, tvbuff_t*, gchar**);
|
||||
tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t*, tvbuff_t*, gchar**);
|
||||
|
||||
|
||||
void snmp_usm_password_to_key_md5(guint8 *password, guint passwordlen, guint8 *engineID, guint engineLength, guint8 *key);
|
||||
void snmp_usm_password_to_key_sha1(guint8 *password, guint passwordlen, 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 */
|
||||
|
|
|
@ -8,6 +8,13 @@
|
|||
SMUX-PDUs
|
||||
|
||||
#.NO_EMIT
|
||||
GetNextRequest-PDU
|
||||
GetResponse-PDU
|
||||
SetRequest-PDU
|
||||
GetRequest-PDU
|
||||
Gauge32
|
||||
NotificationName
|
||||
SnmpEngineID
|
||||
|
||||
#.TYPE_RENAME
|
||||
|
||||
|
@ -20,7 +27,6 @@ BulkPDU/request-id bulkPDU_request-id
|
|||
VAL_PTR = &pdu_type
|
||||
|
||||
#.FN_BODY PDUs
|
||||
|
||||
gint pdu_type;
|
||||
|
||||
%(DEFAULT_BODY)s
|
||||
|
@ -167,32 +173,105 @@ gint pdu_type;
|
|||
|
||||
VAL_PTR = &MsgSecurityModel
|
||||
|
||||
#.FN_BODY SNMPv3Message/msgSecurityParameters
|
||||
#.FN_BODY UsmSecurityParameters/msgAuthoritativeEngineID
|
||||
tvbuff_t *parameter_tvb = NULL;
|
||||
|
||||
switch(MsgSecurityModel){
|
||||
case SNMP_SEC_USM: /* 3 */
|
||||
offset = dissect_snmp_UsmSecurityParameters(FALSE, tvb, offset+2, pinfo, tree, -1);
|
||||
break;
|
||||
case SNMP_SEC_ANY: /* 0 */
|
||||
case SNMP_SEC_V1: /* 1 */
|
||||
case SNMP_SEC_V2C: /* 2 */
|
||||
default:
|
||||
%(DEFAULT_BODY)s
|
||||
break;
|
||||
offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
|
||||
&usm_p.engine_tvb);
|
||||
if (parameter_tvb) {
|
||||
proto_tree* engine_tree = proto_item_add_subtree(get_ber_last_created_item(),ett_engineid);
|
||||
dissect_snmp_engineid(engine_tree, usm_p.engine_tvb, 0, tvb_length_remaining(usm_p.engine_tvb,0));
|
||||
}
|
||||
|
||||
#.FN_PARS SnmpEngineID
|
||||
#.FN_PARS UsmSecurityParameters/msgUserName
|
||||
VAL_PTR = &usm_p.user_tvb
|
||||
|
||||
#.FN_BODY UsmSecurityParameters/msgAuthenticationParameters
|
||||
offset = dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_index, &usm_p.auth_tvb);
|
||||
if (usm_p.auth_tvb) {
|
||||
usm_p.auth_item = get_ber_last_created_item();
|
||||
usm_p.auth_offset = offset_from_real_beginning(usm_p.auth_tvb,0);
|
||||
}
|
||||
#.FN_PARS UsmSecurityParameters/msgPrivacyParameters
|
||||
VAL_PTR = &usm_p.priv_tvb
|
||||
|
||||
VAL_PTR = ¶meter_tvb
|
||||
#.FN_BODY ScopedPduData/encryptedPDU
|
||||
tvbuff_t* crypt_tvb;
|
||||
offset = dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_snmp_encryptedPDU, &crypt_tvb);
|
||||
|
||||
#.FN_BODY SnmpEngineID
|
||||
tvbuff_t *parameter_tvb = NULL;
|
||||
proto_tree *engineid_tree = NULL;
|
||||
proto_item *item = NULL;
|
||||
if( usm_p.encrypted && crypt_tvb
|
||||
&& usm_p.user_assoc
|
||||
&& usm_p.user_assoc->user.privProtocol ) {
|
||||
gchar* error = NULL;
|
||||
|
||||
%(DEFAULT_BODY)s
|
||||
if (parameter_tvb)
|
||||
dissect_snmp_engineid(tree, parameter_tvb, 0, tvb_length_remaining(parameter_tvb,0));
|
||||
tvbuff_t* cleartext_tvb = usm_p.user_assoc->user.privProtocol(&usm_p,
|
||||
crypt_tvb,
|
||||
&error );
|
||||
|
||||
if (! cleartext_tvb) {
|
||||
proto_item* item = get_ber_last_created_item();
|
||||
expert_add_info_format( pinfo, item, PI_UNDECODED, PI_WARN, "Failed to decrypt encryptedPDU: %%s", error );
|
||||
} else {
|
||||
proto_tree* decrypted_tree = proto_item_add_subtree(get_ber_last_created_item(),ett_decrypted);
|
||||
|
||||
add_new_data_source(pinfo, cleartext_tvb, "Decrypted ScopedPDU");
|
||||
tvb_set_child_real_data_tvbuff(tvb, cleartext_tvb);
|
||||
dissect_snmp_ScopedPDU(FALSE, cleartext_tvb, 0, pinfo, decrypted_tree, -1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#.FN_BODY SNMPv3Message/msgSecurityParameters
|
||||
|
||||
// printf(">msgSecurityParameters\n");
|
||||
switch(MsgSecurityModel){
|
||||
case SNMP_SEC_USM: /* 3 */
|
||||
offset = dissect_snmp_UsmSecurityParameters(FALSE, tvb, offset+2, pinfo, tree, -1);
|
||||
usm_p.user_assoc = get_user_assoc(usm_p.engine_tvb, usm_p.user_tvb);
|
||||
break;
|
||||
case SNMP_SEC_ANY: /* 0 */
|
||||
case SNMP_SEC_V1: /* 1 */
|
||||
case SNMP_SEC_V2C: /* 2 */
|
||||
default:
|
||||
%(DEFAULT_BODY)s
|
||||
break;
|
||||
}
|
||||
|
||||
#.FN_FTR SNMPv3Message
|
||||
|
||||
if( usm_p.authenticated
|
||||
&& usm_p.user_assoc
|
||||
&& usm_p.user_assoc->user.authModel ) {
|
||||
gchar* error = NULL;
|
||||
proto_item* authen_item;
|
||||
proto_tree* authen_tree = proto_item_add_subtree(usm_p.auth_item,ett_authParameters);
|
||||
|
||||
gboolean authen_ok = usm_p.user_assoc->user.authModel->authenticate(
|
||||
&usm_p,
|
||||
&error );
|
||||
|
||||
if (error) {
|
||||
authen_item = proto_tree_add_text(authen_tree,tvb,0,0,"Error while verifying Messsage authenticity: %s", error);
|
||||
PROTO_ITEM_SET_GENERATED(authen_item);
|
||||
expert_add_info_format( pinfo, authen_item, PI_MALFORMED, PI_ERROR, "Error while verifying Messsage authenticity: %s", error );
|
||||
} else {
|
||||
int severity;
|
||||
gchar* fmt;
|
||||
|
||||
authen_item = proto_tree_add_boolean(authen_tree, hf_snmp_msgAuthentication, tvb, 0, 0, authen_ok);
|
||||
PROTO_ITEM_SET_GENERATED(authen_item);
|
||||
|
||||
if (authen_ok) {
|
||||
fmt = "SNMP Authentication OK";
|
||||
severity = PI_CHAT;
|
||||
} else {
|
||||
fmt = "SNMP Authentication Error";
|
||||
severity = PI_WARN;
|
||||
}
|
||||
|
||||
expert_add_info_format( pinfo, authen_item, PI_CHECKSUM, severity, fmt );
|
||||
}
|
||||
}
|
||||
|
||||
#.FN_PARS HeaderData/msgFlags
|
||||
|
||||
|
@ -203,10 +282,14 @@ gint pdu_type;
|
|||
|
||||
%(DEFAULT_BODY)s
|
||||
if (parameter_tvb){
|
||||
|
||||
guint8 v3_flags = tvb_get_guint8(parameter_tvb, 0);
|
||||
|
||||
proto_tree_add_item(tree, hf_snmp_v3_flags_report, parameter_tvb, 0, 1, FALSE);
|
||||
proto_tree_add_item(tree, hf_snmp_v3_flags_crypt, parameter_tvb, 0, 1, FALSE);
|
||||
proto_tree_add_item(tree, hf_snmp_v3_flags_auth, parameter_tvb, 0, 1, FALSE);
|
||||
|
||||
usm_p.encrypted = v3_flags & TH_CRYPT ? TRUE : FALSE;
|
||||
usm_p.authenticated = v3_flags & TH_AUTH ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
#.FN_BODY VarBind
|
||||
|
|
|
@ -68,6 +68,7 @@ EXTRA_DIST = \
|
|||
dtd_grammar.lemon \
|
||||
dtd_parse.l \
|
||||
dtd_preparse.l \
|
||||
load_snmp_users_file.l \
|
||||
enterprise-numbers \
|
||||
libwireshark.def \
|
||||
Makefile.common \
|
||||
|
@ -89,6 +90,7 @@ DISTCLEANFILES = \
|
|||
dtd_grammar.h \
|
||||
dtd_parse.c \
|
||||
dtd_preparse.c \
|
||||
load_snmp_users_file.c \
|
||||
radius_dict.c
|
||||
|
||||
|
||||
|
@ -111,6 +113,9 @@ 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
|
||||
|
||||
dtd_parse.c : dtd_parse.l
|
||||
$(LEX) -odtd_parse.c $(srcdir)/dtd_parse.l
|
||||
|
|
|
@ -61,6 +61,7 @@ LIBWIRESHARK_SRC = \
|
|||
in_cksum.c \
|
||||
ipproto.c \
|
||||
ipv4.c \
|
||||
load_snmp_users_file.c \
|
||||
next_tvb.c \
|
||||
nstime.c \
|
||||
oid_resolv.c \
|
||||
|
|
|
@ -31,7 +31,8 @@ LIBAIRPDCAP_SRC = \
|
|||
airpdcap_sha1.c \
|
||||
airpdcap_tkip.c \
|
||||
airpdcap_wep.c \
|
||||
crypt-md5.c
|
||||
crypt-md5.c \
|
||||
hmac.c
|
||||
|
||||
LIBAIRPDCAP_INCLUDES = \
|
||||
airpdcap_debug.h \
|
||||
|
@ -43,4 +44,5 @@ LIBAIRPDCAP_INCLUDES = \
|
|||
airpdcap_user.h \
|
||||
airpdcap_ws.h \
|
||||
crypt-md5.h \
|
||||
hmac.h \
|
||||
wep-wpadefs.h
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* hmac.c
|
||||
*
|
||||
* HMAC: Keyed-Hashing for Message Authentication
|
||||
*
|
||||
* code copied from RFC 2104
|
||||
*
|
||||
* $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 <epan/emem.h>
|
||||
#include <epan/tvbuff.h>
|
||||
#include <epan/crypt/airpdcap_sha1.h>
|
||||
#include <epan/crypt/crypt-md5.h>
|
||||
|
||||
#include "hmac.h"
|
||||
|
||||
|
||||
/*
|
||||
** Function: hmac_sha1
|
||||
*/
|
||||
|
||||
void hmac_sha1(const guint8* text,gint text_len, const guint8* key, gint key_len, guint8 digest[20]) {
|
||||
SHA1_CONTEXT context;
|
||||
guint8 k_ipad[65]; /* inner padding -
|
||||
* key XORd with ipad
|
||||
*/
|
||||
guint8 k_opad[65]; /* outer padding -
|
||||
* key XORd with opad
|
||||
*/
|
||||
guint8 tk[20];
|
||||
int i;
|
||||
/* if key is longer than 64 bytes reset it to key=MD5(key) */
|
||||
if (key_len > 64) {
|
||||
|
||||
SHA1_CONTEXT tctx;
|
||||
|
||||
sha1_init(&tctx);
|
||||
sha1_loop(&tctx, key, key_len);
|
||||
sha1_result(&tctx, tk);
|
||||
|
||||
key = tk;
|
||||
key_len = 20;
|
||||
}
|
||||
|
||||
/*
|
||||
* the HMAC_MD5 transform looks like:
|
||||
*
|
||||
* MD5(K XOR opad, MD5(K XOR ipad, text))
|
||||
*
|
||||
* where K is an n byte key
|
||||
* ipad is the byte 0x36 repeated 64 times
|
||||
|
||||
|
||||
|
||||
Krawczyk, et. al. Informational [Page 8]
|
||||
|
||||
RFC 2104 HMAC February 1997
|
||||
|
||||
|
||||
* opad is the byte 0x5c repeated 64 times
|
||||
* and text is the data being protected
|
||||
*/
|
||||
|
||||
/* start out by storing key in pads */
|
||||
bzero( k_ipad, sizeof k_ipad);
|
||||
bzero( k_opad, sizeof k_opad);
|
||||
bcopy( key, k_ipad, key_len);
|
||||
bcopy( key, k_opad, key_len);
|
||||
|
||||
/* XOR key with ipad and opad values */
|
||||
for (i=0; i<64; i++) {
|
||||
k_ipad[i] ^= 0x36;
|
||||
k_opad[i] ^= 0x5c;
|
||||
}
|
||||
|
||||
/*
|
||||
* perform inner SHA1
|
||||
*/
|
||||
sha1_init(&context); /* init context for 1st
|
||||
* pass */
|
||||
sha1_loop(&context, k_ipad, 64); /* start with inner pad */
|
||||
sha1_loop(&context, text, text_len); /* then text of datagram */
|
||||
sha1_result(&context, digest); /* finish up 1st pass */
|
||||
/*
|
||||
* perform outer SHA1
|
||||
*/
|
||||
sha1_init(&context); /* init context for 2nd
|
||||
* pass */
|
||||
sha1_loop(&context, k_opad, 64); /* start with outer pad */
|
||||
sha1_loop(&context, digest, 16); /* then results of 1st
|
||||
* hash */
|
||||
sha1_result(&context, digest); /* finish up 2nd pass */
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/* hmac.h
|
||||
*
|
||||
*
|
||||
* HMAC: Keyed-Hashing for Message Authentication
|
||||
*
|
||||
* See RFC 2104
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void hmac_md5(const guint8* text,gint text_len, const guint8* key, gint key_len, guint8 digest[16]);
|
||||
void hmac_sha1(const guint8* text,gint text_len, const guint8* key, gint key_len, guint8 digest[20]);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -33,6 +33,61 @@
|
|||
#ifndef PACKET_SNMP_H
|
||||
#define PACKET_SNMP_H
|
||||
|
||||
typedef struct _snmp_usm_key {
|
||||
guint8* data;
|
||||
guint len;
|
||||
} snmp_usm_key_t;
|
||||
|
||||
typedef struct _snmp_ue_assoc_t snmp_ue_assoc_t;
|
||||
typedef struct _snmp_usm_params_t snmp_usm_params_t;
|
||||
|
||||
typedef gboolean (*snmp_usm_authenticator_t)(snmp_usm_params_t*, gchar** error);
|
||||
typedef tvbuff_t* (*snmp_usm_decoder_t)(snmp_usm_params_t*, tvbuff_t* encryptedData, gchar** error);
|
||||
typedef void (*snmp_usm_password_to_key_t)(guint8 *password, guint passwordlen, guint8 *engineID, guint engineLength, guint8 *key);
|
||||
|
||||
typedef struct _snmp_usm_auth_model_t {
|
||||
snmp_usm_password_to_key_t pass2key;
|
||||
snmp_usm_authenticator_t authenticate;
|
||||
guint key_size;
|
||||
} 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;
|
||||
|
||||
snmp_usm_decoder_t privProtocol;
|
||||
snmp_usm_key_t privPassword;
|
||||
snmp_usm_key_t privKey;
|
||||
} snmp_user_t;
|
||||
|
||||
typedef struct {
|
||||
guint8* data;
|
||||
guint len;
|
||||
} snmp_engine_id_t;
|
||||
|
||||
struct _snmp_ue_assoc_t {
|
||||
snmp_user_t user;
|
||||
snmp_engine_id_t engine;
|
||||
};
|
||||
|
||||
struct _snmp_usm_params_t {
|
||||
gboolean authenticated;
|
||||
gboolean encrypted;
|
||||
guint start_offset;
|
||||
guint auth_offset;
|
||||
|
||||
tvbuff_t* engine_tvb;
|
||||
tvbuff_t* user_tvb;
|
||||
proto_item* auth_item;
|
||||
tvbuff_t* auth_tvb;
|
||||
tvbuff_t* priv_tvb;
|
||||
tvbuff_t* msg_tvb;
|
||||
snmp_ue_assoc_t* user_assoc;
|
||||
};
|
||||
|
||||
/*
|
||||
* Guts of the SNMP dissector - exported for use by protocols such as
|
||||
* ILMI.
|
||||
|
@ -41,6 +96,24 @@ 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, gchar**);
|
||||
gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p, gchar**);
|
||||
|
||||
/* SNMPv3 USM privacy functions */
|
||||
tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t*, tvbuff_t*, gchar**);
|
||||
tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t*, tvbuff_t*, gchar**);
|
||||
|
||||
|
||||
void snmp_usm_password_to_key_md5(guint8 *password, guint passwordlen, guint8 *engineID, guint engineLength, guint8 *key);
|
||||
void snmp_usm_password_to_key_sha1(guint8 *password, guint passwordlen, 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 */
|
||||
|
|
Loading…
Reference in New Issue