Skip to content

Commit

Permalink
Add support for loading patterns from file via -pattern-file option.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ledorub committed Aug 20, 2024
1 parent af0af82 commit 0122043
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 11 deletions.
6 changes: 4 additions & 2 deletions cmd/spoof-dpi/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ import (
)

func main() {
args := util.ParseArgs()
args := util.ParseArgs()
if *args.Version {
version.PrintVersion()
os.Exit(0)
}

config := util.GetConfig()
config.Load(args)
if err := config.Load(args); err != nil {
log.Fatalf("loading config: %s", err)
}

pxy := proxy.New(config)
if *config.Debug {
Expand Down
11 changes: 9 additions & 2 deletions util/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Args struct {
SystemProxy *bool
Timeout *int
AllowedPattern *StringArray
PatternFile *string
WindowSize *int
Version *bool
}
Expand Down Expand Up @@ -47,14 +48,20 @@ try lower values if the default value doesn't bypass the DPI;
when not given, the client hello packet will be sent in two parts:
fragmentation for the first data packet and the rest
`)
args.AllowedPattern = new(StringArray)
args.Version = flag.Bool("v", false, "print spoof-dpi's version; this may contain some other relevant information")

args.AllowedPattern = new(StringArray)
flag.Var(
args.AllowedPattern,
"pattern",
"bypass DPI only on packets matching this regex pattern; can be given multiple times",
)
args.PatternFile = flag.String(
"pattern-file",
"",
"bypass DPI only on packets matching regex patterns provided in a file (one per line)",
)

args.Version = flag.Bool("v", false, "print spoof-dpi's version; this may contain some other relevant information")

flag.Parse()

Expand Down
36 changes: 29 additions & 7 deletions util/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func GetConfig() *Config {
return config
}

func (c *Config) Load(args *Args) {
func (c *Config) Load(args *Args) error {
c.Addr = args.Addr
c.Port = args.Port
c.DnsAddr = args.DnsAddr
Expand All @@ -41,18 +41,40 @@ func (c *Config) Load(args *Args) {
c.NoBanner = args.NoBanner
c.SystemProxy = args.SystemProxy
c.Timeout = args.Timeout
c.AllowedPatterns = parseAllowedPattern(args.AllowedPattern)
c.WindowSize = args.WindowSize

patterns, err := parseAllowedPattern(args.AllowedPattern, *args.PatternFile)
if err != nil {
return fmt.Errorf("parsing patterns: %w", err)
}
c.AllowedPatterns = patterns

return nil
}

func parseAllowedPattern(patterns *StringArray) []*regexp.Regexp {
var allowedPatterns []*regexp.Regexp
func parseAllowedPattern(patterns *StringArray, filePath string) ([]*regexp.Regexp, error) {
patternSet := make(map[*regexp.Regexp]struct{})

for _, pattern := range *patterns {
allowedPatterns = append(allowedPatterns, regexp.MustCompile(pattern))
filePatterns, err := loadPatternsFromFile(filePath)
if err != nil {
return nil, fmt.Errorf("loading patterns from file: %w", err)
}
for _, pattern := range filePatterns {
patternSet[pattern] = struct{}{}
}

return allowedPatterns
for _, rawPattern := range *patterns {
pattern := regexp.MustCompile(rawPattern)
patternSet[pattern] = struct{}{}
}

allowedPatterns := make([]*regexp.Regexp, len(patternSet))
writeI := 0
for pattern := range patternSet {
allowedPatterns[writeI] = pattern
writeI++
}
return allowedPatterns, nil
}

func PrintColoredBanner() {
Expand Down
41 changes: 41 additions & 0 deletions util/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package util

import (
"bufio"
"fmt"
"os"
"path/filepath"
"regexp"
)

func loadPatternsFromFile(path string) ([]*regexp.Regexp, error) {
if path == "" {
return nil, nil
}
path, err := filepath.Abs(path)
if err != nil {
return nil, fmt.Errorf("pattern file path: %w", err)
}

file, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("opening pattern file: %w", err)
}
defer func() {
if e := file.Close(); e != nil && err == nil {
err = e
}
}()

var patterns []*regexp.Regexp
scanner := bufio.NewScanner(file)
for scanner.Scan() {
pattern := regexp.MustCompile(scanner.Text())
patterns = append(patterns, pattern)
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("parsing pattern file: %w", err)
}

return patterns, nil
}

0 comments on commit 0122043

Please sign in to comment.