i2p 0.1.4

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.
@@ -0,0 +1,303 @@
1
+ module I2P; module BOB
2
+ ##
3
+ # **I2P Basic Open Bridge (BOB) tunnel manager.**
4
+ #
5
+ # @example Creating and controlling a new tunnel
6
+ # I2P::BOB::Tunnel.new(...) do |tunnel|
7
+ # tunnel.start
8
+ # sleep 0.1 until tunnel.running?
9
+ # # ... code that uses the tunnel goes here ...
10
+ # tunnel.stop
11
+ # end
12
+ #
13
+ # @example Starting a new inbound I2P tunnel in one go
14
+ # I2P::BOB::Tunnel.start({
15
+ # :nickname => :inproxy,
16
+ # :inhost => "127.0.0.1"
17
+ # :inport => 12345, # unused port
18
+ # })
19
+ #
20
+ # @example Starting a new outbound I2P tunnel in one go
21
+ # I2P::BOB::Tunnel.start({
22
+ # :nickname => :myssh,
23
+ # :outhost => "127.0.0.1",
24
+ # :outport => 22, # SSH port
25
+ # })
26
+ #
27
+ # @example Starting an existing tunnel
28
+ # I2P::BOB::Tunnel.start(:myssh)
29
+ #
30
+ # @example Obtaining the I2P destination for a tunnel
31
+ # tunnel = I2P::BOB::Tunnel.start(:mytunnel)
32
+ # tunnel.destination #=> #<I2P::Destination:...>
33
+ #
34
+ # @example Stopping an existing tunnel
35
+ # I2P::BOB::Tunnel.stop(:myssh)
36
+ #
37
+ # @see http://www.i2p2.de/applications.html
38
+ # @see http://bob.i2p.to/bridge.html
39
+ # @since 0.1.4
40
+ class Tunnel
41
+ ##
42
+ # Starts up a new tunnel.
43
+ #
44
+ # @param [Hash{Symbol => Object}] options
45
+ # @option options [String, #to_s] :nickname (Time.now.to_i)
46
+ # @option options [KeyPair, #to_s] :keys (nil)
47
+ # @option options [Boolean] :quiet (false)
48
+ # @option options [String, #to_s] :inhost ("localhost")
49
+ # @option options [Integer, #to_i] :inport (nil)
50
+ # @option options [String, #to_s] :outhost ("localhost")
51
+ # @option options [Integer, #to_i] :outport (nil)
52
+ # @return [Tunnel]
53
+ def self.start(options = {}, &block)
54
+ tunnel = self.new(options).start
55
+
56
+ if block_given?
57
+ begin
58
+ result = block.call(tunnel)
59
+ ensure
60
+ tunnel.stop
61
+ end
62
+ result
63
+ else
64
+ tunnel
65
+ end
66
+ end
67
+
68
+ ##
69
+ # Shuts down an existing tunnel of the given `nickname`.
70
+ #
71
+ # @param [String, #to_s]
72
+ # @return [void]
73
+ def self.stop(nickname)
74
+ self.new(nickname).stop
75
+ end
76
+
77
+ ##
78
+ # Initializes a new tunnel instance.
79
+ #
80
+ # @overload initialize(options = {})
81
+ # @param [Hash{Symbol => Object}] options
82
+ # @option options [String, #to_s] :nickname (Time.now.to_i)
83
+ # @option options [KeyPair, #to_s] :keys (nil)
84
+ # @option options [Boolean] :quiet (false)
85
+ # @option options [String, #to_s] :inhost ("localhost")
86
+ # @option options [Integer, #to_i] :inport (nil)
87
+ # @option options [String, #to_s] :outhost ("localhost")
88
+ # @option options [Integer, #to_i] :outport (nil)
89
+ #
90
+ # @overload initialize(nickname)
91
+ # @param [String, #to_s] nickname
92
+ #
93
+ def initialize(options = {})
94
+ case options
95
+ when Hash
96
+ # Create a new tunnel
97
+ @nickname = options[:nickname] || Time.now.to_i.to_s
98
+ @debug = options[:debug]
99
+ setup(options)
100
+ else
101
+ # Access an existing tunnel
102
+ @nickname = options.to_s
103
+ Client.open { |client| client.getnick(@nickname) }
104
+ end
105
+ end
106
+
107
+ ##
108
+ # Returns the nickname for this tunnel.
109
+ #
110
+ # @return [String]
111
+ # @see Client#getnick
112
+ attr_reader :nickname
113
+
114
+ ##
115
+ # Returns the I2P {I2P::Destination destination} for this tunnel.
116
+ #
117
+ # @return [Destination]
118
+ # @see Client#getdest
119
+ attr_reader :destination
120
+ def destination
121
+ @destination ||= client { getdest }
122
+ end
123
+
124
+ ##
125
+ # Returns the I2P {I2P::KeyPair key pair} for this tunnel.
126
+ #
127
+ # @return [KeyPair]
128
+ # @see Client#getkeys
129
+ attr_reader :keys
130
+ def keys
131
+ @keys ||= client { getkeys }
132
+ end
133
+
134
+ ##
135
+ # Returns `true` if this is an inbound tunnel.
136
+ #
137
+ # @return [Boolean]
138
+ def inbound?
139
+ !!inport
140
+ end
141
+
142
+ ##
143
+ # Returns the inbound host name or IP address for this tunnel.
144
+ #
145
+ # @return [String]
146
+ # @see Client#inhost
147
+ attr_reader :inhost
148
+ def inhost
149
+ @inhost ||= begin
150
+ nil # TODO
151
+ end
152
+ end
153
+
154
+ ##
155
+ # Returns the inbound port number for this tunnel.
156
+ #
157
+ # @return [Integer]
158
+ # @see Client#inport
159
+ attr_reader :inport
160
+ def inport
161
+ @inport ||= begin
162
+ nil # TODO
163
+ end
164
+ end
165
+
166
+ ##
167
+ # Returns `true` if this is an outbound tunnel.
168
+ #
169
+ # @return [Boolean]
170
+ def outbound?
171
+ !!outport
172
+ end
173
+
174
+ ##
175
+ # Returns the outbound host name or IP address for this tunnel.
176
+ #
177
+ # @return [String]
178
+ # @see Client#outhost
179
+ attr_reader :outhost
180
+ def outhost
181
+ @outhost ||= begin
182
+ nil # TODO
183
+ end
184
+ end
185
+
186
+ ##
187
+ # Returns the outbound port number for this tunnel.
188
+ #
189
+ # @return [Integer]
190
+ # @see Client#outport
191
+ attr_reader :outport
192
+ def outport
193
+ @outport ||= begin
194
+ nil # TODO
195
+ end
196
+ end
197
+
198
+ ##
199
+ # Returns `true` if quiet mode is enabled for this tunnel.
200
+ #
201
+ # This only applies to outbound tunnels and has no effect on inbound
202
+ # tunnels.
203
+ #
204
+ # @return [Boolean]
205
+ # @see Client#quiet
206
+ def quiet?
207
+ @quiet ||= begin
208
+ nil # TODO
209
+ end
210
+ end
211
+
212
+ ##
213
+ # Registers the given tunnel `options` with the BOB bridge.
214
+ #
215
+ # @param [Hash{Symbol => Object}] options
216
+ # @return [void]
217
+ def setup(options = {})
218
+ client do |client|
219
+ if options[:keys]
220
+ client.setkeys(options[:keys])
221
+ else
222
+ begin
223
+ client.getkeys
224
+ rescue Error => e
225
+ client.newkeys
226
+ end
227
+ end
228
+
229
+ client.quiet(options[:quiet]) if options[:quiet]
230
+ client.inhost(options[:inhost]) if options[:inhost]
231
+ client.inport(options[:inport]) if options[:inport]
232
+ client.outhost(options[:outhost]) if options[:outhost]
233
+ client.outport(options[:outport]) if options[:outport]
234
+ end
235
+ self
236
+ end
237
+ alias_method :setup!, :setup
238
+
239
+ ##
240
+ # Returns `true` if this tunnel is currently active.
241
+ #
242
+ # @return [Boolean]
243
+ def running?
244
+ true # FIXME
245
+ end
246
+ alias_method :active?, :running?
247
+
248
+ ##
249
+ # Starts up this tunnel.
250
+ #
251
+ # @return [void]
252
+ # @see Client#start
253
+ def start
254
+ client { start }
255
+ self
256
+ end
257
+ alias_method :start!, :start
258
+
259
+ ##
260
+ # Returns `true` if this tunnel is currently in the process of starting
261
+ # up.
262
+ #
263
+ # @return [Boolean]
264
+ def starting?
265
+ # TODO
266
+ end
267
+
268
+ ##
269
+ # Shuts down this tunnel.
270
+ #
271
+ # @return [void]
272
+ # @see Client#stop
273
+ def stop
274
+ client { stop }
275
+ self
276
+ end
277
+ alias_method :stop!, :stop
278
+
279
+ ##
280
+ # Returns `true` if this tunnel is currently in the process of shutting
281
+ # down.
282
+ #
283
+ # @return [Boolean]
284
+ def stopping?
285
+ # TODO
286
+ end
287
+
288
+ def socket
289
+ client.socket
290
+ end
291
+
292
+ ##
293
+ # Returns a {I2P::BOB::Client} instance for accessing low-level
294
+ # information about this tunnel.
295
+ #
296
+ # @yield [client]
297
+ # @yieldparam [Client] client
298
+ # @return [Client]
299
+ def client(&block)
300
+ Client.open(:nickname => nickname, :debug => @debug, &block)
301
+ end
302
+ end
303
+ end; end
@@ -0,0 +1,75 @@
1
+ module I2P
2
+ ##
3
+ # **I2P certificate data structure.**
4
+ #
5
+ # Defines a certificate that can be attached to various I2P structures,
6
+ # such as `RouterIdentity` and `Destination`, allowing routers and clients
7
+ # to help manage denial of service attacks and the network utilization.
8
+ #
9
+ # @see http://docs.i2p2.de/core/net/i2p/data/Certificate.html
10
+ # @since 0.1.3
11
+ class Certificate < Structure
12
+ TYPE_NULL = 0 # Null certificate
13
+ TYPE_HASHCASH = 1 # Hashcash certificate
14
+ TYPE_HIDDEN = 2 # Hidden certificate
15
+ TYPE_SIGNED = 3 # Signed certificate
16
+ TYPE_MULTIPLE = 4
17
+
18
+ LENGTH_SIGNED_WITH_HASH = nil # TODO
19
+
20
+ ##
21
+ # Reads a certificate from the given `input` stream.
22
+ #
23
+ # @param [IO, StringIO] input
24
+ # @return [Certificate]
25
+ def self.read(input)
26
+ type = input.read(1).unpack('c').first
27
+ length = input.read(2).unpack('n').first
28
+ payload = length.zero? ? String.new : input.read(length)
29
+ self.new(type, payload)
30
+ end
31
+
32
+ ##
33
+ # @return [Integer]
34
+ attr_accessor :type
35
+
36
+ ##
37
+ # @return [String]
38
+ attr_accessor :payload
39
+
40
+ ##
41
+ # Initializes a new certificate instance.
42
+ #
43
+ # @param [Integer, #to_i] type
44
+ # @param [String, #to_s] payload
45
+ def initialize(type = TYPE_NULL, payload = String.new)
46
+ @type, @payload = type.to_i, payload
47
+ end
48
+
49
+ ##
50
+ # Returns the byte size of this certificate.
51
+ #
52
+ # @return [Integer]
53
+ def size
54
+ 1 + 2 + (payload ? payload.size : 0)
55
+ end
56
+ alias_method :bytesize, :size
57
+
58
+ ##
59
+ # Returns the binary string representation of this certificate.
60
+ #
61
+ # @return [String]
62
+ def to_s
63
+ StringIO.open do |buffer|
64
+ buffer.write([type].pack('c'))
65
+ if payload && !payload.empty?
66
+ buffer.write([payload.size].pack('n'))
67
+ buffer.write(payload.to_s)
68
+ else
69
+ buffer.write([0].pack('n'))
70
+ end
71
+ buffer.string
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,68 @@
1
+ module I2P
2
+ ##
3
+ # **I2P destination data structure.**
4
+ #
5
+ # Defines an endpoint in the I2P network. The destination may move around
6
+ # in the network, but messages sent to the destination will reach it.
7
+ #
8
+ # @see http://docs.i2p2.de/core/net/i2p/data/Destination.html
9
+ # @since 0.1.3
10
+ class Destination < Structure
11
+ BYTESIZE = 387 # minimum
12
+
13
+ ##
14
+ # Reads a destination from the given `input` stream.
15
+ #
16
+ # @param [IO, StringIO] input
17
+ # @return [Destination]
18
+ def self.read(input)
19
+ self.new(PublicKey.read(input), SigningPublicKey.read(input), Certificate.read(input))
20
+ end
21
+
22
+ ##
23
+ # Initializes a new destination instance.
24
+ #
25
+ # @param [PublicKey] public_key
26
+ # @param [SigningPublicKey] signing_key
27
+ # @param [Certificate] certificate
28
+ def initialize(public_key, signing_key, certificate = Certificate.new)
29
+ @public_key = public_key
30
+ @signing_key = signing_key
31
+ @certificate = certificate
32
+ end
33
+
34
+ ##
35
+ # @return [PublicKey]
36
+ attr_accessor :public_key
37
+
38
+ ##
39
+ # @return [SigningPublicKey]
40
+ attr_accessor :signing_key
41
+
42
+ ##
43
+ # @return [Certificate]
44
+ attr_accessor :certificate
45
+
46
+ ##
47
+ # Returns the byte size of this data structure.
48
+ #
49
+ # @return [Integer]
50
+ def size
51
+ public_key.size + signing_key.size + certificate.size
52
+ end
53
+ alias_method :bytesize, :size
54
+
55
+ ##
56
+ # Returns the binary string representation of this destination.
57
+ #
58
+ # @return [String]
59
+ def to_s
60
+ StringIO.open do |buffer|
61
+ buffer.write(public_key.to_s)
62
+ buffer.write(signing_key.to_s)
63
+ buffer.write(certificate.to_s)
64
+ buffer.string
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,40 @@
1
+ module I2P
2
+ ##
3
+ class Key < Structure
4
+ ##
5
+ # Reads a key data structure from the given `input` stream.
6
+ #
7
+ # @param [IO, StringIO] input
8
+ # @return [Key]
9
+ def self.read(input)
10
+ self.new(input.read(const_get(:BYTESIZE)))
11
+ end
12
+
13
+ ##
14
+ # @return [String]
15
+ attr_accessor :data
16
+
17
+ ##
18
+ # @param [String] data
19
+ def initialize(data)
20
+ @data = data.to_s
21
+ end
22
+
23
+ ##
24
+ # Returns `true` if this key is of the correct size.
25
+ #
26
+ # @return [Boolean]
27
+ # @since 0.1.3
28
+ def valid?
29
+ @data.size.eql?(self.class.const_get(:BYTESIZE))
30
+ end
31
+
32
+ ##
33
+ # Returns the binary string representation of this key.
34
+ #
35
+ # @return [String]
36
+ def to_s
37
+ @data
38
+ end
39
+ end
40
+ end