grim/hgkeeper

Use Go 1.22 and update dependencies
default tip
2 months ago, aklitzing
f33f223bc8fe
Use Go 1.22 and update dependencies

Reviewed at https://reviews.imfreedom.org/r/2949/
package access
import (
"os"
"path/filepath"
"strings"
"sync"
"go.uber.org/zap"
"golang.org/x/crypto/ssh"
)
const (
keysDir = "keys"
)
var (
usernames map[string]string
keysLock sync.Mutex
)
func refreshKeys() error {
keysLock.Lock()
defer keysLock.Unlock()
usernames = map[string]string{}
keysPath := filepath.Join(AdminRepoPath(), keysDir)
if _, err := os.Stat(keysPath); err != nil {
if os.IsNotExist(err) {
zap.S().Error("keys directory not found, no one will be to access hgkeeper")
return nil
}
}
entries, err := os.ReadDir(keysPath)
if err != nil {
return err
}
for _, entry := range entries {
if entry.Type().IsRegular() {
filename := filepath.Join(keysPath, entry.Name())
loadSshKey(filename, entry.Name())
}
}
return nil
}
func loadSshKey(filename, username string) {
buffer, err := os.ReadFile(filename)
if err != nil {
zap.S().Warnf("failed to read keyfile for user %s: %v", username, err)
return
}
counter := 0
// iterate through the file reading one ssh public key at a time
for len(buffer) > 0 {
var pubkey ssh.PublicKey
pubkey, _, _, buffer, err = ssh.ParseAuthorizedKey(buffer)
if err != nil {
if !strings.HasSuffix(err.Error(), "ssh: no key found") {
zap.S().Warnf("failed to parse key file for user %s: %v", username, err)
}
continue
}
key := MarshalPublicKey(pubkey)
if duppedname, found := usernames[key]; found {
zap.S().Warnf(
"duplicate key found for user %s. existing key was for %s.",
username,
duppedname,
)
}
usernames[key] = username
counter++
}
zap.S().Infof("loaded %d keys for user %q", counter, username)
}
func MarshalPublicKey(pubkey ssh.PublicKey) string {
return strings.TrimSpace(string(ssh.MarshalAuthorizedKey(pubkey)))
}
func UsernameFromPubkey(pubkey string) string {
keysLock.Lock()
defer keysLock.Unlock()
username := usernames[pubkey]
if username == "" {
username = searchLdapPubkey(pubkey)
}
return username
}