personal_wordlist 0.1.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 +7 -0
- data/README.md +98 -0
- data/lib/personal_wordlist/dsl/partial.rb +21 -0
- data/lib/personal_wordlist/dsl/sequence.rb +25 -0
- data/lib/personal_wordlist/dsl.rb +23 -0
- data/lib/personal_wordlist/version.rb +3 -0
- data/lib/personal_wordlist.rb +32 -0
- data/personal_wordlist.gemspec +22 -0
- data/spec/dsl_spec.rb +46 -0
- data/spec/features_spec.rb +54 -0
- data/spec/personal_wordlist_spec.rb +16 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/support/people_helper.rb +5 -0
- metadata +74 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: ad270b79c7b8358f7bce982d8e5defc4136b8c5a
|
|
4
|
+
data.tar.gz: 309ec84e26bbb248e99635c8aaa6acab12cd9776
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: e41cc60360bf704cf4d540b23aac241e870f2502e9ef97a8e90f2ab755a4530574eb2213b56fdcf3c4c93f89b1f7e10f342648271bf0d82b5d120fb2bfa97d16
|
|
7
|
+
data.tar.gz: 64f036b8201f234344bbaa6d03ef0ffce62d117312bf05491e309aafad01c4a5a860281d263d222777bb569a288d60b69b9d25e960a9341997a01a8866ceb5cb
|
data/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# personal_wordlist
|
|
2
|
+
|
|
3
|
+
**personal_wordlist** is a wordlist generator backend to create wordlists from the given personal data. It is originally designed for security purposes.
|
|
4
|
+
|
|
5
|
+
personal_wordlist uses a simple DSL to create password patterns and those patterns are used to create password sequences.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```shell
|
|
10
|
+
gem install personal_wordlist
|
|
11
|
+
```
|
|
12
|
+
or add the following line to Gemfile:
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
gem 'personal_wordlist'
|
|
16
|
+
```
|
|
17
|
+
and run `bundle install` from your shell.
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
To start generating wordlists we need to use ```PersonalWordlist.generate``` method with a block.
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
PersonalWordlist.generate(personal_data) do
|
|
25
|
+
# DSL here
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```.generate``` method takes a Hash argument and returns and Array of strings.
|
|
31
|
+
|
|
32
|
+
### Partials
|
|
33
|
+
|
|
34
|
+
```partial``` is a string pattern and can be used to combine more complex strings.
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
partial { first_name[0..1] }
|
|
38
|
+
partial { '123' }
|
|
39
|
+
partial { last_name[0].downcase }
|
|
40
|
+
```
|
|
41
|
+
Consider the data is ```{ first_name: 'John', last_name: 'Doe' }``` and the result will be _Jo123d_.
|
|
42
|
+
|
|
43
|
+
### Sequences
|
|
44
|
+
|
|
45
|
+
```sequence```s are like loops in programming languages. sequence method requires a ```Range``` variable and a block.
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
sequence(1998..2011) do |n|
|
|
49
|
+
# string manupulation here
|
|
50
|
+
end
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
You can insert partials into sequences.
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
sequence(1998..2011) do |n|
|
|
57
|
+
partial { first_name.downcase }
|
|
58
|
+
partial { n.to_s }
|
|
59
|
+
end
|
|
60
|
+
```
|
|
61
|
+
And result becomes: _['john1998', 'john1999', 'john2000', ... 'john2011']_
|
|
62
|
+
|
|
63
|
+
When sequence is done iterating, the result is added to the returning array of strings. If you have multiple sequences, the results from each sequence will be concatenated.
|
|
64
|
+
|
|
65
|
+
### Example
|
|
66
|
+
```
|
|
67
|
+
personal_data = {
|
|
68
|
+
first_name: 'John', last_name: 'Doe',
|
|
69
|
+
date_of_birth: '1980-01-01', favorite_team: 'Galatasaray'
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
PersonalWordlist.generate(personal_data) do
|
|
73
|
+
sequence(0..999) do |n|
|
|
74
|
+
partial { first_name[0..2].downcase }
|
|
75
|
+
partial { n.to_s }
|
|
76
|
+
partial { last_name[0] }
|
|
77
|
+
end
|
|
78
|
+
sequence(0..999) do |n|
|
|
79
|
+
partial { first_name[0..2].downcase }
|
|
80
|
+
partial { n.to_s }
|
|
81
|
+
partial { last_name[0] }
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Future Plans
|
|
87
|
+
|
|
88
|
+
- CLI, I see that as a must.
|
|
89
|
+
- Input Data Adaptors, I am planning to create adaptors such as parsing yaml, xml, csv file to input hash format.
|
|
90
|
+
|
|
91
|
+
## Contribution
|
|
92
|
+
|
|
93
|
+
Contributing to factory_girl:
|
|
94
|
+
|
|
95
|
+
Fork the official repository.
|
|
96
|
+
Make your changes in a topic branch.
|
|
97
|
+
Send a pull request.
|
|
98
|
+
## Licence
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module PersonalWordlist
|
|
2
|
+
module DSL
|
|
3
|
+
# Evaluate of methods in `partial` blocks
|
|
4
|
+
class Partial
|
|
5
|
+
def initialize(personal_data, block)
|
|
6
|
+
@block = block
|
|
7
|
+
@personal_data = personal_data
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def run!
|
|
11
|
+
instance_eval(&@block)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Map unknown methods to known keys of the input hash
|
|
15
|
+
def method_missing(name)
|
|
16
|
+
return @personal_data[name.to_sym] if @personal_data.key?(name)
|
|
17
|
+
fail NoMethodError
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module PersonalWordlist
|
|
2
|
+
module DSL
|
|
3
|
+
# Creates sequences within given patterns
|
|
4
|
+
class Sequence
|
|
5
|
+
include PersonalWordlist::DSL
|
|
6
|
+
|
|
7
|
+
def initialize(personal_data, block, range)
|
|
8
|
+
@block = block
|
|
9
|
+
@personal_data = personal_data
|
|
10
|
+
@current_password = ''
|
|
11
|
+
@range = range || (0..1)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def run!
|
|
15
|
+
passwords = []
|
|
16
|
+
@range.to_a.each do |n|
|
|
17
|
+
# Reset the state of current_password
|
|
18
|
+
@current_password = ''
|
|
19
|
+
passwords << instance_exec(n, &@block)
|
|
20
|
+
end
|
|
21
|
+
passwords
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'personal_wordlist/dsl/partial'
|
|
2
|
+
require 'personal_wordlist/dsl/sequence'
|
|
3
|
+
|
|
4
|
+
module PersonalWordlist
|
|
5
|
+
# DSL Syntax Methods
|
|
6
|
+
module DSL
|
|
7
|
+
def partial(&block)
|
|
8
|
+
fail ArgumentError unless block_given?
|
|
9
|
+
@current_password += Partial.new(@personal_data, block).run!
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def sequence(range, &block)
|
|
13
|
+
fail ArgumentError unless block_given?
|
|
14
|
+
@passwords.concat Sequence.new(@personal_data, block, range).run!
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Map unknown methods to known keys of the input hash
|
|
18
|
+
def method_missing(name)
|
|
19
|
+
return @personal_data[name.to_sym] if @personal_data.key?(name)
|
|
20
|
+
fail NoMethodError
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'personal_wordlist/version'
|
|
2
|
+
require 'personal_wordlist/dsl'
|
|
3
|
+
|
|
4
|
+
##
|
|
5
|
+
# A wordlist generator. Uses simple DSL to define password generation rules.
|
|
6
|
+
module PersonalWordlist
|
|
7
|
+
class PersonalWordlistError < StandardError; end
|
|
8
|
+
class InvalidTemplateError < PersonalWordlistError; end
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
include PersonalWordlist::DSL
|
|
12
|
+
|
|
13
|
+
attr_reader :current_password
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# PersonalWorlList.password
|
|
17
|
+
def generate(personal_data, &block)
|
|
18
|
+
fail ArgumentError unless block_given?
|
|
19
|
+
|
|
20
|
+
# Set class variables
|
|
21
|
+
@personal_data = personal_data
|
|
22
|
+
@block = block
|
|
23
|
+
@current_password = ''
|
|
24
|
+
@passwords = []
|
|
25
|
+
|
|
26
|
+
result = instance_eval(&block)
|
|
27
|
+
|
|
28
|
+
# Ensure that result is always an Array
|
|
29
|
+
result.instance_of?(Array) ? @passwords = result : @passwords << result
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
$LOAD_PATH << File.expand_path('../lib', __FILE__)
|
|
2
|
+
require 'personal_wordlist/version'
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |s|
|
|
5
|
+
s.name = 'personal_wordlist'
|
|
6
|
+
s.version = PersonalWordlist::VERSION
|
|
7
|
+
s.date = '2015-01-18'
|
|
8
|
+
s.summary = 'Create wordlists from personal data.'
|
|
9
|
+
|
|
10
|
+
s.authors = ['Turhan Coskun']
|
|
11
|
+
s.email = 'turhancoskun@gmail.com'
|
|
12
|
+
|
|
13
|
+
s.files = `git ls-files`.split("\n").reject { |path| path =~ /\.gitignore$/ }
|
|
14
|
+
s.test_files = `git ls-files -- Appraisals {spec,features,gemfiles}/*`
|
|
15
|
+
.split("\n")
|
|
16
|
+
|
|
17
|
+
s.require_paths = ['lib']
|
|
18
|
+
s.required_ruby_version = Gem::Requirement.new('>= 1.9.2')
|
|
19
|
+
s.add_development_dependency('rspec')
|
|
20
|
+
|
|
21
|
+
s.license = 'MIT'
|
|
22
|
+
end
|
data/spec/dsl_spec.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
# Puppet class with minimum requirements to test the DSL
|
|
4
|
+
class TestClass
|
|
5
|
+
attr_accessor :current_password, :passwords
|
|
6
|
+
|
|
7
|
+
include PersonalWordlist::DSL
|
|
8
|
+
|
|
9
|
+
def initialize(personal_data)
|
|
10
|
+
@personal_data = personal_data
|
|
11
|
+
@current_password = ''
|
|
12
|
+
@passwords = []
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe 'SocialWordlist::DSL' do
|
|
17
|
+
subject { TestClass.new(john_doe) }
|
|
18
|
+
describe '#partial' do
|
|
19
|
+
it 'should fail if block is not given' do
|
|
20
|
+
expect { subject.partial }.to raise_error ArgumentError
|
|
21
|
+
end
|
|
22
|
+
it 'should access class variables' do
|
|
23
|
+
expect do
|
|
24
|
+
subject.partial do
|
|
25
|
+
"#{first_name}A"
|
|
26
|
+
end
|
|
27
|
+
end.to change { subject.current_password }.from('').to('JohnA')
|
|
28
|
+
subject.current_password = '' # Reset Current Passoword
|
|
29
|
+
expect do
|
|
30
|
+
subject.partial do
|
|
31
|
+
"#{first_name[0]}123#{last_name[0]}xyz"
|
|
32
|
+
end
|
|
33
|
+
end.to change { subject.current_password }.from('').to('J123Dxyz')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe '#sequence' do
|
|
38
|
+
it 'should create sequences' do
|
|
39
|
+
expect do
|
|
40
|
+
subject.sequence(1..3) do |n|
|
|
41
|
+
"#{first_name}#{n}"
|
|
42
|
+
end
|
|
43
|
+
end.to change { subject.passwords }.from([]).to %w(John1 John2 John3)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'PersonalWordlist' do
|
|
4
|
+
context 'when everything is fine' do
|
|
5
|
+
it 'should work with multiple partial DSLs' do
|
|
6
|
+
passwords = PersonalWordlist.generate(john_doe) do
|
|
7
|
+
partial { "#{first_name[0..1]}" }
|
|
8
|
+
partial { '123' }
|
|
9
|
+
partial { "#{last_name[0]}" }
|
|
10
|
+
end
|
|
11
|
+
expect(passwords.first).to eq 'Jo123D'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should combine sequences and partials' do
|
|
15
|
+
passwords = PersonalWordlist.generate(john_doe) do
|
|
16
|
+
sequence(1..5) do |n|
|
|
17
|
+
partial { n.to_s }
|
|
18
|
+
partial { first_name[0] }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
expect(passwords).to eq %w(1J 2J 3J 4J 5J)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'should combine multiple sequences' do
|
|
25
|
+
passwords = PersonalWordlist.generate(john_doe) do
|
|
26
|
+
sequence(125..250) do |n|
|
|
27
|
+
partial { first_name.downcase }
|
|
28
|
+
partial { n.to_s }
|
|
29
|
+
partial { last_name[0].upcase }
|
|
30
|
+
end
|
|
31
|
+
sequence(1960..2000) do |n|
|
|
32
|
+
partial { last_name.downcase }
|
|
33
|
+
partial { n.to_s }
|
|
34
|
+
end
|
|
35
|
+
partial do
|
|
36
|
+
'Test Password'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
expect(passwords.count).to eq 168
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context 'when something went wrong' do
|
|
44
|
+
it 'gives an error when method is not recognized in DSL' do
|
|
45
|
+
expect do
|
|
46
|
+
PersonalWordlist.generate(john_doe) do
|
|
47
|
+
sequence(1..10) do |n|
|
|
48
|
+
partial { n.to_s + undefined_field }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end.to raise_error NoMethodError
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe PersonalWordlist do
|
|
4
|
+
describe '.password' do
|
|
5
|
+
it 'must have a block given' do
|
|
6
|
+
expect do
|
|
7
|
+
PersonalWordlist.generate(john_doe)
|
|
8
|
+
end.to raise_error ArgumentError
|
|
9
|
+
end
|
|
10
|
+
it 'should be an array' do
|
|
11
|
+
passwords = PersonalWordlist.generate(john_doe) do
|
|
12
|
+
end
|
|
13
|
+
expect(passwords).to be_kind_of(Array)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: personal_wordlist
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Turhan Coskun
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2015-01-18 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rspec
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
description:
|
|
28
|
+
email: turhancoskun@gmail.com
|
|
29
|
+
executables: []
|
|
30
|
+
extensions: []
|
|
31
|
+
extra_rdoc_files: []
|
|
32
|
+
files:
|
|
33
|
+
- README.md
|
|
34
|
+
- lib/personal_wordlist.rb
|
|
35
|
+
- lib/personal_wordlist/dsl.rb
|
|
36
|
+
- lib/personal_wordlist/dsl/partial.rb
|
|
37
|
+
- lib/personal_wordlist/dsl/sequence.rb
|
|
38
|
+
- lib/personal_wordlist/version.rb
|
|
39
|
+
- personal_wordlist.gemspec
|
|
40
|
+
- spec/dsl_spec.rb
|
|
41
|
+
- spec/features_spec.rb
|
|
42
|
+
- spec/personal_wordlist_spec.rb
|
|
43
|
+
- spec/spec_helper.rb
|
|
44
|
+
- spec/support/people_helper.rb
|
|
45
|
+
homepage:
|
|
46
|
+
licenses:
|
|
47
|
+
- MIT
|
|
48
|
+
metadata: {}
|
|
49
|
+
post_install_message:
|
|
50
|
+
rdoc_options: []
|
|
51
|
+
require_paths:
|
|
52
|
+
- lib
|
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: 1.9.2
|
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '0'
|
|
63
|
+
requirements: []
|
|
64
|
+
rubyforge_project:
|
|
65
|
+
rubygems_version: 2.4.5
|
|
66
|
+
signing_key:
|
|
67
|
+
specification_version: 4
|
|
68
|
+
summary: Create wordlists from personal data.
|
|
69
|
+
test_files:
|
|
70
|
+
- spec/dsl_spec.rb
|
|
71
|
+
- spec/features_spec.rb
|
|
72
|
+
- spec/personal_wordlist_spec.rb
|
|
73
|
+
- spec/spec_helper.rb
|
|
74
|
+
- spec/support/people_helper.rb
|