schatz 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +8 -0
- data/Gemfile.lock +21 -0
- data/README.txt +14 -0
- data/bin/schatz +12 -0
- data/config/config.yml +10 -0
- data/install.rb +5 -0
- data/lib/schatz.rb +31 -0
- data/lib/schatz/cli/configuration.rb +45 -0
- data/lib/schatz/cli/runner.rb +35 -0
- data/lib/schatz/input/connection.rb +94 -0
- data/lib/schatz/input/connection_result.rb +14 -0
- data/lib/schatz/input/export.rb +14 -0
- data/lib/schatz/input/incr_export.rb +81 -0
- data/lib/schatz/input/incr_line_parser.rb +35 -0
- data/lib/schatz/input/parser.rb +53 -0
- data/lib/schatz/input/result.rb +7 -0
- data/lib/schatz/input/text_export.rb +35 -0
- data/lib/schatz/input/txt_line_parser.rb +29 -0
- data/lib/schatz/output/cmd.rb +30 -0
- data/lib/schatz/output/html.rb +69 -0
- data/lib/schatz/output/out.rb +9 -0
- data/lib/schatz/schemes/direct_tcp.rb +17 -0
- data/lib/schatz/schemes/proxy_http.rb +19 -0
- data/lib/schatz/schemes/proxy_https.rb +18 -0
- data/lib/schatz/testers/incr_test.rb +46 -0
- metadata +71 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
nokogiri (1.5.0-x86-mingw32)
|
5
|
+
rainbow (1.1.3)
|
6
|
+
win32-api (1.4.8-x86-mingw32)
|
7
|
+
win32console (1.3.0-x86-mingw32)
|
8
|
+
windows-api (0.4.0)
|
9
|
+
win32-api (>= 1.4.5)
|
10
|
+
windows-pr (1.2.1)
|
11
|
+
win32-api (>= 1.4.5)
|
12
|
+
windows-api (>= 0.3.0)
|
13
|
+
|
14
|
+
PLATFORMS
|
15
|
+
x86-mingw32
|
16
|
+
|
17
|
+
DEPENDENCIES
|
18
|
+
nokogiri
|
19
|
+
rainbow
|
20
|
+
win32console
|
21
|
+
windows-pr
|
data/README.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
= Tools for connectivity checking
|
2
|
+
== Description
|
3
|
+
Gem provides means for testing TCP direct connections as well as HTTP web services through HTTP proxy.
|
4
|
+
How to install gem:
|
5
|
+
* $ gem install schatz
|
6
|
+
Testing INCRs
|
7
|
+
|
8
|
+
schatz -f file_name [-po] [-do] [-g 123456]
|
9
|
+
|
10
|
+
-f name of the export(.html ior .htm extension) or name of .txt file
|
11
|
+
-po test only http/https links via proxies
|
12
|
+
-do test only direct connections
|
13
|
+
-p test via specified proxy
|
14
|
+
-h help
|
data/bin/schatz
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
|
3
|
+
require File.expand_path(File.dirname(__FILE__)+ "/../lib/schatz")
|
4
|
+
begin
|
5
|
+
Schatz::Cli::Runner.run(ARGV.dup, STDOUT, STDERR)
|
6
|
+
rescue SystemExit => e
|
7
|
+
Kernel.exit(e.status)
|
8
|
+
rescue Exception => e
|
9
|
+
STDERR.puts("#{e.message} (#{e.class})")
|
10
|
+
STDERR.puts(e.backtrace.join("\n"))
|
11
|
+
Kernel.exit(1)
|
12
|
+
end
|
data/config/config.yml
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#please add necessary proxies
|
2
|
+
---
|
3
|
+
proxies:
|
4
|
+
1: "http://10.233.46.129:8080"
|
5
|
+
2: "http://10.233.46.130:8080"
|
6
|
+
3: "http://10.233.46.131:8080"
|
7
|
+
4: "http://10.233.46.132:8080"
|
8
|
+
5: "http://10.237.46.130:8080"
|
9
|
+
6: "http://10.237.46.131:8080"
|
10
|
+
7: "http://10.237.46.132:8080"
|
data/install.rb
ADDED
data/lib/schatz.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
$:.push File.expand_path(File.dirname(__FILE__) + "/../lib")
|
2
|
+
require 'rubygems'
|
3
|
+
require 'optparse'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'schatz/cli/runner'
|
6
|
+
require 'schatz/cli/configuration'
|
7
|
+
require 'schatz/input/export'
|
8
|
+
require 'schatz/testers/incr_test'
|
9
|
+
require 'schatz/input/incr_export'
|
10
|
+
require 'schatz/input/text_export'
|
11
|
+
require 'schatz/input/connection'
|
12
|
+
require 'schatz/input/connection_result'
|
13
|
+
require 'schatz/input/txt_line_parser'
|
14
|
+
require 'schatz/input/incr_line_parser'
|
15
|
+
require 'schatz/output/out'
|
16
|
+
require 'schatz/output/html'
|
17
|
+
require 'schatz/output/cmd'
|
18
|
+
require 'schatz/schemes/direct_tcp'
|
19
|
+
require 'schatz/schemes/proxy_http'
|
20
|
+
require 'schatz/schemes/proxy_https'
|
21
|
+
require 'schatz/input/parser'
|
22
|
+
require 'timeout'
|
23
|
+
require 'rainbow'
|
24
|
+
module Schatz
|
25
|
+
exceptions = %w(IncorrentParameters IncorrectIncrFormat ExportedIncrFieldErrorPorts FileNotExistInCurrentDirectory IncorrectFileFormat SheetNotFound ExportedIncrFieldErrorUnrecognized
|
26
|
+
IncorrectTextFormat NotImplementedMethod)
|
27
|
+
exceptions.each do |exc|
|
28
|
+
const_set exc, Class.new(StandardError)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
Sickill::Rainbow.enabled = true
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Schatz
|
2
|
+
module Cli
|
3
|
+
class Configuration
|
4
|
+
attr_accessor :opt, :options, :stdout, :stderr
|
5
|
+
def initialize(output=STDOUT, error=STDERR,options={})
|
6
|
+
@stdout = output
|
7
|
+
@stderr = error
|
8
|
+
@options =options
|
9
|
+
@opt = OptionParser.new
|
10
|
+
@opt.banner = "Usage: schatz [file_name]"
|
11
|
+
@opt.separator "Options:"
|
12
|
+
@opt.on("-f", "--file [file]") {|file| @options[:file_name] = file}
|
13
|
+
@opt.on("-h", "--help") {|ignore| @options[:help] = true}
|
14
|
+
@opt.on("--po") {|ignore| @options[:proxy_only] = true}
|
15
|
+
@opt.on("--do") {|ignore| @options[:direct_only] = true}
|
16
|
+
@opt.on("-g", "--gcm [gcm]") {|gcm| @options[:gcm] = "gcm000000" +gcm}
|
17
|
+
@opt.on("-p", "--prx [proxy]") {|proxy| @options[:proxies] = {1 => proxy}}
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse!(argv)
|
21
|
+
raise ArgumentError, "expected array of argv" unless argv.is_a?(Array)
|
22
|
+
raise ArgumentError, "you should provide at least a name of the incr" if argv.empty? || argv.first=="-f" && argv.length==1
|
23
|
+
@opt.parse(argv)
|
24
|
+
@options[:file_name] = full_file_name(@options[:file_name]) if @options[:file_name]
|
25
|
+
@options[:proxies] ||= read_config
|
26
|
+
show_info
|
27
|
+
end
|
28
|
+
|
29
|
+
def show_info
|
30
|
+
puts @opt if @options[:help]
|
31
|
+
puts "GCM number is not provided so will check all links. If you want to test only those implemented after specified GCM please mention it".foreground(:yellow) unless @options[:gcm]
|
32
|
+
end
|
33
|
+
|
34
|
+
def full_file_name(file_name)
|
35
|
+
raise FileNotExistInCurrentDirectory until File.exist?(file_name)
|
36
|
+
raise IncorrectFileFormat until file_name =~ /\.xlsx?/ || file_name =~ /\.html?/ || file_name =~ /\.txt?/
|
37
|
+
File.expand_path(file_name)
|
38
|
+
end
|
39
|
+
|
40
|
+
def read_config
|
41
|
+
YAML::load_file(File.expand_path(File.dirname(__FILE__)+"./../../../config/config.yml"))["proxies"]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
module Schatz
|
3
|
+
module Cli
|
4
|
+
class Runner
|
5
|
+
attr_accessor :options, :output, :error, :configuration
|
6
|
+
def self.run(argv, output, error, options={})
|
7
|
+
new(argv, output, error, options).run
|
8
|
+
end
|
9
|
+
def initialize(argv, output, error, options={})
|
10
|
+
@output = output
|
11
|
+
@error = error
|
12
|
+
@configuration = Configuration.new(output, error, options)
|
13
|
+
@configuration.parse!(argv)
|
14
|
+
@options = @configuration.options
|
15
|
+
end
|
16
|
+
def run
|
17
|
+
trap_interrupt
|
18
|
+
source = case @options[:file_name]
|
19
|
+
when /\.htm/
|
20
|
+
Input::IncrExport.new(@options)
|
21
|
+
when /\.txt/
|
22
|
+
Input::TextExport.new(@options)
|
23
|
+
else
|
24
|
+
raise IncorrectFileFormat
|
25
|
+
end
|
26
|
+
outputters = [Output::CMD.new(@options), Output::HTML.new(@options)]
|
27
|
+
tester = Testers::IncrTest.new(@options, outputters)
|
28
|
+
tester.check_connections(source.get_conversations + source.get_links )
|
29
|
+
end
|
30
|
+
def trap_interrupt
|
31
|
+
trap("INT") {exit!}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Schatz
|
2
|
+
module Input
|
3
|
+
class Connection
|
4
|
+
attr_accessor :scheme, :host, :port, :gcm, :result, :color, :description
|
5
|
+
def initialize
|
6
|
+
@port = 80
|
7
|
+
@scheme = "http"
|
8
|
+
yield self
|
9
|
+
if @port=="" || @port==0
|
10
|
+
case @scheme
|
11
|
+
when "http"
|
12
|
+
@port = 80
|
13
|
+
when "https"
|
14
|
+
@port = 443
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
def eql?(b)
|
19
|
+
self.scheme == b.scheme && self.host == b.host && self.port == b.port && self.gcm == b.gcm ? true : false
|
20
|
+
end
|
21
|
+
|
22
|
+
def result=(value)
|
23
|
+
@result=value
|
24
|
+
mark
|
25
|
+
end
|
26
|
+
def scheme=(value)
|
27
|
+
@scheme = value.downcase
|
28
|
+
end
|
29
|
+
def gcm=(value)
|
30
|
+
@gcm = value.downcase
|
31
|
+
end
|
32
|
+
|
33
|
+
def http?
|
34
|
+
@scheme="http"
|
35
|
+
end
|
36
|
+
|
37
|
+
def https?
|
38
|
+
@scheme="https"
|
39
|
+
end
|
40
|
+
|
41
|
+
def mark
|
42
|
+
direct? ? mark_hosts : mark_links
|
43
|
+
end
|
44
|
+
|
45
|
+
def direct?
|
46
|
+
scheme.downcase == "tcp" || scheme.downcase == "udp"
|
47
|
+
end
|
48
|
+
|
49
|
+
def link?
|
50
|
+
scheme.downcase == "http" || scheme.downcase == "https"
|
51
|
+
end
|
52
|
+
|
53
|
+
def mark_hosts
|
54
|
+
self.color = result == "open" ? "green" : "red"
|
55
|
+
end
|
56
|
+
|
57
|
+
def mark_links
|
58
|
+
self.color, self.description= case result
|
59
|
+
when /30[12]/ then ["green", "Redirection to websso"]
|
60
|
+
when "200" then ["green", "OK"]
|
61
|
+
when /40[13]/ then ["green", "Error authorization"]
|
62
|
+
else ["red", result]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def check
|
67
|
+
direct? ? host_check : link_check
|
68
|
+
end
|
69
|
+
def link_check
|
70
|
+
raise ArgumentError unless @proxy
|
71
|
+
begin
|
72
|
+
self.result = case scheme
|
73
|
+
when "http"
|
74
|
+
Schemes::ProxyHttp.http_test(self, @proxy)
|
75
|
+
when "https"
|
76
|
+
Schemes::ProxyHttps.https_test(self, @proxy)
|
77
|
+
end
|
78
|
+
rescue Exception => e
|
79
|
+
self.result = e.message
|
80
|
+
end
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
def host_check
|
85
|
+
begin
|
86
|
+
self.result = Schemes::DirectTcp.direct_test(self.host, self.port, 0.5) ? "open" : "closed"
|
87
|
+
rescue Exception => e
|
88
|
+
self.result = "closed"
|
89
|
+
end
|
90
|
+
self
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Schatz
|
2
|
+
module Input
|
3
|
+
class ConnectionResult < Connection
|
4
|
+
attr_accessor :proxy
|
5
|
+
def initialize(connection, proxy=nil)
|
6
|
+
@scheme = connection.scheme
|
7
|
+
@host = connection.host
|
8
|
+
@port = connection.port
|
9
|
+
@gcm = connection.gcm
|
10
|
+
@proxy = proxy
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'net/http'
|
3
|
+
require 'net/https'
|
4
|
+
require 'schatz/input/parser'
|
5
|
+
require 'timeout'
|
6
|
+
module Schatz
|
7
|
+
module Input
|
8
|
+
class IncrExport < Export
|
9
|
+
include ParserHelper
|
10
|
+
attr_accessor :options, :file
|
11
|
+
|
12
|
+
def initialize(options)
|
13
|
+
@options = options
|
14
|
+
@file = Nokogiri::HTML(File.open(@options[:file_name], 'r'))
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_links
|
18
|
+
Schatz::Input::IncrLineParser.new(rows_in_links_table).links
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_conversations
|
22
|
+
Schatz::Input::IncrLineParser.new(rows_in_conversation_table).connections
|
23
|
+
end
|
24
|
+
|
25
|
+
# eliminate the first row(names of the fields)
|
26
|
+
def rows_in_conversation_table
|
27
|
+
get_rid_of_header(find_conv_table).select {|row| row =~ CONVERSATION_ROW }
|
28
|
+
end
|
29
|
+
|
30
|
+
def rows_in_links_table
|
31
|
+
get_rid_of_header(find_links_table)
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_rid_of_header(table_number)
|
35
|
+
rows = @file.xpath("//table[#{table_number+1}]//tr")
|
36
|
+
rows.map {|row| delete_mess(row) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete_mess(row)
|
40
|
+
row.text.gsub(/[\n\t]/, "").gsub(/\u00A0/, " ").gsub(/\r\r/, " ").gsub(/\r/, "")
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_table options={}
|
44
|
+
allowed_keys= ["table_id"]
|
45
|
+
raise ArgumentError if options.empty?
|
46
|
+
options.keys.each {|key| raise IncorrentParameters unless allowed_keys.include? key.to_s}
|
47
|
+
@file.xpath("/html/body/table")[options[:table_id].to_i]
|
48
|
+
end
|
49
|
+
|
50
|
+
def find_conv_table
|
51
|
+
reg1 = Regexp.new 'Conversation Type'
|
52
|
+
reg2 = Regexp.new 'CR/GCM Number'
|
53
|
+
reg3 = Regexp.new 'Destination Host'
|
54
|
+
find_table([reg1, reg2, reg3])
|
55
|
+
end
|
56
|
+
|
57
|
+
def find_links_table
|
58
|
+
reg1 = Regexp.new 'Intranet Site'
|
59
|
+
reg2 = Regexp.new 'Reason and Activity'
|
60
|
+
reg3 = Regexp.new 'CR/GCM Number'
|
61
|
+
find_table([reg1, reg2, reg3])
|
62
|
+
end
|
63
|
+
|
64
|
+
def find_table(regs)
|
65
|
+
tables = @file.xpath("/html/body/table")
|
66
|
+
conv_table = tables.select {|t| regs.all?{ |regexp| t.text =~ regexp} }
|
67
|
+
raise IncorrectIncrFormat if conv_table.size > 1
|
68
|
+
tables.index(conv_table.first)
|
69
|
+
end
|
70
|
+
|
71
|
+
def delete_source_subnets(row)
|
72
|
+
row.match(SOURCE_SUBNET).to_a.each{|reg| row.gsub!(/#{reg}/, "")} while row =~ SOURCE_SUBNET
|
73
|
+
row
|
74
|
+
end
|
75
|
+
|
76
|
+
def scan_gcm_numbers(rows)
|
77
|
+
rows.map{ |row| row.scan(GCM_NUMBER).first }.compact.map(&:downcase)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Schatz
|
2
|
+
module Input
|
3
|
+
class IncrLineParser < Parser
|
4
|
+
include ParserHelper
|
5
|
+
def initialize(lines)
|
6
|
+
super(lines)
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse(line)
|
10
|
+
case line
|
11
|
+
when IncrExport::LINK_HTML
|
12
|
+
@links << Connection.new do |c|
|
13
|
+
c.gcm = $1.downcase
|
14
|
+
c.scheme = $2
|
15
|
+
c.host = $3
|
16
|
+
c.port = $4.to_i if $4
|
17
|
+
end
|
18
|
+
when IncrExport::CONVERSATION_HTML
|
19
|
+
gcm = $1
|
20
|
+
scheme = $4
|
21
|
+
line.scan(IP_ADDRESS).map do |address|
|
22
|
+
parse_ports_field(line.match(IncrExport::PORTS_WITH_PROTOCOL).captures.first).map do |port|
|
23
|
+
@connections << Connection.new do |c|
|
24
|
+
c.gcm = gcm
|
25
|
+
c.scheme = scheme
|
26
|
+
c.host = address.first
|
27
|
+
c.port = port.to_i
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Schatz
|
2
|
+
module Input
|
3
|
+
class Parser
|
4
|
+
attr_accessor :connections, :links
|
5
|
+
def initialize(lines)
|
6
|
+
@connections = []
|
7
|
+
@links = []
|
8
|
+
lines.map { |line| parse(line)}
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse(line)
|
12
|
+
raise NotImplementedMethod
|
13
|
+
end
|
14
|
+
end
|
15
|
+
module ParserHelper
|
16
|
+
|
17
|
+
LINK = Regexp.new '(https?):\/\/([a-zA-Z0-9\.\-]+\.?d?b?.com):?(\d{1,5}*)'
|
18
|
+
LINK_HTML = Regexp.new '(gcm\d{12}|GCM\d{12}).*(https?):\/\/([a-zA-Z0-9\.\-]+\.?d?b?.com):?(\d{1,5}*).*'
|
19
|
+
SOURCE_SUBNET = Regexp.new '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\ *\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
|
20
|
+
GCM_NUMBER = Regexp.new 'gcm\d{12}|GCM\d{12}'
|
21
|
+
REGEXP_HOST = Regexp.new '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}.+(\d{1,5}[\-\,]?)+$'
|
22
|
+
REGEXP_HOST_PORTS = Regexp.new '^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\ +(\d{1,5}\-\d{1,5}|\d{1,5}(\,\d{1,5})*)$'
|
23
|
+
ONE_PORT = Regexp.new '^\d{1,5}$'
|
24
|
+
ONE_HYPHEN = Regexp.new '^\d{1,5}(\-)+\d{1,5}$'
|
25
|
+
ONE_OR_MORE_COMMA = Regexp.new'^\d{1,5}(,\d{1,5})+$'
|
26
|
+
IP_ADDRESS = Regexp.new '(10\.\d{1,3}\.\d{1,3}\.\d{1,3})(?#matches ip address)(?!.*255\.\d{1,3}\.\d{1,3}\.\d{1,3})'
|
27
|
+
PORTS_WITH_PROTOCOL= Regexp.new '([\d\-\,]{1,450}) ?(TCP|UDP)'
|
28
|
+
CONVERSATION_HTML = Regexp.new "(#{GCM_NUMBER.source}).*#{IP_ADDRESS.source}.*#{PORTS_WITH_PROTOCOL.source}.*"
|
29
|
+
CONVERSATION_ROW = Regexp.new ".*#{IP_ADDRESS.source}.*#{PORTS_WITH_PROTOCOL.source}.*"
|
30
|
+
|
31
|
+
def parse_ports_field(ports)
|
32
|
+
raise ArgumentError, "received nil instead of string for ports" unless ports
|
33
|
+
raise ArgumentError, "received blank instead of string for ports" if ports.empty?
|
34
|
+
ports.gsub!(/ /, "")
|
35
|
+
case ports
|
36
|
+
when ONE_HYPHEN
|
37
|
+
start_range, end_range = ports.split("-")
|
38
|
+
[*start_range..end_range].map(&:to_i)
|
39
|
+
when ONE_OR_MORE_COMMA
|
40
|
+
ports.split(",").map(&:to_i)
|
41
|
+
when ONE_PORT
|
42
|
+
[ports.to_i]
|
43
|
+
else ports
|
44
|
+
raise ExportedIncrFieldErrorPorts, "for #{ports}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def push_connection(host, port, protocol, gcm, hosts)
|
49
|
+
hosts << {:host => host, :port => port.to_i, :protocol => protocol, :gcm => gcm}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'schatz/input/parser'
|
2
|
+
module Schatz
|
3
|
+
module Input
|
4
|
+
class TextExport < Export
|
5
|
+
include ParserHelper
|
6
|
+
attr_accessor :file, :options
|
7
|
+
def initialize(options)
|
8
|
+
@options = options
|
9
|
+
@addresses_with_ports = []
|
10
|
+
@conversations = []
|
11
|
+
@links_with_ports = []
|
12
|
+
@file = File.open(@options[:file_name], 'r')
|
13
|
+
check_format
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_links
|
17
|
+
TxtLineParser.new(split_lines).links
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_conversations
|
21
|
+
TxtLineParser.new(split_lines).connections
|
22
|
+
end
|
23
|
+
|
24
|
+
# split txt file into lines
|
25
|
+
def split_lines
|
26
|
+
@file.pos=0
|
27
|
+
@file.read.split(/\n/).map{ |line| line.gsub /\r/, "" }
|
28
|
+
end
|
29
|
+
|
30
|
+
def check_format
|
31
|
+
raise IncorrectTextFormat, "format of txt file is incorrect" unless split_lines.all? { |line| line =~ REGEXP_HOST || line =~ LINK }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Schatz
|
2
|
+
module Input
|
3
|
+
class TxtLineParser < Parser
|
4
|
+
include ParserHelper
|
5
|
+
def initialize(lines)
|
6
|
+
super(lines)
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse(line)
|
10
|
+
case line
|
11
|
+
when REGEXP_HOST_PORTS
|
12
|
+
parse_ports_field($2).map do |port|
|
13
|
+
@connections << Connection.new do |c|
|
14
|
+
c.host = $1
|
15
|
+
c.port = port
|
16
|
+
c.scheme = "tcp"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
when LINK
|
20
|
+
@links << Connection.new do |c|
|
21
|
+
c.scheme = $1
|
22
|
+
c.host = $2
|
23
|
+
c.port = $3.to_i if $3
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Schatz
|
2
|
+
module Output
|
3
|
+
class CMD < Out
|
4
|
+
def initialize(options={})
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
def print(connection)
|
8
|
+
case connection.scheme
|
9
|
+
when "tcp"
|
10
|
+
direct(connection)
|
11
|
+
when "http"
|
12
|
+
link(connection)
|
13
|
+
when "https"
|
14
|
+
link(connection)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def direct(connection)
|
19
|
+
color = connection.result == "open" ? :green : :red
|
20
|
+
puts (connection.host+" "+connection.port.to_s+" "+connection.scheme).foreground(color)
|
21
|
+
end
|
22
|
+
|
23
|
+
def link(connection)
|
24
|
+
codes = %w(403 302 200)
|
25
|
+
color = codes.include?(connection.result) ? :green : :red
|
26
|
+
puts (connection.scheme+"://"+connection.host+" "+connection.port.to_s+" via "+ connection.proxy).foreground(color)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Schatz
|
2
|
+
module Output
|
3
|
+
class HTML < Out
|
4
|
+
attr_accessor :html, :connections
|
5
|
+
def initialize(options={})
|
6
|
+
@html=""
|
7
|
+
@options = options
|
8
|
+
@connections = []
|
9
|
+
end
|
10
|
+
def print(connection)
|
11
|
+
@connections << connection
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate
|
15
|
+
File.open(file_name,"w+") do |file|
|
16
|
+
print_head
|
17
|
+
print_hosts
|
18
|
+
print_links
|
19
|
+
print_end
|
20
|
+
file << @html
|
21
|
+
@html
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def file_name
|
26
|
+
@options[:file_name].to_s+"_test_"+ Time.now.strftime("%d-%m-%y-%s")+".html"
|
27
|
+
end
|
28
|
+
|
29
|
+
def print_hosts
|
30
|
+
@html << "<h3>Conversation Map</h3>"
|
31
|
+
@html << "<table>"
|
32
|
+
@html << "<tr><th>Number</th><th> IP address</th><th> Port </th><th> Protocol </th><th> Result </th></tr>"
|
33
|
+
@connections.select{ |connection| connection.direct? }.each_with_index do |host, index|
|
34
|
+
@html << "<tr><td>#{index+1}</td><td>#{host.host}</td><td>#{host.port}</td><td>#{host.scheme}</td><td class='#{host.color}'>#{host.result}</td></tr>"
|
35
|
+
end
|
36
|
+
@html << "</table><br/><br/>"
|
37
|
+
end
|
38
|
+
|
39
|
+
def print_links
|
40
|
+
@connections.select{ |connection| connection.link? }.group_by { |connection| connection.proxy}.each do |proxy, links|
|
41
|
+
print_links_table(proxy, links)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def print_links_table(proxy, links)
|
46
|
+
@html << "<h3>Intranet Access #{proxy}</h3>"
|
47
|
+
@html << "<table>"
|
48
|
+
@html << "<tr><th>Number</th><th> Link to page</th><th> Result </th></tr>"
|
49
|
+
links.each_with_index do |link, index|
|
50
|
+
@html << "<tr><td>#{index+1}</td><td><a href='#{link.scheme}://#{link.host}:#{link.port}'> #{link.scheme}://#{link.host}:#{link.port} </td><td class='#{link.color}'>#{link.result}</td></tr>"
|
51
|
+
end
|
52
|
+
@html << "</table>"
|
53
|
+
end
|
54
|
+
def print_head
|
55
|
+
@html << "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'><html lang='en'>
|
56
|
+
<head>
|
57
|
+
<title>Connection Test Results</title>
|
58
|
+
<style type='text/css'>
|
59
|
+
.green{background-color:SeaGreen}
|
60
|
+
.red {background-color:Crimson}
|
61
|
+
</style>
|
62
|
+
</head><body>"
|
63
|
+
end
|
64
|
+
def print_end
|
65
|
+
@html << "</body></html>"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require 'socket'
|
3
|
+
module Schatz
|
4
|
+
module Schemes
|
5
|
+
module DirectTcp
|
6
|
+
def self.direct_test(host, port, timeout =0.1)
|
7
|
+
addr = Socket.pack_sockaddr_in(port, host)
|
8
|
+
s = Socket.new(:AF_INET, :SOCK_STREAM, 0)
|
9
|
+
begin
|
10
|
+
s.connect_nonblock(addr)
|
11
|
+
rescue Errno::EINPROGRESS
|
12
|
+
IO.select(nil, [s], nil, timeout) ? true : (raise Timeout::Error)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
module Schatz
|
4
|
+
module Schemes
|
5
|
+
module ProxyHttp
|
6
|
+
def self.http_test(link, proxy)
|
7
|
+
Proxy.connect(proxy).start(link.host, link.port, :proxy => proxy).get("/").code
|
8
|
+
end
|
9
|
+
end
|
10
|
+
module Proxy
|
11
|
+
def self.connect(proxy)
|
12
|
+
uri = URI(proxy)
|
13
|
+
Net::HTTP::Proxy(uri.host, uri.port)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'uri'
|
2
|
+
module Schatz
|
3
|
+
module Schemes
|
4
|
+
module ProxyHttps
|
5
|
+
def self.https_test(link, proxy)
|
6
|
+
response = Proxy.connect(proxy).start(link.host, link.port, :use_ssl => true, :verify_mode => OpenSSL::SSL::VERIFY_NONE, :open_timeout => 1.5).get("/")
|
7
|
+
case response
|
8
|
+
when Net::HTTPFound
|
9
|
+
"302" if response['location'] =~ /https\:\/\/login\-intranet\.isso\.db\.com/ ? "redirected to WebSSO" : "redirected to #{response['location']}"
|
10
|
+
when Net::HTTPOK
|
11
|
+
"200"
|
12
|
+
else
|
13
|
+
[response.code, response.msg].join(" ")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Schatz
|
2
|
+
module Testers
|
3
|
+
class IncrTest
|
4
|
+
attr_accessor :options, :output, :connections
|
5
|
+
def initialize(options={}, outputters=[])
|
6
|
+
@options = options
|
7
|
+
@outputters = outputters
|
8
|
+
end
|
9
|
+
|
10
|
+
def check_connections(connections)
|
11
|
+
@connections = connections
|
12
|
+
if @options[:direct_only]
|
13
|
+
direct_check
|
14
|
+
elsif @options[:proxy_only]
|
15
|
+
links_check
|
16
|
+
else
|
17
|
+
direct_check
|
18
|
+
links_check
|
19
|
+
end
|
20
|
+
@outputters.each { |outputter| outputter.generate }
|
21
|
+
end
|
22
|
+
|
23
|
+
def links_check
|
24
|
+
match_gcm_connections.select { |c| c.link? }.map do |connection|
|
25
|
+
proxies.map do |proxy|
|
26
|
+
@outputters.each { |out| out.print(Input::ConnectionResult.new(connection, proxy).check) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def direct_check
|
32
|
+
match_gcm_connections.select { |c| c.direct? }.map do |connection|
|
33
|
+
@outputters.each { |out| out.print(Input::ConnectionResult.new(connection).check) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def match_gcm_connections
|
38
|
+
@options[:gcm] ? @connections.select { |c| c.gcm == @options[:gcm] } : @connections
|
39
|
+
end
|
40
|
+
|
41
|
+
def proxies
|
42
|
+
@options[:proxies].values
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: schatz
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sergiy Shevchik
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-03 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Tool for checking the connectivity
|
15
|
+
email: berrouz@gmail.com
|
16
|
+
executables:
|
17
|
+
- schatz
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files:
|
20
|
+
- README.txt
|
21
|
+
files:
|
22
|
+
- lib/schatz.rb
|
23
|
+
- lib/schatz/input/connection.rb
|
24
|
+
- lib/schatz/input/connection_result.rb
|
25
|
+
- lib/schatz/input/export.rb
|
26
|
+
- lib/schatz/input/incr_export.rb
|
27
|
+
- lib/schatz/input/incr_line_parser.rb
|
28
|
+
- lib/schatz/input/parser.rb
|
29
|
+
- lib/schatz/input/result.rb
|
30
|
+
- lib/schatz/input/text_export.rb
|
31
|
+
- lib/schatz/input/txt_line_parser.rb
|
32
|
+
- lib/schatz/cli/runner.rb
|
33
|
+
- lib/schatz/cli/configuration.rb
|
34
|
+
- lib/schatz/output/html.rb
|
35
|
+
- lib/schatz/output/out.rb
|
36
|
+
- lib/schatz/output/cmd.rb
|
37
|
+
- lib/schatz/schemes/direct_tcp.rb
|
38
|
+
- lib/schatz/schemes/proxy_http.rb
|
39
|
+
- lib/schatz/schemes/proxy_https.rb
|
40
|
+
- lib/schatz/testers/incr_test.rb
|
41
|
+
- install.rb
|
42
|
+
- config/config.yml
|
43
|
+
- Gemfile
|
44
|
+
- Gemfile.lock
|
45
|
+
- README.txt
|
46
|
+
- bin/schatz
|
47
|
+
homepage: https://github.com/berrouz/schatz
|
48
|
+
licenses: []
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 1.9.3
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
requirements: []
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.8.11
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: TCP,UDP
|
71
|
+
test_files: []
|