ji2p 0.0.1-jruby

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,62 @@
1
+ require 'java'
2
+
3
+ require 'java'
4
+ require 'digest/sha1'
5
+
6
+ module Ji2p::Control
7
+ class TunnelManager
8
+ @@tunnelctrl = nil
9
+ include_package 'net.i2p'
10
+ include_package 'net.i2p.i2ptunnel'
11
+ include_package 'net.i2p.client'
12
+
13
+ def self.context
14
+ I2PAppContext.getGlobalContext
15
+ end
16
+
17
+ def self.startTunnelWithConfig conf, createPrivKey = false
18
+ unless ['client','httpclient','server','httpserver','sockstunnel'].include? conf['type']
19
+ raise ArgumentError, 'Invalid i2p tunnel type!', caller
20
+ end
21
+ tctrl = TunnelController.new conf, '', createPrivKey
22
+ TunnelCtrl.new tctrl, conf
23
+ end
24
+
25
+ def self.createNewConfig hash = Hash.new
26
+ props = java.util.Properties.new
27
+ dfl = {
28
+ 'option.maxPosts'=>'3',
29
+ 'option.i2cp.destination.sigType'=>'EdDSA_SHA512_Ed25519',
30
+ 'option.i2p.streaming.limitAction'=>'http',
31
+ 'description'=>'jruby-tunnel',
32
+ 'interface'=>'127.0.0.1',
33
+ 'type'=>'httpserver',
34
+ 'option.outbound.quantity'=>'4',
35
+ 'option.inbound.quantity'=>'4',
36
+ 'option.postBanTime'=>'1800',
37
+ 'targetPort'=>'8000',
38
+ 'option.postTotalBanTime'=>'600',
39
+ 'i2cpHost'=>'127.0.0.1',
40
+ 'option.postCheckTime'=>'300',
41
+ 'option.i2p.streaming.maxConnsPerHour'=>'40',
42
+ 'option.shouldBundleReplyInfo'=>'false',
43
+ 'option.outbound.length'=>'1',
44
+ 'targetHost'=>'127.0.0.1',
45
+ 'option.inbound.length'=>'1',
46
+ 'i2cpPort'=>'7654',
47
+ 'persistentClientKey'=>'true',
48
+ 'option.maxTotalPosts'=>'10',
49
+ 'option.i2p.streaming.maxConnsPerDay'=>'100',
50
+ 'option.i2p.streaming.maxTotalConnsPerMinute'=>'25',
51
+ 'option.i2p.streaming.maxConnsPerMinute'=>'15',
52
+ 'name'=>'jruby-tunnel',
53
+ 'option.i2p.streaming.maxConcurrentStreams'=>'20',
54
+ 'privKeyFile'=>'kake.dat',
55
+ 'listenPort'=>'8000'
56
+ }
57
+ merged = dfl.merge(hash)
58
+ merged.keys.each { |k| props[k.to_s] = merged[k].to_s }
59
+ props
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,14 @@
1
+ require 'digest/sha1'
2
+
3
+ module Ji2p
4
+ module Control
5
+ autoload :ClientManager, File.expand_path('control/client_manager.rb', __dir__)
6
+ autoload :Dest, File.expand_path('control/dest.rb', __dir__)
7
+ autoload :Keypair, File.expand_path('control/keypair.rb', __dir__)
8
+ autoload :TunnelManager, File.expand_path('control/tunnel_manager.rb', __dir__)
9
+
10
+ def self.unique_id
11
+ Digest::SHA1.hexdigest([Time.now, rand].join)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ require 'sinatra'
2
+ require 'rack'
3
+ require 'puma'
4
+ require 'faye/websocket'
5
+
6
+ module Ji2p::Server
7
+ class Api
8
+ def initialize
9
+ configure { set :server, :puma }
10
+
11
+ Faye::WebSocket.load_adapter('puma')
12
+ @puma = Rack::Handler.get('puma')
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,66 @@
1
+ require 'active_record'
2
+
3
+ module Ji2p::Server
4
+ module Database
5
+ @@connections = Hash.new
6
+ @@default_connection = nil
7
+
8
+ def self.connect! db=':memory:', db_type='sqlite3'
9
+ conn = ActiveRecord::Base.establish_connection(database: db, adapter: db_type)
10
+ key = "#{db}/#{db_type}/#{Ji2p::Control.unique_id.to_s}"
11
+ @@connections[key] = conn
12
+ @@default_connection = conn if @@default_connection.nil?
13
+ define_state_schema!
14
+ conn
15
+ end
16
+
17
+ def self.connect_with_local_path! name
18
+ java_import 'net.i2p.I2PAppContext'
19
+ ctx = Java::NetI2p::I2PAppContext.getGlobalContext
20
+ path = File.join ctx.getConfigDir.toString, name
21
+ connect! path
22
+ end
23
+
24
+ def self.flush
25
+ @@default_connection.flush
26
+ end
27
+
28
+ def self.default
29
+ @@default_connection
30
+ end
31
+
32
+ def self.is_connected?
33
+ get_connections.size > 0
34
+ end
35
+
36
+ def self.get_connections
37
+ @@connections
38
+ end
39
+
40
+ def self.define_state_schema! b_force=false
41
+ ActiveRecord::Schema.define do
42
+ create_table :keypairs, force: b_force do |t|
43
+ t.string :strid
44
+ t.string :name
45
+ t.text :destination
46
+ t.string :base32
47
+ t.text :private_key_data
48
+ t.json :metadata
49
+ t.timestamps
50
+ end unless ActiveRecord::Base.connection.table_exists? 'keypairs' or b_force
51
+ create_table :tunnels, force: b_force do |t|
52
+ t.string :name
53
+ t.text :description
54
+ t.json :metadata
55
+ t.references :keypair
56
+ t.string :tunnel_type
57
+ t.integer :listen_port
58
+ t.integer :target_port
59
+ t.string :listen_interface
60
+ t.string :target_host
61
+ t.timestamps
62
+ end unless ActiveRecord::Base.connection.table_exists? 'tunnels' or b_force
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,69 @@
1
+ require 'rack'
2
+
3
+ module Ji2p::Server
4
+ class HTTP
5
+ VERSION = "HTTP/1.1" unless defined? VERSION
6
+ CRLF = "\r\n" unless defined? CRLF
7
+
8
+ def initialize(socket, application)
9
+ @socket = socket
10
+ @application = application
11
+ end
12
+
13
+ def parse
14
+ matches = /\A(?<method>\S+)\s+(?<uri>\S+)\s+(?<version>\S+)#{CRLF}\Z/.match(@socket.readline)
15
+ uri = URI.parse(matches[:uri])
16
+
17
+ env = {
18
+ "rack.errors" => $stderr,
19
+ "rack.version" => Rack::VERSION,
20
+ "rack.url_scheme" => uri.scheme || "http",
21
+ "REQUEST_METHOD" => matches[:method],
22
+ "REQUEST_URI" => matches[:uri],
23
+ "HTTP_VERSION" => matches[:version],
24
+ "QUERY_STRING" => uri.query || "",
25
+ "SERVER_PORT" => uri.port || 80,
26
+ "SERVER_NAME" => uri.host || "localhost",
27
+ "PATH_INFO" => uri.path || "",
28
+ "SCRIPT_NAME" => "",
29
+ }
30
+
31
+ while matches = /\A(?<key>[^:]+):\s*(?<value>.+)#{CRLF}\Z/.match(hl = @socket.readline)
32
+ case matches[:key]
33
+ when Rack::CONTENT_TYPE then env["CONTENT_TYPE"] = matches[:value]
34
+ when Rack::CONTENT_LENGTH then env["CONTENT_LENGTH"] = Integer(matches[:value])
35
+ else env["HTTP_" + matches[:key].tr("-", "_").upcase] ||= matches[:value]
36
+ end
37
+ end
38
+
39
+ env["rack.input"] = StringIO.new(@socket.read(env["CONTENT_LENGTH"] || 0))
40
+
41
+ return env #.map { |_,v| String.new v }
42
+ end
43
+
44
+ def handle
45
+ env = parse
46
+
47
+ status, headers, body = @application.call(env)
48
+
49
+ time = Time.now.httpdate
50
+
51
+ @socket.write "#{env['HTTP_VERSION']} #{status} #{Rack::Utils::HTTP_STATUS_CODES.fetch(status.to_i) { 'UNKNOWN' }}#{CRLF}"
52
+ @socket.write "Date: #{time}#{CRLF}"
53
+ @socket.write "Connection: close#{CRLF}"
54
+
55
+ headers.each do |key, value|
56
+ @socket.write "#{key}: #{value}#{CRLF}"
57
+ end
58
+
59
+ @socket.write(CRLF)
60
+
61
+ body.each do |chunk|
62
+ @socket.write(chunk)
63
+ end
64
+
65
+ Ji2p.logger.info("[#{time}] '#{env["REQUEST_METHOD"]} #{env["REQUEST_URI"]} #{env["HTTP_VERSION"]}' #{status}")
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,37 @@
1
+ require_relative 'http.rb'
2
+
3
+ module Ji2p::Server
4
+ class HttpServer
5
+
6
+ def initialize(application, socket)
7
+ @application = application
8
+ @socket = socket
9
+ end
10
+
11
+ def run
12
+ loop do
13
+ begin
14
+ monitor
15
+ rescue Interrupt
16
+ Ji2p.logger.log("INTERRUPTED")
17
+ return
18
+ end
19
+ end
20
+ end
21
+
22
+ def monitor
23
+ #selections, = IO.select(@sockets)
24
+ #io, = selections
25
+ io = @socket
26
+
27
+ begin
28
+ socket = io.accept
29
+ http = Ji2p::Server::HTTP::new(socket, @application)
30
+ http.handle
31
+ ensure
32
+ socket.close
33
+ end
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,4 @@
1
+ module Ji2p::Server
2
+ module Initializer
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ require 'active_record'
2
+
3
+ module Ji2p::Server::Models
4
+ class BaseRecord < ActiveRecord::Base
5
+ self.abstract_class = true
6
+ end
7
+ end
@@ -0,0 +1,32 @@
1
+ require 'active_record'
2
+ require 'base64'
3
+
4
+ module Ji2p::Server::Models
5
+ Ji2p::Control::Keypair.class_eval do
6
+ def to_activerecord
7
+ row = Ji2p::Server::Models::Keypair.new
8
+ row.destination = @dest.base64
9
+ row.base32 = @dest.base32
10
+ row.private_key_data = Base64.encode64(@data)
11
+ row
12
+ end
13
+
14
+ private
15
+
16
+ def write_dummy_stream obj
17
+ s = StringIO.new
18
+ obj.writeBytes(s.to_outputstream)
19
+ Base64.encode64 s.string
20
+ end
21
+ end
22
+ class Keypair < BaseRecord
23
+
24
+ def pk_data
25
+ Base64.decode64(private_key_data)
26
+ end
27
+
28
+ def getKeypairInstance
29
+ Ji2p::Control::Keypair.load_from_stream! StringIO.new(pk_data)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,4 @@
1
+ module Ji2p::Server::Models
2
+ class Tunnel < BaseRecord
3
+ end
4
+ end
@@ -0,0 +1,9 @@
1
+ require 'active_record'
2
+
3
+ module Ji2p::Server
4
+ module Models
5
+ autoload :BaseRecord, File.expand_path('models/base_record.rb', __dir__)
6
+ autoload :Keypair, File.expand_path('models/keypair.rb', __dir__)
7
+ autoload :Tunnel, File.expand_path('models/tunnel.rb', __dir__)
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ module Ji2p
2
+ module Server
3
+ autoload :Api, File.expand_path('server/api.rb', __dir__)
4
+ autoload :Database, File.expand_path('server/database.rb', __dir__)
5
+ end
6
+ end
@@ -0,0 +1,60 @@
1
+ require 'java'
2
+
3
+ module Ji2p::Startup
4
+ java_import java.lang.ClassLoader
5
+ java_import java.lang.System
6
+
7
+ class Bootstrap
8
+ def initialize defaults={'i2p.dir.config' => TMPDIR}
9
+ @defaults = defaults
10
+ end
11
+
12
+ def set_system_property key, value
13
+ System.setProperty key.to_s, value.to_s
14
+ end
15
+
16
+ def get_system_property value
17
+ System.getProperty[value.to_s]
18
+ end
19
+
20
+ def load_jars
21
+ java_import java.lang.Thread
22
+ java_import java.net.URL
23
+ cl = Thread.currentThread.getContextClassLoader
24
+ dirname = System.getProperties['i2p.dir.base']
25
+ Dir["#{dirname}/lib/**.jar"].each do |jar|
26
+ u = Java::JavaNet::URL.new "file://#{jar}"
27
+ cl.addURL u
28
+ end
29
+ end
30
+
31
+ def i2p_loaded?
32
+ java_import java.lang.Thread
33
+ cl = Thread.currentThread.getContextClassLoader
34
+ cl.getURLs.select { |item| item.to_s.include? 'i2p.jar' }.size > 0
35
+ end
36
+
37
+ def check_and_set_props!
38
+ if System.getProperties['i2p.dir.base'].nil?
39
+ unless ENV['I2PDIR'].nil?
40
+ System.setProperty 'i2p.dir.base', ENV['I2PDIR'].to_s
41
+ else
42
+ raise ArgumentError, 'The system property i2p.dir.base is missing!', caller if @defaults['i2p.dir.base'].nil?
43
+ end
44
+ end
45
+ if System.getProperties['i2p.dir.config'].nil?
46
+ raise ArgumentError, 'The system property i2p.dir.config is missing!', caller if @defaults['i2p.dir.config'].nil?
47
+ System.setProperty 'i2p.dir.config', @defaults['i2p.dir.config']
48
+ end
49
+ System.setProperty 'java.awt.headless', 'true' if System.getProperties['java.awt.headless'].nil?
50
+ System.setProperty 'java.library.path', "#{System.getProperties['i2p.dir.base']}/lib" if System.getProperties['java.library.path'].nil?
51
+ end
52
+
53
+ def boot!
54
+ check_and_set_props!
55
+ load_jars unless i2p_loaded?
56
+ RouterManager.start_router!
57
+ RouterManager.router_context
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,21 @@
1
+ require 'java'
2
+
3
+ module Ji2p::Startup
4
+ class RouterManager
5
+ @@router = nil
6
+ include_package 'net.i2p.router'
7
+
8
+ def self.start_router!
9
+ @@router = RouterLaunch.main ARGV if @@router.nil?
10
+ end
11
+
12
+ def self.router_context
13
+ RouterContext.getCurrentContext
14
+ end
15
+
16
+ def self.get_leases
17
+ ctx = RouterManager.router_context
18
+ ctx.netDb.get_leases.to_a
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ module Ji2p
2
+ module Startup
3
+ autoload :Bootstrap, File.expand_path('startup/bootstrap.rb', __dir__)
4
+ autoload :RouterManager, File.expand_path('startup/router_manager.rb', __dir__)
5
+
6
+ TMPDIR = File.expand_path('../../tmp', __dir__) unless defined? TMPDIR
7
+
8
+ def self.tmp_dir
9
+ TMPDIR
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module Ji2p
2
+ VERSION = '0.0.1'.freeze unless defined? VERSION
3
+ end
data/lib/ji2p.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'active_support/dependencies'
2
+ require 'logger'
3
+
4
+ module Ji2p
5
+ require_relative 'ji2p/version.rb'
6
+ autoload :Cluster, File.expand_path('ji2p/cluster.rb', __dir__)
7
+ autoload :Control, File.expand_path('ji2p/control.rb', __dir__)
8
+ autoload :Server, File.expand_path('ji2p/server.rb', __dir__)
9
+ autoload :Startup, File.expand_path('ji2p/startup.rb', __dir__)
10
+ ActiveSupport::Dependencies.autoload_paths << __dir__
11
+ Dir.glob('**/').each do |dir|
12
+ ActiveSupport::Dependencies.autoload_paths << File.expand_path(dir, __dir__)
13
+ end
14
+
15
+ def self.logger
16
+ @logger ||= Logger.new(STDOUT)
17
+ end
18
+
19
+ end