Skip to content

Commit

Permalink
Rewrite encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
Biptaste committed Jun 1, 2022
1 parent 2914167 commit 51eb537
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 68 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
vendor
build
build

# OS
.DS_Store
81 changes: 44 additions & 37 deletions actions/backup.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package actions

import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path"
"path/filepath"
"strings"
Expand Down Expand Up @@ -97,13 +94,54 @@ func BackupActionHandler(ctx domain.ExecutionContext, backupFilesOpt *bool, back
}

for _, file := range config.Get().BackupConfig.Files {
err := filepath.Walk(file, walkFunc)
fmt.Println(file)
fileInfo, err := os.Stat(file)
if err != nil {
return fmt.Errorf("WARN: Unable to walk into %s\n%s\n", file, err)
return fmt.Errorf("%s file or directory not found \n%s\n", file, err)
}
if !fileInfo.IsDir() {
return fmt.Errorf("%s is not a directory \n", file)
}

err = filepath.Walk(file, walkFunc)
if err != nil {
return fmt.Errorf("Unable to walk into %s\n%s\n", file, err)
}
}
}

tmpArchiveFilename := path.Join(backupDir, "backup_archive.tar.gz")

tar := new(archivex.TarFile)
tar.Create(tmpArchiveFilename)
tar.AddAll(path.Join(backupDir, "backup"), false)
tar.Close()

if key != nil && *key != "" {
tmpEncryptedFilename := path.Join(backupDir, "backup_archive.tar.gz.enc")
infile, err := os.Open(tmpArchiveFilename)
if err != nil {
return fmt.Errorf("Unable to open the archive: %s\n", err)
}

outfile, err := os.OpenFile(tmpEncryptedFilename, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return fmt.Errorf("Unable to create the encrypted file: %s\n", err)
}

aesKey := []byte(*key)
hmacKey := aesKey
err = utils.Encrypt(infile, outfile, aesKey, hmacKey)
if err != nil {
return fmt.Errorf("Unable to encrypt file: %s\n", err)
}
infile.Close()
outfile.Close()

tmpArchiveFilename = tmpEncryptedFilename
}

// save the archive with the right name
archiveFilename := ""
if outputOpt != nil && *outputOpt != "" {
archiveFilename = *outputOpt
Expand All @@ -118,38 +156,7 @@ func BackupActionHandler(ctx domain.ExecutionContext, backupFilesOpt *bool, back
archiveFilename = fmt.Sprintf("backup-%d%02d%02d_%02d%02d%02d.tar.gz%s", year, month, day, hour, minutes, seconds, encryptedExtension)
}

wd, err := os.Getwd()
if err != nil {
log.Println(err)
return nil
}
archiveFilename = path.Join(wd, archiveFilename)

// encrypt tar gz
if key != nil && *key != "" {
command := fmt.Sprintf("cd %s; tar -czf - * | openssl enc -aes-256-cbc -salt -k %s -out %s", path.Join(backupDir, "backup"), *key, archiveFilename)
cmd := exec.Command("bash", "-c", command)

var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
return fmt.Errorf(fmt.Sprint(err) + ": " + stderr.String())
}

fmt.Printf("\n %s Done\n", color.GreenString("✓"))
return nil
}

tar := new(archivex.TarFile)
tar.Create(path.Join(backupDir, "backup_archive.tar.gz"))
tar.AddAll(path.Join(backupDir, "backup"), false)
tar.Close()

// save the archive with the right name
err = os.Rename(path.Join(backupDir, "backup_archive.tar.gz"), archiveFilename)
err = os.Rename(tmpArchiveFilename, archiveFilename)
if err != nil {
return fmt.Errorf("Unable to create the backup file: %s\n", err)
}
Expand Down
69 changes: 40 additions & 29 deletions actions/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package actions

