obfusc 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a7fc494a9e84b4aaf03a3f8329f20ea56c75351f
4
+ data.tar.gz: a3b07cbc913a684a1fb3a03ef4c1a93bbad32768
5
+ SHA512:
6
+ metadata.gz: da322a96246e4a6089df5015daa7573a9380e8676d3fd17f9c29876801f96ad1b1348b22648d7bfad095fb71ef0d408a1e3e556fde1ba9ef41cba67ccce6074b
7
+ data.tar.gz: f8d63efaab57384ff143e71f5c638c684c80b31836ad526d64aab2fe1d5ea5dae708407152384e819f340ef160b9692e63343cf93a04c1512e85d3d89439f09c
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ obfusc-*.gem
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.16.0
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ gem 'pry', '~> 0.11.3'
6
+
7
+ # Specify your gem's dependencies in obfusc.gemspec
8
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ obfusc (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ coderay (1.1.2)
10
+ diff-lcs (1.3)
11
+ method_source (0.9.0)
12
+ pry (0.11.3)
13
+ coderay (~> 1.1.0)
14
+ method_source (~> 0.9.0)
15
+ rake (10.5.0)
16
+ rspec (3.7.0)
17
+ rspec-core (~> 3.7.0)
18
+ rspec-expectations (~> 3.7.0)
19
+ rspec-mocks (~> 3.7.0)
20
+ rspec-core (3.7.1)
21
+ rspec-support (~> 3.7.0)
22
+ rspec-expectations (3.7.0)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.7.0)
25
+ rspec-mocks (3.7.0)
26
+ diff-lcs (>= 1.2.0, < 2.0)
27
+ rspec-support (~> 3.7.0)
28
+ rspec-support (3.7.0)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ bundler (~> 1.16)
35
+ obfusc!
36
+ pry (~> 0.11.3)
37
+ rake (~> 10.0)
38
+ rspec (~> 3.0)
39
+
40
+ BUNDLED WITH
41
+ 1.16.0
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ [![Build Status](https://img.shields.io/travis/marcosgz/obfusc.svg?style=flat)](https://travis-ci.org/marcosgz/obfusc)
2
+
3
+ # obfusc
4
+ Simple command line tool to obfuscate a recursive tree of files. Basically just rename a list of files using a random and reversible name. Probably no one will use it. It's something that I'd be interested in when I was a teenager and tried to hide inappropriate files on my PC.
5
+
6
+ *Always preferer "copy" command over "move". Unless you know exactly what are you doing.*
7
+
8
+ ## Installation
9
+ Just install this gem by running
10
+
11
+ ```
12
+ gem install obfusc
13
+ ```
14
+
15
+ After successfully installed a new bin `obfusc` will be available.
16
+
17
+ ## Configuration
18
+ First thing you will need to create a `$HOME/.obfusc.cnf` with with `secret` and `token` keys by executing the following command:
19
+
20
+ ```
21
+ obfusct config generate
22
+ ```
23
+
24
+ Here is an example of generated file:
25
+ ```
26
+ $ cat ~/.obfusc.cnf
27
+ ---
28
+ prefix: "obfusc"
29
+ suffix: "obfusc"
30
+ token: "@l(piZ3ynEz8tjs ,v7DUGP}SmrNMF:f=k4hbBc[dYWIo_uLJq|a9O]5gRK-T6AeXwQ);C{x1H02V"
31
+ secret: "-A:z0rH2Zc4Gb6L@;Cwyd3g)l7JRIa[x]hWsoUD_Epe5O}jifu QqM{89FT=SvVBn1t,|P(NmXKkY"
32
+ ```
33
+
34
+ It's recommended to make a backup of this file before start using this script. All obfuscated depends on token and secret from this config file. All the obfuscated files can no longer be recovered if you overwrite `.obfusc.cnf`.
35
+
36
+ ## Usage
37
+
38
+ Use `obfusc --help` to show basic usage and all commands available.
39
+
40
+ ```
41
+ obfusc <command> <arguments> <options>
42
+ ```
43
+
44
+ #### Commands
45
+ * setup
46
+ * crypt
47
+ * decrypt
48
+
49
+ #### Options
50
+ ```
51
+ -c, --config FILENAME Using a different ".obfusc.cnf" filename (Default to $HOME/.obfusc.cnf)
52
+ -e, --extension STRING Specify a custom file extension. (Default to "obfc")
53
+ -p, --prefix STRING Specify a custom file prefix. (Default to "obfc")
54
+ -v, --[no-]verbose Run verbosely
55
+ -s, --[no-]simulate Do a simulate run without executing actions
56
+ ```
57
+
58
+ ### Crypt command
59
+
60
+ `crypt` is the command used to obfuscated one or more files. Should always be followed by `<move OR copy>` and `<source>` and an optional `<target>`.
61
+
62
+ Example:
63
+ ```
64
+ # Simulate what will happen by executing this command
65
+ $ obfusc crypt copy -v -s empty.gif
66
+ DEBUG: cp empty.gif ./obfusc__6GP5D.nHv.obfusc
67
+
68
+ # Obfuscate the "empty.gif" file with the `copy` mode.
69
+ $ obfusc crypt copy empty.gif
70
+
71
+ # Show obfuscated file
72
+ $ obfusc show ./
73
+ ./obfusc__6GP5D.nHv.obfusc:
74
+ ---> empty.gif
75
+
76
+ # `copy` always keep the original file
77
+ $ ls empty.gif
78
+ empty.gif
79
+ ```
80
+
81
+ ### Decrypt command
82
+ `decrypt` is the command used to revert to original filename one or more obfuscated files. Should always be followed by `<move OR copy>` and `<source>` and an optional `<target>`.
83
+
84
+ Example:
85
+ ```
86
+ # Simulate what will happen by executing this command
87
+ $ obfusc decrypt copy -s -v ./ /tmp/target
88
+ DEBUG: mkdir -p /tmp/target
89
+ DEBUG: cp ./obfusc__6GP5D.nHv.obfusc /tmp/target/empty.gif
90
+
91
+ # Rename obfuscated file to the original name and copy to the target directory
92
+ $ obfusc decrypt copy ./ /tmp/target
93
+
94
+ # Show un-obfuscated file
95
+ $ ls /tmp/target
96
+ empty.gif
97
+
98
+ # Original obfuscated file still existing with copy mode
99
+ $ ls ./obfusc__6GP5D.nHv.obfusc
100
+ ./obfusc__6GP5D.nHv.obfusc
101
+ ```
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "obfusc"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/obfusc ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'obfusc'
5
+
6
+ cli = Obfusc::CLI.new ARGV
7
+ cli.run
data/lib/obfusc/cli.rb ADDED
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Obfusc
4
+ # This model receive and process ARGV from ./exe/obfusc script
5
+ class CLI
6
+ VALID_COMMANDS = %w[setup crypt decrypt show].freeze
7
+
8
+ attr_reader :argumetns, :options
9
+
10
+ def initialize(arguments)
11
+ @arguments = arguments
12
+ @options = {}
13
+ end
14
+
15
+ def run
16
+ configure
17
+ perform(@arguments.shift)
18
+ end
19
+
20
+ protected
21
+
22
+ def perform(command)
23
+ unless VALID_COMMANDS.include?(command)
24
+ puts parser.help
25
+ return
26
+ end
27
+ config = Obfusc::Config.new(@options)
28
+ class_name = "#{command[0].upcase}#{command[1..-1]}Command"
29
+ Obfusc.const_get(class_name).call(config, *@arguments)
30
+ end
31
+
32
+ def configure
33
+ parser.parse!(@arguments)
34
+ end
35
+
36
+ # rubocop:disable BlockLength,MethodLength,AbcSize
37
+ def parser
38
+ @parser = OptionParser.new do |opts|
39
+ opts.banner = 'Usage: obfusc <command> <arguments> <options>'
40
+ opts.separator ''
41
+ opts.separator 'Commands:'
42
+ VALID_COMMANDS.each do |command|
43
+ opts.separator " * #{command}"
44
+ end
45
+
46
+ opts.separator ''
47
+ opts.separator 'Specific options:'
48
+
49
+ opts.on('-c', '--config FILENAME',
50
+ 'Using a different ".obfusc.cnf" filename') do |filename|
51
+ @options[:config_path] = filename
52
+ end
53
+
54
+ opts.on(
55
+ '-e',
56
+ '--extension STRING',
57
+ 'Specify a custom file extension. (Default to "obfc")'
58
+ ) do |extension|
59
+ @options[:extension] = extension
60
+ end
61
+
62
+ opts.on(
63
+ '-p',
64
+ '--prefix STRING',
65
+ 'Specify a custom file prefix. (Default to "obfc")'
66
+ ) do |prefix|
67
+ @options[:prefix] = prefix
68
+ end
69
+
70
+ opts.on('-v', '--[no-]verbose', 'Run verbosely') do |v|
71
+ @options[:verbose] = v
72
+ end
73
+
74
+ opts.on(
75
+ '-s',
76
+ '--[no-]simulate',
77
+ 'Do a simulate run without executing actions'
78
+ ) do |v|
79
+ @options[:simulate] = v
80
+ end
81
+
82
+ opts.separator ''
83
+ opts.separator 'Common options:'
84
+
85
+ opts.on_tail('-h', '--help', 'Show this message') do
86
+ puts opts
87
+ exit
88
+ end
89
+ end
90
+ end
91
+ # rubocop:enable BlockLength,MethodLength,AbcSize
92
+ end
93
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Obfusc
4
+ # Get/Set configurations with its default values.
5
+ class Config
6
+ attr_accessor :config_path, :extension, :verbose, :simulate
7
+
8
+ def initialize(options)
9
+ @config_path = options[:config_path]
10
+ @config_path ||= File.join(ENV['HOME'], '.obfusc.cnf')
11
+
12
+ @extension = options[:extension] || 'obfusc'
13
+ @verbose = options[:verbose] || false
14
+ @simulate = options[:simulate] || false
15
+ end
16
+
17
+ %i[simulate verbose].each do |method|
18
+ define_method "#{method}?" do
19
+ public_send("#{method}") == true
20
+ end
21
+ end
22
+
23
+ def encryptor
24
+ @encryptor ||= Obfusc::Encryptor.new(self)
25
+ end
26
+
27
+ def token
28
+ settings['token']
29
+ end
30
+
31
+ def secret
32
+ settings['secret']
33
+ end
34
+
35
+ def log(msg)
36
+ puts("DEBUG: #{msg}") if verbose?
37
+ end
38
+
39
+ def dry_run
40
+ return unless block_given?
41
+
42
+ yield unless simulate?
43
+ end
44
+
45
+ protected
46
+
47
+ def settings
48
+ @settings ||= YAML.load_file(config_path)
49
+ rescue Errno::ENOENT
50
+ puts "No such file #{config_path}."
51
+ puts "Use: `obfusc setup generate' to generate it"
52
+ {}
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Obfusc
4
+ # Commom methods shared between CryptCommand and DecryptCommand models.
5
+ # Children models only overwrite `show_usage` and files.
6
+ class EncryptorCommandBase
7
+ COMMANDS = %w[move copy].freeze
8
+ CURRENT_DIR = './'.freeze
9
+
10
+ def initialize(config, from, to)
11
+ @config = config
12
+
13
+ @from = from || CURRENT_DIR
14
+ @to = to || CURRENT_DIR
15
+ end
16
+
17
+ def self.call(config, *args)
18
+ command, from, to = args
19
+ model = new(config, from, to)
20
+ command = 'show_usage' unless COMMANDS.include?(command)
21
+ model.public_send(command)
22
+ end
23
+
24
+ def show_usage
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def files
29
+ raise NotImplementedError
30
+ end
31
+
32
+ def move
33
+ files.each_with_index do |(from, to), index|
34
+ create_target_base_directory if index.zero?
35
+ create_directory_from_file(to)
36
+ @config.log("mv #{from} #{to}")
37
+ @config.dry_run do
38
+ FileUtils.mv(from, to, verbose: @config.verbose?)
39
+ end
40
+ end.size
41
+ end
42
+
43
+ def copy
44
+ files.each_with_index do |(from, to), index|
45
+ create_target_base_directory if index.zero?
46
+ create_directory_from_file(to)
47
+ @config.log("cp #{from} #{to}")
48
+ @config.dry_run do
49
+ FileUtils.cp(from, to, verbose: @config.verbose?)
50
+ end
51
+ end.size
52
+ end
53
+
54
+ protected
55
+
56
+ def create_directory_from_file(path)
57
+ return if File.directory?(path)
58
+ dirname = File.dirname(path)
59
+ return if File.expand_path(dirname) == File.expand_path(@to)
60
+
61
+ @config.log("mkdir -p #{dirname}")
62
+ @config.dry_run { FileUtils.mkdir_p(dirname) }
63
+ end
64
+
65
+ def create_target_base_directory
66
+ return if @to == CURRENT_DIR
67
+ return if File.directory?(@to)
68
+
69
+ @config.log("mkdir -p #{@to}")
70
+ @config.dry_run { FileUtils.mkdir_p(@to) }
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'obfusc/commands/concerns/encryptor_command_base'
4
+
5
+ module Obfusc
6
+ # Perform tasks related `crypt` command
7
+ class CryptCommand < Obfusc::EncryptorCommandBase
8
+ # rubocop:disable MethodLength
9
+ def show_usage
10
+ usage = <<-TEXT.gsub(' ', '')
11
+ Usage:
12
+ $ obfusc crypt <* #{COMMANDS.join('|')}> <* from> <to>
13
+ <* > Required arguments
14
+
15
+ Action:
16
+ move: Files will be moved to the target.
17
+ copy: Keep existing files and generate a copy.
18
+
19
+ Files:
20
+ from: Relative or absolute of obfuscated directory/file. You can also use wildcards like "*" or "**".
21
+ to: Relative or absolute directory where un-obfuscated files will be stored. (Default to current directory)
22
+ TEXT
23
+ puts usage
24
+ end
25
+ # rubocop:enable MethodLength
26
+
27
+ protected
28
+
29
+ def files
30
+ recursive_from = File.join(@from, '**/{.*,*}') if File.directory?(@from)
31
+ Dir.glob(recursive_from || @from).each_with_object({}) do |path, memo|
32
+ next if File.directory?(path)
33
+ next if File.symlink?(path)
34
+ memo[path] = File.join(@to, @config.encryptor.encrypt(path))
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'obfusc/commands/concerns/encryptor_command_base'
4
+
5
+ module Obfusc
6
+ # Perform tasks related `decrypt` command
7
+ class DecryptCommand < Obfusc::EncryptorCommandBase
8
+ # rubocop:disable MethodLength
9
+ def show_usage
10
+ usage = <<-TEXT.gsub(' ', '')
11
+ Usage:
12
+ $ obfusc decrypt <* #{COMMANDS.join('|')}> <* from> <to>
13
+ <* > Required arguments
14
+
15
+ Action:
16
+ move: Files will be moved to the target.
17
+ copy: Keep existing files and generate a copy.
18
+
19
+ Files:
20
+ from: Relative or absolute directory/file be obfuscated. You can also use wildcards like "*" or "**".
21
+ to: Relative or absolute directory where obfuscated files will be stored. (Default to current directory)
22
+ TEXT
23
+ puts usage
24
+ end
25
+ # rubocop:enable MethodLength
26
+
27
+ protected
28
+
29
+ def files
30
+ recursive_from = File.join(@from, '**/{.*,*}') if File.directory?(@from)
31
+ Dir.glob(recursive_from || @from).each_with_object({}) do |path, memo|
32
+ next if File.directory?(path)
33
+ next if File.symlink?(path)
34
+ basename = File.basename(path)
35
+ next unless @config.encryptor.obfuscated?(basename)
36
+ memo[path] = File.join(@to, @config.encryptor.decrypt(basename))
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Obfusc
4
+ # Perform tasks related `setup` command
5
+ class SetupCommand
6
+ COMMANDS = %w[generate show].freeze
7
+
8
+ def initialize(config)
9
+ @config = config
10
+ end
11
+
12
+ def self.call(config, *args)
13
+ model = new(config)
14
+ command = args.first
15
+ command = 'show_usage' unless COMMANDS.include?(command)
16
+ model.public_send(command)
17
+ end
18
+
19
+ def show_usage
20
+ puts "Usage:\nobfusc setup <#{COMMANDS.join('|')}>"
21
+ end
22
+
23
+ def generate
24
+ File.open(config_file, 'w') do |f|
25
+ f.write tokenize(Obfusc::Random.generate!)
26
+ end
27
+ end
28
+
29
+ def show
30
+ unless File.exist?(config_file)
31
+ puts "#{config_file} does not exist.\nUse: `obfusc setup generate'"
32
+ return
33
+ end
34
+ YAML.load_file(config_file).each do |key, value|
35
+ puts "#{key}:"
36
+ puts "---> #{value.inspect}"
37
+ end
38
+ end
39
+
40
+ protected
41
+
42
+ def tokenize(characters_hash)
43
+ token = ''
44
+ secret = ''
45
+ characters_hash.sort_by { rand }.each do |key, value|
46
+ token += key
47
+ secret += value
48
+ end
49
+ YAML.dump(
50
+ 'prefix' => @config.prefix,
51
+ 'suffix' => @config.extension,
52
+ 'token' => token,
53
+ 'secret' => secret
54
+ )
55
+ end
56
+
57
+ def config_file
58
+ @config.config_path
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Obfusc
4
+ # Perform tasks related `show` command
5
+ class ShowCommand
6
+
7
+ def initialize(config, source)
8
+ @config = config
9
+ @source = source
10
+ end
11
+
12
+ def self.call(config, *args)
13
+ source = args.first
14
+ model = new(config, source)
15
+ model.public_send(File.exist?(source) ? :run : :show_usage)
16
+ end
17
+
18
+ def run
19
+ files.each do |from, to|
20
+ puts "#{from}:"
21
+ puts "---> #{to}"
22
+ end
23
+ end
24
+
25
+ def show_usage
26
+ usage = <<-TEXT.gsub(' ', '')
27
+ Usage:
28
+ $ obfusc show <source>
29
+
30
+ Files:
31
+ source: Relative or absolute directory where obfuscated files are stored. (Default to current directory)
32
+ TEXT
33
+ puts usage
34
+ end
35
+
36
+ protected
37
+
38
+ def files
39
+ recursive_from = File.join(@source, '**/{.*,*}') if File.directory?(@source)
40
+ Dir.glob(recursive_from || @source).each_with_object({}) do |path, memo|
41
+ next if File.directory?(path)
42
+ next if File.symlink?(path)
43
+ basename = File.basename(path)
44
+ next unless @config.encryptor.obfuscated?(basename)
45
+ memo[path] = @config.encryptor.decrypt(basename)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Obfusc
4
+ # Get/Set configurations with its default values.
5
+ class Config
6
+ attr_accessor :config_path, :extension, :verbose, :simulate, :prefix
7
+
8
+ def initialize(options)
9
+ @config_path = options[:config_path]
10
+ @config_path ||= File.join(ENV['HOME'], '.obfusc.cnf')
11
+
12
+ @extension = options[:extension] || 'obfusc'
13
+ @prefix = options[:prefix] || 'obfusc'
14
+ @verbose = options[:verbose] || false
15
+ @simulate = options[:simulate] || false
16
+ end
17
+
18
+ %i[simulate verbose].each do |method|
19
+ define_method "#{method}?" do
20
+ public_send("#{method}") == true
21
+ end
22
+ end
23
+
24
+ def encryptor
25
+ @encryptor ||= Obfusc::Encryptor.new(self)
26
+ end
27
+
28
+ def token
29
+ settings['token']
30
+ end
31
+
32
+ def secret
33
+ settings['secret']
34
+ end
35
+
36
+ def log(msg)
37
+ puts("DEBUG: #{msg}") if verbose?
38
+ end
39
+
40
+ def dry_run
41
+ return unless block_given?
42
+
43
+ yield unless simulate?
44
+ end
45
+
46
+ protected
47
+
48
+ def settings
49
+ @settings ||= YAML.load_file(config_path)
50
+ rescue Errno::ENOENT
51
+ puts "No such file #{config_path}."
52
+ puts "Use: `obfusc setup generate' to generate it"
53
+ {}
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Obfusc
4
+ # Recursive find files from origin or pattern
5
+ class Encryptor
6
+ SEP_FROM = '/'.freeze
7
+ SEP_TO = '___|___'.freeze
8
+
9
+ def initialize(config)
10
+ @config = config
11
+ @prefix = "#{config.prefix}__"
12
+ @suffix = ".#{config.extension}"
13
+ end
14
+
15
+ def encrypt(path)
16
+ crypted_filename = expand_path_for_encrypt(path).map do |step|
17
+ step.chars.map { |char| charlist[char] || char }.join
18
+ end.join(SEP_TO)
19
+
20
+ [@prefix, crypted_filename, @suffix].join
21
+ end
22
+
23
+ def decrypt(path)
24
+ expand_path_for_decrypt(path).join(SEP_FROM)
25
+ end
26
+
27
+ def obfuscated?(file)
28
+ !!(file =~ obfuscated_expression)
29
+ end
30
+
31
+ protected
32
+
33
+ def expand_path_for_encrypt(path)
34
+ parts = []
35
+ path.split(SEP_FROM).each do |part|
36
+ parts.push(*try_decrypt(part).split(SEP_FROM))
37
+ end
38
+ parts
39
+ end
40
+
41
+ def expand_path_for_decrypt(path, memo = [])
42
+ return memo if String(path).length.zero?
43
+
44
+ if path =~ obfuscated_expression
45
+ parts = normalize(path).split(SEP_TO)
46
+ return [*memo, *parts.map { |part| decrypt_segment(part) }]
47
+ end
48
+
49
+ dir, new_path = path.split(SEP_FROM, 2)
50
+ expand_path_for_decrypt(new_path, [*memo, dir])
51
+ end
52
+
53
+ def decrypt_segment(segment)
54
+ segment.chars.map { |char| charlist.key(char) || char }.join
55
+ end
56
+
57
+ def try_decrypt(step)
58
+ return step unless step =~ obfuscated_expression
59
+ decrypt(step)
60
+ end
61
+
62
+ def obfuscated_expression
63
+ /^(#{Regexp.escape(@prefix)}).*(#{Regexp.escape(@suffix)})$/
64
+ end
65
+
66
+ def charlist
67
+ @charlist ||= begin
68
+ keys = @config.token.split('')
69
+ values = @config.secret.split('')
70
+ Hash[keys.zip(values)]
71
+ end
72
+ end
73
+
74
+ def normalize(path)
75
+ path.sub!(/^(#{Regexp.escape(@prefix)})/, '')
76
+ path.sub!(/(#{Regexp.escape(@suffix)})$/, '')
77
+ path
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Obfusc
4
+ # Grab most comon characters and generate a random list of key and value
5
+ class Random
6
+ DIGIT = (0x30..0x39).map(&:chr)
7
+ ALPHA = (0x41..0x5a).map(&:chr) + (0x61..0x7a).map(&:chr)
8
+ SPECIAL = [
9
+ ' ', '-', '_', ',', ':', ';', '=', '@', '[', ']', '(', ')', '{', '}', '|'
10
+ ].freeze
11
+
12
+ def self.generate!
13
+ hash = {}
14
+ randonize!(hash, DIGIT + ALPHA)
15
+ randonize!(hash, SPECIAL)
16
+ hash
17
+ end
18
+
19
+ private_class_method def self.randonize!(memo, source)
20
+ source.sort_by { rand }.each do |char|
21
+ list = source - (memo.values & source)
22
+ loop do
23
+ memo[char] = list.sample
24
+ break if list.size <= 1
25
+ break if memo[char] != char
26
+ end
27
+ end
28
+ memo
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module Obfusc
2
+ VERSION = '1.0.0'.freeze
3
+ end
data/lib/obfusc.rb ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+ require 'yaml'
5
+ require 'fileutils'
6
+
7
+ require 'obfusc/cli'
8
+ require 'obfusc/config'
9
+ require 'obfusc/encryptor'
10
+ require 'obfusc/random'
11
+ require 'obfusc/version'
12
+
13
+ Dir["#{File.dirname(__FILE__)}/obfusc/commands/*_command.rb"].each do |file|
14
+ require file
15
+ end
16
+
17
+ # Script to obfuscate directories or files using a unique token/secret key.
18
+ module Obfusc
19
+ end
data/obfusc.gemspec ADDED
@@ -0,0 +1,28 @@
1
+
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'obfusc/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'obfusc'
8
+ spec.version = Obfusc::VERSION
9
+ spec.authors = ['Marcos G. Zimmermann']
10
+ spec.email = ['mgzmaster@gmail.com']
11
+ spec.license = 'MIT'
12
+
13
+ spec.summary = 'Command line tool to obfuscate files'
14
+ spec.description = 'Simple script to obfuscate one or more files' \
15
+ ' preserving the directory tree'
16
+ spec.homepage = 'https://github.com/marcosgz/obfusc'
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features)/})
20
+ end
21
+ spec.bindir = 'exe'
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.16'
26
+ spec.add_development_dependency 'rake', '~> 10.0'
27
+ spec.add_development_dependency 'rspec', '~> 3.0'
28
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: obfusc
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Marcos G. Zimmermann
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-01-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Simple script to obfuscate one or more files preserving the directory
56
+ tree
57
+ email:
58
+ - mgzmaster@gmail.com
59
+ executables:
60
+ - obfusc
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".gitignore"
65
+ - ".rspec"
66
+ - ".travis.yml"
67
+ - Gemfile
68
+ - Gemfile.lock
69
+ - README.md
70
+ - Rakefile
71
+ - bin/console
72
+ - bin/setup
73
+ - exe/obfusc
74
+ - lib/obfusc.rb
75
+ - lib/obfusc/cli.rb
76
+ - lib/obfusc/commands/concerns/config.rb
77
+ - lib/obfusc/commands/concerns/encryptor_command_base.rb
78
+ - lib/obfusc/commands/crypt_command.rb
79
+ - lib/obfusc/commands/decrypt_command.rb
80
+ - lib/obfusc/commands/setup_command.rb
81
+ - lib/obfusc/commands/show_command.rb
82
+ - lib/obfusc/config.rb
83
+ - lib/obfusc/encryptor.rb
84
+ - lib/obfusc/random.rb
85
+ - lib/obfusc/version.rb
86
+ - obfusc.gemspec
87
+ homepage: https://github.com/marcosgz/obfusc
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.5.1
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Command line tool to obfuscate files
111
+ test_files: []