gems-status 0.38.0 → 0.39.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/gems-status +1 -1
- data/lib/gems-status.rb +26 -23
- data/lib/gems-status/checkers/exists_in_upstream.rb +17 -14
- data/lib/gems-status/checkers/gem_checker.rb +8 -6
- data/lib/gems-status/checkers/git_check_messages.rb +25 -22
- data/lib/gems-status/checkers/hg_check_messages.rb +25 -22
- data/lib/gems-status/checkers/not_a_security_alert_checker.rb +161 -158
- data/lib/gems-status/checkers/not_native_gem_checker.rb +33 -30
- data/lib/gems-status/checkers/not_rails_checker.rb +16 -13
- data/lib/gems-status/checkers/print_gem_versions.rb +27 -23
- data/lib/gems-status/checkers/scm_check_messages.rb +44 -41
- data/lib/gems-status/checkers/scm_security_messages.rb +5 -3
- data/lib/gems-status/checkers/security_alert.rb +7 -5
- data/lib/gems-status/checkers/svn_check_messages.rb +29 -26
- data/lib/gems-status/gem_simple.rb +42 -40
- data/lib/gems-status/gems_command.rb +30 -28
- data/lib/gems-status/gems_composite_command.rb +85 -82
- data/lib/gems-status/gems_status_metadata.rb +2 -2
- data/lib/gems-status/html_view.rb +240 -237
- data/lib/gems-status/sources/lockfile_gems.rb +64 -61
- data/lib/gems-status/sources/obs_gems.rb +86 -83
- data/lib/gems-status/sources/ruby_gems_gems.rb +32 -30
- data/lib/gems-status/sources/ruby_gems_gems_gem_simple.rb +29 -26
- data/lib/gems-status/utils.rb +77 -74
- data/test/test-gems_command.rb +52 -49
- data/test/test-gems_composite_command.rb +43 -40
- data/test/test-helper.rb +2 -0
- data/test/test-lockfile_gems.rb +64 -61
- data/test/test-not_rails_checker.rb +45 -42
- data/test/test-obs_gems.rb +31 -29
- data/test/test-ruby_gems_gems.rb +22 -20
- data/test/test-utils.rb +42 -39
- metadata +181 -176
@@ -3,39 +3,42 @@ require 'rubygems/old_format'
|
|
3
3
|
require 'open-uri'
|
4
4
|
require 'gems-status/checkers/gem_checker'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
6
|
+
module GemsStatus
|
7
|
+
|
8
|
+
class NotNativeGemChecker < GemChecker
|
9
|
+
def check?(gem)
|
10
|
+
result = nil
|
11
|
+
gem_uri = URI.parse("#{gem.gems_url}/#{gem.name}-#{gem.version}.gem" )
|
12
|
+
uri_debug = gem_uri.clone
|
13
|
+
uri_debug.password = "********" if uri_debug.password
|
14
|
+
Utils::log_debug "download #{@name} from #{uri_debug}"
|
15
|
+
begin
|
16
|
+
if gem_uri.user && gem_uri.password
|
17
|
+
source = open(gem_uri.scheme + "://" + gem_uri.host + "/" + gem_uri.path,
|
18
|
+
Gem.binary_mode,
|
19
|
+
:http_basic_authentication=>[gem_uri.user, gem_uri.password]) do |io|
|
20
|
+
result = Gem::Format.from_io io
|
21
|
+
end
|
22
|
+
else
|
23
|
+
source = open(gem_uri, Gem.binary_mode) do |io|
|
24
|
+
result = Gem::Format.from_io io
|
25
|
+
end
|
23
26
|
end
|
27
|
+
rescue IOError
|
28
|
+
#bug on open-uri:137 on closing strings
|
29
|
+
#it should be
|
30
|
+
#io.close if io && !io.closed?
|
31
|
+
#or is a bug on rubygems???
|
32
|
+
rescue => e
|
33
|
+
Utils::log_error(gem.name, "There was a problem opening #{gem_uri} #{e.class} #{e.message}")
|
24
34
|
end
|
25
|
-
|
26
|
-
|
27
|
-
#it should be
|
28
|
-
#io.close if io && !io.closed?
|
29
|
-
#or is a bug on rubygems???
|
30
|
-
rescue => e
|
31
|
-
Utils::log_error(gem.name, "There was a problem opening #{gem_uri} #{e.class} #{e.message}")
|
35
|
+
return false unless result
|
36
|
+
return result.spec.extensions.empty?
|
32
37
|
end
|
33
|
-
return false unless result
|
34
|
-
return result.spec.extensions.empty?
|
35
|
-
end
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
+
def description
|
40
|
+
"This gem is a native gem or could not get specs: "
|
41
|
+
end
|
39
42
|
end
|
40
|
-
end
|
41
43
|
|
44
|
+
end
|
@@ -3,20 +3,23 @@ require 'rubygems/old_format'
|
|
3
3
|
require 'open-uri'
|
4
4
|
require 'gems-status/checkers/gem_checker'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
gem
|
11
|
-
if
|
12
|
-
|
6
|
+
module GemsStatus
|
7
|
+
|
8
|
+
class NotRailsChecker < GemChecker
|
9
|
+
RAILS_GEMS = ["rails", "railties","activesupport"]
|
10
|
+
def check?(gem)
|
11
|
+
return false if !gem.dependencies
|
12
|
+
gem.dependencies.each do |dep|
|
13
|
+
if RAILS_GEMS.include?(dep.name)
|
14
|
+
return false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
return true
|
13
18
|
end
|
14
|
-
end
|
15
|
-
return true
|
16
|
-
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
+
def description
|
21
|
+
"This gem depends on rails or could not get spec: "
|
22
|
+
end
|
20
23
|
end
|
21
|
-
end
|
22
24
|
|
25
|
+
end
|
@@ -1,32 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
module GemsStatus
|
2
|
+
|
3
|
+
class PrintGemVersions
|
4
|
+
def initialize(conf)
|
5
|
+
Utils::check_parameters('PrintGemVersions', conf, ["licenses"])
|
6
|
+
begin
|
7
|
+
@licenses = YAML::load(File::open(conf["licenses"]))
|
8
|
+
rescue
|
9
|
+
Utils::log_error("?", "There was a problem opening #{conf["licenses"]}")
|
10
|
+
@licenses = []
|
11
|
+
end
|
9
12
|
end
|
10
|
-
end
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def check?(gem)
|
15
|
+
#ignore upstream gems
|
16
|
+
return true if gem.origin == gem.gems_url
|
17
|
+
open("gemversions.txt", "a") do |f|
|
18
|
+
if ! (license = gem.license)
|
19
|
+
license = get_license_string( gem.name, gem.version.to_s)
|
20
|
+
end
|
21
|
+
f.puts "#{gem.name} #{gem.version} #{license}"
|
18
22
|
end
|
19
|
-
|
23
|
+
return true
|
20
24
|
end
|
21
|
-
return true
|
22
|
-
end
|
23
25
|
|
24
|
-
|
26
|
+
private
|
27
|
+
|
28
|
+
def get_license_string(name, version)
|
29
|
+
return "" if ! @licenses[name]
|
30
|
+
return "#{@licenses[name][version]}*" if @licenses[name][version]
|
31
|
+
return "#{@licenses[name].sort.last.join("->")}**"
|
32
|
+
end
|
25
33
|
|
26
|
-
def get_license_string(name, version)
|
27
|
-
return "" if ! @licenses[name]
|
28
|
-
return "#{@licenses[name][version]}*" if @licenses[name][version]
|
29
|
-
return "#{@licenses[name].sort.last.join("->")}**"
|
30
34
|
end
|
31
35
|
|
32
36
|
end
|
@@ -1,53 +1,56 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
1
|
+
module GemsStatus
|
2
|
+
|
3
|
+
class ScmCheckMessages
|
4
|
+
MAX_RETRIES = 3
|
5
|
+
|
6
|
+
def check_messages(name, source_repo, message_checker, origin, counter = 0)
|
7
|
+
begin
|
8
|
+
messages = messages(name, source_repo)
|
9
|
+
return security_alerts(name, messages, message_checker, origin)
|
10
|
+
rescue => e
|
11
|
+
if counter == MAX_RETRIES
|
12
|
+
Utils::log_error name, "There was a problem checking out #{source_repo} #{e}"
|
13
|
+
return {}
|
14
|
+
else
|
15
|
+
Utils::log_debug "There was a problem checking out #{source_repo} #{e}: Trying it again..."
|
16
|
+
return check_messages(name, source_repo, message_checker, origin, counter + 1)
|
17
|
+
end
|
15
18
|
end
|
16
19
|
end
|
17
|
-
end
|
18
20
|
|
19
|
-
private
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
21
|
+
private
|
22
|
+
|
23
|
+
def security_alerts(name, commits, message_checker, origin)
|
24
|
+
results = {}
|
25
|
+
commits.each do |commit|
|
26
|
+
if message_checker.check_message?(message(commit))
|
27
|
+
Utils::log_debug "#{message(commit)}"
|
28
|
+
key = "#{name}_#{origin}_#{commit_key(commit)}"
|
29
|
+
if !key
|
30
|
+
Utils::log_error "no key for #{name}"
|
31
|
+
next
|
32
|
+
end
|
33
|
+
Utils::log_debug "security key: #{key}"
|
34
|
+
results[key] = SecurityAlert.new(message(commit), date(commit))
|
30
35
|
end
|
31
|
-
Utils::log_debug "security key: #{key}"
|
32
|
-
results[key] = SecurityAlert.new(message(commit), date(commit))
|
33
36
|
end
|
37
|
+
return results
|
34
38
|
end
|
35
|
-
return results
|
36
|
-
end
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
def commit_key(commit)
|
41
|
+
raise NotImplementedError
|
42
|
+
end
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
44
|
+
def message(commit)
|
45
|
+
raise NotImplementedError
|
46
|
+
end
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
def messages(name, source_repo)
|
49
|
+
raise NotImplementedError
|
50
|
+
end
|
49
51
|
|
50
|
-
|
51
|
-
|
52
|
+
def date(commit)
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
52
55
|
end
|
53
56
|
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module GemsStatus
|
2
|
+
class ScmSecurityMessages
|
3
|
+
def check_message?(msg)
|
4
|
+
return msg =~ /\b(XSS|CSRF|cross-site|cross site|crosssite|injection|forgery|traversal|CVE|unsafe|vulnerab|risk|security|Malicious|DoS)\b/i
|
5
|
+
end
|
4
6
|
end
|
5
7
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module GemsStatus
|
2
|
+
class SecurityAlert
|
3
|
+
attr_accessor :desc, :date
|
4
|
+
def initialize(desc, date = nil)
|
5
|
+
@desc = desc
|
6
|
+
@date = date
|
7
|
+
end
|
6
8
|
end
|
7
9
|
end
|
@@ -1,39 +1,42 @@
|
|
1
1
|
require "gems-status/checkers/scm_check_messages"
|
2
2
|
|
3
|
-
|
3
|
+
module GemsStatus
|
4
4
|
|
5
|
-
|
5
|
+
class SvnCheckMessages < ScmCheckMessages
|
6
6
|
|
7
|
-
|
8
|
-
return commit
|
9
|
-
end
|
7
|
+
private
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
`svn checkout #{source_repo}`
|
9
|
+
def message(commit)
|
10
|
+
return commit
|
14
11
|
end
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
|
13
|
+
def messages(name, source_repo)
|
14
|
+
if ! File.exists?(svn_dir(source_repo))
|
15
|
+
`svn checkout #{source_repo}`
|
16
|
+
end
|
17
|
+
Dir.chdir(svn_dir(source_repo)) do
|
18
|
+
`svn update`
|
19
|
+
log_messages = `svn log`
|
20
|
+
return log_messages.split("------------------------------------------------------------------------")
|
21
|
+
end
|
19
22
|
end
|
20
|
-
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
def commit_key(commit)
|
25
|
+
if commit.split("|").length == 0
|
26
|
+
Utils::log_error("no key for commit #{commit}")
|
27
|
+
return nil
|
28
|
+
end
|
29
|
+
return commit.split("|")[0].strip
|
26
30
|
end
|
27
|
-
return commit.split("|")[0].strip
|
28
|
-
end
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
def svn_dir(source_repo)
|
33
|
+
source_repo_splitted = URI.parse(source_repo).path.split("/")
|
34
|
+
return source_repo_splitted[-1]
|
35
|
+
end
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
def date(commit)
|
38
|
+
nil
|
39
|
+
end
|
38
40
|
|
41
|
+
end
|
39
42
|
end
|
@@ -1,51 +1,53 @@
|
|
1
|
-
|
2
|
-
attr_reader :name, :version, :md5, :origin, :gems_url, :dependencies
|
3
|
-
def initialize(name, version, md5, origin, gems_url=nil, dependencies = nil )
|
4
|
-
@name = name
|
5
|
-
@version = version
|
6
|
-
@md5 = md5
|
7
|
-
@origin = origin
|
8
|
-
@gems_url = gems_url
|
9
|
-
@dependencies = dependencies
|
10
|
-
end
|
1
|
+
module GemsStatus
|
11
2
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
3
|
+
class GemSimple
|
4
|
+
attr_reader :name, :version, :md5, :origin, :gems_url, :dependencies
|
5
|
+
def initialize(name, version, md5, origin, gems_url=nil, dependencies = nil )
|
6
|
+
@name = name
|
7
|
+
@version = version
|
8
|
+
@md5 = md5
|
9
|
+
@origin = origin
|
10
|
+
@gems_url = gems_url
|
11
|
+
@dependencies = dependencies
|
17
12
|
end
|
18
|
-
@dependencies.each do |dep|
|
19
|
-
return true if dep.name == gem.name
|
20
|
-
end
|
21
|
-
return false
|
22
|
-
end
|
23
13
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
14
|
+
#TODO: write a test for this
|
15
|
+
def depends?(gem)
|
16
|
+
if !@dependencies
|
17
|
+
Utils::log_error(@name, "trying to get depends on a gem that has no info on dependencies #{@name} depends #{gem.name}")
|
18
|
+
return false
|
19
|
+
end
|
20
|
+
@dependencies.each do |dep|
|
21
|
+
return true if dep.name == gem.name
|
22
|
+
end
|
28
23
|
return false
|
29
24
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@dependencies
|
35
|
-
|
25
|
+
|
26
|
+
#TODO: write a test for this
|
27
|
+
def merge_deps(gem)
|
28
|
+
if !@dependencies || !gem.dependencies
|
29
|
+
Utils::log_error(@name, "trying to merge depends on a gem that has no info on dependencies #{@name} merge #{gem.name}")
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
changes = false
|
33
|
+
gem.dependencies.each do |dep|
|
34
|
+
if !@dependencies.include?(dep)
|
35
|
+
changes = true
|
36
|
+
@dependencies << dep
|
37
|
+
Utils::log_debug("adding #{dep} to dependencies")
|
38
|
+
end
|
36
39
|
end
|
40
|
+
return changes
|
37
41
|
end
|
38
|
-
return changes
|
39
|
-
end
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
-
|
43
|
+
def from_git?
|
44
|
+
return @gems_url && @gems_url.start_with?("git://")
|
45
|
+
end
|
44
46
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
def date
|
48
|
+
Utils::log_error(@name, "I do not know when #{@name} was released")
|
49
|
+
nil
|
50
|
+
end
|
49
51
|
|
52
|
+
end
|
50
53
|
end
|
51
|
-
|