Core infrastructure: - Uber fx dependency injection - Chi router with middleware stack - SQLite database with embedded migrations - Embedded templates and static assets - Structured logging with slog Features implemented: - Authentication (login, logout, session management, argon2id hashing) - App management (create, edit, delete, list) - Deployment pipeline (clone, build, deploy, health check) - Webhook processing for Gitea - Notifications (ntfy, Slack) - Environment variables, labels, volumes per app - SSH key generation for deploy keys Server startup: - Server.Run() starts HTTP server on configured port - Server.Shutdown() for graceful shutdown - SetupRoutes() wires all handlers with chi router
54 lines
1.3 KiB
Go
54 lines
1.3 KiB
Go
// Package ssh provides SSH key generation utilities.
|
|
package ssh
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"crypto/rand"
|
|
"encoding/pem"
|
|
"fmt"
|
|
|
|
"golang.org/x/crypto/ssh"
|
|
)
|
|
|
|
// KeyPair contains an SSH key pair.
|
|
type KeyPair struct {
|
|
PrivateKey string
|
|
PublicKey string
|
|
}
|
|
|
|
// GenerateKeyPair generates a new Ed25519 SSH key pair.
|
|
func GenerateKeyPair() (*KeyPair, error) {
|
|
// Generate Ed25519 key pair
|
|
publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to generate key pair: %w", err)
|
|
}
|
|
|
|
// Convert private key to PEM format
|
|
privateKeyPEM, err := ssh.MarshalPrivateKey(privateKey, "")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to marshal private key: %w", err)
|
|
}
|
|
|
|
// Convert public key to authorized_keys format
|
|
sshPublicKey, err := ssh.NewPublicKey(publicKey)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create SSH public key: %w", err)
|
|
}
|
|
|
|
return &KeyPair{
|
|
PrivateKey: string(pem.EncodeToMemory(privateKeyPEM)),
|
|
PublicKey: string(ssh.MarshalAuthorizedKey(sshPublicKey)),
|
|
}, nil
|
|
}
|
|
|
|
// ValidatePrivateKey validates that a private key is valid.
|
|
func ValidatePrivateKey(privateKeyPEM string) error {
|
|
_, err := ssh.ParsePrivateKey([]byte(privateKeyPEM))
|
|
if err != nil {
|
|
return fmt.Errorf("invalid private key: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|