coderrr-rtunnel 0.3.9 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/CHANGELOG +13 -0
  2. data/LICENSE +21 -0
  3. data/Manifest +48 -0
  4. data/README.markdown +40 -15
  5. data/Rakefile +31 -4
  6. data/bin/rtunnel_client +2 -1
  7. data/bin/rtunnel_server +2 -1
  8. data/lib/rtunnel.rb +20 -0
  9. data/lib/rtunnel/client.rb +308 -0
  10. data/lib/rtunnel/command_processor.rb +62 -0
  11. data/lib/rtunnel/command_protocol.rb +50 -0
  12. data/lib/rtunnel/commands.rb +233 -0
  13. data/lib/rtunnel/connection_id.rb +24 -0
  14. data/lib/rtunnel/core.rb +58 -0
  15. data/lib/rtunnel/crypto.rb +106 -0
  16. data/lib/rtunnel/frame_protocol.rb +34 -0
  17. data/lib/rtunnel/io_extensions.rb +54 -0
  18. data/lib/rtunnel/leak.rb +35 -0
  19. data/lib/rtunnel/rtunnel_client_cmd.rb +41 -0
  20. data/lib/rtunnel/rtunnel_server_cmd.rb +32 -0
  21. data/lib/rtunnel/server.rb +351 -0
  22. data/lib/rtunnel/socket_factory.rb +119 -0
  23. data/test/command_stubs.rb +77 -0
  24. data/test/protocol_mocks.rb +43 -0
  25. data/test/scenario_connection.rb +109 -0
  26. data/test/test_client.rb +48 -0
  27. data/test/test_command_protocol.rb +82 -0
  28. data/test/test_commands.rb +49 -0
  29. data/test/test_connection_id.rb +30 -0
  30. data/test/test_crypto.rb +127 -0
  31. data/test/test_frame_protocol.rb +109 -0
  32. data/test/test_io_extensions.rb +70 -0
  33. data/test/test_server.rb +70 -0
  34. data/test/test_socket_factory.rb +42 -0
  35. data/test/test_tunnel.rb +186 -0
  36. data/test_data/authorized_keys2 +4 -0
  37. data/test_data/known_hosts +4 -0
  38. data/test_data/random_rsa_key +27 -0
  39. data/test_data/ssh_host_dsa_key +12 -0
  40. data/test_data/ssh_host_rsa_key +27 -0
  41. data/tests/_ab_test.rb +16 -0
  42. data/tests/_stress_test.rb +96 -0
  43. data/tests/lo_http_server.rb +55 -0
  44. metadata +67 -27
  45. data/ab_test.rb +0 -23
  46. data/lib/client.rb +0 -150
  47. data/lib/cmds.rb +0 -166
  48. data/lib/core.rb +0 -58
  49. data/lib/rtunnel_client_cmd.rb +0 -23
  50. data/lib/rtunnel_server_cmd.rb +0 -18
  51. data/lib/server.rb +0 -197
  52. data/rtunnel.gemspec +0 -18
  53. data/rtunnel_client.rb +0 -3
  54. data/rtunnel_server.rb +0 -3
  55. data/stress_test.rb +0 -68
metadata CHANGED
@@ -1,50 +1,94 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coderrr-rtunnel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.9
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - coderrr
8
+ - costan
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
12
 
12
- date: 2008-10-25 00:00:00 -07:00
13
+ date: 2009-01-11 00:00:00 -08:00
13
14
  default_executable:
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
- name: uuidtools
17
+ name: eventmachine
17
18
  version_requirement:
18
19
  version_requirements: !ruby/object:Gem::Requirement
19
20
  requirements:
20
21
  - - ">="
21
22
  - !ruby/object:Gem::Version
22
- version: 1.0.2
23
+ version: 0.12.2
23
24
  version:
24
- description: reverse tunnel server and client
25
+ - !ruby/object:Gem::Dependency
26
+ name: net-ssh
27
+ version_requirement:
28
+ version_requirements: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.4
33
+ version:
34
+ description: ""
25
35
  email: coderrr.contact@gmail.com
26
- executables: []
27
-
36
+ executables:
37
+ - rtunnel_client
38
+ - rtunnel_server
28
39
  extensions: []
29
40
 
30
41
  extra_rdoc_files: []
31
42
 
32
43
  files:
