diff --git a/modules/modules.mk b/modules/modules.mk index 2a55751098e64ac3876bddd8bef862c26106745a..d6077ebc713c2496163c71970cb0f35c4e651cb0 100644 --- a/modules/modules.mk +++ b/modules/modules.mk @@ -26,7 +26,8 @@ modules_TARGETS += ketcd \ dns64 \ renumber \ http \ - daf + daf \ + version endif # Make C module diff --git a/modules/version/README.rst b/modules/version/README.rst new file mode 100644 index 0000000000000000000000000000000000000000..47a740de93780fb8991b4c69f3c6f1892148cd2c --- /dev/null +++ b/modules/version/README.rst @@ -0,0 +1,15 @@ +.. _mod-version: + +Version +------- + +Module checks for new version and CVEs_. + +Running +^^^^^^^ + +.. code-block:: lua + + modules.load("version") + +.. _cves: https://cve.mitre.org/ diff --git a/modules/version/version.lua b/modules/version/version.lua new file mode 100644 index 0000000000000000000000000000000000000000..6d3a9c3cb43e5a35d72b45bf3eaa8527df5a3c0c --- /dev/null +++ b/modules/version/version.lua @@ -0,0 +1,86 @@ +local M = {} + +local function getLastWord(str) + local space = 1 + for i=#str, 1, -1 do + if str:sub(i,i) == " " then + space = i + break + end + end + return str:sub(space+1, #str) +end + +--Converts string of HEX digits to string +local function hex2string(hex) + local str = "" + for i=1, #hex, 2 do + local ascii = tonumber(hex:sub(i,i+1), 16) + str = str .. string.char(ascii) + end + return str +end + +--Runs "kresd -V" to get installed version +local function getLocalVersion() + local file = io.popen("kresd -V") + local version = file:read('*all') + file:close() + version = getLastWord(version):sub(1,-2) + return version +end + +local function parseCVE(str) + local first + local last + first, last = str:find("CVE") + local position = last+2 + return str:sub(position,-1) +end + +local function parseVersion(str) + local branch = "stable" + local first + local last + first, last = str:find(branch) + local position = last+3 + local delimiter = #str + if str:find("|",position) then + delimiter = str:find("|",position)-1 + end + return str:sub(position, delimiter) +end + +--Parses version from server and compares it to the installed one +local function parse(record) + local output = "" + local str = getLastWord(kres.rr2str(record)) + str = hex2string(str) + local CVE = parseCVE(str) + local version = parseVersion(str) + local localVersion = getLocalVersion() + if version ~= localVersion then + output = output .. string.format("[version] Newer version of Knot DNS Resolver is available. (Current: %s, Available: %s)\n", localVersion, version) + end + if CVE ~= "N/A" then + output = output .. string.format("[version] CVE: %s\n", CVE) + end + io.write(output) +end + +--Parses record from answer +local function request (answer) + local pkt = kres.pkt_t(answer) + if pkt:rcode() == kres.rcode.NOERROR then + parse(pkt:section(kres.section.ANSWER)[1]) + else + print ('Request for version ended with rcode: ', pkt:rcode()) + return + end +end + +function M.init() + resolve('et.knot-resolver.cz', kres.type.TXT, kres.class.IN, 0, request) +end + +return M \ No newline at end of file diff --git a/modules/version/version.mk b/modules/version/version.mk new file mode 100644 index 0000000000000000000000000000000000000000..34b261fe6dd3d12544c186b46f273b22157d9ccc --- /dev/null +++ b/modules/version/version.mk @@ -0,0 +1,2 @@ +version_SOURCES := version.lua +$(call make_lua_module,version)