diff --git a/Makefile b/Makefile index 0c2eb7e..4d1c19b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: info clean common client server passwd subpkgs -SUBPKGS = spinsult hkexnet herradurakex +SUBPKGS = logger spinsult hkexnet herradurakex TOOLS = hkexpasswd hkexsh hkexshd SUBDIRS = $(LIBS) $(TOOLS) @@ -28,12 +28,16 @@ common: client: common $(MAKE) -C hkexsh -ifneq ($(MSYSTEM),) -server: common - echo "hkexshd server not (yet) supported on Windows" -else +ifeq ($(MSYSTEM),) +ifneq ($(GOOS),windows) server: common $(MAKE) -C hkexshd +else + echo "Cross-build of hkexshd server for Windows not yet supported" +endif +else +server: common + echo "hkexshd server not (yet) supported on Windows" endif passwd: common diff --git a/hkexnet/hkexnet.go b/hkexnet/hkexnet.go index e8d3778..1076afa 100644 --- a/hkexnet/hkexnet.go +++ b/hkexnet/hkexnet.go @@ -39,7 +39,6 @@ import ( "io" "io/ioutil" "log" - "log/syslog" "math/big" "math/rand" "net" @@ -48,6 +47,7 @@ import ( "time" "blitter.com/go/hkexsh/herradurakex" + "blitter.com/go/hkexsh/logger" kyber "git.schwanenlied.me/yawning/kyber.git" ) @@ -98,12 +98,12 @@ type ( ) var ( - Log *syslog.Writer // reg. syslog output (no -d) + Log *logger.Writer // reg. syslog output (no -d) ) -func _initLogging(d bool, c string, f syslog.Priority) { +func _initLogging(d bool, c string, f logger.Priority) { if Log == nil { - Log, _ = syslog.New(f, fmt.Sprintf("%s:hkexnet", c)) + Log, _ = logger.New(f, fmt.Sprintf("%s:hkexnet", c)) } if d { log.SetFlags(0) // syslog will have date,time @@ -113,7 +113,7 @@ func _initLogging(d bool, c string, f syslog.Priority) { } } -func Init(d bool, c string, f syslog.Priority) { +func Init(d bool, c string, f logger.Priority) { _initLogging(d, c, f) } @@ -477,7 +477,7 @@ func HKExAcceptSetup(c *net.Conn, hc *Conn) (err error) { // "H_SHA256" func Dial(protocol string, ipport string, extensions ...string) (hc Conn, err error) { if Log == nil { - Init(false, "client", syslog.LOG_DAEMON|syslog.LOG_DEBUG) + Init(false, "client", logger.LOG_DAEMON|logger.LOG_DEBUG) } // Open raw Conn c @@ -534,7 +534,7 @@ func (hc *Conn) Close() (err error) { log.Printf("** Writing closeStat %d at Close()\n", *hc.closeStat) hc.WritePacket(s, CSOExitStatus) err = (*hc.c).Close() - Log.Notice(fmt.Sprintln("[Conn Closing]")) + logger.LogNotice(fmt.Sprintln("[Conn Closing]")) return } @@ -597,14 +597,14 @@ type HKExListener struct { // See go doc net.Listen func Listen(protocol string, ipport string) (hl HKExListener, e error) { if Log == nil { - Init(false, "server", syslog.LOG_DAEMON|syslog.LOG_DEBUG) + Init(false, "server", logger.LOG_DAEMON|logger.LOG_DEBUG) } l, err := net.Listen(protocol, ipport) if err != nil { return HKExListener{nil}, err } - Log.Notice(fmt.Sprintf("[Listening on %s]\n", ipport)) + logger.LogNotice(fmt.Sprintf("[Listening on %s]\n", ipport)) hl.l = l return } @@ -614,7 +614,7 @@ func Listen(protocol string, ipport string) (hl HKExListener, e error) { // // See go doc net.Listener.Close func (hl HKExListener) Close() error { - Log.Notice(fmt.Sprintln("[Listener Closed]")) + logger.LogNotice(fmt.Sprintln("[Listener Closed]")) return hl.l.Close() } @@ -634,7 +634,7 @@ func (hl *HKExListener) Accept() (hc Conn, err error) { if err != nil { return Conn{}, err } - Log.Notice(fmt.Sprintln("[net.Listener Accepted]")) + logger.LogNotice(fmt.Sprintln("[net.Listener Accepted]")) // Read KEx alg proposed by client var kexAlg KEXAlg @@ -713,7 +713,7 @@ func (hc Conn) Read(b []byte) (n int, err error) { // (on server side) err.Error() == ": use of closed network connection" if err != nil { if err == io.EOF || strings.HasSuffix(err.Error(), "use of closed network connection") { - Log.Notice(fmt.Sprintln("[Client hung up]")) + logger.LogNotice(fmt.Sprintln("[Client hung up]")) } else { log.Println(err) } @@ -723,12 +723,12 @@ func (hc Conn) Read(b []byte) (n int, err error) { err = binary.Read(*hc.c, binary.BigEndian, &payloadLen) if err != nil { if err.Error() != "EOF" { - Log.Err(fmt.Sprintln("[2]unexpected Read() err:", err)) + logger.LogErr(fmt.Sprintln("[2]unexpected Read() err:", err)) } } if payloadLen > MAX_PAYLOAD_LEN { - Log.Err(fmt.Sprintf("[Insane payloadLen:%v]\n", payloadLen)) + logger.LogErr(fmt.Sprintf("[Insane payloadLen:%v]\n", payloadLen)) hc.Close() return 1, errors.New("Insane payloadLen") } @@ -740,9 +740,9 @@ func (hc Conn) Read(b []byte) (n int, err error) { // (on server side) err.Error() == ": use of closed network connection" if err != nil && err.Error() != "EOF" { if !strings.HasSuffix(err.Error(), "use of closed network connection") { - Log.Err(fmt.Sprintln("[3]unexpected Read() err:", err)) + logger.LogErr(fmt.Sprintln("[3]unexpected Read() err:", err)) } else { - Log.Notice(fmt.Sprintln("[Client hung up]")) + logger.LogNotice(fmt.Sprintln("[Client hung up]")) } } @@ -787,7 +787,7 @@ func (hc Conn) Read(b []byte) (n int, err error) { if len(payloadBytes) > 0 { hc.SetStatus(CSOType(binary.BigEndian.Uint32(payloadBytes))) } else { - Log.Err(fmt.Sprintln("[truncated payload, cannot determine CSOExitStatus]")) + logger.LogErr(fmt.Sprintln("[truncated payload, cannot determine CSOExitStatus]")) hc.SetStatus(CSETruncCSO) } hc.Close() @@ -800,11 +800,11 @@ func (hc Conn) Read(b []byte) (n int, err error) { log.Printf("<%04x) HMAC:(i)%s (c)%02x\r\n", decryptN, hex.EncodeToString([]byte(hmacIn[0:])), hTmp) if *hc.closeStat == CSETruncCSO { - Log.Err(fmt.Sprintln("[cannot verify HMAC]")) + logger.LogErr(fmt.Sprintln("[cannot verify HMAC]")) } else { // Log alert if hmac didn't match, corrupted channel if !bytes.Equal(hTmp, []byte(hmacIn[0:])) /*|| hmacIn[0] > 0xf8*/ { - Log.Err(fmt.Sprintln("** ALERT - detected HMAC mismatch, possible channel tampering **")) + logger.LogErr(fmt.Sprintln("** ALERT - detected HMAC mismatch, possible channel tampering **")) _, _ = (*hc.c).Write([]byte{CSOHmacInvalid}) } } diff --git a/hkexsh/hkexsh.go b/hkexsh/hkexsh.go index c778d46..8cfe93e 100755 --- a/hkexsh/hkexsh.go +++ b/hkexsh/hkexsh.go @@ -16,7 +16,6 @@ import ( "io" "io/ioutil" "log" - "log/syslog" "os" "os/exec" "os/user" @@ -30,12 +29,13 @@ import ( hkexsh "blitter.com/go/hkexsh" "blitter.com/go/hkexsh/hkexnet" "blitter.com/go/hkexsh/spinsult" + "blitter.com/go/hkexsh/logger" isatty "github.com/mattn/go-isatty" ) var ( wg sync.WaitGroup - Log *syslog.Writer // reg. syslog output (no -d) + Log *logger.Writer // reg. syslog output (no -d) ) // Get terminal size using 'stty' command @@ -471,8 +471,8 @@ func main() { // either the shell session or copy operation. _ = shellMode - Log, _ = syslog.New(syslog.LOG_USER|syslog.LOG_DEBUG, "hkexsh") - hkexnet.Init(dbg, "hkexsh", syslog.LOG_USER|syslog.LOG_DEBUG) + Log, _ = logger.New(logger.LOG_USER|logger.LOG_DEBUG, "hkexsh") + hkexnet.Init(dbg, "hkexsh", logger.LOG_USER|logger.LOG_DEBUG) if dbg { log.SetOutput(Log) } else { diff --git a/logger/Makefile b/logger/Makefile new file mode 100644 index 0000000..32000d7 --- /dev/null +++ b/logger/Makefile @@ -0,0 +1,10 @@ +.PHONY: clean all + +EXE = $(notdir $(shell pwd)) + +all: + go build . + +clean: + $(RM) $(EXE) $(EXE).exe + diff --git a/logger/logger_linux.go b/logger/logger_linux.go new file mode 100644 index 0000000..2179ddd --- /dev/null +++ b/logger/logger_linux.go @@ -0,0 +1,100 @@ +// +build linux +// +// Wrapper around UNIX syslog, so that it also may be wrapped +// with something else for Windows (Sadly, the stdlib log/syslog +// is frozen, and there is no Window implementation.) +package logger + +import ( + sl "log/syslog" +) + +type Priority = sl.Priority +type Writer = sl.Writer + +const ( + // Severity. + + // From /usr/include/sys/syslog.h. + // These are the same on Linux, BSD, and OS X. + LOG_EMERG Priority = iota + LOG_ALERT + LOG_CRIT + LOG_ERR + LOG_WARNING + LOG_NOTICE + LOG_INFO + LOG_DEBUG +) + +const ( + // Facility. + + // From /usr/include/sys/syslog.h. + // These are the same up to LOG_FTP on Linux, BSD, and OS X. + LOG_KERN Priority = iota << 3 + LOG_USER + LOG_MAIL + LOG_DAEMON + LOG_AUTH + LOG_SYSLOG + LOG_LPR + LOG_NEWS + LOG_UUCP + LOG_CRON + LOG_AUTHPRIV + LOG_FTP + _ // unused + _ // unused + _ // unused + _ // unused + LOG_LOCAL0 + LOG_LOCAL1 + LOG_LOCAL2 + LOG_LOCAL3 + LOG_LOCAL4 + LOG_LOCAL5 + LOG_LOCAL6 + LOG_LOCAL7 +) + +var ( + l *sl.Writer +) + +func New(flags Priority, tag string) (w *Writer, e error) { + w, e = sl.New(sl.Priority(flags), tag) + l = w + return w, e +} + +func Alert(s string) error { + return l.Alert(s) +} +func LogClose() error { + return l.Close() +} +func LogCrit(s string) error { + return l.Crit(s) +} +func LogDebug(s string) error { + return l.Debug(s) +} +func LogEmerg(s string) error { + return l.Emerg(s) +} +func LogErr(s string) error { + return l.Err(s) +} +func LogInfo(s string) error { + return l.Info(s) +} +func LogNotice(s string) error { + return l.Notice(s) +} +func LogWarning(s string) error { + return l.Warning(s) +} +func LogWrite(b []byte) (int, error) { + return l.Write(b) +} diff --git a/logger/logger_windows.go b/logger/logger_windows.go new file mode 100644 index 0000000..793e982 --- /dev/null +++ b/logger/logger_windows.go @@ -0,0 +1,94 @@ +// +build windows +// +// Wrapper around UNIX syslog, so that it also may be wrapped +// with something else for Windows. +package logger + +import ( + "os" +) + +type Priority = int +type Writer = os.File + + +const ( + // Severity. + + // From /usr/include/sys/syslog.h. + // These are the same on Linux, BSD, and OS X. + LOG_EMERG Priority = iota + LOG_ALERT + LOG_CRIT + LOG_ERR + LOG_WARNING + LOG_NOTICE + LOG_INFO + LOG_DEBUG +) + +const ( + // Facility. + + // From /usr/include/sys/syslog.h. + // These are the same up to LOG_FTP on Linux, BSD, and OS X. + LOG_KERN Priority = iota << 3 + LOG_USER + LOG_MAIL + LOG_DAEMON + LOG_AUTH + LOG_SYSLOG + LOG_LPR + LOG_NEWS + LOG_UUCP + LOG_CRON + LOG_AUTHPRIV + LOG_FTP + _ // unused + _ // unused + _ // unused + _ // unused + LOG_LOCAL0 + LOG_LOCAL1 + LOG_LOCAL2 + LOG_LOCAL3 + LOG_LOCAL4 + LOG_LOCAL5 + LOG_LOCAL6 + LOG_LOCAL7 +) + +func New(flags Priority, tag string) (w *Writer, e error) { + return os.Stderr, nil +} + +func Alert(s string) error { + return nil +} +func LogClose() error { + return nil +} +func LogCrit(s string) error { + return nil +} +func LogDebug(s string) error { + return nil +} +func LogEmerg(s string) error { + return nil +} +func LogErr(s string) error { + return nil +} +func LogInfo(s string) error { + return nil +} +func LogNotice(s string) error { + return nil +} +func LogWarning(s string) error { + return nil +} +func LogWrite(b []byte) (int, error) { + return len(b), nil +}