Software /
code /
prosody-modules
Comparison
mod_incidents_handling/incidents_handling/incidents_handling.lib.lua @ 1343:7dbde05b48a9
all the things: Remove trailing whitespace
author | Florian Zeitz <florob@babelmonkeys.de> |
---|---|
date | Tue, 11 Mar 2014 18:44:01 +0100 |
parent | 913:f42837829d5f |
comparison
equal
deleted
inserted
replaced
1342:0ae065453dc9 | 1343:7dbde05b48a9 |
---|---|
11 local my_host = nil | 11 local my_host = nil |
12 | 12 |
13 -- // Util and Functions // | 13 -- // Util and Functions // |
14 | 14 |
15 local function ft_str() | 15 local function ft_str() |
16 local d = os_date("%FT%T%z"):gsub("^(.*)(%+%d+)", function(dt, z) | 16 local d = os_date("%FT%T%z"):gsub("^(.*)(%+%d+)", function(dt, z) |
17 if z == "+0000" then return dt.."Z" else return dt..z end | 17 if z == "+0000" then return dt.."Z" else return dt..z end |
18 end) | 18 end) |
19 return d | 19 return d |
20 end | 20 end |
21 | 21 |
22 local function get_incident_layout(i_type) | 22 local function get_incident_layout(i_type) |
23 local layout = { | 23 local layout = { |
24 title = (i_type == "report" and "Incident report form") or (i_type == "request" and "Request for assistance with incident form"), | 24 title = (i_type == "report" and "Incident report form") or (i_type == "request" and "Request for assistance with incident form"), |
25 instructions = "Started/Ended Time, Contacts, Sources and Targets of the attack are mandatory. See RFC 5070 for further format instructions.", | 25 instructions = "Started/Ended Time, Contacts, Sources and Targets of the attack are mandatory. See RFC 5070 for further format instructions.", |
26 { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/commands" }, | 26 { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/commands" }, |
27 | 27 |
28 { name = "name", type = "hidden", value = my_host }, | 28 { name = "name", type = "hidden", value = my_host }, |
29 { name = "entity", type ="text-single", label = "Remote entity to query" }, | 29 { name = "entity", type ="text-single", label = "Remote entity to query" }, |
30 { name = "started", type = "text-single", label = "Incident Start Time" }, | 30 { name = "started", type = "text-single", label = "Incident Start Time" }, |
31 { name = "ended", type = "text-single", label = "Incident Ended Time" }, | 31 { name = "ended", type = "text-single", label = "Incident Ended Time" }, |
32 { name = "reported", type = "hidden", value = ft_str() }, | 32 { name = "reported", type = "hidden", value = ft_str() }, |
33 { name = "description", type = "text-single", label = "Description", | 33 { name = "description", type = "text-single", label = "Description", |
34 desc = "Description syntax is: <lang (in xml:lang format)> <short description>" }, | 34 desc = "Description syntax is: <lang (in xml:lang format)> <short description>" }, |
35 { name = "contacts", type = "text-multi", label = "Contacts", | 35 { name = "contacts", type = "text-multi", label = "Contacts", |
36 desc = "Contacts entries format is: <address> <type> <role> - separated by new lines" }, | 36 desc = "Contacts entries format is: <address> <type> <role> - separated by new lines" }, |
37 { name = "related", type = "text-multi", label = "Related Incidents", | 37 { name = "related", type = "text-multi", label = "Related Incidents", |
38 desc = "Related incidents entries format is: <CSIRT's FQDN> <Incident ID> - separated by new lines" }, | 38 desc = "Related incidents entries format is: <CSIRT's FQDN> <Incident ID> - separated by new lines" }, |
39 { name = "impact", type = "text-single", label = "Impact Assessment", | 39 { name = "impact", type = "text-single", label = "Impact Assessment", |
40 desc = "Impact assessment format is: <severity> <completion> <type>" }, | 40 desc = "Impact assessment format is: <severity> <completion> <type>" }, |
41 { name = "sources", type = "text-multi", label = "Attack Sources", | 41 { name = "sources", type = "text-multi", label = "Attack Sources", |
42 desc = "Attack sources format is: <address> <category> <count> <count-type>" }, | 42 desc = "Attack sources format is: <address> <category> <count> <count-type>" }, |
43 { name = "targets", type = "text-multi", label = "Attack Targets", | 43 { name = "targets", type = "text-multi", label = "Attack Targets", |
44 desc = "Attack target format is: <address> <category> <noderole>" } | 44 desc = "Attack target format is: <address> <category> <noderole>" } |
45 } | 45 } |
46 | 46 |
47 if i_type == "request" then | 47 if i_type == "request" then |
48 table.insert(layout, { | 48 table.insert(layout, { |
49 name = "expectation", | 49 name = "expectation", |
50 type = "list-single", | 50 type = "list-single", |
51 label = "Expected action from remote entity", | 51 label = "Expected action from remote entity", |
52 value = { | 52 value = { |
53 { value = "nothing", label = "No action" }, | 53 { value = "nothing", label = "No action" }, |
65 local function render_list(incidents) | 65 local function render_list(incidents) |
66 local layout = { | 66 local layout = { |
67 title = "Stored Incidents List", | 67 title = "Stored Incidents List", |
68 instructions = "You can select and view incident reports here, if a followup/response is possible it'll be noted in the step after selection.", | 68 instructions = "You can select and view incident reports here, if a followup/response is possible it'll be noted in the step after selection.", |
69 { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/commands" }, | 69 { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/commands" }, |
70 { | 70 { |
71 name = "ids", | 71 name = "ids", |
72 type = "list-single", | 72 type = "list-single", |
73 label = "Stored Incidents", | 73 label = "Stored Incidents", |
74 value = {} | 74 value = {} |
75 } | 75 } |
104 if contact.email then insert_fixed(layout, "--> E-Mail: "..contact.email) end | 104 if contact.email then insert_fixed(layout, "--> E-Mail: "..contact.email) end |
105 if contact.telephone then insert_fixed(layout, "--> Telephone: "..contact.telephone) end | 105 if contact.telephone then insert_fixed(layout, "--> Telephone: "..contact.telephone) end |
106 if contact.postaladdr then insert_fixed(layout, "--> Postal Address: "..contact.postaladdr) end | 106 if contact.postaladdr then insert_fixed(layout, "--> Postal Address: "..contact.postaladdr) end |
107 end | 107 end |
108 | 108 |
109 insert_fixed(layout, "Related Activity --") | 109 insert_fixed(layout, "Related Activity --") |
110 for _, related in ipairs(incident.data.related) do | 110 for _, related in ipairs(incident.data.related) do |
111 insert_fixed(layout, string.format("Name: %s ID: %s", related.name, related.text)) | 111 insert_fixed(layout, string.format("Name: %s ID: %s", related.name, related.text)) |
112 end | 112 end |
113 | 113 |
114 insert_fixed(layout, "Assessment --") | 114 insert_fixed(layout, "Assessment --") |
203 email = email, | 203 email = email, |
204 telephone = telephone, | 204 telephone = telephone, |
205 postaladdr = postaladdr | 205 postaladdr = postaladdr |
206 } | 206 } |
207 else | 207 else |
208 object.contacts[#object.contacts + 1] = { | 208 object.contacts[#object.contacts + 1] = { |
209 role = tag.attr.role, | 209 role = tag.attr.role, |
210 ext_role = (tag.attr["ext-role"] and true) or nil, | 210 ext_role = (tag.attr["ext-role"] and true) or nil, |
211 type = tag.attr.type, | 211 type = tag.attr.type, |
212 ext_type = (tag.attr["ext-type"] and true) or nil, | 212 ext_type = (tag.attr["ext-type"] and true) or nil, |
213 xmlns = jid.attr.xmlns, | 213 xmlns = jid.attr.xmlns, |
224 object.related[#object.related + 1] = { text = t:get_text(), name = tag.attr.name } | 224 object.related[#object.related + 1] = { text = t:get_text(), name = tag.attr.name } |
225 end | 225 end |
226 end | 226 end |
227 elseif tag.name == "Assessment" then | 227 elseif tag.name == "Assessment" then |
228 local impact = tag:get_child("Impact") | 228 local impact = tag:get_child("Impact") |
229 object.assessment = { lang = impact.attr.lang, severity = impact.attr.severity, completion = impact.attr.completion, type = impact.attr.type } | 229 object.assessment = { lang = impact.attr.lang, severity = impact.attr.severity, completion = impact.attr.completion, type = impact.attr.type } |
230 elseif tag.name == "EventData" then | 230 elseif tag.name == "EventData" then |
231 local source = tag:get_child("Flow").tags[1] | 231 local source = tag:get_child("Flow").tags[1] |
232 local target = tag:get_child("Flow").tags[2] | 232 local target = tag:get_child("Flow").tags[2] |
233 local expectation = tag:get_child("Flow").tags[3] | 233 local expectation = tag:get_child("Flow").tags[3] |
234 object.event_data = { sources = {}, targets = {} } | 234 object.event_data = { sources = {}, targets = {} } |
242 end | 242 end |
243 for _, entry in ipairs(target.tags) do | 243 for _, entry in ipairs(target.tags) do |
244 local noderole = { cat = entry:get_child("NodeRole").attr.category, ext = entry:get_child("NodeRole").attr["ext-category"] } | 244 local noderole = { cat = entry:get_child("NodeRole").attr.category, ext = entry:get_child("NodeRole").attr["ext-category"] } |
245 local current = #object.event_data.targets + 1 | 245 local current = #object.event_data.targets + 1 |
246 object.event_data.targets[current] = { addresses = {}, noderole = noderole } | 246 object.event_data.targets[current] = { addresses = {}, noderole = noderole } |
247 for _, tag in ipairs(entry.tags) do | 247 for _, tag in ipairs(entry.tags) do |
248 object.event_data.targets[current].addresses[#object.event_data.targets[current].addresses + 1] = { text = tag:get_text(), cat = tag.attr.category, ext = tag.attr["ext-category"] } | 248 object.event_data.targets[current].addresses[#object.event_data.targets[current].addresses + 1] = { text = tag:get_text(), cat = tag.attr.category, ext = tag.attr["ext-category"] } |
249 end | 249 end |
250 end | 250 end |
251 if expectation then | 251 if expectation then |
252 object.event_data.expectation = { | 252 object.event_data.expectation = { |
253 action = expectation.attr.action, | 253 action = expectation.attr.action, |
254 desc = expectation:get_child("Description") and expectation:get_child("Description"):get_text() | 254 desc = expectation:get_child("Description") and expectation:get_child("Description"):get_text() |
255 } | 255 } |
256 end | 256 end |
257 elseif tag.name == "History" then | 257 elseif tag.name == "History" then |
258 object.history = {} | 258 object.history = {} |
259 for _, t in ipairs(tag.tags) do | 259 for _, t in ipairs(tag.tags) do |
260 object.history[#object.history + 1] = { | 260 object.history[#object.history + 1] = { |
266 end | 266 end |
267 end | 267 end |
268 | 268 |
269 local function stanza_parser(stanza) | 269 local function stanza_parser(stanza) |
270 local object = {} | 270 local object = {} |
271 | 271 |
272 if stanza:get_child("report", xmlns_inc) then | 272 if stanza:get_child("report", xmlns_inc) then |
273 local report = st.clone(stanza):get_child("report", xmlns_inc):get_child("Incident", xmlns_iodef) | 273 local report = st.clone(stanza):get_child("report", xmlns_inc):get_child("Incident", xmlns_iodef) |
274 for _, tag in ipairs(report.tags) do do_tag_mapping(tag, object) end | 274 for _, tag in ipairs(report.tags) do do_tag_mapping(tag, object) end |
275 elseif stanza:get_child("request", xmlns_inc) then | 275 elseif stanza:get_child("request", xmlns_inc) then |
276 local request = st.clone(stanza):get_child("request", xmlns_inc):get_child("Incident", xmlns_iodef) | 276 local request = st.clone(stanza):get_child("request", xmlns_inc):get_child("Incident", xmlns_iodef) |
293 :tag("IncidentID", { name = object.id.name }):text(object.id.text):up() | 293 :tag("IncidentID", { name = object.id.name }):text(object.id.text):up() |
294 :tag("StartTime"):text(object.start_time):up() | 294 :tag("StartTime"):text(object.start_time):up() |
295 :tag("EndTime"):text(object.end_time):up() | 295 :tag("EndTime"):text(object.end_time):up() |
296 :tag("ReportTime"):text(object.report_time):up() | 296 :tag("ReportTime"):text(object.report_time):up() |
297 :tag("Description", { ["xml:lang"] = object.desc.lang }):text(object.desc.text):up():up(); | 297 :tag("Description", { ["xml:lang"] = object.desc.lang }):text(object.desc.text):up():up(); |
298 | 298 |
299 local incident = stanza:get_child(s_type, xmlns_inc):get_child("Incident", xmlns_iodef) | 299 local incident = stanza:get_child(s_type, xmlns_inc):get_child("Incident", xmlns_iodef) |
300 | 300 |
301 for _, contact in ipairs(object.contacts) do | 301 for _, contact in ipairs(object.contacts) do |
302 incident:tag("Contact", { role = (contact.ext_role and "ext-role") or contact.role, | 302 incident:tag("Contact", { role = (contact.ext_role and "ext-role") or contact.role, |
303 ["ext-role"] = (contact.ext_role and contact.role) or nil, | 303 ["ext-role"] = (contact.ext_role and contact.role) or nil, |
304 type = (contact.ext_type and "ext-type") or contact.type, | 304 type = (contact.ext_type and "ext-type") or contact.type, |
306 :tag("Email"):text(contact.email):up() | 306 :tag("Email"):text(contact.email):up() |
307 :tag("Telephone"):text(contact.telephone):up() | 307 :tag("Telephone"):text(contact.telephone):up() |
308 :tag("PostalAddress"):text(contact.postaladdr):up() | 308 :tag("PostalAddress"):text(contact.postaladdr):up() |
309 :tag("AdditionalData") | 309 :tag("AdditionalData") |
310 :tag("jid", { xmlns = contact.xmlns }):text(contact.jid):up():up():up() | 310 :tag("jid", { xmlns = contact.xmlns }):text(contact.jid):up():up():up() |
311 | 311 |
312 end | 312 end |
313 | 313 |
314 incident:tag("RelatedActivity"):up(); | 314 incident:tag("RelatedActivity"):up(); |
315 | 315 |
316 for _, related in ipairs(object.related) do | 316 for _, related in ipairs(object.related) do |
317 incident:get_child("RelatedActivity") | 317 incident:get_child("RelatedActivity") |
318 :tag("IncidentID", { name = related.name }):text(related.text):up(); | 318 :tag("IncidentID", { name = related.name }):text(related.text):up(); |
319 end | 319 end |
320 | 320 |
321 incident:tag("Assessment") | 321 incident:tag("Assessment") |
322 :tag("Impact", { | 322 :tag("Impact", { |
323 lang = object.assessment.lang, | 323 lang = object.assessment.lang, |
324 severity = object.assessment.severity, | 324 severity = object.assessment.severity, |
325 completion = object.assessment.completion, | 325 completion = object.assessment.completion, |
326 type = object.assessment.type | 326 type = object.assessment.type |
327 }):up():up(); | 327 }):up():up(); |
360 end | 360 end |
361 end | 361 end |
362 | 362 |
363 if object.history then | 363 if object.history then |
364 local history = incident:tag("History"):up(); | 364 local history = incident:tag("History"):up(); |
365 | 365 |
366 for _, item in ipairs(object.history) do | 366 for _, item in ipairs(object.history) do |
367 history:tag("HistoryItem", { action = item.action }) | 367 history:tag("HistoryItem", { action = item.action }) |
368 :tag("DateTime"):text(item.date):up() | 368 :tag("DateTime"):text(item.date):up() |
369 :tag("Description"):text(item.desc):up():up(); | 369 :tag("Description"):text(item.desc):up():up(); |
370 end | 370 end |
371 end | 371 end |
372 | 372 |
373 -- Sanitize contact empty tags | 373 -- Sanitize contact empty tags |
374 for _, tag in ipairs(incident) do | 374 for _, tag in ipairs(incident) do |
375 if tag.name == "Contact" then | 375 if tag.name == "Contact" then |
376 for i, check in ipairs(tag) do | 376 for i, check in ipairs(tag) do |
377 if (check.name == "Email" or check.name == "PostalAddress" or check.name == "Telephone") and | 377 if (check.name == "Email" or check.name == "PostalAddress" or check.name == "Telephone") and |
378 not check:get_text() then | 378 not check:get_text() then |
379 table.remove(tag, i) | 379 table.remove(tag, i) |
380 end | 380 end |
381 end | 381 end |
382 end | 382 end |
383 end | 383 end |
384 | 384 |
385 if s_type == "request" then stanza.attr.type = "get" | 385 if s_type == "request" then stanza.attr.type = "get" |
386 elseif s_type == "response" then stanza.attr.type = "set" | 386 elseif s_type == "response" then stanza.attr.type = "set" |
387 else stanza.attr.type = "set" end | 387 else stanza.attr.type = "set" end |
388 | 388 |
389 return stanza | 389 return stanza |
390 end | 390 end |
391 end | 391 end |
392 | 392 |
393 | 393 |
394 _M = {} -- wraps methods into the library. | 394 _M = {} -- wraps methods into the library. |
395 _M.ft_str = ft_str | 395 _M.ft_str = ft_str |
396 _M.get_incident_layout = get_incident_layout | 396 _M.get_incident_layout = get_incident_layout |