uberpass 0.0.1
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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.rdoc +16 -0
- data/Rakefile +1 -0
- data/bin/uberpass +7 -0
- data/lib/uberpass/version.rb +3 -0
- data/lib/uberpass.rb +197 -0
- data/uberpass.gemspec +22 -0
- metadata +71 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
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
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: []
|