Commit 6d0636f
Changed files (4)
lib
lib/tfa/cli.rb
@@ -9,31 +9,23 @@ module TFA
desc "add NAME SECRET", "add a new secret to the database"
def add(name, secret)
- open_database do
- storage.save(name, clean(secret))
- end
+ storage.save(name, clean(secret))
"Added #{name}"
end
desc "destroy NAME", "remove the secret associated with the name"
def destroy(name)
- open_database do
- storage.delete(name)
- end
+ storage.delete(name)
end
desc "show NAME", "shows the secret for the given key"
def show(name = nil)
- open_database do
- name ? storage.secret_for(name) : storage.all
- end
+ name ? storage.secret_for(name) : storage.all
end
desc "totp NAME", "generate a Time based One Time Password using the secret associated with the given NAME."
def totp(name = nil)
- open_database do
- TotpCommand.new(storage).run(name)
- end
+ TotpCommand.new(storage).run(name)
end
desc "now SECRET", "generate a Time based One Time Password for the given secret"
@@ -58,7 +50,6 @@ module TFA
yaml_storage.save(name, secret) if yes?("Migrate `#{name}`?")
end
end
- yaml_storage.encrypt!(passphrase)
File.delete(pstore_path) if yes?("Delete `#{pstore_path}`?")
end
end
@@ -67,14 +58,14 @@ module TFA
def encrypt
return unless ensure_upgraded!
- yaml_storage.encrypt!(passphrase)
+ yaml_storage.encrypt!
end
desc "decrypt", "decrypts the tfa database"
def decrypt
return unless ensure_upgraded!
- yaml_storage.decrypt!(passphrase)
+ yaml_storage.decrypt!
end
private
@@ -88,7 +79,7 @@ module TFA
end
def yaml_storage
- @yaml_storage ||= Storage.new(yaml_path)
+ @yaml_storage ||= SecureProxy.new(Storage.new(yaml_path), passphrase)
end
def filename
@@ -131,12 +122,5 @@ module TFA
def upgraded?
!File.exist?(pstore_path) && File.exist?(yaml_path)
end
-
- def open_database
- yaml_storage.decrypt!(passphrase) if upgraded?
- result = yield
- yaml_storage.encrypt!(passphrase)
- result
- end
end
end
lib/tfa/secure_proxy.rb
@@ -0,0 +1,53 @@
+module TFA
+ class SecureProxy
+ def initialize(original, passphrase)
+ @original = original
+ @digest = Digest::SHA256.digest(passphrase)
+ end
+
+ def encrypt!
+ cipher = OpenSSL::Cipher.new("AES-256-CBC")
+ cipher.encrypt
+ cipher.key = @digest
+ #iv = cipher.random_iv
+ #cipher.iv = iv
+
+ plain_text = read_all
+ #cipher_text = iv + cipher.update(plain_text) + cipher.final
+ cipher_text = cipher.update(plain_text) + cipher.final
+ flush(cipher_text)
+ end
+
+ def decrypt!
+ return unless File.exist?(@original.path)
+
+ cipher_text = read_all
+ decipher = OpenSSL::Cipher.new("AES-256-CBC")
+ decipher.decrypt
+ #decipher.iv = cipher_text[0..decipher.iv_len-1]
+ decipher.key = @digest
+ #data = cipher_text[decipher.iv_len..-1]
+ data = cipher_text
+ flush(decipher.update(data) + decipher.final)
+ end
+
+ private
+
+ def method_missing(name, *args, &block)
+ super unless @original.respond_to?(name)
+
+ decrypt!
+ result = @original.public_send(name, *args, &block)
+ encrypt!
+ result
+ end
+
+ def read_all
+ IO.read(@original.path)
+ end
+
+ def flush(data)
+ IO.write(@original.path, data)
+ end
+ end
+end
lib/tfa/storage.rb
@@ -43,30 +43,6 @@ module TFA
end
end
- def encrypt!(passphrase)
- cipher = OpenSSL::Cipher.new("AES-256-CBC")
- cipher.encrypt
- cipher.key = digest_for(passphrase)
- #iv = cipher.random_iv
- #cipher.iv = iv
-
- plain_text = read_all
- #cipher_text = iv + cipher.update(plain_text) + cipher.final
- cipher_text = cipher.update(plain_text) + cipher.final
- flush(cipher_text)
- end
-
- def decrypt!(passphrase)
- cipher_text = read_all
- decipher = OpenSSL::Cipher.new("AES-256-CBC")
- decipher.decrypt
- #decipher.iv = cipher_text[0..decipher.iv_len-1]
- decipher.key = digest_for(passphrase)
- #data = cipher_text[decipher.iv_len..-1]
- data = cipher_text
- flush(decipher.update(data) + decipher.final)
- end
-
private
def open_readonly
@@ -74,17 +50,5 @@ module TFA
yield @storage
end
end
-
- def read_all
- IO.read(path)
- end
-
- def flush(data)
- IO.write(path, data)
- end
-
- def digest_for(passphrase)
- Digest::SHA256.digest(passphrase)
- end
end
end
lib/tfa.rb
@@ -6,6 +6,7 @@ require "rotp"
require "yaml/store"
require "tfa/cli"
+require "tfa/secure_proxy"
require "tfa/storage"
require "tfa/totp_command"
require "tfa/version"