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 |