mirror of
				https://gogs.blitter.com/RLabs/xs
				synced 2024-08-14 10:26:42 +00:00 
			
		
		
		
	Fixed misuse of iota in xsnet/consts.go that broke channel status opcodes
Cleaned up var declarations and added some greppable comments to show xs setup & flow
This commit is contained in:
		
							parent
							
								
									0204284bb2
								
							
						
					
					
						commit
						cb92b247d7
					
				
					 3 changed files with 66 additions and 35 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -1,4 +1,4 @@ | |||
| VERSION := 0.8.23 | ||||
| VERSION := 0.8.24 | ||||
| .PHONY: lint vis clean common client server passwd subpkgs install uninstall reinstall | ||||
| 
 | ||||
| ## Tag version of binaries with build info wrt.
 | ||||
|  |  | |||
							
								
								
									
										93
									
								
								xs/xs.go
									
										
									
									
									
								
							
							
						
						
									
										93
									
								
								xs/xs.go
									
										
									
									
									
								
							|  | @ -678,31 +678,35 @@ func sendSessionParams(conn io.Writer /* *xsnet.Conn*/, rec *xs.Session) (e erro | |||
| 
 | ||||
| // TODO: reduce gocyclo | ||||
| func main() { | ||||
| 	var vopt bool | ||||
| 	var gopt bool //login via password, asking server to generate authToken | ||||
| 	var dbg bool | ||||
| 	var shellMode bool   // if true act as shell, else file copier | ||||
| 	var cipherAlg string //cipher alg | ||||
| 	var hmacAlg string   //hmac alg | ||||
| 	var kexAlg string    //KEX/KEM alg | ||||
| 	var server string | ||||
| 	var port uint | ||||
| 	var cmdStr string | ||||
| 	var tunSpecStr string // lport1:rport1[,lport2:rport2,...] | ||||
| 	var ( | ||||
| 		isInteractive bool | ||||
| 		vopt          bool | ||||
| 		gopt          bool //login via password, asking server to generate authToken | ||||
| 		dbg           bool | ||||
| 		shellMode     bool   // if true act as shell, else file copier | ||||
| 		cipherAlg     string //cipher alg | ||||
| 		hmacAlg       string //hmac alg | ||||
| 		kexAlg        string //KEX/KEM alg | ||||
| 		server        string | ||||
| 		port          uint | ||||
| 		cmdStr        string | ||||
| 		tunSpecStr    string // lport1:rport1[,lport2:rport2,...] | ||||
| 
 | ||||
| 	var copySrc []byte | ||||
| 	var copyDst string | ||||
| 	var copyQuiet bool | ||||
| 	var copyLimitBPS uint | ||||
| 		copySrc      []byte | ||||
| 		copyDst      string | ||||
| 		copyQuiet    bool | ||||
| 		copyLimitBPS uint | ||||
| 
 | ||||
| 	var authCookie string | ||||
| 	var chaffEnabled bool | ||||
| 	var chaffFreqMin uint | ||||
| 	var chaffFreqMax uint | ||||
| 	var chaffBytesMax uint | ||||
| 		authCookie    string | ||||
| 		chaffEnabled  bool | ||||
| 		chaffFreqMin  uint | ||||
| 		chaffFreqMax  uint | ||||
| 		chaffBytesMax uint | ||||
| 
 | ||||
| 	var op []byte | ||||
| 	isInteractive := false | ||||
| 		op []byte | ||||
| 	) | ||||
| 
 | ||||
| 	//=== Common (xs and xc) option parsing | ||||
| 
 | ||||
| 	flag.BoolVar(&vopt, "v", false, "show version") | ||||
| 	flag.BoolVar(&dbg, "d", false, "debug logging") | ||||
|  | @ -720,6 +724,8 @@ func main() { | |||
| 	flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to <`file`>") | ||||
| 	flag.StringVar(&memprofile, "memprofile", "", "write memory profile to <`file`>") | ||||
| 
 | ||||
| 	//=== xc vs. xs option parsing | ||||
| 
 | ||||
| 	// Find out what program we are (shell or copier) | ||||
| 	myPath := strings.Split(os.Args[0], string(os.PathSeparator)) | ||||
| 	if myPath[len(myPath)-1] != "xc" && | ||||
|  | @ -745,6 +751,8 @@ func main() { | |||
| 		exitWithStatus(0) | ||||
| 	} | ||||
| 
 | ||||
| 	//=== Profiling instrumentation | ||||
| 
 | ||||
| 	if cpuprofile != "" { | ||||
| 		f, err := os.Create(cpuprofile) | ||||
| 		if err != nil { | ||||
|  | @ -761,6 +769,8 @@ func main() { | |||
| 		go func() { http.ListenAndServe("localhost:6060", nil) }() | ||||
| 	} | ||||
| 
 | ||||
| 	//=== User, host, port and path args for file operations, if applicable | ||||
| 
 | ||||
| 	remoteUser, remoteHost, tmpPath, pathIsDest, otherArgs := | ||||
| 		parseNonSwitchArgs(flag.Args()) | ||||
| 	//fmt.Println("otherArgs:", otherArgs) | ||||
|  | @ -781,6 +791,8 @@ func main() { | |||
| 		tmpPath = "." | ||||
| 	} | ||||
| 
 | ||||
| 	//=== Copy mode arg and copy src/dest setup | ||||
| 
 | ||||
| 	var fileArgs string | ||||
| 	if !shellMode /*&& tmpPath != ""*/ { | ||||
| 		// -if pathIsSrc && len(otherArgs) > 1 ERROR | ||||
|  | @ -812,7 +824,7 @@ func main() { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Do some more option consistency checks | ||||
| 	//=== Do some final option consistency checks | ||||
| 
 | ||||
| 	//fmt.Println("server finally is:", server) | ||||
| 	if flag.NFlag() == 0 && server == "" { | ||||
|  | @ -824,7 +836,6 @@ func main() { | |||
| 		log.Fatal("incompatible options -- either cmd (-x) or copy ops but not both") | ||||
| 	} | ||||
| 
 | ||||
| 	//------------------------------------------------------------------- | ||||
| 	// Here we have parsed all options and can now carry out | ||||
| 	// either the shell session or copy operation. | ||||
| 	_ = shellMode | ||||
|  | @ -837,6 +848,8 @@ func main() { | |||
| 		log.SetOutput(ioutil.Discard) | ||||
| 	} | ||||
| 
 | ||||
| 	//=== Auth token fetch for login | ||||
| 
 | ||||
| 	if !gopt { | ||||
| 		// See if we can log in via an auth token | ||||
| 		u, _ := user.Current() // nolint: gosec | ||||
|  | @ -858,7 +871,7 @@ func main() { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Enforce some sane min/max vals on chaff flags | ||||
| 	//=== Enforce some sane min/max vals on chaff flags | ||||
| 	if chaffFreqMin < 2 { | ||||
| 		chaffFreqMin = 2 | ||||
| 	} | ||||
|  | @ -869,6 +882,8 @@ func main() { | |||
| 		chaffBytesMax = 64 | ||||
| 	} | ||||
| 
 | ||||
| 	//=== Shell vs. Copy mode chaff and cmd setup | ||||
| 
 | ||||
| 	if shellMode { | ||||
| 		// We must make the decision about interactivity before Dial() | ||||
| 		// as it affects chaffing behaviour. 20180805 | ||||
|  | @ -909,6 +924,8 @@ func main() { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	//=== TCP / KCP Dial setup | ||||
| 
 | ||||
| 	proto := "tcp" | ||||
| 	if kcpMode != "unused" { | ||||
| 		proto = "kcp" | ||||
|  | @ -919,13 +936,15 @@ func main() { | |||
| 		exitWithStatus(3) | ||||
| 	} | ||||
| 
 | ||||
| 	//=== Shell terminal mode (Shell vs. Copy) setup | ||||
| 
 | ||||
| 	// Set stdin in raw mode if it's an interactive session | ||||
| 	// TODO: send flag to server side indicating this | ||||
| 	//  affects shell command used | ||||
| 	var oldState *xs.State | ||||
| 	defer conn.Close() // nolint: errcheck | ||||
| 
 | ||||
| 	// From this point on, conn is a secure encrypted channel | ||||
| 	//=== From this point on, conn is a secure encrypted channel | ||||
| 
 | ||||
| 	if shellMode { | ||||
| 		if isatty.IsTerminal(os.Stdin.Fd()) { | ||||
|  | @ -941,6 +960,8 @@ func main() { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	//=== Login phase | ||||
| 
 | ||||
| 	// Start login timeout here and disconnect if user/pass phase stalls | ||||
| 	//iloginImpatience := time.AfterFunc(20*time.Second, func() { | ||||
| 	//i	fmt.Printf(" .. [you still there? Waiting for a password.]") | ||||
|  | @ -961,12 +982,14 @@ func main() { | |||
| 		} | ||||
| 		authCookie = string(ab) | ||||
| 	} | ||||
| 	 | ||||
| 
 | ||||
| 	//i_ = loginImpatience.Stop() | ||||
| 	_ = loginTimeout.Stop() | ||||
| 	// Security scrub | ||||
| 	runtime.GC() | ||||
| 
 | ||||
| 	//=== Session param and TERM setup | ||||
| 
 | ||||
| 	// Set up session params and send over to server | ||||
| 	rec := xs.NewSession(op, []byte(uname), []byte(remoteHost), []byte(os.Getenv("TERM")), []byte(cmdStr), []byte(authCookie), 0) | ||||
| 	sendErr := sendSessionParams(&conn, rec) | ||||
|  | @ -982,17 +1005,21 @@ func main() { | |||
| 	authCookie = "" // nolint: ineffassign | ||||
| 	runtime.GC() | ||||
| 
 | ||||
| 	// Read auth reply from server | ||||
| 	//=== Login Auth | ||||
| 
 | ||||
| 	//=== Read auth reply from server | ||||
| 	authReply := make([]byte, 1) // bool: 0 = fail, 1 = pass | ||||
| 	_, err = conn.Read(authReply) | ||||
| 	if err != nil { | ||||
| 		//=== Exit if auth reply not received | ||||
| 		fmt.Fprintln(os.Stderr, "Error reading auth reply") // nolint: errcheck | ||||
| 		rec.SetStatus(255) | ||||
| 	} else if authReply[0] == 0 { | ||||
| 		//=== .. or if auth failed | ||||
| 		fmt.Fprintln(os.Stderr, rejectUserMsg()) // nolint: errcheck | ||||
| 		rec.SetStatus(255) | ||||
| 	} else { | ||||
| 		// Set up chaffing to server | ||||
| 		//=== Set up chaffing to server | ||||
| 		conn.SetupChaff(chaffFreqMin, chaffFreqMax, chaffBytesMax) // enable client->server chaffing | ||||
| 		if chaffEnabled { | ||||
| 			// #gv:s/label=\"main\$2\"/label=\"deferCloseChaff\"/ | ||||
|  | @ -1002,7 +1029,7 @@ func main() { | |||
| 			defer conn.ShutdownChaff() | ||||
| 		} | ||||
| 
 | ||||
| 		// Keepalive for any tunnels that may exist | ||||
| 		//=== (goroutine) Start keepAliveWorker for tunnels | ||||
| 		// #gv:s/label=\"main\$1\"/label=\"tunKeepAlive\"/ | ||||
| 		// TODO:.gv:main:1:tunKeepAlive | ||||
| 		//[1]: better to always send tunnel keepAlives even if client didn't specify | ||||
|  | @ -1021,10 +1048,13 @@ func main() { | |||
| 		go keepAliveWorker() | ||||
| 		//[1]} | ||||
| 
 | ||||
| 		//=== Session entry (shellMode or copyMode) | ||||
| 		if shellMode { | ||||
| 			//=== (shell) launch tunnels | ||||
| 			launchTuns(&conn, remoteHost, tunSpecStr) | ||||
| 			doShellMode(isInteractive, &conn, oldState, rec) | ||||
| 		} else { // copyMode | ||||
| 		} else { | ||||
| 			//=== (.. or file copy) | ||||
| 			s, _ := doCopyMode(&conn, pathIsDest, fileArgs, copyQuiet, copyLimitBPS, rec) // nolint: errcheck,gosec | ||||
| 			rec.SetStatus(s) | ||||
| 		} | ||||
|  | @ -1040,6 +1070,7 @@ func main() { | |||
| 		oldState = nil | ||||
| 	} | ||||
| 
 | ||||
| 	//=== Exit | ||||
| 	exitWithStatus(int(rec.Status())) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -62,12 +62,12 @@ const ( | |||
| 	CSOTermSize           // set term size (rows:cols) | ||||
| 	CSOExitStatus         // Remote cmd exit status | ||||
| 	CSOChaff              // Dummy packet, do not pass beyond decryption | ||||
| 	 | ||||
| 
 | ||||
| 	// Client side errors | ||||
| 	CSOLoginTimeout = 16 | ||||
| 	CSOLoginTimeout | ||||
| 
 | ||||
| 	// Tunnel setup/control/status | ||||
| 	CSOTunSetup = 32     // client -> server tunnel setup request (dstport) | ||||
| 	CSOTunSetup     // client -> server tunnel setup request (dstport) | ||||
| 	CSOTunSetupAck  // server -> client tunnel setup ack | ||||
| 	CSOTunRefused   // server -> client: tunnel rport connection refused | ||||
| 	CSOTunData      // packet contains tunnel data [rport:data] | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue