lockr 0.4.5 → 0.5.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/bin/httplockr.rb +64 -0
  3. data/lib/lockr.rb +0 -4
  4. data/lib/lockr/action/add.rb +7 -14
  5. data/lib/lockr/action/base.rb +3 -24
  6. data/lib/lockr/action/list.rb +7 -8
  7. data/lib/lockr/action/remove.rb +7 -16
  8. data/lib/lockr/action/show.rb +6 -6
  9. data/lib/lockr/fileutils.rb +31 -8
  10. data/lib/lockr/http/httplockrinit.rb +79 -0
  11. data/lib/lockr/pwdmgr.rb +126 -0
  12. data/lib/lockr/sftp.rb +1 -1
  13. data/lib/lockr/version.rb +2 -2
  14. data/resources/static/css/images/animated-overlay.gif +0 -0
  15. data/resources/static/css/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png +0 -0
  16. data/resources/static/css/images/ui-bg_flat_15_cd0a0a_40x100.png +0 -0
  17. data/resources/static/css/images/ui-bg_glass_100_e4f1fb_1x400.png +0 -0
  18. data/resources/static/css/images/ui-bg_glass_50_3baae3_1x400.png +0 -0
  19. data/resources/static/css/images/ui-bg_glass_80_d7ebf9_1x400.png +0 -0
  20. data/resources/static/css/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png +0 -0
  21. data/resources/static/css/images/ui-bg_highlight-hard_70_000000_1x100.png +0 -0
  22. data/resources/static/css/images/ui-bg_highlight-soft_100_deedf7_1x100.png +0 -0
  23. data/resources/static/css/images/ui-bg_highlight-soft_25_ffef8f_1x100.png +0 -0
  24. data/resources/static/css/images/ui-icons_2694e8_256x240.png +0 -0
  25. data/resources/static/css/images/ui-icons_2e83ff_256x240.png +0 -0
  26. data/resources/static/css/images/ui-icons_3d80b3_256x240.png +0 -0
  27. data/resources/static/css/images/ui-icons_72a7cf_256x240.png +0 -0
  28. data/resources/static/css/images/ui-icons_ffffff_256x240.png +0 -0
  29. data/resources/static/css/jquery-ui-1.10.3.custom.min.css +7 -0
  30. data/resources/static/css/jquery.dataTables.css +221 -0
  31. data/resources/static/css/lockr.css +66 -0
  32. data/resources/static/js/jquery-2.0.0.min.js +6 -0
  33. data/resources/static/js/jquery-ui-1.10.3.custom.min.js +7 -0
  34. data/resources/static/js/jquery.dataTables.min.js +155 -0
  35. data/resources/static/js/lockr.js +95 -0
  36. data/resources/views/addnewsite.erb +12 -0
  37. data/resources/views/changepwd.erb +15 -0
  38. data/resources/views/deletepwd.erb +13 -0
  39. data/resources/views/entryrow.erb +15 -0
  40. data/resources/views/index.erb +44 -0
  41. data/resources/views/layout.erb +19 -0
  42. metadata +113 -9
  43. data/lib/lockr/action/aes.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7462c0421259aa68f618fed002fc646889a615eb
4
- data.tar.gz: a3d164b088c4145edd578065fa2ac9aa16d4ac5a
3
+ metadata.gz: 00c196c9cb57f262dee1286f37ffd5af4bfde695
4
+ data.tar.gz: cd8bd88ceec44eea89e2d62ad52c02d481cbb964
5
5
  SHA512:
