enzoic 1.2.0 → 1.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2af7917c4ee90414cdffeda3948ce2a0642f523f6c44fe07db64deab4f5b6e25
4
- data.tar.gz: 4cdfeb61e75c47f95132e9a0c644f89a987597a48685038ac7308dba66e008ee
3
+ metadata.gz: d13fca15fa76f249a013adea0bac59023d847f8021bfe16748999ff0f5d26e52
4
+ data.tar.gz: a64b16ddd1f5ae4eb7dbdf97672c9a36958ae4099698181f47d88a815626d01e
5
5
  SHA512:
6
- metadata.gz: 557fadc6dab20d5d76d2098466c31728ecba0a1fcd16ce9cd13a798817239bb791012691b37130b7e64dd7275728d83c9f89bdfeda10dbde0b369faf705f8ecf
7
- data.tar.gz: 420af16ed93a7696969a74fbfcd13e491e23f934a9f15712fe42fc3eb777e6cdcf51751ac4ebc2bfa28b250fc7d17c3107f10989a524c4f1779811254423cc50
6
+ metadata.gz: cf9305fce6e41d506b445c8e3b17b7ffea8e816482ace8d872dc1a464c260d1b25bbb3d81e88534c2d6bb6a084bb5c0bded0dbfb76cd494a98cfb1d7dbfaeb01
7
+ data.tar.gz: 6aa0dfb06cfbeda5f130a92c77dcb51b36874b0aea2eb128d25c5dc91e033c56228a8af1cbf9b739f4ce9ea494a52e1aa6068b455f2d695b36036cecc58d0995
data/README.md CHANGED
@@ -35,7 +35,8 @@ require 'enzoic'
35
35
  enzoic = Enzoic::Enzoic.new(apiKey: YOUR_API_KEY, secret: YOUR_API_SECRET)
36
36
 
37
37
  # Check whether a password has been compromised
38
- # see https://www.enzoic.com/docs-passwords-api/ for more information
38
+ # for more information, see
39
+ # https://docs.enzoic.com/enzoic-api-developer-documentation/api-reference/passwords-api
39
40
  if enzoic.check_password("password-to-test")
40
41
  puts("Password is compromised")
41
42
  else
@@ -43,7 +44,8 @@ else
43
44
  end
44
45
 
45
46
  # Check whether a specific set of credentials are compromised
46
- # see https://www.enzoic.com/docs-credentials-api/ for more information
47
+ # for more information, see
48
+ # https://docs.enzoic.com/enzoic-api-developer-documentation/api-reference/credentials-api/hashed-credentials-api
47
49
  if enzoic.check_credentials("test@enzoic.com", "password-to-test")
48
50
  puts("Credentials are compromised")
49
51
  else
@@ -63,18 +65,21 @@ else
63
65
  end
64
66
 
65
67
  # get all exposures for a given user
66
- # see https://www.enzoic.com/docs-exposures-api/#get-exposures for more information
68
+ # for more information, see
69
+ # https://docs.enzoic.com/enzoic-api-developer-documentation/api-reference/exposures-api/get-exposures-for-an-email-address
67
70
  exposures = enzoic.get_exposures_for_user("test@enzoic.com")
68
71
  puts(exposures.count.to_s + " exposures found for test@enzoic.com")
69
72
 
70
73
  # now get the full details for the first exposure found
71
- # see https://www.enzoic.com/docs-exposures-api/#get-exposure-details for more information
74
+ # for more information, see
75
+ # https://docs.enzoic.com/enzoic-api-developer-documentation/api-reference/exposures-api/retrieve-details-for-an-exposure
72
76
  details = enzoic.get_exposure_details(exposures.exposures[0])
73
77
  puts("First exposure for test@enzoic.com was " + details.title)
74
78
 
75
79
  # get all passwords for a given user - requires special approval, contact Enzoic sales
76
- # see https://www.enzoic.com/docs-raw-passwords-api/ for more information
77
- user_passwords = enzoic.get_passwords_for_user("eicar_0@enzoic.com")
80
+ # for more information, see
81
+ # https://docs.enzoic.com/enzoic-api-developer-documentation/api-reference/credentials-api/cleartext-credentials-api
82
+ user_passwords = enzoic.get_passwords_for_user("eicar_0@enzoic.com", true)
78
83
  puts("First password for eicar_0@enzoic.com was " + user_passwords.passwords[0].password)
79
84
 
