Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
net snmp未正确更改身份验证和priv协议 我在Linux下的C++程序中使用了网络SNMP库(版本5.7.1)。我有一个Web前端,用户可以在其中选择SNMP版本并进行配置。SNMPv1和SNMPv2工作正常,但我发现SNMPv3存在一些问题_C++_C_Net Snmp - Fatal编程技术网

net snmp未正确更改身份验证和priv协议 我在Linux下的C++程序中使用了网络SNMP库(版本5.7.1)。我有一个Web前端,用户可以在其中选择SNMP版本并进行配置。SNMPv1和SNMPv2工作正常,但我发现SNMPv3存在一些问题

net snmp未正确更改身份验证和priv协议 我在Linux下的C++程序中使用了网络SNMP库(版本5.7.1)。我有一个Web前端,用户可以在其中选择SNMP版本并进行配置。SNMPv1和SNMPv2工作正常,但我发现SNMPv3存在一些问题,c++,c,net-snmp,C++,C,Net Snmp,这是前端的图片:(很抱歉没有直接上传到这里,但我需要至少10个声誉才能做到这一点) 当我启动C++后端并正确输入所有需要的SNMPv3证书时,所有的工作都很好,设备是可访问的。例如,如果我将身份验证协议从MD5更改为SHA,但保留其余凭据不变,那么我会认为该设备无法访问。在现实中,它是可以到达的。重新启动后端后,无法使用相同的设置(如预期)访问设备 发现这个问题后,我进行了一些测试。对于测试,我使用了不同的用户和不同的设置。他们使用不同厂商的三种不同设备运行,每次我都得到相同的结果。因此,它不可

这是前端的图片:(很抱歉没有直接上传到这里,但我需要至少10个声誉才能做到这一点)

<>当我启动C++后端并正确输入所有需要的SNMPv3证书时,所有的工作都很好,设备是可访问的。例如,如果我将身份验证协议从MD5更改为SHA,但保留其余凭据不变,那么我会认为该设备无法访问。在现实中,它是可以到达的。重新启动后端后,无法使用相同的设置(如预期)访问设备

发现这个问题后,我进行了一些测试。对于测试,我使用了不同的用户和不同的设置。他们使用不同厂商的三种不同设备运行,每次我都得到相同的结果。因此,它不可能是设备实现的问题。结果如下所示:

测试后我得出的结论是,net snmp似乎为一个用户名缓存了选定的auth和priv协议。这在测试2中表现得非常好。第一次将用户名与特定协议一起使用时,我得到了预期的结果。更改协议后 预期会有不同的结果,但我得到的结果仍然与以前相同

