machinator 0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|