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>
This commit is contained in:
Alex Brainman
2020-01-19 09:47:15 +11:00
parent 31072773c2
commit 1a268e5305
2 changed files with 28 additions and 5 deletions

View File

@@ -7,6 +7,7 @@ package terminal
import (
"bytes"
"io"
"runtime"
"strconv"
"sync"
"unicode/utf8"
@@ -939,6 +940,8 @@ func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
// 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 @@ func readPasswordLine(reader io.Reader) ([]byte, error) {
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])
}

View File

@@ -323,18 +323,32 @@ func TestTerminalSetSize(t *testing.T) {
}
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 {