|
|
|
|
@@ -12,9 +12,11 @@ import (
|
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"strings"
|
|
|
|
|
"syscall"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
"golang.org/x/term"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
@@ -173,27 +175,17 @@ func rotateCmd() *cobra.Command {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func adminInitCmd() *cobra.Command {
|
|
|
|
|
var keyPath string
|
|
|
|
|
cmd := &cobra.Command{
|
|
|
|
|
return &cobra.Command{
|
|
|
|
|
Use: "admin init",
|
|
|
|
|
Short: "Initialize pass_mgr with admin key",
|
|
|
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
|
|
|
// Require --key-path parameter
|
|
|
|
|
if keyPath == "" {
|
|
|
|
|
fmt.Fprintln(os.Stderr, "Error: --key-path is required")
|
|
|
|
|
fmt.Fprintln(os.Stderr, "Usage: pass_mgr admin init --key-path <path-to-key-file>")
|
|
|
|
|
fmt.Fprintln(os.Stderr, "The key file must contain a password with at least 6 characters")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
if err := initAdmin(keyPath); err != nil {
|
|
|
|
|
if err := initAdminInteractive(); err != nil {
|
|
|
|
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("pass_mgr initialized successfully")
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
cmd.Flags().StringVar(&keyPath, "key-path", "", "Path to admin key file (required, password must be >= 6 chars)")
|
|
|
|
|
return cmd
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func setCmd() *cobra.Command {
|
|
|
|
|
@@ -256,7 +248,42 @@ func loadAdminKey() ([]byte, error) {
|
|
|
|
|
return hash[:], nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func initAdmin(keyPath string) error {
|
|
|
|
|
func initAdminInteractive() error {
|
|
|
|
|
fmt.Print("Enter admin password: ")
|
|
|
|
|
password1, err := term.ReadPassword(int(syscall.Stdin))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to read password: %w", err)
|
|
|
|
|
}
|
|
|
|
|
fmt.Println()
|
|
|
|
|
|
|
|
|
|
// Trim whitespace/newlines
|
|
|
|
|
password1 = []byte(strings.TrimSpace(string(password1)))
|
|
|
|
|
|
|
|
|
|
// Validate password length
|
|
|
|
|
if len(password1) < 6 {
|
|
|
|
|
return fmt.Errorf("password must be at least 6 characters long (got %d)", len(password1))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Print("Confirm admin password: ")
|
|
|
|
|
password2, err := term.ReadPassword(int(syscall.Stdin))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to read password confirmation: %w", err)
|
|
|
|
|
}
|
|
|
|
|
fmt.Println()
|
|
|
|
|
|
|
|
|
|
// Trim whitespace/newlines
|
|
|
|
|
password2 = []byte(strings.TrimSpace(string(password2)))
|
|
|
|
|
|
|
|
|
|
// Check passwords match
|
|
|
|
|
if string(password1) != string(password2) {
|
|
|
|
|
return fmt.Errorf("passwords do not match")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Save the key
|
|
|
|
|
return saveAdminKey(password1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func saveAdminKey(key []byte) error {
|
|
|
|
|
homeDir := getHomeDir()
|
|
|
|
|
adminDir := filepath.Join(homeDir, AdminKeyDir)
|
|
|
|
|
|
|
|
|
|
@@ -265,17 +292,6 @@ func initAdmin(keyPath string) error {
|
|
|
|
|
return fmt.Errorf("failed to create admin directory: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read provided key
|
|
|
|
|
key, err := os.ReadFile(keyPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to read key file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate password length (must be >= 6 characters)
|
|
|
|
|
if len(key) < 6 {
|
|
|
|
|
return fmt.Errorf("password must be at least 6 characters long (got %d)", len(key))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Save key
|
|
|
|
|
keyFile := filepath.Join(adminDir, AdminKeyFile)
|
|
|
|
|
if err := os.WriteFile(keyFile, key, 0600); err != nil {
|
|
|
|
|
@@ -296,6 +312,21 @@ func initAdmin(keyPath string) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func initAdmin(keyPath string) error {
|
|
|
|
|
// Read provided key
|
|
|
|
|
key, err := os.ReadFile(keyPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to read key file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate password length (must be >= 6 characters)
|
|
|
|
|
if len(key) < 6 {
|
|
|
|
|
return fmt.Errorf("password must be at least 6 characters long (got %d)", len(key))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return saveAdminKey(key)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getSecretsDir() string {
|
|
|
|
|
if workspaceDir != "" && agentID != "" {
|
|
|
|
|
return filepath.Join(workspaceDir, SecretsDirName, agentID)
|
|
|
|
|
|