最后,介绍如何进行SNMP调用的一些信息:

  • 有一个名为
    SNMPWrapper
    的类,它处理整个SNMP通信
  • 在构造函数中,我调用
    init\u snmp()
    初始化网络snmp
  • 从外部我只能调用
    get()
    set()
    walk()
    。每次调用其中一个方法时,都会创建一个新的SNMP会话(首先,我使用
    SNMP\u sess\u init()
    创建一个新会话,然后设置所需的内容,最后使用
    SNMP\u sess\u open()
  • 提出请求并收到答复后,我使用
    snmp\u sess\u close()
问题:在更改协议之前,我是否需要进行任何其他清理以使其正常工作

编辑:我添加了一些代码,显示了所描述的行为

int main(int argc, char** argv) {
struct snmp_session session, session1, *ss, *ss1;
struct snmp_pdu *pdu, *pdu1;
struct snmp_pdu *response, *response1;

oid anOID[MAX_OID_LEN];
size_t anOID_len = MAX_OID_LEN;

struct variable_list *vars;
int status, status1;

init_snmp("snmpapp");

const char* user = "md5";
string authpw = "123123123";
string privpw = "";
string ipString = "192.168.15.32";

char ip[16];
memset(&ip, 0, sizeof (ip));
ipString.copy(ip, sizeof (ip) - 1, 0);

/*
 * First request: AuthProto is MD5, no PrivProto is used. The snmp-get
 * request is successful
 */
snmp_sess_init(&session); /* set up defaults */
session.peername = ip;
session.version = SNMP_VERSION_3;

/* set the SNMPv3 user name */
session.securityName = strdup(user);
session.securityNameLen = strlen(session.securityName);

// set the authentication method to MD5     
session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;

session.securityAuthProto = usmHMACMD5AuthProtocol;
session.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
session.securityAuthKeyLen = USM_AUTH_KU_LEN;;

if (generate_Ku(session.securityAuthProto,
        session.securityAuthProtoLen,
        (u_char *) authpw.c_str(), strlen(authpw.c_str()),
        session.securityAuthKey,
        &session.securityAuthKeyLen) != SNMPERR_SUCCESS) {
    //if code reaches here, the creation of the security key was not successful

}

cout << "SecurityAuthProto - session: " << session.securityAuthProto[9] << " / SecurityAuthKey - session: " << session.securityAuthKey << endl;

ss = snmp_open(&session); /* establish the session */

if (!ss) {
    cout << "Couldn't open session1 correctly";
    exit(2);
}

cout << "SecurityAuthProto - ss: " << ss->securityAuthProto[9] << " / SecurityAuthKey - ss: " << ss->securityAuthKey << endl;

//send message
pdu = snmp_pdu_create(SNMP_MSG_GET);
read_objid(".1.3.6.1.2.1.1.1.0", anOID, &anOID_len);
snmp_add_null_var(pdu, anOID, anOID_len);
status = snmp_synch_response(ss, pdu, &response);

/*
 * Process the response.
 */
if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
    cout << "SNMP-read success" << endl;
} else {
    cout << "SNMP-read fail" << endl;
}

if (response)
    snmp_free_pdu(response);
if (!snmp_close(ss))
    cout << "Snmp closing failed" << endl;

/*
 * Second request: Only the authProto is changed from MD5 to SHA1. I expect,
 * that the snmp-get fails, but it still succeeds.
 */

snmp_sess_init(&session1);
session1.peername = ip;
session1.version = SNMP_VERSION_3;

/* set the SNMPv3 user name */
session1.securityName = strdup(user);
session1.securityNameLen = strlen(session1.securityName);

// set the authentication method to SHA1 
session1.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;

session1.securityAuthProto = usmHMACSHA1AuthProtocol;
session1.securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
session1.securityAuthKeyLen = USM_AUTH_KU_LEN;

if (generate_Ku(session1.securityAuthProto,
        session1.securityAuthProtoLen,
        (u_char *) authpw.c_str(), strlen(authpw.c_str()),
        session1.securityAuthKey,
        &session1.securityAuthKeyLen) != SNMPERR_SUCCESS) {
    //if code reaches here, the creation of the security key was not successful
}

cout << "SecurityAuthProto - session1: " << session1.securityAuthProto[9] << " / SecurityAuthKey - session1: " << session1.securityAuthKey << endl;

ss1 = snmp_open(&session1); /* establish the session */

if (!ss1) {
    cout << "Couldn't open session1 correctly";
    exit(2);
}

cout << "SecurityAuthProto - ss1: " << ss1->securityAuthProto[9] << " / SecurityAuthKey - ss1: " << ss1->securityAuthKey << endl;

//send message
pdu1 = snmp_pdu_create(SNMP_MSG_GET);
read_objid(".1.3.6.1.2.1.1.1.0", anOID, &anOID_len);
snmp_add_null_var(pdu1, anOID, anOID_len);
status1 = snmp_synch_response(ss1, pdu1, &response1);

/*
 * Process the response.
 */
if (status1 == STAT_SUCCESS && response1->errstat == SNMP_ERR_NOERROR) {
    cout << "SNMP-read success" << endl;
} else {
    cout << "SNMP-read fail" << endl;
}

if (response1)
    snmp_free_pdu(response1);
snmp_close(ss1);

return 0;
int main(int argc,char**argv){
结构snmp_会话会话,会话1,*ss,*ss1;
结构snmp_pdu*pdu,*pdu1;
结构snmp_pdu*响应,*响应1;
旧的异常[MAX_oid_LEN];
尺寸规格=最大尺寸;
结构变量列表*变量;
int状态,状态1;
初始化snmp(“snmpapp”);
const char*user=“md5”;
字符串authpw=“123123”;
字符串privpw=“”;
字符串ipString=“192.168.15.32”;
char-ip[16];
memset(&ip,0,sizeof(ip));
ipString.copy(ip,sizeof(ip)-1,0);
/*
*第一个请求:AuthProto是MD5,没有使用PrivProto
*请求成功
*/
snmp_sess_init(&session);/*设置默认值*/
session.peername=ip;
session.version=SNMP_version_3;
/*设置SNMPv3用户名*/
session.securityName=strdup(用户);
session.securityNameLen=strlen(session.securityName);
//将身份验证方法设置为MD5
session.securityLevel=SNMP_secu_LEVEL_AUTHNOPRIV;
session.securityAuthProto=usmHMACMD5AuthProtocol;
session.securityAuthProtoLen=USM\u AUTH\u PROTO\u MD5\u LEN;
session.securityAuthKeyLen=USM_AUTH_KU_LEN;;
如果(生成_Ku(session.securityAuthProto,
session.securityAuthProtoLen,
(u_char*)authpw.c_str(),strlen(authpw.c_str()),
session.securityAuthKey,
&session.securityAuthKeyLen)!=SNMPERR\u成功){
//如果代码到达此处,则安全密钥的创建不成功
}

我能自己找到解决办法吗

net snmp为用户的每个EngineId(设备)缓存。如果EngineId有一个现有用户,并且您尝试与该用户打开一个新会话,net snmp将使用缓存的会话。因此解决方案是清除缓存用户的列表

通过此代码片段,我可以解决我的问题:

usmUser* actUser = usm_get_userList();
while (actUser != NULL) {
    usmUser* dummy = actUser;
    usm_remove_user(actUser);
    actUser = dummy->next;
}

我希望我能在这方面帮助其他人。

您还可以更新现有用户的密码:

    for (usmUser* actUser = usm_get_userList(); actUser != NULL; actUser = actUser->next) {
        if (strcmp(actUser->secName, user) == 0) {
            //this method calls generate_Ku with previous security data but with specified password
            usm_set_user_password(actUser, "userSetAuthPass", authpw.c_str());
            break;
        }
    }