lockr 0.4.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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