net-snmp/net-snmp-5.9.1-IdeaUI_antic_attack.patch

203 lines
7.0 KiB
Diff
Raw Permalink Normal View History

From e194c8fbe2cc2b1085a3da97ddb94eb329558446 Mon Sep 17 00:00:00 2001
From: chenrufeng <chenrufeng4@huawei.com>
Date: Fri, 5 Jan 2024 10:38:35 +0800
Subject: [PATCH] add support for IDEAUI_ANTI_ATTACK
---
agent/snmp_agent.c | 2 +
include/net-snmp/library/snmp_api.h | 5 ++
include/net-snmp/output_api.h | 18 ++++++++
include/net-snmp/types.h | 6 +++
snmplib/snmp_api.c | 72 +++++++++++++++++++++++++++++
5 files changed, 103 insertions(+)
diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c
index 273b46772..bff663d32 100644
--- a/agent/snmp_agent.c
+++ b/agent/snmp_agent.c
@@ -2214,7 +2214,9 @@ handle_snmp_packet(int op, netsnmp_session * session, int reqid,
*/
if (pdu->version == SNMP_VERSION_3 &&
session->s_snmp_errno == SNMPERR_USM_AUTHENTICATIONFAILURE) {
+#ifndef IDEAUI_ANTI_ATTACK
send_easy_trap(SNMP_TRAP_AUTHFAIL, 0);
+#endif
return 1;
}
diff --git a/include/net-snmp/library/snmp_api.h b/include/net-snmp/library/snmp_api.h
index 6b4fad6ab..419f44764 100644
--- a/include/net-snmp/library/snmp_api.h
+++ b/include/net-snmp/library/snmp_api.h
@@ -384,6 +384,11 @@ typedef struct request_list {
NETSNMP_IMPORT
void init_snmp(const char *);
+#if defined(IDEAUI_ANTI_ATTACK)
+ NETSNMP_IMPORT
+ void netsnmp_init_antiattack_callback(struct snmp_s_anti_attack* callbacklist);
+#endif
+
NETSNMP_IMPORT
int
snmp_build(u_char ** pkt, size_t * pkt_len, size_t * offset,
diff --git a/include/net-snmp/output_api.h b/include/net-snmp/output_api.h
index 3b142850c..9bce8d704 100644
--- a/include/net-snmp/output_api.h
+++ b/include/net-snmp/output_api.h
@@ -184,4 +184,22 @@ netsnmp_debug_no_dumpsetup(const char *token, const void *buf, size_t len)
#define ERROR_MSG(string) snmp_set_detail(string)
#endif
+#if defined(IDEAUI_ANTI_ATTACK)
+typedef struct snmp_s_anti_info {
+ char *userName;
+ char *peerName;
+ int antiRes;
+} snmp_anti_info;
+
+/*
+ * anti attack
+ */
+struct snmp_s_anti_attack {
+ void (*cb_init_attack_info)(void);
+ void (*cb_uninit_attack_info)(void);
+ unsigned int (*cb_add_attack_info) (char *, const char *);
+ void (*cb_clear_attack_info) (char *, const char *);
+ int (*cb_is_attack_lock) (char *, const char *);
+};
+#endif /* IDEAUI_ANTI_ATTACK */
#endif /* NET_SNMP_OUTPUT_API_H */
diff --git a/include/net-snmp/types.h b/include/net-snmp/types.h
index d489f37b1..830d3b93f 100644
--- a/include/net-snmp/types.h
+++ b/include/net-snmp/types.h
@@ -17,6 +17,12 @@
*/
#include <stdio.h>
+#if defined(IDEAUI_OS_ANDROID)
+#include <sys/select.h>
+typedef unsigned long int ulong;
+typedef unsigned short int ushort;
+typedef unsigned int uint;
+#endif
#ifndef NET_SNMP_CONFIG_H
#error "Please include <net-snmp/net-snmp-config.h> before this file"
diff --git a/snmplib/snmp_api.c b/snmplib/snmp_api.c
index 4042f8046..96e7eeb5b 100644
--- a/snmplib/snmp_api.c
+++ b/snmplib/snmp_api.c
@@ -329,6 +329,13 @@ int snmp_errno = 0;
* END MTCRITICAL_RESOURCE
*/
+#if defined(IDEAUI_ANTI_ATTACK)
+ /*
+ * anti attack
+ */
+struct snmp_s_anti_attack g_stAntiAttack = {NULL, NULL, NULL, NULL, NULL};
+#endif
+
/*
* global error detail storage
*/
@@ -863,6 +870,20 @@ register_default_handlers(void)
netsnmp_register_service_handlers();
}
+#if defined(IDEAUI_ANTI_ATTACK)
+void netsnmp_init_antiattack_callback(struct snmp_s_anti_attack* callbacklist)
+{
+ if (callbacklist == NULL) {
+ return;
+ }
+ g_stAntiAttack.cb_init_attack_info = callbacklist->cb_init_attack_info;
+ g_stAntiAttack.cb_uninit_attack_info = callbacklist->cb_uninit_attack_info;
+ g_stAntiAttack.cb_add_attack_info = callbacklist->cb_add_attack_info;
+ g_stAntiAttack.cb_clear_attack_info = callbacklist->cb_clear_attack_info;
+ g_stAntiAttack.cb_is_attack_lock = callbacklist->cb_is_attack_lock;
+}
+#endif
+
static int init_snmp_init_done = 0; /* To prevent double init's. */
/**
* Calls the functions to do config file loading and mib module parsing
@@ -4287,10 +4308,33 @@ _snmp_parse(void *sessp,
static size_t ourEngineID_len = sizeof(ourEngineID);
netsnmp_pdu *pdu2 = NULL;
+#if defined(IDEAUI_ANTI_ATTACK)
+ char* peerName = NULL;
+ const int ipMaxLen = 256;
+ char szRemoteAddr[ipMaxLen] = {0};
+ char unknownPeer[ipMaxLen] = {0};
+ strcpy(unknownPeer, "UnkownHost");
+ snmp_anti_info antiInfo = {0};
+#endif
session->s_snmp_errno = 0;
session->s_errno = 0;
+#if defined(IDEAUI_ANTI_ATTACK)
+ if (pdu->transport_data_length != 0) {
+ struct sockaddr_in *from_in = (struct sockaddr_in *)pdu->transport_data;
+ if (AF_INET6 == from_in->sin_family) {
+ struct sockaddr_in6 *from_in6 = (struct sockaddr_in6 *)pdu->transport_data;
+ inet_ntop(AF_INET6, (void *) &(from_in6->sin6_addr), szRemoteAddr, sizeof(szRemoteAddr));
+ } else {
+ inet_ntop(AF_INET, (void *) &(from_in->sin_addr), szRemoteAddr, sizeof(szRemoteAddr));
+ }
+ peerName = szRemoteAddr;
+ } else {
+ peerName = unknownPeer;
+ }
+#endif
+
/*
* Ensure all incoming PDUs have a unique means of identification
* (This is not restricted to AgentX handling,
@@ -4391,6 +4435,16 @@ _snmp_parse(void *sessp,
snmp_api_errstring(result)));
if (result) {
+#if defined(IDEAUI_ANTI_ATTACK)
+ antiInfo.userName = pdu->securityName;
+ antiInfo.peerName = peerName;
+ antiInfo.antiRes = result;
+ if (g_stAntiAttack.cb_add_attack_info != NULL &&
+ ((pdu->securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV) ||
+ (pdu->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV))) {
+ g_stAntiAttack.cb_add_attack_info((char *)&antiInfo, (const char*)peerName);
+ }
+#endif
struct snmp_secmod_def *secmod =
find_sec_mod(pdu->securityModel);
if (!sessp) {
@@ -4408,6 +4462,24 @@ _snmp_parse(void *sessp,
}
free_securityStateRef(pdu);
}
+#if defined(IDEAUI_ANTI_ATTACK)
+ else {
+ if ((g_stAntiAttack.cb_is_attack_lock != NULL) &&
+ ((pdu->securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV) ||
+ (pdu->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV))) {
+ antiInfo.userName = pdu->securityName;
+ antiInfo.peerName = peerName;
+ antiInfo.antiRes = result;
+ if (g_stAntiAttack.cb_is_attack_lock((char *)&antiInfo, (const char*)peerName) != 0) {
+ result = SNMPERR_ASN_PARSE_ERR;
+ } else {
+ if (g_stAntiAttack.cb_clear_attack_info != NULL) {
+ g_stAntiAttack.cb_clear_attack_info((char *)&antiInfo, (const char*)peerName);
+ }
+ }
+ }
+ }
+#endif
/* Implement RFC5343 here for two reasons:
1) From a security perspective it handles this otherwise