Skip to content

Commit

Permalink
Add StyLua and luacheck to precommit config file and apply it
Browse files Browse the repository at this point in the history
  • Loading branch information
TheophileDiot committed Oct 12, 2023
1 parent 9c6a664 commit 362433c
Show file tree
Hide file tree
Showing 10 changed files with 428 additions and 323 deletions.
1 change: 1 addition & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
globals = {"ngx"}
13 changes: 13 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ repos:
- id: prettier
name: Prettier Code Formatter

- repo: https://github.com/JohnnyMorganz/StyLua
rev: 27e6b388796604181e810ef05c9fb15a9f7a7769 # frozen: v0.18.2
hooks:
- id: stylua-github
exclude: ^crowdsec/lib/

- repo: https://github.com/lunarmodules/luacheck
rev: ababb6d403d634eb74d2c541035e9ede966e710d # frozen: v1.1.1
hooks:
- id: luacheck
exclude: ^crowdsec/lib/
args: ["--std", "min", "--codes", "--ranges", "--no-cache"]

- repo: https://github.com/pycqa/flake8
rev: 10f4af6dbcf93456ba7df762278ae61ba3120dc6 # frozen: 6.1.0
hooks:
Expand Down
156 changes: 94 additions & 62 deletions clamav/clamav.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
local class = require "middleclass"
local plugin = require "bunkerweb.plugin"
local utils = require "bunkerweb.utils"
local cjson = require "cjson"
local upload = require "resty.upload"
local sha512 = require "resty.sha512"
local str = require "resty.string"
local class = require("middleclass")
local plugin = require("bunkerweb.plugin")
local sha512 = require("resty.sha512")
local str = require("resty.string")
local upload = require("resty.upload")
local utils = require("bunkerweb.utils")

local clamav = class("clamav", plugin)
local clamav = class("clamav", plugin)

local stream_size = function(size)
local floor = math.floor
return ("%c%c%c%c")
:format(
size % 0x100,
floor(size / 0x100) % 0x100,
floor(size / 0x10000) % 0x100,
floor(size / 0x1000000) % 0x100
)
:reverse()
end

local read_all = function(form)
while true do
local typ = form:read()
if not typ then
return
end
if typ == "eof" then
return
end
end
end

function clamav:initialize()
-- Call parent initialize
Expand All @@ -30,7 +53,14 @@ function clamav:init_worker()
if data ~= "PONG" then
return self:ret(false, "wrong data received from ClamAV : " .. data)
end
self.logger:log(ngx.NOTICE, "connectivity with " .. self.variables["CLAMAV_HOST"] .. ":" .. self.variables["CLAMAV_PORT"] .. " is successful")
self.logger:log(
ngx.NOTICE,
"connectivity with "
.. self.variables["CLAMAV_HOST"]
.. ":"
.. self.variables["CLAMAV_PORT"]
.. " is successful"
)
return self:ret(true, "success")
end

Expand All @@ -41,7 +71,13 @@ function clamav:access()
end

-- Check if we have downloads
if not self.ctx.bw.http_content_type or (not self.ctx.bw.http_content_type:match("boundary") or not self.ctx.bw.http_content_type:match("multipart/form%-data")) then
if
not self.ctx.bw.http_content_type
or (
not self.ctx.bw.http_content_type:match("boundary")
or not self.ctx.bw.http_content_type:match("multipart/form%-data")
)
then
return self:ret(true, "no file upload detected")
end

Expand All @@ -51,7 +87,11 @@ function clamav:access()
return self:ret(false, "error while scanning file(s) : " .. detected)
end
if detected then
return self:ret(true, "file with checksum " .. checksum .. "is detected : " .. detected, utils.get_deny_status(self.ctx))
return self:ret(
true,
"file with checksum " .. checksum .. "is detected : " .. detected,
utils.get_deny_status(self.ctx)
)
end
return self:ret(true, "no file detected")
end
Expand All @@ -63,13 +103,16 @@ function clamav:command(cmd)
return false, err
end
-- Send command
local bytes, err = socket:send("n" .. cmd .. "\n")
local bytes
bytes, err = socket:send("n" .. cmd .. "\n")
if not bytes then
socket:close()
return false, err
end
-- Receive response
local data, err, partial = socket:receive("*l")
-- luacheck: ignore partial
local data, partial
data, err, partial = socket:receive("*l")
if not data then
socket:close()
return false, err
Expand All @@ -82,10 +125,7 @@ function clamav:socket()
-- Init socket
local socket = ngx.socket.tcp()
socket:settimeout(tonumber(self.variables["CLAMAV_TIMEOUT"]))
local ok, err = socket:connect(
self.variables["CLAMAV_HOST"],
tonumber(self.variables["CLAMAV_PORT"])
)
local ok, err = socket:connect(self.variables["CLAMAV_HOST"], tonumber(self.variables["CLAMAV_PORT"]))
if not ok then
return false, err
end
Expand All @@ -96,11 +136,10 @@ function clamav:scan()
-- Loop on files
local form = upload:new(4096, 512, true)
if not form then
return false, err
return false, "failed to create upload form"
end
local sha = sha512:new()
local socket = nil
local err = nil
local socket
while true do
-- Read part
local typ, res, err = form:read()
Expand All @@ -111,11 +150,14 @@ function clamav:scan()
return false, "form:read() failed : " .. err
end

