...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package main
16
17 import (
18 "fmt"
19 "log"
20 "net/http"
21 "net/url"
22 "os"
23 "strings"
24 )
25
26 func main() {
27 if len(os.Args) < 2 {
28 fmt.Fprintf(os.Stderr, "usage: %s NETRCFILE [URL]", os.Args[0])
29 os.Exit(2)
30 }
31
32 log.SetPrefix("netrcauth: ")
33
34 if len(os.Args) != 2 {
35
36
37
38 return
39 }
40
41 path := os.Args[1]
42
43 data, err := os.ReadFile(path)
44 if err != nil {
45 if os.IsNotExist(err) {
46 return
47 }
48 log.Fatalf("failed to read %s: %v\n", path, err)
49 }
50
51 u := &url.URL{Scheme: "https"}
52 lines := parseNetrc(string(data))
53 for _, l := range lines {
54 u.Host = l.machine
55 fmt.Printf("%s\n\n", u)
56
57 req := &http.Request{Header: make(http.Header)}
58 req.SetBasicAuth(l.login, l.password)
59 req.Header.Write(os.Stdout)
60 fmt.Println()
61 }
62 }
63
64
65
66
67 type netrcLine struct {
68 machine string
69 login string
70 password string
71 }
72
73 func parseNetrc(data string) []netrcLine {
74
75
76 var nrc []netrcLine
77 var l netrcLine
78 inMacro := false
79 for _, line := range strings.Split(data, "\n") {
80 if inMacro {
81 if line == "" {
82 inMacro = false
83 }
84 continue
85 }
86
87 f := strings.Fields(line)
88 i := 0
89 for ; i < len(f)-1; i += 2 {
90
91
92
93
94
95 switch f[i] {
96 case "machine":
97 l = netrcLine{machine: f[i+1]}
98 case "default":
99 break
100 case "login":
101 l.login = f[i+1]
102 case "password":
103 l.password = f[i+1]
104 case "macdef":
105
106
107
108 inMacro = true
109 }
110 if l.machine != "" && l.login != "" && l.password != "" {
111 nrc = append(nrc, l)
112 l = netrcLine{}
113 }
114 }
115
116 if i < len(f) && f[i] == "default" {
117
118 break
119 }
120 }
121
122 return nrc
123 }
124
View as plain text