howsigned 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 77c7733a7eb4f7222794acebc50b9e614aef192c
4
- data.tar.gz: dfd7b37353b73ad63700fca6cdc78d8a16b7485b
3
+ metadata.gz: 39da123c01e7a3a8e46966e6b8b503d72491178e
4
+ data.tar.gz: e804e937c4be505827b3b105a3ffa22d35d4fea2
5
5
  SHA512:
6
- metadata.gz: 1f981d6e4808f0ab3eb7f4656efd9f60ac6d3c18bd836380534f181f318be36bc82ea747d33f781cf352006e6104ef034aeeb4dbc75bbb386b2cd917304ccf47
7
- data.tar.gz: ecfedbb1c4a046598d671dec865251e66834ab2e5a86f7d7f14d62ad1be597c8766faa00a37e832451a6574036c07a981f65673174bcabb62eb2718da6f7ec4b
6
+ metadata.gz: 6027d20b39f6940b005b23ff8db9a29a48f505bbdb2e88bbd59451a4d04d430f612e267b54212d39933bb9865987aaa83eddb13ecd5ac327496fe969dd166aca
7
+ data.tar.gz: e88ac8a53c40c1c00c8b689c8119377e80b08c70eeadf023cfbfc536aff4246d02a46fa16992fdcebf0ad97eca5cd925403b0fea0f9ecc642c5c3134ee47f353
data/bin/howsigned CHANGED
@@ -1,45 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # Heavily inspired by Shenzhen's `ipa info`
4
- # https://github.com/nomad/shenzhen/blob/master/lib/shenzhen/commands/info.rb
3
+ require 'rubygems'
4
+ require 'commander/import'
5
5
 
6
- require 'plist'
7
- require 'zip'
8
- require 'zip/filesystem'
6
+ require 'entitlements'
7
+ require 'profiles'
8
+ require 'verify'
9
9
 
10
- def validate_ipa!
11
- files = Dir['*.ipa']
12
- @file ||= case files.length
13
- when 0 then nil
14
- when 1 then files.first
15
- else
16
- @file = choose "Select an .ipa", *files
17
- end
18
- end
19
-
20
- validate_ipa! unless @file = ARGV[0]
21
- puts "Missing or unspecified .ipa file" and abort unless @file and ::File.exist?(@file)
22
-
23
- tempdir = ::File.new(Dir.mktmpdir)
24
- unzip = `unzip "#{@file}" -d "#{tempdir.path}"`
25
-
26
- entitlements_hash = Hash.new
27
-
28
- # .app
29
- Dir.glob("#{tempdir.path}/**/*.app") do |file|
30
- entitlements = `codesign -d --entitlements :- "#{file}" 2>&1`
31
- plist_entitlements = Plist::parse_xml(entitlements)
32
- application_identifier = plist_entitlements["application-identifier"]
33
- entitlements_hash[application_identifier] = plist_entitlements
34
- end
35
-
36
- # .appex
37
- Dir.glob("#{tempdir.path}/**/*.appex") do |file|
38
- entitlements = `codesign -d --entitlements :- "#{file}" 2>&1`
39
- plist_entitlements = Plist::parse_xml(entitlements)
40
- application_identifier = plist_entitlements["application-identifier"]
41
- entitlements_hash[application_identifier] = plist_entitlements
42
- end
43
-
44
- puts entitlements_hash.to_plist
10
+ program :version, '0.0.4'
11
+ program :description, 'Utility to determine codesigning on contained binaries in an .ipa'
45
12
 