6
- metadata.gz: faa4356345ce5db24951360a5b580e36d2d603938bc91f8dbedd5cca998b9e26525c3078e06d2be2c1730ed203c64f4d0f27ce583bcd51e13383790e14026b03
7
- data.tar.gz: 0f415641ee26e0946c3720fb68bca396ac60858261d10b4755a948ae128501711c15a40d6cc220d7af8b5516d82f4043e4c357977f0085c005f3e4ac701b3f1b
6
+ metadata.gz: 432c59d178834dd78d626c123b1025b344bba0c2e734d39baf0e051e10614b356a2cb3f347c2f0c1629ccce9667c4168f8bc19e91685d6d8a119a874b735d258
7
+ data.tar.gz: ff736641071a2fe9e4b7caee7d64666675254660fc8804596418c0829eeb66d1eff332c420814a8f931d1a0851afd145a9dd52882f921658da38dd8581c430ad
data/bin/httplockr.rb ADDED
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'lockr/http/httplockrinit'
4
+ require 'erb'
5
+ require 'clipboard'
6
+ require 'padrino-helpers'
7
+
8
+ include ERB::Util
9
+
10
+ init = HttpLockrInit.new()
11
+ init.start()
12
+
13
+ # now start sinatra
14
+ require 'sinatra'
15
+
16
+ if init.getLoadBrowser
17
+ require "browser_gui"
18
+ end
19
+
20
+ register Padrino::Helpers
21
+
22
+ set :pwdmgr, init.getPwdMgr()
23
+ # server config
24
+ set :public_dir, 'resources/static'
25
+ set :bind, '127.0.0.1'
26
+ set :port, 32187
27
+ set :views, 'resources/views'
28
+
29
+ get '/' do
30
+ dir = settings.pwdmgr.list()
31
+ erb :index, :locals => { :directory => dir }
32
+ end
33
+
34
+ get '/password' do
35
+ id = params[:id]
36
+ username = params[:username]
37
+ settings.pwdmgr.copy_to_clipboard( id, username)
38
+ redirect '/'
39
+ end
40
+
41
+ post '/password' do
42
+ id = params[:id]
43
+ username = params[:username]
44
+ password = params[:password]
45
+ newPwdstore = settings.pwdmgr.add( id, username, password)
46
+ dir = settings.pwdmgr.list()
47
+ redirect '/'
48
+ end
49
+
50
+ patch '/password' do
51
+ id = params[:id]
52
+ username = params[:username]
53
+ password = params[:password]
54
+ settings.pwdmgr.change( id, username, password)
55
+ redirect '/'
56
+ end
57
+
58
+ delete '/password' do
59
+ id = params[:id]
60
+ username = params[:username]
61
+ settings.pwdmgr.delete( id, username)
62
+ redirect '/'
63
+ end
64
+
data/lib/lockr.rb CHANGED
@@ -12,7 +12,6 @@ require 'lockr/config'
12
12
  require 'lockr/pwdgen'
13
13
  require 'lockr/sftp'
14
14
  require 'lockr/version'
15
- require 'lockr/fileutils'
16
15
 
17
16
  class Lockr
18
17
 
@@ -156,9 +155,6 @@ class Lockr
156
155
  end
157
156
 
158
157
  def process_actions( configfile, options)
159
- rotate_required = ( ! options[:download].nil? ) || ( ! %w{a add r remove}.index( options[:action]).nil? )
160
- FileUtils.rotate_file( options[:vault], 3) if rotate_required
161
-
162
158
  unless options[:download].nil?
163
159
  sftp = SFTP.new
164
160
  sftp.download( configfile, options[:vault])
@@ -1,15 +1,13 @@
1
- require 'lockr/action/aes'
2
- require 'lockr/pwdstore'
1
+ require 'lockr/action/base'
3
2
 
4
- class AddAction < AesAction
3
+ class AddAction < BaseAction
5
4
 
6
5
  def initialize(id,url,username,pwd,keyfile,vault)
7
- keyfilehash = FileUtils.calculate_sha512_hash( keyfile)
8
-
9
- pwd_directory = load_from_vault( vault)
6
+ super( keyfile, vault)
7
+ pwd_directory = @pwdmgr.list()
10
8
 
11
9
  if pwd_directory.has_key?( id)
12
- pwd_directory_id = YAML::load(decrypt( pwd_directory[id][:enc], keyfilehash, pwd_directory[id][:salt]))
10
+ pwd_directory_id = pwd_directory[id]
13
11
  else
14
12
  pwd_directory_id = {}
15
13
  end
@@ -21,13 +19,8 @@ class AddAction < AesAction
21
19
  end
