sekrets 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +8 -0
- data/bin/sekrets +111 -3
- data/lib/sekrets.rb +153 -1
- data/sekrets.gemspec +1 -1
- metadata +2 -2
data/README
CHANGED
@@ -59,6 +59,14 @@ DESCRIPTION
|
|
59
59
|
|
60
60
|
settings = Sekrets.settings_for('./config/settings.yml.enc')
|
61
61
|
|
62
|
+
RAILS
|
63
|
+
gem 'sekrets' # Gemfile
|
64
|
+
|
65
|
+
bundle install
|
66
|
+
|
67
|
+
rake sekrets:generate:key
|
68
|
+
rake sekrets:generate:editor
|
69
|
+
rake sekrets:generate:config
|
62
70
|
|
63
71
|
DESCRIPTION
|
64
72
|
sekrets provides commandline tools and a library to manage and access
|
data/bin/sekrets
CHANGED
@@ -3,11 +3,11 @@
|
|
3
3
|
Main {
|
4
4
|
#
|
5
5
|
synopsis <<-__
|
6
|
-
~> echo 'plaintext' | sekrets write sekrets.
|
6
|
+
~> echo 'plaintext' | sekrets write sekrets.enc --key 42
|
7
7
|
|
8
|
-
~> sekrets read sekrets.
|
8
|
+
~> sekrets read sekrets.enc --key 42
|
9
9
|
|
10
|
-
~> sekrets edit sekrets.
|
10
|
+
~> sekrets edit sekrets.enc
|
11
11
|
__
|
12
12
|
|
13
13
|
description <<-__
|
@@ -142,6 +142,21 @@ Main {
|
|
142
142
|
|
143
143
|
#
|
144
144
|
mode(:write){
|
145
|
+
synopsis <<-__
|
146
|
+
write encrypted data to file
|
147
|
+
__
|
148
|
+
|
149
|
+
description <<-__
|
150
|
+
write mode writes it's input (default STDIN) to output (deafult STDOUT)
|
151
|
+
after encrypting it with key
|
152
|
+
__
|
153
|
+
|
154
|
+
examples <<-__
|
155
|
+
~> echo 'the pazzw0rd' | sekrets write -k 42 > sekrets.enc
|
156
|
+
|
157
|
+
~> sekrets write output.enc input.txt -k 42
|
158
|
+
__
|
159
|
+
|
145
160
|
argument('output', 'o'){
|
146
161
|
argument :required
|
147
162
|
default STDOUT
|
@@ -171,6 +186,21 @@ Main {
|
|
171
186
|
|
172
187
|
#
|
173
188
|
mode(:read){
|
189
|
+
synopsis <<-__
|
190
|
+
reads encrypted data from a file
|
191
|
+
__
|
192
|
+
|
193
|
+
description <<-__
|
194
|
+
read mode reads it's input (default STDIN) and writes it's output
|
195
|
+
(default STDOUT) after decrypting it with key
|
196
|
+
__
|
197
|
+
|
198
|
+
examples <<-__
|
199
|
+
~> cat output.enc | sekrets read -k 42
|
200
|
+
|
201
|
+
~> sekrets read output.enc output.dec -k 42
|
202
|
+
__
|
203
|
+
|
174
204
|
argument('input', 'i'){
|
175
205
|
argument :required
|
176
206
|
default STDIN
|
@@ -198,8 +228,75 @@ Main {
|
|
198
228
|
end
|
199
229
|
}
|
200
230
|
|
231
|
+
|
232
|
+
#
|
233
|
+
mode(:recrypt){
|
234
|
+
synopsis <<-__
|
235
|
+
re-encrypts a file with a new key
|
236
|
+
__
|
237
|
+
|
238
|
+
description <<-__
|
239
|
+
provide the old and new key by using the --key option twice
|
240
|
+
|
241
|
+
the first key is the current decryption key
|
242
|
+
|
243
|
+
the second key is the new one
|
244
|
+
|
245
|
+
if you do not provide the keys as options you will be prompted for them
|
246
|
+
__
|
247
|
+
|
248
|
+
examples <<-__
|
249
|
+
~> sekrets recrypt sekrets.enc -k current_key -k new_key
|
250
|
+
__
|
251
|
+
|
252
|
+
argument(:path)
|
253
|
+
|
254
|
+
option('key', 'k'){
|
255
|
+
argument :required
|
256
|
+
}
|
257
|
+
|
258
|
+
def run
|
259
|
+
path = params[:path].value
|
260
|
+
|
261
|
+
cur_key, new_key, *ignored = params[:key].values.first(2)
|
262
|
+
|
263
|
+
unless cur_key
|
264
|
+
cur_key = Sekrets.ask("#{ path } [cur key]")
|
265
|
+
end
|
266
|
+
|
267
|
+
unless new_key
|
268
|
+
new_key = Sekrets.ask("#{ path } [new key]")
|
269
|
+
end
|
270
|
+
|
271
|
+
decrypted = Sekrets.read(path, :key => cur_key)
|
272
|
+
encrypted = Sekrets.write(path, decrypted, :key => new_key)
|
273
|
+
decrypted = Sekrets.read(path, :key => new_key)
|
274
|
+
puts path
|
275
|
+
end
|
276
|
+
}
|
277
|
+
|
201
278
|
#
|
202
279
|
mode(:edit){
|
280
|
+
synopsis <<-__
|
281
|
+
spawn an external editor to edit an encrypted file
|
282
|
+
__
|
283
|
+
|
284
|
+
description <<-__
|
285
|
+
edit mode looks first to the unix environment variable SEKRETS_EDTIOR
|
286
|
+
or, if that is not found, the normal EDITOR variable to determine which
|
287
|
+
editor to launch. it assumes that your editor can be launched from the
|
288
|
+
commandline with a file as single argument. vim is the default editor.
|
289
|
+
|
290
|
+
after the editor program exits succesfully the temporary file is
|
291
|
+
encrypted and saved.
|
292
|
+
__
|
293
|
+
|
294
|
+
examples <<-__
|
295
|
+
~> sekrets edit my.passwords.txt -k
|
296
|
+
|
297
|
+
~> EDITOR=mate sekrets edit my.passwords.txt -k
|
298
|
+
__
|
299
|
+
|
203
300
|
argument(:path)
|
204
301
|
|
205
302
|
option('key', 'k'){
|
@@ -252,13 +349,24 @@ Main {
|
|
252
349
|
|
253
350
|
BEGIN {
|
254
351
|
require 'pathname'
|
352
|
+
|
255
353
|
bindir = Pathname.new(__FILE__).dirname.to_s
|
256
354
|
root = File.dirname(bindir)
|
257
355
|
libdir = File.join(root, 'lib')
|
356
|
+
|
258
357
|
require "#{ libdir }/sekrets.rb"
|
358
|
+
|
259
359
|
begin
|
260
360
|
require 'pry'
|
261
361
|
rescue Object
|
262
362
|
nil
|
263
363
|
end
|
364
|
+
|
365
|
+
trap('SIGINT'){ STDERR.puts; exit!(42) }
|
366
|
+
|
367
|
+
if((sekrets_argv = ENV['SEKRETS_ARGV']))
|
368
|
+
ENV.delete('SEKRETS_ARGV')
|
369
|
+
command = [$0, sekrets_argv, *ARGV].flatten.compact.join(' ')
|
370
|
+
exec(command)
|
371
|
+
end
|
264
372
|
}
|
data/lib/sekrets.rb
CHANGED
@@ -242,6 +242,38 @@ class Sekrets
|
|
242
242
|
path
|
243
243
|
end
|
244
244
|
|
245
|
+
def Sekrets.binstub
|
246
|
+
@binstub ||= (
|
247
|
+
unindent(
|
248
|
+
<<-__
|
249
|
+
#! /usr/bin/env ruby
|
250
|
+
|
251
|
+
require 'pathname'
|
252
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
253
|
+
Pathname.new(__FILE__).realpath)
|
254
|
+
|
255
|
+
require 'rubygems'
|
256
|
+
require 'bundler/setup'
|
257
|
+
|
258
|
+
ciphertext = File.expand_path('ciphertext',
|
259
|
+
File.dirname(__FILE__))
|
260
|
+
ENV['SEKRETS_ARGV'] = "edit \#{ ciphertext }"
|
261
|
+
|
262
|
+
exec(Gem.bin_path('sekrets', 'sekrets'))
|
263
|
+
__
|
264
|
+
)
|
265
|
+
)
|
266
|
+
end
|
267
|
+
|
268
|
+
def Sekrets.unindent(string)
|
269
|
+
indent = string.split("\n").select {|line| !line.strip.empty? }.map {|line| line.index(/[^\s]/) }.compact.min || 0
|
270
|
+
string.gsub(/^[[:blank:]]{#{indent}}/, '')
|
271
|
+
end
|
272
|
+
|
273
|
+
def Sekrets.unindent!(string)
|
274
|
+
string.replace(string.unindent)
|
275
|
+
end
|
276
|
+
|
245
277
|
#
|
246
278
|
module Blowfish
|
247
279
|
def cipher(mode, key, data)
|
@@ -286,7 +318,7 @@ BEGIN {
|
|
286
318
|
require 'tmpdir'
|
287
319
|
|
288
320
|
class Sekrets < ::String
|
289
|
-
Version = '1.
|
321
|
+
Version = '1.3.0' unless defined?(Version)
|
290
322
|
|
291
323
|
class << Sekrets
|
292
324
|
def version
|
@@ -342,4 +374,124 @@ BEGIN {
|
|
342
374
|
|
343
375
|
__
|
344
376
|
}
|
377
|
+
|
378
|
+
if defined?(Rails)
|
379
|
+
|
380
|
+
class Sekrets
|
381
|
+
class Engine < Rails::Engine
|
382
|
+
engine_name :sekrets
|
383
|
+
|
384
|
+
rake_tasks do
|
385
|
+
namespace :sekrets do
|
386
|
+
namespace :generate do
|
387
|
+
#
|
388
|
+
desc 'generate a .sekrets.key'
|
389
|
+
task :key do
|
390
|
+
keyfile = File.join(Rails.root, '.sekrets.key')
|
391
|
+
abort("#{ keyfile } exists!") if test(?e, keyfile)
|
392
|
+
key = SecureRandom.hex
|
393
|
+
open(keyfile, 'wb'){|fd| fd.puts(key)}
|
394
|
+
|
395
|
+
begin
|
396
|
+
gitignore = File.join(Rails.root, '.gitignore')
|
397
|
+
buf = IO.read(gitignore)
|
398
|
+
|
399
|
+
unless buf =~ /\.sekrets\.key/
|
400
|
+
open(gitignore, 'a+') do |fd|
|
401
|
+
fd.puts
|
402
|
+
fd.puts '.sekrets.key'
|
403
|
+
fd.puts
|
404
|
+
end
|
405
|
+
end
|
406
|
+
rescue Object
|
407
|
+
end
|
408
|
+
|
409
|
+
puts "created #{ Rails.root }/.sekrets.key"
|
410
|
+
puts "do *NOT* commit this file"
|
411
|
+
puts
|
412
|
+
puts "updated #{ Rails.root }/.gitignore"
|
413
|
+
puts "yes *DO* commit this file"
|
414
|
+
puts
|
415
|
+
puts "*** YOU NEED TO DISTRIBUTE THIS KEY TO YOUR TEAM ***"
|
416
|
+
puts
|
417
|
+
puts "*** YOU NEED DEPLOY THIS KEY WITH YOUR APPLICATION ***"
|
418
|
+
puts
|
419
|
+
puts "hint: require 'sekrets/capistrano' in your Capfile"
|
420
|
+
puts
|
421
|
+
end
|
422
|
+
|
423
|
+
#
|
424
|
+
desc 'generate a secure editor for plaintext application sekrets'
|
425
|
+
task :editor do
|
426
|
+
keyfile = File.join(Rails.root, '.sekrets.key')
|
427
|
+
abort("run 'rake sekrets:generate:key' first") unless test(?e, keyfile)
|
428
|
+
key = IO.binread(keyfile).strip
|
429
|
+
|
430
|
+
editor = File.join(Rails.root, 'sekrets', 'editor')
|
431
|
+
ciphertext = File.join(Rails.root, 'sekrets', 'ciphertext')
|
432
|
+
|
433
|
+
unless test(?s, editor)
|
434
|
+
FileUtils.mkdir_p(File.dirname(editor))
|
435
|
+
open(editor, 'wb'){|fd| fd.write(Sekrets.binstub)}
|
436
|
+
File.chmod(0755, editor)
|
437
|
+
puts "created #{ editor }"
|
438
|
+
end
|
439
|
+
|
440
|
+
unless test(?s, ciphertext)
|
441
|
+
content = "# store sensitive infomation like credit cards, ssh keys, and passwords here\n\n\n"
|
442
|
+
Sekrets.write(ciphertext, content, :key => key)
|
443
|
+
puts "created #{ ciphertext }"
|
444
|
+
end
|
445
|
+
|
446
|
+
puts "run ./sekrets/editor to edit ./sekrets/ciphertext"
|
447
|
+
end
|
448
|
+
|
449
|
+
#
|
450
|
+
desc 'generate a secure config for application sekrets'
|
451
|
+
task :config do
|
452
|
+
keyfile = File.join(Rails.root, '.sekrets.key')
|
453
|
+
abort("run 'rake sekrets:generate:key' first") unless test(?e, keyfile)
|
454
|
+
key = IO.binread(keyfile).strip
|
455
|
+
|
456
|
+
config = File.join(Rails.root, 'config', 'sekrets.yml.enc')
|
457
|
+
unless test(?s, config)
|
458
|
+
FileUtils.mkdir_p(File.dirname(config))
|
459
|
+
require 'yaml' unless defined?(YAML)
|
460
|
+
content = {'api_key' => 42}.to_yaml
|
461
|
+
Sekrets.write(config, content, :key => key)
|
462
|
+
puts "created #{ config }"
|
463
|
+
end
|
464
|
+
|
465
|
+
initializer = File.join(Rails.root, 'config', 'initializers', 'sekrets.rb')
|
466
|
+
unless test(?s, initializer)
|
467
|
+
FileUtils.mkdir_p(File.dirname(initializer))
|
468
|
+
open(initializer, 'wb') do |fd|
|
469
|
+
code = <<-__
|
470
|
+
|
471
|
+
config = File.join(Rails.root, 'config', 'sekrets.yml.enc')
|
472
|
+
key = File.join(Rails.root, '.sekrets.key')
|
473
|
+
|
474
|
+
if test(?e, config)
|
475
|
+
if test(?e, key)
|
476
|
+
SEKRETS = Sekrets.settings_for(config)
|
477
|
+
else
|
478
|
+
SEKRETS = Map.new
|
479
|
+
warn "missing \#{ key }!"
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
__
|
484
|
+
fd.puts(code)
|
485
|
+
end
|
486
|
+
puts "created #{ initializer }"
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
end
|
345
497
|
}
|
data/sekrets.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sekrets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: highline
|