dmp 0.2.2 → 0.2.3
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +20 -15
- data/images/dmp.gif +0 -0
- data/lib/dmp.rb +28 -21
- data/lib/dmp/cli.rb +37 -39
- data/lib/dmp/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c9dd7398d91356cc90ab8d3d0add83edc0d50d45663a811d6121d0c16cde8b8
|
4
|
+
data.tar.gz: b60f942b8c163e50ab11e713fc4740fb29ae3c19e4fc9ed75398223b22a75525
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf84ddb9185de60859708642a2773cf7a38a87f2dd80e0c6540f209ac194e2556fcc601c74d251e4e9db1ccb36a7c2eb1a577d4167211fda3c648d87b68ed16c
|
7
|
+
data.tar.gz: 83f6b8e648e564ca1b7c80979a6c9167228f0c18f940474f416941f94970a632973b326a7bd426f31bee12823721b5c7456991aeacba47f9f00dbcebcbb6ea93
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,19 +3,9 @@
|
|
3
3
|
|
4
4
|
**DMP** (or _Dice My Pass_) is a simple passphrase generator that gives you a passphrase of the desired length using [EFF's long wordlist](http://eff.org/dice). **This little tool was only created for a blog post on how to create a Ruby gem at codingdose.info (WIP) and should be NOT used for production**, can't say much if you like it though.
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
| _ \ | \/ | | _ \
|
10
|
-
| | | | | |\/| | | |_) |
|
11
|
-
| |_| | | | | | | __/
|
12
|
-
|____/ |_| |_| |_|
|
13
|
-
|
14
|
-
version: 0.2.2
|
15
|
-
author: @__franccesco
|
16
|
-
homepage: https://github.com/franccesco/dmp
|
17
|
-
learn more: https://codingdose.info
|
18
|
-
```
|
6
|
+
<p align="center">
|
7
|
+
<img src="images/dmp.gif" />
|
8
|
+
</p>
|
19
9
|
|
20
10
|
## Installation
|
21
11
|
|
@@ -57,16 +47,31 @@ $ dmp
|
|
57
47
|
- Copied to clipboard.
|
58
48
|
```
|
59
49
|
|
60
|
-
**Generate a passphrase of your desired length**
|
50
|
+
**Generate a passphrase of your desired length and check if the password appears in HIBP datasets**
|
61
51
|
```
|
62
|
-
$ dmp gen 5
|
52
|
+
$ dmp gen 5 -H
|
63
53
|
- Passphrase: tavern silly afar luncheon cement
|
54
|
+
- Password is safe to use.
|
55
|
+
```
|
56
|
+
|
57
|
+
**Warns you if your password has been discovered in a HIBP dataset.**
|
58
|
+
```
|
59
|
+
- Passphrase: angular
|
60
|
+
- WARNING: Passphrase vulnerable 91 times!
|
61
|
+
```
|
62
|
+
**Check a password of yours**
|
63
|
+
```
|
64
|
+
$ dmp check
|
65
|
+
Enter your password, press ENTER when you're done.
|
66
|
+
Password (hidden): ****
|
67
|
+
- Your password appears in 213580 data sets!
|
64
68
|
```
|
65
69
|
|
66
70
|
**Help**
|
67
71
|
```
|
68
72
|
Commands:
|
69
73
|
dmp about # Displays version number and information
|
74
|
+
dmp check # Check if a password/passphrase is vulnerable.
|
70
75
|
dmp gen [length] # Generate a passphrase of the desired length.
|
71
76
|
dmp help [COMMAND] # Describe available commands or one specific command
|
72
77
|
```
|
data/images/dmp.gif
ADDED
Binary file
|
data/lib/dmp.rb
CHANGED
@@ -2,37 +2,44 @@ require 'dmp/version'
|
|
2
2
|
require 'net/http'
|
3
3
|
require 'digest/sha1'
|
4
4
|
|
5
|
-
# Module to manage DMP operations
|
6
5
|
module Dmp
|
6
|
+
# Module to manage DMP operations.
|
7
|
+
# gen_passphrase generates a new passphrase of a desired length.
|
8
|
+
# check_pwned checks the password string against the HIBP datasets.
|
7
9
|
# default wordlist provided by EFF https://www.eff.org/dice
|
8
10
|
@eff_wordlist = File.dirname(__FILE__) + '/dmp/assets/eff_long_wordlist.txt'
|
9
11
|
|
10
12
|
def self.gen_passphrase(pass_length = 7)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
# randomize wordlist and strip it to the desired length
|
16
|
-
random_pass = pass_list.shuffle[0...pass_length]
|
17
|
-
random_pass
|
13
|
+
wordlist = File.readlines(@eff_wordlist)
|
14
|
+
wordlist.map(&:strip!)
|
15
|
+
wordlist.shuffle[0...pass_length]
|
18
16
|
end
|
19
17
|
|
20
18
|
def self.check_pwned(passphrase)
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
# This module follows the k-Anonymity principle described in
|
20
|
+
# https://haveibeenpwned.com/API/v2#PwnedPasswords
|
21
|
+
# that allows you to search for the first 5 characters of the hash and
|
22
|
+
# returns a list of hashes for you to search the rest of the hash locally,
|
23
|
+
# followed by the number of times the hash appears in a data set
|
24
|
+
# e.g: 0018A45C4D1DEF81644B54AB7F969B88D65:21
|
25
|
+
passphrase = passphrase.join(' ') if passphrase.is_a?(Array)
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
sha1_pass = Digest::SHA1.hexdigest(passphrase)
|
28
|
+
sha1_excerpt = sha1_pass[0...5]
|
29
|
+
sha1_to_look_for = sha1_pass[5..-1]
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
req = Net::HTTP.get(uri)
|
31
|
+
api_url = URI("https://api.pwnedpasswords.com/range/#{sha1_excerpt}")
|
32
|
+
api_request = Net::HTTP.get(api_url)
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
# Response is text instead of JSON, needs to format the response
|
35
|
+
# to a dictionary so the rest of the hash can be located easier.
|
36
|
+
# => String '0018A45C4D1DEF81644B54AB7F969B88D65:21'
|
37
|
+
# => Array ['0018A45C4D1DEF81644B54AB7F969B88D65:21', ...]
|
38
|
+
# => 2D Array [['0018A45C4D1DEF81644B54AB7F969B88D65', '21'], ...]
|
39
|
+
# => Hash {'0018A45C4D1DEF81644B54AB7F969B88D65': 21, ...}
|
40
|
+
striped_list = api_request.split("\r\n")
|
41
|
+
pass_list = striped_list.map { |hash| hash.split(':') }
|
42
|
+
hash_list = Hash[*pass_list.flatten!]
|
43
|
+
hash_list[sha1_to_look_for.upcase]
|
37
44
|
end
|
38
45
|
end
|
data/lib/dmp/cli.rb
CHANGED
@@ -7,6 +7,16 @@ module Dmp
|
|
7
7
|
# Command line interface for DMP
|
8
8
|
class CLI < Thor
|
9
9
|
default_task :gen_pass
|
10
|
+
|
11
|
+
# Define option 'gen' that accepts a flag to copy to clipboard ('-c')
|
12
|
+
# and another one to check the generated password agains HIBP ('-H')
|
13
|
+
# This argument is the default task and it generates a 7 passphrase lenght.
|
14
|
+
# Usage:
|
15
|
+
# $ dmp gen [optional_length] [optional flags]
|
16
|
+
# Example:
|
17
|
+
# $ dmp gen 8 -c -H
|
18
|
+
# Or:
|
19
|
+
# $ dmp 8
|
10
20
|
desc 'gen [length]', 'Generate a passphrase of the desired length.'
|
11
21
|
method_option :clipboard,
|
12
22
|
aliases: '-c',
|
@@ -17,59 +27,47 @@ module Dmp
|
|
17
27
|
type: :boolean,
|
18
28
|
desc: 'Check if passphrase is vulnerable in HIBP database.'
|
19
29
|
def gen_pass(pass_length = 7)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# if flag clipboard is 'true' then copy passphrase to clipboard
|
24
|
-
if options[:clipboard]
|
25
|
-
Clipboard.copy(passphrase.join(' '))
|
26
|
-
end
|
30
|
+
new_passphrase = Dmp.gen_passphrase(pass_length.to_i)
|
31
|
+
Clipboard.copy(new_passphrase.join(' ')) if options[:clipboard]
|
32
|
+
dataset_count = Dmp.check_pwned(new_passphrase) if options[:hibp]
|
27
33
|
|
28
|
-
|
29
|
-
|
30
|
-
|
34
|
+
colors = String.colors
|
35
|
+
colors.delete(:black) # black color looks ugly in the terminal
|
36
|
+
new_passphrase.map! do |phrase|
|
37
|
+
random_color = colors.sample
|
38
|
+
phrase.colorize(random_color)
|
31
39
|
end
|
32
40
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
colors.delete(:black)
|
41
|
+
copy_msg = '- Copied to clipboard.'.bold.green
|
42
|
+
vuln_pass_msg = "- WARNING: Passphrase appears in #{dataset_count} datasets!".red.bold
|
43
|
+
safe_pass_msg = '- Password was not found in a dataset.'.green.bold
|
37
44
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
puts '- Passphrase: '.bold + passphrase.join(' ')
|
43
|
-
puts '- Copied to clipboard.'.bold.green if options[:clipboard]
|
44
|
-
if vuln_count
|
45
|
-
puts "- WARNING: Passphrase appears in #{vuln_count} datasets!".red.bold
|
46
|
-
elsif options[:hibp]
|
47
|
-
puts '- Password was not found in a dataset.'.green.bold
|
48
|
-
end
|
45
|
+
puts '- Passphrase: '.bold + new_passphrase.join(' ')
|
46
|
+
puts copy_msg if options[:clipboard]
|
47
|
+
puts dataset_count ? vuln_pass_msg : safe_pass_msg if options[:hibp]
|
49
48
|
end
|
50
49
|
|
50
|
+
# Check if passphrase or password is vulnerable interatively
|
51
|
+
# This feature disables echo to avoid making the password visible.
|
52
|
+
# This feature should not ask for the password in the terminal command line
|
53
|
+
# (e.g: dmp check password) as it would be visible in the terminal history.
|
54
|
+
# Usage:
|
55
|
+
# $ dmp check
|
51
56
|
desc 'check', 'Check if a password/passphrase is vulnerable.'
|
52
57
|
def check_pass
|
53
|
-
puts
|
58
|
+
puts "Enter your password, press ENTER when you're done."
|
54
59
|
password = ask('Password (hidden):'.yellow, echo: false)
|
60
|
+
(puts "Aborted.".red.bold; exit) if password.empty?
|
55
61
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
vuln_count = Dmp.check_pwned(password)
|
63
|
-
if vuln_count
|
64
|
-
puts " Your password appears in #{vuln_count} datasets!".red.bold
|
65
|
-
else
|
66
|
-
puts " Your password was not found in a dataset.".green.bold
|
67
|
-
end
|
62
|
+
dataset_count = Dmp.check_pwned(password)
|
63
|
+
vuln_msg = "Your password appears in #{dataset_count} datasets!".red.bold
|
64
|
+
safe_msg = "Your password was not found in a dataset.".green.bold
|
65
|
+
puts dataset_count ? vuln_msg : safe_msg
|
68
66
|
end
|
69
67
|
|
68
|
+
# Displays banner, version number and author
|
70
69
|
desc 'about', 'Displays version number and information'
|
71
70
|
def about
|
72
|
-
# Displays banner, version number and author
|
73
71
|
puts Dmp::BANNER.bold.red
|
74
72
|
puts 'version: '.bold + Dmp::VERSION.green
|
75
73
|
puts 'author: '.bold + '@__franccesco'.green
|
data/lib/dmp/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dmp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Franccesco Orozco
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -200,6 +200,7 @@ files:
|
|
200
200
|
- bin/setup
|
201
201
|
- dmp.gemspec
|
202
202
|
- exe/dmp
|
203
|
+
- images/dmp.gif
|
203
204
|
- lib/dmp.rb
|
204
205
|
- lib/dmp/assets/eff_long_wordlist.txt
|
205
206
|
- lib/dmp/cli.rb
|