diff --git a/readme.txt b/README.md similarity index 58% rename from readme.txt rename to README.md index 566d0b0..7bd5592 100644 --- a/readme.txt +++ b/README.md @@ -10,10 +10,25 @@ Streaming obfuscator of sensitive data in PostgreSQL dumps (pg_dump). $ pg_dump [...] |pgdump-obfuscator |less # inspect -TODO +Configuration ==== -* Config file. Currently obfuscation rules are hardcoded in config.go, so you have to recompile to try new rules. Easy with `go run`. +``` +pgdump-obfuscator -h + +Usage of ./pgdump-obfuscator: + -c value + Configs, example: auth_user:email:email, auth_user:password:bytes + ... +``` + +That mean you can provide as many "-c option" as you need. + +Example: + +``` +pgdump-obfuscator -c auth_user:email:email -c auth_user:password:bytes -c address_useraddress:phone_number:digits -c address_useraddress:land_line:digits +``` Who diff --git a/main.go b/main.go index 97d6f7d..5ed5010 100644 --- a/main.go +++ b/main.go @@ -13,8 +13,44 @@ import ( "strings" "syscall" "time" + "fmt" ) +type configFlags []string + +func (self *configFlags) String() string { + return strings.Join(*self, ", ") +} + +func (self *configFlags) Set(value string) error { + *self = append(*self, value) + return nil +} + +func (self *configFlags) ToConfiguration() (*Configuration, error) { + configuration := &Configuration{} + for _, v := range *self { + splittedValues := strings.Split(v, ":") + if len(splittedValues) == 3 { + table, column, name := splittedValues[0], splittedValues[1], splittedValues[2] + scrambler, err := GetScrambleByName(name) + if err != nil { + return configuration, err + } + configuration.Obfuscations = append( + configuration.Obfuscations, + TargetedObfuscation{ + Target{Table: table, Column: column}, + scrambler, + }, + ) + } else { + return nil, errors.New(fmt.Sprintf("Inccorrect data in configuration flags!\n")) + } + } + return configuration, nil +} + type Target struct { Database string Schema string @@ -155,9 +191,11 @@ func process(config *Configuration, input *bufio.Reader, output io.Writer) error } func main() { + var configs configFlags inputPath := flag.String("input", "-", "Input filename, '-' for stdin") cpuprofile := flag.String("cpuprofile", "", "Write CPU profile to file") memprofile := flag.String("memprofile", "", "Write memory profile to file") + flag.Var(&configs, "c", "Configs, example: auth_user:email:email, auth_user:password:bytes") flag.Parse() if *cpuprofile != "" { @@ -209,5 +247,11 @@ func main() { // TODO output := os.Stdout - process(Config, input, output) + configuration, err := configs.ToConfiguration() + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + process(configuration, input, output) } diff --git a/obfuscators.go b/obfuscators.go index 461a187..9eeced4 100644 --- a/obfuscators.go +++ b/obfuscators.go @@ -7,6 +7,8 @@ import ( "crypto/rand" "crypto/sha256" "net" + "errors" + "fmt" ) var Salt []byte @@ -126,6 +128,20 @@ func ScrambleInet(s []byte) []byte { return []byte(ip.String()) } +func GetScrambleByName(value string) (func(s []byte) []byte, error) { + switch value { + case "bytes": + return ScrambleBytes, nil + case "digits": + return ScrambleDigits, nil + case "email": + return ScrambleEmail, nil + case "inet": + return ScrambleInet, nil + } + return nil, errors.New(fmt.Sprintf("%s is not registered scramble function", value)) +} + func init() { Salt = make([]byte, 16) _, err := rand.Read(Salt)