1
2
3
4
5 package auth
6
7 import (
8 "os"
9 "path/filepath"
10 "runtime"
11 "strings"
12 "sync"
13 )
14
15 type netrcLine struct {
16 machine string
17 login string
18 password string
19 }
20
21 var (
22 netrcOnce sync.Once
23 netrc []netrcLine
24 netrcErr error
25 )
26
27 func parseNetrc(data string) []netrcLine {
28
29
30 var nrc []netrcLine
31 var l netrcLine
32 inMacro := false
33 for _, line := range strings.Split(data, "\n") {
34 if inMacro {
35 if line == "" {
36 inMacro = false
37 }
38 continue
39 }
40
41 f := strings.Fields(line)
42 i := 0
43 for ; i < len(f)-1; i += 2 {
44
45
46
47
48
49 switch f[i] {
50 case "machine":
51 l = netrcLine{machine: f[i+1]}
52 case "default":
53 break
54 case "login":
55 l.login = f[i+1]
56 case "password":
57 l.password = f[i+1]
58 case "macdef":
59
60
61
62 inMacro = true
63 }
64 if l.machine != "" && l.login != "" && l.password != "" {
65 nrc = append(nrc, l)
66 l = netrcLine{}
67 }
68 }
69
70 if i < len(f) && f[i] == "default" {
71
72 break
73 }
74 }
75
76 return nrc
77 }
78
79 func netrcPath() (string, error) {
80 if env := os.Getenv("NETRC"); env != "" {
81 return env, nil
82 }
83 dir, err := os.UserHomeDir()
84 if err != nil {
85 return "", err
86 }
87 base := ".netrc"
88 if runtime.GOOS == "windows" {
89 base = "_netrc"
90 }
91 return filepath.Join(dir, base), nil
92 }
93
94 func readNetrc() {
95 path, err := netrcPath()
96 if err != nil {
97 netrcErr = err
98 return
99 }
100
101 data, err := os.ReadFile(path)
102 if err != nil {
103 if !os.IsNotExist(err) {
104 netrcErr = err
105 }
106 return
107 }
108
109 netrc = parseNetrc(string(data))
110 }
111
View as plain text