|
| 1 | +// Package main controls the user interaction logic for the application |
| 2 | +package main |
| 3 | + |
| 4 | +import ( |
| 5 | + "bufio" |
| 6 | + "flag" |
| 7 | + "fmt" |
| 8 | + "os" |
| 9 | + "ptt/pkg/format" |
| 10 | + "ptt/pkg/models" |
| 11 | + "ptt/pkg/transform" |
| 12 | + "ptt/pkg/utils" |
| 13 | + "sync" |
| 14 | +) |
| 15 | + |
| 16 | +var version = "0.0.0" |
| 17 | +var wg sync.WaitGroup |
| 18 | +var mutex = &sync.Mutex{} |
| 19 | +var retain models.FileArgumentFlag |
| 20 | +var remove models.FileArgumentFlag |
| 21 | +var readFiles models.FileArgumentFlag |
| 22 | +var readURLs models.FileArgumentFlag |
| 23 | +var transformationFiles models.FileArgumentFlag |
| 24 | +var intRange models.IntRange |
| 25 | +var primaryMap map[string]int |
| 26 | +var err error |
| 27 | + |
| 28 | +func main() { |
| 29 | + // Parse command line arguments |
| 30 | + flag.Usage = func() { |
| 31 | + fmt.Fprintf(os.Stderr, "Usage of Password Transformation Tool (ptt) version (%s):\n\n", version) |
| 32 | + fmt.Fprintf(os.Stderr, "ptt [options] [...]\nAccepts standard input and/or additonal arguments.\n\n") |
| 33 | + fmt.Fprintf(os.Stderr, "Options:\n") |
| 34 | + flag.PrintDefaults() |
| 35 | + fmt.Fprintf(os.Stderr, "\nThe '-f', '-k', '-r', '-tf', and '-u' flags can be used multiple times.\n") |
| 36 | + fmt.Fprintf(os.Stderr, "\nTransformation Modes:\n") |
| 37 | + fmt.Fprintf(os.Stderr, " -t append\n\tTransforms input into append rules.\n") |
| 38 | + fmt.Fprintf(os.Stderr, " -t append-remove\n\tTransforms input into append-remove rules.\n") |
| 39 | + fmt.Fprintf(os.Stderr, " -t append-shift\n\tTransforms input into append-shift rules.\n") |
| 40 | + fmt.Fprintf(os.Stderr, " -t prepend\n\tTransforms input into prepend rules.\n") |
| 41 | + fmt.Fprintf(os.Stderr, " -t prepend-remove\n\tTransforms input into prepend-remove rules.\n") |
| 42 | + fmt.Fprintf(os.Stderr, " -t prepend-shift\n\tTransforms input into prepend-shift rules.\n") |
| 43 | + fmt.Fprintf(os.Stderr, " -t insert -i [index]\n\tTransforms input into insert rules starting at index.\n") |
| 44 | + fmt.Fprintf(os.Stderr, " -t overwrite -i [index]\n\tTransforms input into overwrite rules starting at index.\n") |
| 45 | + fmt.Fprintf(os.Stderr, " -t toggle -i [index]\n\tTransforms input into toggle rules starting at index.\n") |
| 46 | + fmt.Fprintf(os.Stderr, " -t encode\n\tTransforms input by URL, HTML, and Unicode escape encoding.\n") |
| 47 | + fmt.Fprintf(os.Stderr, " -t mask -rm [uldsb] -v\n\tTransforms input by masking characters with provided mask.\n") |
| 48 | + fmt.Fprintf(os.Stderr, " -t dehex\n\tTransforms input by decoding $HEX[...] formatted strings.\n") |
| 49 | + fmt.Fprintf(os.Stderr, " -t hex\n\tTransforms input by encoding strings into $HEX[...] format.\n") |
| 50 | + fmt.Fprintf(os.Stderr, " -t remove -rm [uldsb] -v\n\tTransforms input by removing characters with provided mask characters.\n") |
| 51 | + fmt.Fprintf(os.Stderr, " -t retain -rm [uldsb] -tf [file]\n\tTransforms input by creating masks that still retain strings from file.\n") |
| 52 | + fmt.Fprintf(os.Stderr, " -t match -tf [file]\n\tTransforms input by keeping only strings with matching masks from a mask file.\n") |
| 53 | + fmt.Fprintf(os.Stderr, " -t fuzzy-swap -tf [file]\n\tTransforms input by swapping tokens with fuzzy matches from another file.\n") |
| 54 | + fmt.Fprintf(os.Stderr, " -t swap -tf [file]\n\tTransforms input by swapping tokens with exact matches from a ':' separated file.\n") |
| 55 | + } |
| 56 | + |
| 57 | + // Define command line flags |
| 58 | + verbose := flag.Bool("v", false, "Show verbose output when possible.") |
| 59 | + minimum := flag.Int("m", 0, "Minimum numerical frequency to include in output.") |
| 60 | + transformation := flag.String("t", "", "Transformation to apply to input.") |
| 61 | + replacementMask := flag.String("rm", "uldsb", "Replacement mask for transformations if applicable.") |
| 62 | + flag.Var(&retain, "k", "Only keep items in a file.") |
| 63 | + flag.Var(&remove, "r", "Only keep items not in a file.") |
| 64 | + flag.Var(&readFiles, "f", "Read additional files for input.") |
| 65 | + flag.Var(&transformationFiles, "tf", "Read additional files for transformations if applicable.") |
| 66 | + flag.Var(&intRange, "i", "Starting index for transformations if applicable. Accepts ranges separated by '-'. (default 0)") |
| 67 | + flag.Var(&readURLs, "u", "Read additional URLs for input.") |
| 68 | + flag.Parse() |
| 69 | + |
| 70 | + // Parse any retain, remove, or transformation file arguments |
| 71 | + fs := &models.RealFileSystem{} |
| 72 | + retainMap := utils.ReadFilesToMap(fs, retain) |
| 73 | + removeMap := utils.ReadFilesToMap(fs, remove) |
| 74 | + readFilesMap := utils.ReadFilesToMap(fs, readFiles) |
| 75 | + transformationFilesMap := utils.ReadFilesToMap(fs, transformationFiles) |
| 76 | + readURLsMap, err := utils.ReadURLsToMap(readURLs) |
| 77 | + if err != nil { |
| 78 | + fmt.Println("Error reading URLs:", err) |
| 79 | + return |
| 80 | + } |
| 81 | + |
| 82 | + // Read from stdin if provided |
| 83 | + stat, _ := os.Stdin.Stat() |
| 84 | + if (stat.Mode() & os.ModeCharDevice) == 0 { |
| 85 | + primaryMap, err = utils.LoadStdinToMap(bufio.NewScanner(os.Stdin)) |
| 86 | + if err != nil { |
| 87 | + fmt.Println("Error reading from stdin:", err) |
| 88 | + return |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + // Combine stdin with any additional files |
| 93 | + if len(primaryMap) == 0 && len(readFilesMap) == 0 && len(readURLsMap) == 0 { |
| 94 | + flag.Usage() |
| 95 | + return |
| 96 | + } else if len(primaryMap) == 0 { |
| 97 | + primaryMap = utils.CombineMaps(readFilesMap, readURLsMap) |
| 98 | + } else { |
| 99 | + primaryMap = utils.CombineMaps(primaryMap, readFilesMap, readURLsMap) |
| 100 | + } |
| 101 | + |
| 102 | + // Apply transformation if provided |
| 103 | + if *transformation != "" { |
| 104 | + primaryMap = transform.TransformationController(primaryMap, *transformation, intRange.Start, intRange.End, *verbose, *replacementMask, transformationFilesMap) |
| 105 | + } |
| 106 | + |
| 107 | + // Process retain and remove maps if provided |
| 108 | + if len(retainMap) > 0 || len(removeMap) > 0 { |
| 109 | + primaryMap, err = format.RetainRemove(primaryMap, retainMap, removeMap) |
| 110 | + if err != nil { |
| 111 | + fmt.Println("Error processing retain and remove flags:", err) |
| 112 | + return |
| 113 | + } |
| 114 | + } |
| 115 | + |
| 116 | + // Remove items under minimum frequency if provided |
| 117 | + if *minimum > 0 { |
| 118 | + primaryMap = format.RemoveMinimumFrequency(primaryMap, *minimum) |
| 119 | + } |
| 120 | + |
| 121 | + // Print output to stdout |
| 122 | + format.PrintArrayToSTDOUT(primaryMap, *verbose) |
| 123 | +} |
0 commit comments