Merge pull request 'changePassword' (#414) from changePassword into master
Reviewed-on: #414 Reviewed-by: Dan Ballard <dan@openprivacy.ca>
This commit is contained in:
commit
c035ab52bc
|
@ -36,7 +36,6 @@ type Application interface {
|
|||
CreateTaggedPeer(name string, password string, tag string)
|
||||
DeletePeer(onion string, currentPassword string)
|
||||
AddPeerPlugin(onion string, pluginID plugins.PluginID)
|
||||
ChangePeerPassword(onion, oldpass, newpass string)
|
||||
LaunchPeers()
|
||||
|
||||
GetPrimaryBus() event.Manager
|
||||
|
@ -122,10 +121,6 @@ func (app *application) DeletePeer(onion string, password string) {
|
|||
app.appBus.Publish(event.NewEventList(event.AppError, event.Error, event.PasswordMatchError, event.Identity, onion))
|
||||
}
|
||||
|
||||
func (app *application) ChangePeerPassword(onion, oldpass, newpass string) {
|
||||
app.eventBuses[onion].Publish(event.NewEventList(event.ChangePassword, event.Password, oldpass, event.NewPassword, newpass))
|
||||
}
|
||||
|
||||
func (app *application) AddPeerPlugin(onion string, pluginID plugins.PluginID) {
|
||||
app.AddPlugin(onion, pluginID, app.eventBuses[onion], app.acn)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package constants
|
||||
|
||||
// InvalidPasswordError is returned when an incorrect password is provided to a function that requires the current active password
|
||||
const InvalidPasswordError = "invalid_password_error"
|
||||
|
||||
// PasswordsDoNotMatchError is returned when two passwords do not match
|
||||
const PasswordsDoNotMatchError = "passwords_do_not_match"
|
|
@ -13,6 +13,8 @@ import (
|
|||
"git.openprivacy.ca/openprivacy/connectivity"
|
||||
"git.openprivacy.ca/openprivacy/connectivity/tor"
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"io/ioutil"
|
||||
path "path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -80,6 +82,33 @@ func (cp *cwtchPeer) CheckPassword(password string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (cp *cwtchPeer) ChangePassword(password string, newpassword string, newpasswordAgain string) error {
|
||||
cp.mutex.Lock()
|
||||
defer cp.mutex.Unlock()
|
||||
db, err := openEncryptedDatabase(cp.storage.ProfileDirectory, password, false)
|
||||
if db == nil || err != nil {
|
||||
return errors.New(constants.InvalidPasswordError)
|
||||
}
|
||||
cps, err := NewCwtchProfileStorage(db, cp.storage.ProfileDirectory)
|
||||
if err != nil {
|
||||
return errors.New(constants.InvalidPasswordError)
|
||||
}
|
||||
cps.Close()
|
||||
|
||||
salt, err := ioutil.ReadFile(path.Join(cp.storage.ProfileDirectory, saltFile))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// probably redundant but we like api safety
|
||||
if newpassword == newpasswordAgain {
|
||||
rekey := createKey(newpassword, salt)
|
||||
log.Infof("rekeying database...")
|
||||
return cp.storage.Rekey(rekey)
|
||||
}
|
||||
return errors.New(constants.PasswordsDoNotMatchError)
|
||||
}
|
||||
|
||||
// GenerateProtocolEngine
|
||||
// Status: New in 1.5
|
||||
func (cp *cwtchPeer) GenerateProtocolEngine(acn connectivity.ACN, bus event.Manager) (connections.Engine, error) {
|
||||
|
@ -1147,7 +1176,6 @@ func (cp *cwtchPeer) eventHandler() {
|
|||
cp.mutex.Lock()
|
||||
cp.state[ev.Data[event.GroupServer]] = connections.ConnectionStateToType()[ev.Data[event.ConnectionState]]
|
||||
cp.mutex.Unlock()
|
||||
|
||||
default:
|
||||
if ev.EventType != "" {
|
||||
log.Errorf("peer event handler received an event it was not subscribed for: %v", ev.EventType)
|
||||
|
|
|
@ -762,3 +762,12 @@ func (cps *CwtchProfileStorage) Delete() {
|
|||
log.Errorf("error deleting profile directory", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Rekey re-encrypts the datastore with the new key.
|
||||
// **note* this is technically a very dangerous API and should only be called after
|
||||
// checks on the current password and the derived new password.
|
||||
func (cps *CwtchProfileStorage) Rekey(newkey [32]byte) error {
|
||||
// PRAGMA queries don't allow subs...
|
||||
_, err := cps.db.Exec(fmt.Sprintf(`PRAGMA rekey="x'%x'";`, newkey))
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -114,5 +114,6 @@ type CwtchPeer interface {
|
|||
|
||||
ShareFile(fileKey string, serializedManifest string)
|
||||
CheckPassword(password string) bool
|
||||
ChangePassword(oldpassword string, newpassword string, newpasswordAgain string) error
|
||||
Delete()
|
||||
}
|
||||
|
|
|
@ -164,6 +164,17 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
|||
alice.PeerWithOnion(bob.GetOnion())
|
||||
alice.PeerWithOnion(carol.GetOnion())
|
||||
|
||||
// Test that we can rekey alice without issues...
|
||||
err = alice.ChangePassword("asdfasdf", "password 1 2 3", "password 1 2 3")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("error changing password for Alice: %v", err)
|
||||
}
|
||||
|
||||
if !alice.CheckPassword("password 1 2 3") {
|
||||
t.Fatalf("Alice password did not change...")
|
||||
}
|
||||
|
||||
waitForConnection(t, alice, bob.GetOnion(), connections.AUTHENTICATED)
|
||||
waitForConnection(t, alice, carol.GetOnion(), connections.AUTHENTICATED)
|
||||
waitForConnection(t, bob, alice.GetOnion(), connections.AUTHENTICATED)
|
||||
|
@ -342,7 +353,6 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
|||
if numGoRoutinesStart != numGoRoutinesPostAppShutdown {
|
||||
t.Errorf("Number of GoRoutines at start (%v) does not match number of goRoutines after cleanup of peers and servers (%v), clean up failed, v detected!", numGoRoutinesStart, numGoRoutinesPostAppShutdown)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Utility function for sending a message from a peer to a group
|
||||
|
|
Loading…
Reference in New Issue