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 + -
显示快捷键?