passman 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/README.md +8 -8
- data/bin/passman-cli +209 -0
- data/lib/passman/version.rb +1 -1
- data/passman.gemspec +3 -2
- metadata +36 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4a5990f9427f34027040866471aded1a37127ee
|
4
|
+
data.tar.gz: 7166dc20494bf466a3265e68b115b6b858aabe68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 009e75e96876a26cfcb094c9959910bb1f1c526cdb04ce3fd76114fe3eb989ca455ed69250a1e698fff95cf4237d277507df5f6b685ef34a15a8ee72238b239d
|
7
|
+
data.tar.gz: 7914d3de727b8a3fc134ec2e7a284e9843ebcdb5e15692dc6ae30e3750ef3d8df40a0b07fed8f4a33a0a05abff06bf07e6699ce19331f155c73f0f498275766a
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -21,14 +21,14 @@ PassMan will save your passwords in a file called 'passman.json' by default, you
|
|
21
21
|
First of all you will need a 32 bit (or more) symmetric key. This will be used in the future to encrypt and decrypt your passwords but PassMan will not store that value. Everytime PassMan needs to encrypt or decrypt your passwords it will ask you for one key. You can tell PassMan to create a new secure random key if you want to:
|
22
22
|
|
23
23
|
```
|
24
|
-
passman -g 32
|
25
|
-
|
24
|
+
$ passman -g 32
|
25
|
+
#=> c50647a4dde91848fb5edda217149258
|
26
26
|
```
|
27
27
|
|
28
28
|
Once you have your key, write it down on paper or try to remember it. Now you can start saving your passwords.
|
29
29
|
|
30
30
|
```
|
31
|
-
passman -a Twitter -u alebian -p MySuperPassword
|
31
|
+
$ passman -a Twitter -u alebian -p MySuperPassword
|
32
32
|
```
|
33
33
|
|
34
34
|
You will be prompted to insert you key and then PassMan will store your password.
|
@@ -36,31 +36,31 @@ You will be prompted to insert you key and then PassMan will store your password
|
|
36
36
|
Now you can retreive your passwords:
|
37
37
|
|
38
38
|
```
|
39
|
-
passman -r Twitter
|
39
|
+
$ passman -r Twitter
|
40
40
|
```
|
41
41
|
|
42
42
|
You can tell Passman to store your password in a different file:
|
43
43
|
|
44
44
|
```
|
45
|
-
passman -a Twitter -u alebian -p MySuperPassword -f ~/my_database
|
45
|
+
$ passman -a Twitter -u alebian -p MySuperPassword -f ~/my_database
|
46
46
|
```
|
47
47
|
|
48
48
|
You can list the stored accounts:
|
49
49
|
|
50
50
|
```
|
51
|
-
passman -l
|
51
|
+
$ passman -l
|
52
52
|
```
|
53
53
|
|
54
54
|
You can delete your accounts:
|
55
55
|
|
56
56
|
```
|
57
|
-
passman -d Twitter
|
57
|
+
$ passman -d Twitter
|
58
58
|
```
|
59
59
|
|
60
60
|
For any password generated, you can combine the parameter -c to copy it in your clipboard, this way it won't be stored in your terminal history.
|
61
61
|
|
62
62
|
```
|
63
|
-
passman -g -
|
63
|
+
$ passman -g -c
|
64
64
|
#=> Password copied to clipboard!
|
65
65
|
```
|
66
66
|
|
data/bin/passman-cli
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'colorize'
|
4
|
+
require 'passman'
|
5
|
+
require 'json'
|
6
|
+
require 'clipboard'
|
7
|
+
require 'highline'
|
8
|
+
|
9
|
+
DEFAULT_PATH = File.expand_path('~') + '/passman.json'
|
10
|
+
|
11
|
+
@cli = HighLine.new
|
12
|
+
@database_path = DEFAULT_PATH
|
13
|
+
@manager = nil
|
14
|
+
|
15
|
+
def main_menu(message, is_error)
|
16
|
+
system 'clear'
|
17
|
+
puts '--------------------------------------------------------------------------------'.colorize(:light_yellow)
|
18
|
+
puts '| |'.colorize(:light_yellow)
|
19
|
+
puts '| _____ __ __ |'.colorize(:light_yellow)
|
20
|
+
puts '| | __ \\ | \\/ | |'.colorize(:light_yellow)
|
21
|
+
puts '| | |__) |_ _ ___ ___| \\ / | __ _ _ __ |'.colorize(:light_yellow)
|
22
|
+
puts "| | ___/ _` / __/ __| |\\/| |/ _` | '_ \\ |".colorize(:light_yellow)
|
23
|
+
puts '| | | | (_| \\__ \\__ \\ | | | (_| | | | | |'.colorize(:light_yellow)
|
24
|
+
puts '| |_| \\__,_|___/___/_| |_|\\__,_|_| |_| |'.colorize(:light_yellow)
|
25
|
+
puts '| |'.colorize(:light_yellow)
|
26
|
+
puts '| Welcome to PassMan, your password manager |'.colorize(:light_yellow)
|
27
|
+
puts '| |'.colorize(:light_yellow)
|
28
|
+
puts '--------------------------------------------------------------------------------'.colorize(:light_yellow)
|
29
|
+
unless message.nil?
|
30
|
+
puts ''
|
31
|
+
puts message.colorize(:red) + "\n\n" if is_error
|
32
|
+
puts message.colorize(:green) + "\n\n" unless is_error
|
33
|
+
end
|
34
|
+
puts "Options:\n".colorize(:light_yellow)
|
35
|
+
puts ' 1) Get a previously saved password'
|
36
|
+
puts ' 2) Create a new password'
|
37
|
+
puts ' 3) Manage your saved passwords'
|
38
|
+
puts ' 4) About'
|
39
|
+
puts " 5) Exit\n\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_manager
|
43
|
+
return true unless @manager.nil?
|
44
|
+
unless File.exist?(@database_path)
|
45
|
+
puts "It appears that you don't have previously saved database."
|
46
|
+
puts 'Would you like to create one or load a file stored somewhere else?'
|
47
|
+
option = @cli.ask '[l/C] '
|
48
|
+
|
49
|
+
case option
|
50
|
+
when 'l'
|
51
|
+
new_path = @cli.ask 'Where is your database located? '
|
52
|
+
return false unless File.exist?(new_path)
|
53
|
+
@database_path = new_path
|
54
|
+
else
|
55
|
+
file = File.new(@database_path, 'w+')
|
56
|
+
file.write(JSON.generate({}))
|
57
|
+
file.close
|
58
|
+
print "\tcreated ".colorize(:green)
|
59
|
+
puts @database_path
|
60
|
+
puts "\nRemember to back up this file once in a while!\n\n".colorize(:light_yellow)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
@manager = Passman::Manager.new(@database_path)
|
64
|
+
end
|
65
|
+
|
66
|
+
def print_accounts(database)
|
67
|
+
puts "You have this accounts in your database:\n\n"
|
68
|
+
database.each do |account, info|
|
69
|
+
puts account + ' -> ' + info['username']
|
70
|
+
end
|
71
|
+
puts ''
|
72
|
+
end
|
73
|
+
|
74
|
+
def clipboard_password_prompt(password)
|
75
|
+
puts 'Would you like to see your password now or copy it to the clipboard?'
|
76
|
+
copy = @cli.ask '[s/C] '
|
77
|
+
case copy
|
78
|
+
when 's'
|
79
|
+
["Your password is: #{password}", false]
|
80
|
+
else
|
81
|
+
Clipboard.copy(password)
|
82
|
+
['Password copied to clipboard!', false]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def retreive_saved_password
|
87
|
+
database = JSON.parse(File.read(@database_path)) if File.exist?(@database_path)
|
88
|
+
return ['Failed to read database', true] if database.nil?
|
89
|
+
return ['Empty database', false] if database.empty?
|
90
|
+
print_accounts(database)
|
91
|
+
account = @cli.ask "Which account's password would you like me to tell you? "
|
92
|
+
puts "I'm going to need the secret passphrase you used when you stored it"
|
93
|
+
key = @cli.ask('Enter your key: ') { |q| q.echo = '*' }
|
94
|
+
begin
|
95
|
+
response = @manager.get(account, key)
|
96
|
+
clipboard_password_prompt(response[1]['password'])
|
97
|
+
rescue
|
98
|
+
['Wrong passphrase!', true]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def create_password
|
103
|
+
puts 'Good choice! Let me store your password'
|
104
|
+
account = @cli.ask "Which account is this for? (Facebook, Google, etc)\n"
|
105
|
+
username = @cli.ask "What is your username for this account?\n"
|
106
|
+
puts 'Would you like me to create a secure password for you?'
|
107
|
+
secure = @cli.ask '[n/Y] '
|
108
|
+
password = nil
|
109
|
+
case secure
|
110
|
+
when 'n'
|
111
|
+
puts 'What password would you like to use?'
|
112
|
+
password = @cli.ask('Enter your password: ') { |q| q.echo = '*' }
|
113
|
+
password_confirmation = @cli.ask('Repeat your password: ') { |q| q.echo = '*' }
|
114
|
+
return ["Passwords don't match", true] if password != password_confirmation
|
115
|
+
else
|
116
|
+
puts 'The default password length is 32 characters, is this ok for you?'
|
117
|
+
length = @cli.ask '[n/Y] '
|
118
|
+
case length
|
119
|
+
when 'n'
|
120
|
+
length = @cli.ask 'How many characters would you like? '
|
121
|
+
password = @manager.generate_password(length.to_i)
|
122
|
+
else
|
123
|
+
password = @manager.generate_password
|
124
|
+
end
|
125
|
+
end
|
126
|
+
puts 'In order to save your password encrypted, I need a secret passphrase you can remember.'
|
127
|
+
puts "Make it hard to guess and don't tell it to anyone!"
|
128
|
+
key = @cli.ask('Enter your key: ') { |q| q.echo = '*' }
|
129
|
+
key_confirmation = @cli.ask('Repeat your key: ') { |q| q.echo = '*' }
|
130
|
+
return ["Keys don't match", true] if key != key_confirmation
|
131
|
+
|
132
|
+
begin
|
133
|
+
@manager.add(account, username, password, key)
|
134
|
+
response = clipboard_password_prompt(password)
|
135
|
+
["Password stored successfully!\n#{response[0]}", false]
|
136
|
+
rescue
|
137
|
+
['There was an error saving your password', true]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def manage_passwords
|
142
|
+
database = JSON.parse(File.read(@database_path)) if File.exist?(@database_path)
|
143
|
+
return ['Failed to read database', true] if database.nil?
|
144
|
+
return ['Empty database', false] if database.empty?
|
145
|
+
print_accounts(database)
|
146
|
+
account = @cli.ask 'Which account would you like to delete? '
|
147
|
+
begin
|
148
|
+
@manager.delete(account)
|
149
|
+
["#{account} account deleted", false]
|
150
|
+
rescue
|
151
|
+
['Invalid account', true]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def about
|
156
|
+
puts "PassMan is a password manager tool that let's you easily create and store secure"
|
157
|
+
puts 'passwords. All of them are encrypted before saving, using AES-256 symmetric-key'
|
158
|
+
puts 'algorithm. The symmetric-key is provided by you and PassMan never stores it.'
|
159
|
+
puts 'All the generated passwords are created using a secure random algorithm.'
|
160
|
+
puts "For more information you can visit: https://github.com/alebian/passman\n".colorize(:light_yellow)
|
161
|
+
@cli.ask 'Press enter to continue '
|
162
|
+
end
|
163
|
+
|
164
|
+
@execute = true
|
165
|
+
message = nil
|
166
|
+
is_error = false
|
167
|
+
while @execute
|
168
|
+
main_menu(message, is_error)
|
169
|
+
option = @cli.ask('What would you like to do?')
|
170
|
+
puts ''
|
171
|
+
case option
|
172
|
+
when '1'
|
173
|
+
# Get password
|
174
|
+
if load_manager
|
175
|
+
message, is_error = retreive_saved_password
|
176
|
+
else
|
177
|
+
message = 'Database not found'
|
178
|
+
is_error = true
|
179
|
+
end
|
180
|
+
|
181
|
+
when '2'
|
182
|
+
# Create password
|
183
|
+
if load_manager
|
184
|
+
message, is_error = create_password
|
185
|
+
else
|
186
|
+
message = 'Database not found'
|
187
|
+
is_error = true
|
188
|
+
end
|
189
|
+
|
190
|
+
when '3'
|
191
|
+
# Manage passwords
|
192
|
+
if load_manager
|
193
|
+
message, is_error = manage_passwords
|
194
|
+
else
|
195
|
+
message = 'Database not found'
|
196
|
+
is_error = true
|
197
|
+
end
|
198
|
+
|
199
|
+
when '4'
|
200
|
+
# About
|
201
|
+
about
|
202
|
+
when '5'
|
203
|
+
# Exit
|
204
|
+
@execute = false
|
205
|
+
else
|
206
|
+
message = nil
|
207
|
+
is_error = false
|
208
|
+
end
|
209
|
+
end
|
data/lib/passman/version.rb
CHANGED
data/passman.gemspec
CHANGED
@@ -21,8 +21,9 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_dependency 'colorize', '~> 0.7', '>= 0.7.5'
|
23
23
|
spec.add_dependency 'clipboard', '~> 1.1', '>= 1.1.0'
|
24
|
+
spec.add_dependency 'highline', '~> 1.7', '>= 1.7.8'
|
24
25
|
|
25
26
|
spec.add_development_dependency 'bundler', '>= 1.3.0', '< 2.0'
|
26
|
-
spec.add_development_dependency 'byebug' if RUBY_VERSION >= '2.0.0'
|
27
|
-
spec.add_development_dependency 'rubocop', '~> 0.
|
27
|
+
spec.add_development_dependency 'byebug', '~> 9.0', '>= 9.0.5' if RUBY_VERSION >= '2.0.0'
|
28
|
+
spec.add_development_dependency 'rubocop', '~> 0.42', '>= 0.42.0'
|
28
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alejandro Bezdjian
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -50,6 +50,26 @@ dependencies:
|
|
50
50
|
- - ">="
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: 1.1.0
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: highline
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '1.7'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.7.8
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.7'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.7.8
|
53
73
|
- !ruby/object:Gem::Dependency
|
54
74
|
name: bundler
|
55
75
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,41 +94,48 @@ dependencies:
|
|
74
94
|
name: byebug
|
75
95
|
requirement: !ruby/object:Gem::Requirement
|
76
96
|
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '9.0'
|
77
100
|
- - ">="
|
78
101
|
- !ruby/object:Gem::Version
|
79
|
-
version:
|
102
|
+
version: 9.0.5
|
80
103
|
type: :development
|
81
104
|
prerelease: false
|
82
105
|
version_requirements: !ruby/object:Gem::Requirement
|
83
106
|
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '9.0'
|
84
110
|
- - ">="
|
85
111
|
- !ruby/object:Gem::Version
|
86
|
-
version:
|
112
|
+
version: 9.0.5
|
87
113
|
- !ruby/object:Gem::Dependency
|
88
114
|
name: rubocop
|
89
115
|
requirement: !ruby/object:Gem::Requirement
|
90
116
|
requirements:
|
91
117
|
- - "~>"
|
92
118
|
- !ruby/object:Gem::Version
|
93
|
-
version: '0.
|
119
|
+
version: '0.42'
|
94
120
|
- - ">="
|
95
121
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
122
|
+
version: 0.42.0
|
97
123
|
type: :development
|
98
124
|
prerelease: false
|
99
125
|
version_requirements: !ruby/object:Gem::Requirement
|
100
126
|
requirements:
|
101
127
|
- - "~>"
|
102
128
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0.
|
129
|
+
version: '0.42'
|
104
130
|
- - ">="
|
105
131
|
- !ruby/object:Gem::Version
|
106
|
-
version: 0.
|
132
|
+
version: 0.42.0
|
107
133
|
description: PassMan is a password manager that stores your passwords encrypted, let's
|
108
134
|
you retreive them and create new ones.
|
109
135
|
email: alebezdjian@gmail.com
|
110
136
|
executables:
|
111
137
|
- passman
|
138
|
+
- passman-cli
|
112
139
|
extensions: []
|
113
140
|
extra_rdoc_files: []
|
114
141
|
files:
|
@@ -121,6 +148,7 @@ files:
|
|
121
148
|
- README.md
|
122
149
|
- Rakefile
|
123
150
|
- bin/passman
|
151
|
+
- bin/passman-cli
|
124
152
|
- lib/passman.rb
|
125
153
|
- lib/passman/crypto.rb
|
126
154
|
- lib/passman/manager.rb
|
@@ -152,4 +180,3 @@ signing_key:
|
|
152
180
|
specification_version: 4
|
153
181
|
summary: Password manager.
|
154
182
|
test_files: []
|
155
|
-
has_rdoc:
|