80
85
  ```
data/enzoic.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.bindir = "exe"
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
- spec.add_dependency 'ffi', '~> 1.11.1'
23
+ spec.add_dependency 'ffi', '~> 1.15.5'
24
24
  spec.add_dependency 'ffi-compiler', '~> 1.0.1'
25
25
  spec.add_dependency 'rest-client', '~> 2.0', '>= 2.0.2'
26
26
  spec.add_dependency 'bcrypt', '~> 3.1', '>= 3.1.11'
@@ -3,7 +3,8 @@ require 'digest'
3
3
  require 'bcrypt'
4
4
  require 'unix_crypt'
5
5
  require 'zlib'
6
- require 'digest/whirlpool'
6
+ require 'digest/whirlpool.bundle'
7
+ #require 'open_ssl'
7
8
  require 'base64url'
8
9
 
9
10
  module Enzoic
@@ -272,24 +273,47 @@ module Enzoic
272
273
  return result
273
274
  end
274
275
 
276
+ def self.sha256crypt(to_hash, salt)
277
+ return self.sha_crypt("5", UnixCrypt::SHA256, to_hash, salt)
278
+ end
279
+
275
280
  def self.sha512crypt(to_hash, salt)
276
- return UnixCrypt::SHA512.build(to_hash, salt.start_with?("$6$") ? salt[3..salt.length] : salt)
281
+ return self.sha_crypt("6", UnixCrypt::SHA512, to_hash, salt)
282
+ end
283
+
284
+ def self.sha_crypt(crypt_version, crypter, to_hash, salt)
285
+ # special handling if the salt contains an embedded rounds specifier
286
+ if salt.start_with?("$" + crypt_version + "$") && salt.include?("$rounds=")
287
+ # extract rounds
288
+ rounds_starting_idx = salt.index("$rounds=") + 8
289
+ rounds = salt[rounds_starting_idx..salt.length]
290
+ salt_portion = rounds[rounds.index("$") + 1..rounds.length]
291
+
292
+ begin
293
+ rounds = Integer(rounds[0..rounds.index("$") - 1])
294
+ rescue ArgumentError
295
+ rounds = 5000
296
+ end
297
+
298
+ result = crypter.build(to_hash, salt_portion, rounds)
299
+
300
+ # if the default rounds of 5000 was used, add this back in to the resultant hash as this library, unlike most,
301
+ # will strip it out.
302
+ if rounds == 5000
303
+ result = result[0..2] + "rounds=5000$" + result[3..result.length]
304
+ end
305
+
306
+ return result
307
+ end
308
+ return crypter.build(to_hash, salt.start_with?("$" + crypt_version + "$") ? salt[3..salt.length] : salt)
277
309
  end
278
310
 
279
311
  def self.custom_algorithm10(to_hash, salt)
280
312
  return self.sha512(to_hash + ":" + salt)
281
313
  end
282
314
 
283
- def self.sha256crypt(to_hash, salt)
284
- salt_to_use = salt
285
- if salt_to_use.start_with?("$5$")
286
- salt_to_use = salt_to_use[3..salt.length];
287
- end
288
- if salt_to_use.start_with?("rounds=")
289
- salt_to_use = salt_to_use[salt_to_use.index("$") + 1..salt_to_use.length]
290
- end
291
-
292
- return UnixCrypt::SHA256.build(to_hash, salt_to_use)
315
+ def self.hmac_sha1_salt_as_hash(to_hash, salt)
316
+ return OpenSSL::HMAC.hexdigest("sha1", salt, to_hash)
293
317
  end
294
318
 
295
319
  def self.authMeSHA256(to_hash, salt)
@@ -41,8 +41,9 @@ module Enzoic
41
41
  CustomAlgorithm9 = 38
42
42
  SHA512Crypt = 39
43
43
  CustomAlgorithm10 = 40
44
- SHA256Crypt = 41
44
+ HMACSHA1_SaltAsHash = 41
45
45
  AuthMeSHA256 = 42
46
+ SHA256Crypt = 43
46
47
 
47
48
  Unknown = 97
48
49
  UnusablePassword = 98
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  # Standard Gem version constant.
3
3
  module Enzoic
4
- VERSION = "1.2.0".freeze
4
+ VERSION = "1.4.0".freeze
5
5
  end
data/lib/enzoic.rb CHANGED
@@ -138,9 +138,10 @@ module Enzoic
138
138
  end
139
139
  end
140
140
 
141
- def get_passwords_for_user(username)
141
+ def get_passwords_for_user(username, include_exposure_details = false)
142
142
  response = make_rest_call(@baseURL + Constants::ACCOUNTS_API_PATH + "?username=" +
143
- Hashing.sha256(username.downcase) + "&includePasswords=1",
143
+ Hashing.sha256(username.downcase) + "&includePasswords=1" +
144
+ (include_exposure_details ? "&includeExposureDetails=1" : ""),
144
145
  "GET", nil)
145
146
 
146
147
  if response == "404"
@@ -301,6 +302,10 @@ module Enzoic
301
302
  if salt != nil && salt.length > 0
302
303
  return Hashing.authMeSHA256(password, salt)
303
304
  end
305
+ when PasswordType::HMACSHA1_SaltAsHash
306
+ if salt != nil && salt.length > 0
307
+ return Hashing.hmac_sha1_salt_as_hash(password, salt)
308
+ end
304
309
  else
305
310
  return nil
306
311
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enzoic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Enzoic
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-22 00:00:00.000000000 Z
11
+ date: 2023-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.11.1
19
+ version: 1.15.5
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.11.1
26
+ version: 1.15.5
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ffi-compiler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -116,20 +116,20 @@ dependencies:
116
116
  name: bundler
117
117
  requirement: !ruby/object:Gem::Requirement
118
118
  requirements:
119
- - - ">="
119
+ - - "~>"
120
120
  - !ruby/object:Gem::Version
121
121
  version: 2.2.11
122
- - - "~>"
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: 2.2.11
125
125
  type: :development
126
126
  prerelease: false
127
127
  version_requirements: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
129
+ - - "~>"
130
130
  - !ruby/object:Gem::Version
131
131
  version: 2.2.11
132
- - - "~>"
132
+ - - ">="
133
133
  - !ruby/object:Gem::Version
134
134
  version: 2.2.11
135
135
  - !ruby/object:Gem::Dependency
@@ -361,7 +361,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
361
361
  - !ruby/object:Gem::Version
362
362
  version: '0'
363
363
  requirements: []
364
- rubygems_version: 3.0.3.1
364
+ rubygems_version: 3.1.6
365
365
  signing_key:
366
366
  specification_version: 4
367
367
  summary: Ruby library for Enzoic API