package Encryption
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/aes"
|
|
"errors"
|
|
"os"
|
|
"os/exec"
|
|
"io/ioutil"
|
|
"io"
|
|
)
|
|
|
|
func EditEncryptedFile(password string, FilePath string) (error) {
|
|
var (
|
|
editor string
|
|
tmpFilePath string
|
|
ciphertext []byte
|
|
plaintext []byte
|
|
tmpFile *os.File
|
|
encryptedFile *os.File
|
|
cmd *exec.Cmd
|
|
e error
|
|
)
|
|
editor = os.Getenv("EDITOR")
|
|
if editor == "" {
|
|
return errors.New("EDITOR variable cannot be blank")
|
|
}
|
|
|
|
tmpFilePath = os.Getenv("TMPDIR")
|
|
if tmpFilePath == "" {
|
|
tmpFilePath = "/tmp"
|
|
}
|
|
|
|
ciphertext, e = ioutil.ReadFile(FilePath)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
if len(ciphertext) < aes.BlockSize {
|
|
return errors.New("ciphertext too short")
|
|
}
|
|
|
|
plaintext, e = DecryptData(password, ciphertext)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
|
|
tmpFile, e = ioutil.TempFile(tmpFilePath, "")
|
|
if e != nil {
|
|
return e
|
|
}
|
|
_, e = io.Copy(tmpFile, bytes.NewReader(plaintext))
|
|
if e != nil {
|
|
return e
|
|
}
|
|
|
|
e = tmpFile.Close()
|
|
if e != nil {
|
|
return e
|
|
}
|
|
|
|
cmd = exec.Command(editor, tmpFile.Name())
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stdin = os.Stdin
|
|
cmd.Stderr = os.Stderr
|
|
e = cmd.Run()
|
|
if (e != nil) {
|
|
return e
|
|
}
|
|
|
|
plaintext, e = ioutil.ReadFile(tmpFile.Name())
|
|
if e != nil {
|
|
return e
|
|
}
|
|
|
|
ciphertext, e = EncryptData(password, plaintext)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
// open output file
|
|
encryptedFile, e = os.OpenFile(FilePath, os.O_RDWR, 0666)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
|
|
defer func() {
|
|
encryptedFile.Close()
|
|
SecureDelete(tmpFile.Name())
|
|
}()
|
|
|
|
_, e = io.Copy(encryptedFile, bytes.NewReader(ciphertext))
|
|
if e != nil {
|
|
return e
|
|
}
|
|
|
|
return nil
|
|
}
|