-- acf model for squid module (..., package.seeall) -- Load libraries require("modelfunctions") require("validator") require("format") require("fs") -- Set variables local squidconf = "/etc/squid/squid.conf" local squiddigestusers = "/etc/squid/users.list" local processname = "squid" local packagename = "squid" local config, configcontent local validate_config = function(newconfig) local success = true success = modelfunctions.validatemulti(newconfig.value.authmethod) for i,val in ipairs(newconfig.value.httpports.value) do local before, after = string.match(val, "^([^:]+):([^:]+)$") if not (before and after) then after = val end if not validator.is_port(after) then newconfig.value.httpports.errtxt = "Invalid port" success = false break end end return success, newconfig end getstatus = function() return modelfunctions.getstatus(processname, packagename, "Squid status") end startstop_service = function(action) return modelfunctions.startstop_service(processname, action) end get_configfile = function() return modelfunctions.getfiledetails(squidconf) end update_configfile = function( filedetails ) filedetails.value.filename.value = squidconf return modelfunctions.setfiledetails(filedetails) end read_digest_userlist = function() local retval = modelfunctions.getfiledetails(squiddigestusers) retval.value.filecontent.descr = "List of username:password entries" -- check to see if the file is being used configcontent = configcontent or fs.read_file(squidconf) config = config or format.parse_linesandwords(configcontent) retval.value.status = cfe({ errtxt="Digest authentication not enabled", label="User list status" }) for i,line in ipairs(config) do if line[1] == "auth_param" and line[2] == "digest" and line[3] == "program" then if line[5] == squiddigestusers then retval.value.status.value = "User list in use" retval.value.status.errtxt = nil else retval.value.status.errtxt = "Digest authentication not using this user list" end end end return retval end update_digest_userlist = function( userlistdetails ) userlistdetails.value.filename.value = squiddigestusers return modelfunctions.updatefiledetails(userlistdetails) end enable_digest_userlist = function() configcontent = configcontent or fs.read_file(squidconf) local newline = "auth_param digest program /usr/sbin/digest_pw_auth "..squiddigestusers local lastauth, authline local lines = {} -- first loop to comment out / uncomment existing lines local linenum = 0 for line in string.gmatch(configcontent, "([^\n]*)\n?") do linenum = linenum + 1 if not authline and not string.match(line, "^[%s#]*$") then local first, second, third = string.match(line, "([^%s#]+)%s+(%S+)%s+(%S+)") if first == "auth_param" then lastauth = linenum if second == "digest" and third == "program" then authline = linenum line = string.gsub(line, "^[%s#]+", "") local fifth = string.match(line, "^%S+%s+%S+%s+%S+%s+%S+%s+(%S+)") line = string.gsub(line, fifth, squiddigestusers) end end end lines[#lines+1] = line end if not authline then if not lastauth then lines[#lines+1] = newline else table.insert(lines, lastauth+1, newline) end end fs.write_file(squidconf, string.gsub(table.concat(lines, "\n"), "\n+$", "")) config = nil configcontent = nil return cfe({ value="Successfully enabled user list", label="Enable disgest user list result" }) end --[[ get_saccess = function() local config = {} config.s_ip = get_file_contents( "/etc/squid/anoniplist" ) config.s_browser = get_file_contents( "/etc/squid/anonbrowserlist" ) config.s_domain = get_file_contents( "/etc/squid/anondomainlist" ) return config end update_saccess = function( config ) write_file_contents( "/etc/squid/anoniplist", config.s_ip ) write_file_contents( "/etc/squid/anonbrowserlist", config.s_browser ) write_file_contents( "/etc/squid/anondomainlist", config.s_domain ) return end write_file_contents = function( name, contents ) local ptr = io.open( name, "wb+" ) if ptr ~= nil then ptr:write( format.dostounix( contents ) ) ptr:close() end return end get_file_contents = function( name ) local retval = "" local ptr = io.open( name ) if ptr ~= nil then retval = ptr:read( "*a" ) ptr:close() if retval == nil then retval = "" end end return retval end --]] read_config = function() local retval = { httpports = { type="list", value={}, label="HTTP Ports", descr="List of port, IP:port, or hostname:port entries that Squid will listen on" }, accesslog = { type="boolean", value=false, label="Log Access" }, diskcache = { type="boolean", value=false, label="Disk Cache" }, authmethod = { type="multi", value={}, label="Authentication Methods", option={"negotiate", "ntlm", "digest", "basic"} }, } configcontent = configcontent or fs.read_file(squidconf) config = config or format.parse_linesandwords(configcontent) if config then for i,line in ipairs(config) do if line[1] == "http_port" then table.insert(retval.httpports.value, line[2]) elseif line[1] == "access_log" then retval.accesslog.value = (line[2] ~= "none") elseif line[1] == "cache_dir" then retval.diskcache.value = (line[2] ~= "null") elseif line[1] == "auth_param" and line[3] == "program" then table.insert(retval.authmethod.value, line[2]) end end end return cfe({ type="group", value=retval, label="Squid Config" }) end update_config = function(newconfig) local success, newconfig = validate_config(newconfig) if success then configcontent = configcontent or fs.read_file(squidconf) local lastport, lastlog, lastcache, lastauth local didports = {} local didlog, didcache local didauths = {} local reverseports = {} for i,port in ipairs(newconfig.value.httpports.value) do reverseports[port] = i end local reverseauths = {} for i,auth in ipairs(newconfig.value.authmethod.value) do reverseauths[auth] = i end local lines = {} -- first loop to comment out / uncomment existing lines local linenum = 0 for line in string.gmatch(configcontent, "([^\n]*)\n?") do linenum = linenum + 1 if not string.match(line, "^[%s#]*$") then local first, second = string.match(line, "([^%s#]+)%s+(%S+)") if first == "http_port" then lastport = linenum line = string.gsub(line, "^[%s#]+", "") if not reverseports[second] then line = "# "..line else didports[second] = true end elseif first == "access_log" then lastlog = linenum line = string.gsub(line, "^[%s#]+", "") if (newconfig.value.accesslog.value and second == "none") or (not newconfig.value.accesslog.value and second ~= "none") then line = "# "..line else didlog = true end elseif first == "cache_dir" then lastcache = linenum line = string.gsub(line, "^[%s#]+", "") if (newconfig.value.diskcache.value and second == "null") or (not newconfig.value.diskcache.value and second ~= "null") then line = "# "..line else didcache = true end elseif first == "auth_param" then lastauth = linenum if string.match(line, "[^%s#]+%s+%S+%s+(%S+)") == "program" then line = string.gsub(line, "^[%s#]+", "") if not reverseauths[second] then line = "# "..line else didauths[second] = true end end end end lines[#lines+1] = line end -- We've gone through the file, now check to see if everything is done local tobedone = {} local line for i,port in ipairs(newconfig.value.httpports.value) do if not didports[port] then line = "http_port "..port if lastport then table.insert(tobedone, {linenum=lastport+1, line=line}) else table.insert(lines, line) end end end if not didlog then if newconfig.value.accesslog.value then line = "access_log /var/log/squid/access.log" else line = "access_log none" end if lastlog then table.insert(tobedone, {linenum=lastlog+1, line=line}) else table.insert(lines, line) end end if not didcache then if newconfig.value.diskcache.value then line = "cache_dir diskd /var/cache/squid 400 16 256" else line = "cache_dir null" end if lastcache then table.insert(tobedone, {linenum=lastcache+1, line=line}) else table.insert(lines, line) end end for i,auth in ipairs(newconfig.value.authmethod.value) do if not didauths[auth] then line = "auth_param "..auth.." program " -- These entries have not been tested and probably don't work if auth == "basic" then line = line .. "/usr/libexec/ncsa_auth /usr/etc/passwd" elseif auth == "digest" then line = line .. "/usr/sbin/digest_pw_auth /etc/squid/users.list" elseif auth == "ntlm" then line = line .. "/usr/sbin/wb_ntlmauth" elseif auth == "negotiate" then line = line .. "/usr/sbin/ntlm_auth --helper-protocol=gss-spnego" end if lastauth then table.insert(tobedone, {linenum=lastauth+1, line=line}) else table.insert(lines, line) end end end if #tobedone > 0 then table.sort(tobedone, function(a,b) return (a.linenum > b.linenum) end) for i,entry in ipairs(tobedone) do table.insert(lines, entry.linenum, entry.line) end end -- finally, write the file fs.write_file(squidconf, string.gsub(table.concat(lines, "\n"), "\n+$", "")) config = nil configcontent = nil else newconfig.errtxt = "Failed to set config" end return newconfig end --[[ read_acls = function() local acls = cfe({ type="structure", value={}, label="Squid Access Lists" }) configcontent = configcontent or fs.read_file(squidconf) config = config or format.parse_linesandwords(configcontent) for i,line in ipairs(config) do if line[1] == "acl" then table.insert(acls.value, {line=line.line, linenum=line.linenum}) end end return acls end read_acl = function(linenum) local line = cfe({ label="Squid Access List" }) local linecfe = cfe({ value=linenum, label="Line number" }) configcontent = configcontent or fs.read_file(squidconf) line.value = format.getline(configcontent, linenum) or "" return cfe({ type="group", value={line=line, linenum=linecfe}, label="Squid Access List" }) end update_acl = function(acl) -- local success, acl = validate_acl(acl) configcontent = configcontent or fs.read_file(squidconf) configcontent = format.replaceline(configcontent, acl.value.linenum.value, acl.value.line.value) fs.write_file(squidconf, string.gsub(configcontent, "\n+$", "")) config = nil configcontent = nil return acl end create_acl = function(acl) -- local success, acl = validate_acl(acl) configcontent = configcontent or fs.read_file(squidconf) config = config or format.parse_linesandwords(configcontent) local linenum = -1 for i=#config,1,-1 do if config[i][1] == "acl" then linenum = config[i].linenum configcontent = format.insertline(configcontent, linenum, acl.value.line.value) break end end if linenum == -1 then configcontent = string.gsub(configcontent, "\n?$", "\n") .. acl.value.line.value end fs.write_file(squidconf, string.gsub(configcontent, "\n+$", "")) config = nil configcontent = nil return acl end delete_acl = function(linenum) configcontent = configcontent or fs.read_file(squidconf) configcontent = format.replaceline(configcontent, linenum) fs.write_file(squidconf, string.gsub(configcontent, "\n+$", "")) config = nil configcontent = nil return acl end --]]