snmpm_usm.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 512 行 · 第 1/2 页
ERL
512 行
end.do_decrypt(Data, #usm_user{sec_name = SecName, priv = PrivP, priv_key = PrivKey}, #usmSecurityParameters{msgPrivacyParameters = PrivParms}) -> EncryptedPDU = snmp_pdus:dec_scoped_pdu_data(Data), try_decrypt(PrivP, PrivKey, PrivParms, EncryptedPDU, SecName).try_decrypt(usmNoPrivProtocol, _, _, _, SecName) -> % 3.2.5 error(usmStatsUnsupportedSecLevels, ?usmStatsUnsupportedSecLevels_instance, SecName);try_decrypt(usmDESPrivProtocol, PrivKey, MsgPrivParams, EncryptedPDU, SecName) -> case (catch des_decrypt(PrivKey, MsgPrivParams, EncryptedPDU)) of {ok, DecryptedData} -> DecryptedData; _ -> error(usmStatsDecryptionErrors, ?usmStatsDecryptionErrors, SecName) end;try_decrypt(usmAesCfb128Protocol, PrivKey, UsmSecParams, EncryptedPDU, SecName) -> case (catch aes_decrypt(PrivKey, UsmSecParams, EncryptedPDU)) of {ok, DecryptedData} -> DecryptedData; _ -> error(usmStatsDecryptionErrors, ?usmStatsDecryptionErrors, SecName) end. %%-----------------------------------------------------------------%% Func: process_outgoing_msg(Message, SecEngineID, SecName, %% SecData, SecLevel) ->%% {ok, {SecEngineID, SecName, ScopedPDUBytes, SecData}} |%% {error, Reason} | {error, Reason, ErrorInfo}%% Return value may be throwed.%% Types: Reason -> term()%% Purpose: %%-----------------------------------------------------------------generate_outgoing_msg(Message, SecEngineID, SecName, SecData, SecLevel) -> %% 3.1.1 ?vtrace("generate_outgoing_msg -> entry (3.1.1)",[]), {UserName, AuthProtocol, PrivProtocol, AuthKey, PrivKey} = case SecData of [] -> % 3.1.1b %% Not a response - read from LCD case snmpm_config:get_usm_user_from_sec_name(SecEngineID, SecName) of {ok, User} -> {User#usm_user.name, User#usm_user.auth, User#usm_user.priv, User#usm_user.auth_key, User#usm_user.priv_key}; _ -> error(unknownSecurityName) end; [MsgUserName] -> %% This means the user at the engine is unknown {MsgUserName, usmNoAuthProtocol, usmNoPrivProtocol, "", ""}; _ -> % 3.1.1a SecData end, %% 3.1.4 ?vtrace("generate_outgoing_msg -> (3.1.4)",[]), ScopedPduBytes = Message#message.data, {ScopedPduData, MsgPrivParams} = encrypt(ScopedPduBytes, PrivProtocol, PrivKey, SecLevel), SnmpEngineID = get_engine_id(), ?vtrace("SnmpEngineID: ~p (3.1.6)",[SnmpEngineID]), %% 3.1.6 {MsgAuthEngineBoots, MsgAuthEngineTime} = case snmp_misc:is_auth(SecLevel) of false when SecData == [] -> % not a response {0, 0}; true when SecEngineID /= SnmpEngineID -> {get_engine_boots(SecEngineID), get_engine_time(SecEngineID)}; _ -> {get_engine_boots(), get_engine_time()} end, %% 3.1.5 - 3.1.7 ?vtrace("generate_outgoing_msg -> (3.1.5 - 3.1.7)",[]), UsmSecParams = #usmSecurityParameters{msgAuthoritativeEngineID = SecEngineID, msgAuthoritativeEngineBoots = MsgAuthEngineBoots, msgAuthoritativeEngineTime = MsgAuthEngineTime, msgUserName = UserName, msgPrivacyParameters = MsgPrivParams}, Message2 = Message#message{data = ScopedPduData}, %% 3.1.8 ?vtrace("generate_outgoing_msg -> (3.1.8)",[]), authenticate_outgoing(Message2, UsmSecParams, AuthKey, AuthProtocol, SecLevel).%% Ret: {ScopedPDU, MsgPrivParams} - both are already encoded as OCTET STRINGsencrypt(Data, PrivProtocol, PrivKey, SecLevel) -> case snmp_misc:is_priv(SecLevel) of false -> % 3.1.4b {Data, []}; true -> % 3.1.4a case (catch try_encrypt(PrivProtocol, PrivKey, Data)) of {ok, ScopedPduData, MsgPrivParams} -> {snmp_pdus:enc_oct_str_tag(ScopedPduData), MsgPrivParams}; {error, Reason} -> error(Reason); _ -> error(encryptionError) end end.try_encrypt(usmNoPrivProtocol, _PrivKey, _Data) -> % 3.1.2 error(unsupportedSecurityLevel);try_encrypt(usmDESPrivProtocol, PrivKey, Data) -> des_encrypt(PrivKey, Data);try_encrypt(usmAesCfb128Protocol, PrivKey, Data) -> aes_encrypt(PrivKey, Data).authenticate_outgoing(Message, UsmSecParams, AuthKey, AuthProtocol, SecLevel) -> Message2 = case snmp_misc:is_auth(SecLevel) of true -> auth_out(AuthProtocol, AuthKey, Message, UsmSecParams); false -> set_msg_auth_params(Message, UsmSecParams) end, snmp_pdus:enc_message_only(Message2). %%-----------------------------------------------------------------%% Auth and priv algorithms%%-----------------------------------------------------------------auth_in(AuthProtocol, AuthKey, AuthParams, Packet) -> snmp_usm:auth_in(AuthProtocol, AuthKey, AuthParams, Packet).auth_out(AuthProtocol, AuthKey, Message, UsmSecParams) -> snmp_usm:auth_out(AuthProtocol, AuthKey, Message, UsmSecParams).set_msg_auth_params(Message, UsmSecParams) -> snmp_usm:set_msg_auth_params(Message, UsmSecParams, []).des_encrypt(PrivKey, Data) -> snmp_usm:des_encrypt(PrivKey, Data, fun get_des_salt/0).des_decrypt(PrivKey, MsgPrivParams, EncData) -> snmp_usm:des_decrypt(PrivKey, MsgPrivParams, EncData).get_des_salt() -> SaltInt = snmpm_config:incr_counter(usm_des_salt, 1), EngineBoots = get_engine_boots(), [?i32(EngineBoots), ?i32(SaltInt)].aes_encrypt(PrivKey, Data) -> snmp_usm:aes_encrypt(PrivKey, Data, fun get_aes_salt/0).aes_decrypt(PrivKey, UsmSecParams, EncData) -> #usmSecurityParameters{msgPrivacyParameters = MsgPrivParams, msgAuthoritativeEngineTime = EngineTime, msgAuthoritativeEngineBoots = EngineBoots} = UsmSecParams, snmp_usm:aes_decrypt(PrivKey, MsgPrivParams, EncData, EngineBoots, EngineTime).get_aes_salt() -> SaltInt = snmpm_config:incr_counter(usm_aes_salt, 1), [?i64(SaltInt)].%%-----------------------------------------------------------------get_engine_id() -> {ok, EngineID} = snmpm_config:get_engine_id(), EngineID.get_engine_boots() -> {ok, Boots} = snmpm_config:get_engine_boots(), Boots.get_engine_time() -> {ok, Diff} = snmpm_config:get_engine_time(), Diff.%%-----------------------------------------------------------------%% We cache the local values of all non-auth engines we know.%% See section 2.3 (Time Synchronization) of the RFC.%%-----------------------------------------------------------------get_engine_boots(SnmpEngineID) -> {ok, Boots} = snmpm_config:get_usm_eboots(SnmpEngineID), Boots.get_engine_time(SnmpEngineID) -> {ok, Diff} = snmpm_config:get_usm_etime(SnmpEngineID), Diff. get_engine_latest_time(SnmpEngineID) -> {ok, Time} = snmpm_config:get_usm_eltime(SnmpEngineID), Time. set_engine_boots(SnmpEngineID, EngineBoots) -> snmpm_config:set_usm_eboots(SnmpEngineID, EngineBoots).set_engine_time(SnmpEngineID, EngineTime) -> Diff = snmp_misc:now(sec) - EngineTime, snmpm_config:set_usm_etime(SnmpEngineID, Diff).set_engine_latest_time(SnmpEngineID, EngineTime) -> snmpm_config:set_usm_eltime(SnmpEngineID, EngineTime).%%-----------------------------------------------------------------%% Utility functions%%-----------------------------------------------------------------error(Reason) -> throw({error, Reason}).error(Reason, ErrorInfo) -> throw({error, Reason, ErrorInfo}).error(Variable, Oid, SecName) -> error(Variable, Oid, SecName, []).error(Variable, Oid, SecName, Opts) -> Val = inc(Variable), ErrorInfo = {#varbind{oid = Oid, variabletype = 'Counter32', value = Val}, SecName, Opts}, throw({error, Variable, ErrorInfo}).%%-----------------------------------------------------------------init_counters() -> F = fun(Counter) -> snmpm_config:maybe_cre_stats_counter(Counter, 0) end, lists:map(F, counters()).reset() -> F = fun(Counter) -> snmpm_config:reset_stats_counter(Counter) end, lists:map(F, counters()).counters() -> [usmStatsUnsupportedSecLevels, usmStatsNotInTimeWindows, usmStatsUnknownUserNames, usmStatsUnknownEngineIDs, usmStatsWrongDigests, usmStatsDecryptionErrors].inc(Name) -> snmpm_config:incr_stats_counter(Name, 1).
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?