赞
踩
实现一个在配置文件设置信息,一运行就可以自动执行设定指令的软件。
这次实现的是 :
1. 加密解密模块, 用于加密密码, 在配置时配置已加密的密码就可以;
2. 需要配置,自然也就有配置文件的序列化反序列化;
3. 这么多操作如果都放到一个文件执行就需要命令行指令知道当前该执行的动作, 所以还有个命令行交互
运行环境: Windows, 基于Golang, 暂时没有使用什么不可跨平台接口, 理论上支持Linux/MacOS
目标终端:树莓派DebianOS(主要做用它测试)
package utils import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/base64" "io" ) type Encryption struct { Key []byte } func NewEncryption(key string) *Encryption { return &Encryption{Key: []byte(key)} } func (e *Encryption) Encrypt(text string) (string, error) { block, err := aes.NewCipher(e.Key) if err != nil { return "", err } textBytes := []byte(text) // 对于CBC模式,需要使用PKCS#7填充plaintext到blocksize的整数倍 textBytes = e.pad(textBytes, aes.BlockSize) ciphertext := make([]byte, aes.BlockSize+len(textBytes)) iv := ciphertext[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } mode := cipher.NewCBCEncrypter(block, iv) mode.CryptBlocks(ciphertext[aes.BlockSize:], textBytes) return base64.StdEncoding.EncodeToString(ciphertext), nil } func (e *Encryption) Decrypt(text string) (string, error) { data, err := base64.StdEncoding.DecodeString(text) if err != nil { return "", err } block, err := aes.NewCipher(e.Key) if err != nil { return "", err } if len(data) < aes.BlockSize { return "", err } iv := data[:aes.BlockSize] data = data[aes.BlockSize:] mode := cipher.NewCBCDecrypter(block, iv) mode.CryptBlocks(data, data) data = e.unpad(data, aes.BlockSize) return string(data), nil } // pad 使用PKCS#7标准填充数据 func (e *Encryption) pad(buf []byte, blockSize int) []byte { padding := blockSize - (len(buf) % blockSize) padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(buf, padtext...) } // unpad 移除PKCS#7标准填充的数据 func (e *Encryption) unpad(buf []byte, blockSize int) []byte { if len(buf)%blockSize != 0 { return nil } padding := int(buf[len(buf)-1]) return buf[:len(buf)-padding] }
isettings.go
package utils import ( "errors" ) type SettingsType int const ( SETTINGS_JSON SettingsType = 0 ) type ISettings interface { FromBytes(src []byte) error ToBytes() ([]byte, error) FromFile(filepath string) error ToFile(filepath string) error Data() interface{} } func NewSettings(typ SettingsType, model interface{}) (ISettings, error) { if nil == model { return nil, errors.New("model == nil") } switch typ { case SETTINGS_JSON: return NewJsonSettings(model) default: return nil, errors.New("wrong setting type") } }
jsonsettings.go
package utils import ( "encoding/json" "os" ) type JsonSettings struct { dat interface{} } func NewJsonSettings(v interface{}) (ISettings, error) { cfg := &JsonSettings{dat: v} return cfg, nil } func (c *JsonSettings) FromBytes(src []byte) error { return json.Unmarshal(src, c.dat) } func (c *JsonSettings) ToBytes() ([]byte, error) { return json.MarshalIndent(c.dat, "", " ") } func (c *JsonSettings) FromFile(filepath string) error { bs, err := os.ReadFile(filepath) if nil != err { return err } err = c.FromBytes(bs) return err } func (c *JsonSettings) ToFile(filepath string) error { bs, err := c.ToBytes() if nil != err { return err } err = os.WriteFile(filepath, bs, 0666) return err } func (c *JsonSettings) Data() interface{} { return c.dat }
package cmd import ( "github.com/spf13/cobra" "os" ) var rootCommand = rootCmd() /* 所有指令初始化 */ func init() { rootCommand.AddCommand(runCmd()) rootCommand.AddCommand(versionCmd()) rootCommand.AddCommand(initCmd()) rootCommand.AddCommand(encryptCmd()) } func rootCmd() *cobra.Command { var cmd = &cobra.Command{ Use: "ssh_remote_access", Short: "SSH Remote Access Tool", Long: "SSH Remote Access Tool, get help from https://listentome.blog.csdn.net/", Run: rootRun, } cmd.Flags().BoolP("run", "r", false, "run job list") cmd.Flags().BoolP("init", "i", false, "initialize the tool") cmd.Flags().BoolP("version", "v", false, "get version") cmd.Flags().StringP("encrypt", "e", "", "encrypt the string") return cmd } func rootRun(cmd *cobra.Command, args []string) { var cmdStrings = []string{"run", "init", "version", "encrypt"} var matchCmd string for _, v := range cmdStrings { var flag = cmd.Flag(v) if flag != nil && flag.Changed { matchCmd = v break } } if matchCmd == "" { matchCmd = "help" cmd.Help() return } for _, v := range cmd.Commands() { if v.Name() == matchCmd { v.Run(cmd, args) return } } } func Execute() error { rootCommand.SetArgs(os.Args[1:]) return rootCommand.Execute() }
https://gitee.com/grayhsu/ssh_remote_access
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。