Class: Passw3rd::PasswordService
- Inherits:
-
Object
- Object
- Passw3rd::PasswordService
- Defined in:
- lib/passw3rd/password_service.rb
Class Attribute Summary collapse
Class Method Summary collapse
- .cipher_name ⇒ Object
- .cipher_name=(cipher_name) ⇒ Object
- .configure(&block) ⇒ Object
- .create_key_iv_file(path = nil) ⇒ Object
- .decrypt(cipher_text, key_path = self.key_file_dir) ⇒ Object
- .encrypt(password, key_path = self.key_file_dir) ⇒ Object
- .get_password(password_file, options = {:key_path => self.key_file_dir, :force => true}) ⇒ Object
- .iv_path(path = ::Passw3rd::PasswordService.key_file_dir) ⇒ Object
- .key_path(path = self.key_file_dir) ⇒ Object
- .rotate_keys(args = {}) ⇒ Object
- .write_password_file(password, output_path, key_path = self.key_file_dir) ⇒ Object
Class Attribute Details
.key_file_dir ⇒ Object
18 19 20 |
# File 'lib/passw3rd/password_service.rb', line 18 def key_file_dir @key_file_dir || ENV['passw3rd-key_file_dir'] || Dir.getwd end |
.password_file_dir ⇒ Object
13 14 15 |
# File 'lib/passw3rd/password_service.rb', line 13 def password_file_dir @password_file_dir || ENV['passw3rd-password_file_dir'] || Dir.getwd end |
Class Method Details
.cipher_name ⇒ Object
27 28 29 |
# File 'lib/passw3rd/password_service.rb', line 27 def cipher_name defined?(@cipher_name) ? @cipher_name : APPROVED_CIPHERS.first end |
.cipher_name=(cipher_name) ⇒ Object
22 23 24 25 |
# File 'lib/passw3rd/password_service.rb', line 22 def cipher_name= (cipher_name) raise "Hey man, you can only use #{APPROVED_CIPHERS}, you supplied #{cipher_name}" if cipher_name.nil? || !APPROVED_CIPHERS.include?(cipher_name) @cipher_name = ENV['passw3rd-cipher_name'] || cipher_name end |
.configure(&block) ⇒ Object
32 33 34 |
# File 'lib/passw3rd/password_service.rb', line 32 def self.configure(&block) instance_eval &block end |
.create_key_iv_file(path = nil) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/passw3rd/password_service.rb', line 105 def self.create_key_iv_file(path = nil) unless path path = ::Passw3rd::PasswordService.key_file_dir end # d'oh! cipher = OpenSSL::Cipher::Cipher.new(::Passw3rd::PasswordService.cipher_name) iv = cipher.random_iv key = cipher.random_key begin File.open(self.key_path(path), 'w') {|f| f.write(key.unpack("H*").join) } File.open(self.iv_path(path), 'w') {|f| f.write(iv.unpack("H*").join) } rescue puts "Couldn't write key/IV to #{path}\n" raise $! end path end |
.decrypt(cipher_text, key_path = self.key_file_dir) ⇒ Object
65 66 67 68 69 70 71 72 73 74 |
# File 'lib/passw3rd/password_service.rb', line 65 def self.decrypt(cipher_text, key_path = self.key_file_dir) cipher = cipher_setup(:decrypt, key_path) begin d = cipher.update(cipher_text) d << cipher.final rescue OpenSSL::Cipher::CipherError => err puts "Couldn't decrypt password #{cipher_text}. Are you using the right keys (#{key_path})?" raise err end end |
.encrypt(password, key_path = self.key_file_dir) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/passw3rd/password_service.rb', line 52 def self.encrypt(password, key_path = self.key_file_dir) raise ArgumentError, "password cannot be blank" if password.to_s.empty? cipher = cipher_setup(:encrypt, key_path) begin e = cipher.update(password) e << cipher.final rescue OpenSSL::Cipher::CipherError => err puts "Couldn't encrypt password." raise err end end |
.get_password(password_file, options = {:key_path => self.key_file_dir, :force => true}) ⇒ Object
36 37 38 39 40 41 42 |
# File 'lib/passw3rd/password_service.rb', line 36 def self.get_password (password_file, = {:key_path => self.key_file_dir, :force => true}) uri = _parse_uri(password_file) encoded_password = read_file(uri) decrypt(encoded_password, [:key_path]) rescue => e raise ArgumentError, "Could not decrypt passw3rd file #{password_file} - #{e}" if [:force] end |
.iv_path(path = ::Passw3rd::PasswordService.key_file_dir) ⇒ Object
129 130 131 |
# File 'lib/passw3rd/password_service.rb', line 129 def self.iv_path(path = ::Passw3rd::PasswordService.key_file_dir) File.join(path || self.key_file_dir, IV_FILE) end |
.key_path(path = self.key_file_dir) ⇒ Object
125 126 127 |
# File 'lib/passw3rd/password_service.rb', line 125 def self.key_path(path= self.key_file_dir) File.join(path || self.key_file_dir, KEY_FILE) end |
.rotate_keys(args = {}) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/passw3rd/password_service.rb', line 76 def self.rotate_keys(args = {}) unless args.empty? ::Passw3rd::PasswordService.configure do |c| c.password_file_dir = args[:password_file_dir] c.key_file_dir = args[:key_file_dir] c.cipher_name = args[:cipher] end end passwords = [] Dir.foreach(::Passw3rd::PasswordService.password_file_dir) do |passw3rd_file| next if %w{. ..}.include?(passw3rd_file) || passw3rd_file =~ /\A\.passw3rd/ puts "Rotating #{passw3rd_file}" passwords << {:clear_password => ::Passw3rd::PasswordService.get_password(passw3rd_file), :file => passw3rd_file} end ::Passw3rd::PasswordService.cipher_name = args[:new_cipher] if args[:new_cipher] path = self.create_key_iv_file puts "Wrote new keys to #{path}" passwords.each do |password| full_path = File.join(::Passw3rd::PasswordService.password_file_dir, password[:file]) ::Passw3rd::PasswordService.write_password_file(password[:clear_password], password[:file]) puts "Wrote new password to #{full_path}" end end |
.write_password_file(password, output_path, key_path = self.key_file_dir) ⇒ Object
44 45 46 47 48 49 50 |
# File 'lib/passw3rd/password_service.rb', line 44 def self.write_password_file(password, output_path, key_path = self.key_file_dir) enc_password = encrypt(password, key_path) base64pw = Base64.encode64(enc_password) path = File.join(password_file_dir, output_path) write_file(path, base64pw) path end |