Add (as default) option to use system shadow passwds

This commit is contained in:
Russ Magee 2019-12-19 20:01:39 -08:00
parent 1f84bc95ff
commit faf4d5c50a
3 changed files with 57 additions and 4 deletions

View File

@ -18,6 +18,7 @@ Architecture
(parts split out into hkexnet/*, hkexsession.go)
(DONE) - Make KEx fully-pluggable: isolate all code to do with Herradura into a
KEx-neutral pkg so it can be swapped out for other methods (eg., DH etc.)
(DONE - test branch) - Use system password db (/etc/{passwd,shadow})
Features
(DONE) - Support for hkcp (hkex-cp) - secure file copy protocol

50
auth.go
View File

@ -13,6 +13,7 @@ package xs
import (
"bytes"
"encoding/csv"
"errors"
"fmt"
"io"
"io/ioutil"
@ -22,13 +23,49 @@ import (
"strings"
"github.com/jameskeane/bcrypt"
passlib "gopkg.in/hlandau/passlib.v1"
)
func userExistsOnSystem(who string) bool {
_, userErr := user.Lookup(who)
return userErr == nil
// --------- System passwd/shadow auth routine(s) --------------
// Verify a password against system standard shadow file
// Note auxilliary fields for expiry policy are *not* inspected.
func VerifyPass(user, password string) (bool, error) {
passlib.UseDefaults(passlib.Defaults20180601)
pwFileData, e := ioutil.ReadFile("/etc/shadow")
if e != nil {
return false, e
}
pwLines := strings.Split(string(pwFileData), "\n")
if len(pwLines) < 1 {
return false, errors.New("Empty shadow file!")
} else {
var line string
var hash string
var idx int
for idx = range pwLines {
line = pwLines[idx]
lFields := strings.Split(line, ":")
if lFields[0] == user {
hash = lFields[1]
break
}
}
if len(hash) == 0 {
return false, errors.New("nil hash!")
} else {
pe := passlib.VerifyNoUpgrade(password, hash)
if pe != nil {
return false, pe
}
}
}
return true, nil
}
// --------- End System passwd/shadow auth routine(s) ----------
// ------------- xs-local passwd auth routine(s) ---------------
// AuthUserByPasswd checks user login information using a password.
// This checks /etc/xs.passwd for auth info, and system /etc/passwd
// to cross-check the user actually exists.
@ -84,6 +121,13 @@ func AuthUserByPasswd(username string, auth string, fname string) (valid bool, a
return
}
// ------------- End xs-local passwd auth routine(s) -----------
func userExistsOnSystem(who string) bool {
_, userErr := user.Lookup(who)
return userErr == nil
}
// AuthUserByToken checks user login information against an auth token.
// Auth tokens are stored in each user's $HOME/.xs_id and are requested
// via the -g option.

View File

@ -509,6 +509,8 @@ func main() {
var dbg bool
var laddr string
var useSystemPasswd bool
flag.BoolVar(&vopt, "v", false, "show version")
flag.StringVar(&laddr, "l", ":2000", "interface[:port] to listen")
flag.StringVar(&kcpMode, "K", "unused", `set to one of ["KCP_NONE","KCP_AES", "KCP_BLOWFISH", "KCP_CAST5", "KCP_SM4", "KCP_SALSA20", "KCP_SIMPLEXOR", "KCP_TEA", "KCP_3DES", "KCP_TWOFISH", "KCP_XTEA"] to use KCP (github.com/xtaci/kcp-go) reliable UDP instead of TCP`)
@ -517,6 +519,7 @@ func main() {
flag.UintVar(&chaffFreqMin, "f", 100, "chaff pkt freq min (msecs)")
flag.UintVar(&chaffFreqMax, "F", 5000, "chaff pkt freq max (msecs)")
flag.UintVar(&chaffBytesMax, "B", 64, "chaff pkt size max (bytes)")
flag.BoolVar(&useSystemPasswd, "s", true, "use system shadow passwds")
flag.BoolVar(&dbg, "d", false, "debug logging")
flag.Var(&aKEXAlgs, "aK", `List of allowed KEX algs (eg. 'KEXAlgA KEXAlgB ... KEXAlgN') (default allow all)`)
@ -709,7 +712,12 @@ func main() {
if xs.AuthUserByToken(string(rec.Who()), string(rec.ConnHost()), string(rec.AuthCookie(true))) {
valid = true
} else {
valid, allowedCmds = xs.AuthUserByPasswd(string(rec.Who()), string(rec.AuthCookie(true)), "/etc/xs.passwd")
if useSystemPasswd {
//var passErr error
valid, _ /*passErr*/ = xs.VerifyPass(string(rec.Who()), string(rec.AuthCookie(true)))
} else {
valid, allowedCmds = xs.AuthUserByPasswd(string(rec.Who()), string(rec.AuthCookie(true)), "/etc/xs.passwd")
}
}
// Security scrub