Decrypt settings on start (#2)
This commit is contained in:
parent
d78809c9ee
commit
dfd3ae592b
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -33,22 +34,6 @@ type Settings struct {
|
||||||
const settingsName = "calanonsync.json"
|
const settingsName = "calanonsync.json"
|
||||||
const keyName = ".calanonsync.key"
|
const keyName = ".calanonsync.key"
|
||||||
|
|
||||||
func ensurePassword(password *string, name string) {
|
|
||||||
if *password != "" {
|
|
||||||
// Nothing to do. Password already set.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
print(name + " password: ")
|
|
||||||
b, err := terminal.ReadPassword(int(syscall.Stdin))
|
|
||||||
println()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
*password = string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadSettings() Settings {
|
func LoadSettings() Settings {
|
||||||
f, err := os.Open(settingsName)
|
f, err := os.Open(settingsName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -64,6 +49,55 @@ func LoadSettings() Settings {
|
||||||
settings.CalDAV.URL += "/"
|
settings.CalDAV.URL += "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load a key if possible.
|
||||||
|
var key []byte = nil
|
||||||
|
keyString, err := ioutil.ReadFile(keyName)
|
||||||
|
if err == nil {
|
||||||
|
key, err = base64.StdEncoding.DecodeString(string(keyString))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Could not load encryption key: %s\n", err)
|
||||||
|
}
|
||||||
|
} else if !os.IsNotExist(err) {
|
||||||
|
log.Fatalf("Could not load encryption key: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ensurePassword := func(password *string, name string) {
|
||||||
|
if *password == "" {
|
||||||
|
print(name + " password: ")
|
||||||
|
b, err := terminal.ReadPassword(int(syscall.Stdin))
|
||||||
|
println()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*password = string(b)
|
||||||
|
} else if key != nil {
|
||||||
|
// Password already set. Since we have an encryption key, try to
|
||||||
|
// decrypt the password.
|
||||||
|
pwbytes, err := base64.StdEncoding.DecodeString(*password)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Could not decode password: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Could not create cipher: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(pwbytes) < block.BlockSize() {
|
||||||
|
log.Fatalln("Could not decrypt password. Encrypted stream is too short.")
|
||||||
|
}
|
||||||
|
|
||||||
|
iv := pwbytes[:aes.BlockSize]
|
||||||
|
result := pwbytes[aes.BlockSize:]
|
||||||
|
|
||||||
|
stream := cipher.NewCFBDecrypter(block, iv)
|
||||||
|
stream.XORKeyStream(result, result)
|
||||||
|
|
||||||
|
*password = string(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ensurePassword(&settings.EWS.Password, "EWS")
|
ensurePassword(&settings.EWS.Password, "EWS")
|
||||||
ensurePassword(&settings.CalDAV.Password, "CalDAV")
|
ensurePassword(&settings.CalDAV.Password, "CalDAV")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue