IRC8.mrc
· 3.7 KiB · Text
Raw
; IRC8 connection by JD
on ^1:LOGON:*:{
raw -q IRCVERS IRC8 MSN-OCX!9.02.0310.2401
raw -q AUTH GateKeeper I : $+ $gk.header(1)
haltdef
}
on 1:PARSELINE:in:*:{
tokenize 32 $parseline
if ($1 == AUTH) {
if ($2 == GateKeeper || $2 == GateKeeperPassport) {
if ($3 == S) {
; Extended (Passport) Authentication. Send %ticket and %passport to server.
if ($2- == GateKeeperPassport S :OK) {
raw -qn $1-3 $+($base($len(%ticket), 10, 16, 8), %ticket, $base($len(%profile), 10, 16, 8), %profile)
}
; Attempt to find GateKeeper v3 Challenge (8 bytes, escaped)
elseif ($regex($gettok($parseline,4-,32), /^:GKSSP\\0(?:[^\\]|\\.){2}\x03\\0\\0\\0\x02\\0\\0\\0((?:[^\\]|\\.){8})$/u) > 0) {
; Escaped text can contain characters the client can't handle (eg. 0x00), so convert to &binvar
bset -a &challenge 1 $regsubex($regml(1) $+ $servertarget, /([^\\]|\\.)/gu, $gk.asc(\1) $+ $chr(32))
; GateKeeper authenticaiton is a HMAC-MD5 with fixed key
var %result = $hmac(&challenge, SRFMKSJANDRESKKC, md5, 1)
.parseline -it
.raw -n $1-3 $+(:,$gk.header(3),$regsubex(%result $+ $gk.guid($2), /([0-9a-f]{2})/g, $gk.hex2chr(\1)))
}
else {
echo $color(info2) -t * GateKeeper Authentication Failed
}
}
elseif ($3 == *) {
var %oid = $iif($5 != 0, $+($chr(40),OID: $5,$chr(41)))
echo $color(info) -t * Logged in as $4 %oid
.parseline -it
raw -q USER $username * * : $+ $iif($fullname, $ifmatch, ...)
raw -q NICK $me
}
else {
echo $color(info2) -t * GateKeeper Authentication Failed
}
}
else {
; This is not GateKeeper.
echo $color(info2) -t * ERROR: Unknown Authentication Package $+($chr(40),$2,$chr(41))
}
}
elseif ($2 == JOIN) {
.parseline -it $1-2 $4-
if ($gettok($3, 4, 44) isin +@.) {
parseline -itq $+($1 MODE $right($4, -1) +, $replace($gettok($3, 4, 44), +, v, @, o, ., q) $right($gettok($1, 1, 33), -1))
}
}
elseif ($2 == 004) {
.parseline -itq : $+ $server 005 $me PREFIX=(qov).@+ CHANTYPES=%#
}
elseif ($2 == 353) {
var %original = $right($6-, -1)
var %new
var %i = 1
while (%i <= $numtok(%original, 32)) {
var %user = $gettok(%original, %i, 32)
%new = %new $gettok(%user, $numtok(%user, 44), 44)
inc %i
}
.parseline -it $1-5 : $+ %new
}
}
; Usage: $gk.header(sequence) - Returns GateKeeper v3 header with specified sequence (1 or 3 for client)
alias -l gk.header return $+(GKSSP\0JD,$chr(3),\0\0\0,$chr($$1),\0\0\0)
; Usage: $gk.asc(char) - Returns $asc equivalent for a potentially escaped character (eg. \n)
alias -l gk.asc {
; Not escaped
if ($left($1, 1) != \) return $asc($1)
; Invalid escape
elseif ($mid($1, 2, 1) !isincs 0tnrbc\) return $asc($mid($1, 2, 1))
; Valid escape (\0 doesn't need replacement)
return $replacecs($mid($1, 2, 1), t, 9, n, 10, r, 13, b, 32, c, 44, \, 92)
}
; Usage: $gk.hex2chr(hex) - Returns an escaped $chr equivalent from hex
alias -l gk.hex2chr {
; Normalise - Remove zero padding
var %h = $base($1, 16, 16)
; Chars need escapinh
if (%h == 0) return \0
elseif (%h == 9) return \t
elseif (%h == A) return \n
elseif (%h == D) return \r
elseif (%h == 20) return \b
elseif (%h == 2C) return \c
elseif (%h == 5C) return \\
; Chars don't need escaping
else return $chr($base($1, 16, 10))
}
alias -l gk.guid {
if ($1 == GateKeeperPassport) return $str(00, 16)
if (!$var(%GK.GUID)) set %GK.GUID $md5($time $date $gmt $ctime $ticks)
return %GK.GUID
}
; Adds $username for mIRC (Built-in for AdiIRC)
alias -l username {
if (@ isin $emailaddr) return $gettok($emailaddr, 1, 46)
else return $me
}
1 | ; IRC8 connection by JD |
2 | |
3 | on ^1:LOGON:*:{ |
4 | raw -q IRCVERS IRC8 MSN-OCX!9.02.0310.2401 |
5 | raw -q AUTH GateKeeper I : $+ $gk.header(1) |
6 | haltdef |
7 | } |
8 | |
9 | on 1:PARSELINE:in:*:{ |
10 | tokenize 32 $parseline |
11 | if ($1 == AUTH) { |
12 | if ($2 == GateKeeper || $2 == GateKeeperPassport) { |
13 | if ($3 == S) { |
14 | ; Extended (Passport) Authentication. Send %ticket and %passport to server. |
15 | if ($2- == GateKeeperPassport S :OK) { |
16 | raw -qn $1-3 $+($base($len(%ticket), 10, 16, 8), %ticket, $base($len(%profile), 10, 16, 8), %profile) |
17 | } |
18 | ; Attempt to find GateKeeper v3 Challenge (8 bytes, escaped) |
19 | elseif ($regex($gettok($parseline,4-,32), /^:GKSSP\\0(?:[^\\]|\\.){2}\x03\\0\\0\\0\x02\\0\\0\\0((?:[^\\]|\\.){8})$/u) > 0) { |
20 | ; Escaped text can contain characters the client can't handle (eg. 0x00), so convert to &binvar |
21 | bset -a &challenge 1 $regsubex($regml(1) $+ $servertarget, /([^\\]|\\.)/gu, $gk.asc(\1) $+ $chr(32)) |
22 | ; GateKeeper authenticaiton is a HMAC-MD5 with fixed key |
23 | var %result = $hmac(&challenge, SRFMKSJANDRESKKC, md5, 1) |
24 | .parseline -it |
25 | .raw -n $1-3 $+(:,$gk.header(3),$regsubex(%result $+ $gk.guid($2), /([0-9a-f]{2})/g, $gk.hex2chr(\1))) |
26 | } |
27 | else { |
28 | echo $color(info2) -t * GateKeeper Authentication Failed |
29 | } |
30 | } |
31 | elseif ($3 == *) { |
32 | var %oid = $iif($5 != 0, $+($chr(40),OID: $5,$chr(41))) |
33 | echo $color(info) -t * Logged in as $4 %oid |
34 | .parseline -it |
35 | raw -q USER $username * * : $+ $iif($fullname, $ifmatch, ...) |
36 | raw -q NICK $me |
37 | } |
38 | else { |
39 | echo $color(info2) -t * GateKeeper Authentication Failed |
40 | } |
41 | } |
42 | else { |
43 | ; This is not GateKeeper. |
44 | echo $color(info2) -t * ERROR: Unknown Authentication Package $+($chr(40),$2,$chr(41)) |
45 | } |
46 | } |
47 | elseif ($2 == JOIN) { |
48 | .parseline -it $1-2 $4- |
49 | if ($gettok($3, 4, 44) isin +@.) { |
50 | parseline -itq $+($1 MODE $right($4, -1) +, $replace($gettok($3, 4, 44), +, v, @, o, ., q) $right($gettok($1, 1, 33), -1)) |
51 | } |
52 | } |
53 | elseif ($2 == 004) { |
54 | .parseline -itq : $+ $server 005 $me PREFIX=(qov).@+ CHANTYPES=%# |
55 | } |
56 | elseif ($2 == 353) { |
57 | var %original = $right($6-, -1) |
58 | var %new |
59 | var %i = 1 |
60 | while (%i <= $numtok(%original, 32)) { |
61 | var %user = $gettok(%original, %i, 32) |
62 | %new = %new $gettok(%user, $numtok(%user, 44), 44) |
63 | inc %i |
64 | } |
65 | .parseline -it $1-5 : $+ %new |
66 | } |
67 | } |
68 | |
69 | ; Usage: $gk.header(sequence) - Returns GateKeeper v3 header with specified sequence (1 or 3 for client) |
70 | alias -l gk.header return $+(GKSSP\0JD,$chr(3),\0\0\0,$chr($$1),\0\0\0) |
71 | |
72 | ; Usage: $gk.asc(char) - Returns $asc equivalent for a potentially escaped character (eg. \n) |
73 | alias -l gk.asc { |
74 | ; Not escaped |
75 | if ($left($1, 1) != \) return $asc($1) |
76 | ; Invalid escape |
77 | elseif ($mid($1, 2, 1) !isincs 0tnrbc\) return $asc($mid($1, 2, 1)) |
78 | ; Valid escape (\0 doesn't need replacement) |
79 | return $replacecs($mid($1, 2, 1), t, 9, n, 10, r, 13, b, 32, c, 44, \, 92) |
80 | } |
81 | |
82 | ; Usage: $gk.hex2chr(hex) - Returns an escaped $chr equivalent from hex |
83 | alias -l gk.hex2chr { |
84 | ; Normalise - Remove zero padding |
85 | var %h = $base($1, 16, 16) |
86 | |
87 | ; Chars need escapinh |
88 | if (%h == 0) return \0 |
89 | elseif (%h == 9) return \t |
90 | elseif (%h == A) return \n |
91 | elseif (%h == D) return \r |
92 | elseif (%h == 20) return \b |
93 | elseif (%h == 2C) return \c |
94 | elseif (%h == 5C) return \\ |
95 | ; Chars don't need escaping |
96 | else return $chr($base($1, 16, 10)) |
97 | } |
98 | |
99 | alias -l gk.guid { |
100 | if ($1 == GateKeeperPassport) return $str(00, 16) |
101 | if (!$var(%GK.GUID)) set %GK.GUID $md5($time $date $gmt $ctime $ticks) |
102 | return %GK.GUID |
103 | } |
104 | |
105 | ; Adds $username for mIRC (Built-in for AdiIRC) |
106 | alias -l username { |
107 | if (@ isin $emailaddr) return $gettok($emailaddr, 1, 46) |
108 | else return $me |
109 | } |
110 |
README.md
· 638 B · Markdown
Raw
# MSN (IRC8) compatible connection script
## Requirements
* [x] AdiIRC-first - Works with both mIRC and AdiIRC
* [x] Native GateKeeper / GateKeeperPassport Authentication
* [ ] Support WHISPER (and converts WHISPER to & from PRIVMSG)
* [x] Convert IRC8 JOIN to IRC JOIN
* [x] Support MODE on IRC8 JOIN (+v/o/q)
* [x] Convert IRC8 NAMES to IRC NAMES
## Nice to haves
* [ ] Convert styled PRIVMSG to normal PRIVMSG
* [ ] Supports CTCP "ERR NOUSERWHISPER".
* [ ] Convert AWAY to IRCv3 AWAY (if it does something in clients)
* [ ] Don't default to IRC8
## Known Issues
* Auth doesn't always work with AdiIRC (probably due to UTF8 quirks)
MSN (IRC8) compatible connection script
Requirements
- AdiIRC-first - Works with both mIRC and AdiIRC
- Native GateKeeper / GateKeeperPassport Authentication
- Support WHISPER (and converts WHISPER to & from PRIVMSG)
- Convert IRC8 JOIN to IRC JOIN
- Support MODE on IRC8 JOIN (+v/o/q)
- Convert IRC8 NAMES to IRC NAMES
Nice to haves
- Convert styled PRIVMSG to normal PRIVMSG
- Supports CTCP "ERR NOUSERWHISPER".
- Convert AWAY to IRCv3 AWAY (if it does something in clients)
- Don't default to IRC8
Known Issues
- Auth doesn't always work with AdiIRC (probably due to UTF8 quirks)