22
20
  end
23
21
 
24
- new_store = PasswordStore.new( id, url, username, pwd)
25
- pwd_directory_id[username] = new_store
26
-
27
- pwd_directory[id] = {}
28
- pwd_directory[id][:enc], pwd_directory[id][:salt] = encrypt( pwd_directory_id.to_yaml, keyfilehash)
29
-
30
- save_to_vault( pwd_directory, vault)
22
+ # ###TODO add url
23
+ @pwdmgr.add( id, username, pwd)
31
24
  say("Password saved for ID '<%= color('#{id}', :blue) %>' and user '<%= color('#{username}', :green) %>'")
32
25
  end
33
26
 
@@ -1,28 +1,7 @@
1
- require 'openssl'
2
- require 'lockr/encryption/aes'
3
- require 'lockr/fileutils'
1
+ require 'lockr/pwdmgr'
4
2
 
5
3
  class BaseAction
6
- include FileUtils
7
-
8
- def save_to_vault( storelist, vault)
9
- FileUtils.store_obj_yaml( vault, storelist)
10
- end
11
-
12
- # loads the datastructure for the password sets from the file
13
- # it looks like this:
14
- #
15
- # pwd_directory = {
16
- # :id => {
17
- # :enc => 'encrypted password store list',
18
- # :salt => 'salt for decryption'
19
- # }
20
- # }
21
- #
22
- # decrypted_store_list = {
23
- # :username => PasswordStore
24
- # }
25
- def load_from_vault( vault)
26
- FileUtils.load_obj_yaml( vault)
4
+ def initialize( keyfile, vault)
5
+ @pwdmgr = PasswordManager.new( keyfile, vault)
27
6
  end
28
7
  end
@@ -1,20 +1,19 @@
1
- require 'lockr/action/aes'
2
- require 'lockr/pwdstore'
1
+ require 'lockr/action/base'
3
2
 
4
- class ListAction < AesAction
3
+ class ListAction < BaseAction
5
4
 
6
5
  def initialize( keyfile, vault)
7
- pwd_directory = load_from_vault( vault)
6
+ super( keyfile, vault)
7
+ pwdlist = @pwdmgr.list()
8
8
  out = []
9
9
 
10
10
  if keyfile.nil?
