3 Commits

Author SHA1 Message Date
26c50085d6 new/pipeline (#6)
All checks were successful
code scans / scans (push) Successful in 1m27s
Reviewed-on: #6
Co-authored-by: jake <jake.young.dev@gmail.com>
Co-committed-by: jake <jake.young.dev@gmail.com>
2025-04-24 18:22:16 +00:00
13d3b2cef3 feature/view-all (#5)
Reviewed-on: #5
Co-authored-by: jake <jake.young.dev@gmail.com>
Co-committed-by: jake <jake.young.dev@gmail.com>
2025-04-20 05:28:56 +00:00
4100762986 Update README.md 2025-04-19 05:18:26 +00:00
9 changed files with 66 additions and 13 deletions

View File

@@ -0,0 +1,25 @@
name: "code scans"
on: [push, pull_request] #runs on pushes to any branch
jobs:
scans:
runs-on: smoke-test
steps:
- name: "clone code"
uses: actions/checkout@v4
- name: "install go"
uses: https://code.jakeyoungdev.com/actions/install-go@v0.1.3
with:
commands: |
golang.org/x/vuln/cmd/govulncheck@latest
- name: "dependency and stdlib scan"
uses: https://code.jakeyoungdev.com/actions/report-vulns@master
with:
manager: go
- name: "static code analysis"
uses: securego/gosec@master
with:
args: ./...

View File

@@ -1,5 +1,5 @@
# mctl
mctl is a terminal-friendly remote connection client
mctl is a terminal-friendly remote console client
## Installation
Install mctl using golang
@@ -43,6 +43,10 @@ Saved commands can be viewed with:
```bash
mctl view <name>
```
All saved commands can be viewed with:
```bash
mctl view all
```
### Running saved commands
Commands that have been saved can be run with:
@@ -93,7 +97,9 @@ mctl delete <name>
All configuration data will be kept in the home directory and any sensitive data is encrypted for added security
## Security
RCon is an inherently insecure protocol, passwords are sent in plaintext and, if possible, the port should not be exposed to the internet. It is best to keep these connections local or over a VPN
RCon is an inherently insecure protocol, passwords are sent in plaintext and, if possible, the port should not be exposed to the internet. It is best to keep these connections local or over a VPN.
mctl utilizes [govulncheck](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck) and [gosec](https://github.com/securego/gosec) in workflows to ensure quality, secure code is being pushed. These workflow steps must pass before a PR will be accepted
## Development
this repo is currently in heavy development and may encounter breaking changes, use a tag to prevent any surprises

View File

@@ -48,7 +48,8 @@ var configCmd = &cobra.Command{
viper.Set("server", cfgserver)
viper.Set("password", string(ciphert))
viper.Set("port", cfgport)
viper.WriteConfig()
err = viper.WriteConfig()
cobra.CheckErr(err)
fmt.Println()
fmt.Println("Config file updated!")
},
@@ -57,9 +58,11 @@ var configCmd = &cobra.Command{
func init() {
initConfig()
configCmd.Flags().StringVarP(&cfgserver, "server", "s", "", "server address")
configCmd.MarkFlagRequired("server")
err := configCmd.MarkFlagRequired("server")
cobra.CheckErr(err)
configCmd.Flags().IntVarP(&cfgport, "port", "p", 0, "server rcon port")
configCmd.MarkFlagRequired("port")
err = configCmd.MarkFlagRequired("port")
cobra.CheckErr(err)
rootCmd.AddCommand(configCmd)
}
@@ -72,7 +75,8 @@ func initConfig() {
viper.SetConfigType("yaml")
viper.SetConfigName(".mctl")
viper.AutomaticEnv()
viper.ReadInConfig()
err = viper.ReadInConfig()
cobra.CheckErr(err)
if err := viper.ReadInConfig(); err != nil {
//file does not exist, create it
@@ -92,6 +96,7 @@ func initConfig() {
//write config
viper.Set("customcmd", cmdMap)
viper.Set("device", string(uu))
viper.SafeWriteConfig()
err = viper.SafeWriteConfig()
cobra.CheckErr(err)
}
}

View File

@@ -21,7 +21,8 @@ var deleteCmd = &cobra.Command{
cmdMap := viper.Get("customcmd").(map[string]any)
delete(cmdMap, args[0])
viper.Set("customcmd", cmdMap)
viper.WriteConfig()
err := viper.WriteConfig()
cobra.CheckErr(err)
}
},
PreRunE: func(cmd *cobra.Command, args []string) error {

View File

@@ -14,7 +14,7 @@ var rootCmd = &cobra.Command{
Use: "mctl",
Short: "A remote console client",
Long: `mctl is a terminal-friendly remote console client made to manage game servers.`,
Version: "v0.3.3",
Version: "v0.3.4",
// Run: func(cmd *cobra.Command, args []string) { },
}

View File

@@ -36,7 +36,8 @@ var saveCmd = &cobra.Command{
}
cmdMap[args[0]] = txt
viper.Set("customcmd", cmdMap)
viper.WriteConfig()
err := viper.WriteConfig()
cobra.CheckErr(err)
fmt.Println("\nSaved!")
}
}

View File

@@ -6,6 +6,7 @@ package cmd
import (
"errors"
"fmt"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
@@ -16,7 +17,7 @@ var viewCmd = &cobra.Command{
Use: "view <name>",
Example: "mctl view test",
Short: "View saved commands",
Long: `Load command using the supplied name and displays it in the terminal`,
Long: `Load command using the supplied name and displays it in the terminal, 'all' will list every saved command`,
Run: func(cmd *cobra.Command, args []string) {
var cm map[string]any
cmdMap := viper.Get("customcmd")
@@ -26,6 +27,17 @@ var viewCmd = &cobra.Command{
}
cm = cmdMap.(map[string]any)
if strings.EqualFold(args[0], "all") {
//show all commands
fmt.Println("\nCommands: ")
for k, v := range cm {
fmt.Printf("%s - %s\n", k, v)
}
fmt.Println()
return
}
custom, ok := cm[args[0]]
if !ok {
fmt.Println("command not found")

View File

@@ -21,7 +21,10 @@ func EncryptPassword(b []byte) ([]byte, error) {
return nil, err
}
ct := aesg.Seal(nil, []byte(nonce), []byte(b), nil)
//adding #nosec trigger here since gosec interprets this as a hardcoded nonce value. The nonce is calculated using crypto/rand when the
//config command is ran and is pulled from memory when used any times after, for now we must prevent the scan from catching here until gosec
//is updated to account for this properly
ct := aesg.Seal(nil, []byte(nonce), []byte(b), nil) // #nosec
return ct, nil
}

2
go.mod
View File

@@ -1,6 +1,6 @@
module code.jakeyoungdev.com/jake/mctl
go 1.24.0
go 1.24.2
require (
github.com/jake-young-dev/mcr v1.3.1