require "nokogiri" require "json" require "yaml" require "socket" puts "Arguments: #{ARGV.join(", ")[0..-1]}" puts "Filename: #{__FILE__}" puts "Script: #{$0}" puts "Required gems: nokogiri" puts if ARGV[0] == "generate" class BOBResponse def self.iws sock full = String.new ans = sock.gets while ans[0...4] == "DATA" full += ans ans = sock.gets end full += ans BOBResponse.new full end def initialize ans @ans = ans.chomp @parsed = false self.parse! end def data? ! @data.nil? end def ok? @status == "OK" end def error? @status == "ERROR" end def answer @ans end def content @content end def data @data end def status @status end def parse! if @ans[0...4] == "DATA" @data = Array.new @ans.lines.each { |x| x.chomp! if x[0...4] == "DATA" @data.push x[5..-1] elsif x[0...2] == "OK" @status = x[0...2] @content = x[3..-1] end } elsif @ans[0...2] == "OK" @status = @ans[0...2] @content = @ans[3..-1] elsif @ans[0...5] == "ERROR" @status = @ans[0...5] @content = @ans[6..-1] end @parsed = true end end class BOBRequest def initialize cmd, args = String.new @cmd = cmd @args = args end def full_request "#{@cmd} #{@args}\n" end def send sock sock.puts self.full_request sleep 2 if @cmd == "stop" end end class BOBInitial def self.iws sock BOBInitial.new sock.gets, sock.gets end def initialize line1, line2 @line1 = line1.chomp @line2 = line2.chomp self.parse! end def parse! @apiname = @line1[0...3] @version = @line1[4..-1] @bobstatus = @line2 end def apiname @apiname end def version @version end def status @bobstatus end def ok? @bobstatus == "OK" end def error? @bobstatus == "ERROR" end end def raiseiferror sock resp = BOBResponse.iws(sock) raise "Line: #{__LINE__}; Message: #{resp.answer}" if resp.error? end bob = TCPSocket.new "127.0.0.1", 2827 raise "I was unable to connect to the BOB API on host 127.0.0.1 and port 2827." if bob.closed? #p BOBInitial.new bob.gets, bob.gets if BOBInitial.iws(bob).ok? puts "Connected to BOB" else raise "Unable to connect to BOB" end puts "BOB: Set nickname to ruby" BOBRequest.new("setnick", "ruby").send bob raiseiferror bob puts "BOB: Generate new keys" BOBRequest.new("newkeys").send bob raiseiferror bob puts "BOB: Set inhost to 127.0.0.1" BOBRequest.new("inhost", "127.0.0.1").send bob raiseiferror bob puts "BOB: Set inport to 2000" BOBRequest.new("inport", "2000").send bob raiseiferror bob puts "BOB: Start tunnel..." BOBRequest.new("start").send bob raiseiferror bob sleep 0.5 puts "BOB: Tunnel started" puts "BOB: Lookup for identiguy.i2p" BOBRequest.new("lookup", "identiguy.i2p").send bob resp = BOBResponse.iws bob raise "Line: #{__LINE__}; Message: #{resp.answer}" if resp.error? b64 = resp.content puts "Connect to API" conn = TCPSocket.new "127.0.0.1", 2000 puts "Connect to identiguy.i2p" conn.puts b64 http_request = <<~ENDOFREQUEST GET / HTTP/1.1 Host: identiguy.i2p User-Agent: Ruby Script Accept: text/html Connection: close ENDOFREQUEST puts "Send http request" conn.puts http_request puts "Receive and evaluate results" doc = Nokogiri::HTML conn.read conn.close eepsites = Hash.new tables = doc.xpath("//table//tr//td") full = tables.length / 3 i = 0 while i < tables.length name = tables[i].content if name.include? ".b32.i2p" i += 2 next end puts "Create entries: #{i/3 + 1} of #{full} - #{name}" eepsites[name] = [ name, tables[i+1].children[0].attributes["href"].value[ (26+name.length) .. -1], tables[i+1].children[2].attributes["href"].value[7..-2], tables[i+2].content ] i += 3 end unless ARGV.include? "--no-marshal" puts "Generate results: Write as marshal" fil = File.new "eepsites.marshal", "wb" fil.write Marshal.dump(eepsites) fil.close end unless ARGV.include? "--no-json" puts "Generate results: Write as JSON" fil = File.new "eepsites.json", "w" fil.write JSON.dump eepsites fil.close end unless ARGV.include? "--no-yaml" puts "Generate results: Write as YAML" fil = File.new "eepsites.yaml", "w" fil.write YAML.dump eepsites fil.close end if ARGV.include? "--generate-html" puts "Generate results: Write as HTML" fil = File.new "eepsites.html", "w" fil.puts '' fil.puts '' fil.puts ' ' fil.puts ' ' fil.puts ' eepsites' fil.puts ' ' fil.puts ' ' fil.puts ' ' fil.puts ' ' fil.puts ' ' fil.puts ' ' fil.puts ' ' fil.puts ' ' fil.puts ' ' fil.puts ' ' fil.puts ' ' fil.puts ' ' fil.puts ' ' fil.puts ' ' eepsites.each { |key, val| fil.puts ' ' fil.puts " " fil.puts " " fil.puts " " fil.puts " " fil.puts ' ' } fil.puts ' ' fil.puts '
Hostnamebase64base32Last Reachable
#{val[0]}#{val[1]}#{val[2]}#{val[3]}
' fil.puts ' ' fil.puts '' end sleep 1 puts "BOB: Stop tunnel..." BOBRequest.new("stop").send bob raiseiferror bob puts "Close connection to the BOB API" BOBRequest.new("clear").send bob raiseiferror bob BOBRequest.new("quit").send bob raiseiferror bob bob.close elsif ARGV[0] == "parse" obj = nil if File.exist? "eepsites.marshal" obj = Marshal.load File.read "eepsites.marshal" elsif File.exist? "eepsites.json" obj = JSON.load File.read "eepsites.json" elsif File.exist? "eepsites.yaml" obj = YAML.load File.read "eepsites.yaml" else raise "No eepsites.[marshal|json|yaml] file found. Please run ruby #{__FILE__} generate first." end obj.each { |key, val| puts "#{key}:" puts "\tHostname: #{val[0]}" unless ARGV.include? "--no-hostname" puts "\tbase64: #{val[1]}" unless ARGV.include? "--no-base64" puts "\tbase32: #{val[2]}" unless ARGV.include? "--no-base32" puts "\tLast Reachable: #{val[3]}" unless ARGV.include? "--no-date" puts "\n" } elsif ARGV[0] == "info" obj = nil if File.exist? "eepsites.marshal" obj = Marshal.load File.read "eepsites.marshal" elsif File.exist? "eepsites.json" obj = JSON.load File.read "eepsites.json" elsif File.exist? "eepsites.yaml" obj = YAML.load File.read "eepsites.yaml" else raise "No eepsites.[marshal|json|yaml] file found. Please run ruby #{__FILE__} generate first." end raise "I can not found #{ARGV[1]}" unless obj.has_key? ARGV[1] puts "#{ARGV[1]}:" puts "\tHostname: #{obj[ARGV[1]][0]}" unless ARGV.include? "--no-hostname" puts "\tbase64: #{obj[ARGV[1]][1]}" unless ARGV.include? "--no-base64" puts "\tbase32: #{obj[ARGV[1]][2]}" unless ARGV.include? "--no-base32" puts "\tLast Reachable: #{obj[ARGV[1]][3]}" unless ARGV.include? "--no-date" end