starting ssh client
This commit is contained in:
parent
314a403ed9
commit
488f733ab1
@ -1,3 +1,4 @@
|
||||
export BOT_TOKEN=
|
||||
export CRYPTO_TOKEN=
|
||||
export OPENAI_TOKEN=
|
||||
export OPENAI_TOKEN=
|
||||
export ADMIN_DISCORD_ID=
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,2 +1,4 @@
|
||||
.env
|
||||
pb_data
|
||||
pb_data
|
||||
*.pem
|
||||
*.pub
|
||||
68
bot/bot.go
68
bot/bot.go
@ -1,6 +1,7 @@
|
||||
package bot
|
||||
|
||||
import (
|
||||
"bitbot/pb"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
@ -11,9 +12,10 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
BotToken string
|
||||
OpenAIToken string
|
||||
CryptoToken string
|
||||
BotToken string
|
||||
OpenAIToken string
|
||||
CryptoToken string
|
||||
AllowedUserID string
|
||||
)
|
||||
|
||||
func Run() {
|
||||
@ -26,7 +28,7 @@ func Run() {
|
||||
|
||||
discord.Open()
|
||||
defer discord.Close()
|
||||
|
||||
pb.Run()
|
||||
log.Info("BitBot is running...")
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
@ -56,11 +58,63 @@ func newMessage(discord *discordgo.Session, message *discordgo.MessageCreate) {
|
||||
|
||||
conversationHistory = append(conversationHistory, userMessage)
|
||||
|
||||
if strings.Contains(message.Content, "!bit") || isPrivateChannel {
|
||||
chatGPT(discord, message.ChannelID, message.Content, conversationHistory)
|
||||
} else if strings.Contains(message.Content, "!cry") {
|
||||
if strings.Contains(message.Content, "!cry") {
|
||||
currentCryptoPrice := getCurrentCryptoPrice(message.Content)
|
||||
discord.ChannelMessageSendComplex(message.ChannelID, currentCryptoPrice)
|
||||
} else if strings.Contains(message.Content, "!bit") || isPrivateChannel {
|
||||
chatGPT(discord, message.ChannelID, message.Content, conversationHistory)
|
||||
} else if strings.Contains(message.Content, "!genkey") {
|
||||
if message.Author.ID == AllowedUserID {
|
||||
err := GenerateAndSaveSSHKeyPairIfNotExist()
|
||||
if err != nil {
|
||||
discord.ChannelMessageSend(message.ChannelID, "Error generating or saving key pair.")
|
||||
return
|
||||
}
|
||||
discord.ChannelMessageSend(message.ChannelID, "SSH key pair generated and saved successfully!")
|
||||
} else {
|
||||
discord.ChannelMessageSend(message.ChannelID, "You are not authorized to use this command.")
|
||||
}
|
||||
} else if strings.Contains(message.Content, "!showkey") {
|
||||
if message.Author.ID == AllowedUserID {
|
||||
publicKey, err := GetPublicKey()
|
||||
if err != nil {
|
||||
discord.ChannelMessageSend(message.ChannelID, "Error fetching public key.")
|
||||
return
|
||||
}
|
||||
discord.ChannelMessageSend(message.ChannelID, publicKey)
|
||||
} else {
|
||||
discord.ChannelMessageSend(message.ChannelID, "You are not authorized to use this command.")
|
||||
}
|
||||
} else if strings.Contains(message.Content, "!regenkey") {
|
||||
if message.Author.ID == AllowedUserID {
|
||||
err := GenerateAndSaveSSHKeyPair()
|
||||
if err != nil {
|
||||
discord.ChannelMessageSend(message.ChannelID, "Error regenerating and saving key pair.")
|
||||
return
|
||||
}
|
||||
discord.ChannelMessageSend(message.ChannelID, "SSH key pair regenerated and saved successfully!")
|
||||
} else {
|
||||
discord.ChannelMessageSend(message.ChannelID, "You are not authorized to use this command.")
|
||||
}
|
||||
} else if strings.Contains(message.Content, "!ssh") {
|
||||
if message.Author.ID == AllowedUserID {
|
||||
commandParts := strings.Fields(message.Content)
|
||||
if len(commandParts) != 2 {
|
||||
discord.ChannelMessageSend(message.ChannelID, "Invalid command format. Use !ssh username@remote-host:port")
|
||||
return
|
||||
}
|
||||
|
||||
connectionDetails := commandParts[1]
|
||||
err := SSHConnectToRemoteServer(connectionDetails)
|
||||
if err != nil {
|
||||
discord.ChannelMessageSend(message.ChannelID, "Error connecting to remote server.")
|
||||
return
|
||||
}
|
||||
|
||||
discord.ChannelMessageSend(message.ChannelID, "Connected to remote server!")
|
||||
} else {
|
||||
discord.ChannelMessageSend(message.ChannelID, "You are not authorized to use this command.")
|
||||
}
|
||||
}
|
||||
|
||||
conversationHistoryMap[userID] = conversationHistory
|
||||
|
||||
@ -3,7 +3,7 @@ package bot
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@ -41,7 +41,7 @@ func getCurrentCryptoPrice(message string) *discordgo.MessageSend {
|
||||
}
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(response.Body)
|
||||
body, _ := io.ReadAll(response.Body)
|
||||
defer response.Body.Close()
|
||||
|
||||
var data CryptoData
|
||||
|
||||
185
bot/sshclient.go
Normal file
185
bot/sshclient.go
Normal file
@ -0,0 +1,185 @@
|
||||
package bot
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
const (
|
||||
privateKeyPath = "private_key.pem"
|
||||
publicKeyPath = "public_key.pub"
|
||||
bits = 2048
|
||||
)
|
||||
|
||||
func GenerateAndSaveSSHKeyPairIfNotExist() error {
|
||||
if KeyFilesExist(privateKeyPath, publicKeyPath) {
|
||||
return nil
|
||||
}
|
||||
|
||||
privateKey, publicKey, err := GenerateSSHKeyPair(bits)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = SavePrivateKeyToFile(privateKeyPath, privateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = SavePublicKeyToFile(publicKeyPath, publicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GenerateAndSaveSSHKeyPair() error {
|
||||
privateKey, publicKey, err := GenerateSSHKeyPair(bits)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = SavePrivateKeyToFile(privateKeyPath, privateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = SavePublicKeyToFile(publicKeyPath, publicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func KeyFilesExist(privateKeyPath, publicKeyPath string) bool {
|
||||
_, privateKeyErr := os.Stat(privateKeyPath)
|
||||
_, publicKeyErr := os.Stat(publicKeyPath)
|
||||
return !os.IsNotExist(privateKeyErr) && !os.IsNotExist(publicKeyErr)
|
||||
}
|
||||
|
||||
func GenerateSSHKeyPair(bits int) (*rsa.PrivateKey, ssh.PublicKey, error) {
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return privateKey, publicKey, nil
|
||||
}
|
||||
|
||||
func SavePrivateKeyToFile(filename string, privateKey *rsa.PrivateKey) error {
|
||||
privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey)
|
||||
privateKeyPEM := &pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: privateKeyBytes,
|
||||
}
|
||||
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
err = pem.Encode(file, privateKeyPEM)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SavePublicKeyToFile(filename string, publicKey ssh.PublicKey) error {
|
||||
publicKeyBytes := ssh.MarshalAuthorizedKey(publicKey)
|
||||
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.WriteString(string(publicKeyBytes))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SSHConnectToRemoteServer(connectionDetails string) error {
|
||||
privateKey, err := LoadPrivateKey(privateKeyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config := &ssh.ClientConfig{
|
||||
User: "username", // You will replace this with the actual username extracted from connectionDetails
|
||||
Auth: []ssh.AuthMethod{
|
||||
ssh.PublicKeys(privateKey),
|
||||
},
|
||||
// Other configuration options like HostKeyCallback, etc.
|
||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
||||
}
|
||||
|
||||
// Extract username, host, and port from connectionDetails
|
||||
parts := strings.Split(connectionDetails, "@")
|
||||
if len(parts) != 2 {
|
||||
return errors.New("invalid connection format")
|
||||
}
|
||||
username := parts[0]
|
||||
hostPort := parts[1]
|
||||
|
||||
config.User = username // Set the actual username
|
||||
|
||||
// Connect to the remote server
|
||||
client, err := ssh.Dial("tcp", hostPort, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// Now you have a connected SSH client to the remote server.
|
||||
// You can use this client to perform remote commands or file transfers.
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func LoadPrivateKey(path string) (ssh.Signer, error) {
|
||||
keyBytes, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
privateKeyBlock, _ := pem.Decode(keyBytes)
|
||||
if privateKeyBlock == nil || privateKeyBlock.Type != "RSA PRIVATE KEY" {
|
||||
return nil, errors.New("failed to decode valid private key")
|
||||
}
|
||||
|
||||
privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ssh.NewSignerFromKey(privateKey)
|
||||
}
|
||||
|
||||
func GetPublicKey() (string, error) {
|
||||
publicKeyBytes, err := os.ReadFile(publicKeyPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(publicKeyBytes), nil
|
||||
}
|
||||
5
main.go
5
main.go
@ -28,10 +28,15 @@ func main() {
|
||||
if !ok {
|
||||
log.Fatal("Must set OpenAI token as env variable: OPENAI_TOKEN")
|
||||
}
|
||||
AllowedUserID, ok := os.LookupEnv("ADMIN_DISCORD_ID")
|
||||
if !ok {
|
||||
log.Fatal("Must set OpenAI token as env variable: ADMIN_DISCORD_ID")
|
||||
}
|
||||
|
||||
bot.BotToken = botToken
|
||||
bot.CryptoToken = cryptoToken
|
||||
bot.OpenAIToken = openAIToken
|
||||
bot.AllowedUserID = AllowedUserID
|
||||
|
||||
bot.Run()
|
||||
}
|
||||
|
||||
1
pb/pb.go
1
pb/pb.go
@ -8,7 +8,6 @@ import (
|
||||
func Run() {
|
||||
app := pocketbase.New()
|
||||
|
||||
// Start the PocketBase server in a goroutine.
|
||||
func() {
|
||||
if err := app.Start(); err != nil {
|
||||
log.Fatal(err)
|
||||
|
||||
BIN
pb_data/data.db
BIN
pb_data/data.db
Binary file not shown.
BIN
pb_data/logs.db
BIN
pb_data/logs.db
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user