6
6
# SOCKS5 support (integration) is experimental!!!
9
::Version::setSubversionId {$Id: proxy.tcl 11344 2009-07-12 21:18:51Z kakaroto $}
9
::Version::setSubversionId {$Id: proxy.tcl 11886 2010-01-11 01:43:13Z kakaroto $}
11
11
package provide Proxy 0.1
12
package require -exact http 2.4.4
13
package require SASL::NTLM;
15
package require base64;
14
17
# This should be converted to a proper package, to use with package require
15
18
source socks.tcl ;# SOCKS5 proxy support
170
173
return [socket -async $thost $tport]
176
####################################################
177
# All NTLM stuff adapted from autoproxy
178
####################################################
180
proc NTLMsecureSocket { args } {
185
set s [NTLMauthenticate $thost $tport]
186
return [::tls::import $socket]
190
proc NTLMsocket { args } {
195
return [::autoproxy::NTLMauthenticate $thost $tport]
200
proc NTLMCallback { context command args } {
202
switch -exact -- $command {
203
username { return [::config::getKey proxyuser] }
204
password { return [::config::getKey proxypass] }
206
hostname { return [info host] }
207
default { return -code error unxpected }
211
proc NTLMauthenticate { thost tport } {
214
set phost $options(proxy_host)
215
set pport $options(proxy_port)
217
set s [socket $phost $pport]
218
fconfigure $s -blocking 1 -buffering line -translation crlf
220
set ctx [SASL::new -mechanism NTLM -callback [namespace origin NTLMCallback]]
222
set more_steps [SASL::step $ctx $challenge]
223
set response [SASL::response $ctx]
225
#puts "Sending NTLM message to proxy"
226
#puts "NTLM key: [base64::encode -wrapchar {} $response]"
227
puts $s "CONNECT $thost:$tport HTTP/1.1\nHost: $phost\nProxy-Connection: Keep-Alive\nConnection: Keep-Alive\nCache-Control: no-cache\nPragma: no-cache\nProxy-Authorization: NTLM [base64::encode -wrapchar {} $response]\n"
229
if {!$more_steps} {break}
230
#puts "Handling proxy reply"
233
while {[set line [gets $s]] ne "" } {
234
append response $line\r\n
235
# break if headers done
241
regexp {Content-Length: ([0-9]*)} $response -> length
242
#puts "response length: $length"
244
if {$length eq {} } {
247
set body [read $s [expr $length-1] ]
250
regexp {Proxy-Authenticate: NTLM (.*)\r\n} $response -> challenge
251
#puts "Server challenge: $challenge"
252
set challenge [base64::decode $challenge]
254
#puts "Handshake completed"
261
while {[gets $socket r] > 0} {
265
set result [lindex $reply 0]
266
if {! [regexp {^HTTP/1\.[01] +2[0-9][0-9]} $result]} {
267
return -code error $result
270
fconfigure $s -translation binary -buffering none -blocking 0
173
277
::snit::type Proxy {
175
279
delegate method * to proxy
378
482
if { [::config::getKey proxytype] == "http"} {
379
status_log "registering http secure socket "
380
if { [catch {http::register https 443 HTTPsecureSocket} res]} {
382
MSN::reconnect "Proxy returned error: $res"
483
if { [::config::getKey proxyauthmethod] == "ntlm" } {
484
status_log "registering ntlm socket"
485
::http::config -proxyhost ""
486
if { [catch {http::register http 80 NTLMsocket} res]} {
488
MSN::reconnect "Proxy returned error: $res"
491
status_log "registering ntlm secure socket "
492
if { [catch {http::register https 443 NTLMsecureSocket} res]} {
494
MSN::reconnect "Proxy returned error: $res"
498
status_log "registering http secure socket "
499
if { [catch {http::register https 443 HTTPsecureSocket} res]} {
501
MSN::reconnect "Proxy returned error: $res"
386
506
# http://wiki.tcl.tk/2627 :(