8d0117399c
Bug: raw ed25519.PublicKey bytes were stored directly instead of OpenSSH authorized-key format (ssh-ed25519 AAAA... label). Fixes: - internal/sshmanager/fingerprint.go: GenerateKeyPair now uses ssh.NewPublicKey + ssh.MarshalAuthorizedKey - internal/sshmanager/keys.go: EnsureServerKey uses same fix; also regenerates .pub file from private key if stored value is corrupt - internal/sshmanager/fingerprint.go: add MarshalED25519PublicKey, PublicKeyFromPrivateKeyFile, RegeneratePublicKeyFromPrivateKeyFile - internal/models/sshkey.go: add UpdatePublicKey - internal/api/handlers_sshkeys.go: List+Get recover existing DB records with corrupt public keys by regenerating from private key file and updating the DB Also adds golang.org/x/crypto/ssh dependency via go mod tidy.
86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
package models
|
|
|
|
import (
|
|
"database/sql"
|
|
"time"
|
|
)
|
|
|
|
type SSHKey struct {
|
|
ID int64 `db:"id" json:"id"`
|
|
Label string `db:"label" json:"label"`
|
|
PrivateKeyPath string `db:"private_key_path" json:"-"`
|
|
PublicKey string `db:"public_key" json:"public_key"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
}
|
|
|
|
type SSHKeyRepository struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
func NewSSHKeyRepository(db *sql.DB) *SSHKeyRepository {
|
|
return &SSHKeyRepository{db: db}
|
|
}
|
|
|
|
func (r *SSHKeyRepository) Create(label, privPath, pubKey string) (int64, error) {
|
|
res, err := r.db.Exec(
|
|
"INSERT INTO ssh_keys (label, private_key_path, public_key) VALUES (?, ?, ?)",
|
|
label, privPath, pubKey,
|
|
)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return res.LastInsertId()
|
|
}
|
|
|
|
func (r *SSHKeyRepository) GetByID(id int64) (*SSHKey, error) {
|
|
var k SSHKey
|
|
err := r.db.QueryRow(
|
|
"SELECT id, label, private_key_path, public_key, created_at FROM ssh_keys WHERE id = ?",
|
|
id,
|
|
).Scan(&k.ID, &k.Label, &k.PrivateKeyPath, &k.PublicKey, &k.CreatedAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &k, nil
|
|
}
|
|
|
|
func (r *SSHKeyRepository) GetAll() ([]SSHKey, error) {
|
|
rows, err := r.db.Query(
|
|
"SELECT id, label, private_key_path, public_key, created_at FROM ssh_keys ORDER BY label")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var keys []SSHKey
|
|
for rows.Next() {
|
|
var k SSHKey
|
|
if err := rows.Scan(&k.ID, &k.Label, &k.PrivateKeyPath, &k.PublicKey, &k.CreatedAt); err != nil {
|
|
return nil, err
|
|
}
|
|
keys = append(keys, k)
|
|
}
|
|
return keys, rows.Err()
|
|
}
|
|
|
|
func (r *SSHKeyRepository) Delete(id int64) error {
|
|
_, err := r.db.Exec("DELETE FROM ssh_keys WHERE id = ?", id)
|
|
return err
|
|
}
|
|
|
|
func (r *SSHKeyRepository) UpdatePublicKey(id int64, pubKey string) error {
|
|
_, err := r.db.Exec("UPDATE ssh_keys SET public_key = ? WHERE id = ?", pubKey, id)
|
|
return err
|
|
}
|
|
|
|
func (r *SSHKeyRepository) GetServerKey() (*SSHKey, error) {
|
|
var k SSHKey
|
|
err := r.db.QueryRow(
|
|
"SELECT id, label, private_key_path, public_key, created_at FROM ssh_keys WHERE label = 'server' LIMIT 1",
|
|
).Scan(&k.ID, &k.Label, &k.PrivateKeyPath, &k.PublicKey, &k.CreatedAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &k, nil
|
|
}
|