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