forked from aksdb/CalAnonSync
Decrypt settings on start (#2)
This commit is contained in:
parent
d78809c9ee
commit
dfd3ae592b
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -33,22 +34,6 @@ type Settings struct {
|
|||
const settingsName = "calanonsync.json"
|
||||
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 {
|
||||
f, err := os.Open(settingsName)
|
||||
if err != nil {
|
||||
|
@ -64,6 +49,55 @@ func LoadSettings() Settings {
|
|||
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.CalDAV.Password, "CalDAV")
|
||||
|
||||
|
|
Loading…
Reference in New Issue