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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user