diff --git a/hkexauth.go b/hkexauth.go index 84c15d6..5d6aa0a 100644 --- a/hkexauth.go +++ b/hkexauth.go @@ -28,9 +28,6 @@ func AuthUser(username string, auth string, fname string) (valid bool, allowedCm } r := csv.NewReader(bytes.NewReader(b)) - b = nil - runtime.GC() // Paranoia and prob. not effective; kill authFile in b[] - r.Comma = ':' r.Comment = '#' r.FieldsPerRecord = 4 // username:salt:authCookie:disallowedCmdList (a,b,...) @@ -51,5 +48,13 @@ func AuthUser(username string, auth string, fname string) (valid bool, allowedCm break } } + // Security scrub + for i := range b { + b[i] = 0 + } + b = nil + r = nil + runtime.GC() + return } diff --git a/hkexnet.go b/hkexnet.go index e1c63e7..05ce922 100644 --- a/hkexnet.go +++ b/hkexnet.go @@ -319,8 +319,6 @@ func (hl HKExListener) Accept() (hc Conn, err error) { // See go doc io.Reader func (c Conn) Read(b []byte) (n int, err error) { //log.Printf("[Decrypting...]\r\n") - log.Printf("Read() requests %d bytes\n", len(b)) - for { //log.Printf("c.dBuf.Len(): %d\n", c.dBuf.Len()) if c.dBuf.Len() > 0 /* len(b) */ { @@ -349,7 +347,6 @@ func (c Conn) Read(b []byte) (n int, err error) { log.Println("unexpected Read() err:", err) } else { log.Println("[Client hung up]") - // TODO: Stop chaff if active } return 0, err } @@ -536,15 +533,15 @@ func (c *Conn) chaffHelper(szMax int) { // hkexsh.Copy() is a modified version of io.Copy() func Copy(dst io.Writer, src io.Reader) (written int64, err error) { - // // If the reader has a WriteTo method, use it to do the copy. - // // Avoids an allocation and a copy. - // if wt, ok := src.(io.WriterTo); ok { - // return wt.WriteTo(dst) - // } - // // Similarly, if the writer has a ReadFrom method, use it to do the copy. - // if rt, ok := dst.(io.ReaderFrom); ok { - // return rt.ReadFrom(src) - // } + // If the reader has a WriteTo method, use it to do the copy. + // Avoids an allocation and a copy. + if wt, ok := src.(io.WriterTo); ok { + return wt.WriteTo(dst) + } + // Similarly, if the writer has a ReadFrom method, use it to do the copy. + if rt, ok := dst.(io.ReaderFrom); ok { + return rt.ReadFrom(src) + } buf := make([]byte, 32*1024) for { diff --git a/hkexsh/hkexsh.go b/hkexsh/hkexsh.go index d37535a..76a96c7 100644 --- a/hkexsh/hkexsh.go +++ b/hkexsh/hkexsh.go @@ -17,6 +17,7 @@ import ( "os/exec" "os/signal" "os/user" + "runtime" "strings" "sync" "syscall" @@ -79,7 +80,7 @@ func main() { flag.StringVar(&server, "s", "localhost:2000", "server hostname/address[:port]") flag.StringVar(&cmdStr, "x", "", "command to run (default empty - interactive shell)") flag.StringVar(&altUser, "u", "", "specify alternate user") - flag.StringVar(&authCookie, "a", "", "auth cookie (MultiCheese3999(tm) 2FA cookie") + flag.StringVar(&authCookie, "a", "", "auth cookie") flag.BoolVar(&dbg, "d", false, "debug logging") flag.Parse() @@ -145,6 +146,9 @@ func main() { panic(err) } authCookie = string(ab) + // Security scrub + ab = nil + runtime.GC() } rec := &cmdSpec{ @@ -187,8 +191,10 @@ func main() { } if isInteractive { - log.Println("[Got EOF]") - wg.Done() // server hung up, close WaitGroup to exit client + log.Println("[* Got EOF *]") + _ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort. + wg.Done() + os.Exit(0) } }() @@ -236,8 +242,6 @@ func main() { } } log.Println("[Sent EOF]") - //FIXME: regression circa. April 30 2018 on 'exit' from client, - //fixme: Enter/RETURN required prior to actua client exit wg.Done() // client hung up, close WaitGroup to exit client }() } diff --git a/hkexshd/hkexshd.go b/hkexshd/hkexshd.go index a207847..e33180f 100644 --- a/hkexshd/hkexshd.go +++ b/hkexshd/hkexshd.go @@ -16,6 +16,7 @@ import ( "os" "os/exec" "os/user" + "runtime" "syscall" hkexsh "blitter.com/go/hkexsh" @@ -246,6 +247,12 @@ func main() { rec.op[0], string(rec.who), string(rec.cmd)) valid, allowedCmds := hkexsh.AuthUser(string(rec.who), string(rec.authCookie), "/etc/hkexsh.passwd") + // Security scrub + for i := range rec.authCookie { + rec.authCookie[i] = 0 + } + runtime.GC() + if !valid { log.Println("Invalid user", string(rec.who)) c.Write([]byte(rejectUserMsg()))