leeloo 0.3.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/lib/leeloo.rb +2 -0
- data/lib/leeloo/command.rb +76 -68
- data/lib/leeloo/controller.rb +122 -0
- data/lib/leeloo/keystore.rb +44 -0
- data/lib/leeloo/output.rb +28 -13
- data/lib/leeloo/preferences.rb +4 -3
- data/lib/leeloo/secret.rb +15 -0
- data/lib/leeloo/server.rb +37 -0
- data/lib/leeloo/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 45be4ecf01ce08cd7317d3c6f9d8a612d999b972efdcbfe322a964a06f77a303
|
|
4
|
+
data.tar.gz: bd3a8767c2c1d70cdc21856b180cb7f3651c9777471f70a35af810130650d4ef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1ec00409e8ac173872aac71537aad50d40f93a24634b1b101b6f46b59d658696c2480d6e5157fd7cd1d864acc4cc6ec5e421eed6ff74f560c4e25f57ecd7bd27
|
|
7
|
+
data.tar.gz: 1d259f7fc29192bcf6d1cd3a7f7f92d8e9244d79e11741f2fce8f82f8aab0d7cfd5c96ad120c16aa018b8c69540e937e6986a8f18a297a7d137d748e5e19511d
|
data/lib/leeloo.rb
CHANGED
data/lib/leeloo/command.rb
CHANGED
|
@@ -9,29 +9,9 @@ end
|
|
|
9
9
|
|
|
10
10
|
module Leeloo
|
|
11
11
|
|
|
12
|
-
class OutputFactory
|
|
13
|
-
def self.create options
|
|
14
|
-
output = nil
|
|
15
|
-
if options.ascii
|
|
16
|
-
output = Ascii.new
|
|
17
|
-
else
|
|
18
|
-
output = Terminal.new
|
|
19
|
-
end
|
|
20
|
-
if options.clipboard
|
|
21
|
-
ClipboardOutputDecorator.new output
|
|
22
|
-
else
|
|
23
|
-
output
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
12
|
class Command
|
|
29
13
|
include Commander::Methods
|
|
30
14
|
|
|
31
|
-
def initialize
|
|
32
|
-
@preferences = PrivateLocalFileSystemPreferences.new.load
|
|
33
|
-
end
|
|
34
|
-
|
|
35
15
|
def run
|
|
36
16
|
program :name, 'leeloo'
|
|
37
17
|
program :version, Leeloo::VERSION
|
|
@@ -52,8 +32,7 @@ module Leeloo
|
|
|
52
32
|
c.option '--keystore STRING', String, 'a selected keystore'
|
|
53
33
|
|
|
54
34
|
c.action do |args, options|
|
|
55
|
-
|
|
56
|
-
OutputFactory.create(options).render_secrets keystore.secrets
|
|
35
|
+
SecretsController.new(options).display
|
|
57
36
|
end
|
|
58
37
|
end
|
|
59
38
|
|
|
@@ -66,10 +45,9 @@ module Leeloo
|
|
|
66
45
|
c.action do |args, options|
|
|
67
46
|
abort "name is missing" unless args.length == 1
|
|
68
47
|
name = args.first
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
OutputFactory.create(options).render_secrets secrets
|
|
48
|
+
ctl = SecretsController.new(options)
|
|
49
|
+
ctl.search(name)
|
|
50
|
+
ctl.display
|
|
73
51
|
end
|
|
74
52
|
end
|
|
75
53
|
|
|
@@ -79,7 +57,7 @@ module Leeloo
|
|
|
79
57
|
c.option '--ascii', nil, 'display secrets without unicode tree'
|
|
80
58
|
|
|
81
59
|
c.action do |args, options|
|
|
82
|
-
|
|
60
|
+
KeystoreController.new(options).display
|
|
83
61
|
end
|
|
84
62
|
end
|
|
85
63
|
|
|
@@ -87,10 +65,12 @@ module Leeloo
|
|
|
87
65
|
c.syntax = 'leeloo keystore remove <name>'
|
|
88
66
|
c.description = "remove a keystore (path/to/keystore is not destroyed)"
|
|
89
67
|
|
|
90
|
-
c.action do |args, options|
|
|
68
|
+
c.action do |args, options|args
|
|
91
69
|
abort "name is missing" unless args.length == 1
|
|
92
|
-
|
|
93
|
-
|
|
70
|
+
name = args.first
|
|
71
|
+
ctl = KeystoreController.new(options)
|
|
72
|
+
ctl.remove(name)
|
|
73
|
+
ctl.display
|
|
94
74
|
end
|
|
95
75
|
end
|
|
96
76
|
|
|
@@ -100,10 +80,11 @@ module Leeloo
|
|
|
100
80
|
|
|
101
81
|
c.action do |args, options|
|
|
102
82
|
abort "name or path is missing" unless args.length == 2
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
83
|
+
name = args.first
|
|
84
|
+
path = args.last
|
|
85
|
+
ctl = KeystoreController.new(options)
|
|
86
|
+
ctl.add(name, path)
|
|
87
|
+
ctl.display
|
|
107
88
|
end
|
|
108
89
|
end
|
|
109
90
|
|
|
@@ -113,9 +94,10 @@ module Leeloo
|
|
|
113
94
|
|
|
114
95
|
c.action do |args, options|
|
|
115
96
|
abort "name is missing" unless args.length == 1
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
97
|
+
name = args.first
|
|
98
|
+
ctl = KeystoreController.new(options)
|
|
99
|
+
ctl.set_default(name)
|
|
100
|
+
ctl.display
|
|
119
101
|
end
|
|
120
102
|
end
|
|
121
103
|
|
|
@@ -129,10 +111,9 @@ module Leeloo
|
|
|
129
111
|
c.action do |args, options|
|
|
130
112
|
abort "name is missing" unless args.length == 1
|
|
131
113
|
name = args.first
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
OutputFactory.create(options).render_secret secret
|
|
114
|
+
ctl = SecretController.new(options)
|
|
115
|
+
ctl.read(name)
|
|
116
|
+
ctl.display
|
|
136
117
|
end
|
|
137
118
|
end
|
|
138
119
|
|
|
@@ -147,22 +128,9 @@ module Leeloo
|
|
|
147
128
|
c.action do |args, options|
|
|
148
129
|
abort "name is missing" unless args.length == 1
|
|
149
130
|
name = args.first
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
phrase = SecureRandom.base64(32).truncate(options.generate.to_i) if options.generate
|
|
154
|
-
|
|
155
|
-
unless phrase
|
|
156
|
-
phrase = password "secret"
|
|
157
|
-
confirm = password "confirm it"
|
|
158
|
-
abort "not the same secret" unless phrase == confirm
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
keystore = @preferences.keystore(options.keystore)
|
|
162
|
-
secret = keystore.secret_from_name(name)
|
|
163
|
-
secret.write(phrase)
|
|
164
|
-
|
|
165
|
-
OutputFactory.create(options).render_secret secret
|
|
131
|
+
ctl = SecretController.new(options)
|
|
132
|
+
ctl.write(name)
|
|
133
|
+
ctl.display
|
|
166
134
|
end
|
|
167
135
|
end
|
|
168
136
|
|
|
@@ -172,9 +140,9 @@ module Leeloo
|
|
|
172
140
|
c.option '--keystore STRING', String, 'a selected keystore'
|
|
173
141
|
|
|
174
142
|
c.action do |args, options|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
143
|
+
ctl = TranslateController.new(options)
|
|
144
|
+
ctl.translate
|
|
145
|
+
ctl.display
|
|
178
146
|
end
|
|
179
147
|
end
|
|
180
148
|
|
|
@@ -186,10 +154,9 @@ module Leeloo
|
|
|
186
154
|
c.action do |args, options|
|
|
187
155
|
abort "name is missing" unless args.length == 1
|
|
188
156
|
name = args.first
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
secret.erase
|
|
157
|
+
ctl = SecretController.new(options)
|
|
158
|
+
ctl.remove(name)
|
|
159
|
+
ctl.display
|
|
193
160
|
end
|
|
194
161
|
end
|
|
195
162
|
|
|
@@ -199,8 +166,9 @@ module Leeloo
|
|
|
199
166
|
c.option '--keystore STRING', String, 'a selected keystore'
|
|
200
167
|
|
|
201
168
|
c.action do |args, options|
|
|
202
|
-
|
|
203
|
-
|
|
169
|
+
ctl = KeystoreController.new(options)
|
|
170
|
+
ctl.sync
|
|
171
|
+
ctl.display
|
|
204
172
|
end
|
|
205
173
|
end
|
|
206
174
|
|
|
@@ -210,8 +178,48 @@ module Leeloo
|
|
|
210
178
|
c.option '--keystore STRING', String, 'a selected keystore'
|
|
211
179
|
|
|
212
180
|
c.action do |args, options|
|
|
213
|
-
|
|
214
|
-
|
|
181
|
+
ctl = KeystoreController.new(options)
|
|
182
|
+
ctl.init
|
|
183
|
+
ctl.display
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
command :share do |c|
|
|
188
|
+
c.syntax = 'leeloo share <name>'
|
|
189
|
+
c.description = "share a secret with someone"
|
|
190
|
+
c.option '--keystore STRING', String, 'a selected keystore'
|
|
191
|
+
|
|
192
|
+
c.action do |args, options|
|
|
193
|
+
abort "name is missing" unless args.length == 1
|
|
194
|
+
name = args.first
|
|
195
|
+
ctl = ShareController.new(options)
|
|
196
|
+
ctl.token(name)
|
|
197
|
+
ctl.display
|
|
198
|
+
ctl.start_server
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
command :token do |c|
|
|
203
|
+
c.syntax = 'leeloo token <name>'
|
|
204
|
+
c.description = "generate an access token for a given secret"
|
|
205
|
+
c.option '--keystore STRING', String, 'a selected keystore'
|
|
206
|
+
|
|
207
|
+
c.action do |args, options|
|
|
208
|
+
abort "name is missing" unless args.length == 1
|
|
209
|
+
name = args.first
|
|
210
|
+
ctl = ShareController.new(options)
|
|
211
|
+
ctl.token(name)
|
|
212
|
+
ctl.display
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
command :server do |c|
|
|
217
|
+
c.syntax = 'leeloo server'
|
|
218
|
+
c.description = "start a server access token"
|
|
219
|
+
|
|
220
|
+
c.action do |args, options|
|
|
221
|
+
ctl = ShareController.new(options)
|
|
222
|
+
ctl.start_server
|
|
215
223
|
end
|
|
216
224
|
end
|
|
217
225
|
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
module Leeloo
|
|
2
|
+
class OutputFactory
|
|
3
|
+
def self.create options
|
|
4
|
+
output = nil
|
|
5
|
+
if options.ascii
|
|
6
|
+
output = Ascii.new
|
|
7
|
+
else
|
|
8
|
+
output = Terminal.new
|
|
9
|
+
end
|
|
10
|
+
if options.clipboard
|
|
11
|
+
ClipboardOutputDecorator.new output
|
|
12
|
+
else
|
|
13
|
+
output
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Controller
|
|
19
|
+
def display
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class PrivateLocalFileSystemController < Controller
|
|
24
|
+
def initialize options
|
|
25
|
+
@preferences = PrivateLocalFileSystemPreferences.new.load
|
|
26
|
+
@keystore = @preferences.keystore(options.keystore)
|
|
27
|
+
@output = OutputFactory.create(options)
|
|
28
|
+
@options = options
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class SecretsController < PrivateLocalFileSystemController
|
|
33
|
+
def initialize options
|
|
34
|
+
super options
|
|
35
|
+
@secrets = @preferences.keystore(@options.keystore).secrets
|
|
36
|
+
end
|
|
37
|
+
def search name
|
|
38
|
+
@secrets = @secrets.select { |secret| secret.name.downcase.include? name.downcase } || []
|
|
39
|
+
end
|
|
40
|
+
def display
|
|
41
|
+
@output.render_secrets @secrets
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class SecretController < PrivateLocalFileSystemController
|
|
46
|
+
def read name
|
|
47
|
+
@secret = @keystore.secret_from_name(name)
|
|
48
|
+
end
|
|
49
|
+
def write name
|
|
50
|
+
phrase = nil
|
|
51
|
+
|
|
52
|
+
phrase = STDIN.read if @options.stdin
|
|
53
|
+
phrase = SecureRandom.base64(32).truncate(@options.generate.to_i) if @options.generate
|
|
54
|
+
|
|
55
|
+
unless phrase
|
|
56
|
+
phrase = password "secret"
|
|
57
|
+
confirm = password "confirm it"
|
|
58
|
+
abort "not the same secret" unless phrase == confirm
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
@secret = @keystore.secret_from_name(name)
|
|
62
|
+
@secret.write(phrase)
|
|
63
|
+
end
|
|
64
|
+
def remove name
|
|
65
|
+
@secret = @keystore.secret_from_name(name)
|
|
66
|
+
@secret.erase
|
|
67
|
+
end
|
|
68
|
+
def display
|
|
69
|
+
@output.render_secret @secret
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class TranslateController < PrivateLocalFileSystemController
|
|
74
|
+
def translate
|
|
75
|
+
@text = STDIN.read
|
|
76
|
+
@text.scan(/\$\{.*\}/).each do |secret|
|
|
77
|
+
begin
|
|
78
|
+
@text.gsub! secret, (@keystore.secret_from_name(secret[2..-2])).read.to_s.strip
|
|
79
|
+
rescue => exception
|
|
80
|
+
# silent
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
def display
|
|
85
|
+
@output.render_text @text
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
class KeystoreController < PrivateLocalFileSystemController
|
|
90
|
+
def add name, path
|
|
91
|
+
@preferences.add_keystore({"name" => name, "path" => path, "cypher" => "gpg", "vc" => "git"})
|
|
92
|
+
@preferences.keystore(name).init
|
|
93
|
+
end
|
|
94
|
+
def remove name
|
|
95
|
+
@preferences.remove_keystore name
|
|
96
|
+
end
|
|
97
|
+
def set_default name
|
|
98
|
+
@preferences.set_default_keystore name
|
|
99
|
+
end
|
|
100
|
+
def sync
|
|
101
|
+
@keystore.sync
|
|
102
|
+
end
|
|
103
|
+
def init
|
|
104
|
+
@keystore.init
|
|
105
|
+
end
|
|
106
|
+
def display
|
|
107
|
+
@output.render_preferences @preferences
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
class ShareController < PrivateLocalFileSystemController
|
|
112
|
+
def token name
|
|
113
|
+
@footprint = @keystore.footprint_of(name)
|
|
114
|
+
end
|
|
115
|
+
def start_server
|
|
116
|
+
Server.new.start @preferences
|
|
117
|
+
end
|
|
118
|
+
def display
|
|
119
|
+
@output.render_footprint @footprint
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
data/lib/leeloo/keystore.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'gpgme'
|
|
2
2
|
require 'fileutils'
|
|
3
3
|
require 'git'
|
|
4
|
+
require 'base64'
|
|
4
5
|
|
|
5
6
|
module Leeloo
|
|
6
7
|
|
|
@@ -51,6 +52,14 @@ module Leeloo
|
|
|
51
52
|
# initialize the keystore
|
|
52
53
|
end
|
|
53
54
|
|
|
55
|
+
def footprint name
|
|
56
|
+
# footprint a given secret path
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def secret_from_footprint footprint
|
|
60
|
+
# returns a secret object
|
|
61
|
+
end
|
|
62
|
+
|
|
54
63
|
def == keystore
|
|
55
64
|
self.name == keystore.name
|
|
56
65
|
end
|
|
@@ -92,6 +101,19 @@ module Leeloo
|
|
|
92
101
|
secret_of "#{path}/secrets/#{name}"
|
|
93
102
|
end
|
|
94
103
|
|
|
104
|
+
def footprint_of name
|
|
105
|
+
secret = secret_from_name name
|
|
106
|
+
{ "footprint" => secret.footprint, "keystore" => self.name, "secret" => secret.name }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def secret_from_footprint footprint
|
|
110
|
+
secret = secret_from_name footprint["secret"]
|
|
111
|
+
unless secret.footprint == footprint["footprint"]
|
|
112
|
+
raise "footprint is not valid"
|
|
113
|
+
end
|
|
114
|
+
secret
|
|
115
|
+
end
|
|
116
|
+
|
|
95
117
|
end
|
|
96
118
|
|
|
97
119
|
class GpgPrivateLocalFileSystemKeystore < PrivateLocalFileSystemKeystore
|
|
@@ -119,6 +141,20 @@ module Leeloo
|
|
|
119
141
|
secret_of "#{path}/secrets/#{name}.gpg"
|
|
120
142
|
end
|
|
121
143
|
|
|
144
|
+
def footprint_of name
|
|
145
|
+
footprint = super name
|
|
146
|
+
footprint["sign"] = Base64.strict_encode64 GPGME::Crypto.new.sign(footprint["footprint"]).to_s
|
|
147
|
+
footprint
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def secret_from_footprint footprint
|
|
151
|
+
data = GPGME::Crypto.new.verify(Base64.strict_decode64 footprint["sign"]) { |signature| signature.valid? }
|
|
152
|
+
if data.read == footprint["footprint"]
|
|
153
|
+
super footprint
|
|
154
|
+
else
|
|
155
|
+
raise "signature is not valid"
|
|
156
|
+
end
|
|
157
|
+
end
|
|
122
158
|
end
|
|
123
159
|
|
|
124
160
|
class GitKeystoreDecorator < Keystore
|
|
@@ -148,6 +184,14 @@ module Leeloo
|
|
|
148
184
|
@keystore.path
|
|
149
185
|
end
|
|
150
186
|
|
|
187
|
+
def footprint_of element
|
|
188
|
+
@keystore.footprint_of element
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def secret_from_footprint footprint
|
|
192
|
+
@keystore.secret_from_footprint footprint
|
|
193
|
+
end
|
|
194
|
+
|
|
151
195
|
def sync
|
|
152
196
|
@git.pull
|
|
153
197
|
@keystore.sync
|
data/lib/leeloo/output.rb
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
require 'clipboard'
|
|
2
2
|
require 'tty-table'
|
|
3
3
|
require 'tty-tree'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'base64'
|
|
6
|
+
require 'socket'
|
|
4
7
|
|
|
5
8
|
module Leeloo
|
|
6
9
|
|
|
@@ -15,7 +18,13 @@ module Leeloo
|
|
|
15
18
|
def render_secret secret
|
|
16
19
|
end
|
|
17
20
|
|
|
18
|
-
def
|
|
21
|
+
def render_text text
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def render_footprint footprint
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def render_share footprint
|
|
19
28
|
end
|
|
20
29
|
end
|
|
21
30
|
|
|
@@ -37,16 +46,14 @@ module Leeloo
|
|
|
37
46
|
end
|
|
38
47
|
end
|
|
39
48
|
|
|
40
|
-
def
|
|
41
|
-
text.scan(/\$\{.*\}/).each do |secret|
|
|
42
|
-
begin
|
|
43
|
-
text.gsub! secret, (keystore.secret_from_name(secret[2..-2])).read.to_s.strip
|
|
44
|
-
rescue => exception
|
|
45
|
-
# silent
|
|
46
|
-
end
|
|
47
|
-
end
|
|
49
|
+
def render_text text
|
|
48
50
|
puts text
|
|
49
51
|
end
|
|
52
|
+
|
|
53
|
+
def render_footprint footprint
|
|
54
|
+
puts "token:"
|
|
55
|
+
puts Base64.strict_encode64 footprint.to_json
|
|
56
|
+
end
|
|
50
57
|
end
|
|
51
58
|
|
|
52
59
|
class Terminal < Ascii
|
|
@@ -107,16 +114,16 @@ module Leeloo
|
|
|
107
114
|
@output.render_secrets secrets
|
|
108
115
|
end
|
|
109
116
|
|
|
110
|
-
def
|
|
111
|
-
@output.
|
|
117
|
+
def render_text text
|
|
118
|
+
@output.render_text text
|
|
112
119
|
end
|
|
113
120
|
|
|
114
121
|
def render_secret secret
|
|
115
122
|
|
|
116
123
|
Signal.trap("INT") do
|
|
117
124
|
Clipboard.clear
|
|
118
|
-
abort "
|
|
119
|
-
|
|
125
|
+
abort "cleared"
|
|
126
|
+
end
|
|
120
127
|
|
|
121
128
|
Clipboard.copy secret.read
|
|
122
129
|
wait = Thread.new do
|
|
@@ -129,6 +136,14 @@ module Leeloo
|
|
|
129
136
|
wait.join
|
|
130
137
|
Clipboard.clear
|
|
131
138
|
end
|
|
139
|
+
|
|
140
|
+
def render_footprint footprint
|
|
141
|
+
@output.render_footprint footprint
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def render_share footprint
|
|
145
|
+
@output.render_share footprint
|
|
146
|
+
end
|
|
132
147
|
end
|
|
133
148
|
|
|
134
149
|
end
|
data/lib/leeloo/preferences.rb
CHANGED
|
@@ -34,8 +34,9 @@ module Leeloo
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def remove_keystore name
|
|
37
|
+
abort "you can not remove default keystore" if name == @default
|
|
37
38
|
keystore = @keystores.find { |k| k["name"] == name }
|
|
38
|
-
if keystore !=nil
|
|
39
|
+
if keystore != nil
|
|
39
40
|
@keystores.delete keystore
|
|
40
41
|
end
|
|
41
42
|
end
|
|
@@ -70,8 +71,8 @@ module Leeloo
|
|
|
70
71
|
self
|
|
71
72
|
end
|
|
72
73
|
|
|
73
|
-
def keystore_of
|
|
74
|
-
keystore = @keystores.find { |keystore| keystore["name"] ==
|
|
74
|
+
def keystore_of name
|
|
75
|
+
keystore = @keystores.find { |keystore| keystore["name"] == name }
|
|
75
76
|
KeystoreFactory::create keystore
|
|
76
77
|
end
|
|
77
78
|
|
data/lib/leeloo/secret.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'gpgme'
|
|
2
2
|
require 'fileutils'
|
|
3
|
+
require 'digest'
|
|
3
4
|
|
|
4
5
|
module Leeloo
|
|
5
6
|
class Secret
|
|
@@ -26,6 +27,9 @@ module Leeloo
|
|
|
26
27
|
# erase the secret
|
|
27
28
|
end
|
|
28
29
|
|
|
30
|
+
def footprint
|
|
31
|
+
# a footprint is a token proving the authenticity of a secret
|
|
32
|
+
end
|
|
29
33
|
end
|
|
30
34
|
|
|
31
35
|
class LocalFileSystemSecret < Secret
|
|
@@ -50,6 +54,13 @@ module Leeloo
|
|
|
50
54
|
File.delete @pathname
|
|
51
55
|
end
|
|
52
56
|
|
|
57
|
+
def footprint
|
|
58
|
+
secret = File.read @pathname
|
|
59
|
+
md5 = Digest::MD5.new
|
|
60
|
+
md5 << secret
|
|
61
|
+
md5.hexdigest
|
|
62
|
+
end
|
|
63
|
+
|
|
53
64
|
end
|
|
54
65
|
|
|
55
66
|
class GpgLocalFileSystemSecret < LocalFileSystemSecret
|
|
@@ -88,6 +99,10 @@ module Leeloo
|
|
|
88
99
|
@secret.read
|
|
89
100
|
end
|
|
90
101
|
|
|
102
|
+
def footprint
|
|
103
|
+
@secret.footprint
|
|
104
|
+
end
|
|
105
|
+
|
|
91
106
|
def write phrase
|
|
92
107
|
@secret.write phrase
|
|
93
108
|
@git.add @secret.pathname
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'webrick'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'base64'
|
|
4
|
+
|
|
5
|
+
class Server
|
|
6
|
+
|
|
7
|
+
def start preferences
|
|
8
|
+
|
|
9
|
+
puts """
|
|
10
|
+
Please share this url :
|
|
11
|
+
http://your_ip:8000\?q=YOUR_TOKEN
|
|
12
|
+
|
|
13
|
+
run ssh -R:localhost:8000 ssh.localhost.run
|
|
14
|
+
if you want to share your password through tunneling
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
server = WEBrick::HTTPServer.new :Port => 8000
|
|
18
|
+
server.mount_proc '/' do |req, res|
|
|
19
|
+
query = req.query()["q"] || req.body()
|
|
20
|
+
if query
|
|
21
|
+
begin
|
|
22
|
+
body = JSON.parse(Base64.strict_decode64 query)
|
|
23
|
+
key = body["body"] ? JSON.parse(body["body"]) : body
|
|
24
|
+
res.body = preferences.keystore(key["keystore"]).secret_from_footprint(key).read.to_s
|
|
25
|
+
rescue => exception
|
|
26
|
+
puts exception
|
|
27
|
+
res.status = 400
|
|
28
|
+
end
|
|
29
|
+
else
|
|
30
|
+
res.status = 400
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
trap 'INT' do server.shutdown end
|
|
35
|
+
server.start
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/leeloo/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: leeloo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- sylvek
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-
|
|
11
|
+
date: 2019-12-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: commander
|
|
@@ -147,10 +147,12 @@ files:
|
|
|
147
147
|
- exe/leeloo
|
|
148
148
|
- lib/leeloo.rb
|
|
149
149
|
- lib/leeloo/command.rb
|
|
150
|
+
- lib/leeloo/controller.rb
|
|
150
151
|
- lib/leeloo/keystore.rb
|
|
151
152
|
- lib/leeloo/output.rb
|
|
152
153
|
- lib/leeloo/preferences.rb
|
|
153
154
|
- lib/leeloo/secret.rb
|
|
155
|
+
- lib/leeloo/server.rb
|
|
154
156
|
- lib/leeloo/version.rb
|
|
155
157
|
homepage: https://github.com/sylvek/leeloo
|
|
156
158
|
licenses:
|