pwss 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +9 -18
- data/.travis.yml +4 -0
- data/LICENSE.txt +17 -18
- data/README.md +454 -0
- data/Rakefile +9 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/pwss +6 -0
- data/lib/pwss.rb +17 -127
- data/lib/pwss/cipher.rb +11 -74
- data/lib/pwss/cli/command_semantics.rb +402 -0
- data/lib/pwss/cli/command_syntax.rb +156 -0
- data/lib/pwss/fileops.rb +31 -22
- data/lib/pwss/generators/bank_account.rb +18 -0
- data/lib/pwss/generators/code.rb +13 -0
- data/lib/pwss/generators/credit_card.rb +23 -0
- data/lib/pwss/generators/entry.rb +36 -0
- data/lib/pwss/generators/fields.rb +119 -0
- data/lib/pwss/generators/sim.rb +15 -0
- data/lib/pwss/generators/software_license.rb +19 -0
- data/lib/pwss/password.rb +94 -0
- data/lib/pwss/safe.rb +183 -0
- data/lib/pwss/version.rb +1 -1
- data/pwss.gemspec +19 -13
- metadata +85 -25
- data/README.textile +0 -190
- data/bin/pwss +0 -445
- data/lib/pwss/bank_account.rb +0 -18
- data/lib/pwss/credit_card.rb +0 -23
- data/lib/pwss/entry.rb +0 -69
- data/lib/pwss/software_license.rb +0 -21
data/README.textile
DELETED
@@ -1,190 +0,0 @@
|
|
1
|
-
h1. Pwss
|
2
|
-
|
3
|
-
A password manager in the spirit of "pws":https://github.com/janlelis/pws.
|
4
|
-
|
5
|
-
Features:
|
6
|
-
|
7
|
-
* PWSS manages password *files*:
|
8
|
-
** A password file can store different entries (password and other sensitive information)
|
9
|
-
** The user can manage different password files (e.g., work, personal)
|
10
|
-
* Entries in a password file can be any of Entry, CreditCard, BankAccount, SoftwareLicense. Each type stores a different set of infos:
|
11
|
-
** *Entry:* title, username, password, url, description
|
12
|
-
** *CreditCard:* title, issuer, name_on_card, card_number, valid_from, valid_till, verification_number, pin, url, notes
|
13
|
-
** *BankAccount:* title, name, iban, url, description
|
14
|
-
** *SoftwareLicense: title, version, license_number, licensed_to, email, purchased_on
|
15
|
-
* Password files can be encrypted
|
16
|
-
* Encrypted password files can be decrypted, for instance, to batch process entries, to migrate to another tool, or to manually edit entries
|
17
|
-
* Entries are human-readable (and editable), when the password file is not encrypted
|
18
|
-
|
19
|
-
h2. Installation
|
20
|
-
|
21
|
-
Type from the command line:
|
22
|
-
|
23
|
-
bc. $ gem install pwss
|
24
|
-
|
25
|
-
h2. Quick Start
|
26
|
-
|
27
|
-
Try the following:
|
28
|
-
|
29
|
-
bc. $ pwss init
|
30
|
-
$ pwss add First Entry
|
31
|
-
$ pwss get First
|
32
|
-
|
33
|
-
For some more information:
|
34
|
-
|
35
|
-
bc. $ pwss man # get information from the command line
|
36
|
-
$ pwss -h # command syntax
|
37
|
-
|
38
|
-
h2. Detailed Instructions
|
39
|
-
|
40
|
-
*Getting started.* @pwss@ stores passwords in a YAML file (also called "safe" or "password file" in the following), possibly encrypted.
|
41
|
-
|
42
|
-
A typical usage scenario is the following:
|
43
|
-
|
44
|
-
# @pwss init@ will create a new encrypted password safe in @~/.pwss.yaml.enc@. If you specify a filename without the @.enc@ extension, the password safe will be stored in plain text (see below).
|
45
|
-
# @pwss add@ will add a new entry to the file
|
46
|
-
# @pwss get string@ will retrieve all entries whose *title* contains @string@, let the user choose an entry, and make the password of the chosen entry available in the clipboard for a given period (the default is 30 seconds; the option @-w@ controls the amount of time the password is available)
|
47
|
-
|
48
|
-
*Using multiple safes.* If you want to create multiple password files or store a password file in a non-standard location, use the @-f@ (@--filename@) option:
|
49
|
-
|
50
|
-
# @pwss init -f MYFILE@
|
51
|
-
# @pwss add -f MYFILE@
|
52
|
-
# @pwss get -f MYFILE@
|
53
|
-
|
54
|
-
*Do not forget to use the extension @.enc@, if your password file to be encrypted.* (See "Encrypted and Plain files", below.)
|
55
|
-
|
56
|
-
*Controlling how long passwords are made available for* Use the @-w@ option to determine how long the password is made available in the clipboard. For instance:
|
57
|
-
|
58
|
-
bc. $ pwss get my_email -w 3
|
59
|
-
|
60
|
-
will retrieve a user selected entry whose title is @my_email@ and make the password available in the clipboard for @3@ seconds.
|
61
|
-
|
62
|
-
Use @0@ to keep the password in the clipboard till a key is pressed.
|
63
|
-
|
64
|
-
*Automatically Generated Password* pwss can automatically generate passwords for entries which are added or updated.
|
65
|
-
|
66
|
-
The generated passwords are random sequences of chars and symbols. No attempt is made to make them readable or simpler to remember. You can use the @-a@ option to limit the generator to use only digits and letters ([0-9a-zA-Z]): this is useful, for instance, for websites which do accept certain classes of characters.
|
67
|
-
|
68
|
-
Use the @-g LENGTH@ option to determine the password length.
|
69
|
-
|
70
|
-
*The automatically generated password is made available in the clipboard, so that it can be used as needed*.
|
71
|
-
|
72
|
-
For instance:
|
73
|
-
|
74
|
-
bc. $ pwss update my_email -g 10 -a -w 20
|
75
|
-
|
76
|
-
will update the @my_email@ entry, by replacing the existing password with one of length @10@ automatically generated by @pwss@; the password contains only alphabetic characters and digits. The new password will be made available in the clipboard for @20@ seconds.
|
77
|
-
|
78
|
-
*Encrypted and Plain Files.* @pwss@ works equally well with encrypted and plain files. More in details, the file extension determines whether @pwss@ tries to decrypt/encrypt the file or not. Use @.enc@ extension to tell @pwss@ the file is encrypted; any other extension will tell @pwss@ to treat the file as plain text.
|
79
|
-
|
80
|
-
For instance:
|
81
|
-
|
82
|
-
bc. $ pwss init -f a.yaml.enc
|
83
|
-
|
84
|
-
will initialize an encrypted safe @a.yaml.enc@.
|
85
|
-
|
86
|
-
By contrast,
|
87
|
-
|
88
|
-
bc. $ pwss init -f a.yaml
|
89
|
-
|
90
|
-
Encrypting sensitive information is a good idea. (Just in case you were expecting a witty statement.) However, if you use @pwss@ to store non-critical infomation, prefer to edit the password safe with a text editor, or use another application for managing encryption and decryption, using @pwss@ with the file in plain format might be more convenient.
|
91
|
-
|
92
|
-
*Moving from plain to encrypted.* You can use the @encrypt@ and @decrypt@ commands at any time to move from the plain to the encrypted format.
|
93
|
-
|
94
|
-
bc. $ pwss -f YOURFILE encrypt
|
95
|
-
|
96
|
-
will encrypt @YOURFILE@, while @decrypt@ will perform the opposite operation.
|
97
|
-
|
98
|
-
*Starting from an Existing File.* You can also start from an existing file, as long as it is an array of YAML records, each containing, at least, a @title@ and a @password@ field. (See next section, for the file structure.)
|
99
|
-
|
100
|
-
In this scenario, you can use the following commands to get started:
|
101
|
-
|
102
|
-
# @pwss -f YOURFILE encrypt@ will encrypt your existing password file
|
103
|
-
# @mv YOURFILE.enc ~/.pwss.yaml.enc@ moves the encrypted file to the default location (not necessary, but it simplifies the workflow)
|
104
|
-
|
105
|
-
To add entries to the password safe, use the @add@ command. If you prefer to operate on the file using a text editor, you can also use the @decrypt@ and @encrypt@ commands.
|
106
|
-
|
107
|
-
*Defining your entries.* @pwss@ requires entries to have only a @title@ and a @password@ field. If you want you can define and store your own records in the yaml files.
|
108
|
-
|
109
|
-
*Getting Help.*
|
110
|
-
|
111
|
-
bc. $ pwss
|
112
|
-
|
113
|
-
will show all command options.
|
114
|
-
|
115
|
-
h2. Under the Hood
|
116
|
-
|
117
|
-
@pwss@ adopts a human-readable format for storing passwords, when the file is not encrypted, of course! (Unless you have mathematical super-powers and can read encrypted text.)
|
118
|
-
|
119
|
-
The password files is a YAML file containing an array of entries. By default, entries have the following records:
|
120
|
-
|
121
|
-
* title
|
122
|
-
* username
|
123
|
-
* password
|
124
|
-
* url
|
125
|
-
* description
|
126
|
-
|
127
|
-
Example
|
128
|
-
|
129
|
-
<pre>
|
130
|
-
- title: A webservice
|
131
|
-
username: username@example.com
|
132
|
-
password: 1234567890
|
133
|
-
url: http://www.example.com
|
134
|
-
description: >
|
135
|
-
with a password like the one above, who needs a password safe
|
136
|
-
|
137
|
-
- title: My email
|
138
|
-
username: username@example.com
|
139
|
-
password: 1234567890
|
140
|
-
url: http://www.example.com
|
141
|
-
description: >
|
142
|
-
Also available via email client, with the following connection parameters
|
143
|
-
smtp.example.com
|
144
|
-
imap.example.com
|
145
|
-
</pre>
|
146
|
-
|
147
|
-
Notice that only @title@ and @password@ are required.
|
148
|
-
|
149
|
-
h2. Changelog
|
150
|
-
|
151
|
-
* *Release 0.5.1* fixes a bug of the "add" command, which threw an error if the title was not supplied on the command line. When adding an entry, now it is possible to specify the title on the command line or just wait for the title prompt
|
152
|
-
* *Release 0.5.0* This is a release mainly focused on improving interaction. It includes small changes to the command syntax and improved exit conditions. In details:
|
153
|
-
** *add* now accepts the title in the command line. For instance @pwss add New Entry@
|
154
|
-
** *new* is now an alias for the *add* command
|
155
|
-
** *update* now requires to specify the field: use @-p@, @--password@, or @--field password@, if you want to update the password
|
156
|
-
** show the usage summary, if no arguments are given
|
157
|
-
** *C-c* is now trapped and properly managed (clearing the clipboard)
|
158
|
-
** decryption errors are now properly managed
|
159
|
-
** the content of the clipboard is now restored after the waiting period
|
160
|
-
|
161
|
-
* *Release 0.4.0*
|
162
|
-
** New @--stdout@ option will output password to standard output (useful for integration with other applications)
|
163
|
-
** New @--select N@ option will automatically select the @N@th entry (rather than asking the user to select an entry).
|
164
|
-
|
165
|
-
* *Release 0.3.0*
|
166
|
-
** internal refactoring: CLI parsing is now based on "Slop":https://github.com/leejarvis/slop. The documentation has been revised and should now be simpler to understand.
|
167
|
-
** added some controls to avoid overwriting existing files (in particular: init, encrypt, and decrypt). The command is now less Unix-like, but I hope you will appreciate a bit more safety.
|
168
|
-
|
169
|
-
* *Release 0.2.0* (never really made it to the public -- use version 0.3.0)
|
170
|
-
** it is now possible to add entries of various types (= with different fields). The supported types include: CreditCard, BankAccount, SoftwareLicense. Use the -e (--entry) option to specify the type of entry to add
|
171
|
-
** an empty string can now be used to exit (instead of -1) when multiple matches are found
|
172
|
-
|
173
|
-
* *Release 0.1.0*
|
174
|
-
** the update command now allows one to update the password or any other field of existing entries
|
175
|
-
** a simple password generator allows pwss to generate a random password
|
176
|
-
** most commands make the password of the selected entry available in the clipboard (useful, for instance, if you automatically generate a password)
|
177
|
-
** a destroy command allows one to delete an entry from a safe. Similar to get, all entries matching a query are shown. The user is then asked to select which entry has to be deleted or stop. User confirmation is required even in case of a single match.
|
178
|
-
|
179
|
-
h2. License
|
180
|
-
|
181
|
-
Licensed under the terms of the MIT License.
|
182
|
-
|
183
|
-
|
184
|
-
h2. Contributing
|
185
|
-
|
186
|
-
1. Fork it (http://github.com/<my-github-username>/pwss/fork )
|
187
|
-
2. Create your feature branch (@git checkout -b my-new-feature@)
|
188
|
-
3. Commit your changes (@git commit -am 'Add some feature'@)
|
189
|
-
4. Push to the branch (@git push origin my-new-feature@)
|
190
|
-
5. Create new Pull Request
|
data/bin/pwss
DELETED
@@ -1,445 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'fileutils'
|
4
|
-
require 'slop'
|
5
|
-
require 'date'
|
6
|
-
|
7
|
-
require "pwss"
|
8
|
-
require "pwss/version"
|
9
|
-
require "pwss/cipher"
|
10
|
-
require "pwss/entry"
|
11
|
-
require "pwss/credit_card"
|
12
|
-
require "pwss/bank_account"
|
13
|
-
require "pwss/software_license"
|
14
|
-
require "pwss/fileops"
|
15
|
-
|
16
|
-
# load filename and decrypt, if necessary
|
17
|
-
# return the filename as string and the password (in case you need to save)
|
18
|
-
def file2string filename
|
19
|
-
string = FileOps::load filename
|
20
|
-
if FileOps::encrypted? filename then
|
21
|
-
password = Cipher::ask_password
|
22
|
-
string = Cipher::decrypt string, password
|
23
|
-
end
|
24
|
-
[string, password]
|
25
|
-
end
|
26
|
-
|
27
|
-
# add and new are command aliases. Unfortunately slop does not seem to support aliases.
|
28
|
-
# hence this function, which is called by both commands.
|
29
|
-
def add opts, args
|
30
|
-
filename = opts.to_hash[:filename] || DEFAULT_FILENAME
|
31
|
-
waiting = opts.to_hash[:wait] || DEFAULT_SECS
|
32
|
-
length = opts.to_hash[:generate] || 0
|
33
|
-
type = opts.to_hash[:type] || "Entry"
|
34
|
-
alnum = opts.to_hash[:alnum]
|
35
|
-
|
36
|
-
default_title = args.join(" ")
|
37
|
-
string, password = file2string filename
|
38
|
-
|
39
|
-
puts "Adding #{default_title != "" ? "entry '" + default_title + "'" : "an entry"} of type '#{type}' to #{filename}"
|
40
|
-
# ask for a new entry
|
41
|
-
if default_title != "" then
|
42
|
-
overrides = {"title" => ["Readline.readline('title (leave empty for \"#{default_title}\"): ')", "'#{default_title}'"]}
|
43
|
-
else
|
44
|
-
overrides = Hash.new
|
45
|
-
end
|
46
|
-
pe = eval("Pwss::" + type).new
|
47
|
-
pe.ask length, alnum, overrides
|
48
|
-
|
49
|
-
# add the entry to the safe
|
50
|
-
entries = YAML::load(string) || Array.new
|
51
|
-
entries << pe.entry
|
52
|
-
|
53
|
-
# check status of input file and encrypt if necessary
|
54
|
-
if FileOps::encrypted? filename then
|
55
|
-
new_string = Cipher::encrypt entries.to_yaml, password
|
56
|
-
else
|
57
|
-
new_string = entries.to_yaml
|
58
|
-
end
|
59
|
-
|
60
|
-
FileOps::backup filename
|
61
|
-
FileOps::save filename, new_string
|
62
|
-
|
63
|
-
puts "Entry added."
|
64
|
-
|
65
|
-
# make password available in the clipboard, if there is a password to make available
|
66
|
-
if pe.entry["password"]
|
67
|
-
Cipher.password_to_clipboard pe.entry["password"], waiting
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
version = Pwss::VERSION
|
72
|
-
man = <<EOS
|
73
|
-
NAME
|
74
|
-
pwss -- A command-line password manager
|
75
|
-
|
76
|
-
SYNOPSYS
|
77
|
-
pwss [-h|-v]
|
78
|
-
pwss command [options] [args]
|
79
|
-
|
80
|
-
DESCRIPTION
|
81
|
-
PWSS is a password manager, in the spirit of pws.
|
82
|
-
|
83
|
-
Features:
|
84
|
-
|
85
|
-
* PWSS manages password *files*:
|
86
|
-
- A password file can store different entries (password and other
|
87
|
-
sensitive information)
|
88
|
-
- The user can manage different password files (e.g., work, personal)
|
89
|
-
|
90
|
-
* Entries in a password file can be any of Entry, CreditCard, BankAccount,
|
91
|
-
SoftwareLicense. Each type stores a different set of infos:
|
92
|
-
|
93
|
-
- Entry: title, username, password, url, description
|
94
|
-
- CreditCard: title, issuer, name_on_card, card_number, valid_from,
|
95
|
-
valid_till, verification_number, pin, url, notes
|
96
|
-
- BankAccount: title, name, iban, url, description
|
97
|
-
- SoftwareLicense: title, version, license_number, licensed_to,
|
98
|
-
email, purchased_on
|
99
|
-
|
100
|
-
* Password files can be encrypted
|
101
|
-
|
102
|
-
* Encrypted password files can be decrypted, for instance, to batch process
|
103
|
-
entries, to migrate to another tool, or to manually edit entries
|
104
|
-
|
105
|
-
* Entries are human-readable (and editable), when the password file is not
|
106
|
-
encrypted
|
107
|
-
|
108
|
-
EXAMPLES
|
109
|
-
pwss -h # get syntax of each command
|
110
|
-
|
111
|
-
# scenario
|
112
|
-
pwss init -f a.enc # generate an encrypted safe a.enc
|
113
|
-
pwss add -f a.enc -g 16 -a # add an entry (pwss will generate a random 16-char password)
|
114
|
-
pwss get -f a.enc my secret account # find an entry
|
115
|
-
|
116
|
-
VERSION
|
117
|
-
This is version #{version}
|
118
|
-
|
119
|
-
LICENSE
|
120
|
-
MIT
|
121
|
-
|
122
|
-
SEE ALSO
|
123
|
-
pwss -h
|
124
|
-
pwss man
|
125
|
-
https://github.com/avillafiorita/pwss
|
126
|
-
EOS
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
#
|
131
|
-
# Main App Starts Here!
|
132
|
-
#
|
133
|
-
cmd = nil
|
134
|
-
opts = Slop.parse :help => true, :strict => true do
|
135
|
-
# the default filename
|
136
|
-
DEFAULT_FILENAME = File.join(Dir.home, ".pwss.yaml.enc")
|
137
|
-
# the default number of seconds password is available in the clipboard
|
138
|
-
DEFAULT_SECS = 30
|
139
|
-
|
140
|
-
banner "pwss [-h|-v]\npwss command [options] [args]"
|
141
|
-
|
142
|
-
##############################################################################
|
143
|
-
on "-v", "--version", 'Print version information' do
|
144
|
-
cmd = "version"
|
145
|
-
puts "pwss version #{version}"
|
146
|
-
end
|
147
|
-
|
148
|
-
##############################################################################
|
149
|
-
command :man do
|
150
|
-
banner "pwss man"
|
151
|
-
description "Print detailed information about how to use pwss"
|
152
|
-
|
153
|
-
run do |_, _|
|
154
|
-
cmd = "man"
|
155
|
-
puts man
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
##############################################################################
|
160
|
-
command :init do
|
161
|
-
banner "pwss init [options]"
|
162
|
-
description "Init a new password file"
|
163
|
-
|
164
|
-
on "-f", "--filename=", "Password file to create. Use extension '.enc' to encrypt it."
|
165
|
-
|
166
|
-
run do |opts, args|
|
167
|
-
cmd = "init"
|
168
|
-
filename = opts.to_hash[:filename] || DEFAULT_FILENAME
|
169
|
-
|
170
|
-
if File.exists?(filename)
|
171
|
-
puts "Error: file #{filename} already exists."
|
172
|
-
exit 1
|
173
|
-
end
|
174
|
-
|
175
|
-
empty_safe = "# safe created on #{Date.today}\n"
|
176
|
-
|
177
|
-
# check status of input file and encrypt if necessary
|
178
|
-
if FileOps::encrypted? filename then
|
179
|
-
password = Cipher::check_password
|
180
|
-
new_string = Cipher::encrypt empty_safe, password
|
181
|
-
else
|
182
|
-
new_string = empty_safe
|
183
|
-
end
|
184
|
-
|
185
|
-
FileOps::backup(filename) if File.exists?(filename)
|
186
|
-
FileOps::save filename, new_string
|
187
|
-
|
188
|
-
puts "New safe created in #{filename}"
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
##############################################################################
|
193
|
-
command :list do
|
194
|
-
banner "pwss list [options]"
|
195
|
-
description "List all entries of a file (e.g., to decrypt or batch process)"
|
196
|
-
|
197
|
-
on "-f", "--filename=", "Password file to use."
|
198
|
-
|
199
|
-
run do |opts, args|
|
200
|
-
cmd = "list"
|
201
|
-
|
202
|
-
filename = opts.to_hash[:filename] || DEFAULT_FILENAME
|
203
|
-
|
204
|
-
string, _ = file2string filename
|
205
|
-
entries = YAML::load(string) || Array.new
|
206
|
-
|
207
|
-
Pwss::list entries
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
##############################################################################
|
212
|
-
command :get do
|
213
|
-
banner "pwss get [options] string"
|
214
|
-
description "Get password for entry matching <string> in the title field"
|
215
|
-
|
216
|
-
on "-f", "--filename=", "Password file to use"
|
217
|
-
on "-w", "--wait=", "Seconds password is available in the clipboard (0 = interactive)", as: Integer
|
218
|
-
on "--stdout", "Output the password to standard output"
|
219
|
-
on "--select=", "Select the N-th matching entry", as: Integer
|
220
|
-
|
221
|
-
run do |opts, args|
|
222
|
-
cmd = "get"
|
223
|
-
|
224
|
-
filename = opts.to_hash[:filename] || DEFAULT_FILENAME
|
225
|
-
waiting = opts.to_hash[:wait] || DEFAULT_SECS
|
226
|
-
stdout_opt = opts.to_hash[:stdout]
|
227
|
-
entry_no = opts.to_hash[:select] || nil
|
228
|
-
|
229
|
-
string, _ = file2string filename
|
230
|
-
entries = YAML::load(string) || Array.new
|
231
|
-
|
232
|
-
password = Pwss::get args.join(" "), entries, entry_no
|
233
|
-
|
234
|
-
if password then
|
235
|
-
stdout_opt ? printf("%s", password) : Cipher.password_to_clipboard(password, waiting)
|
236
|
-
end
|
237
|
-
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
|
242
|
-
##############################################################################
|
243
|
-
command :add do
|
244
|
-
banner "pwss add [options] [entry title]"
|
245
|
-
description "Add an entry and copy its password in the clipboard"
|
246
|
-
|
247
|
-
on "-f", "--filename=", "Password file to use"
|
248
|
-
on "-w", "--wait=", "Seconds password is available in the clipboard (0 = interactive)", as: Integer
|
249
|
-
|
250
|
-
on "-e", "--entry=", "Create an entry of type TYPE (Entry, CreditCard, BankAccount, SoftwareLicense).\n Default to 'Entry', which is good enough for websites credentials"
|
251
|
-
|
252
|
-
on "-g", "--generate=", "Generate a random password of given length.", as: Integer
|
253
|
-
on "-a", "--alnum", "Use only alphanumeric chars for the randomly generated password"
|
254
|
-
|
255
|
-
run do |opts, args|
|
256
|
-
cmd = "add"
|
257
|
-
add opts, args
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
command :new do
|
262
|
-
banner "pwss new [options] [entry title]"
|
263
|
-
description "An alias for add"
|
264
|
-
|
265
|
-
on "-f", "--filename=", "Password file to use"
|
266
|
-
on "-w", "--wait=", "Seconds password is available in the clipboard (0 = interactive)", as: Integer
|
267
|
-
|
268
|
-
on "-e", "--entry=", "Create an entry of type TYPE (Entry, CreditCard, BankAccount, SoftwareLicense).\n Default to 'Entry', which is good enough for websites credentials"
|
269
|
-
|
270
|
-
on "-g", "--generate=", "Generate a random password of given length.", as: Integer
|
271
|
-
on "-a", "--alnum", "Use only alphanumeric chars for the randomly generated password"
|
272
|
-
|
273
|
-
run do |opts, args|
|
274
|
-
cmd = "new"
|
275
|
-
add opts, args
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
##############################################################################
|
280
|
-
command :update do
|
281
|
-
banner "pwss update [options] string"
|
282
|
-
description "Update given field of user-selected entry matching <string>"
|
283
|
-
|
284
|
-
on "-f", "--filename=", "Password file to use"
|
285
|
-
on "-w", "--wait=", "Seconds password is available in the clipboard (0 = interactive)", as: Integer
|
286
|
-
on "-g", "--generate=", "Generate a random password of given length", as: Integer
|
287
|
-
on "-a", "--alnum", "Use only alphanumeric chars for the randomly generated password"
|
288
|
-
on "--field=", 'Field to update'
|
289
|
-
on "-p", "--password", "an alias for --field password"
|
290
|
-
|
291
|
-
run do |opts, args|
|
292
|
-
cmd = "update"
|
293
|
-
|
294
|
-
filename = opts.to_hash[:filename] || DEFAULT_FILENAME
|
295
|
-
waiting = opts.to_hash[:wait] || DEFAULT_SECS
|
296
|
-
length = opts.to_hash[:generate] || 0
|
297
|
-
alnum = opts.to_hash[:alnum]
|
298
|
-
field = opts.to_hash[:password] ? "password" : opts.to_hash[:field]
|
299
|
-
|
300
|
-
if not field then
|
301
|
-
puts "Please specify a field to update (used --field ... or -p)"
|
302
|
-
exit 1
|
303
|
-
end
|
304
|
-
|
305
|
-
string, password = file2string filename
|
306
|
-
|
307
|
-
# load entries and update
|
308
|
-
entries = YAML::load(string) || Array.new
|
309
|
-
|
310
|
-
if field == "password" then
|
311
|
-
# update password
|
312
|
-
entries, entry_password = Pwss::update args.join(" "), entries, length, alnum
|
313
|
-
else
|
314
|
-
entries, entry_password = Pwss::update_field args.join(" "), entries, field
|
315
|
-
end
|
316
|
-
|
317
|
-
# check status of input file and encrypt if necessary
|
318
|
-
if FileOps::encrypted? filename then
|
319
|
-
new_string = Cipher::encrypt entries.to_yaml, password
|
320
|
-
else
|
321
|
-
new_string = entries.to_yaml
|
322
|
-
end
|
323
|
-
|
324
|
-
FileOps::backup filename
|
325
|
-
FileOps::save filename, new_string
|
326
|
-
|
327
|
-
puts "Entry updated."
|
328
|
-
|
329
|
-
# copy to clipboard the new password
|
330
|
-
if entry_password
|
331
|
-
Cipher.password_to_clipboard entry_password, waiting
|
332
|
-
end
|
333
|
-
end
|
334
|
-
end
|
335
|
-
|
336
|
-
##############################################################################
|
337
|
-
# Look for entries matching string, offer the user to select one of the
|
338
|
-
# matching entries, and destroy the entry.
|
339
|
-
# The command asks for confirmation even if there is only one matching entry.
|
340
|
-
# Destroyed entries cannot be recovered (unless you dig in the backup file).
|
341
|
-
command :destroy do
|
342
|
-
banner "pwss destroy [options] string"
|
343
|
-
description "Destroy a user-selected entry matching <string>, after user confirmation."
|
344
|
-
|
345
|
-
on "-f", "--filename=", "Password file to create. Use extension '.enc' to encrypt it."
|
346
|
-
|
347
|
-
run do |opts, args|
|
348
|
-
cmd = "destroy"
|
349
|
-
|
350
|
-
filename = opts.to_hash[:filename] || DEFAULT_FILENAME
|
351
|
-
|
352
|
-
string, password = file2string filename
|
353
|
-
entries = YAML::load(string)
|
354
|
-
|
355
|
-
entries = Pwss::destroy args.join(" "), entries
|
356
|
-
|
357
|
-
# check status of input file and encrypt if necessary
|
358
|
-
if FileOps::encrypted? filename then
|
359
|
-
new_string = Cipher::encrypt entries.to_yaml, password
|
360
|
-
else
|
361
|
-
new_string = entries.to_yaml
|
362
|
-
end
|
363
|
-
|
364
|
-
FileOps::backup filename
|
365
|
-
FileOps::save filename, new_string
|
366
|
-
|
367
|
-
puts "Entry deleted."
|
368
|
-
end
|
369
|
-
end
|
370
|
-
|
371
|
-
##############################################################################
|
372
|
-
# OPERATIONS ON PASSWORD FILES
|
373
|
-
##############################################################################
|
374
|
-
|
375
|
-
##############################################################################
|
376
|
-
command :encrypt do
|
377
|
-
banner "pwss encrypt [options]"
|
378
|
-
description "Encrypt a password safe"
|
379
|
-
|
380
|
-
on "-f", "--filename=", "Password file to encrypt. Write to <file>.enc."
|
381
|
-
|
382
|
-
run do |opts, _|
|
383
|
-
cmd = "encrypt"
|
384
|
-
|
385
|
-
filename = opts.to_hash[:filename] || DEFAULT_FILENAME.sub(/\.enc$/, "")
|
386
|
-
|
387
|
-
if not File.exists?(filename)
|
388
|
-
puts "Error: file #{filename} does not exist."
|
389
|
-
exit 1
|
390
|
-
end
|
391
|
-
|
392
|
-
password = Cipher::check_password
|
393
|
-
data = FileOps::load filename
|
394
|
-
encrypted = Cipher::encrypt data, password
|
395
|
-
|
396
|
-
enc_filename = filename + ".enc"
|
397
|
-
|
398
|
-
if File.exists?(enc_filename)
|
399
|
-
FileOps::backup enc_filename
|
400
|
-
puts "Warning: existing #{enc_filename} backupped to #{enc_filename}~"
|
401
|
-
end
|
402
|
-
FileOps::save enc_filename, encrypted
|
403
|
-
puts "An encrypted copy now lives in #{enc_filename}"
|
404
|
-
puts "You might want to check everything is ok and delete the plain file: #{filename}"
|
405
|
-
end
|
406
|
-
end
|
407
|
-
|
408
|
-
##############################################################################
|
409
|
-
command :decrypt do
|
410
|
-
banner "pwss decrypt [options]"
|
411
|
-
description "Decrypt a password safe"
|
412
|
-
|
413
|
-
on "-f", "--filename=", "Password file to decrypt. Write to <file>, without '.enc'."
|
414
|
-
|
415
|
-
run do |opts, _|
|
416
|
-
cmd = "decrypt"
|
417
|
-
|
418
|
-
filename = opts.to_hash[:filename] || DEFAULT_FILENAME
|
419
|
-
|
420
|
-
if not File.exists?(filename)
|
421
|
-
puts "Error: file #{filename} does not exist."
|
422
|
-
exit 1
|
423
|
-
end
|
424
|
-
|
425
|
-
password = Cipher::ask_password
|
426
|
-
data = FileOps::load filename
|
427
|
-
decrypted = Cipher::decrypt data, password
|
428
|
-
|
429
|
-
dec_filename = filename.sub(/\.enc$/,"")
|
430
|
-
if File.exists?(dec_filename)
|
431
|
-
FileOps::backup dec_filename
|
432
|
-
puts "Warning: existing #{dec_filename} backupped to #{dec_filename}~"
|
433
|
-
end
|
434
|
-
|
435
|
-
FileOps::save dec_filename, decrypted
|
436
|
-
puts "A decrypted copy now lives in #{dec_filename}"
|
437
|
-
puts "You might want to check everything is ok and delete #{filename}, if you wish."
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
end
|
442
|
-
|
443
|
-
if cmd == nil then
|
444
|
-
puts opts
|
445
|
-
end
|