diff --git a/api/client.go b/api/client.go index 2c28d84d33b193a3236f2332a9c69a16f4e3e5d9..0aee60d576cae5301f0e7d5e48f0d91e68f50a21 100644 --- a/api/client.go +++ b/api/client.go @@ -304,7 +304,7 @@ func Login(storageDir string, password []byte, parameters params.Network) (*Clie } // initialize the auth tracker - c.auth = auth.NewManager(c.switchboard, c.storage, c.network) + c.auth = auth.NewManager(c.switchboard, c.storage, c.network, parameters.ReplayRequests) // Add all processes to the followerServices err = c.registerFollower() @@ -363,7 +363,7 @@ func LoginWithNewBaseNDF_UNSAFE(storageDir string, password []byte, } // initialize the auth tracker - c.auth = auth.NewManager(c.switchboard, c.storage, c.network) + c.auth = auth.NewManager(c.switchboard, c.storage, c.network, parameters.ReplayRequests) err = c.registerFollower() if err != nil { @@ -420,7 +420,7 @@ func LoginWithProtoClient(storageDir string, password []byte, protoClientJSON [] } // initialize the auth tracker - c.auth = auth.NewManager(c.switchboard, c.storage, c.network) + c.auth = auth.NewManager(c.switchboard, c.storage, c.network, parameters.ReplayRequests) err = c.registerFollower() if err != nil { diff --git a/auth/callback.go b/auth/callback.go index c0acff7b66784d4834cdfddc78c297b5496ff84b..7d3f262165df1f8cb5eb1f30a5c3283a99da9150 100644 --- a/auth/callback.go +++ b/auth/callback.go @@ -165,7 +165,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message, return } else { //check if the relationship already exists, - rType, _, _, err := m.storage.Auth().GetRequest(partnerID) + rType, _, c, err := m.storage.Auth().GetRequest(partnerID) if err != nil && !strings.Contains(err.Error(), auth.NoRequest) { // if another error is received, print it and exit em := fmt.Sprintf("Received new Auth request for %s, "+ @@ -183,6 +183,15 @@ func (m *Manager) handleRequest(cmixMsg format.Message, "is a duplicate", partnerID) jww.WARN.Print(em) events.Report(5, "Auth", "DuplicateRequest", em) + // if the caller of the API wants requests replayed, + // replay the duplicate request + if m.replayRequests{ + cbList := m.requestCallbacks.Get(c.ID) + for _, cb := range cbList { + rcb := cb.(interfaces.RequestCallback) + go rcb(c) + } + } return // if we sent a request, then automatically confirm // then exit, nothing else needed @@ -296,7 +305,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message, cbList := m.requestCallbacks.Get(c.ID) for _, cb := range cbList { rcb := cb.(interfaces.RequestCallback) - go rcb(c, "") + go rcb(c) } return } diff --git a/auth/manager.go b/auth/manager.go index b5803d69feb7ae67073e351b1c7fd24c3ac5b597..4562ed804dfba7f0dae6d587d64f15b72742f534 100644 --- a/auth/manager.go +++ b/auth/manager.go @@ -23,16 +23,19 @@ type Manager struct { storage *storage.Session net interfaces.NetworkManager + + replayRequests bool } func NewManager(sw interfaces.Switchboard, storage *storage.Session, - net interfaces.NetworkManager) *Manager { + net interfaces.NetworkManager, replayRequests bool) *Manager { m := &Manager{ requestCallbacks: newCallbackMap(), confirmCallbacks: newCallbackMap(), rawMessages: make(chan message.Receive, 1000), storage: storage, net: net, + replayRequests: replayRequests, } sw.RegisterChannel("Auth", switchboard.AnyUser(), message.Raw, m.rawMessages) @@ -89,3 +92,15 @@ func (m *Manager) AddSpecificConfirmCallback(id *id.ID, cb interfaces.ConfirmCal func (m *Manager) RemoveSpecificConfirmCallback(id *id.ID) { m.confirmCallbacks.RemoveSpecific(id) } + +func (m *Manager)ReplayRequests(){ + cList := m.storage.Auth().GetAllReceived() + for i := range cList{ + c := cList[i] + cbList := m.requestCallbacks.Get(c.ID) + for _, cb := range cbList { + rcb := cb.(interfaces.RequestCallback) + go rcb(c) + } + } +} diff --git a/bindings/authenticatedChannels.go b/bindings/authenticatedChannels.go index 67d2a885098b34671d75014189b682ed75a6a32c..36888a604177ae36b37d80f97ad61b01700cb51a 100644 --- a/bindings/authenticatedChannels.go +++ b/bindings/authenticatedChannels.go @@ -63,7 +63,7 @@ func (c *Client) RequestAuthenticatedChannel(recipientMarshaled, func (c *Client) RegisterAuthCallbacks(request AuthRequestCallback, confirm AuthConfirmCallback) { - requestFunc := func(requestor contact.Contact, message string) { + requestFunc := func(requestor contact.Contact) { requestorBind := &Contact{c: &requestor} request.Callback(requestorBind) } @@ -136,3 +136,8 @@ func (c *Client) GetRelationshipFingerprint(partnerID []byte) (string, error) { return c.api.GetRelationshipFingerprint(partner) } + +// ReplayRequests Resends all pending requests over the normal callbacks +func (c *Client) ReplayRequests() () { + c.api.GetAuthRegistrar().ReplayRequests() +} \ No newline at end of file diff --git a/cmd/root.go b/cmd/root.go index 328f814cd5f67dd93b13075e93d62795b3684861..7f38db02a83e6cbcd869637e9c5a6fbec920cd14 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -473,7 +473,7 @@ func initClientCallbacks(client *api.Client) (chan *id.ID, }) if viper.GetBool("unsafe-channel-creation") { authMgr.AddGeneralRequestCallback(func( - requestor contact.Contact, message string) { + requestor contact.Contact) { jww.INFO.Printf("Channel Request: %s", requestor.ID) _, err := client.ConfirmAuthenticatedChannel( @@ -681,13 +681,11 @@ func deleteChannel(client *api.Client, partnerId *id.ID) { } } -func printChanRequest(requestor contact.Contact, message string) { +func printChanRequest(requestor contact.Contact) { msg := fmt.Sprintf("Authentication channel request from: %s\n", requestor.ID) jww.INFO.Printf(msg) fmt.Printf(msg) - msg = fmt.Sprintf("Authentication channel request message: %s\n", message) - jww.INFO.Printf(msg) // fmt.Printf(msg) } diff --git a/cmd/single.go b/cmd/single.go index cc0cadadd56ea05f1656a7ff7ed3858213ee3169..cd6cc0a8815caa9969f02123274a0023512988e9 100644 --- a/cmd/single.go +++ b/cmd/single.go @@ -53,7 +53,7 @@ var singleCmd = &cobra.Command{ // If unsafe channels, then add auto-acceptor if viper.GetBool("unsafe-channel-creation") { authMgr.AddGeneralRequestCallback(func( - requester contact.Contact, message string) { + requester contact.Contact) { jww.INFO.Printf("Got request: %s", requester.ID) _, err := client.ConfirmAuthenticatedChannel(requester) if err != nil { diff --git a/cmd/ud.go b/cmd/ud.go index 767bc12eab4e84c82c93efc2a80e6b4613bc0a7a..34fff1c098f490195a952ac302cc7256ccf7b577 100644 --- a/cmd/ud.go +++ b/cmd/ud.go @@ -53,7 +53,7 @@ var udCmd = &cobra.Command{ // If unsafe channels, add auto-acceptor if viper.GetBool("unsafe-channel-creation") { authMgr.AddGeneralRequestCallback(func( - requester contact.Contact, message string) { + requester contact.Contact) { jww.INFO.Printf("Got Request: %s", requester.ID) _, err := client.ConfirmAuthenticatedChannel(requester) if err != nil { diff --git a/interfaces/auth.go b/interfaces/auth.go index bb3cae74d0a37f0fda2c34e8ce0623af6f8a789f..4ce22fba789b45a5616a640f0409a054f6a05ecb 100644 --- a/interfaces/auth.go +++ b/interfaces/auth.go @@ -12,7 +12,7 @@ import ( "gitlab.com/xx_network/primitives/id" ) -type RequestCallback func(requestor contact.Contact, message string) +type RequestCallback func(requestor contact.Contact) type ConfirmCallback func(partner contact.Contact) type Auth interface { @@ -42,4 +42,6 @@ type Auth interface { AddSpecificConfirmCallback(id *id.ID, cb ConfirmCallback) // Removes a specific callback to be used on auth confirm. RemoveSpecificConfirmCallback(id *id.ID) + //Replays all pending received requests over tha callbacks + ReplayRequests() } diff --git a/interfaces/params/network.go b/interfaces/params/network.go index 67d083802e516de5d0feca95a299416489561a8a..259cbef58fdc572195b0e1ecea284e427afad675 100644 --- a/interfaces/params/network.go +++ b/interfaces/params/network.go @@ -34,6 +34,8 @@ type Network struct { // Determines if the state of every round processed is tracked in ram. // This is very memory intensive and is primarily used for debugging VerboseRoundTracking bool + // Resends auth requests up the stack if received multiple times + ReplayRequests bool Rounds Messages @@ -54,6 +56,7 @@ func GetDefaultNetwork() Network { FastPolling: true, BlacklistedNodes: make([]string, 0), VerboseRoundTracking: false, + ReplayRequests: true, } n.Rounds = GetDefaultRounds() n.Messages = GetDefaultMessage() diff --git a/storage/auth/store.go b/storage/auth/store.go index addd3d138499ae09cfc5e9dc5d221d79d95d060a..acf15c3d28c0b7d8e5dea5d1c3613290e4484d6a 100644 --- a/storage/auth/store.go +++ b/storage/auth/store.go @@ -261,6 +261,19 @@ func (s *Store) AddReceived(c contact.Contact, key *sidh.PublicKey) error { return nil } +func (s *Store)GetAllReceived()[]contact.Contact{ + s.mux.RLock() + defer s.mux.RUnlock() + cList := make([]contact.Contact, 0, len(s.requests)) + for key := range s.requests{ + r := s.requests[key] + if r.rt == Receive{ + cList = append(cList,*r.receive) + } + } + return cList +} + // GetFingerprint can return either a private key or a sentRequest if the // fingerprint is found. If it returns a sentRequest, then it takes the lock to // ensure there is only one operator at a time. The user of the API must release