11
- pwd_directory.each { |id,value|
11
+ pwdlist.each { |id,value|
12
12
  out << "Id: #{id}"
13
13
  }
14
14
  else
15
- keyfilehash = FileUtils.calculate_sha512_hash( keyfile)
16
- pwd_directory.each { |oid,value|
17
- pwd_directory_id = YAML::load(decrypt( value[:enc], keyfilehash, value[:salt]))
15
+ pwdlist.each { |oid,site_directory|
16
+ pwd_directory_id = site_directory
18
17
  pwd_directory_id.each { |username, pwdstore|
19
18
  out << "Id: #{pwdstore.id} / Username: #{pwdstore.username}"
20
19
  }
@@ -1,18 +1,18 @@
1
- require 'lockr/action/aes'
2
- require 'lockr/pwdstore'
1
+ require 'lockr/action/base'
3
2
 
4
- class RemoveAction < AesAction
3
+ class RemoveAction < BaseAction
5
4
 
6
5
  def initialize(id,username,keyfile,vault)
7
- keyfilehash = FileUtils.calculate_sha512_hash( keyfile)
8
- pwd_directory = load_from_vault( vault)
6
+ super( keyfile, vault)
7
+
8
+ pwd_directory = @pwdmgr.list()
9
9
 
10
10
  unless pwd_directory.has_key?( id)
11
11
  puts "Id '#{id}' not found"
12
12
  exit 20
13
13
  end
14
14
 
15
- pwd_directory_id = YAML::load(decrypt( pwd_directory[id][:enc], keyfilehash, pwd_directory[id][:salt]))
15
+ pwd_directory_id = pwd_directory[id]
16
16
 
17
17
  unless pwd_directory_id.has_key?(username)
18
18
  puts "Username '#{username}' not found for id '#{id}'"
@@ -24,16 +24,7 @@ class RemoveAction < AesAction
24
24
  exit 22
25
25
  end
26
26
 
27
- pwd_directory_id.delete( username)
28
-
29
- if ( pwd_directory_id.size == 0 )
30
- pwd_directory.delete( id)
31
- else
32
- pwd_directory[id] = {}
33
- pwd_directory[id][:enc], pwd_directory[id][:salt] = encrypt( pwd_directory_id.to_yaml, keyfilehash)
34
- end
35
-
36
- save_to_vault( pwd_directory, vault)
27
+ @pwdmgr.delete( id, username)
37
28
  puts "Entry removed"
38
29
  end
39
30
 
@@ -1,18 +1,18 @@
1
- require 'lockr/action/aes'
1
+ require 'lockr/action/base'
2
2
 
3
- class ShowAction < AesAction
3
+ class ShowAction < BaseAction
4
4
 
5
- def initialize(id,username,keyfile, vault)
6
- keyfilehash = FileUtils.calculate_sha512_hash( keyfile)
5
+ def initialize(id, username, keyfile, vault)
6
+ super( keyfile, vault)
7
7
 
8
- pwd_directory = load_from_vault( vault)
8
+ pwd_directory = @pwdmgr.list()
9
9
 
10
10
  unless pwd_directory.has_key?( id)
11
11
  puts "Id '#{id}' not found"
12
12
  exit 10
13
13
  end
14
14
 
15
- pwd_directory_id = YAML::load(decrypt( pwd_directory[id][:enc], keyfilehash, pwd_directory[id][:salt]))
15
+ pwd_directory_id = pwd_directory[id]
16
16
 
17
17
  if username.nil?
18
18
  if pwd_directory_id.length == 1
@@ -1,8 +1,10 @@
1
- module FileUtils
1
+ require 'yaml'
2
+
3
+ module LockrFileUtils
2
4
 
3
5
  # rotate the provided file with a maximum of 'limit' backups
4
6
  # renamed filed will be named file_0, file_1, ...
5
- def FileUtils.rotate_file( file, limit)
7
+ def LockrFileUtils.rotate_file( file, limit)
6
8
  return unless File.exists?(file)
7
9
 
8
10
  # move old files first
@@ -10,11 +12,11 @@ module FileUtils
10
12
  max_files.downto( 0) { |i|
11
13
 
12
14
  if i == 0
13
- FileUtils.copy( file, "#{file}_#{i}")
15
+ LockrFileUtils.copy( file, "#{file}_#{i}")
14
16
  else
15
17
  j = i - 1
16
18
  if File.exists?("#{file}_#{j}")
17
- FileUtils.copy( "#{file}_#{j}", "#{file}_#{i}")
19
+ LockrFileUtils.copy( "#{file}_#{j}", "#{file}_#{i}")
18
20
  end
19
21
  end
20
22
  }
@@ -23,7 +25,7 @@ module FileUtils
23
25
  end
24
26
 
25
27
  # copy file_src to file_target
26
- def FileUtils.copy( file_src, file_target)
28
+ def LockrFileUtils.copy( file_src, file_target)
27
29
  return unless File.exists?( file_src)
28
30
 
29
31
  dst = File.new( file_target, 'w')
@@ -34,14 +36,14 @@ module FileUtils
34
36
  end
35
37
 
36
38
  # store an object as yaml to file
37
- def FileUtils.store_obj_yaml( file, object)
39
+ def LockrFileUtils.store_obj_yaml( file, object)
38
40
  File.open( file, 'w') do |f|
39
41
  f.write( object.to_yaml)
40
42
  end
41
43
  end
42
44
 
43
45
  # load an yaml object from file
44
- def FileUtils.load_obj_yaml( file)
46
+ def LockrFileUtils.load_obj_yaml( file)
45
47
  object = {}
46
48
 
47
49
  unless File.exist?( file)
@@ -56,7 +58,7 @@ module FileUtils
56
58
  end
57
59
 
58
60
  # calculate the sha512 hash of a file
59
- def FileUtils.calculate_sha512_hash( filename)
61
+ def LockrFileUtils.calculate_sha512_hash( filename)
60
62
  sha512 = OpenSSL::Digest::SHA512.new
61
63
 
62
64
  File.open( filename) do |file|
@@ -71,4 +73,25 @@ module FileUtils
71
73
 
72
74
  sha512.to_s
73
75
  end
76
+
77
+ def save_to_vault( storelist, vault)
78
+ LockrFileUtils.store_obj_yaml( vault, storelist)
79
+ end
80
+
81
+ # loads the datastructure for the password sets from the file
82
+ # it looks like this:
83
+ #
84
+ # pwd_directory = {
85
+ # :id => {
86
+ # :enc => 'encrypted password store list',
87
+ # :salt => 'salt for decryption'
88
+ # }
89
+ # }
90
+ #
91
+ # decrypted_store_list = {
92
+ # :username => PasswordStore
93
+ # }
94
+ def load_from_vault( vault)
95
+ LockrFileUtils.load_obj_yaml( vault)
96
+ end
74
97
  end
@@ -0,0 +1,79 @@
1
+ require 'optparse'
2
+ require 'lockr/config'
3
+ require 'lockr/pwdmgr'
4
+
5
+ class HttpLockrInit
6
+
7
+ def start()
8
+ options = parse_options()
9
+
10
+ unless options[:keyfile]
11
+ puts 'Please provide a keyfile'
12
+ raise ArgumentError
13
+ end
14
+
15
+ configfile = Configuration.new()
16
+ cfg = configfile.config[:lockr]
17
+ options[:vault] = File.expand_path(cfg[:vault]) if options[:vault] == 'vault.yaml'
18
+
19
+ @pwdmgr = PasswordManager.new( options[:keyfile], options[:vault])
20
+ @load_browser = options[:browser]
21
+ end
22
+
23
+ def getPwdMgr
24
+ return @pwdmgr
25
+ end
26
+
27
+ def getLoadBrowser
28
+ return @load_browser
29
+ end
30
+
31
+ def parse_options()
32
+ options = {}
33
+
34
+ optparse = OptionParser.new do|opts|
35
+ # Set a banner, displayed at the top
36
+ # of the help screen.
37
+ opts.banner = "Usage: httplockr [options]"
38
+
39
+ options[:keyfile] = nil
40
+ opts.on( '-k', '--keyfile FILE', 'the FILE to use as key for the password encryption') do |file|
41
+ options[:keyfile] = File.expand_path(file)
42
+ end
43
+
44
+ options[:vault] = 'vault.yaml'
45
+ opts.on( '-v', '--vault FILE', 'FILE is the name of the vault to store the password sets') do |file|
46
+ options[:vault] = File.expand_path(file)
47
+ end
48
+
49
+ options[:browser] = false
50
+ opts.on( '-b', '--browser', 'open browser windows for lockr') do |d|
51
+ options[:browser] = true
52
+ end
53
+
54
+ # This displays the help screen, all programs are
55
+ # assumed to have this option.
56
+ opts.on( '-h', '--help', 'Display this screen' ) do
57
+ puts opts
58
+ exit
59
+ end
60
+
61
+ opts.on('--version', 'Show version') do
62
+ puts "HttpLockr #{LockrVer::VERSION} (#{LockrVer::DATE})"
63
+ exit
64
+ end
65
+
66
+ opts.separator ""
67
+ opts.separator "For detailed instructions on how to use HttpLockr, please visit http://lockr.byteblues.com"
68
+ end
69
+
70
+ # Parse the command-line. Remember there are two forms
71
+ # of the parse method. The 'parse' method simply parses
72
+ # ARGV, while the 'parse!' method parses ARGV and removes
73
+ # any options found there, as well as any parameters for
74
+ # the options. What's left is the list of files to resize.
75
+ optparse.parse!
76
+
77
+ options
78
+ end
79
+ end
@@ -0,0 +1,126 @@
1
+ require 'lockr/encryption/aes'
2
+ require 'lockr/pwdstore'
3
+ require 'lockr/fileutils'
4
+ require 'rufus/scheduler'
5
+
6
+ class PasswordManager
7
+ include Aes
8
+ include LockrFileUtils
9
+
10
+ NUM_BACKUP_FILES = 3
11
+
12
+ def initialize( keyfile, vault)
13
+ puts "Initializing Password manager module. Vault: '#{vault}', Keyfile: '...'"
14
+ @vault_file = vault
15
+ @keyfile = keyfile
16
+ @scheduler = Rufus::Scheduler.new
17
+ end
18
+
19
+ def list()
20
+ return decrypt_vault()
21
+ end
22
+
23
+ def copy_to_clipboard( id, username)
24
+ vault = decrypt_vault()
25
+
26
+ Clipboard.copy vault[id][username].password
27
+ puts 'Password copied to clipboard'
28
+
29
+ if @job != nil
30
+ begin
31
+ @scheduler.unschedule( @job)
32
+ puts 'Unscheduled old clear task'
33
+ rescue ArgumentError
34
+ # job no longer active
35
+ end
36
+ end
37
+
38
+ puts 'Scheduling clipboard reset in 15 seconds'
39
+ @job = @scheduler.in '15s' do
40
+ Clipboard.copy ' '
41
+ puts 'Clipboard cleared'
42
+ end
43
+ end
44
+
45
+ def add( id, username, password)
46
+ vault = decrypt_vault()
47
+ site_dir = {}
48
+
49
+ # get site directory
50
+ if vault.has_key?( id)
51
+ site_dir = vault[id]
52
+ end
53
+
54
+ # TODO add url
55
+ new_store = PasswordStore.new( id, nil, username, password)
56
+ site_dir[username] = new_store
57
+ vault[id] = site_dir
58
+
59
+ encrypt_vault( vault)
60
+ puts 'Added new id/username combination'
61
+ return new_store
62
+ end
63
+
64
+ def change( id, username, password)
65
+ vault = decrypt_vault()
66
+ site_dir = vault[id]
67
+ site_dir[username].password = password
68
+
69
+ encrypt_vault( vault)
70
+ puts 'Changed password'
71
+ end
72
+
73
+ def delete( id, username)
74
+ vault = decrypt_vault()
75
+ site_dir = vault[id]
76
+
77
+ site_dir.delete( username)
78
+
79
+ if ( site_dir.size == 0 )
80
+ vault.delete( id)
81
+ end
82
+
83
+ encrypt_vault( vault)
84
+ puts 'Deleted password'
85
+ end
86
+
87
+ private
88
+
89
+ def decrypt_vault()
90
+ pwd_directory = load_from_vault( @vault_file)
91
+ keyfilehash = '00000000' # initialize with dummy hash
92
+
93
+ if ( @keyfile != nil )
94
+ keyfilehash = LockrFileUtils.calculate_sha512_hash( @keyfile)
95
+ end
96
+
97
+ vault = {}
98
+
99
+ pwd_directory.each { |id,site_dir_enc|
100
+ begin
101
+ vault[id] = YAML::load(decrypt( site_dir_enc[:enc], keyfilehash, site_dir_enc[:salt]))
102
+ rescue OpenSSL::Cipher::CipherError
103
+ # could not decrypt
104
+ vault[id] = nil
105
+ end
106
+ }
107
+
108
+ return vault
109
+ end
110
+
111
+ def encrypt_vault( vault)
112
+ LockrFileUtils.rotate_file( @vault_file, NUM_BACKUP_FILES)
113
+ keyfilehash = LockrFileUtils.calculate_sha512_hash( @keyfile)
114
+
115
+ pwd_directory = {}
116
+
117
+ vault.each { |id, site_dir_dec|
118
+ pwd_directory[id] = {}
119
+ pwd_directory[id][:enc], pwd_directory[id][:salt] = encrypt( site_dir_dec.to_yaml, keyfilehash)
120
+ }
121
+
122
+ save_to_vault( pwd_directory, @vault_file)
123
+ puts 'Vault saved'
124
+ end
125
+
126
+ end