librex 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +1 -1
- data/Rakefile +13 -0
- data/lib/rex.rb +4 -1
- data/lib/rex/assembly/nasm.rb +4 -0
- data/lib/rex/compat.rb +31 -1
- data/lib/rex/encoder/alpha2/generic.rb +11 -10
- data/lib/rex/exceptions.rb +1 -1
- data/lib/rex/exploitation/egghunter.rb +27 -0
- data/lib/rex/file.rb +13 -0
- data/lib/rex/io/stream.rb +9 -1
- data/lib/rex/io/stream_abstraction.rb +18 -7
- data/lib/rex/io/stream_server.rb +2 -2
- data/lib/rex/job_container.rb +1 -1
- data/lib/rex/mime/message.rb +5 -4
- data/lib/rex/ole.rb +83 -6
- data/lib/rex/ole/propset.rb +144 -0
- data/lib/rex/parser/ip360_aspl_xml.rb +102 -0
- data/lib/rex/parser/ip360_xml.rb +93 -0
- data/lib/rex/parser/nessus_xml.rb +118 -0
- data/lib/rex/parser/netsparker_xml.rb +94 -0
- data/lib/rex/parser/retina_xml.rb +109 -0
- data/lib/rex/post/meterpreter/channel.rb +15 -8
- data/lib/rex/post/meterpreter/client.rb +32 -3
- data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +14 -5
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +3 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +5 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +16 -8
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -7
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +15 -4
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +13 -7
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +20 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +63 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +18 -7
- data/lib/rex/post/meterpreter/packet_response_waiter.rb +10 -17
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +16 -6
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +4 -5
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +2 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +4 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +157 -0
- data/lib/rex/proto/dhcp/server.rb +8 -4
- data/lib/rex/proto/http/client.rb +19 -45
- data/lib/rex/proto/http/packet.rb +8 -5
- data/lib/rex/proto/http/response.rb +8 -3
- data/lib/rex/proto/http/server.rb +1 -1
- data/lib/rex/proto/proxy/socks4a.rb +4 -4
- data/lib/rex/proto/rfb.rb +19 -0
- data/lib/rex/proto/rfb.rb.ut.rb +37 -0
- data/lib/rex/proto/rfb/cipher.rb +78 -0
- data/lib/rex/proto/rfb/client.rb +207 -0
- data/lib/rex/proto/rfb/constants.rb +52 -0
- data/lib/rex/proto/tftp/server.rb +20 -17
- data/lib/rex/services/local_relay.rb +1 -1
- data/lib/rex/socket.rb +69 -10
- data/lib/rex/socket/comm/local.rb +7 -4
- data/lib/rex/socket/range_walker.rb +14 -1
- data/lib/rex/text.rb +28 -3
- data/lib/rex/text.rb.ut.rb +14 -0
- data/lib/rex/thread_factory.rb +42 -0
- data/lib/rex/ui/text/input/buffer.rb +1 -1
- data/lib/rex/zip/archive.rb +74 -9
- data/lib/rex/zip/entry.rb +6 -1
- metadata +22 -7
@@ -0,0 +1,19 @@
|
|
1
|
+
##
|
2
|
+
# $Id: $
|
3
|
+
##
|
4
|
+
|
5
|
+
##
|
6
|
+
#
|
7
|
+
# RFB protocol support
|
8
|
+
#
|
9
|
+
# by Joshua J. Drake <jduck>
|
10
|
+
#
|
11
|
+
# Based on:
|
12
|
+
# vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
|
13
|
+
# vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
|
14
|
+
#
|
15
|
+
##
|
16
|
+
|
17
|
+
require 'rex/proto/rfb/constants'
|
18
|
+
require 'rex/proto/rfb/cipher'
|
19
|
+
require 'rex/proto/rfb/client'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
##
|
4
|
+
# $Id: $
|
5
|
+
##
|
6
|
+
|
7
|
+
##
|
8
|
+
#
|
9
|
+
# RFB protocol support
|
10
|
+
#
|
11
|
+
# by Joshua J. Drake <jduck>
|
12
|
+
#
|
13
|
+
# Based on:
|
14
|
+
# vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
|
15
|
+
# vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
|
16
|
+
#
|
17
|
+
##
|
18
|
+
|
19
|
+
require 'rex/socket'
|
20
|
+
require 'rex/proto/rfb'
|
21
|
+
|
22
|
+
sd = Rex::Socket::Tcp.create('PeerHost' => ENV["VNCHOST"], 'PeerPort' => Rex::Proto::RFB::DefaultPort)
|
23
|
+
|
24
|
+
v = Rex::Proto::RFB::Client.new(sd)
|
25
|
+
if not v.connect('password')
|
26
|
+
$stderr.puts v.error
|
27
|
+
exit(1)
|
28
|
+
end
|
29
|
+
|
30
|
+
loop {
|
31
|
+
sret = select([sd],nil,nil,10)
|
32
|
+
puts sret.inspect
|
33
|
+
if sret and sret[0].include? sd
|
34
|
+
buf = sd.sysread(8192)
|
35
|
+
puts "read #{buf.length} bytes: #{buf.inspect}"
|
36
|
+
end
|
37
|
+
}
|
@@ -0,0 +1,78 @@
|
|
1
|
+
##
|
2
|
+
# $Id: $
|
3
|
+
##
|
4
|
+
|
5
|
+
##
|
6
|
+
#
|
7
|
+
# RFB protocol support
|
8
|
+
#
|
9
|
+
# by Joshua J. Drake <jduck>
|
10
|
+
#
|
11
|
+
# Based on:
|
12
|
+
# vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
|
13
|
+
# vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
|
14
|
+
#
|
15
|
+
##
|
16
|
+
|
17
|
+
# Required for VNC authentication
|
18
|
+
require 'openssl'
|
19
|
+
|
20
|
+
module Rex
|
21
|
+
module Proto
|
22
|
+
module RFB
|
23
|
+
|
24
|
+
##
|
25
|
+
# A bit of information about the DES algorithm was found here:
|
26
|
+
# http://www.vidarholen.net/contents/junk/vnc.html
|
27
|
+
#
|
28
|
+
# In addition, VNC uses two individual 8 byte block encryptions rather than
|
29
|
+
# using any block mode (like cbc, ecb, etc).
|
30
|
+
##
|
31
|
+
|
32
|
+
class Cipher
|
33
|
+
|
34
|
+
def self.mangle_password(password)
|
35
|
+
key = ''
|
36
|
+
key = password.dup if password
|
37
|
+
key.slice!(8,key.length) if key.length > 8
|
38
|
+
key << "\x00" * (8 - key.length) if key.length < 8
|
39
|
+
|
40
|
+
# We have to mangle the key so the LSB are kept vs the MSB
|
41
|
+
[key.unpack('B*').first.scan(/.{8}/).map! { |e| e.reverse }.join].pack('B*')
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.encrypt(plain, password)
|
45
|
+
key = self.mangle_password(password)
|
46
|
+
|
47
|
+
# VNC auth does two 8-byte blocks individually instead supporting some block mode
|
48
|
+
cipher = ''
|
49
|
+
2.times { |x|
|
50
|
+
c = OpenSSL::Cipher::Cipher.new('des')
|
51
|
+
c.encrypt
|
52
|
+
c.key = key
|
53
|
+
cipher << c.update(plain[x*8, 8])
|
54
|
+
}
|
55
|
+
|
56
|
+
cipher
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# NOTE: The default password is that of winvnc/etc which is used for
|
61
|
+
# encrypting the password(s) on disk/in registry.
|
62
|
+
#
|
63
|
+
def self.decrypt(cipher, password = "\x17\x52\x6b\x06\x23\x4e\x58\x07")
|
64
|
+
key = self.mangle_password(password)
|
65
|
+
|
66
|
+
# NOTE: This only does one 8 byte block
|
67
|
+
plain = ''
|
68
|
+
c = OpenSSL::Cipher::Cipher.new('des')
|
69
|
+
c.decrypt
|
70
|
+
c.key = key
|
71
|
+
c.update(cipher)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
##
|
2
|
+
# $Id: $
|
3
|
+
##
|
4
|
+
|
5
|
+
##
|
6
|
+
#
|
7
|
+
# RFB protocol support
|
8
|
+
#
|
9
|
+
# by Joshua J. Drake <jduck>
|
10
|
+
#
|
11
|
+
# Based on:
|
12
|
+
# vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
|
13
|
+
# vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
|
14
|
+
#
|
15
|
+
# TODO: determine how to detect a view-only session.
|
16
|
+
##
|
17
|
+
|
18
|
+
module Rex
|
19
|
+
module Proto
|
20
|
+
module RFB
|
21
|
+
|
22
|
+
class Client
|
23
|
+
|
24
|
+
def initialize(sock, opts = {})
|
25
|
+
@sock = sock
|
26
|
+
@opts = opts
|
27
|
+
|
28
|
+
@banner = nil
|
29
|
+
@majver = MajorVersion
|
30
|
+
@minver = -1
|
31
|
+
@auth_types = []
|
32
|
+
end
|
33
|
+
|
34
|
+
def read_error_message
|
35
|
+
len = @sock.get_once(4)
|
36
|
+
return 'Unknown error' if not len or len.length != 4
|
37
|
+
|
38
|
+
len = len.unpack("N").first
|
39
|
+
@sock.get_once(len)
|
40
|
+
end
|
41
|
+
|
42
|
+
def handshake
|
43
|
+
@banner = @sock.get_once(12)
|
44
|
+
if not @banner
|
45
|
+
@error = "Unable to obtain banner from server"
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
|
49
|
+
# RFB Protocol Version 3.3 (1998-01)
|
50
|
+
# RFB Protocol Version 3.7 (2003-08)
|
51
|
+
# RFB Protocol Version 3.8 (2007-06)
|
52
|
+
|
53
|
+
if @banner =~ /RFB ([0-9]{3})\.([0-9]{3})/
|
54
|
+
maj = $1.to_i
|
55
|
+
if maj != MajorVersion
|
56
|
+
@error = "Invalid major version number: #{maj}"
|
57
|
+
return false
|
58
|
+
end
|
59
|
+
else
|
60
|
+
@error = "Invalid RFB banner: #{@banner}"
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
|
64
|
+
@minver = $2.to_i
|
65
|
+
|
66
|
+
our_ver = "RFB %03d.%03d\n" % [MajorVersion, @minver]
|
67
|
+
@sock.put(our_ver)
|
68
|
+
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
def connect(password = nil)
|
73
|
+
return false if not handshake
|
74
|
+
return false if not authenticate(password)
|
75
|
+
return false if not send_client_init
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
def send_client_init
|
80
|
+
if @opts[:exclusive]
|
81
|
+
@sock.put("\x00") # do share.
|
82
|
+
else
|
83
|
+
@sock.put("\x01") # do share.
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def authenticate(password = nil)
|
88
|
+
type = negotiate_authentication
|
89
|
+
return false if not type
|
90
|
+
|
91
|
+
# Authenticate.
|
92
|
+
case type
|
93
|
+
when AuthType::None
|
94
|
+
# Nothing here.
|
95
|
+
|
96
|
+
when AuthType::VNC
|
97
|
+
return false if not negotiate_vnc_auth(password)
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
# Handle reading the security result message
|
102
|
+
result = @sock.get_once(4)
|
103
|
+
if not result
|
104
|
+
@error = "Unable to read auth result"
|
105
|
+
return false
|
106
|
+
end
|
107
|
+
|
108
|
+
result = result.unpack('N').first
|
109
|
+
case result
|
110
|
+
when 0
|
111
|
+
return true
|
112
|
+
|
113
|
+
when 1
|
114
|
+
if @minver >= 8
|
115
|
+
msg = read_error_message
|
116
|
+
@error = "Authentication failed: #{msg}"
|
117
|
+
else
|
118
|
+
@error = "Authentication failed"
|
119
|
+
end
|
120
|
+
when 2
|
121
|
+
@error = "Too many authentication attempts"
|
122
|
+
else
|
123
|
+
@error = "Unknown authentication result: #{result}"
|
124
|
+
end
|
125
|
+
|
126
|
+
false
|
127
|
+
end
|
128
|
+
|
129
|
+
def negotiate_authentication
|
130
|
+
# Authentication type negotiation is protocol version specific.
|
131
|
+
if @minver < 7
|
132
|
+
buf = @sock.get_once(4)
|
133
|
+
if not buf
|
134
|
+
@error = "Unable to obtain requested authentication method"
|
135
|
+
return nil
|
136
|
+
end
|
137
|
+
@auth_types = buf.unpack('N')
|
138
|
+
if not @auth_types or @auth_types.first == 0
|
139
|
+
msg = read_error_message
|
140
|
+
@error = "No authentication types available: #{msg}"
|
141
|
+
return nil
|
142
|
+
end
|
143
|
+
else
|
144
|
+
buf = @sock.get_once(1)
|
145
|
+
if not buf
|
146
|
+
@error = "Unable to obtain supported authentication method count"
|
147
|
+
return nil
|
148
|
+
end
|
149
|
+
|
150
|
+
# first byte is number of security types
|
151
|
+
num_types = buf.unpack("C").first
|
152
|
+
if (num_types == 0)
|
153
|
+
msg = read_error_message
|
154
|
+
@error = "No authentication types available: #{msg}"
|
155
|
+
return nil
|
156
|
+
end
|
157
|
+
|
158
|
+
buf = @sock.get_once(num_types)
|
159
|
+
if not buf or buf.length != num_types
|
160
|
+
@error = "Unable to read authentication types"
|
161
|
+
return nil
|
162
|
+
end
|
163
|
+
|
164
|
+
@auth_types = buf.unpack("C*")
|
165
|
+
end
|
166
|
+
|
167
|
+
if not @auth_types or @auth_types.length < 1
|
168
|
+
@error = "No authentication types found"
|
169
|
+
return nil
|
170
|
+
end
|
171
|
+
|
172
|
+
# Select the one we prefer
|
173
|
+
selected = nil
|
174
|
+
selected ||= AuthType::None if @opts[:allow_none] and @auth_types.include? AuthType::None
|
175
|
+
selected ||= AuthType::VNC if @auth_types.include? AuthType::VNC
|
176
|
+
|
177
|
+
if not selected
|
178
|
+
@error = "No supported authentication method found."
|
179
|
+
return nil
|
180
|
+
end
|
181
|
+
|
182
|
+
# For 3.7 and later, clients must state which security-type to use
|
183
|
+
@sock.put([selected].pack('C')) if @minver >= 7
|
184
|
+
|
185
|
+
selected
|
186
|
+
end
|
187
|
+
|
188
|
+
def negotiate_vnc_auth(password = nil)
|
189
|
+
challenge = @sock.get_once(16)
|
190
|
+
if not challenge or challenge.length != 16
|
191
|
+
@error = "Unable to obtain VNC challenge"
|
192
|
+
return false
|
193
|
+
end
|
194
|
+
|
195
|
+
response = Cipher.encrypt(challenge, password)
|
196
|
+
@sock.put(response)
|
197
|
+
|
198
|
+
true
|
199
|
+
end
|
200
|
+
|
201
|
+
attr_reader :error, :majver, :minver, :auth_types
|
202
|
+
attr_reader :view_only
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
##
|
2
|
+
# $Id: $
|
3
|
+
##
|
4
|
+
|
5
|
+
##
|
6
|
+
#
|
7
|
+
# RFB protocol support
|
8
|
+
#
|
9
|
+
# by Joshua J. Drake <jduck>
|
10
|
+
#
|
11
|
+
# Based on:
|
12
|
+
# vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
|
13
|
+
# vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
|
14
|
+
#
|
15
|
+
##
|
16
|
+
|
17
|
+
module Rex
|
18
|
+
module Proto
|
19
|
+
module RFB
|
20
|
+
|
21
|
+
DefaultPort = 5900
|
22
|
+
|
23
|
+
# Version information
|
24
|
+
MajorVersion = 3
|
25
|
+
# NOTE: We will emulate whatever minor version the server reports.
|
26
|
+
|
27
|
+
# Security types
|
28
|
+
class AuthType
|
29
|
+
Invalid = 0
|
30
|
+
None = 1
|
31
|
+
VNC = 2
|
32
|
+
RA2 = 5
|
33
|
+
RA2ne = 6
|
34
|
+
Tight = 16
|
35
|
+
Ultra = 17
|
36
|
+
TLS = 18
|
37
|
+
VeNCrypt = 19
|
38
|
+
GtkVncSasl = 20
|
39
|
+
MD5Hash = 21
|
40
|
+
ColinDeanXVP = 22
|
41
|
+
|
42
|
+
def self.to_s(num)
|
43
|
+
self.constants.each { |c|
|
44
|
+
return c.to_s if self.const_get(c) == num
|
45
|
+
}
|
46
|
+
'Unknown'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: server.rb
|
1
|
+
# $Id: server.rb 11454 2010-12-30 16:37:58Z hdm $
|
2
2
|
require 'rex/socket'
|
3
3
|
require 'rex/proto/tftp'
|
4
4
|
|
@@ -51,7 +51,7 @@ class Server
|
|
51
51
|
'Context' => context
|
52
52
|
)
|
53
53
|
|
54
|
-
self.thread =
|
54
|
+
self.thread = Rex::ThreadFactory.spawn("TFTPServerMonitor", false) {
|
55
55
|
monitor_socket
|
56
56
|
}
|
57
57
|
end
|
@@ -64,10 +64,10 @@ class Server
|
|
64
64
|
@shutting_down = true
|
65
65
|
|
66
66
|
# Wait a maximum of 30 seconds for all transfers to finish.
|
67
|
-
start = Time.now
|
67
|
+
start = ::Time.now
|
68
68
|
while (self.transfers.length > 0)
|
69
69
|
::IO.select(nil, nil, nil, 0.5)
|
70
|
-
dur = Time.now - start
|
70
|
+
dur = ::Time.now - start
|
71
71
|
break if (dur > 30)
|
72
72
|
end
|
73
73
|
|
@@ -93,7 +93,7 @@ class Server
|
|
93
93
|
# Register an entire directory to serve files from
|
94
94
|
#
|
95
95
|
def set_tftproot(rootdir)
|
96
|
-
@tftproot = rootdir if File.directory?(rootdir)
|
96
|
+
@tftproot = rootdir if ::File.directory?(rootdir)
|
97
97
|
end
|
98
98
|
|
99
99
|
|
@@ -101,7 +101,7 @@ class Server
|
|
101
101
|
# Register a directory to write uploaded files to
|
102
102
|
#
|
103
103
|
def set_output_dir(outdir)
|
104
|
-
@output_dir = outdir if File.directory?(outdir)
|
104
|
+
@output_dir = outdir if ::File.directory?(outdir)
|
105
105
|
end
|
106
106
|
|
107
107
|
|
@@ -153,15 +153,15 @@ class Server
|
|
153
153
|
# entry to the files hash.
|
154
154
|
#
|
155
155
|
def find_file_in_root(fname)
|
156
|
-
fn = File.expand_path(File.join(@tftproot, fname))
|
156
|
+
fn = ::File.expand_path(::File.join(@tftproot, fname))
|
157
157
|
|
158
158
|
# Don't allow directory traversal
|
159
159
|
return nil if fn.index(@tftproot) != 0
|
160
160
|
|
161
|
-
return nil if not File.file?(fn) or not File.readable?(fn)
|
161
|
+
return nil if not ::File.file?(fn) or not ::File.readable?(fn)
|
162
162
|
|
163
163
|
# Read the file contents, and register it as being served once
|
164
|
-
data = data = File.open(fn, "rb") { |fd| fd.read(fd.stat.size) }
|
164
|
+
data = data = ::File.open(fn, "rb") { |fd| fd.read(fd.stat.size) }
|
165
165
|
register_file(fname, data, true)
|
166
166
|
|
167
167
|
# Return the last file in the array
|
@@ -172,7 +172,8 @@ class Server
|
|
172
172
|
attr_accessor :listen_host, :listen_port, :context
|
173
173
|
attr_accessor :sock, :files, :transfers, :uploaded
|
174
174
|
attr_accessor :thread
|
175
|
-
|
175
|
+
|
176
|
+
attr_accessor :incoming_file_hook
|
176
177
|
|
177
178
|
protected
|
178
179
|
|
@@ -185,14 +186,16 @@ protected
|
|
185
186
|
nil
|
186
187
|
end
|
187
188
|
|
188
|
-
|
189
189
|
def save_output(tr)
|
190
190
|
self.uploaded << tr[:file]
|
191
|
+
|
192
|
+
return incoming_file_hook.call(tr) if incoming_file_hook
|
193
|
+
|
191
194
|
if @output_dir
|
192
195
|
fn = tr[:file][:name].split(File::SEPARATOR)[-1]
|
193
196
|
if fn
|
194
|
-
fn = File.join(@output_dir, fn)
|
195
|
-
File.open(fn, "wb") { |fd|
|
197
|
+
fn = ::File.join(@output_dir, fn)
|
198
|
+
::File.open(fn, "wb") { |fd|
|
196
199
|
fd.write(tr[:file][:data])
|
197
200
|
}
|
198
201
|
end
|
@@ -201,7 +204,7 @@ protected
|
|
201
204
|
|
202
205
|
|
203
206
|
def check_retransmission(tr)
|
204
|
-
elapsed = Time.now - tr[:last_sent]
|
207
|
+
elapsed = ::Time.now - tr[:last_sent]
|
205
208
|
if (elapsed >= tr[:timeout])
|
206
209
|
# max retries reached?
|
207
210
|
if (tr[:retries] < 3)
|
@@ -262,7 +265,7 @@ protected
|
|
262
265
|
pkt << chunk
|
263
266
|
|
264
267
|
send_packet(tr[:from], pkt)
|
265
|
-
tr[:last_sent] = Time.now
|
268
|
+
tr[:last_sent] = ::Time.now
|
266
269
|
|
267
270
|
# If the file is a one-serve, mark it as started
|
268
271
|
tr[:file][:started] = true if (tr[:file][:once])
|
@@ -282,7 +285,7 @@ protected
|
|
282
285
|
pkt = [OpAck, tr[:block]].pack('nn')
|
283
286
|
|
284
287
|
send_packet(tr[:from], pkt)
|
285
|
-
tr[:last_sent] = Time.now
|
288
|
+
tr[:last_sent] = ::Time.now
|
286
289
|
|
287
290
|
# If we had a 0-511 byte chunk, we're done.
|
288
291
|
if (tr[:last_size] and tr[:last_size] < tr[:blksize])
|
@@ -355,7 +358,7 @@ protected
|
|
355
358
|
|
356
359
|
#puts "%s %s %s" % [start, fn, mode]
|
357
360
|
|
358
|
-
if
|
361
|
+
if not @shutting_down
|
359
362
|
transfer = {
|
360
363
|
:type => OpWrite,
|
361
364
|
:from => from,
|