Fixed error in processing of allowed HMAC algs.

xsd: allowed algs default to none if unspecified.
This commit is contained in:
Russ Magee 2021-11-14 21:17:56 -08:00
parent 129dce4b08
commit cfc9ab8590
2 changed files with 254 additions and 231 deletions

View File

@ -439,9 +439,9 @@ var (
aHMACAlgs allowedHMACAlgs aHMACAlgs allowedHMACAlgs
) )
type allowedKEXAlgs []string // TODO type allowedKEXAlgs []string
type allowedCipherAlgs []string // TODO type allowedCipherAlgs []string
type allowedHMACAlgs []string // TODO type allowedHMACAlgs []string
func (a allowedKEXAlgs) allowed(k xsnet.KEXAlg) bool { func (a allowedKEXAlgs) allowed(k xsnet.KEXAlg) bool {
for i := 0; i < len(a); i++ { for i := 0; i < len(a); i++ {
@ -527,9 +527,33 @@ func main() {
flag.BoolVar(&useSystemPasswd, "s", true, "use system shadow passwds") flag.BoolVar(&useSystemPasswd, "s", true, "use system shadow passwds")
flag.BoolVar(&dbg, "d", false, "debug logging") flag.BoolVar(&dbg, "d", false, "debug logging")
flag.Var(&aKEXAlgs, "aK", `List of allowed KEX algs (eg. 'KEXAlgA KEXAlgB ... KEXAlgN') (default allow all)`) flag.Var(&aKEXAlgs, "aK", `Allowed KEX algs (eg. '-aK KEXAlgA -aK KEXAlgB ...') (default: none)
flag.Var(&aCipherAlgs, "aC", `List of allowed ciphers (eg. 'CipherAlgA CipherAlgB ... CipherAlgN') (default allow all)`) KEX_all
flag.Var(&aHMACAlgs, "aH", `List of allowed HMACs (eg. 'HMACAlgA HMACAlgB ... HMACAlgN') (default allow all)`) KEX_HERRADURA256
KEX_HERRADURA512
KEX_HERRADURA1024
KEX_HERRADURA2048
KEX_KYBER512
KEX_KYBER768
KEX_KYBER1024
KEX_NEWHOPE
KEX_NEWHOPE_SIMPLE
KEX_FRODOKEM_1344AES
KEX_FRODOKEM_1344SHAKE
KEX_FRODOKEM_976AES
KEX_FRODOKEM_976SHAKE`)
flag.Var(&aCipherAlgs, "aC", `Allowed ciphers (eg. '-aC CAlgA -aC CAlgB ...') (default: none)
C_all
C_AES_256
C_TWOFISH_128
C_BLOWFISH_64
C_CRYPTMT1
C_HOPSCOTCH
C_CHACHA20_12`)
flag.Var(&aHMACAlgs, "aH", `Allowed HMACs (eg. '-aH HMACAlgA -aH HMACAlgB ...') (default: none)
H_all
H_SHA256
H_SHA512`)
flag.Parse() flag.Parse()
@ -566,17 +590,17 @@ func main() {
// Set up allowed algs, if specified (default allow all) // Set up allowed algs, if specified (default allow all)
if len(aKEXAlgs) == 0 { if len(aKEXAlgs) == 0 {
aKEXAlgs = []string{"KEX_all"} aKEXAlgs = []string{"none"}
} }
logger.LogNotice(fmt.Sprintf("Allowed KEXAlgs: %v\n", aKEXAlgs)) // nolint: gosec,errcheck logger.LogNotice(fmt.Sprintf("Allowed KEXAlgs: %v\n", aKEXAlgs)) // nolint: gosec,errcheck
if len(aCipherAlgs) == 0 { if len(aCipherAlgs) == 0 {
aCipherAlgs = []string{"C_all"} aCipherAlgs = []string{"none"}
} }
logger.LogNotice(fmt.Sprintf("Allowed CipherAlgs: %v\n", aCipherAlgs)) // nolint: gosec,errcheck logger.LogNotice(fmt.Sprintf("Allowed CipherAlgs: %v\n", aCipherAlgs)) // nolint: gosec,errcheck
if len(aHMACAlgs) == 0 { if len(aHMACAlgs) == 0 {
aHMACAlgs = []string{"H_all"} aHMACAlgs = []string{"none"}
} }
logger.LogNotice(fmt.Sprintf("Allowed HMACAlgs: %v\n", aHMACAlgs)) // nolint: gosec,errcheck logger.LogNotice(fmt.Sprintf("Allowed HMACAlgs: %v\n", aHMACAlgs)) // nolint: gosec,errcheck
@ -620,233 +644,235 @@ func main() {
conn, err := l.Accept() conn, err := l.Accept()
if err != nil { if err != nil {
log.Printf("Accept() got error(%v), hanging up.\n", err) log.Printf("Accept() got error(%v), hanging up.\n", err)
} else if !aKEXAlgs.allowed(conn.KEX()) {
log.Printf("Accept() rejected for banned KEX alg %d, hanging up.\n", conn.KEX())
conn.SetStatus(xsnet.CSEKEXAlgDenied)
conn.Close()
} else if !aCipherAlgs.allowed(conn.CAlg()) {
log.Printf("Accept() rejected for banned Cipher alg %d, hanging up.\n", conn.CAlg())
conn.SetStatus(xsnet.CSECipherAlgDenied)
conn.Close()
} else if !aHMACAlgs.allowed(conn.HAlg()) {
log.Printf("Accept() rejected for banned HMAC alg %d, hanging up.\n", conn.HAlg())
conn.SetStatus(xsnet.CSEHMACAlgDenied)
conn.Close()
} else { } else {
log.Println("Accepted client") if !aKEXAlgs.allowed(conn.KEX()) {
log.Printf("Accept() rejected for banned KEX alg %d, hanging up.\n", conn.KEX())
conn.SetStatus(xsnet.CSEKEXAlgDenied)
conn.Close()
} else if !aCipherAlgs.allowed(conn.CAlg()) {
log.Printf("Accept() rejected for banned Cipher alg %d, hanging up.\n", conn.CAlg())
conn.SetStatus(xsnet.CSECipherAlgDenied)
conn.Close()
} else if !aHMACAlgs.allowed(conn.HAlg()) {
log.Printf("Accept() rejected for banned HMAC alg %d, hanging up.\n", conn.HAlg())
conn.SetStatus(xsnet.CSEHMACAlgDenied)
conn.Close()
} else {
log.Println("Accepted client")
// Set up chaffing to client // Set up chaffing to client
// Will only start when runShellAs() is called // Will only start when runShellAs() is called
// after stdin/stdout are hooked up // after stdin/stdout are hooked up
conn.SetupChaff(chaffFreqMin, chaffFreqMax, chaffBytesMax) // configure server->client chaffing conn.SetupChaff(chaffFreqMin, chaffFreqMax, chaffBytesMax) // configure server->client chaffing
// Handle the connection in a new goroutine. // Handle the connection in a new goroutine.
// The loop then returns to accepting, so that // The loop then returns to accepting, so that
// multiple connections may be served concurrently. // multiple connections may be served concurrently.
go func(hc *xsnet.Conn) (e error) { go func(hc *xsnet.Conn) (e error) {
defer hc.Close() // nolint: errcheck defer hc.Close() // nolint: errcheck
// Start login timeout here and disconnect if user/pass phase stalls // Start login timeout here and disconnect if user/pass phase stalls
loginTimeout := time.AfterFunc(30*time.Second, func() { loginTimeout := time.AfterFunc(30*time.Second, func() {
logger.LogNotice(fmt.Sprintln("Login timed out")) // nolint: errcheck,gosec logger.LogNotice(fmt.Sprintln("Login timed out")) // nolint: errcheck,gosec
hc.Write([]byte{0}) // nolint: gosec,errcheck hc.Write([]byte{0}) // nolint: gosec,errcheck
hc.Close() hc.Close()
}) })
//We use io.ReadFull() here to guarantee we consume //We use io.ReadFull() here to guarantee we consume
//just the data we want for the xs.Session, and no more. //just the data we want for the xs.Session, and no more.
//Otherwise data will be sitting in the channel that isn't //Otherwise data will be sitting in the channel that isn't
//passed down to the command handlers. //passed down to the command handlers.
var rec xs.Session var rec xs.Session
var len1, len2, len3, len4, len5, len6 uint32 var len1, len2, len3, len4, len5, len6 uint32
n, err := fmt.Fscanf(hc, "%d %d %d %d %d %d\n", &len1, &len2, &len3, &len4, &len5, &len6) n, err := fmt.Fscanf(hc, "%d %d %d %d %d %d\n", &len1, &len2, &len3, &len4, &len5, &len6)
log.Printf("xs.Session read:%d %d %d %d %d %d\n", len1, len2, len3, len4, len5, len6) log.Printf("xs.Session read:%d %d %d %d %d %d\n", len1, len2, len3, len4, len5, len6)
if err != nil || n < 6 { if err != nil || n < 6 {
log.Println("[Bad xs.Session fmt]") log.Println("[Bad xs.Session fmt]")
return err return err
}
tmp := make([]byte, len1)
_, err = io.ReadFull(hc, tmp)
if err != nil {
log.Println("[Bad xs.Session.Op]")
return err
}
rec.SetOp(tmp)
tmp = make([]byte, len2)
_, err = io.ReadFull(hc, tmp)
if err != nil {
log.Println("[Bad xs.Session.Who]")
return err
}
rec.SetWho(tmp)
tmp = make([]byte, len3)
_, err = io.ReadFull(hc, tmp)
if err != nil {
log.Println("[Bad xs.Session.ConnHost]")
return err
}
rec.SetConnHost(tmp)
tmp = make([]byte, len4)
_, err = io.ReadFull(hc, tmp)
if err != nil {
log.Println("[Bad xs.Session.TermType]")
return err
}
rec.SetTermType(tmp)
tmp = make([]byte, len5)
_, err = io.ReadFull(hc, tmp)
if err != nil {
log.Println("[Bad xs.Session.Cmd]")
return err
}
rec.SetCmd(tmp)
tmp = make([]byte, len6)
_, err = io.ReadFull(hc, tmp)
if err != nil {
log.Println("[Bad xs.Session.AuthCookie]")
return err
}
rec.SetAuthCookie(tmp)
log.Printf("[xs.Session: op:%c who:%s connhost:%s cmd:%s auth:****]\n",
rec.Op()[0], string(rec.Who()), string(rec.ConnHost()), string(rec.Cmd()))
var valid bool
var allowedCmds string // Currently unused
if xs.AuthUserByToken(xs.NewAuthCtx(), string(rec.Who()), string(rec.ConnHost()), string(rec.AuthCookie(true))) {
valid = true
} else {
if useSystemPasswd {
//var passErr error
valid, _ /*passErr*/ = xs.VerifyPass(xs.NewAuthCtx(), string(rec.Who()), string(rec.AuthCookie(true)))
} else {
valid, allowedCmds = xs.AuthUserByPasswd(xs.NewAuthCtx(), string(rec.Who()), string(rec.AuthCookie(true)), "/etc/xs.passwd")
} }
}
_ = loginTimeout.Stop() tmp := make([]byte, len1)
// Security scrub _, err = io.ReadFull(hc, tmp)
rec.ClearAuthCookie() if err != nil {
log.Println("[Bad xs.Session.Op]")
// Tell client if auth was valid return err
if valid {
hc.Write([]byte{1}) // nolint: gosec,errcheck
} else {
logger.LogNotice(fmt.Sprintln("Invalid user", string(rec.Who()))) // nolint: errcheck,gosec
hc.Write([]byte{0}) // nolint: gosec,errcheck
return
}
log.Printf("[allowedCmds:%s]\n", allowedCmds)
if rec.Op()[0] == 'A' {
// Generate automated login token
addr := hc.RemoteAddr()
hname := goutmp.GetHost(addr.String())
logger.LogNotice(fmt.Sprintf("[Generating autologin token for [%s@%s]]\n", rec.Who(), hname)) // nolint: gosec,errcheck
token := GenAuthToken(string(rec.Who()), string(rec.ConnHost()))
tokenCmd := fmt.Sprintf("echo \"%s\" | tee -a ~/.xs_id", token)
cmdStatus, runErr := runShellAs(string(rec.Who()), hname, string(rec.TermType()), tokenCmd, false, hc, chaffEnabled)
// Returned hopefully via an EOF or exit/logout;
// Clear current op so user can enter next, or EOF
rec.SetOp([]byte{0})
if runErr != nil {
logger.LogErr(fmt.Sprintf("[Error generating autologin token for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
} else {
log.Printf("[Autologin token generation completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)
hc.SetStatus(xsnet.CSOType(cmdStatus))
} }
} else if rec.Op()[0] == 'c' { rec.SetOp(tmp)
// Non-interactive command
addr := hc.RemoteAddr()
hname := goutmp.GetHost(addr.String())
logger.LogNotice(fmt.Sprintf("[Running command for [%s@%s]]\n", rec.Who(), hname)) // nolint: gosec,errcheck
cmdStatus, runErr := runShellAs(string(rec.Who()), hname, string(rec.TermType()), string(rec.Cmd()), false, hc, chaffEnabled)
// Returned hopefully via an EOF or exit/logout;
// Clear current op so user can enter next, or EOF
rec.SetOp([]byte{0})
if runErr != nil {
logger.LogErr(fmt.Sprintf("[Error spawning cmd for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
} else {
logger.LogNotice(fmt.Sprintf("[Command completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)) // nolint: gosec,errcheck
hc.SetStatus(xsnet.CSOType(cmdStatus))
}
} else if rec.Op()[0] == 's' {
// Interactive session
addr := hc.RemoteAddr()
hname := goutmp.GetHost(addr.String())
logger.LogNotice(fmt.Sprintf("[Running shell for [%s@%s]]\n", rec.Who(), hname)) // nolint: gosec,errcheck
cmdStatus, runErr := runShellAs(string(rec.Who()), hname, string(rec.TermType()), string(rec.Cmd()), true, hc, chaffEnabled) tmp = make([]byte, len2)
// Returned hopefully via an EOF or exit/logout; _, err = io.ReadFull(hc, tmp)
// Clear current op so user can enter next, or EOF if err != nil {
rec.SetOp([]byte{0}) log.Println("[Bad xs.Session.Who]")
if runErr != nil { return err
Log.Err(fmt.Sprintf("[Error spawning shell for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
} else {
logger.LogNotice(fmt.Sprintf("[Shell completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)) // nolint: gosec,errcheck
hc.SetStatus(xsnet.CSOType(cmdStatus))
} }
} else if rec.Op()[0] == 'D' { rec.SetWho(tmp)
// File copy (destination) operation - client copy to server
log.Printf("[Client->Server copy]\n")
addr := hc.RemoteAddr()
hname := goutmp.GetHost(addr.String())
logger.LogNotice(fmt.Sprintf("[c->s copy for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
cmdStatus, runErr := runClientToServerCopyAs(string(rec.Who()), string(rec.TermType()), hc, string(rec.Cmd()), chaffEnabled)
// Returned hopefully via an EOF or exit/logout;
// Clear current op so user can enter next, or EOF
rec.SetOp([]byte{0})
if runErr != nil {
logger.LogErr(fmt.Sprintf("[c->s copy error for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
} else {
logger.LogNotice(fmt.Sprintf("[c->s copy completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)) // nolint: gosec,errcheck
}
// TODO: Test this with huge files.. see Bug #22 - do we need to
// sync w/sender (client) that we've gotten all data?
hc.SetStatus(xsnet.CSOType(cmdStatus))
// Send CSOExitStatus *before* client closes channel tmp = make([]byte, len3)
s := make([]byte, 4) _, err = io.ReadFull(hc, tmp)
binary.BigEndian.PutUint32(s, cmdStatus) if err != nil {
log.Printf("** cp writing closeStat %d at Close()\n", cmdStatus) log.Println("[Bad xs.Session.ConnHost]")
hc.WritePacket(s, xsnet.CSOExitStatus) // nolint: gosec,errcheck return err
} else if rec.Op()[0] == 'S' { }
// File copy (src) operation - server copy to client rec.SetConnHost(tmp)
log.Printf("[Server->Client copy]\n")
addr := hc.RemoteAddr() tmp = make([]byte, len4)
hname := goutmp.GetHost(addr.String()) _, err = io.ReadFull(hc, tmp)
logger.LogNotice(fmt.Sprintf("[s->c copy for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck if err != nil {
cmdStatus, runErr := runServerToClientCopyAs(string(rec.Who()), string(rec.TermType()), hc, string(rec.Cmd()), chaffEnabled) log.Println("[Bad xs.Session.TermType]")
if runErr != nil { return err
logger.LogErr(fmt.Sprintf("[s->c copy error for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck }
rec.SetTermType(tmp)
tmp = make([]byte, len5)
_, err = io.ReadFull(hc, tmp)
if err != nil {
log.Println("[Bad xs.Session.Cmd]")
return err
}
rec.SetCmd(tmp)
tmp = make([]byte, len6)
_, err = io.ReadFull(hc, tmp)
if err != nil {
log.Println("[Bad xs.Session.AuthCookie]")
return err
}
rec.SetAuthCookie(tmp)
log.Printf("[xs.Session: op:%c who:%s connhost:%s cmd:%s auth:****]\n",
rec.Op()[0], string(rec.Who()), string(rec.ConnHost()), string(rec.Cmd()))
var valid bool
var allowedCmds string // Currently unused
if xs.AuthUserByToken(xs.NewAuthCtx(), string(rec.Who()), string(rec.ConnHost()), string(rec.AuthCookie(true))) {
valid = true
} else { } else {
if useSystemPasswd {
//var passErr error
valid, _ /*passErr*/ = xs.VerifyPass(xs.NewAuthCtx(), string(rec.Who()), string(rec.AuthCookie(true)))
} else {
valid, allowedCmds = xs.AuthUserByPasswd(xs.NewAuthCtx(), string(rec.Who()), string(rec.AuthCookie(true)), "/etc/xs.passwd")
}
}
_ = loginTimeout.Stop()
// Security scrub
rec.ClearAuthCookie()
// Tell client if auth was valid
if valid {
hc.Write([]byte{1}) // nolint: gosec,errcheck
} else {
logger.LogNotice(fmt.Sprintln("Invalid user", string(rec.Who()))) // nolint: errcheck,gosec
hc.Write([]byte{0}) // nolint: gosec,errcheck
return
}
log.Printf("[allowedCmds:%s]\n", allowedCmds)
if rec.Op()[0] == 'A' {
// Generate automated login token
addr := hc.RemoteAddr()
hname := goutmp.GetHost(addr.String())
logger.LogNotice(fmt.Sprintf("[Generating autologin token for [%s@%s]]\n", rec.Who(), hname)) // nolint: gosec,errcheck
token := GenAuthToken(string(rec.Who()), string(rec.ConnHost()))
tokenCmd := fmt.Sprintf("echo \"%s\" | tee -a ~/.xs_id", token)
cmdStatus, runErr := runShellAs(string(rec.Who()), hname, string(rec.TermType()), tokenCmd, false, hc, chaffEnabled)
// Returned hopefully via an EOF or exit/logout; // Returned hopefully via an EOF or exit/logout;
logger.LogNotice(fmt.Sprintf("[s->c copy completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)) // nolint: gosec,errcheck // Clear current op so user can enter next, or EOF
} rec.SetOp([]byte{0})
// HACK: Bug #22: (xc) Need to wait for rcvr to get final data if runErr != nil {
// TODO: Await specific msg from client to inform they have gotten all data from the tarpipe logger.LogErr(fmt.Sprintf("[Error generating autologin token for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
time.Sleep(time.Duration(900 * time.Millisecond)) // Let rcvr set this on setup? } else {
log.Printf("[Autologin token generation completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)
hc.SetStatus(xsnet.CSOType(cmdStatus))
}
} else if rec.Op()[0] == 'c' {
// Non-interactive command
addr := hc.RemoteAddr()
hname := goutmp.GetHost(addr.String())
logger.LogNotice(fmt.Sprintf("[Running command for [%s@%s]]\n", rec.Who(), hname)) // nolint: gosec,errcheck
cmdStatus, runErr := runShellAs(string(rec.Who()), hname, string(rec.TermType()), string(rec.Cmd()), false, hc, chaffEnabled)
// Returned hopefully via an EOF or exit/logout;
// Clear current op so user can enter next, or EOF
rec.SetOp([]byte{0})
if runErr != nil {
logger.LogErr(fmt.Sprintf("[Error spawning cmd for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
} else {
logger.LogNotice(fmt.Sprintf("[Command completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)) // nolint: gosec,errcheck
hc.SetStatus(xsnet.CSOType(cmdStatus))
}
} else if rec.Op()[0] == 's' {
// Interactive session
addr := hc.RemoteAddr()
hname := goutmp.GetHost(addr.String())
logger.LogNotice(fmt.Sprintf("[Running shell for [%s@%s]]\n", rec.Who(), hname)) // nolint: gosec,errcheck
// Clear current op so user can enter next, or EOF cmdStatus, runErr := runShellAs(string(rec.Who()), hname, string(rec.TermType()), string(rec.Cmd()), true, hc, chaffEnabled)
rec.SetOp([]byte{0}) // Returned hopefully via an EOF or exit/logout;
hc.SetStatus(xsnet.CSOType(cmdStatus)) // Clear current op so user can enter next, or EOF
//fmt.Println("Waiting for EOF from other end.") rec.SetOp([]byte{0})
//_, _ = hc.Read(nil /*ackByte*/) if runErr != nil {
//fmt.Println("Got remote end ack.") Log.Err(fmt.Sprintf("[Error spawning shell for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
} else { } else {
logger.LogErr(fmt.Sprintln("[Bad xs.Session]")) // nolint: gosec,errcheck logger.LogNotice(fmt.Sprintf("[Shell completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)) // nolint: gosec,errcheck
} hc.SetStatus(xsnet.CSOType(cmdStatus))
return }
}(&conn) // nolint: errcheck } else if rec.Op()[0] == 'D' {
// File copy (destination) operation - client copy to server
log.Printf("[Client->Server copy]\n")
addr := hc.RemoteAddr()
hname := goutmp.GetHost(addr.String())
logger.LogNotice(fmt.Sprintf("[c->s copy for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
cmdStatus, runErr := runClientToServerCopyAs(string(rec.Who()), string(rec.TermType()), hc, string(rec.Cmd()), chaffEnabled)
// Returned hopefully via an EOF or exit/logout;
// Clear current op so user can enter next, or EOF
rec.SetOp([]byte{0})
if runErr != nil {
logger.LogErr(fmt.Sprintf("[c->s copy error for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
} else {
logger.LogNotice(fmt.Sprintf("[c->s copy completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)) // nolint: gosec,errcheck
}
// TODO: Test this with huge files.. see Bug #22 - do we need to
// sync w/sender (client) that we've gotten all data?
hc.SetStatus(xsnet.CSOType(cmdStatus))
// Send CSOExitStatus *before* client closes channel
s := make([]byte, 4)
binary.BigEndian.PutUint32(s, cmdStatus)
log.Printf("** cp writing closeStat %d at Close()\n", cmdStatus)
hc.WritePacket(s, xsnet.CSOExitStatus) // nolint: gosec,errcheck
} else if rec.Op()[0] == 'S' {
// File copy (src) operation - server copy to client
log.Printf("[Server->Client copy]\n")
addr := hc.RemoteAddr()
hname := goutmp.GetHost(addr.String())
logger.LogNotice(fmt.Sprintf("[s->c copy for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
cmdStatus, runErr := runServerToClientCopyAs(string(rec.Who()), string(rec.TermType()), hc, string(rec.Cmd()), chaffEnabled)
if runErr != nil {
logger.LogErr(fmt.Sprintf("[s->c copy error for %s@%s]\n", rec.Who(), hname)) // nolint: gosec,errcheck
} else {
// Returned hopefully via an EOF or exit/logout;
logger.LogNotice(fmt.Sprintf("[s->c copy completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)) // nolint: gosec,errcheck
}
// HACK: Bug #22: (xc) Need to wait for rcvr to get final data
// TODO: Await specific msg from client to inform they have gotten all data from the tarpipe
time.Sleep(time.Duration(900 * time.Millisecond)) // Let rcvr set this on setup?
// Clear current op so user can enter next, or EOF
rec.SetOp([]byte{0})
hc.SetStatus(xsnet.CSOType(cmdStatus))
//fmt.Println("Waiting for EOF from other end.")
//_, _ = hc.Read(nil /*ackByte*/)
//fmt.Println("Got remote end ack.")
} else {
logger.LogErr(fmt.Sprintln("[Bad xs.Session]")) // nolint: gosec,errcheck
}
return
}(&conn) // nolint: errcheck
} // algs valid and not blacklisted
} // Accept() success } // Accept() success
} //endfor } //endfor
//logger.LogNotice(fmt.Sprintln("[Exiting]")) // nolint: gosec,errcheck //logger.LogNotice(fmt.Sprintln("[Exiting]")) // nolint: gosec,errcheck

View File

@ -25,6 +25,7 @@ package xsnet
import ( import (
"bytes" "bytes"
"crypto/cipher" "crypto/cipher"
crand "crypto/rand"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"errors" "errors"
@ -39,7 +40,6 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
crand "crypto/rand"
hkex "blitter.com/go/herradurakex" hkex "blitter.com/go/herradurakex"
"blitter.com/go/kyber" "blitter.com/go/kyber"
@ -169,11 +169,11 @@ func (hc *Conn) HAlg() CSHmacAlg {
} }
func (h *CSHmacAlg) String() string { func (h *CSHmacAlg) String() string {
switch (*h >> 8) & 0x0FF { switch *h & 0x0FF {
case HmacSHA256: case HmacSHA256:
return "H_SHA256" return "H_SHA256"
case HmacSHA512: case HmacSHA512:
return "C_SHA512" return "H_SHA512"
default: default:
return "H_ERR_UNK" return "H_ERR_UNK"
} }
@ -296,7 +296,7 @@ func _new(kexAlg KEXAlg, conn *net.Conn) (hc *Conn, e error) {
case KEX_FRODOKEM_976AES: case KEX_FRODOKEM_976AES:
fallthrough fallthrough
case KEX_FRODOKEM_976SHAKE: case KEX_FRODOKEM_976SHAKE:
log.Printf("[KEx alg %d accepted]\n", kexAlg) //log.Printf("[KEx alg %d is valid]\n", kexAlg)
default: default:
// UNREACHABLE: _getkexalgnum() guarantees a valid KEX value // UNREACHABLE: _getkexalgnum() guarantees a valid KEX value
hc.kex = KEX_HERRADURA512 hc.kex = KEX_HERRADURA512
@ -672,7 +672,6 @@ func FrodoKEMAcceptSetup(c *net.Conn, hc *Conn) (err error) {
} }
pubB, secB := kem.Keygen() pubB, secB := kem.Keygen()
// [Alice sends use a public key (na, ea) // [Alice sends use a public key (na, ea)
pubA_bigint := big.NewInt(0) pubA_bigint := big.NewInt(0)
_, err = fmt.Fscanf(*c, "0x%x\n", pubA_bigint) _, err = fmt.Fscanf(*c, "0x%x\n", pubA_bigint)
@ -1173,10 +1172,8 @@ func (hl *HKExListener) Accept() (hc Conn, err error) {
return Conn{}, err return Conn{}, err
} }
// Finally, ensure alg proposed by client is allowed by server config
//if hc.kex.String() {
log.Println("[hc.Accept successful]") log.Println("[hc.Accept successful]")
return return hc, err
} }
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/