1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2006-2019. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21-module(snmpa_conf).
22
23%% Avoid warning for local function error/1 clashing with autoimported BIF.
24-compile({no_auto_import,[error/1]}).
25-export([
26	 %% agent.conf
27	 agent_entry/2,
28	 write_agent_config/2, write_agent_config/3,
29	 append_agent_config/2,
30	 read_agent_config/1,
31
32	 %% context.conf
33	 context_entry/1,
34	 write_context_config/2, write_context_config/3,
35	 append_context_config/2,
36	 read_context_config/1,
37
38	 %% community.conf
39	 community_entry/1, community_entry/5,
40	 write_community_config/2, write_community_config/3,
41	 append_community_config/2,
42	 read_community_config/1,
43
44	 %% standard.conf
45	 standard_entry/2,
46	 write_standard_config/2, write_standard_config/3,
47	 append_standard_config/2,
48	 read_standard_config/1,
49
50	 %% target_addr.conf
51	 target_addr_entry/5, target_addr_entry/6,  target_addr_entry/7,
52	 target_addr_entry/8, target_addr_entry/10, target_addr_entry/11,
53	 write_target_addr_config/2, write_target_addr_config/3,
54	 append_target_addr_config/2,
55	 read_target_addr_config/1,
56
57	 %% target_params.conf
58	 target_params_entry/2, target_params_entry/4, target_params_entry/5,
59	 write_target_params_config/2, write_target_params_config/3,
60	 append_target_params_config/2,
61	 read_target_params_config/1,
62
63	 %% xyz.conf
64	 notify_entry/3,
65	 write_notify_config/2, write_notify_config/3,
66	 append_notify_config/2,
67	 read_notify_config/1,
68
69	 %% xyz.conf
70	 usm_entry/1, usm_entry/13,
71	 write_usm_config/2, write_usm_config/3,
72	 append_usm_config/2,
73	 read_usm_config/1,
74
75	 %% xyz.conf
76	 vacm_s2g_entry/3,
77	 vacm_acc_entry/8,
78	 vacm_vtf_entry/2, vacm_vtf_entry/4,
79	 write_vacm_config/2, write_vacm_config/3,
80	 append_vacm_config/2,
81 	 read_vacm_config/1
82	]).
83
84
85
86-export_type([
87              usm_entry/0
88             ]).
89
90-type usm_entry() :: {
91                      EngineID    :: string(),
92                      UserName    :: string(),
93                      SecName     :: string(),
94                      Clone       :: zeroDotZero | [non_neg_integer()],
95                      AuthP       :: usmNoAuthProtocol |
96                                     usmHMACMD5AuthProtocol |
97                                     usmHMACSHAAuthProtocol,
98                      AuthKeyC    :: string(),
99                      OwnAuthKeyC :: string(),
100                      PrivP       :: usmNoPrivProtocol |
101                                     usmDESPrivProtocol |
102                                     usmAesCfb128Protocol,
103                      PrivKeyC    :: string(),
104                      OwnPrivKeyC :: string(),
105                      Public      :: string(),
106                      %% Size 16 for usmHMACMD5AuthProtocol
107                      %% Size 20 for usmHMACSHAAuthProtocol
108                      AuthKey     :: [non_neg_integer()],
109                      %% Size 16 for usmDESPrivProtocol | usmAesCfb128Protocol
110                      PrivKey     :: [non_neg_integer()]
111                     }.
112
113
114%%
115%% ------ agent.conf ------
116%%
117
118agent_entry(Tag, Val) ->
119    {Tag, Val}.
120
121
122write_agent_config(Dir, Conf) ->
123    Comment =
124"%% This file defines the Agent local configuration info\n"
125"%% The data is inserted into the snmpEngine* variables defined\n"
126"%% in SNMP-FRAMEWORK-MIB, and the intAgent* variables defined\n"
127"%% in OTP-SNMPEA-MIB.\n"
128"%% Each row is a 2-tuple:\n"
129"%% {AgentVariable, Value}.\n"
130"%% For example\n"
131"%% {intAgentUDPPort, 4000}.\n"
132"%% The ip address for the agent is sent as id in traps.\n"
133"%% {intAgentIpAddress, [127,42,17,5]}.\n"
134"%% {snmpEngineID, \"agentEngine\"}.\n"
135"%% {snmpEngineMaxMessageSize, 484}.\n"
136"%%\n\n",
137    Hdr = header() ++ Comment,
138    write_agent_config(Dir, Hdr, Conf).
139
140write_agent_config(Dir, Hdr, Conf)
141  when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
142    Order = fun snmp_framework_mib:order_agent/2,
143    Check = fun snmp_framework_mib:check_agent/2,
144    Write = fun (Fd, Entries) -> write_agent_conf(Fd, Hdr, Entries) end,
145    write_config_file(Dir, "agent.conf", Order, Check, Write, Conf).
146
147append_agent_config(Dir, Conf)
148  when is_list(Dir) and is_list(Conf) ->
149    Order = fun snmp_framework_mib:order_agent/2,
150    Check = fun snmp_framework_mib:check_agent/2,
151    Write = fun write_agent_conf/2,
152    append_config_file(Dir, "agent.conf", Order, Check, Write, Conf).
153
154read_agent_config(Dir) ->
155    Order = fun snmp_framework_mib:order_agent/2,
156    Check = fun snmp_framework_mib:check_agent/2,
157    read_config_file(Dir, "agent.conf", Order, Check).
158
159
160write_agent_conf(Fd, "", Conf) ->
161    write_agent_conf(Fd, Conf);
162write_agent_conf(Fd, Hdr, Conf) ->
163    io:format(Fd, "~s~n", [Hdr]),
164    write_agent_conf(Fd, Conf).
165
166write_agent_conf(_Fd, []) ->
167    ok;
168write_agent_conf(Fd, [H|T]) ->
169    do_write_agent_conf(Fd, H),
170    write_agent_conf(Fd, T).
171
172do_write_agent_conf(Fd, {intAgentTransports = Tag, Val}) ->
173    io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
174do_write_agent_conf(Fd, {intAgentTransportDomain = Tag, Val}) ->
175    io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
176do_write_agent_conf(Fd, {intAgentIpAddress = Tag, Val}) ->
177    io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
178do_write_agent_conf(Fd, {intAgentUDPPort = Tag, Val} ) ->
179    io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
180do_write_agent_conf(Fd, {intAgentMaxPacketSize = Tag, Val} ) ->
181    io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
182do_write_agent_conf(Fd, {snmpEngineMaxMessageSize = Tag, Val} ) ->
183    io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
184do_write_agent_conf(Fd, {snmpEngineID = Tag, Val} ) ->
185    io:format(Fd, "{~w, ~p}.~n", [Tag, Val]);
186do_write_agent_conf(_Fd, Crap) ->
187    error({bad_agent_config, Crap}).
188
189
190%%
191%% ------ context.conf ------
192%%
193
194context_entry(Ctx) ->
195    Ctx.
196
197
198write_context_config(Dir, Conf) ->
199    Comment =
200"%% This file defines the contexts known to the agent.\n"
201"%% The data is inserted into the vacmContextTable defined\n"
202"%% in SNMP-VIEW-BASED-ACM-MIB.\n"
203"%% Each row is a string:\n"
204"%% ContextName.\n"
205"%%\n"
206"%% The empty string is the default context.\n"
207"%% For example\n"
208"%% \"bridge1\".\n"
209"%% \"bridge2\".\n"
210"%%\n\n",
211    Hdr = header() ++ Comment,
212    write_context_config(Dir, Hdr, Conf).
213
214write_context_config(Dir, Hdr, Conf)
215  when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
216    Order = fun snmp_conf:no_order/2,
217    Check = fun check_context/2,
218    Write = fun (Fd, Entries) -> write_context_conf(Fd, Hdr, Entries) end,
219    write_config_file(Dir, "context.conf", Order, Check, Write, Conf).
220
221append_context_config(Dir, Conf)
222  when is_list(Dir) and is_list(Conf) ->
223    Order = fun snmp_conf:no_order/2,
224    Check = fun check_context/2,
225    Write = fun write_context_conf/2,
226    append_config_file(Dir, "context.conf", Order, Check, Write, Conf).
227
228read_context_config(Dir) ->
229    Order = fun snmp_conf:no_order/2,
230    Check = fun check_context/2,
231    read_config_file(Dir, "context.conf", Order, Check).
232
233
234check_context(Entry, State) ->
235    {check_ok(snmp_framework_mib:check_context(Entry)),
236     State}.
237
238write_context_conf(Fd, "", Conf) ->
239    write_context_conf(Fd, Conf);
240write_context_conf(Fd, Hdr, Conf) ->
241    io:format(Fd, "~s~n", [Hdr]),
242    write_context_conf(Fd, Conf).
243
244write_context_conf(_Fd, []) ->
245    ok;
246write_context_conf(Fd, [H|T]) when is_list(H) ->
247    io:format(Fd, "\"~s\".~n", [H]),
248    write_context_conf(Fd, T);
249write_context_conf(_Fd, X) ->
250    error({invalid_context_config, X}).
251
252
253%%
254%% ------ community.conf ------
255%%
256
257community_entry(CommIndex) when CommIndex == "public" ->
258    CommName     = CommIndex,
259    SecName      = "initial",
260    CtxName      = "",
261    TransportTag = "",
262    community_entry(CommIndex, CommName, SecName, CtxName, TransportTag);
263community_entry(CommIndex) when CommIndex == "all-rights" ->
264    CommName     = CommIndex,
265    SecName      = CommIndex,
266    CtxName      = "",
267    TransportTag = "",
268    community_entry(CommIndex, CommName, SecName, CtxName, TransportTag).
269
270community_entry(CommIndex, CommName, SecName, CtxName, TransportTag) ->
271    {CommIndex, CommName, SecName, CtxName, TransportTag}.
272
273
274write_community_config(Dir, Conf) ->
275    Comment =
276"%% This file defines the community info which maps to VACM parameters.\n"
277"%% The data is inserted into the snmpCommunityTable defined\n"
278"%% in SNMP-COMMUNITY-MIB.\n"
279"%% Each row is a 5-tuple:\n"
280"%% {CommunityIndex, CommunityName, SecurityName, ContextName, TransportTag}.\n"
281"%% For example\n"
282"%% {\"1\", \"public\", \"initial\", \"\", \"\"}.\n"
283"%% {\"2\", \"secret\", \"secret_name\", \"\", \"tag\"}.\n"
284"%% {\"3\", \"bridge1\", \"initial\", \"bridge1\", \"\"}.\n"
285"%%\n\n",
286    Hdr = header() ++ Comment,
287    write_community_config(Dir, Hdr, Conf).
288
289write_community_config(Dir, Hdr, Conf)
290  when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
291    Order = fun snmp_conf:no_order/2,
292    Check = fun check_community/2,
293    Write = fun (Fd, Entries) -> write_community_conf(Fd, Hdr, Entries) end,
294    write_config_file(Dir, "community.conf", Order, Check, Write, Conf).
295
296append_community_config(Dir, Conf)
297  when is_list(Dir) and is_list(Conf) ->
298    Order = fun snmp_conf:no_order/2,
299    Check = fun check_community/2,
300    Write = fun write_community_conf/2,
301    append_config_file(Dir, "community.conf", Order, Check, Write, Conf).
302
303read_community_config(Dir) ->
304    Order = fun snmp_conf:no_order/2,
305    Check = fun check_community/2,
306    read_config_file(Dir, "community.conf", Order, Check).
307
308
309check_community(Entry, State) ->
310    {check_ok(snmp_community_mib:check_community(Entry)),
311     State}.
312
313write_community_conf(Fd, "", Conf) ->
314    write_community_conf(Fd, Conf);
315write_community_conf(Fd, Hdr, Conf) ->
316    io:format(Fd, "~s~n", [Hdr]),
317    write_community_conf(Fd, Conf).
318
319write_community_conf(Fd, Conf) ->
320    Fun =
321	fun({Idx, Name, SecName, CtxName, TranspTag}) ->
322		io:format(
323		  Fd,
324		  "{\"~s\", \"~s\", \"~s\", \"~s\", \"~s\"}.~n",
325		  [Idx, Name, SecName, CtxName, TranspTag]);
326	     (Crap) ->
327		error({bad_community_config, Crap})
328	end,
329    lists:foreach(Fun, Conf).
330
331
332%%
333%% ------ standard.conf ------
334%%
335
336standard_entry(Tag, Val) ->
337    {Tag, Val}.
338
339
340write_standard_config(Dir, Conf) ->
341    Comment =
342"%% This file defines the STANDARD-MIB info.\n"
343"%% Each row is a 2-tuple:\n"
344"%% {StandardVariable, Value}.\n"
345"%% For example\n"
346"%% {sysDescr, \"Erlang SNMP agent\"}.\n"
347"%% {sysObjectID, [1,2,3]}.\n"
348"%% {sysContact, \"{mbj,eklas}@erlang.ericsson.se\"}.\n"
349"%% {sysName, \"test\"}.\n"
350"%% {sysLocation, \"erlang\"}.\n"
351"%% {sysServices, 72}.\n"
352"%% {snmpEnableAuthenTraps, enabled}.\n"
353"%%\n\n",
354    Hdr = header() ++ Comment,
355    write_standard_config(Dir, Hdr, Conf).
356
357write_standard_config(Dir, Hdr, Conf)
358  when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
359    Order = fun snmp_conf:no_order/2,
360    Check = fun check_standard/2,
361    Write = fun (Fd, Entries) -> write_standard_conf(Fd, Hdr, Entries) end,
362    write_config_file(Dir, "standard.conf", Order, Check, Write, Conf).
363
364append_standard_config(Dir, Conf)
365  when is_list(Dir) and is_list(Conf) ->
366    Order = fun snmp_conf:no_order/2,
367    Check = fun check_standard/2,
368    Write = fun write_standard_conf/2,
369    append_config_file(Dir, "standard.conf", Order, Check, Write, Conf).
370
371read_standard_config(Dir) ->
372    Order = fun snmp_conf:no_order/2,
373    Check = fun check_standard/2,
374    read_config_file(Dir, "standard.conf", Order, Check).
375
376
377check_standard(Entry, State) ->
378    {check_ok(snmp_standard_mib:check_standard(Entry)),
379     State}.
380
381write_standard_conf(Fd, "", Conf) ->
382    write_standard_conf(Fd, Conf);
383write_standard_conf(Fd, Hdr, Conf) ->
384    io:format(Fd, "~s~n", [Hdr]),
385    write_standard_conf(Fd, Conf).
386
387write_standard_conf(Fd, Conf) ->
388    Fun = fun({Tag, Val}) -> do_write_standard_conf(Fd, Tag, Val) end,
389    lists:foreach(Fun, Conf).
390
391do_write_standard_conf(Fd, sysDescr = Tag, Val) ->
392    io:format(Fd, "{~w, \"~s\"}.~n", [Tag, Val]);
393do_write_standard_conf(Fd, sysObjectID = Tag, Val) ->
394    io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
395do_write_standard_conf(Fd, sysContact = Tag,  Val) ->
396    io:format(Fd, "{~w, \"~s\"}.~n", [Tag, Val]);
397do_write_standard_conf(Fd, sysName = Tag,     Val) ->
398    io:format(Fd, "{~w, \"~s\"}.~n", [Tag, Val]);
399do_write_standard_conf(Fd, sysLocation = Tag, Val) ->
400    io:format(Fd, "{~w, \"~s\"}.~n", [Tag, Val]);
401do_write_standard_conf(Fd, sysServices = Tag, Val) ->
402    io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
403do_write_standard_conf(Fd, snmpEnableAuthenTraps = Tag, Val) ->
404    io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
405do_write_standard_conf(_Fd, Tag, Val) ->
406    error({bad_standard_config, {Tag, Val}}).
407
408
409%%
410%% ------ target_addr.conf ------
411%%
412
413target_addr_entry(
414  Name, Ip, TagList, ParamsName, EngineId) ->
415    target_addr_entry(Name, Ip, TagList, ParamsName, EngineId, []).
416
417target_addr_entry(
418  Name, Domain, Addr, TagList,
419  ParamsName, EngineId) when is_atom(Domain) ->
420    target_addr_entry(
421      Name, Domain, Addr, TagList,
422      ParamsName, EngineId, []);
423target_addr_entry(
424  Name, Ip, TagList, ParamsName,
425  EngineId, TMask) ->
426    target_addr_entry(
427      Name, Ip, 162, TagList, ParamsName,
428      EngineId, TMask, 2048).
429
430target_addr_entry(
431  Name, Domain_or_Ip, Addr_or_Port, TagList,
432  ParamsName, EngineId, TMask) ->
433    target_addr_entry(
434      Name, Domain_or_Ip, Addr_or_Port, TagList,
435      ParamsName, EngineId, TMask, 2048).
436
437target_addr_entry(
438  Name, Domain_or_Ip, Addr_or_Port, TagList,
439  ParamsName, EngineId, TMask, MaxMessageSize) ->
440    target_addr_entry(
441      Name, Domain_or_Ip, Addr_or_Port, 1500, 3, TagList,
442      ParamsName, EngineId, TMask, MaxMessageSize).
443
444target_addr_entry(
445  Name, Domain_or_Ip, Addr_or_Port, Timeout, RetryCount, TagList,
446  ParamsName, EngineId, TMask, MaxMessageSize) ->
447    {Name, Domain_or_Ip, Addr_or_Port, Timeout, RetryCount, TagList,
448     ParamsName, EngineId, TMask, MaxMessageSize}.
449
450target_addr_entry(
451  Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
452  ParamsName, EngineId,TMask, MaxMessageSize) ->
453    {Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
454     ParamsName, EngineId, TMask, MaxMessageSize}.
455
456
457write_target_addr_config(Dir, Conf) ->
458    Comment =
459"%% This file defines the target address parameters.\n"
460"%% The data is inserted into the snmpTargetAddrTable defined\n"
461"%% in SNMP-TARGET-MIB, and in the snmpTargetAddrExtTable defined\n"
462"%% in SNMP-COMMUNITY-MIB.\n"
463"%% Each row is a 10 or 11-tuple (Domain is optional):\n"
464"%% {Name, \n"
465"%%  Domain, Ip, Port, \n"
466"%%  Timeout, RetryCount, TagList, ParamsName, EngineId,\n"
467"%%  TMask, MaxMessageSize}.\n"
468"%% The value of Domain decide the format of the Ip and TMask values. \n"
469"%% If not present, classic Ipv4 is assumed. \n"
470"%% The EngineId value is only used if Inform-Requests are sent to this\n"
471"%% target.  If Informs are not sent, this value is ignored, and can be\n"
472"%% e.g. an empty string.  However, if Informs are sent, it is essential\n"
473"%% that the value of EngineId matches the value of the target's\n"
474"%% actual snmpEngineID.\n"
475"%% For example\n"
476"%% {\"1.2.3.4 v1\", [1,2,3,4], 162, \n"
477"%%  1500, 3, \"std_inform\", \"otp_v2\", \"\",\n"
478"%%  [127,0,0,0],  2048}.\n"
479"%%\n\n",
480    Hdr = header() ++ Comment,
481    write_target_addr_config(Dir, Hdr, Conf).
482
483write_target_addr_config(Dir, Hdr, Conf)
484  when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
485    Order = fun snmp_conf:no_order/2,
486    Check = fun check_target_addr/2,
487    Write = fun (Fd, Entries) -> write_target_addr_conf(Fd, Hdr, Entries) end,
488    write_config_file(Dir, "target_addr.conf", Order, Check, Write, Conf).
489
490append_target_addr_config(Dir, Conf)
491  when is_list(Dir) and is_list(Conf) ->
492    Order = fun snmp_conf:no_order/2,
493    Check = fun check_target_addr/2,
494    Write = fun write_target_addr_conf/2,
495    append_config_file(Dir, "target_addr.conf", Order, Check, Write, Conf).
496
497read_target_addr_config(Dir) ->
498    Order = fun snmp_conf:no_order/2,
499    Check = fun check_target_addr/2,
500    read_config_file(Dir, "target_addr.conf", Order, Check).
501
502
503check_target_addr(Entry, State) ->
504    {check_ok(snmp_target_mib:check_target_addr(Entry)),
505     State}.
506
507write_target_addr_conf(Fd, "", Conf) ->
508    write_target_addr_conf(Fd, Conf);
509write_target_addr_conf(Fd, Hdr, Conf) ->
510    io:format(Fd, "~s~n", [Hdr]),
511    write_target_addr_conf(Fd, Conf).
512
513write_target_addr_conf(Fd, Conf) ->
514    Fun = fun(Entry) -> do_write_target_addr_conf(Fd, Entry) end,
515    lists:foreach(Fun, Conf),
516    ok.
517
518do_write_target_addr_conf(
519  Fd,
520  {Name, Domain, Address, Timeout, RetryCount, TagList,
521   ParamsName, EngineId, TMask, MaxMessageSize})
522  when is_atom(Domain) ->
523    io:format(
524      Fd,
525      "{\"~s\", ~w, ~w, ~w, ~w, \"~s\", \"~s\", \"~s\", ~w, ~w}.~n",
526      [Name, Domain, Address, Timeout, RetryCount, TagList,
527       ParamsName, EngineId, TMask, MaxMessageSize]);
528do_write_target_addr_conf(
529  Fd,
530  {Name, Ip, Udp, Timeout, RetryCount, TagList,
531   ParamsName, EngineId, TMask, MaxMessageSize})
532  when is_integer(Udp) ->
533    Domain = snmp_target_mib:default_domain(),
534    Address = {Ip, Udp},
535    do_write_target_addr_conf(
536      Fd,
537      {Name, Domain, Address, Timeout, RetryCount, TagList,
538       ParamsName, EngineId, TMask, MaxMessageSize});
539do_write_target_addr_conf(
540  _Fd,
541  {_Name, Domain, Address, _Timeout, _RetryCount, _TagList,
542   _ParamsName, _EngineId, _TMask, _MaxMessageSize}) ->
543    error({bad_address, {Domain, Address}});
544do_write_target_addr_conf(
545  Fd,
546  {Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
547   ParamsName, EngineId, TMask, MaxMessageSize}) ->
548    Address = {Ip, Udp},
549    do_write_target_addr_conf(
550      Fd,
551      {Name, Domain, Address, Timeout, RetryCount, TagList,
552       ParamsName, EngineId, TMask, MaxMessageSize});
553do_write_target_addr_conf(_Fd, Crap) ->
554    error({bad_target_addr_config, Crap}).
555
556
557%%
558%% ------ target_params.conf ------
559%%
560
561target_params_entry(Name, Vsn) ->
562    SecName  = "initial",
563    SecLevel = noAuthNoPriv,
564    target_params_entry(Name, Vsn, SecName, SecLevel).
565
566target_params_entry(Name, Vsn, SecName, SecLevel) ->
567    MPModel = if Vsn =:= v1 -> v1;
568		 Vsn =:= v2 -> v2c;
569		 Vsn =:= v3 -> v3
570	      end,
571    SecModel = if Vsn =:= v1 -> v1;
572		  Vsn =:= v2 -> v2c;
573		  Vsn =:= v3 -> usm
574	       end,
575    target_params_entry(Name, MPModel, SecModel, SecName, SecLevel).
576
577target_params_entry(Name, MPModel, SecModel, SecName, SecLevel) ->
578    {Name, MPModel, SecModel, SecName, SecLevel}.
579
580
581write_target_params_config(Dir, Conf) ->
582    Comment =
583"%% This file defines the target parameters.\n"
584"%% The data is inserted into the snmpTargetParamsTable defined\n"
585"%% in SNMP-TARGET-MIB.\n"
586"%% Each row is a 5-tuple:\n"
587"%% {Name, MPModel, SecurityModel, SecurityName, SecurityLevel}.\n"
588"%% For example\n"
589"%% {\"target_v3\", v3, usm, \"\", noAuthNoPriv}.\n"
590"%%\n\n",
591    Hdr = header() ++ Comment,
592    write_target_params_config(Dir, Hdr, Conf).
593
594write_target_params_config(Dir, Hdr, Conf)
595  when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
596    Order = fun snmp_conf:no_order/2,
597    Check = fun check_target_params/2,
598    Write = fun (Fd, Entries) -> write_target_params_conf(Fd, Hdr, Entries) end,
599    write_config_file(Dir, "target_params.conf", Order, Check, Write, Conf).
600
601append_target_params_config(Dir, Conf)
602  when is_list(Dir) and is_list(Conf) ->
603    Order = fun snmp_conf:no_order/2,
604    Check = fun check_target_params/2,
605    Write = fun write_target_params_conf/2,
606    append_config_file(Dir, "target_params.conf", Order, Check, Write, Conf).
607
608read_target_params_config(Dir) ->
609    Order = fun snmp_conf:no_order/2,
610    Check = fun check_target_params/2,
611    read_config_file(Dir, "target_params.conf", Order, Check).
612
613
614check_target_params(Entry, State) ->
615    {check_ok(snmp_target_mib:check_target_params(Entry)),
616     State}.
617
618write_target_params_conf(Fd, "", Conf) ->
619    write_target_params_conf(Fd, Conf);
620write_target_params_conf(Fd, Hdr, Conf) ->
621    io:format(Fd, "~s~n", [Hdr]),
622    write_target_params_conf(Fd, Conf).
623
624write_target_params_conf(Fd, Conf) ->
625    Fun = fun(Entry) -> do_write_target_params_conf(Fd, Entry) end,
626    lists:foreach(Fun, Conf).
627
628do_write_target_params_conf(Fd,
629			    {Name, MpModel, SecModel, SecName, SecLevel}) ->
630    io:format(Fd, "{\"~s\", ~w, ~w, \"~s\", ~w}.~n",
631              [Name, MpModel, SecModel, SecName, SecLevel]);
632do_write_target_params_conf(_Fd, Crap) ->
633    error({bad_target_params_config, Crap}).
634
635
636%%
637%% ------ notify.conf ------
638%%
639
640notify_entry(Name, Tag, Type) ->
641    {Name, Tag, Type}.
642
643
644write_notify_config(Dir, Conf) ->
645    Comment =
646"%% This file defines the notification parameters.\n"
647"%% The data is inserted into the snmpNotifyTable defined\n"
648"%% in SNMP-NOTIFICATION-MIB.\n"
649"%% The Name is used as CommunityString for v1 and v2c.\n"
650"%% Each row is a 3-tuple:\n"
651"%% {Name, Tag, Type}.\n"
652"%% For example\n"
653"%% {\"standard trap\", \"std_trap\", trap}.\n"
654"%% {\"standard inform\", \"std_inform\", inform}.\n"
655"%%\n\n",
656    Hdr = header() ++ Comment,
657    write_notify_config(Dir, Hdr, Conf).
658
659write_notify_config(Dir, Hdr, Conf)
660  when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
661    Order = fun snmp_conf:no_order/2,
662    Check = fun check_notify/2,
663    Write = fun (Fd, Entries) -> write_notify_conf(Fd, Hdr, Entries) end,
664    write_config_file(Dir, "notify.conf", Order, Check, Write, Conf).
665
666append_notify_config(Dir, Conf)
667  when is_list(Dir) and is_list(Conf) ->
668    Order = fun snmp_conf:no_order/2,
669    Check = fun check_notify/2,
670    Write = fun write_notify_conf/2,
671    append_config_file(Dir, "notify.conf", Order, Check, Write, Conf).
672
673read_notify_config(Dir) ->
674    Order = fun snmp_conf:no_order/2,
675    Check = fun check_notify/2,
676    read_config_file(Dir, "notify.conf", Order, Check).
677
678
679check_notify(Entry, State) ->
680    {check_ok(snmp_notification_mib:check_notify(Entry)),
681     State}.
682
683write_notify_conf(Fd, "", Conf) ->
684    write_notify_conf(Fd, Conf);
685write_notify_conf(Fd, Hdr, Conf) ->
686    io:format(Fd, "~s~n", [Hdr]),
687    write_notify_conf(Fd, Conf).
688
689write_notify_conf(Fd, Conf) ->
690    Fun = fun(Entry) -> do_write_notify_conf(Fd, Entry) end,
691    lists:foreach(Fun, Conf).
692
693do_write_notify_conf(Fd, {Name, Tag, Type}) ->
694    io:format(Fd, "{\"~s\", \"~s\", ~w}.~n", [Name, Tag, Type]);
695do_write_notify_conf(_Fd, Crap) ->
696    error({bad_notify_config, Crap}).
697
698
699%%
700%% ------ usm.conf ------
701%%
702
703usm_entry(EngineID) ->
704    UserName    = "initial",
705    SecName     = "initial",
706    Clone       = zeroDotZero,
707    AuthP       = usmNoAuthProtocol,
708    AuthKeyC    = "",
709    OwnAuthKeyC = "",
710    PrivP       = usmNoPrivProtocol,
711    PrivKeyC    = "",
712    OwnPrivKeyC = "",
713    Public      = "",
714    AuthKey     = "",
715    PrivKey     = "",
716    usm_entry(EngineID, UserName, SecName, Clone,
717	      AuthP, AuthKeyC, OwnAuthKeyC,
718              PrivP, PrivKeyC, OwnPrivKeyC,
719              Public, AuthKey, PrivKey).
720
721usm_entry(EngineID, UserName, SecName, Clone,
722	  AuthP, AuthKeyC, OwnAuthKeyC,
723	  PrivP, PrivKeyC, OwnPrivKeyC,
724	  Public, AuthKey, PrivKey) ->
725    {EngineID, UserName, SecName, Clone,
726     AuthP, AuthKeyC, OwnAuthKeyC,
727     PrivP, PrivKeyC, OwnPrivKeyC,
728     Public, AuthKey, PrivKey}.
729
730
731write_usm_config(Dir, Conf) ->
732    Comment =
733"%% This file defines the security parameters for the user-based\n"
734"%% security model.\n"
735"%% The data is inserted into the usmUserTable defined\n"
736"%% in SNMP-USER-BASED-SM-MIB.\n"
737"%% Each row is a 13-tuple:\n"
738"%% {EngineID, UserName, SecName, Clone, AuthP, AuthKeyC, OwnAuthKeyC,\n"
739"%%  PrivP, PrivKeyC, OwnPrivKeyC, Public, AuthKey, PrivKey}.\n"
740"%% For example\n"
741"%% {\"agentEngine\", \"initial\", \"initial\", zeroDotZero,\n"
742"%%  usmNoAuthProtocol, \"\", \"\", usmNoPrivProtocol, \"\", \"\", \"\",\n"
743"%%  \"\", \"\"}.\n"
744"%%\n\n",
745    Hdr = header() ++ Comment,
746    write_usm_config(Dir, Hdr, Conf).
747
748write_usm_config(Dir, Hdr, Conf)
749  when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
750    Order = fun snmp_conf:no_order/2,
751    Check = fun check_usm/2,
752    Write = fun (Fd, Entries) -> write_usm_conf(Fd, Hdr, Entries) end,
753    write_config_file(Dir, "usm.conf", Order, Check, Write, Conf).
754
755append_usm_config(Dir, Conf)
756  when is_list(Dir) and is_list(Conf) ->
757    Order = fun snmp_conf:no_order/2,
758    Check = fun check_usm/2,
759    Write = fun write_usm_conf/2,
760    append_config_file(Dir, "usm.conf", Order, Check, Write, Conf).
761
762read_usm_config(Dir) ->
763    Order = fun snmp_conf:no_order/2,
764    Check = fun check_usm/2,
765    read_config_file(Dir, "usm.conf", Order, Check).
766
767
768check_usm(Entry, State) ->
769    {check_ok(snmp_user_based_sm_mib:check_usm(Entry)),
770     State}.
771
772write_usm_conf(Fd, "", Conf) ->
773    write_usm_conf(Fd, Conf);
774write_usm_conf(Fd, Hdr, Conf) ->
775    io:format(Fd, "~s~n", [Hdr]),
776    write_usm_conf(Fd, Conf).
777
778write_usm_conf(Fd, Conf) ->
779    Fun = fun(Entry) -> do_write_usm_conf(Fd, Entry) end,
780    lists:foreach(Fun, Conf).
781
782do_write_usm_conf(
783  Fd,
784  {EngineID, UserName, SecName, Clone,
785   AuthP, AuthKeyC, OwnAuthKeyC,
786   PrivP, PrivKeyC, OwnPrivKeyC,
787   Public, AuthKey, PrivKey}) ->
788    io:format(Fd, "{", []),
789    io:format(Fd, "~p, ", [EngineID]),
790    io:format(Fd, "~p, ", [UserName]),
791    io:format(Fd, "~p, ", [SecName]),
792    io:format(Fd, "~w, ",     [Clone]),
793    io:format(Fd, "~w, ",     [AuthP]),
794    do_write_usm2(Fd, AuthKeyC, ", "),
795    do_write_usm2(Fd, OwnAuthKeyC, ", "),
796    io:format(Fd, "~w, ",     [PrivP]),
797    do_write_usm2(Fd, PrivKeyC, ", "),
798    do_write_usm2(Fd, OwnPrivKeyC, ", "),
799    do_write_usm2(Fd, Public, ", "),
800    do_write_usm2(Fd, AuthKey, ", "),
801    do_write_usm2(Fd, PrivKey, ""),
802    io:format(Fd, "}.~n", []);
803do_write_usm_conf(_Fd, Crap) ->
804    error({bad_usm_config, Crap}).
805
806do_write_usm2(Fd, "", P) ->
807    io:format(Fd, "\"\"~s", [P]);
808do_write_usm2(Fd, X, P) ->
809    io:format(Fd, "~w~s", [X, P]).
810
811
812%%
813%% ------ vacm.conf ------
814%%
815
816vacm_s2g_entry(SecModel, SecName, GroupName) ->
817    {vacmSecurityToGroup, SecModel, SecName, GroupName}.
818
819vacm_acc_entry(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) ->
820    {vacmAccess, GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV}.
821
822vacm_vtf_entry(ViewIndex, ViewSubtree) ->
823    vacm_vtf_entry(ViewIndex, ViewSubtree, included, null).
824vacm_vtf_entry(ViewIndex, ViewSubtree, ViewStatus, ViewMask) ->
825    {vacmViewTreeFamily, ViewIndex, ViewSubtree, ViewStatus, ViewMask}.
826
827
828write_vacm_config(Dir, Conf) ->
829    Comment =
830"%% This file defines the Mib Views.\n"
831"%% The data is inserted into the vacm* tables defined\n"
832"%% in SNMP-VIEW-BASED-ACM-MIB.\n"
833"%% Each row is one of 3 tuples; one for each table in the MIB:\n"
834"%% {vacmSecurityToGroup, SecModel, SecName, GroupName}.\n"
835"%% {vacmAccess, GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV}.\n"
836"%% {vacmViewTreeFamily, ViewIndex, ViewSubtree, ViewStatus, ViewMask}.\n"
837"%% For example\n"
838"%% {vacmSecurityToGroup, v2c, \"initial\", \"initial\"}.\n"
839"%% {vacmSecurityToGroup, usm, \"initial\", \"initial\"}.\n"
840"%%  read/notify access to system\n"
841"%% {vacmAccess, \"initial\", \"\", any, noAuthNoPriv, exact,\n"
842"%%              \"system\", \"\", \"system\"}.\n"
843"%% {vacmViewTreeFamily, \"system\", [1,3,6,1,2,1,1], included, null}.\n"
844"%% {vacmViewTreeFamily, \"exmib\", [1,3,6,1,3], included, null}."
845" % for EX1-MIB\n"
846"%% {vacmViewTreeFamily, \"internet\", [1,3,6,1], included, null}.\n"
847"%%\n\n",
848    Hdr = header() ++ Comment,
849    write_vacm_config(Dir, Hdr, Conf).
850
851write_vacm_config(Dir, Hdr, Conf)
852  when is_list(Dir) and is_list(Hdr) and is_list(Conf) ->
853    Order = fun snmp_conf:no_order/2,
854    Check = fun check_vacm/2,
855    Write = fun (Fd, Entries) -> write_vacm_conf(Fd, Hdr, Entries) end,
856    write_config_file(Dir, "vacm.conf", Order, Check, Write, Conf).
857
858append_vacm_config(Dir, Conf)
859  when is_list(Dir) and is_list(Conf) ->
860    Order = fun snmp_conf:no_order/2,
861    Check = fun check_vacm/2,
862    Write = fun write_vacm_conf/2,
863    append_config_file(Dir, "vacm.conf", Order, Check, Write, Conf).
864
865read_vacm_config(Dir) ->
866    Order = fun snmp_conf:no_order/2,
867    Check = fun check_vacm/2,
868    read_config_file(Dir, "vacm.conf", Order, Check).
869
870
871check_vacm(Entry, State) ->
872    {check_ok(snmp_view_based_acm_mib:check_vacm(Entry)),
873     State}.
874
875write_vacm_conf(Fd, "", Conf) ->
876    write_vacm_conf(Fd, Conf);
877write_vacm_conf(Fd, Hdr, Conf) ->
878    io:format(Fd, "~s~n", [Hdr]),
879    write_vacm_conf(Fd, Conf).
880
881write_vacm_conf(Fd, Conf) ->
882    Fun = fun(Entry) -> do_write_vacm_conf(Fd, Entry) end,
883    lists:foreach(Fun, Conf).
884
885do_write_vacm_conf(
886  Fd,
887  {vacmSecurityToGroup,
888   SecModel, SecName, GroupName}) ->
889    io:format(
890      Fd, "{vacmSecurityToGroup, ~w, ~p, ~p}.~n",
891      [SecModel, SecName, GroupName]);
892do_write_vacm_conf(
893  Fd,
894  {vacmAccess,
895   GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV}) ->
896    io:format(
897      Fd, "{vacmAccess, ~p, ~p, ~w, ~w, ~w, "
898      "~p, ~p, ~p}.~n",
899      [GroupName, Prefix, SecModel, SecLevel,
900       Match, RV, WV, NV]);
901do_write_vacm_conf(
902  Fd,
903  {vacmViewTreeFamily,
904   ViewIndex, ViewSubtree, ViewStatus, ViewMask}) ->
905    io:format(
906      Fd, "{vacmViewTreeFamily, ~p, ~w, ~w, ~w}.~n",
907      [ViewIndex, ViewSubtree, ViewStatus, ViewMask]);
908do_write_vacm_conf(_Fd, Crap) ->
909    error({bad_vacm_config, Crap}).
910
911
912%% ---- config file wrapper functions ----
913
914write_config_file(Dir, File, Order, Check, Write, Conf) ->
915    snmp_config:write_config_file(Dir, File, Order, Check, Write, Conf).
916
917append_config_file(Dir, File, Order, Check, Write, Conf) ->
918    snmp_config:append_config_file(Dir, File, Order, Check, Write, Conf).
919
920read_config_file(Dir, File, Order, Check) ->
921    snmp_config:read_config_file(Dir, File, Order, Check).
922
923
924%% ---- config file utility functions ----
925
926check_ok(ok) ->
927    ok;
928check_ok({ok, _}) ->
929    ok.
930
931header() ->
932    {Y,Mo,D} = date(),
933    {H,Mi,S} = time(),
934    io_lib:format(
935      "%% This file was generated by "
936      "~w (version-~s) ~w-~2.2.0w-~2.2.0w "
937      "~2.2.0w:~2.2.0w:~2.2.0w\n",
938      [?MODULE, ?version, Y, Mo, D, H, Mi, S]).
939
940error(R) ->
941    throw({error, R}).
942