mirror of
				https://gogs.blitter.com/RLabs/xs
				synced 2024-08-14 10:26:42 +00:00 
			
		
		
		
	Add (as default) option to use system shadow passwds
This commit is contained in:
		
							parent
							
								
									96cdec0a86
								
							
						
					
					
						commit
						f6a85ca071
					
				
					 3 changed files with 57 additions and 4 deletions
				
			
		
							
								
								
									
										1
									
								
								TODO.txt
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								TODO.txt
									
										
									
									
									
								
							|  | @ -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
									
										
									
									
									
								
							
							
						
						
									
										50
									
								
								auth.go
									
										
									
									
									
								
							|  | @ -13,6 +13,7 @@ package xs | |||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/csv" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
|  | @ -22,12 +23,48 @@ 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 | ||||
|  | @ -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. | ||||
|  |  | |||
|  | @ -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)`) | ||||
|  | @ -708,9 +711,14 @@ func main() { | |||
| 				var allowedCmds string // Currently unused | ||||
| 				if xs.AuthUserByToken(string(rec.Who()), string(rec.ConnHost()), string(rec.AuthCookie(true))) { | ||||
| 					valid = true | ||||
| 				} else { | ||||
| 					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 | ||||
| 				rec.ClearAuthCookie() | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue