uberpass 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in uberpass.gemspec
4
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,16 @@
1
+ = Über password
2
+
3
+ == Create keypair
4
+
5
+ $ openssl genrsa -des3 -out ~/.uberpass/private.pem 2048
6
+ $ openssl rsa -in ~/.uberpass/private.pem -out ~/.uberpass/public.pem -outform PEM -pubout
7
+
8
+ == Use
9
+
10
+ You personal passwords:
11
+
12
+ $ uberpass
13
+
14
+ or you work related passwords:
15
+
16
+ $ uberpass happy_place
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/uberpass ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Signal.trap("INT") { exit }
4
+
5
+ require 'uberpass'
6
+
7
+ Uberpass::CLI.new(ARGV.pop)
@@ -0,0 +1,3 @@
1
+ module Uberpass
2
+ VERSION = "0.0.1"
3
+ end
data/lib/uberpass.rb ADDED
@@ -0,0 +1,197 @@
1
+ require 'uberpass/version'
2
+ require 'openssl'
3
+ require 'yaml'
4
+
5
+ module Uberpass
6
+ class Decrypt
7
+ attr_reader :decrypted_data
8
+
9
+ def initialize(private_key, encrypted_data, encrypted_key, encrypted_iv)
10
+ key = OpenSSL::PKey::RSA.new(private_key)
11
+ cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
12
+ cipher.decrypt
13
+ cipher.key = key.private_decrypt(encrypted_key)
14
+ cipher.iv = key.private_decrypt(encrypted_iv)
15
+
16
+ @decrypted_data = cipher.update(encrypted_data)
17
+ @decrypted_data << cipher.final
18
+ end
19
+ end
20
+
21
+ class Encrypt
22
+ attr_reader :encrypted_data, :encrypted_key, :encrypted_iv
23
+
24
+ def initialize(public_key, decrypted_data)
25
+ key = OpenSSL::PKey::RSA.new(public_key)
26
+ cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
27
+ cipher.encrypt
28
+ cipher.key = random_key = cipher.random_key
29
+ cipher.iv = random_iv = cipher.random_iv
30
+
31
+ @encrypted_data = cipher.update(decrypted_data)
32
+ @encrypted_data << cipher.final
33
+
34
+ @encrypted_key = key.public_encrypt(random_key)
35
+ @encrypted_iv = key.public_encrypt(random_iv)
36
+ end
37
+ end
38
+
39
+ class FileHandler
40
+ class << self
41
+ attr_accessor :namespace
42
+
43
+ def configure
44
+ yield self
45
+ end
46
+
47
+ def name_spaced_file(file_name)
48
+ @namespace.nil? ? file_name : "#{file_name}_#{@namespace}"
49
+ end
50
+
51
+ def private_key_file
52
+ File.expand_path("~/.uberpass/private.pem")
53
+ end
54
+
55
+ def public_key_file
56
+ File.expand_path("~/.uberpass/public.pem")
57
+ end
58
+
59
+ def passwords_file
60
+ File.expand_path("~/.uberpass/#{name_spaced_file("passwords")}")
61
+ end
62
+
63
+ def key_file
64
+ File.expand_path("~/.uberpass/#{name_spaced_file("key")}")
65
+ end
66
+
67
+ def iv_file
68
+ File.expand_path("~/.uberpass/#{name_spaced_file("iv")}")
69
+ end
70
+
71
+ def show_password(key)
72
+ passwords = decrypted_passwords
73
+ passwords[key]["password"] unless passwords[key].nil?
74
+ end
75
+
76
+ def list_keys
77
+ decrypted_passwords.keys
78
+ end
79
+
80
+ def decrypted_passwords
81
+ if File.exists?(passwords_file)
82
+ YAML::load(
83
+ Decrypt.new(
84
+ File.read(private_key_file),
85
+ File.read(passwords_file),
86
+ File.read(key_file),
87
+ File.read(iv_file)
88
+ ).decrypted_data
89
+ )
90
+ else
91
+ {}
92
+ end
93
+ end
94
+
95
+ def new_password(key)
96
+ passwords = decrypted_passwords
97
+ passwords[key] = {
98
+ "password" => Array.new(32).map{ rand(2) == 1 ? (65 + rand(58)).chr : rand(10) }.join,
99
+ "created_at" => Time.now
100
+ }
101
+ encryptor = Encrypt.new(File.read(public_key_file), passwords.to_yaml)
102
+ write(encryptor)
103
+ passwords[key]["password"]
104
+ end
105
+
106
+ def destroy_password(key)
107
+ passwords = decrypted_passwords
108
+ entry = passwords.delete key
109
+ encryptor = Encrypt.new(File.read(public_key_file), passwords.to_yaml)
110
+ write(encryptor)
111
+ entry
112
+ end
113
+
114
+ def write(encryptor)
115
+ File.open(passwords_file, "w") { |file|
116
+ file.write(encryptor.encrypted_data)
117
+ }
118
+ File.open(key_file, "w") { |file|
119
+ file.write(encryptor.encrypted_key)
120
+ }
121
+ File.open(iv_file, "w") { |file|
122
+ file.write(encryptor.encrypted_iv)
123
+ }
124
+ end
125
+ end
126
+ end
127
+
128
+ class CLI
129
+ def initialize(namespace)
130
+ FileHandler.configure do |handler|
131
+ handler.namespace = namespace
132
+ end
133
+ print "\nactions:\n"
134
+ print " generate\n"
135
+ print " destroy\n"
136
+ print " reveal\n"
137
+ print " list\n"
138
+ print " exit\n"
139
+ actions
140
+ end
141
+
142
+ def actions
143
+ print "\n> "
144
+ action, argument = $stdin.gets.chomp.split(' ')
145
+ do_action_with_rescue action, argument
146
+ end
147
+
148
+ def do_action_with_rescue(action, argument)
149
+ begin
150
+ do_action action, argument
151
+ rescue OpenSSL::PKey::RSAError
152
+ print "\nInvalid PEM pass phrase. Please try again.\n\n"
153
+ do_action_with_rescue action, argument
154
+ end
155
+ end
156
+
157
+ def do_action(action, argument)
158
+ case action
159
+ when "generate", "g"
160
+ if argument.to_s.strip == ""
161
+ print "choose a name ie. generate twitter"
162
+ else
163
+ password = FileHandler.new_password(argument)
164
+ print "password for #{argument}: #{password}\n"
165
+ end
166
+ when "destroy", "d"
167
+ if argument.to_s.strip == ""
168
+ print "choose a name ie. destroy twitter"
169
+ else
170
+ print "\nare you sure you? [yn] "
171
+ if $stdin.gets.chomp == "y"
172
+ FileHandler.destroy_password(argument)
173
+ print "password removed\n"
174
+ end
175
+ end
176
+ when "reveal", "r"
177
+ if argument.to_s.strip == ""
178
+ print "choose a name ie. reveal twitter"
179
+ else
180
+ password = FileHandler.show_password(argument)
181
+ print "password for #{argument}: #{password}\n"
182
+ end
183
+ when "list", "l"
184
+ keys = FileHandler.list_keys
185
+ print "\n"
186
+ keys.each do |key|
187
+ print " - #{key}\n"
188
+ end
189
+ when "exit"
190
+ exit
191
+ else
192
+ print "invalid option"
193
+ end
194
+ actions
195
+ end
196
+ end
197
+ end
data/uberpass.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "uberpass/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "uberpass"
7
+ s.version = Uberpass::VERSION
8
+ s.authors = ["Rufus Post"]
9
+ s.email = ["rufuspost@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{command line key chain}
12
+ s.description = %q{uses open ssl and a cli to generate and retrieve passwords}
13
+
14
+ s.rubyforge_project = "uberpass"
15
+
16
+ s.add_development_dependency "rake"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uberpass
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Rufus Post
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &70271985916320 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70271985916320
25
+ description: uses open ssl and a cli to generate and retrieve passwords
26
+ email:
27
+ - rufuspost@gmail.com
28
+ executables:
29
+ - uberpass
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - README.rdoc
36
+ - Rakefile
37
+ - bin/uberpass
38
+ - lib/uberpass.rb
39
+ - lib/uberpass/version.rb
40
+ - uberpass.gemspec
41
+ homepage: ''
42
+ licenses: []
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ segments:
54
+ - 0
55
+ hash: 3622611926086671674
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ segments:
63
+ - 0
64
+ hash: 3622611926086671674
65
+ requirements: []
66
+ rubyforge_project: uberpass
67
+ rubygems_version: 1.8.11
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: command line key chain
71
+ test_files: []