8331
by kakaroto
Add SVN $Id$ tag to the new files and add the keywords property on them... |
1 |
::Version::setSubversionId {$Id$} |
2 |
||
3 |
package require des
|
|
8795
by kakaroto
Use the newest and great DES package... to avoid issues with 'invalid keyset handle' when that des package gets loaded into amsn by some plugin or something |
4 |
|
5 |
snit::type SecurityToken { |
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
6 |
option -name -default "" |
7 |
option -address -default "" |
|
8 |
option -policy -default "" |
|
9 |
option -type -default "" |
|
10 |
option -created -default "" |
|
11 |
option -expires -default "" |
|
12 |
option -ticket -default "" |
|
7869
by kakaroto
MSNP15 support!!! (partial + experimental). SSO authentication works, MBI cryptography works, we can authenticate and chat and read/send OIMs, etc... BUT we just don't download the contact list yet.. will be added soon! :) |
13 |
option -proof -default "" |
7867
by kakaroto
Fixes the issues i had before.. now SSO authentication works 100%svn diff yeay! :) |
14 |
option -local_clock -default "" |
8261
by kakaroto
Token expiration is now fixed... if we try to use an SSO token after it expired it will automatically fetch a new one and call your function when the token is renewed.. |
15 |
option -server_clock -default "" |
16 |
||
17 |
method IsExpired { } { |
|
18 |
if {$options(-ticket) == "" || |
|
19 |
$options(-local_clock) == "" || |
|
20 |
$options(-server_clock) == "" || |
|
21 |
$options(-expires) == ""} { |
|
22 |
return 1 |
|
23 |
}
|
|
24 |
set created_clock $options(-local_clock) |
|
25 |
set current_clock [clock seconds] |
|
26 |
set elapsed [expr {$current_clock - $created_clock}] |
|
27 |
||
28 |
set created 0 |
|
29 |
set expires 0 |
|
30 |
if { [regexp {(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})} $options(-server_clock) -> y m d h min s] } { |
|
31 |
set created [clock scan "${y}-${m}-${d} ${h}:${min}:${s}"] |
|
32 |
}
|
|
33 |
if { [regexp {(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})} $options(-expires) -> y m d h min s] } { |
|
34 |
set expires [clock scan "${y}-${m}-${d} ${h}:${min}:${s}"] |
|
35 |
}
|
|
36 |
if {$created == 0 || $expires == 0 } { |
|
37 |
return 1 |
|
38 |
}
|
|
39 |
set remaining [expr {$expires - $created}] |
|
40 |
if {$remaining < $elapsed} { |
|
41 |
return 1 |
|
42 |
} else { |
|
43 |
return 0 |
|
44 |
}
|
|
45 |
}
|
|
46 |
}
|
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
47 |
|
48 |
||
49 |
# Single Sign-On Authentication method (used by MSNP15+)
|
|
50 |
snit::type SSOAuthentication { |
|
51 |
variable security_tokens
|
|
52 |
variable soap_req "" |
|
7885
by kakaroto
SSO auth object should cancel SOAP request if it gets destroyed + Code cleaning, removed debug outputs |
53 |
variable callbacks [list] |
8261
by kakaroto
Token expiration is now fixed... if we try to use an SSO token after it expired it will automatically fetch a new one and call your function when the token is renewed.. |
54 |
option -username -default "" |
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
55 |
option -password -default "" |
56 |
option -nonce -default "" |
|
7869
by kakaroto
MSNP15 support!!! (partial + experimental). SSO authentication works, MBI cryptography works, we can authenticate and chat and read/send OIMs, etc... BUT we just don't download the contact list yet.. will be added soon! :) |
57 |
option -done -default 0 |
9682
by kakaroto
Add support for the profile accrual error as reported here : http://www.amsn-project.net/forums/viewtopic.php?t=7214&highlight= |
58 |
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
59 |
constructor { args } { |
60 |
$self configurelist $args |
|
61 |
||
62 |
set security_tokens [SecurityToken create %AUTO% -name Passport -address "http://Passport.NET/tb"] |
|
7867
by kakaroto
Fixes the issues i had before.. now SSO authentication works 100%svn diff yeay! :) |
63 |
|
64 |
lappend security_tokens [SecurityToken create %AUTO% -name Contacts -address "contacts.msn.com" -policy "MBI"] |
|
8460
by kakaroto
Fix the 'internal server error' users were having when using passwords with special chars and upper case letters |
65 |
lappend security_tokens [SecurityToken create %AUTO% -name Messenger -address "messenger.msn.com" -policy "?id=507"] |
7867
by kakaroto
Fixes the issues i had before.. now SSO authentication works 100%svn diff yeay! :) |
66 |
lappend security_tokens [SecurityToken create %AUTO% -name MessengerClear -address "messengerclear.live.com" -policy "MBI_KEY_OLD"] |
67 |
lappend security_tokens [SecurityToken create %AUTO% -name MessengerSecure -address "messengersecure.live.com" -policy "MBI_SSL"] |
|
68 |
||
69 |
lappend security_tokens [SecurityToken create %AUTO% -name Spaces -address "spaces.live.com" -policy "MBI"] |
|
70 |
lappend security_tokens [SecurityToken create %AUTO% -name Storage -address "storage.msn.com" -policy "MBI"] |
|
8318
by kakaroto
Remove unused Voice SSO token, and add storage token.. it's used for Roaming Content.. also make Roaming content use the new storage token.. it should make it more stable now. |
71 |
|
7867
by kakaroto
Fixes the issues i had before.. now SSO authentication works 100%svn diff yeay! :) |
72 |
}
|
73 |
||
74 |
destructor { |
|
75 |
catch { |
|
7869
by kakaroto
MSNP15 support!!! (partial + experimental). SSO authentication works, MBI cryptography works, we can authenticate and chat and read/send OIMs, etc... BUT we just don't download the contact list yet.. will be added soon! :) |
76 |
foreach token $security_tokens { |
77 |
$token destroy |
|
78 |
}
|
|
79 |
set security_tokens "" |
|
8849
by kakaroto
correctly reset the soap_req to avoid the invalid command name errors |
80 |
}
|
7867
by kakaroto
Fixes the issues i had before.. now SSO authentication works 100%svn diff yeay! :) |
81 |
if { $soap_req != "" } { |
7885
by kakaroto
SSO auth object should cancel SOAP request if it gets destroyed + Code cleaning, removed debug outputs |
82 |
catch { $soap_req destroy } |
83 |
set soap_req "" |
|
8849
by kakaroto
correctly reset the soap_req to avoid the invalid command name errors |
84 |
}
|
7885
by kakaroto
SSO auth object should cancel SOAP request if it gets destroyed + Code cleaning, removed debug outputs |
85 |
|
7867
by kakaroto
Fixes the issues i had before.. now SSO authentication works 100%svn diff yeay! :) |
86 |
}
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
87 |
|
88 |
method RequireSecurityToken { name command {full 0} } { |
|
8280
by kakaroto
We can now request the full token instead of just the ticket from SSO, this is useful for proof+ticket Passport security token. |
89 |
set token [$self GetSecurityTokenByName $name] |
8261
by kakaroto
Token expiration is now fixed... if we try to use an SSO token after it expired it will automatically fetch a new one and call your function when the token is renewed.. |
90 |
if {$token == "" || [$token IsExpired] } { |
91 |
lappend callbacks [list $name $command $full] |
|
8280
by kakaroto
We can now request the full token instead of just the ticket from SSO, this is useful for proof+ticket Passport security token. |
92 |
$self Authenticate [list $self RequireSecurityTokenCB ] |
8261
by kakaroto
Token expiration is now fixed... if we try to use an SSO token after it expired it will automatically fetch a new one and call your function when the token is renewed.. |
93 |
} else { |
94 |
if {$full} { |
|
8280
by kakaroto
We can now request the full token instead of just the ticket from SSO, this is useful for proof+ticket Passport security token. |
95 |
eval $command [list $token] |
96 |
} else { |
|
97 |
eval $command [list [$token cget -ticket]] |
|
98 |
}
|
|
99 |
}
|
|
8261
by kakaroto
Token expiration is now fixed... if we try to use an SSO token after it expired it will automatically fetch a new one and call your function when the token is renewed.. |
100 |
}
|
101 |
||
102 |
method RequireSecurityTokenCB {err} { |
|
103 |
set clbks $callbacks |
|
8263
by kakaroto
Might prevent issue where a callback calls a function that requires a token and the token expired in the meantime... |
104 |
set callbacks [list] |
105 |
||
106 |
foreach callback $clbks { |
|
107 |
foreach {name command full} $callback break |
|
8280
by kakaroto
We can now request the full token instead of just the ticket from SSO, this is useful for proof+ticket Passport security token. |
108 |
set token [$self GetSecurityTokenByName $name] |
8261
by kakaroto
Token expiration is now fixed... if we try to use an SSO token after it expired it will automatically fetch a new one and call your function when the token is renewed.. |
109 |
if {$full} { |
8280
by kakaroto
We can now request the full token instead of just the ticket from SSO, this is useful for proof+ticket Passport security token. |
110 |
eval $command [list $token] |
111 |
} else { |
|
112 |
eval $command [list [$token cget -ticket]] |
|
113 |
}
|
|
114 |
}
|
|
8261
by kakaroto
Token expiration is now fixed... if we try to use an SSO token after it expired it will automatically fetch a new one and call your function when the token is renewed.. |
115 |
}
|
116 |
||
117 |
method GetSecurityTokenByName { name } { |
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
118 |
foreach token $security_tokens { |
119 |
set n [$token cget -name] |
|
120 |
if {$n == $name } { |
|
121 |
return $token |
|
122 |
}
|
|
123 |
}
|
|
124 |
return "" |
|
125 |
}
|
|
126 |
method GetSecurityTokenByAddress { address } { |
|
127 |
foreach token $security_tokens { |
|
128 |
set addr [$token cget -address] |
|
129 |
if {$addr == $address } { |
|
130 |
return $token |
|
131 |
}
|
|
132 |
}
|
|
133 |
return "" |
|
134 |
}
|
|
135 |
||
136 |
method AuthenticateCallback { callbk soap } { |
|
7869
by kakaroto
MSNP15 support!!! (partial + experimental). SSO authentication works, MBI cryptography works, we can authenticate and chat and read/send OIMs, etc... BUT we just don't download the contact list yet.. will be added soon! :) |
137 |
status_log "SSO::AuthenticateCallback : $soap - [$soap GetStatus]" |
8051
by kakaroto
Fix connection errors and authentication erros with MSNP15 |
138 |
if { [$soap GetStatus] == "success" } { |
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
139 |
set xml [$soap GetResponse] |
140 |
set server_clock [GetXmlAttribute $xml "S:Envelope:S:Header:psf:pp:psf:serverInfo" "ServerTime"] |
|
8261
by kakaroto
Token expiration is now fixed... if we try to use an SSO token after it expired it will automatically fetch a new one and call your function when the token is renewed.. |
141 |
set i 0 |
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
142 |
while {1} { |
7867
by kakaroto
Fixes the issues i had before.. now SSO authentication works 100%svn diff yeay! :) |
143 |
set subxml [GetXmlNode $xml "S:Envelope:S:Body:wst:RequestSecurityTokenResponseCollection:wst:RequestSecurityTokenResponse" $i] |
144 |
incr i
|
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
145 |
if { $subxml == "" } { |
146 |
break
|
|
147 |
}
|
|
148 |
||
149 |
set address [GetXmlEntry $subxml "wst:RequestSecurityTokenResponse:wsp:AppliesTo:wsa:EndpointReference:wsa:Address"] |
|
150 |
set token [$self GetSecurityTokenByAddress $address] |
|
151 |
#puts "$subxml\n\n\n"
|
|
7885
by kakaroto
SSO auth object should cancel SOAP request if it gets destroyed + Code cleaning, removed debug outputs |
152 |
if {$token != "" } { |
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
153 |
$token configure -type [GetXmlEntry $subxml "wst:RequestSecurityTokenResponse:wst:TokenType"] |
154 |
$token configure -created [GetXmlEntry $subxml "wst:RequestSecurityTokenResponse:wst:LifeTime:wsu:Created"] |
|
155 |
$token configure -expires [GetXmlEntry $subxml "wst:RequestSecurityTokenResponse:wst:LifeTime:wsu:Expires"] |
|
156 |
$token configure -ticket [GetXmlEntry $subxml "wst:RequestSecurityTokenResponse:wst:RequestedSecurityToken:wsse:BinarySecurityToken"] |
|
7869
by kakaroto
MSNP15 support!!! (partial + experimental). SSO authentication works, MBI cryptography works, we can authenticate and chat and read/send OIMs, etc... BUT we just don't download the contact list yet.. will be added soon! :) |
157 |
if {[$token cget -ticket] == "" } { |
8280
by kakaroto
We can now request the full token instead of just the ticket from SSO, this is useful for proof+ticket Passport security token. |
158 |
catch {$token configure -ticket [list2xml [GetXmlNode $subxml "wst:RequestSecurityTokenResponse:wst:RequestedSecurityToken:EncryptedData"]]} |
8368
by kakaroto
do not crash if there's no security token : http://www.amsn-project.net/forums/viewtopic.php?t=5231&highlight= |
159 |
}
|
8280
by kakaroto
We can now request the full token instead of just the ticket from SSO, this is useful for proof+ticket Passport security token. |
160 |
$token configure -proof [GetXmlEntry $subxml "wst:RequestSecurityTokenResponse:wst:RequestedProofToken:wst:BinarySecret"] |
7867
by kakaroto
Fixes the issues i had before.. now SSO authentication works 100%svn diff yeay! :) |
161 |
$token configure -local_clock [clock seconds] |
8261
by kakaroto
Token expiration is now fixed... if we try to use an SSO token after it expired it will automatically fetch a new one and call your function when the token is renewed.. |
162 |
$token configure -server_clock $server_clock |
163 |
||
8051
by kakaroto
Fix connection errors and authentication erros with MSNP15 |
164 |
status_log "Found security token $token for address $address" green |
165 |
set faultcode [GetXmlEntry $subxml "wst:RequestSecurityTokenResponse:S:Fault:faultcode"] |
|
9682
by kakaroto
Add support for the profile accrual error as reported here : http://www.amsn-project.net/forums/viewtopic.php?t=7214&highlight= |
166 |
set faultstring [GetXmlEntry $subxml "wst:RequestSecurityTokenResponse:S:Fault:faultstring"] |
167 |
if {$faultcode == "wsse:FailedAuthentication"} { |
|
168 |
if {[string trim $faultstring] == "Profile accrual is required"} { |
|
169 |
set error 4 |
|
170 |
} else { |
|
171 |
set error 5 |
|
172 |
}
|
|
173 |
status_log "Security token for $address had a fault ($faultcode): $faultstring" red |
|
174 |
if {[catch {eval $callbk [list $error]} result]} { |
|
175 |
bgerror $result |
|
176 |
}
|
|
177 |
return
|
|
178 |
}
|
|
179 |
}
|
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
180 |
}
|
181 |
if {[catch {eval $callbk [list 0]} result]} { |
|
182 |
bgerror $result |
|
183 |
}
|
|
184 |
} elseif {[$soap GetStatus] == "fault" } { |
|
8235
by kakaroto
change soap API.. GetStatus will be 'fault' in case of a soap fault, and GetLastError becomes the faultcode |
185 |
set faultcode [$soap GetFaultCode] |
8237
by kakaroto
Add Fault handling in soap |
186 |
set faultstring [$soap GetFaultString] |
187 |
||
8235
by kakaroto
change soap API.. GetStatus will be 'fault' in case of a soap fault, and GetLastError becomes the faultcode |
188 |
status_log "Error authenticating : $faultcode - $faultstring" green |
189 |
if {$faultcode == "wsse:FailedAuthentication" } { |
|
190 |
set error 2 |
|
191 |
} elseif {$faultcode == "psf:Redirect"} { |
|
8250
by kakaroto
Fix SSO Authentication psf:Redirect faultcode. now we redirect and resend the soap request. Fixes authentication issues for @msn.com users.. thx Takeshi |
192 |
set xml [$soap GetResponse] |
193 |
set url [GetXmlEntry $xml "S:Envelope:S:Fault:psf:redirectUrl"] |
|
194 |
status_log "SSO Authentication redirected to $url" |
|
195 |
$soap configure -url $url |
|
196 |
if {[catch {$soap SendSOAPRequest} ] } { |
|
8879
by kakaroto
Add a TTL for the soap messages so you can't send the same soap request more than -ttl (default 5) times.. this avoids looping forever with the redirections... |
197 |
set error 3 |
198 |
} else { |
|
199 |
return
|
|
200 |
}
|
|
201 |
} else { |
|
8235
by kakaroto
change soap API.. GetStatus will be 'fault' in case of a soap fault, and GetLastError becomes the faultcode |
202 |
set error 1 |
203 |
}
|
|
204 |
if {[catch {eval $callbk [list $error]} result]} { |
|
205 |
bgerror $result |
|
206 |
}
|
|
207 |
} else { |
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
208 |
$soap destroy |
209 |
set soap_req "" |
|
8849
by kakaroto
correctly reset the soap_req to avoid the invalid command name errors |
210 |
if {[catch {eval $callbk [list 1]} result]} { |
7869
by kakaroto
MSNP15 support!!! (partial + experimental). SSO authentication works, MBI cryptography works, we can authenticate and chat and read/send OIMs, etc... BUT we just don't download the contact list yet.. will be added soon! :) |
211 |
bgerror $result |
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
212 |
}
|
213 |
}
|
|
214 |
}
|
|
215 |
||
216 |
method Authenticate { callbk } { |
|
7869
by kakaroto
MSNP15 support!!! (partial + experimental). SSO authentication works, MBI cryptography works, we can authenticate and chat and read/send OIMs, etc... BUT we just don't download the contact list yet.. will be added soon! :) |
217 |
if {$soap_req != "" } { |
7885
by kakaroto
SSO auth object should cancel SOAP request if it gets destroyed + Code cleaning, removed debug outputs |
218 |
$soap_req destroy |
219 |
set soap_req "" |
|
220 |
}
|
|
221 |
set soap_req [SOAPRequest create %AUTO% \ |
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
222 |
-url "https://login.live.com/RST.srf" \ |
223 |
-xml [$self getSSOXml] \ |
|
224 |
-callback [list $self AuthenticateCallback $callbk]] |
|
7869
by kakaroto
MSNP15 support!!! (partial + experimental). SSO authentication works, MBI cryptography works, we can authenticate and chat and read/send OIMs, etc... BUT we just don't download the contact list yet.. will be added soon! :) |
225 |
$soap_req SendSOAPRequest |
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
226 |
}
|
227 |
||
228 |
method getSSOXml { args } { |
|
229 |
||
230 |
set xml {<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wssc="http://schemas.xmlsoap.org/ws/2004/04/sc" xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust">} |
|
231 |
||
232 |
append xml {<Header>} |
|
233 |
append xml {<ps:AuthInfo xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="PPAuthInfo">} |
|
234 |
append xml {<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>} |
|
235 |
append xml {<ps:BinaryVersion>4</ps:BinaryVersion>} |
|
236 |
append xml {<ps:UIVersion>1</ps:UIVersion>} |
|
237 |
append xml {<ps:Cookies></ps:Cookies>} |
|
238 |
append xml {<ps:RequestParams>AQAAAAIAAABsYwQAAAA0MTA1</ps:RequestParams>} |
|
8460
by kakaroto
Fix the 'internal server error' users were having when using passwords with special chars and upper case letters |
239 |
append xml {</ps:AuthInfo>} |
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
240 |
|
241 |
append xml {<wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext">} |
|
242 |
append xml {<wsse:UsernameToken Id="user">} |
|
7867
by kakaroto
Fixes the issues i had before.. now SSO authentication works 100%svn diff yeay! :) |
243 |
append xml "<wsse:Username>[xmlencode $options(-username)]</wsse:Username>" |
7926
by kakaroto
XML encode everything.. you never know where an '&' could get in the middle of our xml... |
244 |
append xml "<wsse:Password>[xmlencode $options(-password)]</wsse:Password>" |
245 |
append xml {</wsse:UsernameToken>} |
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
246 |
append xml {</wsse:Security>} |
247 |
append xml {</Header>} |
|
248 |
||
249 |
append xml {<Body>} |
|
250 |
append xml {<ps:RequestMultipleSecurityTokens xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="RSTS">} |
|
251 |
||
252 |
set id 0 |
|
253 |
foreach token $security_tokens { |
|
254 |
set address [$token cget -address] |
|
255 |
set policy [$token cget -policy] |
|
256 |
||
257 |
append xml "<wst:RequestSecurityToken Id=\"RST${id}\">" |
|
258 |
append xml {<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>} |
|
259 |
append xml {<wsp:AppliesTo>} |
|
260 |
append xml {<wsa:EndpointReference xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">} |
|
261 |
append xml "<wsa:Address>${address}</wsa:Address>" |
|
262 |
append xml {</wsa:EndpointReference>} |
|
263 |
append xml {</wsp:AppliesTo>} |
|
264 |
||
265 |
# The http://Passport.NET/tb token doesn't have a policy reference
|
|
266 |
if {$policy != ""} { |
|
267 |
append xml "<wsse:PolicyReference xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"[xmlencode ${policy}]\">" |
|
7869
by kakaroto
MSNP15 support!!! (partial + experimental). SSO authentication works, MBI cryptography works, we can authenticate and chat and read/send OIMs, etc... BUT we just don't download the contact list yet.. will be added soon! :) |
268 |
append xml {</wsse:PolicyReference>} |
7867
by kakaroto
Fixes the issues i had before.. now SSO authentication works 100%svn diff yeay! :) |
269 |
}
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
270 |
append xml {</wst:RequestSecurityToken>} |
271 |
||
272 |
incr id
|
|
273 |
}
|
|
274 |
||
275 |
append xml {</ps:RequestMultipleSecurityTokens>} |
|
276 |
append xml {</Body>} |
|
277 |
append xml {</Envelope>} |
|
278 |
||
279 |
return $xml |
|
280 |
}
|
|
281 |
}
|
|
282 |
||
283 |
||
284 |
snit::type MBIAuthentication { |
|
7869
by kakaroto
MSNP15 support!!! (partial + experimental). SSO authentication works, MBI cryptography works, we can authenticate and chat and read/send OIMs, etc... BUT we just don't download the contact list yet.. will be added soon! :) |
285 |
|
286 |
typemethod MBICrypt {nonce proof } { |
|
287 |
set key1 [base64::decode $proof] |
|
288 |
set key2 [MBIAuthentication deriveKey $key1 "WS-SecureConversationSESSION KEY HASH"] |
|
289 |
set key3 [MBIAuthentication deriveKey $key1 "WS-SecureConversationSESSION KEY ENCRYPTION"] |
|
290 |
||
291 |
set hash [binary format H* [::sha1::hmac $key2 $nonce]] |
|
292 |
||
293 |
set iv [MBIAuthentication rand 8] |
|
294 |
set des_message $nonce |
|
295 |
append des_message [string repeat "\x08" [expr {72 - [string length $nonce]}]] |
|
296 |
set cipher [::DES::des -mode cbc -dir encrypt -key $key3 -iv $iv -- $des_message] |
|
9546
by kakaroto
Add '--' arg to ::DES::des to avoid it crashing when the encrypted password starts with a dash |
297 |
|
7869
by kakaroto
MSNP15 support!!! (partial + experimental). SSO authentication works, MBI cryptography works, we can authenticate and chat and read/send OIMs, etc... BUT we just don't download the contact list yet.. will be added soon! :) |
298 |
|
299 |
set header [binary format iiH8H8iii 28 1 03660000 04800000 [string length $iv] [string length $hash] [string length $cipher]] |
|
300 |
set data "${iv}${hash}${cipher}" |
|
301 |
||
302 |
return [string map {"\n" ""} [base64::encode "${header}${data}"]] |
|
303 |
}
|
|
304 |
||
305 |
typemethod deriveKey { key magic } { |
|
306 |
set hash1 [binary format H* [::sha1::hmac $key $magic]] |
|
307 |
set hash2 [binary format H* [::sha1::hmac $key "${hash1}${magic}"]] |
|
308 |
||
309 |
set hash3 [binary format H* [::sha1::hmac $key $hash1]] |
|
310 |
set hash4 [binary format H* [::sha1::hmac $key "${hash3}${magic}"]] |
|
311 |
return "${hash2}[string range $hash4 0 3]" |
|
312 |
}
|
|
313 |
||
314 |
typemethod rand { bytes } { |
|
315 |
set result "" |
|
316 |
for {set i 0 } { $i < $bytes } { incr i } { |
|
317 |
append result [binary format c [expr {int(rand() * 256)}]] |
|
318 |
}
|
|
319 |
return $result |
|
320 |
}
|
|
321 |
}
|
|
322 |
||
323 |
snit::type LockKeyAuthentication { |
|
7866
by kakaroto
Initial implementation of the SSO authentication algorithm. Not working for now, but I have to go, will fix once I get home |
324 |
|
325 |
||
326 |
method CreateLockKey {chldata prodid prodkey} { |
|
327 |
||
328 |
# Create an MD5 hash out of the given data, then form 32 bit integers from it
|
|
329 |
set md5hash [::md5::md5 $chldata$prodkey] |
|
330 |
set md5parts [$self MD5HashToInt $md5hash] |
|
331 |
||
332 |
||
333 |
# Then create a valid productid string, divisable by 8, then form 32 bit integers from it
|
|
334 |
set nrPadZeros [expr {8 - [string length $chldata$prodid] % 8}] |
|
335 |
set padZeros [string repeat 0 $nrPadZeros] |
|
336 |
set chlprodid [$self CHLProdToInt $chldata$prodid$padZeros] |
|
337 |
||
338 |
# Create the key we need to XOR
|
|
339 |
set key [$self KeyFromInt $md5parts $chlprodid] |
|
340 |
||
341 |
set low 0x[string range $md5hash 0 15] |
|
342 |
set high 0x[string range $md5hash 16 32] |
|
343 |
set low [expr {$low ^ $key}] |
|
344 |
set high [expr {$high ^ $key}] |
|
345 |
||
346 |
set p1 [format %8.8x [expr {($low / 0x100000000) % 0x100000000}]] |
|
347 |
set p2 [format %8.8x [expr {$low % 0x100000000}]] |
|
348 |
set p3 [format %8.8x [expr {($high / 0x100000000) % 0x100000000}]] |
|
349 |
set p4 [format %8.8x [expr {$high % 0x100000000}]] |
|
350 |
||
351 |
return $p1$p2$p3$p4 |
|
352 |
}
|
|
353 |
||
354 |
method KeyFromInt { md5parts chlprod } { |
|
355 |
# Create a new series of numbers
|
|
356 |
set key_temp 0 |
|
357 |
set key_high 0 |
|
358 |
set key_low 0 |
|
359 |
||
360 |
# Then loop on the entries in the second array we got in the parameters
|
|
361 |
for {set i 0} {$i < [llength $chlprod]} {incr i 2} { |
|
362 |
||
363 |
# Make $key_temp zero again and perform calculation as described in the documents
|
|
364 |
set key_temp [lindex $chlprod $i] |
|
365 |
set key_temp [expr {(wide(0x0E79A9C1) * wide($key_temp)) % wide(0x7FFFFFFF)}] |
|
366 |
set key_temp [expr {wide($key_temp) + wide($key_high)}] |
|
367 |
set key_temp [expr {(wide([lindex $md5parts 0]) * wide($key_temp)) + wide([lindex $md5parts 1])}] |
|
368 |
set key_temp [expr {wide($key_temp) % wide(0x7FFFFFFF)}] |
|
369 |
||
370 |
set key_high [lindex $chlprod [expr {$i+1}]] |
|
371 |
set key_high [expr {(wide($key_high) + wide($key_temp)) % wide(0x7FFFFFFF)}] |
|
372 |
set key_high [expr {(wide([lindex $md5parts 2]) * wide($key_high)) + wide([lindex $md5parts 3])}] |
|
373 |
set key_high [expr {wide($key_high) % wide(0x7FFFFFFF)}] |
|
374 |
||
375 |
set key_low [expr {wide($key_low) + wide($key_temp) + wide($key_high)}] |
|
376 |
}
|
|
377 |
||
378 |
set key_high [expr {(wide($key_high) + wide([lindex $md5parts 1])) % wide(0x7FFFFFFF)}] |
|
379 |
set key_low [expr {(wide($key_low) + wide([lindex $md5parts 3])) % wide(0x7FFFFFFF)}] |
|
380 |
||
381 |
set key_high 0x[$self byteInvert [format %8.8X $key_high]] |
|
382 |
set key_low 0x[$self byteInvert [format %8.8X $key_low]] |
|
383 |
||
384 |
set long_key [expr {(wide($key_high) << 32) + wide($key_low)}] |
|
385 |
||
386 |
return $long_key |
|
387 |
}
|
|
388 |
||
389 |
# Takes an CHLData + ProdID + Padded string and chops it in 4 bytes. Then converts to 32 bit integers
|
|
390 |
method CHLProdToInt { CHLProd } { |
|
391 |
set hexs {} |
|
392 |
set result {} |
|
393 |
while {[string length $CHLProd] > 0} { |
|
394 |
lappend hexs [string range $CHLProd 0 3] |
|
395 |
set CHLProd [string range $CHLProd 4 end] |
|
396 |
}
|
|
397 |
for {set i 0} {$i < [llength $hexs]} {incr i} { |
|
398 |
binary scan [lindex $hexs $i] H8 int |
|
399 |
lappend result 0x[$self byteInvert $int] |
|
400 |
}
|
|
401 |
return $result |
|
402 |
}
|
|
403 |
||
404 |
||
405 |
# Takes an MD5 string and chops it in 4. Then "decodes" the HEX and converts to 32 bit integers. After that it ANDs
|
|
406 |
method MD5HashToInt { md5hash } { |
|
407 |
binary scan $md5hash a8a8a8a8 hash1 hash2 hash3 hash4 |
|
408 |
set hash1 [expr {"0x[$self byteInvert $hash1]" & 0x7FFFFFFF}] |
|
409 |
set hash2 [expr {"0x[$self byteInvert $hash2]" & 0x7FFFFFFF}] |
|
410 |
set hash3 [expr {"0x[$self byteInvert $hash3]" & 0x7FFFFFFF}] |
|
411 |
set hash4 [expr {"0x[$self byteInvert $hash4]" & 0x7FFFFFFF}] |
|
412 |
||
413 |
return [list $hash1 $hash2 $hash3 $hash4] |
|
414 |
}
|
|
415 |
||
416 |
method byteInvert { hex } { |
|
417 |
set hexs {} |
|
418 |
while {[string length $hex] > 0} { |
|
419 |
lappend hexs [string range $hex 0 1] |
|
420 |
set hex [string range $hex 2 end] |
|
421 |
}
|
|
422 |
set hex "" |
|
423 |
for {set i [expr [llength $hexs] -1]} {$i >= 0} {incr i -1} { |
|
424 |
append hex [lindex $hexs $i] |
|
425 |
}
|
|
426 |
return $hex |
|
427 |
}
|
|
428 |
||
429 |
}
|
|
430 |
||
431 |