@@ -0,0 +1,38 @@
1
+ # Heavily inspired by Shenzhen's `ipa info`
2
+ # https://github.com/nomad/shenzhen/blob/master/lib/shenzhen/commands/info.rb
3
+
4
+ require 'plist'
5
+ require 'zip'
6
+ require 'zip/filesystem'
7
+ require 'validate_ipa'
8
+ require 'extract_zip'
9
+
10
+ def append_entitlements(path, entitlements_hash)
11
+ Dir.glob(path) do |file|
12
+ entitlements = `codesign -d --entitlements :- "#{file}" 2>&1`
13
+ plist_entitlements = Plist::parse_xml(entitlements)
14
+ application_identifier = plist_entitlements["application-identifier"]
15
+ entitlements_hash[application_identifier] = plist_entitlements
16
+ end
17
+ end
18
+
19
+ command :entitlements do |c|
20
+ c.syntax = 'howsigned entitlements [.ipa file]'
21
+ c.description = 'Prints entitlements of specified .ipa in plist format'
22
+ c.action do |args, options|
23
+ validate_ipa! unless @file = args.pop
24
+ puts "Missing or unspecified .ipa file" and abort unless @file and ::File.exist?(@file)
25
+
26
+ tempdir = ::File.new(Dir.mktmpdir)
27
+ extract_zip(@file, tempdir)
28
+
29
+ entitlements_hash = Hash.new
30
+
31
+ append_entitlements("#{tempdir.path}/**/*.app", entitlements_hash)
32
+ append_entitlements("#{tempdir.path}/**/*.appex", entitlements_hash)
33
+
34
+ puts entitlements_hash.to_plist
35
+ end
36
+ end
37
+
38
+
@@ -0,0 +1,12 @@
1
+ require 'zip'
2
+
3
+ def extract_zip(file, destination)
4
+ FileUtils.mkdir_p(destination)
5
+
6
+ Zip::File.open(file) do |zip_file|
7
+ zip_file.each do |f|
8
+ fpath = File.join(destination, f.name)
9
+ zip_file.extract(f, fpath) unless File.exist?(fpath)
10
+ end
11
+ end
12
+ end
data/lib/profiles.rb ADDED
@@ -0,0 +1,33 @@
1
+ require 'plist'
2
+ require 'zip'
3
+ require 'zip/filesystem'
4
+ require 'validate_ipa'
5
+ require 'extract_zip'
6
+
7
+ def get_profiles(path)
8
+ profiles = Hash.new
9
+ Dir.glob(path) do |file|
10
+ profile = `security cms -D -i "#{file}" 2>&1`
11
+ plist_profile = Plist::parse_xml(profile)
12
+ app_id = plist_profile["AppIDName"]
13
+ profiles[app_id] = plist_profile
14
+ end
15
+
16
+ return profiles.to_plist
17
+ end
18
+
19
+ command :profiles do |c|
20
+ c.syntax = 'howsigned profiles [.ipa file]'
21
+ c.description = 'Prints embedded profiles of specified .ipa in plist format'
22
+ c.action do |args, options|
23
+ validate_ipa! unless @file = args.pop
24
+ puts "Missing or unspecified .ipa file" and abort unless @file and ::File.exist?(@file)
25
+
26
+ tempdir = ::File.new(Dir.mktmpdir)
27
+ extract_zip(@file, tempdir)
28
+
29
+ puts get_profiles("#{tempdir.path}/**/*.mobileprovision")
30
+ end
31
+ end
32
+
33
+
@@ -0,0 +1,9 @@
1
+ def validate_ipa!
2
+ files = Dir['*.ipa']
3
+ @file ||= case files.length
4
+ when 0 then nil
5
+ when 1 then files.first
6
+ else
7
+ @file = choose "Select an .ipa", *files
8
+ end
9
+ end
data/lib/verify.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'plist'
2
+ require 'zip'
3
+ require 'zip/filesystem'
4
+ require 'validate_ipa'
5
+ require 'extract_zip'
6
+
7
+ def verify_binaries(path)
8
+ Dir.glob(path) do |file|
9
+ codesign = `codesign --verify "#{file}" 2>&1`
10
+ if(!codesign.to_s.empty?)
11
+ puts codesign
12
+ end
13
+ end
14
+ end
15
+
16
+ command :verify do |c|
17
+ c.syntax = 'howsigned verify [.ipa file]'
18
+ c.description = 'Verifies the code signature of all binaries contained within the .ipa, will return nothing if signed correctly'
19
+ c.action do |args, options|
20
+ validate_ipa! unless @file = args.pop
21
+ puts "Missing or unspecified .ipa file" and abort unless @file and ::File.exist?(@file)
22
+
23
+ tempdir = ::File.new(Dir.mktmpdir)
24
+ extract_zip(@file, tempdir)
25
+
26
+ entitlements_hash = Hash.new
27
+
28
+ app_codesign = verify_binaries("#{tempdir.path}/**/*.app")
29
+ if(!app_codesign.to_s.empty?)
30
+ puts app_codesign
31
+ end
32
+
33
+ appex_codesign = verify_binaries("#{tempdir.path}/**/*.appex")
34
+ if(!appex_codesign.to_s.empty?)
35
+ puts appex_codesign
36
+ end
37
+ end
38
+ end
39
+
40
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: howsigned
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael MacDougall
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: commander
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.3'
41
55
  description: Utility to see how the contained binaries within an .ipa are signed
42
56
  email: mmacdougall@etsy.com
43
57
  executables:
@@ -46,6 +60,11 @@ extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
48
62
  - bin/howsigned
63
+ - lib/entitlements.rb
64
+ - lib/extract_zip.rb
65
+ - lib/profiles.rb
66
+ - lib/validate_ipa.rb
67
+ - lib/verify.rb
49
68
  homepage: http://www.etsy.com
50
69
  licenses:
51
70
  - MIT