streamdeck-remote/ssh.go

100 lines
1.7 KiB
Go

package main
import (
"github.com/valyala/fastjson"
"golang.org/x/crypto/ssh"
"io/ioutil"
"meow.tf/streamdeck/sdk"
"os"
)
func sshActionHandler(action, context string, payload *fastjson.Value, deviceId string) {
settings := payload.Get("settings")
if settings == nil {
sdk.ShowAlert(context)
return
}
user := sdk.JsonStringValue(settings, "ssh_user")
host := sdk.JsonStringValue(settings, "ssh_host")
if host == "" {
sdk.ShowAlert(context)
return
}
command := sdk.JsonStringValue(settings, "ssh_command")
if command == "" {
sdk.ShowAlert(context)
return
}
config := &ssh.ClientConfig{
User: user,
}
if keyFile := sdk.JsonStringValue(settings, "ssh_key"); keyFile != "" {
s, err := loadPrivateKey(keyFile, sdk.JsonStringValue(settings, "ssh_key_passphrase"))
if err != nil {
sdk.ShowAlert(context)
return
}
config.Auth = []ssh.AuthMethod{
ssh.PublicKeys(s),
}
} else if password := sdk.JsonStringValue(settings, "ssh_password"); password != "" {
config.Auth = []ssh.AuthMethod{
ssh.Password(password),
}
}
client, err := ssh.Dial("tcp", host, config)
if err != nil {
sdk.ShowAlert(context)
return
}
session, err := client.NewSession()
if err != nil {
sdk.ShowAlert(context)
return
}
err = session.Run(command)
if err == nil {
sdk.ShowOk(context)
} else {
sdk.ShowAlert(context)
}
}
func loadPrivateKey(file, passphrase string) (ssh.Signer, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
b, err := ioutil.ReadAll(f)
if err != nil {
return nil, err
}
if passphrase != "" {
return ssh.ParsePrivateKeyWithPassphrase(b, []byte(passphrase))
}
return ssh.ParsePrivateKey(b)
}