passbox 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04ac7ed6574fa1f0647f44dc8f19d522cd668c35ab1b0bc680c4af28f724fb7d
4
- data.tar.gz: c21638c4eb47791c5e39fa682a30083744307670a9046101ccfdb515374329b5
3
+ metadata.gz: 7f7ecaf34fb41df4dc4b08c057d4850dd824fb2008f42af37900fada39b55dab
4
+ data.tar.gz: faaca8fd5355c9ee2b519afbfe6190efe20bb9f53cb2ac4731547d3f12d62f6d
5
5
  SHA512:
6
- metadata.gz: 595b8fdff85d782828e65731955a03524be9a45e178befc0559bb06b2b68b9c39ea4602a201072e81a105d7110e659b933b34fc426f54fa519a1d590e9bd8423
7
- data.tar.gz: a43ac4ec10eada49313a1ae5b77c553cd49c970475dd5df494bda03bdf288804216dc8fabbc35f386e9a6f2455840ef9ec7250f5f603f87aa51bc5b614296fe9
6
+ metadata.gz: aa21924d9a86c26eb5c4cbeefaa376fb46bc9dee134d308f2b51994f1c74a5b90ee81df72c0ca551a8bb2a9ec0a35c559af1068dcc39ac17a7f0e7f1fd3e822b
7
+ data.tar.gz: 762e06d5b9a53e9787c6b63aaa1410f6aded92a527e8a6b6350b7610497e94cd9d3ac21b1bdac59bf046c48eaa80933a412a89eb9fb931e715a3394cd8672f3e
data/LICENSE CHANGED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Kaushal Rupani
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -5,6 +5,8 @@ A Ruby based minimalistic offline cli password manager using strong AES encrypti
5
5
  ## Table of Contents
