mctl/cmd/config.go
jake 2dc4807908
All checks were successful
code scans / scans (push) Successful in 1m2s
gosec fixes and nosec adds
2025-04-24 13:43:55 -04:00

103 lines
2.5 KiB
Go

/*
Copyright © 2025 Jake jake.young.dev@gmail.com
*/
package cmd
import (
"crypto/rand"
"fmt"
"io"
"os"
"code.jakeyoungdev.com/jake/mctl/cryptography"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"golang.org/x/term"
)
var (
cfgserver string
cfgport int
)
// configCmd represents the config command
var configCmd = &cobra.Command{
Use: "config",
Example: "mctl config -s x.x.x.x -p 61695",
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)
//generate and apply random nonce
nonce := make([]byte, 12)
_, err = io.ReadFull(rand.Reader, nonce)
cobra.CheckErr(err)
viper.Set("nonce", string(nonce))
//encrypt password
ciphert, err := cryptography.EncryptPassword(ps)
cobra.CheckErr(err)
//update config file with new values
viper.Set("server", cfgserver)
viper.Set("password", string(ciphert))
viper.Set("port", cfgport)
err = viper.WriteConfig()
cobra.CheckErr(err)
fmt.Println()
fmt.Println("Config file updated!")
},
}
func init() {
initConfig()
configCmd.Flags().StringVarP(&cfgserver, "server", "s", "", "server address")
err := configCmd.MarkFlagRequired("server")
cobra.CheckErr(err)
configCmd.Flags().IntVarP(&cfgport, "port", "p", 0, "server rcon port")
err = configCmd.MarkFlagRequired("port")
cobra.CheckErr(err)
rootCmd.AddCommand(configCmd)
}
// init config sets viper config and checks for config file, creating it if it doesn't exist
func initConfig() {
home, err := os.UserHomeDir()
cobra.CheckErr(err)
viper.AddConfigPath(home)
viper.SetConfigType("yaml")
viper.SetConfigName(".mctl")
viper.AutomaticEnv()
err = viper.ReadInConfig()
cobra.CheckErr(err)
if err := viper.ReadInConfig(); err != nil {
//file does not exist, create it
viper.Set("server", cfgserver)
viper.Set("password", "")
viper.Set("port", cfgport)
viper.Set("nonce", "")
//generate psuedo-random key
uu := make([]byte, 32)
_, err := rand.Read(uu)
cobra.CheckErr(err)
//create custom command map
cmdMap := make(map[string]any, 0)
//write config
viper.Set("customcmd", cmdMap)
viper.Set("device", string(uu))
err = viper.SafeWriteConfig()
cobra.CheckErr(err)
}
}