machinator 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/README.rdoc +101 -0
- data/bin/machinator +2 -0
- data/lib/machinator/console_interface.rb +58 -0
- data/lib/machinator/obfuscator.rb +87 -0
- data/lib/machinator.rb +3 -0
- data/machinator.gemspec +22 -0
- metadata +71 -0
data/README.rdoc
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
Machinator can perform code obfuscation on file content and directory structures.
|
2
|
+
|
3
|
+
It can be paired up with high level language deployment and/or compression routines to keep even Big Brother guessing. Or can it?
|
4
|
+
|
5
|
+
http://rubygems.org/gems/machinator
|
6
|
+
|
7
|
+
== Terminal usage
|
8
|
+
|
9
|
+
As a ruby gem
|
10
|
+
|
11
|
+
machinator -h
|
12
|
+
|
13
|
+
Or (with the source) you can just:
|
14
|
+
|
15
|
+
ruby bin/machinator -h
|
16
|
+
|
17
|
+
== Obfuscating
|
18
|
+
|
19
|
+
Machinator lets you define the schema for obfuscation.
|
20
|
+
|
21
|
+
A schema (in YAML) is defined in a .machinator file in the current directory, or a manually specified Hash resource.
|
22
|
+
|
23
|
+
A schema has a words and a names hash collection, with each key/pair being a regular expression and strings to replace with any occurences, respectively.
|
24
|
+
|
25
|
+
An example:
|
26
|
+
|
27
|
+
words: {
|
28
|
+
namepsace\.Foo: nameSpace.bar
|
29
|
+
}
|
30
|
+
|
31
|
+
names: {
|
32
|
+
SomeFile\.js$: ABC.js
|
33
|
+
}
|
34
|
+
|
35
|
+
Any words are matched against the entire file. File names are obfuscated afterwards (will only be matched once).
|
36
|
+
|
37
|
+
== Using In Code
|
38
|
+
|
39
|
+
require "machinator"
|
40
|
+
winston = Machinator::Obfuscator.new
|
41
|
+
winston.neverspeak(source, schema)
|
42
|
+
|
43
|
+
The source can be an actual string to obfuscate, a File object, or a directory/file path to operate on.
|
44
|
+
Keep in mind that the Obfuscator module will overwrite any files/directories that matches the schema.
|
45
|
+
|
46
|
+
Note: If you specify a string to obfusctate that is actually a valid file/directory path it will operate on that instead.
|
47
|
+
|
48
|
+
== Manipulating Strings
|
49
|
+
|
50
|
+
In the case of passing in a string an obfuscated copy will be returned.
|
51
|
+
|
52
|
+
new_string = winston.neverspeak("some string to obfuscate", {
|
53
|
+
"words" => {
|
54
|
+
/^some\sstring/ => "something"
|
55
|
+
}
|
56
|
+
})
|
57
|
+
|
58
|
+
== Operating on Files and Directories
|
59
|
+
|
60
|
+
You can operate on a single file, where the first matched names key/pair is applied to the file name and any words are applied against the file content.
|
61
|
+
|
62
|
+
# renames to foo.foo
|
63
|
+
winston.neverspeak("foo.bar", {
|
64
|
+
"names" => {
|
65
|
+
/bar$/ => "foo"
|
66
|
+
}
|
67
|
+
})
|
68
|
+
|
69
|
+
If you specify a directory all files and directories inside will be operated on (recursively, bottom up), applying names/words matches to each file.
|
70
|
+
|
71
|
+
# let somedir have 'afile' in it
|
72
|
+
winston.neverspeak("somedir", {
|
73
|
+
"names" => {
|
74
|
+
/afile$/ => "thefile"
|
75
|
+
}
|
76
|
+
})
|
77
|
+
|
78
|
+
Note: This will recurse (fairly deep) so make sure the passed in directory is correct, or you could possibly bring on the apocalypse.
|
79
|
+
|
80
|
+
== Filtering
|
81
|
+
|
82
|
+
You can pass in a block to filer file operations (both words and names).
|
83
|
+
|
84
|
+
winston.neverspeak("somedir", schema) { |path|
|
85
|
+
true
|
86
|
+
} # will operate on every file found
|
87
|
+
|
88
|
+
== Dependencies
|
89
|
+
|
90
|
+
None
|
91
|
+
|
92
|
+
== Tests
|
93
|
+
|
94
|
+
rake test (need mocha, and rake... if you want)
|
95
|
+
|
96
|
+
== Author
|
97
|
+
|
98
|
+
Copyright 2010 Brent Lintner
|
99
|
+
|
100
|
+
The MIT License
|
101
|
+
http://www.opensource.org/licenses/mit-license.php
|
data/bin/machinator
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module Machinator
|
2
|
+
class ConsoleInterface
|
3
|
+
require 'ostruct'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
VERSION_TEXT = '0.1'
|
7
|
+
HELP = <<TEXT
|
8
|
+
|
9
|
+
== Machinator
|
10
|
+
obfuscate file content and directory structures
|
11
|
+
|
12
|
+
== Usage
|
13
|
+
machinator [options]
|
14
|
+
|
15
|
+
== Options
|
16
|
+
-h, --help Displays help message
|
17
|
+
-v, --version Displays the version
|
18
|
+
|
19
|
+
TEXT
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@options = OpenStruct.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def interpret(argv)
|
26
|
+
@argv = argv
|
27
|
+
parsed_options?
|
28
|
+
end
|
29
|
+
|
30
|
+
def peace_out(msg)
|
31
|
+
puts(msg) ; exit!(0)
|
32
|
+
end
|
33
|
+
|
34
|
+
def parsed_options?
|
35
|
+
@options.verbose = false
|
36
|
+
|
37
|
+
opts = OptionParser.new
|
38
|
+
|
39
|
+
opts.on('-v', '--version') { peace_out(VERSION_TEXT) }
|
40
|
+
opts.on('-h', '--help') { peace_out(HELP) }
|
41
|
+
opts.on('-o', '--obfuscate [path]') { |path| }
|
42
|
+
|
43
|
+
begin
|
44
|
+
opts.parse!(@argv)
|
45
|
+
rescue Exception => e
|
46
|
+
handle_exception(e) ; exit!(0)
|
47
|
+
end
|
48
|
+
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
def handle_exception(e)
|
53
|
+
puts("\nshit pooped!\n\n")
|
54
|
+
puts "#{e.class.to_s} ==> #{e.message}\n\n"
|
55
|
+
puts e.backtrace.join("\n")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Machinator
|
2
|
+
class Room101 < StandardError ; end
|
3
|
+
class Obfuscator
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@block, @source, @schema = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def neverspeak(source, schema=nil, &block)
|
11
|
+
@schema = schema
|
12
|
+
@source = source
|
13
|
+
@block = block
|
14
|
+
|
15
|
+
if @schema.nil?
|
16
|
+
config = File.join(@source, ".machinator")
|
17
|
+
if !File.exists?(config)
|
18
|
+
raise Room101, "no schema specified and no .machinator file was found."
|
19
|
+
end
|
20
|
+
@schema = YAML::load(File.open(config))
|
21
|
+
end
|
22
|
+
|
23
|
+
if @source.is_a?(File) || File.exist?(@source)
|
24
|
+
if !File.directory?(@source)
|
25
|
+
if !@block || @block.call(source)
|
26
|
+
obfuscate_file
|
27
|
+
obfuscate_file_name
|
28
|
+
end
|
29
|
+
else
|
30
|
+
obfuscate_dir
|
31
|
+
end
|
32
|
+
else
|
33
|
+
@source = String.new(@source)
|
34
|
+
obfuscate_string
|
35
|
+
return @source
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def obfuscate_string(source=@source)
|
42
|
+
@schema["words"].each { |key, value|
|
43
|
+
source.gsub!(Regexp.new(key), value)
|
44
|
+
} if @schema["words"].is_a?(Hash)
|
45
|
+
end
|
46
|
+
|
47
|
+
def obfuscate_file(source=@source)
|
48
|
+
raise Room101, "could not find file to obfuscate (#{source})" if !File.exists?(@source)
|
49
|
+
file_buffer = ""
|
50
|
+
IO.foreach(source) { |line| file_buffer << line }
|
51
|
+
obfuscate_string(file_buffer)
|
52
|
+
File.open(source, "w") { |file| file.syswrite(file_buffer) }
|
53
|
+
end
|
54
|
+
|
55
|
+
def obfuscate_file_name(source=@source)
|
56
|
+
@schema["names"].each { |key, value|
|
57
|
+
if (regex = Regexp.new(key)) =~ source
|
58
|
+
FileUtils.mv(source, source.gsub(regex, value)) ; break
|
59
|
+
end
|
60
|
+
} if @schema["names"].is_a?(Hash)
|
61
|
+
end
|
62
|
+
|
63
|
+
def obfuscate_dir(source=@source)
|
64
|
+
recurse(source) { |full_path|
|
65
|
+
if !@block || @block.call(full_path)
|
66
|
+
obfuscate_file(full_path) if !File.directory?(full_path)
|
67
|
+
obfuscate_file_name(full_path)
|
68
|
+
end
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def recurse(dir, limit=20, &block)
|
73
|
+
raise Room101, "recursive limit (20) reached" if limit <= 0
|
74
|
+
actual_path = dir.is_a?(File) ? dir.path : dir
|
75
|
+
Dir.foreach(actual_path) { |item|
|
76
|
+
full_path = File.join(actual_path, item)
|
77
|
+
if item !~ /^\.\.?$/
|
78
|
+
if File.directory?(full_path)
|
79
|
+
recurse(full_path, limit - 1, &block)
|
80
|
+
end
|
81
|
+
yield(full_path)
|
82
|
+
end
|
83
|
+
}
|
84
|
+
yield(actual_path)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/machinator.rb
ADDED
data/machinator.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.platform = Gem::Platform::RUBY
|
3
|
+
s.name = 'machinator'
|
4
|
+
s.version = '0.1'
|
5
|
+
s.summary = 'obfuscate file content and directory structures.'
|
6
|
+
s.description = 'obfuscate file content and directory structures'
|
7
|
+
|
8
|
+
s.required_ruby_version = '>= 1.8.6'
|
9
|
+
|
10
|
+
s.author = 'Brent Lintner'
|
11
|
+
s.email = 'brent.lintner@gmail.com'
|
12
|
+
s.homepage = 'http://github.com/brentlintner/machinator'
|
13
|
+
|
14
|
+
s.files = Dir['bin/*', 'machinator.gemspec', 'README.rdoc', 'lib/**/*'].to_a
|
15
|
+
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.extra_rdoc_files = %w( README.rdoc )
|
18
|
+
s.rdoc_options.concat ['--main', 'README.rdoc']
|
19
|
+
|
20
|
+
s.executables = ["machinator"]
|
21
|
+
s.require_path = "lib"
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: machinator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
version: "0.1"
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- Brent Lintner
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain: []
|
15
|
+
|
16
|
+
date: 2011-01-03 00:00:00 -05:00
|
17
|
+
default_executable:
|
18
|
+
dependencies: []
|
19
|
+
|
20
|
+
description: obfuscate file content and directory structures
|
21
|
+
email: brent.lintner@gmail.com
|
22
|
+
executables:
|
23
|
+
- machinator
|
24
|
+
extensions: []
|
25
|
+
|
26
|
+
extra_rdoc_files:
|
27
|
+
- README.rdoc
|
28
|
+
files:
|
29
|
+
- bin/machinator
|
30
|
+
- machinator.gemspec
|
31
|
+
- README.rdoc
|
32
|
+
- lib/machinator/console_interface.rb
|
33
|
+
- lib/machinator/obfuscator.rb
|
34
|
+
- lib/machinator.rb
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: http://github.com/brentlintner/machinator
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options:
|
41
|
+
- --main
|
42
|
+
- README.rdoc
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
segments:
|
51
|
+
- 1
|
52
|
+
- 8
|
53
|
+
- 6
|
54
|
+
version: 1.8.6
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 1.3.7
|
67
|
+
signing_key:
|
68
|
+
specification_version: 3
|
69
|
+
summary: obfuscate file content and directory structures.
|
70
|
+
test_files: []
|
71
|
+
|