6
6
  - [1. Introduction](#introduction)
7
7
  - [2. Installation](#install)
8
+ - [2a. Homebrew](#brew)
9
+ - [2b. Rubygems](#gem)
8
10
  - [3. Usage](#usage)
9
11
  - [3a. Initial Setup](#init)
10
12
  - [3b. Add a new password](#add)
@@ -28,11 +30,21 @@ Note: I wouldn't say its uncrackable as nothing in the world is.
28
30
 
29
31
  ## <a name="install"></a> 2. Installation
30
32
  Passbox currently only supports Linux/MacOS based envvrionments.
31
- As its a ruby based, it needs a working installation of Ruby version 2 and above installed as a pre-requisite.
32
- It can be installed as just any other gem.
33
+
34
+ ### <a name="brew"></a> 2a. Homebrew
35
+ Easiest way to install on macos is using [Homebrew](https://brew.sh)
36
+ ```console
37
+ $ brew tap krupani/homebrew-formulae
38
+ $ brew install passbox
39
+ ```
40
+
41
+ ### <a name="gem"></a> 2b. Rubygems
42
+ If you have a working installation of ruby, passbox can be installed as a rubygem simply by using gem command.
43
+
44
+ ```console
45
+ $ gem install passbox
46
+ ```
33
47
 
34
- ``` gem install passbox ```
35
-
36
48
 
37
49
  ## <a name="usage"></a> 3. Usage
38
50
  As mentioned above, passbox is a cli based utility. Below are few basic functions which you can perform.
@@ -41,25 +53,45 @@ As mentioned above, passbox is a cli based utility. Below are few basic function
41
53
  Before starting, you need to setup the passbox utility which will include creating a base directory and creating your master password.
42
54
  This can be easily done using the init command as follows:
43
55
 
44
- ``` passbox init ```
56
+ ```console
57
+ $ passbox init
58
+ ```
45
59
 
46
60
  This will ask you create a master password, its recommended you create this one time master password really complex and more than 10 characters to make it really difficult to brute force.
47
61
 
48
62
  ### <a name="add"></a> 3b. Add a new password
49
63
  Once passbox is setup, you can start adding password. It can be done using the create command which can be used as follows:
50
64
 
51
- ``` passbox add ```
52
-
53
- This command will ask you 3 questions:
54
- - first to enter your account name (no special charaters)
55
- - eg twitter, facebook etc
56
- - second to enter your account username
57
- - last to enter your password
65
+ ```console
66
+ $ passbox add
67
+ ```
68
+
69
+ This command will give you an option to chose the type of secret you want to add into passbox:
70
+ - Login
71
+ - Username<sup>*</sup>
72
+ - Password<sup>*</sup>
73
+ - Url (optional)
74
+ - Note (optional)
75
+ - Pin (Pin)
76
+ - Pin<sup>*</sup>
77
+ - Note (optional)
78
+ - Credit / Debit Card
79
+ - Card Number<sup>*</sup>
80
+ - Card Expiry<sup>*</sup>
81
+ - Card CVV<sup>*</sup>
82
+ - Card Pin (optional)
83
+ - Note (optional)
84
+
85
+ After chosing an option above, the utility will ask you 2 questions:
86
+ - to create a new account name.
87
+ - to enter your master password for authentication purposes.
58
88
 
59
89
  ### <a name="read"></a> 3c. Read an existing password
60
90
  Once you have saved your password, you can view them as and when needed, authenticating using your master password and entering your account name of the password you want to view, as follows :
61
91
 
62
- ``` passbox read ```
92
+ ```console
93
+ $ passbox read
94
+ ```
63
95
 
64
96
  This command will ask you 2 questions:
65
97
  - to enter you account name for which you want to view the password.
@@ -68,28 +100,36 @@ This command will ask you 2 questions:
68
100
  ### <a name="update"></a> 3d. Update an existing password
69
101
  You can update your account details (username and password) when needed, authenticating using your master password and entering your account name you need to update :
70
102
 
71
- ``` passbox update ```
103
+ ```console
104
+ $ passbox update
105
+ ```
72
106
 
73
- This command will ask you 4 questions:
107
+ This command will first ask you 2 questions:
74
108
  - First to enter you account name for which you want to update the password.
75
109
  - Next, to enter you master password for authentication purposes.
76
- - Then to enter your new updated account username
77
- - Last to enter your new updated password
110
+
111
+ Then depending the account type, appropriate fields will be asked to be filled. If you wish to not change the exisitng value, just hit enter and move onto next field or enter a new value to update the field to new value.
78
112
 
79
113
  ### <a name="delete"></a> 3e. Delete an existing account
80
114
  You can delete an existing account, if you do not need it anymore. It can be done using the delete command and does not require any kind of authentication.
81
115
 
82
- ``` passbox delete ```
116
+ ```console
117
+ $ passbox delete
118
+ ```
83
119
 
84
- This command will only ask you the account name to delete.
120
+ This command will first ask you 2 questions:
121
+ - First to enter you account name which you want to delete.
122
+ - Next, to enter you master password for authentication purposes.
85
123
 
86
124
  ### <a name="list"></a> 3f. List all available accounts
87
125
  You can list all accounts you have using the following command without any authentication required.
88
126
 
89
- ``` passbox list ```
127
+ ```console
128
+ $ passbox list
129
+ ```
90
130
 
91
131
  ## <a name="contributing"></a> 4. Contributing
92
132
  Ideas and suggestions are always always most welcome. Please fork this code and feel free to add any updates, suggestions etc and create a pull request.
93
133
 
94
134
  ## <a name="issues"></a> 5. Issues
95
- If you face any problem related to syntax, usability, documentation then please raise an [issues](https://github.com/krupani/passbox/issues) . Please note to add in detailed description of the issue you are facing.
135
+ If you face any problem related to syntax, usability, documentation then please raise an [issue](https://github.com/krupani/passbox/issues) . Please note to add details of the issue you are facing.
data/bin/passbox CHANGED
@@ -5,64 +5,59 @@ require 'passbox'
5
5
  def print_help
6
6
  puts <<HELP
7
7
 
8
- Usage: passbox <command>
8
+ Commands
9
9
 
10
- Commands
10
+ -v, version Prints the version of passbox.
11
+ Usage: passbox version | passbox -v | passbox --version
11
12
 
12
- version : Prints the version of passbox
13
- currently installed.
14
- Usage: passbox --version | passbox -v
13
+ -h, help Prints help information
14
+ Usage: passbox help | passbox -h | passbox --help
15
15
 
16
- help : Prints help information
17
- (No authentication required.)
16
+ -i, init Setup a passbox store and create master password.
17
+ Usage: passbox init | passbox -i
18
18
 
19
- init : Helps setup a passbox store and
20
- setup a master password.
19
+ ls, list Lists all accounts in passbox.
20
+ Usage: passbox list | passbox ls
21
21
 
22
- list : Lists all the accounts present
23
- in passbox.
24
- (No authentication required.)
22
+ +, add add a new account into passbox.
23
+ Usage: passbox add | passbox +
25
24
 
26
- add : add a new account with username and
27
- password into passbox.
28
- (Authentication required.)
25
+ =, read read an account present in passbox.
26
+ Usage: passbox read | passbox =
29
27
 
30
- read : read username and password from an
31
- existing account present in passbox.
32
- (Authentication required.)
33
-
34
- update : update username and password in an
35
- existing account present in passbox.
36
- (Authentication required.)
37
-
38
- delete : delete an account from passbox.
39
- (Authentication required.)
28
+ ++, update update details of an account present in passbox.
29
+ Usage: passbox update | passbox ++
30
+
31
+ -, delete delete an account from passbox.
32
+ Usage: passbox delete | passbox del | passbox -
40
33
 
41
34
  HELP
42
35
  end
43
36
 
44
37
  if ARGV.length == 0
45
38
  print_help
46
- else
39
+ elsif ARGV.length == 1
47
40
  cmd = ARGV.shift
48
41
  case(cmd.downcase)
49
42
  when "help", "--help", "-h"
50
43
  print_help
51
44
  when 'version', '--version', '-v'
52
45
  puts File.read(File.expand_path("../../lib/passbox/version", __FILE__))
53
- when "init"
46
+ when "init", "-i"
54
47
  init
55
- when "add"
48
+ when "+", "add"
56
49
  create_pass
57
- when "read"
50
+ when "=", "read"
58
51
  read_pass
59
- when "update"
52
+ when "++", "update"
60
53
  update_pass
61
- when "delete"
54
+ when "-", "delete", "del"
62
55
  delete_pass
63
- when "list"
56
+ when "list", "ls"
64
57
  list_of_accounts
65
58
  else
66
- puts "Invalid Command. Enter 'passbox help' to show usage"
59
+ puts "Invalid Command. Enter 'passbox help' to show usage.".red
67
60
  end
61
+ else
62
+ puts "Too many arguments. Enter 'passbox help' to show usage.".red
68
63
  end
data/lib/passbox.rb CHANGED
@@ -1,5 +1,12 @@
1
1
  require 'passbox/aes'
2
2
  require 'passbox/auth'
3
3
  require 'passbox/init'
4
- require 'passbox/crud'
4
+ require 'passbox/accounts'
5
+ require 'passbox/crud/create'
6
+ require 'passbox/crud/read'
7
+ require 'passbox/crud/update'
8
+ require 'passbox/crud/delete'
9
+ require 'passbox/helpers/options'
10
+ require 'passbox/helpers/colourize'
11
+ require 'passbox/helpers/strings'
5
12
  include Passbox
@@ -0,0 +1,75 @@
1
+ module Passbox
2
+ require 'json'
3
+
4
+ def list_of_accounts
5
+ check_passbox
6
+ empty = true
7
+ files_ext = Dir["#{$pbdir}/*.pb"]
8
+ print "\nLogin & Passwords\n".bold.cyan if files_ext.size != 0
9
+ files_ext.each_with_index do |file,i|
10
+ print "#{i+1}. #{file.split('/').last.split('.').first}\n".cyan
11
+ empty = false
12
+ end
13
+ files_ext = Dir["#{$pbdir}/*.pn"]
14
+ print "\nAccount Pins\n".bold.magenta if files_ext.size != 0
15
+ files_ext.each_with_index do |file,i|
16
+ print "#{i+1}. #{file.split('/').last.split('.').first}\n".magenta
17
+ empty = false
18
+ end
19
+ files_ext = Dir["#{$pbdir}/*.cc"]
20
+ print "\nCredit & Debit Cards\n".bold.yellow if files_ext.size != 0
21
+ files_ext.each_with_index do |file,i|
22
+ print "#{i+1}. #{file.split('/').last.split('.').first}\n".yellow
23
+ empty = false
24
+ end
25
+ print no_accounts.yellow if empty
26
+ end
27
+
28
+ def verify_account
29
+ print enter_account_name
30
+ acc = user_input
31
+ files = Dir.glob("#{$pbdir}/#{acc}.{pb,pn,cc}")
32
+ if files.size == 0
33
+ print account_not_found
34
+ exit(0)
35
+ elsif files.size == 1
36
+ return files.first
37
+ else
38
+ files.each_with_index do |file, i|
39
+ filename = file.split("/").last.split(".").first
40
+ fileext = file.split("/").last.split(".").last
41
+ case fileext
42
+ when "pb"
43
+ print "\n#{i+1}: #{filename} - Login & Password Category"
44
+ when "pn"
45
+ print "\n#{i+1}: #{filename} - Account Pins Category"
46
+ when "cc"
47
+ print "\n#{i+1}: #{filename} - Credit/Debit Card Category"
48
+ else
49
+ # do nothing
50
+ end
51
+ end
52
+ print multiple_accounts
53
+ option = user_input.to_i
54
+ if (1..files.size).include?(option)
55
+ return files[option-1]
56
+ else
57
+ print invalid_selection.red
58
+ exit(0)
59
+ end
60
+ end
61
+ end
62
+
63
+ def does_account_exists(acc, type)
64
+ files = Dir.glob("#{$pbdir}/#{acc}.{pb,pn,cc}")
65
+ if files.size == 0
66
+ return false
67
+ else
68
+ files.each do |file|
69
+ return true if (file.split(".").last == $options[type])
70
+ end
71
+ return false
72
+ end
73
+ end
74
+
75
+ end
data/lib/passbox/auth.rb CHANGED
@@ -3,37 +3,71 @@ module Passbox
3
3
  require 'digest'
4
4
 
5
5
  def get_password_from_user(action=:account)
6
- if (action == :account)
7
- print "Please enter your account password: "
6
+ case action
7
+ when :account
8
+ print enter_account_password
8
9
  return password_input(action)
9
- elsif (action == :master)
10
+ when :pin
11
+ print enter_account_pin
12
+ return password_input(action)
13
+ when :cvv
14
+ print enter_cc_cvv
15
+ return password_input(action)
16
+ when :card_pin
17
+ print enter_cc_pin
18
+ return password_input(action)
19
+ when :master
20
+ attempt = 0
10
21
  while(true)
11
- print "Please create your master password (min 8 chars): "
22
+ attempt = attempt + 1;
23
+ print create_master_password
12
24
  pass256 = password_input(action)
13
- return pass256 if pass256;
25
+ if pass256
26
+ print re_enter_master_password
27
+ re_pass256 = password_input(action)
28
+ if re_pass256 == pass256
29
+ print pb_setup_complete.bold.green
30
+ return pass256
31
+ else
32
+ print passwords_mismatch.bold.red
33
+ exit(0);
34
+ end
35
+ else
36
+ print password_validation.red
37
+ end
38
+ if attempt == 3
39
+ print too_many_attempts.bold.red
40
+ exit(0)
41
+ end
14
42
  end
15
- elsif (action == :auth)
16
- print "Please enter your master password: "
43
+ when :auth
44
+ print enter_master_password
17
45
  return password_input(action)
18
46
  end
19
47
  end
20
48
 
21
49
  def password_input(action)
22
- pass = STDIN.noecho(&:gets).chomp
23
- if (pass.length < 8 && action != :account)
24
- if (action == :master)
25
- print "\nPassword should be minimum 8 characters, try again!!\n"
26
- return false
27
- elsif (action == :auth)
28
- print "\nInvalid Password!!\n"
29
- exit(0)
30
- end
31
- elsif (action == :account)
32
- print("\n")
33
- return pass
50
+ begin
51
+ pass = STDIN.noecho(&:gets).chomp
52
+ rescue Interrupt
53
+ puts thank_you.cyan
54
+ exit(0)
55
+ end
56
+ case action
57
+ when :master, :auth
58
+ if (pass.length < 8)
59
+ if (action == :master)
60
+ return false
61
+ elsif (action == :auth)
62
+ print invalid_password.bold.red
63
+ exit(0)
64
+ end
65
+ else
66
+ return Digest::SHA256.hexdigest(pass)
67
+ end
34
68
  else
35
69
  print("\n")
36
- return Digest::SHA256.hexdigest(pass)
70
+ return pass
37
71
  end
38
72
  end
39
73
 
@@ -41,11 +75,11 @@ module Passbox
41
75
  pass256User = get_password_from_user(:auth)
42
76
  pass256File = decrypt($passfile, pass256User)
43
77
  if pass256File == pass256User
44
- print("Authentication Successful!!\n")
78
+ print auth_success.bold.green
45
79
  return pass256File
46
80
  else
47
- print("Authentication Failed!!\n")
48
- return false
81
+ print auth_failed.bold.red
82
+ exit(0)
49
83
  end
50
84
  end
51
85
 
@@ -0,0 +1,121 @@
1
+ module Passbox
2
+
3
+ def create_pass
4
+ check_passbox
5
+ option = select_option
6
+ key = passbox_auth
7
+ acc = create_account(option, key)
8
+ case option
9
+ when 1
10
+ login(acc, key)
11
+ when 2
12
+ pin(acc, key)
13
+ when 3
14
+ cc(acc, key)
15
+ else
16
+ exit(0)
17
+ end
18
+ end
19
+
20
+ def create_account(option, key)
21
+ attempts = 0
22
+ while(true)
23
+ if attempts == 3
24
+ print too_many_attempts.bold.red
25
+ exit(0)
26
+ end
27
+ print enter_account_name
28
+ acc = user_input.downcase
29
+ if acc.empty?
30
+ print account_name_blank.red
31
+ attempts = attempts + 1
32
+ next;
33
+ end
34
+ if (acc.count("a-z0-9_-") == acc.length)
35
+ account_exists = does_account_exists(acc, option)
36
+ if account_exists
37
+ print account_already_exists.red
38
+ attempts = attempts + 1
39
+ next;
40
+ end
41
+ break
42
+ else
43
+ print account_name_invalid
44
+ attempts = attempts + 1
45
+ end
46
+ end
47
+ return acc
48
+ end
49
+
50
+ def login(acc, key, action=:create)
51
+ attempts = 0
52
+ hash = {}
53
+ hash["username"] = fill_manadatory_field(enter_username, username_blank, action)
54
+ hash["password"] = fill_manadatory_field("", password_blank, action, :account)
55
+ print enter_url
56
+ url = user_input
57
+ hash["url"] = url unless url.empty?
58
+ print enter_note
59
+ note = user_input
60
+ hash["note"] = note unless note.empty?
61
+ return hash if action == :update
62
+ json = hash.to_json
63
+ encrypt(json, key, "#{$pbdir}/#{acc}.pb")
64
+ print "Account #{acc} has been successfully created!! \n\n".green
65
+ end
66
+
67
+ def pin(acc, key, action = :create)
68
+ attempts = 0
69
+ hash = {}
70
+ hash["pin"] = fill_manadatory_field("", pin_blank, action, :pin)
71
+ print enter_note
72
+ note = user_input
73
+ hash["note"] = note unless note.empty?
74
+ return hash if action == :update
75
+ json = hash.to_json
76
+ encrypt(json, key, "#{$pbdir}/#{acc}.pn")
77
+ print "Account #{acc} has been successfully created!! \n\n".green
78
+ end
79
+
80
+ def cc(acc, key, action = :create)
81
+ attempts = 0
82
+ hash = {}
83
+ hash["card_number"] = fill_manadatory_field(enter_cc_no, cc_no_blank, action)
84
+ hash["card_expiry"] = fill_manadatory_field(enter_cc_exp, cc_exp_blank, action)
85
+ hash["card_cvv"] = fill_manadatory_field("", cc_cvv_blank, action, :cvv)
86
+ cc_pin = get_password_from_user(:card_pin)
87
+ hash["card_pin"] = cc_pin unless cc_pin.empty?
88
+ print enter_note
89
+ note = user_input
90
+ hash["note"] = note unless note.empty?
91
+ return hash if action == :update
92
+ json = hash.to_json
93
+ encrypt(json, key, "#{$pbdir}/#{acc}.cc")
94
+ print "Account #{acc} has been successfully created!! \n\n".green
95
+ end
96
+
97
+ def fill_manadatory_field(enter_message, blank_message, action=:create, type=nil)
98
+ attempts = 0
99
+ while(true)
100
+ if attempts == 3
101
+ print too_many_attempts.bold.red
102
+ exit(0)
103
+ end
104
+ if (type.nil?)
105
+ print enter_message
106
+ field = user_input
107
+ else
108
+ field = get_password_from_user(type)
109
+ end
110
+ if field.empty?
111
+ if (action == :create)
112
+ print blank_message.red
113
+ attempts = attempts + 1
114
+ next;
115
+ end
116
+ end
117
+ return field
118
+ end
119
+ end
120
+
121
+ end
@@ -0,0 +1,13 @@
1
+ module Passbox
2
+
3
+ def delete_pass
4
+ check_passbox
5
+ filename = verify_account
6
+ key = passbox_auth
7
+ if key
8
+ File.delete(filename)
9
+ print "\nYour account #{filename.split("/").last.split(".").first} has been deleted!!\n\n".bold.yellow
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,33 @@
1
+ module Passbox
2
+
3
+ def read_pass(action=:display)
4
+ check_passbox
5
+ filename = verify_account
6
+ key = passbox_auth
7
+
8
+ if key
9
+ data = JSON.parse(decrypt(filename, key))
10
+ return data, filename, key if (action == :update)
11
+ case filename.split(".").last
12
+ when "pb"
13
+ print "\nusername : #{data['username']}\n"
14
+ print "password : #{data['password']}\n"
15
+ print "url : #{data['url']}\n" if data['url']
16
+ print "note : #{data['note']}\n" if data['note']
17
+ print "\n"
18
+ when "pn"
19
+ print "\npin : #{data['pin']}\n"
20
+ print "note : #{data['note']}\n" if data['note']
21
+ print "\n"
22
+ when "cc"
23
+ print "\ncard number : #{data['card_number']}\n"
24
+ print "expiry : #{data['card_expiry']}\n"
25
+ print "cvv : #{data['card_cvv']}\n" if data['card_cvv']
26
+ print "card pin : #{data['card_pin']}\n" if data['card_pin']
27
+ print "note : #{data['note']}\n" if data['note']
28
+ print "\n"
29
+ end
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,36 @@
1
+ module Passbox
2
+
3
+ def update_pass
4
+ existing, filename, key = read_pass(:update)
5
+ update_details(existing, filename, key)
6
+ print account_update_success.green
7
+ end
8
+
9
+ def update_details(existing, filename, key)
10
+ print update_instructions.yellow
11
+ change_flag = false
12
+ case filename.split(".").last
13
+ when "pb"
14
+ updated = login(nil, key, :update)
15
+ existing["username"] = updated["username"] unless updated["username"].empty?
16
+ existing["password"] = updated["password"] unless updated["password"].empty?
17
+ existing["url"] = updated["url"] unless (updated["url"].nil? || updated["url"].empty?)
18
+ existing["note"] = updated["note"] unless (updated["note"].nil? || updated["note"].empty?)
19
+ when "pn"
20
+ updated = pin(nil, key, :update)
21
+ existing["pin"] = updated["pin"] unless updated["pin"].empty?
22
+ existing["note"] = updated["note"] unless (updated["note"].nil? || updated["note"].empty?)
23
+ when "cc"
24
+ updated = cc(nil, key, :update)
25
+ existing["card_number"] = updated["card_number"] unless updated["card_number"].empty?
26
+ existing["card_expiry"] = updated["card_expiry"] unless updated["card_expiry"].empty?
27
+ existing["card_cvv"] = updated["card_cvv"] unless updated["card_cvv"].empty?
28
+ existing["card_pin"] = updated["card_pin"] unless (updated["card_pin"].nil? || updated["card_pin"].empty?)
29
+ existing["note"] = updated["note"] unless (updated["note"].nil? || updated["note"].empty?)
30
+ else
31
+ # do nothing
32
+ end
33
+ encrypt(existing.to_json, key, filename)
34
+ end
35
+
36
+ end
@@ -0,0 +1,27 @@
1
+ class String
2
+
3
+ def black; "\e[30m#{self}\e[0m" end
4
+ def red; "\e[31m#{self}\e[0m" end
5
+ def green; "\e[32m#{self}\e[0m" end
6
+ def yellow; "\e[33m#{self}\e[0m" end
7
+ def blue; "\e[34m#{self}\e[0m" end
8
+ def magenta; "\e[35m#{self}\e[0m" end
9
+ def cyan; "\e[36m#{self}\e[0m" end
10
+ def gray; "\e[37m#{self}\e[0m" end
11
+
12
+ def bg_black; "\e[40m#{self}\e[0m" end
13
+ def bg_red; "\e[41m#{self}\e[0m" end
14
+ def bg_green; "\e[42m#{self}\e[0m" end
15
+ def bg_brown; "\e[43m#{self}\e[0m" end
16
+ def bg_blue; "\e[44m#{self}\e[0m" end
17
+ def bg_magenta; "\e[45m#{self}\e[0m" end
18
+ def bg_cyan; "\e[46m#{self}\e[0m" end
19
+ def bg_gray; "\e[47m#{self}\e[0m" end
20
+
21
+ def bold; "\e[1m#{self}\e[22m" end
22
+ def italic; "\e[3m#{self}\e[23m" end
23
+ def underline; "\e[4m#{self}\e[24m" end
24
+ def blink; "\e[5m#{self}\e[25m" end
25
+ def reverse_color; "\e[7m#{self}\e[27m" end
26
+
27
+ end
@@ -0,0 +1,37 @@
1
+ module Passbox
2
+
3
+ def display_add_options
4
+ print "\n1. Password"
5
+ print "\n2. Pin"
6
+ print "\n3. Debit/Credit Card"
7
+ print "\nPlease select one of the above options: "
8
+ return user_input.to_i
9
+ end
10
+
11
+ def select_option
12
+ attempt = 0
13
+ while(true)
14
+ attempt = attempt + 1
15
+ option = display_add_options
16
+ if (1..3).include?(option)
17
+ return option
18
+ else
19
+ print "\nInvalid selection. Please try again!!\n".red
20
+ end
21
+ if attempt==3
22
+ print "\nToo many invalid attempts. Bye!!\n\n".bold.red
23
+ exit(0)
24
+ end
25
+ end
26
+ end
27
+
28
+ def user_input
29
+ begin
30
+ return gets.chomp
31
+ rescue Interrupt
32
+ puts "\n\nThank you for using passbox. Bye!!\n".cyan
33
+ exit(0)
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,53 @@
1
+ module Passbox
2
+
3
+ def account_name_blank; return "Account Name cannot be empty, try again!!\n"; end
4
+ def username_blank; return "Username cannot be empty, try again!!\n"; end
5
+ def password_blank; return "Password cannot be empty, try again!!\n"; end
6
+ def pin_blank; return "Pin cannot be empty, try again!!\n"; end
7
+ def cc_no_blank; return "Credit/Debit Card cannot be empty, try again!!\n"; end
8
+ def cc_exp_blank; return "Card Expiry cannot be empty, try again!!\n"; end
9
+ def cc_cvv_blank; return "Card CVV cannot be empty, try again!!\n"; end
10
+
11
+ # init.rb
12
+ def pb_already_setup; return "Your passbox is already setup. Please type 'passbox help' to see usage.\n"; end
13
+ def pb_not_setup; return "Passbox is not setup, use 'passbox init' command to start.\n"; end
14
+
15
+ # accounts.rb
16
+ def no_accounts; return "\nIts all empty here!! Use 'passbox add' to create new account.\n\n"; end
17
+ def enter_account_name; return "Please enter you account name: "; end
18
+ def account_not_found; return "Account not found, Use 'passbox list' to see all your existing accounts.\n"; end
19
+ def multiple_accounts; return "\nMultiple accounts found, please chose one: "; end
20
+ def invalid_selection; return "\nInvalid selection. Try again. Bye!!\n\n"; end
21
+
22
+ # create.rb
23
+ def too_many_attempts; return "\nToo many attempts. Start again!!\n\n"; end
24
+ def enter_account_name; return "\nEnter you account name (alphabets/numbers/underscore/dash): "; end
25
+ def account_already_exists; return "Account Name already exists, try different name!!\n"; end
26
+ def account_name_invalid; return "Alphabets, Numbers, Underscore and Dashes only, try again please!!\n"; end
27
+ def enter_username; return "Please enter in your username: "; end
28
+ def enter_url; return "Please enter in the login url: "; end
29
+ def enter_note; return "Enter note to self (optional): "; end
30
+ def enter_cc_no; return "Please enter in your credit/debit card number: "; end
31
+ def enter_cc_exp; return "Please enter your card expiry: "; end
32
+
33
+ # update.rb
34
+ def account_update_success; return "\nAccount details has been successfully updated!! \n"; end
35
+ def update_instructions; return "\nHit enter for no change or input a new value. \n"; end
36
+
37
+ # auth.rb
38
+ def enter_account_password; return "Please enter your Account Password: "; end
39
+ def enter_account_pin; return "Please enter you Account Pin: "; end
40
+ def enter_cc_cvv; return "Please enter you Card CVV: "; end
41
+ def enter_cc_pin; return "Please enter you Card Pin: "; end
42
+ def create_master_password; return "Please create your master password (min 8 chars): "; end
43
+ def re_enter_master_password; return "\nPlease re-enter your master password: "; end
44
+ def pb_setup_complete; return "\n\nPassbox setup complete. Use 'passbox help' to explore.\n\n"; end
45
+ def passwords_mismatch; return "\n\nPasswords don't match. Try again!!\n\n"; end
46
+ def password_validation; return "\nPassword should be minimum 8 characters, try again!!\n"; end
47
+ def enter_master_password; return "Please enter your Master Password: "; end
48
+ def thank_you; return "\n\nThank you for using passbox. Bye!!\n"; end
49
+ def invalid_password; return "\nInvalid Password!!\n"; end
50
+ def auth_success; return "Authentication Successful!!\n"; end
51
+ def auth_failed; return "Authentication Failed!!\n"; end
52
+
53
+ end
data/lib/passbox/init.rb CHANGED
@@ -3,13 +3,14 @@ module Passbox
3
3
  homedir = Dir.home
4
4
  $pbdir = homedir+"/.passbox"
5
5
  $passfile = $pbdir+"/pass.mp"
6
+ $options = {1=>"pb", 2=>"pn", 3=>"cc"}
6
7
 
7
8
  def init
8
9
  pass256=""
9
10
 
10
11
  if (Dir.exists?($pbdir))
11
12
  if(File.exists?($passfile))
12
- print "Your passbox is already setup. Please type 'passbox help' to see usage.\n"
13
+ print pb_already_setup
13
14
  return
14
15
  else
15
16
  pass256 = get_password_from_user(:master)
@@ -23,7 +24,8 @@ module Passbox
23
24
 
24
25
  def check_passbox
25
26
  if !File.exists?($passfile)
26
- print "Passbox is not setup, please start with 'passbox init' command to start using passbox\n"
27
+ print pb_not_setup
28
+ exit(0)
27
29
  end
28
30
  end
29
31
 
data/lib/passbox/version CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 2.0.0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaushal Rupani
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-26 00:00:00.000000000 Z
11
+ date: 2021-06-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A gem to store and manage password offline, encrypted using AES 256 strong
14
14
  encryption.
@@ -22,22 +22,29 @@ files:
22
22
  - README.md
23
23
  - bin/passbox
24
24
  - lib/passbox.rb
25
+ - lib/passbox/accounts.rb
25
26
  - lib/passbox/aes.rb
26
27
  - lib/passbox/auth.rb
27
- - lib/passbox/crud.rb
28
+ - lib/passbox/crud/create.rb
29
+ - lib/passbox/crud/delete.rb
30
+ - lib/passbox/crud/read.rb
31
+ - lib/passbox/crud/update.rb
32
+ - lib/passbox/helpers/colourize.rb
33
+ - lib/passbox/helpers/options.rb
34
+ - lib/passbox/helpers/strings.rb
28
35
  - lib/passbox/init.rb
29
36
  - lib/passbox/version
30
37
  homepage: https://github.com/krupani/passbox
31
38
  licenses:
32
39
  - MIT
33
40
  metadata: {}
34
- post_install_message:
41
+ post_install_message:
35
42
  rdoc_options: []
36
43
  require_paths:
37
44
  - lib
38
45
  required_ruby_version: !ruby/object:Gem::Requirement
39
46
  requirements:
40
- - - "~>"
47
+ - - ">="
41
48
  - !ruby/object:Gem::Version
42
49
  version: '2'
43
50
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -46,8 +53,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
46
53
  - !ruby/object:Gem::Version
47
54
  version: '0'
48
55
  requirements: []
49
- rubygems_version: 3.1.2
50
- signing_key:
56
+ rubygems_version: 3.2.3
57
+ signing_key:
51
58
  specification_version: 4
52
59
  summary: 'PassBox gem : AES encrypted offline password manager'
53
60
  test_files: []
data/lib/passbox/crud.rb DELETED
@@ -1,77 +0,0 @@
1
- module Passbox
2
- require 'json'
3
-
4
- def verify_account
5
- print "Please enter you account name (case-sensitive): "
6
- acc = gets.chomp
7
- if (!File.exists?("#{$pbdir}/#{acc}.pb"))
8
- print "Account not found, Use 'passbox list' to see all your existing accounts.\n"
9
- exit(0)
10
- end
11
- return acc
12
- end
13
-
14
- def creds(acc, key)
15
- print "Please enter in your account username: "
16
- uname = gets.chomp
17
- pass = get_password_from_user(:account)
18
- hash = {:username => uname, :password => pass}
19
- json = hash.to_json
20
- encrypt(json, key, "#{$pbdir}/#{acc}.pb")
21
- end
22
-
23
- def create_pass
24
- check_passbox
25
- key = passbox_auth
26
- if key
27
- while(true)
28
- print "\nEnter you account name (alphabets/numbers only): "
29
- acc = gets.chomp.downcase
30
- if (acc.count("a-z0-9") == acc.length)
31
- break
32
- else
33
- "\nAccount name can only have Alphabets and Numbers (no special characters), try again!!"
34
- end
35
- end
36
- end
37
- creds(acc,key)
38
- print "Account #{acc} has been successfully created!! \n"
39
- end
40
-
41
- def read_pass
42
- check_passbox
43
- acc=verify_account
44
- key = passbox_auth
45
- if key
46
- data = JSON.parse(decrypt("#{$pbdir}/#{acc}.pb", key))
47
- print "username : #{data['username']}\n"
48
- print "password : #{data['password']}\n"
49
- end
50
- end
51
-
52
- def update_pass
53
- check_passbox
54
- acc=verify_account
55
- key = passbox_auth
56
- creds(acc,key)
57
- print "Account details has been successfully updated!! \n"
58
- end
59
-
60
- def delete_pass
61
- check_passbox
62
- acc = verify_account
63
- if key
64
- File.delete("#{$pbdir}/#{acc}.pb")
65
- print("\nAccount #{acc} has been deleted!!")
66
- end
67
- end
68
-
69
- def list_of_accounts
70
- check_passbox
71
- files_ext = Dir["#{$pbdir}/*.pb"]
72
- files_ext.each_with_index do |file,i|
73
- print "#{i+1}. #{file.split('/').last.split('.').first}\n"
74
- end
75
- end
76
-
77
- end