33
- - lib/rtunnel_server_cmd.rb
34
- - lib/client.rb
35
- - lib/core.rb
36
- - lib/rtunnel_client_cmd.rb
37
- - lib/server.rb
38
- - lib/cmds.rb
39
- - bin/rtunnel_server
40
- - bin/rtunnel_client
41
- - ab_test.rb
44
+ - CHANGELOG
45
+ - LICENSE
46
+ - Manifest
42
47
  - README.markdown
43
- - rtunnel.gemspec
44
- - stress_test.rb
45
48
  - Rakefile
46
- - rtunnel_client.rb
47
- - rtunnel_server.rb
49
+ - bin/rtunnel_client
50
+ - bin/rtunnel_server
51
+ - lib/rtunnel.rb
52
+ - lib/rtunnel/client.rb
53
+ - lib/rtunnel/command_protocol.rb
54
+ - lib/rtunnel/commands.rb
55
+ - lib/rtunnel/core.rb
56
+ - lib/rtunnel/crypto.rb
57
+ - lib/rtunnel/frame_protocol.rb
58
+ - lib/rtunnel/io_extensions.rb
59
+ - lib/rtunnel/leak.rb
60
+ - lib/rtunnel/rtunnel_client_cmd.rb
61
+ - lib/rtunnel/rtunnel_server_cmd.rb
62
+ - lib/rtunnel/server.rb
63
+ - lib/rtunnel/socket_factory.rb
64
+ - lib/rtunnel/connection_id.rb
65
+ - lib/rtunnel/command_processor.rb
66
+ - spec/client_spec.rb
67
+ - spec/cmds_spec.rb
68
+ - spec/integration_spec.rb
69
+ - spec/server_spec.rb
70
+ - spec/spec_helper.rb
71
+ - test/command_stubs.rb
72
+ - test/protocol_mocks.rb
73
+ - test/scenario_connection.rb
74
+ - test/test_client.rb
75
+ - test/test_command_protocol.rb
76
+ - test/test_commands.rb
77
+ - test/test_crypto.rb
78
+ - test/test_frame_protocol.rb
79
+ - test/test_io_extensions.rb
80
+ - test/test_server.rb
81
+ - test/test_socket_factory.rb
82
+ - test/test_tunnel.rb
83
+ - test/test_connection_id.rb
84
+ - test_data/known_hosts
85
+ - test_data/ssh_host_rsa_key
86
+ - test_data/random_rsa_key
87
+ - test_data/ssh_host_dsa_key
88
+ - test_data/authorized_keys2
89
+ - tests/_ab_test.rb
90
+ - tests/_stress_test.rb
91
+ - tests/lo_http_server.rb
48
92
  has_rdoc: false
49
93
  homepage: http://github.com/coderrr/rtunnel
50
94
  post_install_message:
@@ -70,10 +114,6 @@ rubyforge_project:
70
114
  rubygems_version: 1.2.0
71
115
  signing_key:
72
116
  specification_version: 2
