|
|
@@ -5,8 +5,10 @@ |
|
|
|
// Copyright JF Possibilities, Inc. All rights reserved. |
|
|
|
// |
|
|
|
// Provide a control panel to manage which domains we want to watch, |
|
|
|
// ignore anc block. |
|
|
|
// ignore and block. |
|
|
|
////////////////////////////////////////////////////////////////////// |
|
|
|
// TODO: put the note fields to use (dns,dns_wild) |
|
|
|
// TODO: Any purpose in wild-card selection "accepted" host names? |
|
|
|
#include <stdlib.h> |
|
|
|
#include <string> |
|
|
|
#include <stdexcept> |
|
|
@@ -36,6 +38,21 @@ |
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////// |
|
|
|
// DNS wild card matcher |
|
|
|
////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
|
|
bool dns_wild_match(const StringList &wilds, const std::string &host) { |
|
|
|
for(StringList::const_iterator i=wilds.begin(); i!=wilds.end(); i++) { |
|
|
|
if(host.length()<i->length()) continue; |
|
|
|
if(host==*i) return true; |
|
|
|
if(host.substr(host.length()-i->length()+1)=="."+*i) return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////// |
|
|
|
// C++CMS App to manage the state of all known domain names. |
|
|
|
////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
|
@@ -48,7 +65,7 @@ struct app: public cppcms::application { |
|
|
|
int items_per_page; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string numlist(const std::string &field) { |
|
|
|
std::string r; |
|
|
|
const cppcms::http::request::form_type &POST = request().post(); |
|
|
@@ -64,19 +81,66 @@ struct app: public cppcms::application { |
|
|
|
} |
|
|
|
return r; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void list(Domain::STATUS sid) { |
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// This looks at new log entries and creates missing DNS entries. |
|
|
|
/// This should be run periodically. Right now we run just prior |
|
|
|
/// displaying a "list" page. This could be used in a CRON job... |
|
|
|
|
|
|
|
void catchup() { |
|
|
|
std::string s; |
|
|
|
StringList list; |
|
|
|
DomainList c; |
|
|
|
|
|
|
|
StringList wild; |
|
|
|
|
|
|
|
/// Read list of wild-card blocks /// |
|
|
|
|
|
|
|
cppdb::result r = *sql |
|
|
|
<< "SELECT name FROM dns_wild WHERE status=?" |
|
|
|
<< Domain::blocked; |
|
|
|
while(r.next()) { |
|
|
|
r >> s; |
|
|
|
wild.push_back(s); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Auto-add unknown domains to DNS list /// |
|
|
|
|
|
|
|
// Find all connections not recorded in the DNS table |
|
|
|
r = *sql << |
|
|
|
"SELECT c.them_name " |
|
|
|
"FROM connections c LEFT OUTER JOIN dns ON c.them_name=dns.name " |
|
|
|
"WHERE c.them_name<>'' AND dns.name IS NULL " |
|
|
|
"GROUP BY c.them_name"; |
|
|
|
while(r.next()) { |
|
|
|
r >> s; |
|
|
|
list.push_back(s); |
|
|
|
} |
|
|
|
|
|
|
|
// add them |
|
|
|
if(!list.empty()) { |
|
|
|
cppdb::statement q = *sql << "INSERT INTO dns (name, status) VALUES (?,?)"; |
|
|
|
for(StringList::iterator i=list.begin(); i!=list.end(); i++) { |
|
|
|
q.reset(); |
|
|
|
// If blocked by wild card add it to the blocked list otherwise its |
|
|
|
// undecided. |
|
|
|
q << *i << (Domain::blocked*dns_wild_match(wild, *i)) << cppdb::exec; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void list(Domain::STATUS sid) { |
|
|
|
int i; |
|
|
|
std::string s; |
|
|
|
DomainList c; |
|
|
|
cppdb::result r; |
|
|
|
|
|
|
|
// TODO: put this someplace else? |
|
|
|
|
|
|
|
|
|
|
|
/// Form processing /// |
|
|
|
|
|
|
|
|
|
|
|
if(request().request_method()=="POST") { |
|
|
|
std::string op = request().post("op"); |
|
|
|
// nothing to do without a valid "op" |
|
|
@@ -86,37 +150,36 @@ struct app: public cppcms::application { |
|
|
|
*sql << "UPDATE dns SET status="+op+" WHERE name IN ("+s+")" |
|
|
|
<< cppdb::exec; |
|
|
|
} |
|
|
|
if((s=request().post("domain"))!="") { |
|
|
|
if(s=="*" || s=="*.") { |
|
|
|
c.error = "'*' and '*.' are not acceptable."; |
|
|
|
} else if((s=request().post("domain"))!="") { |
|
|
|
// wild card block handling |
|
|
|
if(s.substr(0,2)=="*.") { |
|
|
|
s = s.substr(2); |
|
|
|
if(op=="2") |
|
|
|
*sql << "INSERT INTO dns_wild (name,status) VALUES (?,?)" |
|
|
|
<< s << op |
|
|
|
<< cppdb::exec; |
|
|
|
else |
|
|
|
c.error = "Wild cards can only be used to <b>block</b> domains. " |
|
|
|
"This has been treated as regular domain prefix " |
|
|
|
"search."; |
|
|
|
} |
|
|
|
// regardless move all existing matches to the specified status. |
|
|
|
*sql << "UPDATE dns SET status=? WHERE name=? OR name LIKE ?" |
|
|
|
<< op << s << ("%."+s) |
|
|
|
<< cppdb::exec; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Auto add unknown domains to DNS list /// |
|
|
|
|
|
|
|
cppdb::result r = *sql << |
|
|
|
"SELECT c.them_name " |
|
|
|
"FROM connections c LEFT OUTER JOIN dns ON c.them_name=dns.name " |
|
|
|
"WHERE c.them_name<>'' AND dns.name IS NULL " |
|
|
|
"GROUP BY c.them_name"; |
|
|
|
while(r.next()) { |
|
|
|
r >> s; |
|
|
|
list.push_back(s); |
|
|
|
} |
|
|
|
|
|
|
|
if(!list.empty()) { |
|
|
|
cppdb::statement q = *sql << "INSERT INTO dns (name) VALUES (?)"; |
|
|
|
for(StringList::iterator i=list.begin(); i!=list.end(); i++) { |
|
|
|
q.reset(); |
|
|
|
q << *i << cppdb::exec; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Produce list of unknowns /// |
|
|
|
|
|
|
|
c.filter = filter_titles[sid]; |
|
|
|
/// Update DB with new log data /// |
|
|
|
|
|
|
|
catchup(); |
|
|
|
|
|
|
|
/// Produce list of names of the desired STATUS /// |
|
|
|
|
|
|
|
c.filter = filter_titles[sid]; |
|
|
|
s = request().get("pg"); |
|
|
|
if(s=="") |
|
|
|
c.page = 1; |
|
|
@@ -136,22 +199,22 @@ struct app: public cppcms::application { |
|
|
|
c.pages = (c.count+items_per_page-1)/items_per_page; |
|
|
|
render("mainskin", "domain_list", c); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void undecided() { list(Domain::undecided); } |
|
|
|
void accepted() { list(Domain::accepted ); } |
|
|
|
void blocked() { list(Domain::blocked ); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app(cppcms::service &s): cppcms::application(s), items_per_page(50) { |
|
|
|
#ifdef DEBUGGIN |
|
|
|
std::cerr << "spawning app object" << std::endl; |
|
|
|
#endif |
|
|
|
sql.reset(new cppdb::session()); |
|
|
|
sql->open(settings().get<std::string>("trafficctrl.db")); |
|
|
|
|
|
|
|
|
|
|
|
mapper().root(root_uri); |
|
|
|
mapper().assign("blocked", "/blocked"); |
|
|
|
dispatcher().assign("/blocked/?", &app::blocked, this); |
|
|
@@ -161,7 +224,7 @@ std::cerr << "spawning app object" << std::endl; |
|
|
|
dispatcher().assign("/?", &app::undecided, this); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// logging |
|
|
|
void main(const std::string url) { |
|
|
|
#ifdef DEBUGGIN |
|
|
@@ -172,7 +235,7 @@ std::cerr << "request: " << url << '\n' |
|
|
|
#endif |
|
|
|
cppcms::application::main(url); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|