-
Notifications
You must be signed in to change notification settings - Fork 32
/
list_auth_provider.go
115 lines (101 loc) · 2.81 KB
/
list_auth_provider.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package auth
import (
"context"
"github.com/fluxcd/go-git/v5/plumbing/transport/http"
"github.com/fluxcd/go-git/v5/plumbing/transport/ssh"
"github.com/kluctl/kluctl/v2/pkg/git/git-url"
"github.com/kluctl/kluctl/v2/pkg/git/messages"
ssh2 "golang.org/x/crypto/ssh"
"strings"
)
type ListAuthProvider struct {
MessageCallbacks messages.MessageCallbacks
entries []AuthEntry
}
type AuthEntry struct {
Host string
PathPrefix string
Username string
Password string
SshKey []byte
KnownHosts []byte
CABundle []byte
}
func (a *ListAuthProvider) AddEntry(e AuthEntry) {
a.entries = append(a.entries, e)
}
func (a *ListAuthProvider) BuildAuth(ctx context.Context, gitUrl git_url.GitUrl) AuthMethodAndCA {
a.MessageCallbacks.Trace("ListAuthProvider: BuildAuth for %s", gitUrl.String())
a.MessageCallbacks.Trace("ListAuthProvider: path=%s, username=%s, scheme=%s", gitUrl.Path, gitUrl.User.Username(), gitUrl.Scheme)
for _, e := range a.entries {
a.MessageCallbacks.Trace("ListAuthProvider: try host=%s, pathPrefix=%s, username=%s", e.Host, e.PathPrefix, e.Username)
if e.Host != "*" && e.Host != gitUrl.Hostname() {
continue
}
urlPath := gitUrl.Path
if strings.HasPrefix(urlPath, "/") {
urlPath = urlPath[1:]
}
if !strings.HasPrefix(urlPath, e.PathPrefix) {
continue
}
if e.Username == "" {
continue
}
username := ""
if gitUrl.User != nil {
username = gitUrl.User.Username()
}
if username != "" && e.Username != "*" && username != e.Username {
continue
}
if username == "" {
username = e.Username
}
if username == "*" {
// can't use "*" as username
continue
}
if gitUrl.IsSsh() {
if e.SshKey == nil {
a.MessageCallbacks.Trace("ListAuthProvider: empty ssh key is not accepted")
continue
}
a.MessageCallbacks.Trace("ListAuthProvider: using username+sshKey")
pk, err := ssh.NewPublicKeys(username, e.SshKey, "")
if err != nil {
a.MessageCallbacks.Trace("ListAuthProvider: failed to parse private key: %v", err)
} else {
hostKeyCallback := buildVerifyHostCallback(a.MessageCallbacks, e.KnownHosts)
return AuthMethodAndCA{
AuthMethod: pk,
Hash: func() ([]byte, error) {
return buildHash(pk.Signer)
},
ClientConfig: func() (*ssh2.ClientConfig, error) {
ccfg, err := pk.ClientConfig()
if err != nil {
return nil, err
}
ccfg.HostKeyCallback = hostKeyCallback
return ccfg, nil
},
}
}
} else {
if e.Password == "" {
a.MessageCallbacks.Trace("ListAuthProvider: empty password is not accepted")
continue
}
a.MessageCallbacks.Trace("ListAuthProvider: using username+password")
return AuthMethodAndCA{
AuthMethod: &http.BasicAuth{
Username: username,
Password: e.Password,
},
CABundle: e.CABundle,
}
}
}
return AuthMethodAndCA{}
}