-- acf model for squid -- Copyright(c) 2007 A. Brodmann - Licensed under terms of GPL2 module (..., package.seeall) squidconf = "/etc/squid/squid.conf" --- the tokenizer functions - must be dislocated into a library later tokenizer = {} tokenizer.new = function( str, delim ) local token = {} token.value = str; token.delim = delim; token.pos = 1 return token end tokenizer.pos = function( value, substr, pos ) local retval = pos local done = false while not done and retval <= #value do if string.sub( value, retval, retval ) == substr then done = true else retval = retval + 1 end end return retval end tokenizer.next = function( token ) if token.pos > #token.value then return token, nil end local strpos = tokenizer.pos( token.value, token.delim, token.pos ) retval = string.sub(token.value, token.pos, strpos-1) if retval == token.delim then retval = "" token.pos = token.pos + 1 else token.pos = strpos + 1 end return token, retval end --- get_status = function() local retval = "stopped" local ptr = io.popen( "/bin/pidof squid" ) local pid = ptr:read( "*a" ) ptr:close() if pid ~= nil then if #pid > 1 then retval = "running" end end return retval end service_control = function( control ) local retval = "" local ptr = io.popen( "/etc/init.d/squid " .. control, "r" ) if ptr ~= nil then local retmsg = ptr:read( "*a" ) ptr:close() if retmsg ~= nil then retval = retmsg else retval = "service_control(): Failed to read output from initscript!\n" end else retval = "service_control(): Failed to start/stop/restart service!\n" end return retval end get_adv_config = function() local retval = "" local ptr = io.open( "/etc/squid/squid.conf", "r" ) if ptr ~= nil then local retcfg = ptr:read( "*a" ) ptr:close() if retcfg == nil then retval = "\n\n Error: Failed to read /etc/squid/squid.conf!\n\n" else retval = retcfg end end return retval end update_adv_config = function( config ) local retval = "Successfully updated /etc/squid/squid.conf!" local ptr = io.open( "/etc/squid/squid.conf", "wb+" ) if ptr ~= nil then ptr:write( config ) ptr:close() else retval = "update_config(): Error, failed to open /etc/squid/squid.conf!\n" end return retval end get_conf_tag = function( tag, gat ) local retval = "" local error = "" local found = false local done = false local fptr = io.open( squidconf, "r" ) if fptr == nil then return "", "Failed to open squid config file!" end while not found and not done do local line = fptr:read( "*l" ) if line == nil then done = true else if string.sub( line, 1, 22 ) == tag then found = true end end end if done then fptr:close() return "", "TAG not found in squid config!" end found = false done = false while not found and not done do local line = fptr:read( "*l" ) if line == nil then done = true elseif string.sub( line, 1, 22 ) == gat then found = true else retval = retval .. "\n" .. line end end if done then fptr:close() return "", "End TAG (GAT) not found in squid config! '" .. gat .. "'" end fptr:close() return retval, error end get_basic_config = function() local error = "" local config = { proxyip = { value="empty", type="text", label="Proxy IP" }, proxyport = { value="", type="text", label="Proxy Port" }, filterip = { value="", type="text", label="Filter IP" }, filterport = { value="", type="text", label="Filter Port" }, filterregex = { value="", type="text", label="FilterRegex" }, safeports = { value="", type="text", label="Safe_ports" }, sslports = { value="", type="text", label="SSL_ports" }, accesslog = { value="", type="select", label="Access Logs", option={ "yes", "no" } }, diskcache = { value="", type="select", label="Disk Cache Parameters", option={ "yes", "no" } }, authmethod = { value="", type="text", label="Authentication Method" } } local cfg1, error = get_conf_tag( "### ACF-SQUID-TAG-0001", "### ACF-SQUID-GAT-0001" ) if #error > 0 then return config, error end local cfg1tok = "" local cfg2tok = "" local cfg3tok = "" --- get proxyip, proxyport cfg1tok = tokenizer.new( cfg1, "\n" ) local done = false while not done do local str1 = "" cfg1tok, str1 = tokenizer.next( cfg1tok ) if str1 == nil then return nil, "Corrupt squid.conf! Missing 'http_port' statement!" else if string.sub( str1, 1, 10 ) == "http_port " then local str2 = "" local ipport = "" local ip = "" local port = "" cfg2tok = tokenizer.new( str1, " " ) cfg2tok, ipport = tokenizer.next( cfg2tok ) cfg2tok, ipport = tokenizer.next( cfg2tok ) if ipport == nil then return config, "Corrupt squid.conf! Missing parameter #1 for 'http_port' statement!" end cfg3tok = tokenizer.new( ipport, ":" ) cfg3tok, ip = tokenizer.next( cfg3tok ) cfg3tok, port = tokenizer.next( cfg3tok ) if port == nil then port = ip ip = "" end config.proxyip.value = ip config.proxyport.value = port done = true end end end cfg1tok = nil cfg2tok = nil cfg3tok = nil --- get filterip, filterport local cfg1, error = get_conf_tag( "### ACF-SQUID-TAG-0007", "### ACF-SQUID-GAT-0007" ) if #error > 0 then return config, error end cfg1tok = tokenizer.new( cfg1, "\n" ) done = false while not done do local str1 = "" cfg1tok, str1 = tokenizer.next( cfg1tok ) if str1 == nil then return nil, "Corrupt squid.conf! Missing 'cache_peer' statement!" else if string.sub( str1, 1, 11 ) == "cache_peer " then local str2 = "" local tmp = "" local ip = "" local port = "" cfg2tok = tokenizer.new( str1, " " ) cfg2tok, tmp = tokenizer.next( cfg2tok ) cfg2tok, ip = tokenizer.next( cfg2tok ) cfg2tok, tmp = tokenizer.next( cfg2tok ) cfg2tok, port = tokenizer.next( cfg2tok ) if ip == nil or port == nil then return config, "Corrupt squid.conf! Missing parameters #2 and/or #4 for 'cache_peer' statement!" end config.filterip.value = ip config.filterport.value = port done = true end end end cfg1tok = nil cfg2tok = nil cfg3tok = nil --- get diskcache local cfg1, error = get_conf_tag( "### ACF-SQUID-TAG-0002", "### ACF-SQUID-GAT-0002" ) if #error > 0 then return config, error end cfg1tok = tokenizer.new( cfg1, "\n" ) done = false while not done do local str1 = "" cfg1tok, str1 = tokenizer.next( cfg1tok ) if str1 == nil then return nil, "Corrupt squid.conf! Missing 'cache_dir' statement!" else if string.sub( str1, 1, 15 ) == "cache_dir diskd" then config.diskcache.value = "yes" done = true elseif string.sub( str1, 1, 14 ) == "cache_dir null" then config.diskcache.value = "no" done = true end end end cfg1tok = nil --- authentication method local cfg1, error = get_conf_tag( "### ACF-SQUID-TAG-0004", "### ACF-SQUID-GAT-0004" ) if #error > 0 then return config, error end cfg1tok = tokenizer.new( cfg1, "\n" ) local done = false local auth = "" while not done do local str1 = "" cfg1tok, str1 = tokenizer.next( cfg1tok ) if str1 == nil then done = true else if string.sub( str1, 1, 18 ) == "auth_param digest " then if string.match( auth, "D" ) == nil then auth = auth .. "D" end elseif string.sub( str1, 1, 16 ) == "auth_param ntlm " then if string.match( auth, "N" ) == nil then auth = auth .. "N" end elseif string.sub( str1, 1, 17 ) == "auth_param basic " then if string.match( auth, "B" ) == nil then auth = auth .. "B" end end end end config.authmethod.value = auth cfg1tok = nil --- get filterregex local cfg1, error = get_conf_tag( "### ACF-SQUID-TAG-0005", "### ACF-SQUID-GAT-0005" ) if #error > 0 then return config, error end cfg1tok = tokenizer.new( cfg1, "\n" ) done = false while not done do local str1 = "" cfg1tok, str1 = tokenizer.next( cfg1tok ) if str1 == nil then return nil, "Corrupt squid.conf! Missing 'acl ContentFilter urlpath_regex -i' statement!" else if string.sub( str1, 1, 35 ) == "acl ContentFilter urlpath_regex -i " then config.filterregex.value = string.sub( str1, 36 ) done = true end end end cfg1tok = nil cfg2tok = nil cfg3tok = nil --- get SSL_ports, Safe_ports local done1 = false local done2 = false cfg1tok = tokenizer.new( cfg1, "\n" ) while not done1 or not done2 do local str1 = "" cfg1tok, str1 = tokenizer.next( cfg1tok ) if str1 == nil then return nil, "Corrupt squid.conf! Missing 'acl SSL_ports/Safe_ports' statement!" else if string.sub( str1, 1, 19 ) == "acl SSL_ports port " then config.sslports.value = string.sub( str1, 20 ) done1 = true elseif string.sub( str1, 1, 20 ) == "acl Safe_ports port " then config.safeports.value = string.sub( str1, 21 ) done2 = true end end end cfg1tok = nil return config, error end