@@ -177,6 +177,9 @@ func OpenSSHPort(
177177 reg * DeviceRegistration ,
178178 port int32 ,
179179) error {
180+ if port < 1 || port > 65535 {
181+ return fmt .Errorf ("invalid SSH port %d: port must be between 1 and 65535" , port )
182+ }
180183 client := nodeClients .NewNodeClient (tokenProvider , config .GlobalConfig .GetBrevPublicAPIURL ())
181184 _ , err := client .OpenPort (ctx , connect .NewRequest (& nodev1.OpenPortRequest {
182185 ExternalNodeId : reg .ExternalNodeID ,
@@ -275,30 +278,34 @@ func SetTestSSHPort(port int32) { testSSHPort = &port }
275278func ClearTestSSHPort () { testSSHPort = nil }
276279
277280// PromptSSHPort prompts the user for the target SSH port, defaulting to 22 if
278- // they press Enter or leave it empty. Returns an error for invalid port numbers.
279- // Uses a single print + stdin read to avoid promptui rendering the label twice .
281+ // they press Enter or leave it empty. Re-prompts on invalid input until a valid
282+ // port is provided. Only returns an error for unrecoverable I/O failures .
280283func PromptSSHPort (t * terminal.Terminal ) (int32 , error ) {
281284 if testSSHPort != nil {
282285 return * testSSHPort , nil
283286 }
284- t .Vprintf (" %s " , t .Green ("SSH port (default 22):" ))
285287 reader := bufio .NewReader (os .Stdin )
286- line , err := reader .ReadString ('\n' )
287- if err != nil {
288- return 0 , fmt .Errorf ("reading input: %w" , err )
289- }
290- portStr := strings .TrimSpace (line )
291- if portStr == "" {
292- return defaultSSHPort , nil
293- }
294- n , err := strconv .ParseUint (portStr , 10 , 16 )
295- if err != nil {
296- return 0 , fmt .Errorf ("invalid port %q: %w" , portStr , err )
297- }
298- if n < 1 || n > 65535 {
299- return 0 , fmt .Errorf ("port must be between 1 and 65535, got %d" , n )
288+ for {
289+ t .Vprintf (" %s " , t .Green ("SSH port (default 22):" ))
290+ line , err := reader .ReadString ('\n' )
291+ if err != nil {
292+ return 0 , fmt .Errorf ("reading input: %w" , err )
293+ }
294+ portStr := strings .TrimSpace (line )
295+ if portStr == "" {
296+ return defaultSSHPort , nil
297+ }
298+ n , err := strconv .ParseUint (portStr , 10 , 16 )
299+ if err != nil {
300+ t .Vprintf (" %s\n " , t .Yellow (fmt .Sprintf ("Invalid port %q: port must be a number between 1 and 65535" , portStr )))
301+ continue
302+ }
303+ if n < 1 || n > 65535 { // explicit gate even though ParseUint will already fail values out of range
304+ t .Vprintf (" %s\n " , t .Yellow (fmt .Sprintf ("Invalid port %q: port must be between 1 and 65535" , portStr )))
305+ continue
306+ }
307+ return int32 (n ), nil
300308 }
301- return int32 (n ), nil
302309}
303310
304311// InstallAuthorizedKey appends the given public key to the user's
0 commit comments