howsigned 0.0.2 → 0.0.4

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