func (c *client) loadState(stateFile *disk.StateFile, pw string) error { parsedState, err := stateFile.Read(pw) if err != nil { return err } return c.unmarshal(parsedState) }
// importTombFile decrypts a file with the given path, using a hex-encoded key // and loads the client state from the result. func (c *client) importTombFile(stateFile *disk.StateFile, keyHex, path string) error { keyBytes, err := hex.DecodeString(keyHex) if err != nil { return err } var key [32]byte var nonce [24]byte if len(keyBytes) != len(key) { return fmt.Errorf("Incorrect key length: %d (want %d)", len(keyBytes), len(key)) } copy(key[:], keyBytes) tombBytes, err := ioutil.ReadFile(path) if err != nil { return err } plaintext, ok := secretbox.Open(nil, tombBytes, &nonce, &key) if !ok { return errors.New("Incorrect key") } c.stateLock, err = stateFile.Lock(true /* create */) if c.stateLock == nil && err == nil { return errors.New("Output statefile is locked.") } if err != nil { return err } writerChan := make(chan disk.NewState) writerDone := make(chan struct{}) go stateFile.StartWriter(writerChan, writerDone) writerChan <- disk.NewState{State: plaintext} close(writerChan) <-writerDone return nil }
func (c *cliClient) createErasureStorage(pw string, stateFile *disk.StateFile) error { c.Printf("%s %s\n", termInfoPrefix, tpmIntroMsg) present := tpm.Present() if !present { c.Printf("%s %s\n", termErrPrefix, tpmNotPresentMsg) } else { c.Printf("%s %s\n", termInfoPrefix, tpmPresentMsg) } ConfigureLoop: for present { c.term.SetPrompt("Try to configure TPM (y/n)> ") PromptLoop: for { line, err := c.term.ReadLine() if err != nil { return err } switch line { case "y", "yes", "Yes": break PromptLoop case "n", "no", "No": break ConfigureLoop } } tpm := disk.TPM{ Log: func(format string, args ...interface{}) { msg := fmt.Sprintf(format, args...) c.Printf("%s\n", terminalEscape(msg, false)) }, Rand: c.rand, } stateFile.Erasure = &tpm if err := stateFile.Create(pw); err != nil { c.Printf("%s Setup failed with error: %s\n", termErrPrefix, terminalEscape(err.Error(), false)) } else { c.Printf("%s TPM in use for this statefile\n", termInfoPrefix) return nil } } c.Printf("%s TPM will not be used for this statefile\n", termErrPrefix) stateFile.Erasure = nil return stateFile.Create(pw) }
func (c *guiClient) createErasureStorage(pw string, stateFile *disk.StateFile) error { var tpmInfo string present := tpm.Present() if present { tpmInfo = tpmPresentMsg } else { tpmInfo = tpmNotPresentMsg } ui := VBox{ widgetBase: widgetBase{padding: 40, expand: true, fill: true, name: "vbox"}, children: []Widget{ Label{ widgetBase: widgetBase{font: "DejaVu Sans 30"}, text: "Configure TPM", }, Label{ widgetBase: widgetBase{ padding: 20, font: "DejaVu Sans 14", }, text: tpmIntroMsg + "\n\n" + tpmInfo, wrap: 600, }, HBox{ children: []Widget{ Button{ widgetBase: widgetBase{ name: "tpm", insensitive: !present, }, text: "Try to configure TPM", }, }, }, TextView{ widgetBase: widgetBase{name: "log", expand: true, fill: true}, editable: false, }, Button{ widgetBase: widgetBase{name: "continue"}, text: "Continue without TPM", }, }, } c.gui.Actions() <- SetBoxContents{name: "body", child: ui} c.gui.Actions() <- SetFocus{name: "tpm"} c.gui.Actions() <- UIState{uiStateErasureStorage} c.gui.Signal() var logText string tpm := disk.TPM{ Log: func(format string, args ...interface{}) { c.log.Printf(format, args...) logText += fmt.Sprintf(format, args...) + "\n" c.gui.Actions() <- SetTextView{name: "log", text: logText} c.gui.Signal() }, Rand: c.rand, } NextEvent: for { event, ok := <-c.gui.Events() if !ok { c.ShutdownAndSuspend() } click, ok := event.(Click) if !ok { continue } switch click.name { case "continue": stateFile.Erasure = nil return stateFile.Create(pw) case "tpm": if len(logText) > 0 { c.gui.Actions() <- SetTextView{name: "log", text: ""} c.gui.Signal() logText = "" time.Sleep(300 * time.Millisecond) } stateFile.Erasure = &tpm c.gui.Actions() <- Sensitive{name: "tpm", sensitive: false} c.gui.Actions() <- Sensitive{name: "continue", sensitive: false} c.gui.Signal() if err := stateFile.Create(pw); err != nil { tpm.Log("Setup failed with error: %s", err) tpm.Log("You can click the button to try again") c.gui.Actions() <- Sensitive{name: "tpm", sensitive: true} c.gui.Actions() <- Sensitive{name: "continue", sensitive: true} c.gui.Signal() continue NextEvent } return nil } } panic("unreachable") }
func (c *client) createErasureStorage(pw string, stateFile *disk.StateFile) error { // No NVRAM support on OpenBSD yet. return stateFile.Create(pw) }
func (c *cliClient) createErasureStorage(pw string, stateFile *disk.StateFile) error { c.Printf("%s %s\n", termErrPrefix, "Erasure storage not yet implemented.") stateFile.Erasure = nil return stateFile.Create(pw) }
func (c *guiClient) createErasureStorage(pw string, stateFile *disk.StateFile) error { var tpmInfo string present := tpm.Present() if present { tpmInfo = "Your computer appears to have a TPM chip. Click below to try and use it. You'll need tcsd (the TPM daemon) running." } else { tpmInfo = "Your computer does not appear to have a TPM chip. Without one, it's possible that someone in physical possession of your computer and passphrase could extract old messages that should have been deleted. Using a computer with a TPM is strongly preferable until alternatives can be implemented." } ui := VBox{ widgetBase: widgetBase{padding: 40, expand: true, fill: true, name: "vbox"}, children: []Widget{ Label{ widgetBase: widgetBase{font: "DejaVu Sans 30"}, text: "Configure TPM", }, Label{ widgetBase: widgetBase{ padding: 20, font: "DejaVu Sans 14", }, text: "It's very difficult to erase information on modern computers so Pond tries to use the TPM chip if possible.\n\n" + tpmInfo, wrap: 600, }, HBox{ children: []Widget{ Button{ widgetBase: widgetBase{ name: "tpm", insensitive: !present, }, text: "Try to configure TPM", }, }, }, TextView{ widgetBase: widgetBase{name: "log", expand: true, fill: true}, editable: false, }, Button{ widgetBase: widgetBase{name: "continue"}, text: "Continue without TPM", }, }, } c.gui.Actions() <- SetBoxContents{name: "body", child: ui} c.gui.Actions() <- SetFocus{name: "tpm"} c.gui.Actions() <- UIState{uiStateErasureStorage} c.gui.Signal() var logText string tpm := disk.TPM{ Log: func(format string, args ...interface{}) { c.log.Printf(format, args...) logText += fmt.Sprintf(format, args...) + "\n" c.gui.Actions() <- SetTextView{name: "log", text: logText} c.gui.Signal() }, Rand: c.rand, } NextEvent: for { event, ok := <-c.gui.Events() if !ok { c.ShutdownAndSuspend() } click, ok := event.(Click) if !ok { continue } switch click.name { case "continue": stateFile.Erasure = nil return stateFile.Create(pw) case "tpm": if len(logText) > 0 { c.gui.Actions() <- SetTextView{name: "log", text: ""} c.gui.Signal() logText = "" time.Sleep(300 * time.Millisecond) } stateFile.Erasure = &tpm c.gui.Actions() <- Sensitive{name: "tpm", sensitive: false} c.gui.Actions() <- Sensitive{name: "continue", sensitive: false} c.gui.Signal() if err := stateFile.Create(pw); err != nil { tpm.Log("Setup failed with error: %s", err) tpm.Log("You can click the button to try again") c.gui.Actions() <- Sensitive{name: "tpm", sensitive: true} c.gui.Actions() <- Sensitive{name: "continue", sensitive: true} c.gui.Signal() continue NextEvent } return nil } } panic("unreachable") }
func (c *client) createErasureStorage(pw string, stateFile *disk.StateFile) error { return stateFile.Create(pw) }