mirror of
https://github.com/golang/go
synced 2024-11-24 07:20:02 -07:00
cmd/go/internal/web2: make netrc parsing more robust
- Respect the NETRC environment variable if set. - Ignore lines that contain macro definitions. - Associate the 'machine' token with only the tokens that follow (not precede) it. Updates #29888 Updates #26232 Change-Id: I3128b7d6da2d6492df7c864e165eea1a27384f0f Reviewed-on: https://go-review.googlesource.com/c/go/+/161698 Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
This commit is contained in:
parent
131eb8fbf8
commit
2d68380713
@ -37,29 +37,61 @@ type netrcLine struct {
|
|||||||
password string
|
password string
|
||||||
}
|
}
|
||||||
|
|
||||||
var netrcOnce sync.Once
|
var (
|
||||||
var netrc []netrcLine
|
netrcOnce sync.Once
|
||||||
|
netrc []netrcLine
|
||||||
|
netrcErr error
|
||||||
|
)
|
||||||
|
|
||||||
func parseNetrc(data string) []netrcLine {
|
func parseNetrc(data string) []netrcLine {
|
||||||
|
// See https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html
|
||||||
|
// for documentation on the .netrc format.
|
||||||
var nrc []netrcLine
|
var nrc []netrcLine
|
||||||
var l netrcLine
|
var l netrcLine
|
||||||
|
inMacro := false
|
||||||
for _, line := range strings.Split(data, "\n") {
|
for _, line := range strings.Split(data, "\n") {
|
||||||
|
if inMacro {
|
||||||
|
if line == "" {
|
||||||
|
inMacro = false
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
f := strings.Fields(line)
|
f := strings.Fields(line)
|
||||||
for i := 0; i < len(f)-1; i += 2 {
|
i := 0
|
||||||
|
for ; i < len(f)-1; i += 2 {
|
||||||
|
// Reset at each "machine" token.
|
||||||
|
// “The auto-login process searches the .netrc file for a machine token
|
||||||
|
// that matches […]. Once a match is made, the subsequent .netrc tokens
|
||||||
|
// are processed, stopping when the end of file is reached or another
|
||||||
|
// machine or a default token is encountered.”
|
||||||
switch f[i] {
|
switch f[i] {
|
||||||
case "machine":
|
case "machine":
|
||||||
l.machine = f[i+1]
|
l = netrcLine{machine: f[i+1]}
|
||||||
|
case "default":
|
||||||
|
break
|
||||||
case "login":
|
case "login":
|
||||||
l.login = f[i+1]
|
l.login = f[i+1]
|
||||||
case "password":
|
case "password":
|
||||||
l.password = f[i+1]
|
l.password = f[i+1]
|
||||||
|
case "macdef":
|
||||||
|
// “A macro is defined with the specified name; its contents begin with
|
||||||
|
// the next .netrc line and continue until a null line (consecutive
|
||||||
|
// new-line characters) is encountered.”
|
||||||
|
inMacro = true
|
||||||
|
}
|
||||||
|
if l.machine != "" && l.login != "" && l.password != "" {
|
||||||
|
nrc = append(nrc, l)
|
||||||
|
l = netrcLine{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if l.machine != "" && l.login != "" && l.password != "" {
|
|
||||||
nrc = append(nrc, l)
|
if i < len(f) && f[i] == "default" {
|
||||||
l = netrcLine{}
|
// “There can be only one default token, and it must be after all machine tokens.”
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nrc
|
return nrc
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,22 +105,36 @@ func havePassword(machine string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func netrcPath() string {
|
func netrcPath() (string, error) {
|
||||||
switch runtime.GOOS {
|
if env := os.Getenv("NETRC"); env != "" {
|
||||||
case "windows":
|
return env, nil
|
||||||
return filepath.Join(os.Getenv("USERPROFILE"), "_netrc")
|
|
||||||
case "plan9":
|
|
||||||
return filepath.Join(os.Getenv("home"), ".netrc")
|
|
||||||
default:
|
|
||||||
return filepath.Join(os.Getenv("HOME"), ".netrc")
|
|
||||||
}
|
}
|
||||||
|
dir, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
base := ".netrc"
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
base = "_netrc"
|
||||||
|
}
|
||||||
|
return filepath.Join(dir, base), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readNetrc() {
|
func readNetrc() {
|
||||||
data, err := ioutil.ReadFile(netrcPath())
|
path, err := netrcPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
netrcErr = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
netrcErr = err
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
netrc = parseNetrc(string(data))
|
netrc = parseNetrc(string(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,16 +10,37 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var testNetrc = `
|
var testNetrc = `
|
||||||
|
machine incomplete
|
||||||
|
password none
|
||||||
|
|
||||||
machine api.github.com
|
machine api.github.com
|
||||||
login user
|
login user
|
||||||
password pwd
|
password pwd
|
||||||
|
|
||||||
machine incomlete.host
|
machine incomlete.host
|
||||||
login justlogin
|
login justlogin
|
||||||
|
|
||||||
machine test.host
|
machine test.host
|
||||||
login user2
|
login user2
|
||||||
password pwd2
|
password pwd2
|
||||||
|
|
||||||
|
machine oneline login user3 password pwd3
|
||||||
|
|
||||||
|
machine ignore.host macdef ignore
|
||||||
|
login nobody
|
||||||
|
password nothing
|
||||||
|
|
||||||
|
machine hasmacro.too macdef ignore-next-lines login user4 password pwd4
|
||||||
|
login nobody
|
||||||
|
password nothing
|
||||||
|
|
||||||
|
default
|
||||||
|
login anonymous
|
||||||
|
password gopher@golang.org
|
||||||
|
|
||||||
|
machine after.default
|
||||||
|
login oops
|
||||||
|
password too-late-in-file
|
||||||
`
|
`
|
||||||
|
|
||||||
func TestReadNetrc(t *testing.T) {
|
func TestReadNetrc(t *testing.T) {
|
||||||
@ -27,6 +48,8 @@ func TestReadNetrc(t *testing.T) {
|
|||||||
want := []netrcLine{
|
want := []netrcLine{
|
||||||
{"api.github.com", "user", "pwd"},
|
{"api.github.com", "user", "pwd"},
|
||||||
{"test.host", "user2", "pwd2"},
|
{"test.host", "user2", "pwd2"},
|
||||||
|
{"oneline", "user3", "pwd3"},
|
||||||
|
{"hasmacro.too", "user4", "pwd4"},
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(lines, want) {
|
if !reflect.DeepEqual(lines, want) {
|
||||||
|
Loading…
Reference in New Issue
Block a user