sekrets 1.2.0 → 1.3.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.
Files changed (5) hide show
  1. data/README +8 -0
  2. data/bin/sekrets +111 -3
  3. data/lib/sekrets.rb +153 -1
  4. data/sekrets.gemspec +1 -1
  5. 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
@@ -3,11 +3,11 @@
3
3
  Main {
4
4
  #
5
5
  synopsis <<-__
6
- ~> echo 'plaintext' | sekrets write sekrets.txt --key 42
6
+ ~> echo 'plaintext' | sekrets write sekrets.enc --key 42
7
7
 
8
- ~> sekrets read sekrets.txt --key 42
8
+ ~> sekrets read sekrets.enc --key 42
9
9
 
10
- ~> sekrets edit sekrets.txt
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
  }
@@ -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.2.0' unless defined?(Version)
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
  }
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification::new do |spec|
5
5
  spec.name = "sekrets"
6
- spec.version = "1.2.0"
6
+ spec.version = "1.3.0"
7
7
  spec.platform = Gem::Platform::RUBY
8
8
  spec.summary = "sekrets"
9
9
  spec.description = "description: sekrets kicks the ass"
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.2.0
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-21 00:00:00.000000000 Z
12
+ date: 2013-02-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: highline