73
- summary: reverse tunnel server and client
74
- test_files:
75
- - spec/integration_spec.rb
76
- - spec/spec_helper.rb
77
- - spec/client_spec.rb
78
- - spec/cmds_spec.rb
79
- - spec/server_spec.rb
117
+ summary: Reverse tunnel server and client.
118
+ test_files: []
119
+
data/ab_test.rb DELETED
@@ -1,23 +0,0 @@
1
- #require 'facets'
2
- require 'net/http'
3
- require 'logger'
4
- require 'stringio'
5
- require 'webrick'
6
-
7
- require 'lib/core'
8
-
9
- puts "make sure a fast responding webserver is started on port 4000"
10
-
11
- base_dir = File.dirname(__FILE__)
12
-
13
- fork{ exec "ruby #{base_dir}/rtunnel_server.rb > /dev/null 2>&1" }
14
- fork{ exec "ruby #{base_dir}/rtunnel_client.rb -c localhost -f 5000 -t 4000 > /dev/null" }
15
-
16
- sleep 2
17
-
18
- (puts "you need ab (apache bench) to run this stress test" ; exit) if %x{which ab}.empty?
19
-
20
- Process.wait fork { exec("ab -c 500 -n 10000 http://localhost:5000/") }
21
-
22
- puts "done, hit ^C"
23
- sleep 999999
data/lib/client.rb DELETED
@@ -1,150 +0,0 @@
1
- require 'core'
2
- require 'cmds'
3
- require 'leak'
4
-
5
- require 'gserver'
6
- require 'timeout'
7
-
8
- module RTunnel
9
- class Client
10
- CONNECTIONS = {}
11
-
12
- def initialize(options = {})
13
- @control_address = options[:control_address]
14
- @control_address << ":#{DEFAULT_CONTROL_PORT}" if @control_address !~ /:\d+$/
15
- @control_host = @control_address.split(/:/).first
16
-
17
- @remote_listen_address = options[:remote_listen_address]
18
- @remote_listen_address.insert 0, "0.0.0.0:" if @remote_listen_address =~ /^\d+$/
19
-
20
- @tunnel_to_address = options[:tunnel_to_address]
21
- @tunnel_to_address.insert 0, "localhost:" if @tunnel_to_address =~ /^\d+$/
22
-
23
- [@control_address, @remote_listen_address, @tunnel_to_address].each do |addr|
24
- addr.replace_with_ip!
25
- end
26
-
27
- @ping_timeout = options[:ping_timeout] || PING_TIMEOUT
28
- end
29
-
30
- def start
31
- @threads = []
32
-
33
- @last_ping = Time.now
34
-
35
- @threads << Thread.safe do
36
- loop do
37
- if @check_ping and (Time.now - @last_ping) > @ping_timeout
38
- D "control connection timeout"
39
- @control_sock.close rescue nil
40
- end
41
-
42
- sleep 1
43
- end
44
- end
45
-
46
- # Memory leak testing
47
- LeakTracker.start
48
-
49
- @main_thread = Thread.safe do
50
- loop do
51
- stop_ping_check
52
- D "connecting to control address (#{@control_address})"
53
- @control_sock = begin
54
- timeout(5) { TCPSocket.new(*@control_address.split(/:/)) }
55
- rescue Exception
56
- D "fail"
57
- sleep 1
58
- next
59
- end
60
-
61
- start_ping_check
62
-
63
- write_to_control_sock RemoteListenCommand.new(@remote_listen_address)
64
-
65
- cmd_queue = ""
66
- while data = (@control_sock.readpartial(16384) rescue (D "control sock read error: #{$!.inspect}"; nil))
67
- cmd_queue << data
68
- while Command.match(cmd_queue)
69
- case command = Command.parse(cmd_queue)
70
- when PingCommand
71
- @last_ping = Time.now
72
- when CreateConnectionCommand
73
- begin
74
- # TODO: this currently blocks, but if we put it in thread, a SendDataCommand may try to get run for this connection before the connection exists
75
- CONNECTIONS[command.conn_id] = TCPSocket.new(*@tunnel_to_address.split(/:/))
76
-
77
- Thread.safe do
78
- cmd = command
79
- conn = CONNECTIONS[cmd.conn_id]
80
-
81
- begin
82
- while localdata = conn.readpartial(16834)
83
- write_to_control_sock SendDataCommand.new(cmd.conn_id, localdata)
84
- end
85
- rescue Exception
86
- begin
87
- D "to tunnel closed, closing from tunnel"
88
- conn.close
89
- CONNECTIONS.delete cmd.conn_id
90
- write_to_control_sock CloseConnectionCommand.new(cmd.conn_id)
91
- rescue
92
- p $!
93
- puts $!.backtrace.join("\n")
94
- end
95
- end
96
- end
97
- rescue Exception
98
- D "error connecting to local port"
99
- write_to_control_sock CloseConnectionCommand.new(command.conn_id)
100
- end
101
- when CloseConnectionCommand
102
- D "closing connection #{command.conn_id}"
103
- if connection = CONNECTIONS[command.conn_id]
104
- # TODO: how the hell do u catch a .close error?
105
- connection.close_read
106
- #connection.close unless connection.closed?
107
- CONNECTIONS.delete(command.conn_id)
108
- end
109
- when SendDataCommand
110
- if connection = CONNECTIONS[command.conn_id]
111
- connection.write(command.data)
112
- else
113
- puts "WARNING: received data for non existant connection!"
114
- end
115
- end
116
- end
117
- end
118
- end
119
- end
120
-
121
- @threads << @main_thread
122
- end
123
-
124
- def join
125
- @main_thread.join
126
- end
127
-
128
- def stop
129
- @threads.each { |t| t.kill! rescue nil}
130
- @control_sock.close rescue nil
131
- end
132
-
133
- private
134
-
135
- def write_to_control_sock(data)
136
- (@control_sock_mutex ||= Mutex.new).synchronize do
137
- @control_sock.write data
138
- end
139
- end
140
-
141
- def start_ping_check
142
- @last_ping = Time.now
143
- @check_ping = true
144
- end
145
-
146
- def stop_ping_check
147
- @check_ping = false
148
- end
149
- end
150
- end
data/lib/cmds.rb DELETED
@@ -1,166 +0,0 @@
1
- module RTunnel
2
- class Command
3
-
4
- def to_s
5
- CLASSES_TO_CODES[self.class].dup
6
- end
7
-
8
- class << self
9
- def parse(data)
10
- klass = class_from_code(data[0..0])
11
-
12
- new_data = data[1..-1]
13
- cmd = klass.parse(new_data)
14
-
15
- data.replace(new_data)
16
-
17
- cmd
18
- end
19
-
20
- def match(data)
21
- return false if ! (klass = class_from_code(data[0..0]))
22
-
23
- klass.match(data[1..-1])
24
- end
25
-
26
- private
27
-
28
- def class_from_code(code)
29
- CODES_TO_CLASSES[code]
30
- end
31
- end
32
- end
33
-
34
- class ConnectionCommand < Command
35
- attr_reader :conn_id
36
-
37
- def initialize(conn_id)
38
- @conn_id = conn_id
39
- end
40
-
41
- def to_s
42
- super + "#{conn_id}|"
43
- end
44
-
45
- class << self
46
- RE = %r{^([^|]+)\|}
47
-
48
- def parse(data)
49
- data =~ RE
50
- conn_id = $1
51
-
52
- cmd = self.new(conn_id)
53
-
54
- data.sub! RE, ''
55
-
56
- cmd
57
- end
58
-
59
- def match(data)
60
- !! (data =~ RE)
61
- end
62
- end
63
-
64
- end
65
-
66
- class CreateConnectionCommand < ConnectionCommand
67
- end
68
-
69
- class CloseConnectionCommand < ConnectionCommand
70
- end
71
-
72
- class SendDataCommand < Command
73
- attr_reader :conn_id
74
- attr_reader :data
75
-
76
- def initialize(conn_id, data)
77
- @conn_id = conn_id
78
- @data = data
79
- end
80
-
81
- def to_s
82
- super + "#{conn_id}|#{data.size}|#{data}"
83
- end
84
-
85
- class << self
86
- RE = %r{^([^|]+)\|([^|]+)\|}
87
-
88
- def parse(data)
89
- data =~ RE
90
-
91
- conn_id = $1
92
- data_size = $2.to_i
93
-
94
- new_data = data.sub(RE, '')
95
- cmd_data = new_data[0,data_size]
96
-
97
- cmd = SendDataCommand.new(conn_id, cmd_data)
98
-
99
- data.replace(new_data[data_size..-1])
100
-
101
- cmd
102
- end
103
-
104
- def match(data)
105
- return false if ! (data =~ RE)
106
-
107
- data_size = $2.to_i
108
-
109
- data.sub(RE, '').size >= data_size
110
- end
111
- end
112
- end
113
-
114
- class RemoteListenCommand < Command
115
- attr_reader :address
116
-
117
- def initialize(address)
118
- @address = address
119
- end
120
-
121
- def to_s
122
- super + "#{address}|"
123
- end
124
-
125
- class << self
126
- RE = %r{^([^|]+)\|}
127
-
128
- def parse(data)
129
- data =~ RE
130
- address = $1
131
-
132
- cmd = self.new(address)
133
-
134
- data.sub! RE, ''
135
-
136
- cmd
137
- end
138
-
139
- def match(data)
140
- !! (data =~ RE)
141
- end
142
- end
143
-
144
- end
145
-
146
- class PingCommand < Command
147
- def self.parse(data)
148
- PingCommand.new
149
- end
150
-
151
- def self.match(data)
152
- true
153
- end
154
- end
155
-
156
- class Command
157
- CODES_TO_CLASSES = {
158
- "C" => CreateConnectionCommand,
159
- "X" => CloseConnectionCommand,
160
- "D" => SendDataCommand,
161
- "P" => PingCommand,
162
- "L" => RemoteListenCommand,
163
- }
164
- CLASSES_TO_CODES = CODES_TO_CLASSES.invert
165
- end
166
- end