/* Copyright © 2025 Jake jake.young.dev@gmail.com */ package cmd import ( "crypto/aes" "crypto/cipher" "crypto/rand" "fmt" "io" "os" "github.com/google/uuid" "github.com/spf13/cobra" "github.com/spf13/viper" "golang.org/x/term" ) var ( server string port int ) // configCmd represents the config command var configCmd = &cobra.Command{ Use: "config", Short: "Create and populate config file", Long: `Creates the .mctl file in the user home directory populating it with the server address, rcon password, and rcon port to be pulled when using Login command`, Run: func(cmd *cobra.Command, args []string) { //read in password using term to keep it secure/hidden from bash history fmt.Printf("Password: ") ps, err := term.ReadPassword(int(os.Stdin.Fd())) cobra.CheckErr(err) //setup aes encrypter block, err := aes.NewCipher([]byte(viper.Get("device").(string))) cobra.CheckErr(err) //generate and apply random nonce nonce := make([]byte, 12) _, err = io.ReadFull(rand.Reader, nonce) cobra.CheckErr(err) aesg, err := cipher.NewGCM(block) cobra.CheckErr(err) //encrypt rcon password ciphert := aesg.Seal(nil, nonce, ps, nil) //update config file with new values viper.Set("server", server) viper.Set("password", string(ciphert)) viper.Set("port", port) viper.Set("nonce", string(nonce)) viper.WriteConfig() fmt.Println() fmt.Println("Config file updated!") }, } func init() { initConfig() configCmd.Flags().StringVarP(&server, "server", "s", "", "server address") configCmd.MarkFlagRequired("server") configCmd.Flags().IntVarP(&port, "port", "p", 0, "server rcon port") configCmd.MarkFlagRequired("port") rootCmd.AddCommand(configCmd) } func initConfig() { home, err := os.UserHomeDir() cobra.CheckErr(err) viper.AddConfigPath(home) viper.SetConfigType("yaml") viper.SetConfigName(".mctl") viper.AutomaticEnv() viper.ReadInConfig() if err := viper.ReadInConfig(); err != nil { //file does not exist, create it viper.Set("server", server) viper.Set("password", "") viper.Set("port", port) viper.Set("nonce", "") //generate a uuid to be used as encryption key uu := uuid.New() viper.Set("device", uu.String()) viper.SafeWriteConfig() } }