首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >net-snmp没有正确地更改auth和priv协议。

net-snmp没有正确地更改auth和priv协议。
EN

Stack Overflow用户
提问于 2013-08-22 12:28:13
回答 2查看 2.1K关注 0票数 3

我在Linux下的c++程序中使用net库(Version5.7.1)。我有一个Web前端,用户可以选择SNMP版本并对其进行配置。SNMPv1和SNMPv2工作得很好,但我对SNMPv3有一些意见。

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

当我启动c++后端并正确输入所有所需的SNMPv3凭据时,一切正常,设备可以到达。例如,如果我将Auth协议从MD5更改为SHA,但将其余凭据保持不变,我预计设备将无法再访问。在现实中,它始终是可触及的。在重新启动后端后,设备(如预期的那样)不再可以用相同的设置到达。

在发现这个问题后,我做了一些测试。在测试中,我使用了不同的用户和不同的设置。他们运行的三个不同的设备,不同的供应商,我每次都得到相同的结果。因此,它不能实现设备的问题。结果可以在这里看到:测试结果

经过测试,我的结论是,net似乎将选定的auth和priv协议缓存为一个用户名。在Test 2中可以看到这一点,当我第一次使用带有特定协议的用户名时,我就得到了预期的结果。在更改协议之后,期望得到不同的结果,但我仍然得到了与以前相同的结果。

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

  • 有一个名为SNMPWrapper的类,它分配整个SNMP通信。
  • 在构造函数中,我将init_snmp()调用到init。
  • 从外部看,我只能调用get()set()walk()。每次调用这些方法之一时,都会创建一个新的SNMP会话(首先,我用snmp_sess_init()创建一个新会话,而不是设置所需的内容,最后用snmp_sess_open()打开会话)。
  • 在我提出请求并收到我的答复后,我将结束与snmp_sess_close()的会话。

问题:,为了使它正常工作,在更改协议之前,我还需要做其他清理吗?

Edit我添加了一些代码,它显示了所描述的行为

代码语言:javascript
运行
复制
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;

}

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-27 13:00:13

我自己找到了解决办法:

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

有了这个代码片段,我可以解决我的问题:

代码语言:javascript
运行
复制
usmUser* actUser = usm_get_userList();
while (actUser != NULL) {
    usmUser* dummy = actUser;
    usm_remove_user(actUser);
    actUser = dummy->next;
}

我希望我能帮到别人。

票数 6
EN

Stack Overflow用户

发布于 2019-05-01 13:31:27

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

代码语言:javascript
运行
复制
    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;
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18380435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档