ssh/terminal: adjust ReadConsole rules on windows

CL 212377 changed end of input character on windows - from \n to \r.
But CL 212377 did not adjust ReadConsole accordingly. For example,
after CL 212377 \n was still used to end of password processing,
and \r was ignored.

This CL swaps these rules - \r is now used to end password processing,
and \n are ignored. The change only affects windows, all non windows
code should work as before.

This CL also adjusts TestReadPasswordLineEnd to fit new rules.

Fixes golang/go#36609

Change-Id: I027bf80d10e7d4d4b17ff0264935d14b8bea9097
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/215417
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
diff --git a/terminal.go b/terminal.go
index dd7378c..d1b4fca 100644
--- a/terminal.go
+++ b/terminal.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"io"
+	"runtime"
 	"strconv"
 	"sync"
 	"unicode/utf8"
@@ -939,6 +940,8 @@
 // readPasswordLine reads from reader until it finds \n or io.EOF.
 // The slice returned does not include the \n.
 // readPasswordLine also ignores any \r it finds.
+// Windows uses \r as end of line. So, on Windows, readPasswordLine
+// reads until it finds \r and ignores any \n it finds during processing.
 func readPasswordLine(reader io.Reader) ([]byte, error) {
 	var buf [1]byte
 	var ret []byte
@@ -952,9 +955,15 @@
 					ret = ret[:len(ret)-1]
 				}
 			case '\n':
-				return ret, nil
+				if runtime.GOOS != "windows" {
+					return ret, nil
+				}
+				// otherwise ignore \n
 			case '\r':
-				// remove \r from passwords on Windows
+				if runtime.GOOS == "windows" {
+					return ret, nil
+				}
+				// otherwise ignore \r
 			default:
 				ret = append(ret, buf[0])
 			}
diff --git a/terminal_test.go b/terminal_test.go
index 4e7a0c6..2a2facc 100644
--- a/terminal_test.go
+++ b/terminal_test.go
@@ -323,18 +323,32 @@
 }
 
 func TestReadPasswordLineEnd(t *testing.T) {
-	var tests = []struct {
+	type testType struct {
 		input string
 		want  string
-	}{
-		{"\n", ""},
+	}
+	var tests = []testType{
 		{"\r\n", ""},
 		{"test\r\n", "test"},
+		{"test\r", "test"},
+		{"test\n", "test"},
 		{"testtesttesttes\n", "testtesttesttes"},
 		{"testtesttesttes\r\n", "testtesttesttes"},
 		{"testtesttesttesttest\n", "testtesttesttesttest"},
 		{"testtesttesttesttest\r\n", "testtesttesttesttest"},
+		{"\btest", "test"},
+		{"t\best", "est"},
+		{"te\bst", "tst"},
+		{"test\b", "tes"},
+		{"test\b\r\n", "tes"},
+		{"test\b\n", "tes"},
+		{"test\b\r", "tes"},
 	}
+	eol := "\n"
+	if runtime.GOOS == "windows" {
+		eol = "\r"
+	}
+	tests = append(tests, testType{eol, ""})
 	for _, test := range tests {
 		buf := new(bytes.Buffer)
 		if _, err := buf.WriteString(test.input); err != nil {