Index: trunk/mwblocker/checklog-table.sql |
— | — | @@ -0,0 +1,9 @@ |
| 2 | +CREATE TABLE checklog ( |
| 3 | + check_timestamp DATETIME, |
| 4 | + check_ip VARCHAR(40), |
| 5 | + check_blocked TINYINT(1), |
| 6 | + check_log TEXT, |
| 7 | + KEY (check_ip,check_blocked), |
| 8 | + KEY (check_blocked,check_IP), |
| 9 | + KEY (check_timestamp) |
| 10 | +); |
Property changes on: trunk/mwblocker/checklog-table.sql |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 11 | + native |
Added: svn:keywords |
2 | 12 | + Author Date Id Revision |
Index: trunk/mwblocker/MWBlocker/Checker.boo |
— | — | @@ -78,13 +78,29 @@ |
79 | 79 | |
80 | 80 | def Guilty(sig as string): |
81 | 81 | Log("${_suspect} matches scan signature ${sig}") |
82 | | - //LogScan(_suspect, sig) |
83 | | - actions = CommaList(sig, "action") |
84 | | - MailReport() |
| 82 | + block = false |
| 83 | + mail = false |
| 84 | + for action in CommaList(sig, "action"): |
| 85 | + if action == "block": |
| 86 | + Log("Blocking IP.") |
| 87 | + block = true |
| 88 | + if action == "mail": |
| 89 | + mail = true |
| 90 | + MailReport() |
| 91 | + try: |
| 92 | + Recorder.Record(_suspect, block, _log.ToString()) |
| 93 | + except e: |
| 94 | + Log("Failed to record to block database: ${e}") |
| 95 | + if mail: |
| 96 | + MailReport() |
85 | 97 | return true |
86 | 98 | |
87 | 99 | def Innocent(): |
88 | 100 | Log("${_suspect} is clear of known signatures") |
| 101 | + try: |
| 102 | + Recorder.Record(_suspect, false, _log.ToString()) |
| 103 | + except e: |
| 104 | + Log("Failed to record to check log database: ${e}") |
89 | 105 | return false |
90 | 106 | |
91 | 107 | def MailReport(): |
Index: trunk/mwblocker/MWBlocker/Recorder.boo |
— | — | @@ -0,0 +1,65 @@ |
| 2 | +// created on 9/7/2005 at 6:25 PM |
| 3 | + |
| 4 | +namespace MediaWiki.Blocker |
| 5 | + |
| 6 | +import System |
| 7 | +import System.Data |
| 8 | + |
| 9 | +// Current MySQL Connector/NET is broken on non-Windows platforms |
| 10 | +//import MySql.Data.MySqlClient |
| 11 | +import ByteFX.Data.MySqlClient |
| 12 | + |
| 13 | +class Recorder: |
| 14 | + static def IsChecked(suspect as Suspect): |
| 15 | + return CheckHits(suspect, "") |
| 16 | + |
| 17 | + static def IsBlocked(suspect as Suspect): |
| 18 | + return CheckHits(suspect, "AND check_blocked") |
| 19 | + |
| 20 | + static def CheckHits(suspect as Suspect, where as string): |
| 21 | + try: |
| 22 | + cmd = MySqlCommand("""SELECT COUNT(*) FROM checklog WHERE check_ip=@ip ${where}""", Connection) |
| 23 | + cmd.Parameters.Add("@ip", suspect.IP.ToString()) |
| 24 | + using reader = cmd.ExecuteReader(CommandBehavior.SingleResult): |
| 25 | + reader.Read() |
| 26 | + return reader.GetInt32(0) > 0 |
| 27 | + except e: |
| 28 | + print "Ouch: ${e}" |
| 29 | + return false |
| 30 | + |
| 31 | + static def Record(suspect as Suspect, blocked as bool, log as string): |
| 32 | + cmd = MySqlCommand("""INSERT INTO checklog |
| 33 | + (check_timestamp, check_ip, check_blocked, check_log) |
| 34 | + VALUES (@timestamp, @ip, @blocked, @log)""", Connection) |
| 35 | + cmd.Parameters.Add("@timestamp", DateTime.UtcNow) |
| 36 | + cmd.Parameters.Add("@ip", suspect.IP.ToString()) |
| 37 | + cmd.Parameters.Add("@blocked", blocked) |
| 38 | + cmd.Parameters.Add("@log", log) |
| 39 | + cmd.ExecuteNonQuery() |
| 40 | + |
| 41 | + static def FormatTimestamp(ts as DateTime): |
| 42 | + return ts.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'") |
| 43 | + |
| 44 | + static def TimestampFormat(time as DateTime): |
| 45 | + return "{0:0000}{1:00}{2:00}{3:00}{4:00}{5:00}" % ( |
| 46 | + time.Year, |
| 47 | + time.Month, |
| 48 | + time.Day, |
| 49 | + time.Hour, |
| 50 | + time.Minute, |
| 51 | + time.Second) |
| 52 | + |
| 53 | + static _db as MySqlConnection |
| 54 | + |
| 55 | + static Connection as MySqlConnection: |
| 56 | + get: |
| 57 | + if _db is null: |
| 58 | + server = "localhost" |
| 59 | + user = "wikiuser" |
| 60 | + password = "userman" |
| 61 | + database = "blocker" |
| 62 | + connstr = "server=${server};uid=${user};pwd=${password};database=${database};pooling=false" |
| 63 | + db = MySqlConnection(connstr) |
| 64 | + db.Open() |
| 65 | + _db = db |
| 66 | + return _db |
Property changes on: trunk/mwblocker/MWBlocker/Recorder.boo |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 67 | + native |
Added: svn:keywords |
2 | 68 | + Author Date Id Revision |
Index: trunk/mwblocker/MWBlocker/MWBlocker.mdp |
— | — | @@ -26,6 +26,7 @@ |
27 | 27 | <File name="./CheckerThread.boo" subtype="Code" buildaction="Compile" /> |
28 | 28 | <File name="./app.config" subtype="Code" buildaction="Nothing" /> |
29 | 29 | <File name="./Suspect.boo" subtype="Code" buildaction="Compile" /> |
| 30 | + <File name="./Recorder.boo" subtype="Code" buildaction="Compile" /> |
30 | 31 | </Contents> |
31 | 32 | <References> |
32 | 33 | <ProjectReference type="Gac" localcopy="True" refto="Boo.Lang, Version=1.0.0.0, Culture=neutral, PublicKeyToken=32c39770e9a21a67" /> |
— | — | @@ -33,5 +34,7 @@ |
34 | 35 | <ProjectReference type="Assembly" localcopy="True" refto="../libs/CookComputing.XmlRpc.dll" /> |
35 | 36 | <ProjectReference type="Gac" localcopy="True" refto="System.Web, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> |
36 | 37 | <ProjectReference type="Assembly" localcopy="True" refto="../libs/Nini.dll" /> |
| 38 | + <ProjectReference type="Gac" localcopy="True" refto="System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> |
| 39 | + <ProjectReference type="Gac" localcopy="True" refto="ByteFX.Data, Version=0.7.6.1, Culture=neutral, PublicKeyToken=0738eb9f132ed756" /> |
37 | 40 | </References> |
38 | 41 | </Project> |
\ No newline at end of file |
Index: trunk/mwblocker/MWBlocker/CheckerThread.boo |
— | — | @@ -20,10 +20,12 @@ |
21 | 21 | while true: |
22 | 22 | try: |
23 | 23 | next = _queue.Dequeue() as Suspect |
24 | | - if Checker(next).Check(): |
25 | | - _positiveCount++ |
26 | | - _checkedCount++ |
27 | | - print next |
| 24 | + if Recorder.IsChecked(next): |
| 25 | + print "Skipping previously checked ${next}" |
| 26 | + else: |
| 27 | + if Checker(next).Check(): |
| 28 | + _positiveCount++ |
| 29 | + _checkedCount++ |
28 | 30 | except e as InvalidOperationException: |
29 | 31 | // Nothing there; wait a bit. |
30 | 32 | Thread.Sleep(1000) |