summaryrefslogtreecommitdiffstats
path: root/cgi-bin
diff options
context:
space:
mode:
Diffstat (limited to 'cgi-bin')
-rwxr-xr-xcgi-bin/query.pl130
-rw-r--r--cgi-bin/secret/.htaccess6
-rwxr-xr-xcgi-bin/secret/investigate.pl203
-rwxr-xr-xcgi-bin/secret/logs.pl34
-rwxr-xr-xcgi-bin/showUsers.pl75
5 files changed, 448 insertions, 0 deletions
diff --git a/cgi-bin/query.pl b/cgi-bin/query.pl
new file mode 100755
index 0000000..4a9ed26
--- /dev/null
+++ b/cgi-bin/query.pl
@@ -0,0 +1,130 @@
+#!/usr/bin/perl
+
+#use warnings;
+use Data::Dumper;
+use strict;
+use DBI;
+
+use CGI_Lite;
+
+my $dbh = DBI->connect("DBI:mysql:database=asm_main;host=localhost;port=3306", 'USER', 'PASSWORD');
+
+my $debug = 0;
+
+sub esc
+{
+ my ($arg) = @_;
+ $arg = $dbh->quote($arg);
+ $arg =~ s/\*/%/g;
+ $arg =~ s/_/\\_/g;
+ $arg =~ s/\?/_/g;
+ return $arg;
+}
+
+my $cgi = new CGI_Lite;
+my %data = $cgi->parse_form_data;
+
+$debug = int($data{debug}) if (defined($data{debug}));
+
+if ($debug) {
+ print "Content-type: text/plain", "\n\n";
+ print Dumper(\%data);
+} else {
+ print "Content-type: text/html", "\n\n";
+ print "<html><head><title>Query results</title></head><body>\n";
+}
+
+my ($channel, $nick, $user, $host);
+my ($level, $id, $reason);
+
+my $qry = "SELECT time, channel, nick, user, host, gecos, level, id, reason FROM alertlog WHERE ";
+
+if (defined($data{channel})) {
+ $qry = $qry . "channel like " . esc($data{channel});
+} else { die "channel not defined!\n"; }
+
+if (defined($data{nick}) && ($data{nick} ne "*") && ($data{nick} ne "")) {
+ $qry .= " and nick like " . esc($data{nick});
+}
+
+if (defined($data{user}) && ($data{user} ne "*") && ($data{user} ne "")) {
+ $qry .= " and user like " . esc($data{user});
+}
+
+if (defined($data{host}) && ($data{host} ne "*") && ($data{host} ne "")) {
+ $qry .= " and host like " . esc($data{host});
+}
+
+if (defined($data{gecos}) && ($data{gecos} ne "*") && ($data{gecos} ne "")) {
+ $qry .= " and gecos like " . esc($data{gecos});
+}
+
+if (defined($data{since})) {
+ $qry .= sprintf("and time > '%04d-%02d-%02d %02d:%02d:%02d'",
+ int($data{syear}), int($data{smonth}), int($data{sday}),
+ int($data{shour}), int($data{smin}), int($data{ssec}));
+}
+
+if (defined($data{before})) {
+ $qry .= sprintf("and time < '%04d-%02d-%02d %02d:%02d:%02d'",
+ int($data{byear}), int($data{bmonth}), int($data{bday}),
+ int($data{bhour}), int($data{bmin}), int($data{bsec}));
+}
+
+#if (defined($data{id})) {
+# $qry .= " and id = " . $dbh->quote($data{id});
+#}
+
+if (defined($data{level}) && ($data{level} ne "any")) {
+ $qry .= " and level = " . $dbh->quote($data{level});
+}
+
+if (defined($data{reason})) {
+ $qry .= " and reason like " . esc($data{reason});
+}
+
+if (defined($data{sort}) && defined($data{order}) && ($data{order} =~ /^[ad]$/ ) &&
+ ( $data{sort} =~ /^(time|nick|user|host|level|id|reason)$/ ) ) {
+ $qry .= " order by " . $data{sort};
+ $qry .= " desc" if $data{order} eq "d";
+}
+
+if ($debug) {
+ print "Querying: ";
+ print Dumper($qry);
+}
+
+my $sth = $dbh->prepare($qry);
+$sth->execute;
+my $names = $sth->{'NAME'};
+my $numFields = $sth->{'NUM_OF_FIELDS'};
+
+ print "<table border=\"1\"><tr>" unless $debug;
+
+for (my $i = 0; $i < $numFields; $i++) {
+ if ($debug) {
+ printf("%s%s", $i ? "," : "", $$names[$i]);
+ } else {
+ print "<th>" . $$names[$i] . "</th>";
+ }
+}
+
+print "</tr>" unless $debug;
+print "\n";
+
+while (my $ref = $sth->fetchrow_arrayref) {
+ print "<tr>" unless $debug;
+
+ for (my $i = 0; $i < $numFields; $i++) {
+ if ($debug) {
+ printf("%s%s", $i ? "," : "", $$ref[$i]);
+ } else {
+ print "<td>" . $$ref[$i] . "</td>";
+ }
+ }
+ print "</tr>" unless $debug;
+ print "\n";
+}
+unless ($debug) {
+ print "</table></body></html>";
+}
diff --git a/cgi-bin/secret/.htaccess b/cgi-bin/secret/.htaccess
new file mode 100644
index 0000000..14ea91d
--- /dev/null
+++ b/cgi-bin/secret/.htaccess
@@ -0,0 +1,6 @@
+AuthType Basic
+AuthName "Restricted Files"
+AuthUserFile /home/icxcnika/AntiSpamMeta/HTTP_ACCESS_USER
+AuthGroupFile /home/icxcnika/AntiSpamMeta/HTTP_ACCESS_GROUP
+Require group actionlogs
+#Require user icxcnika
diff --git a/cgi-bin/secret/investigate.pl b/cgi-bin/secret/investigate.pl
new file mode 100755
index 0000000..0716480
--- /dev/null
+++ b/cgi-bin/secret/investigate.pl
@@ -0,0 +1,203 @@
+#!/usr/bin/perl
+
+#use warnings;
+use Data::Dumper;
+use strict;
+use DBI;
+
+use CGI_Lite;
+
+my $dbh = DBI->connect("DBI:mysql:database=asm_main;host=localhost;port=3306", 'USER', 'PASSWORD');
+
+my $debug = 0;
+
+sub esc
+{
+ my ($arg) = @_;
+ $arg = $dbh->quote($arg);
+ $arg =~ s/\*/%/g;
+ $arg =~ s/_/\\_/g;
+ $arg =~ s/\?/_/g;
+ return $arg;
+}
+
+sub dottedQuadToInt
+{
+ my ($dottedquad) = @_;
+ my $ip_number = 0;
+ my @octets = split(/\./, $dottedquad);
+ foreach my $octet (@octets) {
+ $ip_number <<= 8;
+ $ip_number |= $octet;
+ }
+ return $ip_number;
+}
+
+my $cgi = new CGI_Lite;
+my %data = $cgi->parse_form_data;
+
+$debug = int($data{debug}) if (defined($data{debug}));
+
+if ( !defined($data{query}) ) {
+print "Content-type: text/html", "\n\n";
+print <<HTML;
+<html>
+ <head>
+ <title>AntiSpamMeta database query page</title>
+ </head>
+ <body>
+ <h3>Maintaining AntiSpamMeta takes work! Please
+<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
+<input type="hidden" name="cmd" value="_s-xclick">
+<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----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-----END PKCS7-----
+">
+<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
+<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
+</form></h3>
+ <p>Matching is done based on field1 OR field2 OR field3 etc. Wildcards are supported,
+except for the realIP field, which must be blank or an IPv4 dotted quad.</p>
+ <form action="/cgi-bin/secret/investigate.pl" method="get">
+ <input type="hidden" name="query" value="1" />
+HTML
+print ' Nickname: <input type="text" name="nick" ' . (defined($data{nick}) ? 'value="'.$data{nick}.'" ' : '') . "/><br />\n";
+print ' User: <input type="text" name="user" ' . (defined($data{user}) ? 'value="'.$data{user}.'" ' : '') . "/><br />\n";
+print ' Hostname: <input type="text" name="host" ' . (defined($data{host}) ? 'value="'.$data{host}.'" ' : '') . "/><br />\n";
+print ' Gecos: <input type="text" name="gecos" ' . (defined($data{gecos}) ? 'value="'.$data{gecos}.'" ' : '') . "/><br />\n";
+print ' Account: <input type="text" name="account" ' . (defined($data{account}) ? 'value="'.$data{account}.'" ' : '') . "/><br />\n";
+print ' Real IP: <input type="text" name="realip" ' . (defined($data{realip}) ? 'value="'.$data{realip}.'" ' : '') . "/>\n";
+print <<HTML;
+ <br /><br /><input type="submit" value="Query!" />
+ </form>
+ </body>
+</html>
+HTML
+exit 0;
+}
+
+if ($debug) {
+ print "Content-type: text/plain", "\n\n";
+ print Dumper(\%data);
+} else {
+ print "Content-type: text/html", "\n\n";
+ print <<HTML;
+<html>
+<head>
+<title>Query results</title>
+<style>
+tr {font-size:90%;}
+.uhg {font-size:60%;}
+.desc {font-size:90%;}
+.time {font-size:80%;}
+.action {}
+.nick {}
+</style>
+</head>
+<body>
+HTML
+}
+
+
+##Queryable items:
+## nick, user, host, realip, gecos, account
+my $qry = 'SELECT * FROM actionlog WHERE ';
+
+if (defined($data{nick}) && ($data{nick} ne "*") && ($data{nick} ne "")) {
+ $qry .= " nick like " . esc($data{nick}) . ' or ';
+}
+
+if (defined($data{user}) && ($data{user} ne "*") && ($data{user} ne "")) {
+ $qry .= ' user like ' . esc($data{user}) . ' or ';
+}
+
+if (defined($data{host}) && ($data{host} ne "*") && ($data{host} ne "")) {
+ $qry .= ' host like ' . esc($data{host}) . ' or ';
+}
+
+if (defined($data{gecos}) && ($data{gecos} ne "*") && ($data{gecos} ne "")) {
+ $qry .= ' gecos like ' . esc($data{gecos}) . ' or ';
+}
+
+if (defined($data{account}) && ($data{account} ne "*") && ($data{account} ne "")) {
+ $qry .= ' account like ' . esc($data{account}) . ' or ';
+}
+
+if (defined($data{realip}) && ($data{realip} =~ /^\d+\.\d+\.\d+\.\d+$/)) {
+ $qry .= ' ip = ' . dottedQuadToInt($data{realip}) . ' or ';
+}
+
+$qry .= '(1 = 0)'; # rather than trying to get rid of a trailing 'or '
+
+if ($debug) {
+ print "Querying: ";
+ print Dumper($qry);
+}
+
+my $sth = $dbh->prepare($qry);
+$sth->execute;
+my $names = $sth->{'NAME'};
+my $numFields = $sth->{'NUM_OF_FIELDS'};
+
+#fields are index,time,action,reason,channel,nick,user,host,ip,gecos,account,bynick,byuser,byhost,bygecos,byaccount
+my %f = (
+ "index" => 0,
+ "time" => 1,
+ "action" => 2,
+ "reason" => 3,
+ "channel" => 4,
+ "nick" => 5,
+ "user" => 6,
+ "host" => 7,
+ "ip" => 8,
+ "gecos" => 9,
+ "account" => 10,
+ "bynick" => 11,
+ "byuser" => 12,
+ "byhost" => 13,
+ "bygecos" => 14,
+ "byaccount" => 15
+);
+
+print "<table border=\"0\">" unless $debug;
+if ($debug) {
+ for (my $i = 0; $i < $numFields; $i++) {
+ printf("%s%s", $i ? "," : "", $$names[$i]);
+ }
+}
+#print "</tr>" unless $debug;
+print "\n";
+
+while (my $ref = $sth->fetchrow_arrayref) {
+#fields are index,time,action,reason,channel,nick,user,host,ip,gecos,account,bynick,byuser,byhost,bygecos,byaccount
+ unless ($debug) {
+ print '<tr>';
+ print '<td><a href="logs.pl?index=' . $$ref[$f{'index'}] . '" class="index">#' . $$ref[$f{'index'}] . ':</a></td>';
+ print '<td nowrap="nowrap" class="time">' . $$ref[$f{'time'}] . '</td>';
+
+ print '<td nowrap="nowrap"><span class="nick">' . $$ref[$f{'nick'}] . '</span>';
+ print '<span class="uhg">!' . $$ref[$f{'user'}] . '@' . $$ref[$f{'host'}] . ' (' . $$ref[$f{'gecos'}] . ')';
+ print ' [' . $$ref[$f{'account'}] . ']' if ($$ref[$f{'account'}] ne '');
+ print '</span>';
+ print ' <span class="desc">received</span> <span class="action">' . $$ref[$f{'action'}] . '</span>';
+ print ' (' . $$ref[$f{'reason'}] . ')' if ($$ref[$f{'reason'}] ne '');
+ print ' <span class="desc">on</span> ' . $$ref[$f{'channel'}] if ($$ref[$f{'channel'}] ne '');
+ print ' ';
+# print '</td>';
+# print '<td>';
+ if ($$ref[$f{'bynick'}] ne '') {
+ print '<span class="desc">by</span> ' . $$ref[$f{'bynick'}];
+ print '<span class="uhg">!' . $$ref[$f{'byuser'}] . '@' . $$ref[$f{'byhost'}] . ' (' . $$ref[$f{'bygecos'}] . ')';
+ print ' [' . $$ref[$f{'byaccount'}] . ']' if ($$ref[$f{'byaccount'}] ne '');
+ print '</span>';
+ }
+ print '</td>';
+ print '</tr>';
+ } else {
+ for (my $i = 0; $i < $numFields; $i++) {
+ printf("%s%s", $i ? "," : "", $$ref[$i]);
+ }
+ }
+ print "\n";
+}
+unless ($debug) {
+ print "</table></body></html>";
+}
diff --git a/cgi-bin/secret/logs.pl b/cgi-bin/secret/logs.pl
new file mode 100755
index 0000000..419f450
--- /dev/null
+++ b/cgi-bin/secret/logs.pl
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+
+#use warnings;
+use Data::Dumper;
+use strict;
+use DBI;
+
+use CGI_Lite;
+my $cgi = new CGI_Lite;
+my %data = $cgi->parse_form_data;
+my $index = $data{index};
+print "Content-type: text/plain", "\n\n";
+if ( !defined($index) ) {
+ print "Nice hax!\n";
+ exit 0;
+}
+$index = int $index;
+
+if ( $index < 50000) {
+ my $block;
+ $block = "50K" if $index < 50000;
+ $block = "40K" if $index < 40000;
+ $block = "30K" if $index < 30000;
+ $block = "20K" if $index < 20000;
+ $block = "10K" if $index < 10000;
+ print "tar -Oxf /var/www/actionlogs/$block.tar.gz $index.txt\n\n";
+ print `tar -Oxf /var/www/actionlogs/$block.tar.gz $index.txt`;
+} elsif ( -e "/var/www/actionlogs/$index.txt.lzma" ) {
+ print `lzcat /var/www/actionlogs/$index.txt.lzma`;
+} elsif ( -e "/var/www/actionlogs/$index.txt" ) {
+ print `cat /var/www/actionlogs/$index.txt`;
+} else {
+ print "u wot m8?\n";
+}
diff --git a/cgi-bin/showUsers.pl b/cgi-bin/showUsers.pl
new file mode 100755
index 0000000..913ee22
--- /dev/null
+++ b/cgi-bin/showUsers.pl
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+
+#use warnings;
+use Data::Dumper;
+use strict;
+use DBI;
+use XML::Simple qw(:strict);
+
+
+print "Content-type: text/html", "\n\n";
+print <<HTML;
+<html>
+ <head>
+ <title>AntiSpamMeta User List</title>
+ </head>
+ <body>
+ <h3>Maintaining AntiSpamMeta takes work! Please
+<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
+<input type="hidden" name="cmd" value="_s-xclick">
+<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----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-----END PKCS7-----
+">
+<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
+<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
+</form></h3>
+<table>
+<tr><th>NickServ account</th><th>h</th><th>s</th><th>a</th><th>d</th></tr>
+HTML
+
+my $xs1 = XML::Simple->new( KeyAttr => ['id'], Cache => [ qw/memcopy/ ]);
+my $users = $xs1->XMLin( "/home/icxcnika/AntiSpamMeta/config-main/users.xml", ForceArray => 'person');
+
+sub printout
+{
+ my ($user) = @_;
+ print "<tr><td style=\"text-align:right\">$user</td>";
+ print "<td>";
+ print "x" if (index($users->{person}->{$user}->{flags}, 'h') != -1);
+ print "</td>";
+ print "<td>";
+ print "x" if (index($users->{person}->{$user}->{flags}, 's') != -1);
+ print "</td>";
+ print "<td>";
+ print "x" if (index($users->{person}->{$user}->{flags}, 'a') != -1);
+ print "</td>";
+ print "<td>";
+ print "x" if (index($users->{person}->{$user}->{flags}, 'd') != -1);
+ print "</td>";
+ print "</tr>\n";
+}
+
+foreach my $user (keys %{$users->{person}}) {
+ if (index($users->{person}->{$user}->{flags}, 'd') != -1) {
+ printout($user);
+ delete $users->{person}->{$user};
+ }
+}
+foreach my $user (keys %{$users->{person}}) {
+ if (index($users->{person}->{$user}->{flags}, 'a') != -1) {
+ printout($user);
+ delete $users->{person}->{$user};
+ }
+}
+foreach my $user (keys %{$users->{person}}) {
+ if (index($users->{person}->{$user}->{flags}, 's') != -1) {
+ printout($user);
+ delete $users->{person}->{$user}
+ }
+}
+
+foreach my $user (keys %{$users->{person}}) {
+ printout($user);
+}
+print "</table></body></html>";
+
+exit 0;