starting ssh client

This commit is contained in:
Kristian 2023-08-21 04:10:25 +02:00
parent 314a403ed9
commit 488f733ab1
9 changed files with 258 additions and 12 deletions

View File

@ -1,3 +1,4 @@
export BOT_TOKEN=
export CRYPTO_TOKEN=
export OPENAI_TOKEN=
export OPENAI_TOKEN=
export ADMIN_DISCORD_ID=

4
.gitignore vendored
View File

@ -1,2 +1,4 @@
.env
pb_data
pb_data
*.pem
*.pub

View File

@ -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

View File

@ -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
View 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
}

View File

@ -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()
}

View File

@ -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)

Binary file not shown.

Binary file not shown.