package sshserver import ( "crypto/md5" "fmt" "strings" "golang.org/x/crypto/ssh" "github.com/forgeo/forgebucket/internal/models" ) // lookupKey is the SSH PublicKeyCallback. It computes the MD5 fingerprint of // the presented key (matching the format stored by the SSH key registration // handler) and looks it up in the database. func (s *Server) lookupKey(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { fp := fingerprintMD5(key) var sshKey models.SSHKey if found, _ := s.db.Where("fingerprint = ?", fp).Get(&sshKey); !found { return nil, fmt.Errorf("unknown key") } // Resolve the username so the session handler can use it for permission checks. var user models.User if found, _ := s.db.ID(sshKey.UserID).Get(&user); !found { return nil, fmt.Errorf("user not found") } return &ssh.Permissions{ Extensions: map[string]string{ "username": user.Username, "user_id": fmt.Sprintf("%d", user.ID), }, }, nil } func fingerprintMD5(pub ssh.PublicKey) string { hash := md5.Sum(pub.Marshal()) parts := make([]string, len(hash)) for i, b := range hash { parts[i] = fmt.Sprintf("%02x", b) } return strings.Join(parts, ":") }