]> source.dussan.org Git - rspamd.git/commitdiff
[Project] Add preliminary support of vcard parser
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 12 Jan 2021 15:42:08 +0000 (15:42 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 12 Jan 2021 15:42:08 +0000 (15:42 +0000)
lualib/lua_content/init.lua
lualib/lua_content/vcard.lua [new file with mode: 0644]

index 7bf42b9a1a690b4695a9fd2ce7550d8c7e00cac5..7947f16ab8fc74e203c43056695bd0de21c6099e 100644 (file)
@@ -31,6 +31,12 @@ local content_modules = {
     extensions = {'ics'},
     output = "text"
   },
+  vcf = {
+    mime_type = {"text/vcard", "application/vcard"},
+    module = require "lua_content/vcard",
+    extensions = {'vcf'},
+    output = "text"
+  },
   pdf = {
     mime_type = "application/pdf",
     module = require "lua_content/pdf",
diff --git a/lualib/lua_content/vcard.lua b/lualib/lua_content/vcard.lua
new file mode 100644 (file)
index 0000000..1237999
--- /dev/null
@@ -0,0 +1,85 @@
+--[[
+Copyright (c) 2021, Vsevolod Stakhov <vsevolod@highsecure.ru>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+]]--
+
+local l = require 'lpeg'
+local lua_util = require "lua_util"
+local N = "lua_content"
+
+local vcard_grammar
+
+-- XXX: Currently it is a copy of ical grammar
+local function gen_grammar()
+  if not vcard_grammar then
+    local wsp = l.S(" \t\v\f")
+    local crlf = (l.P"\r"^-1 * l.P"\n") + l.P"\r"
+    local eol = (crlf * #crlf) + (crlf - (crlf^-1 * wsp))
+    local name = l.C((l.P(1) - (l.P":"))^1) / function(v) return (v:gsub("[\n\r]+%s","")) end
+    local value = l.C((l.P(1) - eol)^0) / function(v) return (v:gsub("[\n\r]+%s","")) end
+    vcard_grammar = name * ":" * wsp^0 * value * eol^-1
+  end
+
+  return vcard_grammar
+end
+
+local exports = {}
+
+local function extract_text_data(specific)
+  local fun = require "fun"
+
+  local tbl = fun.totable(fun.map(function(e) return e[2]:lower() end, specific.elts))
+  return table.concat(tbl, '\n')
+end
+
+local function process_vcard(input, mpart, task)
+  local control={n='\n', r=''}
+  local rspamd_url = require "rspamd_url"
+  local escaper = l.Ct((gen_grammar() / function(key, value)
+    value = value:gsub("\\(.)", control)
+    key = key:lower()
+    local local_urls = rspamd_url.all(task:get_mempool(), value)
+
+    if local_urls and #local_urls > 0 then
+      for _,u in ipairs(local_urls) do
+        lua_util.debugm(N, task, 'vcard: found URL in vcard %s',
+            tostring(u))
+        task:inject_url(u, mpart)
+      end
+    end
+    lua_util.debugm(N, task, 'vcard: vcard key %s = "%s"',
+        key, value)
+    return {key, value}
+  end)^1)
+
+  local elts = escaper:match(input)
+
+  if not elts then
+    return nil
+  end
+
+  return {
+    tag = 'vcard',
+    extract_text = function() return nil end, -- NYI
+    elts = elts
+  }
+end
+
+--[[[
+-- @function vcard.process(input)
+-- Returns all values from vcard as a plain text. Names are completely ignored.
+--]]
+exports.process = process_vcard
+
+return exports
\ No newline at end of file