| 
					
				 | 
			
			
				@@ -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 
			 |