github.com/freiheit-com/kuberpult@v1.24.2-0.20240328135542-315d5630abe6/services/cd-service/pkg/repository/credentials.go (about) 1 /*This file is part of kuberpult. 2 3 Kuberpult is free software: you can redistribute it and/or modify 4 it under the terms of the Expat(MIT) License as published by 5 the Free Software Foundation. 6 7 Kuberpult is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 MIT License for more details. 11 12 You should have received a copy of the MIT License 13 along with kuberpult. If not, see <https://directory.fsf.org/wiki/License:Expat>. 14 15 Copyright 2023 freiheit.com*/ 16 17 package repository 18 19 import ( 20 "bytes" 21 "context" 22 "encoding/base64" 23 "fmt" 24 "io" 25 "os" 26 27 "github.com/freiheit-com/kuberpult/pkg/logger" 28 git "github.com/libgit2/git2go/v34" 29 "go.uber.org/zap" 30 "golang.org/x/crypto/ssh" 31 ) 32 33 type Credentials struct { 34 SshKey string 35 } 36 37 func base64encode(c []byte) string { 38 var buf bytes.Buffer 39 enc := base64.NewEncoder(base64.StdEncoding, &buf) 40 enc.Write(c) //nolint: errcheck 41 enc.Close() 42 return buf.String() 43 } 44 45 func (c *Credentials) load() (*credentialsStore, error) { 46 store := &credentialsStore{ 47 sshPrivateKey: "", 48 sshPublicKey: "", 49 } 50 if c.SshKey != "" { 51 pkey, err := os.Open(c.SshKey) 52 if err != nil { 53 return nil, err 54 } 55 defer pkey.Close() 56 privKeyContent, err := io.ReadAll(pkey) 57 if err != nil { 58 return nil, err 59 } 60 priv, err := ssh.ParsePrivateKey(privKeyContent) 61 if err != nil { 62 return nil, err 63 } 64 pubKeyContent := fmt.Sprintf("%s %s\n", priv.PublicKey().Type(), base64encode(priv.PublicKey().Marshal())) 65 store.sshPrivateKey = string(privKeyContent) 66 store.sshPublicKey = pubKeyContent 67 } 68 return store, nil 69 } 70 71 type credentialsStore struct { 72 sshPrivateKey string 73 sshPublicKey string 74 } 75 76 func (c *credentialsStore) CredentialsCallback(ctx context.Context) git.CredentialsCallback { 77 if c == nil { 78 return func(url string, username_from_url string, allowed_types git.CredentialType) (*git.Credential, error) { 79 return nil, nil 80 } 81 } 82 logger := logger.FromContext(ctx) 83 return func(url string, username_from_url string, allowed_types git.CredentialType) (*git.Credential, error) { 84 logger.Debug("git.credentialsCallback", 85 zap.String("url", url), 86 zap.String("username", username_from_url), 87 ) 88 if c.sshPrivateKey != "" && allowed_types|git.CredTypeSshKey != 0 { 89 return git.NewCredentialSSHKeyFromMemory(username_from_url, c.sshPublicKey, c.sshPrivateKey, "") 90 } 91 return nil, nil 92 } 93 }