mirror of
				https://gogs.blitter.com/RLabs/xs
				synced 2024-08-14 10:26:42 +00:00 
			
		
		
		
	Added login timeout (30s)
Signed-off-by: Russ Magee <rmagee@gmail.com>
This commit is contained in:
		
							parent
							
								
									9cd48bd828
								
							
						
					
					
						commit
						dbae15bff3
					
				
					 2 changed files with 28 additions and 8 deletions
				
			
		
							
								
								
									
										27
									
								
								xs/xs.go
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								xs/xs.go
									
										
									
									
									
								
							|  | @ -420,7 +420,7 @@ func doShellMode(isInteractive bool, conn *xsnet.Conn, oldState *xs.State, rec * | ||||||
| 		// exit with inerr == nil | 		// exit with inerr == nil | ||||||
| 		_, inerr := io.Copy(os.Stdout, conn) | 		_, inerr := io.Copy(os.Stdout, conn) | ||||||
| 		if inerr != nil { | 		if inerr != nil { | ||||||
| 			_ = xs.Restore(int(os.Stdin.Fd()), oldState) // #nosec | 			restoreTermState(oldState) | ||||||
| 			// Copy operations and user logging off will cause | 			// Copy operations and user logging off will cause | ||||||
| 			// a "use of closed network connection" so handle that | 			// a "use of closed network connection" so handle that | ||||||
| 			// gracefully here | 			// gracefully here | ||||||
|  | @ -435,7 +435,7 @@ func doShellMode(isInteractive bool, conn *xsnet.Conn, oldState *xs.State, rec * | ||||||
| 
 | 
 | ||||||
| 		if isInteractive { | 		if isInteractive { | ||||||
| 			log.Println("[* Got EOF *]") | 			log.Println("[* Got EOF *]") | ||||||
| 			_ = xs.Restore(int(os.Stdin.Fd()), oldState) // #nosec | 			restoreTermState(oldState) | ||||||
| 			exitWithStatus(int(rec.Status())) | 			exitWithStatus(int(rec.Status())) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -463,7 +463,7 @@ func doShellMode(isInteractive bool, conn *xsnet.Conn, oldState *xs.State, rec * | ||||||
| 			if outerr != nil { | 			if outerr != nil { | ||||||
| 				log.Println(outerr) | 				log.Println(outerr) | ||||||
| 				fmt.Println(outerr) | 				fmt.Println(outerr) | ||||||
| 				_ = xs.Restore(int(os.Stdin.Fd()), oldState) // #nosec | 				restoreTermState(oldState) | ||||||
| 				log.Println("[Hanging up]") | 				log.Println("[Hanging up]") | ||||||
| 				exitWithStatus(0) | 				exitWithStatus(0) | ||||||
| 			} | 			} | ||||||
|  | @ -848,12 +848,17 @@ func main() { | ||||||
| 			} | 			} | ||||||
| 			// #gv:s/label=\"main\$1\"/label=\"deferRestore\"/ | 			// #gv:s/label=\"main\$1\"/label=\"deferRestore\"/ | ||||||
| 			// TODO:.gv:main:1:deferRestore | 			// TODO:.gv:main:1:deferRestore | ||||||
| 			defer func() { _ = xs.Restore(int(os.Stdin.Fd()), oldState) }() // nolint: errcheck,gosec | 			defer restoreTermState(oldState) | ||||||
| 		} else { | 		} else { | ||||||
| 			log.Println("NOT A TTY") | 			log.Println("NOT A TTY") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// Start login timeout here and disconnect if user/pass phase stalls | ||||||
|  | 	loginTimeout := time.AfterFunc(30*time.Second, func() { | ||||||
|  | 		fmt.Printf(" .. [login timeout]") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
| 	if len(authCookie) == 0 { | 	if len(authCookie) == 0 { | ||||||
| 		//No auth token, prompt for password | 		//No auth token, prompt for password | ||||||
| 		fmt.Printf("Gimme cookie:") | 		fmt.Printf("Gimme cookie:") | ||||||
|  | @ -864,6 +869,8 @@ func main() { | ||||||
| 		} | 		} | ||||||
| 		authCookie = string(ab) | 		authCookie = string(ab) | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	_ = loginTimeout.Stop() | ||||||
| 	// Security scrub | 	// Security scrub | ||||||
| 	runtime.GC() | 	runtime.GC() | ||||||
| 
 | 
 | ||||||
|  | @ -871,9 +878,9 @@ func main() { | ||||||
| 	rec := xs.NewSession(op, []byte(uname), []byte(remoteHost), []byte(os.Getenv("TERM")), []byte(cmdStr), []byte(authCookie), 0) | 	rec := xs.NewSession(op, []byte(uname), []byte(remoteHost), []byte(os.Getenv("TERM")), []byte(cmdStr), []byte(authCookie), 0) | ||||||
| 	sendErr := sendSessionParams(&conn, rec) | 	sendErr := sendSessionParams(&conn, rec) | ||||||
| 	if sendErr != nil { | 	if sendErr != nil { | ||||||
| 		_ = xs.Restore(int(os.Stdin.Fd()), oldState) // nolint: errcheck,gosec | 		restoreTermState(oldState) | ||||||
| 		rec.SetStatus(254) | 		rec.SetStatus(254) | ||||||
| 		fmt.Fprintln(os.Stderr, "Error: server rejected secure proposal params") // nolint: errcheck | 		fmt.Fprintln(os.Stderr, "Error: server rejected secure proposal params or login timed out") // nolint: errcheck | ||||||
| 		exitWithStatus(int(rec.Status())) | 		exitWithStatus(int(rec.Status())) | ||||||
| 		//log.Fatal(sendErr) | 		//log.Fatal(sendErr) | ||||||
| 	} | 	} | ||||||
|  | @ -930,19 +937,23 @@ func main() { | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if rec.Status() != 0 { | 		if rec.Status() != 0 { | ||||||
| 			_ = xs.Restore(int(os.Stdin.Fd()), oldState)                         // nolint: errcheck,gosec | 			restoreTermState(oldState) | ||||||
| 			fmt.Fprintln(os.Stderr, "Session exited with status:", rec.Status()) // nolint: errcheck | 			fmt.Fprintln(os.Stderr, "Session exited with status:", rec.Status()) // nolint: errcheck | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if oldState != nil { | 	if oldState != nil { | ||||||
| 		_ = xs.Restore(int(os.Stdin.Fd()), oldState) // nolint: gosec | 		restoreTermState(oldState) | ||||||
| 		oldState = nil | 		oldState = nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	exitWithStatus(int(rec.Status())) | 	exitWithStatus(int(rec.Status())) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func restoreTermState(oldState *xs.State) { | ||||||
|  | 	_ = xs.Restore(int(os.Stdin.Fd()), oldState) // nolint: errcheck,gosec | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // exitWithStatus wraps os.Exit() plus does any required pprof housekeeping | // exitWithStatus wraps os.Exit() plus does any required pprof housekeeping | ||||||
| func exitWithStatus(status int) { | func exitWithStatus(status int) { | ||||||
| 	if cpuprofile != "" { | 	if cpuprofile != "" { | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"syscall" | 	"syscall" | ||||||
|  | 	"time" | ||||||
| 	"unsafe" | 	"unsafe" | ||||||
| 
 | 
 | ||||||
| 	"blitter.com/go/goutmp" | 	"blitter.com/go/goutmp" | ||||||
|  | @ -640,6 +641,13 @@ func main() { | ||||||
| 			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 | ||||||
|  | 				loginTimeout := time.AfterFunc(30*time.Second, func() { | ||||||
|  | 					logger.LogNotice(fmt.Sprintln("Login timed out")) // nolint: errcheck,gosec | ||||||
|  | 					hc.Write([]byte{0})                               // nolint: gosec,errcheck | ||||||
|  | 					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 | ||||||
|  | @ -719,6 +727,7 @@ func main() { | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | 				_ = loginTimeout.Stop() | ||||||
| 				// Security scrub | 				// Security scrub | ||||||
| 				rec.ClearAuthCookie() | 				rec.ClearAuthCookie() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue