rcs-common 9.6.0

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.
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