mctl/cmd/config.go

96 lines
2.2 KiB
Go
Raw Normal View History

/*
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()
}
}