|
@@ -5,8 +5,10 @@
|
|
|
namespace eval ::putils {
|
|
|
## some internal variables for messaging and stuff :) not your business after all.
|
|
|
|
|
|
- set local_ver "0.3"
|
|
|
+ set local_ver "0.4truncatesender"
|
|
|
|
|
|
+ package require base64
|
|
|
+ package require md5
|
|
|
|
|
|
# if putils-variable (thus, putils!) is already loaded, then .. well .. load again, but, this time, quietly. ;-)
|
|
|
if {![info exists putils]} {
|
|
@@ -66,6 +68,191 @@ proc ::putils::kill_spaces {text} {
|
|
|
return $text
|
|
|
}
|
|
|
|
|
|
+proc ::putils::put_bot {target_botnetnick fromdata} {
|
|
|
+ # real maxlen for putbot is 400. but we have overhead.
|
|
|
+ set maxmsglen 330
|
|
|
+
|
|
|
+ set calcmsglen [expr $maxmsglen + 1]
|
|
|
+
|
|
|
+ #debug
|
|
|
+ #set fromdata "12345678901234567890"
|
|
|
+
|
|
|
+ if {[islinked $target_botnetnick] == 1} {
|
|
|
+
|
|
|
+ # prepare data ...! encode. send multiple data, if needed.
|
|
|
+ # encode it, base64
|
|
|
+ set data [::base64::encode $fromdata]
|
|
|
+ putlog "base64: $data"
|
|
|
+
|
|
|
+ # make a hash of $data
|
|
|
+ set md5 [::md5::md5 -hex $data]
|
|
|
+ putlog "md5: $md5"
|
|
|
+
|
|
|
+ set data_len [string length $data]
|
|
|
+ putlog "data_len: $data_len"
|
|
|
+
|
|
|
+ # into how many pieces does this message to be splitted?
|
|
|
+ # default 1
|
|
|
+ set count_parts 1
|
|
|
+ if {$data_len > $calcmsglen} {
|
|
|
+ set count_parts [expr $data_len / $calcmsglen]
|
|
|
+ set remainder [expr $data_len % $calcmsglen]
|
|
|
+ set real [expr ${data_len}.00 / ${calcmsglen}.00]
|
|
|
+ putlog "remainder: $remainder real: $real"
|
|
|
+ if {[expr $data_len % $calcmsglen] > 0} {
|
|
|
+ set count_parts [expr $count_parts + 1]
|
|
|
+ }
|
|
|
+ putlog "length: $data_len messagedata will be divided into $count_parts parts"
|
|
|
+ }
|
|
|
+#MTIzNDU2Nzg5MDEyMzQ1Njc4OTA=
|
|
|
+#MTIzNDU2
|
|
|
+#Nzg5MDEy
|
|
|
+#MzQ1Njc4
|
|
|
+#OTA=
|
|
|
+ # cut data into pieces and send!
|
|
|
+ for {set x 0} {$x < $count_parts} {incr x} {
|
|
|
+ puts "x is $x"
|
|
|
+
|
|
|
+ # get the part
|
|
|
+ set part [string range $data 0 $maxmsglen]
|
|
|
+
|
|
|
+ # kill the part out of the original string
|
|
|
+ set data [string replace $data 0 $maxmsglen ""]
|
|
|
+
|
|
|
+ putbot $target_botnetnick [concat "rec_putils " $md5 " " [expr $x + 1] " " $count_parts " " $part]
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ putlog "::putils:: put_bot: + a message delivered to ${target_botnetnick}."
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ putlog "::putils:: put_bot: + a message couldn't be delivered. Bot ${target_botnetnick} is not linked"
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+proc ::putils::rec_bot {sender_botnetnick cmd rec_data} {
|
|
|
+ # cmd is "rec_putils"
|
|
|
+ #putlog "inside rec_bot. we want to decode rec_data: $rec_data"
|
|
|
+
|
|
|
+ set rec_data [split $rec_data]
|
|
|
+
|
|
|
+ set message_hash [join [lindex $rec_data 0]]
|
|
|
+ set current_part [join [lindex $rec_data 1]]
|
|
|
+ #putlog "current_part: $current_part"
|
|
|
+ set count_parts [join [lindex $rec_data 2]]
|
|
|
+ #putlog "count_parts: $count_parts"
|
|
|
+
|
|
|
+ set base64data [join [lindex $rec_data 3]]
|
|
|
+
|
|
|
+ variable themessage
|
|
|
+ variable kill_coordinates
|
|
|
+ variable kill_timer_id
|
|
|
+
|
|
|
+ # push to intermediary variable .. everything is there. it's our message stack.
|
|
|
+ lappend themessage "$message_hash" "${current_part}" "$count_parts" "${base64data}"
|
|
|
+
|
|
|
+ # kill old one, start a new one.
|
|
|
+ if {[info exists kill_timer_id]} {
|
|
|
+ set timerlist [utimers]
|
|
|
+
|
|
|
+ foreach {timerinfo} $timerlist {
|
|
|
+ set timer_id [join [lindex $timerinfo 2]]
|
|
|
+ if {$timer_id == $kill_timer_id} {
|
|
|
+ killutimer $kill_timer_id
|
|
|
+ }
|
|
|
+ }
|
|
|
+ unset kill_timer_id
|
|
|
+ unset kill_coordinates
|
|
|
+ }
|
|
|
+ set kill_timer_id [utimer 2 "::putils::timer_cleanup"]
|
|
|
+
|
|
|
+ proc ::putils::timer_cleanup {} {
|
|
|
+ set themessage ""
|
|
|
+ set kill_coordinates ""
|
|
|
+ }
|
|
|
+
|
|
|
+ # .tcl namespace eval ::putils { unset themessage }
|
|
|
+ set copymessage $themessage
|
|
|
+
|
|
|
+ set my_count 0
|
|
|
+ set before_part ""
|
|
|
+
|
|
|
+ # build a null list with X-count-elements
|
|
|
+ set base64 ""
|
|
|
+ for {set x 1} {$x <= $count_parts} {incr x} {
|
|
|
+ lappend base64 $x
|
|
|
+ }
|
|
|
+
|
|
|
+ set iteration 0
|
|
|
+ set finish 0
|
|
|
+ foreach {hash current_part count base64data} $copymessage {
|
|
|
+ incr iteration
|
|
|
+ if {$hash == $message_hash} {
|
|
|
+
|
|
|
+ if {$current_part != $before_part} {
|
|
|
+ incr my_count
|
|
|
+ set before_part $current_part
|
|
|
+
|
|
|
+ # insert the element into the right place of the X-count-element list
|
|
|
+ lset base64 [expr $current_part - 1] $base64data
|
|
|
+ # save the coordinates for later deletion.
|
|
|
+ #1*4 - 4 3 2 1
|
|
|
+ set kill_from [expr ($iteration * 4) - 4]
|
|
|
+ set kill_to [expr ($iteration * 4) - 1]
|
|
|
+ lappend kill_coordinates $kill_from $kill_to
|
|
|
+ #putlog "current_part: $current_part kill_from: $kill_from kill_to: $kill_to"
|
|
|
+
|
|
|
+ if {$my_count == $count} {
|
|
|
+ regsub -all " " ${base64} "" base64
|
|
|
+ #putlog "base64: $base64"
|
|
|
+ set finish 1
|
|
|
+ # now delete this 4 from the $themessage
|
|
|
+ foreach {kill_from kill_to} $kill_coordinates {
|
|
|
+ putlog "kill_from: $kill_from kill_to: $kill_to"
|
|
|
+ for {set y $kill_from} {$y <= $kill_to} {incr y} {
|
|
|
+ lset themessage $y "X"
|
|
|
+ #putlog "themessage: $themessage"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ set kill_coordinates ""
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if {$finish == 1} {
|
|
|
+ putlog "base64: $base64"
|
|
|
+ # decode base64data ...
|
|
|
+ set original_data [::base64::decode $base64]
|
|
|
+ #putlog "original_data1: $original_data"
|
|
|
+ set original_data [split $original_data]
|
|
|
+ putlog "original_data2: $original_data"
|
|
|
+
|
|
|
+ set md5 [::md5::md5 -hex $base64]
|
|
|
+ if {$md5 == $message_hash} {
|
|
|
+ #putlog "alright md5"
|
|
|
+ # start the targetted procedure with the received data. if available.
|
|
|
+ set bindlist [split [join [binds bot]]]
|
|
|
+ foreach {type o cmd cnt procedure} $bindlist {
|
|
|
+ putlog "cmd: $cmd procedure: $procedure"
|
|
|
+ # FIXME: we currently don't check for permissions...
|
|
|
+ if {$cmd == [join [lindex $original_data 0]]} {
|
|
|
+ putlog "execute procedure $procedure $sender_botnetnick [join [lindex $original_data 0]] [join [lrange $original_data 1 end]]"
|
|
|
+ #execute procedure
|
|
|
+ $procedure $sender_botnetnick [join [lindex $original_data 0]] [join [lrange $original_data 1 end]]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+bind bot - rec_putils ::putils::rec_bot
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
# cleans the input text from all irc control codes... and even has
|