local bytes

-- Header case : check if we have a filename
if typ == "header" then
local found = false
-- luacheck: ignore 213
for i, header in ipairs(res) do
if header:find("^.*filename=\"(.*)\".*$") then
if header:find('^.*filename="(.*)".*$') then
found = true
break
end
Expand All @@ -126,97 +168,99 @@ function clamav:scan()
end
socket, err = self:socket()
if not socket then
self:read_all(form)
read_all(form)
return false, "socket failed : " .. err
end
local bytes, err = socket:send("nINSTREAM\n")
bytes, err = socket:send("nINSTREAM\n")
if not bytes then
socket:close()
self:read_all(form)
read_all(form)
return false, "socket:send() failed : " .. err
end
end
-- Body case : update checksum and send to clamav
-- Body case : update checksum and send to clamav
elseif typ == "body" and socket then
sha:update(res)
local bytes, err = socket:send(self:stream_size(#res) .. res)
bytes, err = socket:send(stream_size(#res) .. res)
if not bytes then
socket:close()
self:read_all(form)
read_all(form)
return false, "socket:send() failed : " .. err
end
-- Part end case : get final checksum and clamav result
-- Part end case : get final checksum and clamav result
elseif typ == "part_end" and socket then
local checksum = str.to_hex(sha:final())
sha:reset()
-- Check if file is in cache
local ok, cached = self:is_in_cache(checksum)
if not ok then
self.logger:log(ngx.ERR, "can't check if file with checksum " .. checksum .. " is in cache : " .. cached)
self.logger:log(
ngx.ERR,
"can't check if file with checksum " .. checksum .. " is in cache : " .. cached
)
elseif cached then
socket:close()
socket = nil
if cached ~= "clean" then
self:read_all(form)
read_all(form)
return true, cached, checksum
end
else
-- End the INSTREAM
local bytes, err = socket:send(self:stream_size(0))
bytes, err = socket:send(stream_size(0))
if not bytes then
socket:close()
self:read_all(form)
read_all(form)
return false, "socket:send() failed : " .. err
end
-- Read result
local data, err, partial = socket:receive("*l")
-- luacheck: ignore partial
local data, partial
data, err, partial = socket:receive("*l")
if not data then
socket:close()
self:read_all(form)
read_all(form)
return false, err
end
socket:close()
socket = nil
if data:match("^.*INSTREAM size limit exceeded.*$") then
self.logger:log(ngx.ERR, "can't scan file with checksum " .. checksum .. " because size exceeded StreamMaxLength in clamd.conf")
self.logger:log(
ngx.ERR,
"can't scan file with checksum "
.. checksum
.. " because size exceeded StreamMaxLength in clamd.conf"
)
else
local istart, iend, data = data:find("^stream: (.*) FOUND$")
-- luacheck: ignore iend
local istart
istart, iend, data = data:find("^stream: (.*) FOUND$")
local detected = "clean"
if istart then
detected = data
end
local ok, err = self:add_to_cache(checksum, detected)
ok, err = self:add_to_cache(checksum, detected)
if not ok then
self.logger:log(ngx.ERR, "can't cache result : " .. err)
end
if detected ~= "clean" then
self:read_all(form)
read_all(form)
return true, detected, checksum
end
end

end
-- End of body case : no file detected
-- End of body case : no file detected
elseif typ == "eof" then
if socket then
socket:close()
end
return true
end
end
-- luacheck: ignore 511
return false, "malformed content"
end

function clamav:stream_size(size)
local floor = math.floor
return ("%c%c%c%c"):format(
size % 0x100,
floor(size / 0x100) % 0x100,
floor(size / 0x10000) % 0x100,
floor(size / 0x1000000) % 0x100
):reverse()
end

function clamav:is_in_cache(checksum)
local ok, data = self.cachestore:get("plugin_clamav_" .. checksum)
if not ok then
Expand All @@ -233,16 +277,4 @@ function clamav:add_to_cache(checksum, value)
return true
end

function clamav:read_all(form)
while true do
local typ = form:read()
if not typ then
return
end
if typ == "eof" then
return
end
end
end

return clamav
Loading

0 comments on commit 362433c

Please sign in to comment.