Added md5 check for duplicate REP submissions.
authorplugd <plugd@thelambdalab.xyz>
Tue, 20 Aug 2024 10:09:24 +0000 (12:09 +0200)
committerplugd <plugd@thelambdalab.xyz>
Tue, 20 Aug 2024 10:09:24 +0000 (12:09 +0200)
qwikboard

index 7008994..edb9d1d 100755 (executable)
--- a/qwikboard
+++ b/qwikboard
@@ -111,6 +111,16 @@ function fs.mktempdir()
    return posix.mkdtemp("/tmp/qwikboard-XXXXXX")
 end
 
+function fs.getmd5(filename)
+   local md5_file_name = filename .. ".md5"
+   os.execute(qb.md5sum .. " " .. filename .. " > " .. md5_file_name)
+   local md5fh = assert(io.open(md5_file_name), "r")
+   local md5f_str = md5fh:read("*all")
+   md5fh:close()
+
+   return string.match(md5f_str, "^(%w+)%s")
+end
+
 --- Message database parsing ---
 
 function Message(msg)
@@ -371,6 +381,11 @@ qb.unzip = "/usr/bin/unzip"
 -- and that the handler can execute it and read your
 -- system's nncp.hjson file.
 qb.nncp_file = "/usr/bin/nncp-file"
+
+-- Location of md5sum.  If available, this is used to check
+-- for duplicate REP submissions.
+qb.md5sum = "/usr/bin/md5sum"
+
 ]])
    cf:close()
    
@@ -432,18 +447,21 @@ about this.]]
    qwk.import_rep(arg[1], arg[2])
 end
 
-local function restore_nncp_usernames()
-   nncp_usernames = {}
+local function restore_nncp_userdata()
+   nncp_userdata = {}
    if fs.exists(qb.path .. "/nncp_users.lua") then
       dofile(qb.path .. "/nncp_users.lua")
    end
 end
 
-local function store_nncp_usernames()
+local function store_nncp_userdata()
    local fh = assert(io.open(qb.path .. "/nncp_users.lua", "w"))
-   for k,v in pairs(nncp_usernames) do
-      fh:write("nncp_usernames[" .. string.format("%q",k) .. "] = " ..
-               string.format("%q", v) .. "\n")
+   for uid,tab in pairs(nncp_userdata) do
+      fh:write("nncp_userdata[" .. string.format("%q",uid) .. "] = {\n")
+      for k,v in pairs(tab) do
+         fh:write(k .. ": " string.format(%q, v) .. ",\n")
+      end
+      fh:write("}\n")
    end
 end
 
@@ -464,33 +482,33 @@ exec: {
      return false
    end
 
-   restore_nncp_usernames()
+   restore_nncp_userdata()
 
    local input_string = io.stdin:read("*all")
 
    if string.match(input_string, "^%s*get") then
 
-      local user_name = string.match(input_string, "^%s*get%s+(%w+)%s*$")
-      if user_name then
-         nncp_usernames[node_id] = user_name
-         store_nncp_usernames()
+      local handle = string.match(input_string, "^%s*get%s+(%w+)%s*$")
+      if handle then
+         nncp_userdata[node_id].handle = user_name
+         store_nncp_userdata()
       else
-         user_name = nncp_usernames[node_id]
+         handle = nncp_userdata.handle[node_id]
       end
       
-      if not user_name then
+      if not handle then
          print("Error: no known handle for node " .. node_id .. ". Aborting.")
          return false
       end
 
-      print("Building QWK packet for user '" .. user_name .. "'")
+      print("Building QWK packet for user '" .. handle .. "'")
       -- Construct QWK packet
 
       local out_file_name = os.tmpname()
       fs.rmfile(out_file_name)
       local out_file_name = out_file_name .. ".qwk"
 
-      qwk.build_qwk(user_name, out_file_name)
+      qwk.build_qwk(handle, out_file_name)
 
       os.execute(qb.nncp_file .. " " .. out_file_name .. " " ..
                  node_id .. ":" .. qb.bbsid .. ".QWK")
@@ -498,14 +516,14 @@ exec: {
       fs.rmfile(out_file_name)
 
    else
-      local user_name = nncp_usernames[node_id]
+      local handle = nncp_userdata[node_id].handle
       
-      if not user_name then
+      if not handle then
          print("Error: No user name for node " .. node_id .. " found. Aborting.")
          return false
       end
 
-      print("Accepting REP packet from user '" .. user_name .. "'")
+      print("Accepting REP packet from user '" .. handle .. "'")
       -- Accept REP packet
 
       local rep_file_name = os.tmpname()
@@ -516,7 +534,21 @@ exec: {
       rf:write(input_string)
       rf:close()
 
-      qwk.import_rep(user_name, rep_file_name)
+      if qb.md5sum then
+         -- Check for duplicate REP submissions
+         
+         local md5 = fs.getmd5(rep_file_name)
+         local stored_md5 = nncp_userdata[node_id].md5
+         if stored_md5 and (md5 ~= stored_md5) then
+            print("Error: Duplicate REP submission detected. Skipping.")
+            return false
+         end
+
+         nncp_userdata[node_id].md5 = md5
+         store_nncp_userdata()
+      end
+
+      qwk.import_rep(handle, rep_file_name)
 
       fs.rmfile(rep_file_name)
    end