-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsalsacrypt.tcl
346 lines (323 loc) · 11.4 KB
/
salsacrypt.tcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# salsacrypt.tcl by kniffy, based on blowcrypt.tcl v3.6 by poci/PPX
#
# all of this was made easy because of FiSHDANCE, courtesy tittof :)
#
# newskool changelog:
#
# 1.0 / 24.07.2017
# - blowfish cipher changed to xsalsa20+poly1305
#
# oldskool changelog:
#
# 3.5 to 3.6 / 23.12.2006 09:53:04
# - typo (exlusive-binds) fixed!!
# - fixed bug on nicks with special chars
# - fixed bug with " ... messages
# - more eggdrop-like behaviour ( even messages w/o : are valid for 1 word )
# - fixed nicktracker
#
# 3.1 to 3.5 / 06.06.2006 23:32:43
# - 1.6.18rc1 behaviour (exclusive-binds)
# - external configuration file
# - internal code now put into bc-namespace
# - mode-splitup: normal or paranoid (read blowcrypt.conf)
#
# 3.0 to 3.1 / 05.01.2006 16:34:57
# - added a message length check (message with no content wont be sent just like the real behaviour of eggdrop)
# - removed array unset again so exchanged keys wont get deleted on rehash
#
# following changes were sent in by neoxed
# - corrected several spelling mistakes
# - binds are compared case-insensitively
# - the lastbind variable is now updated to the appropriate command name
# - bind callbacks are now properly expanded before evaluation
#
# 2.5 to 3.0 / 24.07.2005 12:10:43
# - added a command (ismsgencrypted) that returns 1 if the bind was toggled by a encrypted message and 0 if not (useful for script developers only)
# - channelnames dont have to be lower case any more (thats one thing many users got stuck with)
# - fixed: loading scripts/DH1080_tcl.dll even if blowso was set to something else
# - other minor changes
# - pubm/msgm support
#
# 2.3 to 2.5 / 10.06.2005 18:43:14
# - now the keyexchange part gets disabled if DH1080_tcl.so does not exist. so the script works just without keyexchange :]
# - option to change the location of DH1080_tcl.so
# - i also compiled a windows version of DH1080_tcl. get it on http://poci.u5-inside.de! (means 100% windrop compatible) =)
#
# 2.2 to 2.3 / 30.12.2004 12:52:24
# - i took both 2.2's (sorry for the misleading versioning) and put the advantages of each in 1 script = 2.3 :)
#
# 2.1 to 2.2 / 15.12.2004 17:27:09
# - no "space-stripping" anymore ;>
# - test command
#
# look forward for another version with pubm support ;>
#
# !! COMPILE FISHDANCE !!
#
load scripts/libfishdance.so
# initializing stuff
namespace eval bc {
variable keys
variable userkeys
variable mode
variable keyexmod
variable tmpkey
variable paradata
variable paratimer
variable version 36
}
if {[catch {source [file dirname [info script]]/salsacrypt.conf} error]} {
putlog "\002bc\002:error: $error"
return
}
catch {rename putquick putquick2;rename putserv putserv2;rename puthelp puthelp2}
# wrapper & api
proc ::puthelp {text {option ""}} {
::bc::put puthelp $text $option
}
proc ::putserv {text {option ""}} {
::bc::put putserv $text $option
}
proc ::putquick {text {option ""}} {
::bc::put putquick $text $option
}
proc ::ismsgencrypted {} {
if {[info exists ::bc::isencryptedmessage]} {return 1}
return 0
}
# internal
proc ::bc::put {type text {option ""}} {
if {![regexp -nocase {^(privmsg) ?.+$} $text "" msgtype]} {
${type}2 $text
return
}
if {![regexp -nocase {^(\S+) (\S+) :(.+)$} $text "" msgtype msgdest msgtext]} {
if {![regexp -nocase {^(\S+) (\S+) (\S+)$} $text "" msgtype msgdest msgtext]} {
putlog "BOGUS MESSAGE!"; return
}
}
set key [::bc::getKey $msgdest]
if {$option==""} {
if {$key!=""} {
${type}2 "PRIVMSG $msgdest :+OK [::fishdance::encrypt $key $msgtext]"
} else {
if {$::bc::mode=="paranoid"} {
if {[string match "#*" $msgdest]} {
putlog "nonono"
} else {
if {![info exists ::bc::paradata([string tolower $msgdest])]} {
::bc::initKeyExchange $msgdest
set ::bc::paradata([string tolower $msgdest]) [list [list $type $text]]
set ::bc::paratimer([string tolower $msgdest]) [utimer 10 "[list unset ::bc::paradata([string tolower $msgdest])];[list ${type}2 "PRIVMSG $msgdest :get a keyex plugin!"]"]
} else {
lappend ::bc::paradata([string tolower $msgdest]) [list $type $text]
killutimer $::bc::paratimer([string tolower $msgdest])
set ::bc::paratimer([string tolower $msgdest]) [utimer 10 "[list unset ::bc::paradata([string tolower $msgdest])];[list ${type}2 "PRIVMSG $msgdest :get a keyex plugin!"]"]
}
}
} else {
${type}2 $text
}
}
} else {
if {$key!=""} {
${type}2 "PRIVMSG $msgdest :+OK [::fishdance::encrypt $key $msgtext]" $option
} else {
if {$::bc::mode=="paranoid"} {
if {[string match "#*" $msgdest]} {
putlog "nonono"
} else {
if {![info exists ::bc::paradata([string tolower $msgdest])]} {
::bc::initKeyExchange $msgdest
set ::bc::paradata([string tolower $msgdest]) [list [list $type $text $option]]
set ::bc::paratimer([string tolower $msgdest]) [utimer 10 "[list unset ::bc::paradata([string tolower $msgdest])];[list ${type}2 "PRIVMSG $msgdest :get a keyex plugin!"]"]
} else {
lappend ::bc::paradata([string tolower $msgdest]) [list $type $text $option]
killutimer $::bc::paratimer([string tolower $msgdest])
set ::bc::paratimer([string tolower $msgdest]) [utimer 10 "[list unset ::bc::paradata([string tolower $msgdest])];[list ${type}2 "PRIVMSG $msgdest :get a keyex plugin!"]"]
}
}
} else {
${type}2 $text $option
}
}
}
}
proc ::bc::getKey {for} {
if {![string match "#*" $for]} {
if {[info exists ::bc::userkeys([string tolower $for])]} {
return $::bc::userkeys([string tolower $for])
}
}
foreach entry $::bc::keys {
if {[string equal -nocase $for [lindex [split $entry] 0]]} {
return [lindex $entry 1]
}
}
}
proc ::bc::onEncryptedText {nick host hand chan arg} {
set key [::bc::getKey $chan]
if {$key==""} {return}
set tmp [::fishdance::decrypt $key $arg]
if {[regexp {^(\S+) ?(.*)$} $tmp "" trigger arguments]} {
foreach item [binds pub] {
if {[lindex $item 2]=="+OK"} {continue}
if {[lindex $item 1]!="-|-"} {
if {![matchattr $hand [lindex $item 1] $chan]} {continue}
}
if {[string equal -nocase [lindex $item 2] $trigger]} {
# The lastbind variable must be updated to reflect the
# command being triggered, otherwise will always be "+OK".
set ::lastbind [lindex $item 2]
set ::bc::isencryptedmessage 1
# Use "eval" to expand the callback script, for example:
# bind pub -|- !something [list PubCommand MyEvent]
# proc PubCommand {event nick host hand chan text} {...}
eval [lindex $item 4] [list $nick $host $hand $chan $arguments]
unset ::bc::isencryptedmessage
if {[info exists ::exclusive-binds] && ${::exclusive-binds}} {
return
}
}
}
}
foreach item [binds pubm] {
if {[lindex $item 2]=="+OK"} {continue}
if {[lindex $item 1]!="-|-"} {
if {![matchattr $hand [lindex $item 1] $chan]} {continue}
}
if {[string match -nocase [lindex $item 2] "$chan $tmp"]} {
set ::lastbind [lindex $item 2]
set ::bc::isencryptedmessage 1
eval [lindex $item 4] [list $nick $host $hand $chan $tmp]
unset ::bc::isencryptedmessage
}
}
}
proc ::bc::onEncryptedMsg {nick host hand arg} {
set key [::bc::getKey $nick]
if {$key==""} {
puthelp2 "PRIVMSG $nick :remove your key or exchange a new one with me"
return
}
set tmp [::fishdance::decrypt $key $arg]
if {[regexp {^(\S+) ?(.*)$} $tmp "" trigger arguments]} {
foreach item [binds msg] {
if {[lindex $item 2]=="+OK"} {continue}
if {[lindex $item 1]!="-|-"} {
if {![matchattr $hand [lindex $item 1]]} {continue}
}
if {![string compare -nocase [lindex $item 2] $trigger]} {
# The lastbind variable must be updated to reflect the
# command being triggered, otherwise will always be "+OK".
set ::lastbind [lindex $item 2]
set ::bc::isencryptedmessage 1
# Use "eval" to expand the callback script, for example:
# bind msg -|- !something [list MsgCommand MyEvent]
# proc MsgCommand {event nick host hand text} {...}
eval [lindex $item 4] [list $nick $host $hand $arguments]
unset ::bc::isencryptedmessage
if {[info exists ::exclusive-binds] && ${::exclusive-binds}} {
return
}
}
}
}
foreach item [binds msgm] {
if {[lindex $item 2]=="+OK"} {continue}
if {[lindex $item 1]!="-|-"} {
if {![matchattr $hand [lindex $item 1]]} {continue}
}
if {[string match -nocase [lindex $item 2] $tmp]} {
set ::lastbind [lindex $item 2]
set ::bc::isencryptedmessage 1
eval [lindex $item 4] [list $nick $host $hand $tmp]
unset ::bc::isencryptedmessage
}
}
}
proc ::bc::unsetKey {for} {
foreach index [array names ::bc::userkeys] {
if {[string equal -nocase $for $index]} {
unset ::bc::userkeys($index)
return 1
}
}
return 0
}
proc ::bc::bckeydel {nick host hand arg} {
unsetKey $nick
puthelp2 "PRIVMSG $nick :done!"
}
proc ::bc::keyexnick {nick host hand chan newnick} {
if {[info exists ::bc::userkeys([string tolower $nick])] && [string tolower $nick]!=[string tolower $newnick]} {
set ::bc::userkeys([string tolower $newnick]) $::bc::userkeys([string tolower $nick])
unset ::bc::userkeys([string tolower $nick])
}
}
proc ::bc::initKeyExchange {nick} {
set privkey [string repeat x 300]
set pubkey [string repeat x 300]
DH1080gen "$privkey" "$pubkey"
set ::bc::tmpkey($nick) "$privkey"
putquick2 "NOTICE $nick :DH1080_INIT $pubkey"
}
proc ::bc::onKeyExchangeInit {nick host handle text dest} {
if {![string equal -nocase $dest $::botnick]} {return}
if {![regexp -nocase {dh1080_init (\S+)} $text "" hispubkey]} {return}
set myprivkey [string repeat x 300]
set mypubkey [string repeat x 300]
DH1080gen "$myprivkey" "$mypubkey"
putquick2 "NOTICE $nick :DH1080_FINISH $mypubkey"
DH1080comp "$myprivkey" "$hispubkey"
set ::bc::userkeys([string tolower $nick]) $hispubkey
# do paranoid mode stuff
if {[info exists ::bc::paradata([string tolower $nick])]} {
foreach entry $::bc::paradata([string tolower $nick]) {
[lindex $entry 0] [lindex $entry 1]
}
killutimer $::bc::paratimer([string tolower $nick])
unset ::bc::paratimer([string tolower $nick])
unset ::bc::paradata([string tolower $nick])
}
# till here
unset hispubkey
}
proc ::bc::onKeyExchangeFinish {nick host handle text dest} {
if {![string equal -nocase $dest $::botnick]} {return}
if {![regexp -nocase {dh1080_finish (\S+)} $text "" hispubkey]} {return}
DH1080comp "$::bc::tmpkey($nick)" "$hispubkey"
set ::bc::userkeys([string tolower $nick]) $hispubkey
# do paranoid mode stuff
if {[info exists ::bc::paradata([string tolower $nick])]} {
foreach entry $::bc::paradata([string tolower $nick]) {
[lindex $entry 0] [lindex $entry 1]
}
killutimer $::bc::paratimer([string tolower $nick])
unset ::bc::paratimer([string tolower $nick])
unset ::bc::paradata([string tolower $nick])
}
# till here
unset ::bc::tmpkey($nick)
unset hispubkey
}
# binds
bind pub - +OK ::bc::onEncryptedText
if {![catch {load $::bc::keyexmod} error]} {
bind msg - +OK ::bc::onEncryptedMsg
bind msg - !bckeydel ::bc::bckeydel
bind nick - * ::bc::keyexnick
bind notc - "DH1080_INIT *" ::bc::onKeyExchangeInit
bind notc - "DH1080_FINISH *" ::bc::onKeyExchangeFinish
} else {
if {$::bc::keyexmod!=""} {
putlog "\002bc\002:warning: $error - keyexchange is disabled until we can load it someday :>"
}
}
proc test { nick host hand chan arg } {
puthelp "PRIVMSG $chan :$nick-$host-$hand-$chan-$arg"
}
bind pub - !test test
#putlog "blowcrypt.tcl v[format %.1f [expr $::bc::version / 10.0]] by poci/PPX - blowcrypting the scene since ~2003!"
putlog "salsacrypt loaded, word to your mom!"