import (
"archive/tar"
"bytes"
"compress/gzip"
"fmt"
"io"
"log"
"os"
"os/exec"
"path"
"path/filepath"
"strings"

Expand Down Expand Up @@ -58,16 +58,23 @@ func RestoreActionHandler(ctx domain.ExecutionContext, file string, restoreConfi

fmt.Printf("\n\n")

encryptedExtension := file[len(file)-4:]
dpath, dfile := path.Split(file)
fmt.Println("%s --- %s", dpath, dfile)
encryptedExtension := dfile[len(dfile)-4:]
isEncrypted := encryptedExtension == ".enc" && key != nil || *key != ""
encryptedFile := file
// decrypt in an hidden file
decryptedFile := dpath + "." + dfile[:len(dfile)-4]
fmt.Println(encryptedFile, decryptedFile, *key)

if isEncrypted {
var err error
file, err = decrypt(file, key)
err := decrypt(encryptedFile, decryptedFile, key)
if err != nil {
fmt.Println(err)
return
}

file = decryptedFile
}

err := untar(ctx, file, configFilesRestoration, filesRestoration, dbRestoration)
Expand All @@ -78,7 +85,7 @@ func RestoreActionHandler(ctx domain.ExecutionContext, file string, restoreConfi

// remove decrypted file
if isEncrypted {
err = os.Remove(file)
err = os.Remove(decryptedFile)
if err != nil {
fmt.Println(err)
return
Expand All @@ -88,34 +95,29 @@ func RestoreActionHandler(ctx domain.ExecutionContext, file string, restoreConfi
fmt.Printf("\n %s Done\n", color.GreenString("✓"))
}

func decrypt(file string, key *string) (string, error) {
encryptedExtension := file[len(file)-4:]

if encryptedExtension != ".enc" || key == nil || *key == "" {
return file, nil
func decrypt(encryptedFile string, decryptedFile string, key *string) error {
infile, err := os.Open(encryptedFile)
if err != nil {
log.Fatal(err)
}

// decrypt in an hidden file
outputFile := "." + file[:len(file)-4]
command := fmt.Sprintf("openssl enc -d -aes-256-cbc -salt -k %s -in %s -out %s", *key, file, outputFile)
cmd := exec.Command("bash", "-c", command)

var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
outfile, err := os.OpenFile(decryptedFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
removeErr := os.Remove(outputFile)
if removeErr != nil {
fmt.Println(removeErr)
}
log.Fatal(err)
}

return "", fmt.Errorf(fmt.Sprint(err) + ": " + stderr.String())
aesKey := []byte(*key)
hmacKey := aesKey
err = utils.Decrypt(infile, outfile, aesKey, hmacKey)
infile.Close()
outfile.Close()

if err != nil {
removeDecryptedFile(decryptedFile)
return fmt.Errorf("Unable to decrypt the file %s\n%s\n", decryptedFile, err)
}
fmt.Printf("\n %s %s decrypted\n", color.GreenString("✓"), file)
fmt.Printf("\n %s %s decrypted\n", color.GreenString("✓"), encryptedFile)

return outputFile, nil
return nil
}

func untar(ctx domain.ExecutionContext, tarball string, configFilesRestoration bool, filesRestoration bool, dbRestoration bool) error {
Expand Down Expand Up @@ -293,3 +295,12 @@ func restorePostgres(ctx domain.ExecutionContext, containerID string, dumpFilena
cmd := domain.NewCommand([]string{"docker", "exec", "-i", "-e", fmt.Sprintf("PGPASSWORD=\"%s\"", password), containerID, "pg_restore", fmt.Sprintf("--username=%s", user), "-d", database, "-c"})
cmd.ExecuteWithStdin(postgresDumpReader)
}

func removeDecryptedFile(file string) {
if _, err := os.Stat(file); err == nil {
removeErr := os.Remove(file)
if removeErr != nil {
fmt.Println(removeErr)
}
}
}
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ func main() {
backupDB := cmd.BoolOpt("db", false, "Indicates if DB will be backup")

outputFilename := cmd.StringOpt("o output", "", "Set the filename of the tar.gz")
key := cmd.StringOpt("k", "", "the encryption password")
key := cmd.StringOpt("k", "", "the encryption password (32 characters for a key of 256 bits)")

cmd.Action = func() {
if *quiet == false {
Expand Down
Loading

0 comments on commit 51eb537

Please sign in to comment.