From 5ccc7f4fd931ec978079eb522d1d4ee3118a0b9a Mon Sep 17 00:00:00 2001 From: Simon Let Date: Mon, 17 Feb 2020 14:54:05 +0100 Subject: [PATCH 1/3] fix ctrl_R widget shadowing the bash_preexec hook --- scripts/widgets.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/widgets.sh b/scripts/widgets.sh index 257a6c8..335cadb 100644 --- a/scripts/widgets.sh +++ b/scripts/widgets.sh @@ -88,6 +88,12 @@ __resh_widget_arrow_down() { __resh_helper_arrow_post } __resh_widget_control_R() { + # this is a very bad workaround + # force bash-preexec to run repeatedly because otherwise premature run of bash-preexec overshadows the next poper run + # I honestly think that it's impossible to make widgets work in bash without hacks like this + # shellcheck disable=2034 + __bp_preexec_interactive_mode="on" + # local __RESH_PREFIX=${BUFFER:0:CURSOR} # __RESH_HIST_RECALL_ACTIONS="$__RESH_HIST_RECALL_ACTIONS;control_R:$__RESH_PREFIX" local PREVBUFFER=$BUFFER From 944c8b52ee7dc21c498d9daed2286f7a7af387fa Mon Sep 17 00:00:00 2001 From: Simon Let Date: Mon, 17 Feb 2020 15:34:45 +0100 Subject: [PATCH 2/3] update sanitization to handle ctrl_R widget plus handle situations when ';' and '|||' separators are used together --- cmd/control/cmd/sanitize.go | 2 +- cmd/sanitize/main.go | 110 ++++++++++++++++++++++++------------ go.sum | 1 + 3 files changed, 76 insertions(+), 37 deletions(-) diff --git a/cmd/control/cmd/sanitize.go b/cmd/control/cmd/sanitize.go index 50b3b5f..a6fe4c4 100644 --- a/cmd/control/cmd/sanitize.go +++ b/cmd/control/cmd/sanitize.go @@ -22,7 +22,7 @@ var sanitizeCmd = &cobra.Command{ fmt.Println(" HOW IT WORKS") fmt.Println(" In sanitized history, all sensitive information is replaced with its SHA1 hashes.") fmt.Println() - fmt.Println("Sanitizing ...") + fmt.Println("Resulting sanitized files ...") fmt.Println(" * ~/resh_history_sanitized.json (full lengh hashes)") execCmd := exec.Command("resh-sanitize", "-trim-hashes", "0", "--output", dir+"/resh_history_sanitized.json") execCmd.Stdout = os.Stdout diff --git a/cmd/sanitize/main.go b/cmd/sanitize/main.go index 9d5a8aa..7ebcecb 100644 --- a/cmd/sanitize/main.go +++ b/cmd/sanitize/main.go @@ -10,6 +10,7 @@ import ( "flag" "fmt" "log" + "math" "net/url" "os" "os/user" @@ -19,6 +20,7 @@ import ( "strings" "unicode" + "github.com/coreos/go-semver/semver" "github.com/curusarn/resh/pkg/records" giturls "github.com/whilp/git-urls" ) @@ -178,7 +180,7 @@ func (s *sanitizer) sanitizeRecord(record *records.Record) error { } if len(record.RecallActionsRaw) > 0 { - record.RecallActionsRaw, err = s.sanitizeRecallActions(record.RecallActionsRaw) + record.RecallActionsRaw, err = s.sanitizeRecallActions(record.RecallActionsRaw, record.ReshVersion) if err != nil { log.Fatal("RecallActionsRaw:", record.RecallActionsRaw, "; sanitization error:", err) } @@ -188,44 +190,80 @@ func (s *sanitizer) sanitizeRecord(record *records.Record) error { return nil } -// sanitizes the recall actions by replacing the recall prefix with it's length -func (s *sanitizer) sanitizeRecallActions(str string) (string, error) { - sanStr := "" - divider := ";" - if strings.Contains(str, "|||") { - divider = "|||" - // normal mode - } - for x, actionStr := range strings.Split(str, divider+"arrow_") { - if x == 0 { - continue +func fixSeparator(str string) string { + if len(str) > 0 && str[0] == ';' { + return "|||" + str[1:] + } + return str +} + +func minIndex(str string, substrs []string) (idx, substrIdx int) { + minMatch := math.MaxInt32 + for i, sep := range substrs { + match := strings.Index(str, sep) + if match != -1 && match < minMatch { + minMatch = match + substrIdx = i } - if len(actionStr) == 0 { - return str, errors.New("Action can't be empty; idx=" + strconv.Itoa(x)) + } + idx = minMatch + return +} + +// sanitizes the recall actions by replacing the recall prefix with it's length +func (s *sanitizer) sanitizeRecallActions(str string, reshVersion string) (string, error) { + if len(str) == 0 { + return "", nil + } + var separators []string + seps := []string{"|||"} + refVersion, err := semver.NewVersion("2.5.14") + if err != nil { + return str, err + } + if len(reshVersion) == 0 { + return str, errors.New("sanitizeRecallActions: record.ReshVersion is an empty string") + } + recordVersion, err := semver.NewVersion(reshVersion[1:]) + if err != nil { + return str, err + } + if recordVersion.LessThan(*refVersion) { + seps = append(seps, ";") + } + + actions := []string{"arrow_up", "arrow_down", "control_R"} + for _, sep := range seps { + for _, action := range actions { + separators = append(separators, sep+action+":") } - var action string - var prefix string - if strings.HasPrefix(actionStr, "up:") { - action = "arrow_up" - if len(actionStr) < 3 { - return str, errors.New("Action is too short:" + actionStr) - } - if len(actionStr) != 3 { - prefix = actionStr[4:] - } - } else if strings.HasPrefix(actionStr, "down:") { - action = "arrow_down" - if len(actionStr) < 5 { - return str, errors.New("Action is too short:" + actionStr) - } - if len(actionStr) != 5 { - prefix = actionStr[6:] - } - } else { - return str, errors.New("Action should start with one of (arrow_up, arrow_down); got: arrow_" + actionStr) + } + /* + - find any of {|||,;}{arrow_up,arrow_down,control_R}: in the recallActions (on the lowest index) + - use found substring to parse out the next prefix + - sanitize prefix + - add fixed substring and sanitized prefix to output + */ + doBreak := false + sanStr := "" + idx := 0 + var currSeparator string + tokenLen, sepIdx := minIndex(str, separators) + if tokenLen != 0 { + return str, errors.New("sanitizeReacallActions: unexpected string before first action/separator") + } + currSeparator = separators[sepIdx] + idx += len(currSeparator) + for !doBreak { + tokenLen, sepIdx := minIndex(str[idx:], separators) + if tokenLen > len(str[idx:]) { + tokenLen = len(str[idx:]) + doBreak = true } - sanPrefix := strconv.Itoa(len(prefix)) - sanStr += "|||" + action + ":" + sanPrefix + // token := str[idx : idx+tokenLen] + sanStr += fixSeparator(currSeparator) + strconv.Itoa(tokenLen) + idx += tokenLen + len(currSeparator) + currSeparator = separators[sepIdx] } return sanStr, nil } diff --git a/go.sum b/go.sum index 430efce..7b6e13c 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,7 @@ github.com/awesome-gocui/termbox-go v0.0.0-20190427202837-c0aef3d18bcc h1:wGNpKc github.com/awesome-gocui/termbox-go v0.0.0-20190427202837-c0aef3d18bcc/go.mod h1:tOy3o5Nf1bA17mnK4W41gD7PS3u4Cv0P0pqFcoWMy8s= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From 198176427b5838693c57e560e1ffa525f47c5075 Mon Sep 17 00:00:00 2001 From: Simon Let Date: Mon, 17 Feb 2020 15:53:52 +0100 Subject: [PATCH 3/3] use sha256 instead of sha1, minor changes --- cmd/control/cmd/sanitize.go | 4 ++-- cmd/sanitize/main.go | 16 ++++++---------- go.mod | 1 + go.sum | 1 + 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/cmd/control/cmd/sanitize.go b/cmd/control/cmd/sanitize.go index a6fe4c4..9d32d43 100644 --- a/cmd/control/cmd/sanitize.go +++ b/cmd/control/cmd/sanitize.go @@ -20,9 +20,9 @@ var sanitizeCmd = &cobra.Command{ fmt.Println() fmt.Println(" HOW IT WORKS") - fmt.Println(" In sanitized history, all sensitive information is replaced with its SHA1 hashes.") + fmt.Println(" In sanitized history, all sensitive information is replaced with its SHA256 hashes.") fmt.Println() - fmt.Println("Resulting sanitized files ...") + fmt.Println("Creating sanitized history files ...") fmt.Println(" * ~/resh_history_sanitized.json (full lengh hashes)") execCmd := exec.Command("resh-sanitize", "-trim-hashes", "0", "--output", dir+"/resh_history_sanitized.json") execCmd.Stdout = os.Stdout diff --git a/cmd/sanitize/main.go b/cmd/sanitize/main.go index 7ebcecb..cd6f0cb 100644 --- a/cmd/sanitize/main.go +++ b/cmd/sanitize/main.go @@ -2,7 +2,7 @@ package main import ( "bufio" - "crypto/sha1" + "crypto/sha256" "encoding/binary" "encoding/hex" "encoding/json" @@ -480,21 +480,17 @@ func (s *sanitizer) hashToken(token string) string { if len(token) <= 0 { return token } - // hash with sha1 - h := sha1.New() - h.Write([]byte(token)) - sum := h.Sum(nil) - return s.trimHash(hex.EncodeToString(sum)) + // hash with sha256 + sum := sha256.Sum256([]byte(token)) + return s.trimHash(hex.EncodeToString(sum[:])) } func (s *sanitizer) hashNumericToken(token string) string { if len(token) <= 0 { return token } - h := sha1.New() - h.Write([]byte(token)) - sum := h.Sum(nil) - sumInt := int(binary.LittleEndian.Uint64(sum)) + sum := sha256.Sum256([]byte(token)) + sumInt := int(binary.LittleEndian.Uint64(sum[:])) if sumInt < 0 { return strconv.Itoa(sumInt * -1) } diff --git a/go.mod b/go.mod index c3a34e1..b5fb37b 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.12 require ( github.com/BurntSushi/toml v0.3.1 github.com/awesome-gocui/gocui v0.6.0 + github.com/coreos/go-semver v0.2.0 github.com/jpillora/longestcommon v0.0.0-20161227235612-adb9d91ee629 github.com/mattn/go-runewidth v0.0.8 // indirect github.com/mattn/go-shellwords v1.0.6 diff --git a/go.sum b/go.sum index 7b6e13c..49cdf66 100644 --- a/go.sum +++ b/go.sum @@ -52,6 +52,7 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=