Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-instance conversation #28

Open
juniorz opened this issue Jun 8, 2017 · 8 comments
Open

Multi-instance conversation #28

juniorz opened this issue Jun 8, 2017 · 8 comments
Labels
architecture discuss importance high An issue that is absolutely necessary to have done before final release pidgin plugin
Milestone

Comments

@juniorz
Copy link
Member

juniorz commented Jun 8, 2017

From the plugin perspective, something like this should be possible:

  1. Alice (on device 1101) has an OTR conversation with Bob (on device 1201).
  2. Bob (on device 1202) starts a new OTR conversation with Alice (still on device 1101).
  3. Alice should have both conversations running simultaneously, and should be able to receive and send messages to both conversations.

libotr keeps a separate context for each of these conversations and automatically manages when to add new contexts when a new instance tag is seen.

When a message is sent, you may choose to send it to a particular instance tag or tell the library which strategy to use when deciding which instance should receive the message (OTRL_INSTAG_BEST, OTRL_INSTAG_RECENT, OTRL_INSTAG_RECENT_RECEIVED, OTRL_INSTAG_RECENT_SENT).

At the moment, we only support a single conversation with a peer (identified by its ID, like alice@tw.com).

@juniorz juniorz added this to the Working prototype milestone Jun 8, 2017
juniorz added a commit that referenced this issue Jun 8, 2017
@olabini
Copy link
Contributor

olabini commented Apr 9, 2018

I think we need to be careful to not do too much of the instance tag management in the libotr-ng - I suspect the plugin should be more responsible for this, just as we have it in the otr3 for Go-lang.

@claucece claucece removed this from the Working prototype milestone Apr 10, 2018
@claucece claucece added importance high An issue that is absolutely necessary to have done before final release architecture and removed waiting labels Jun 26, 2018
@claucece
Copy link
Member

This needs careful investigation to see if it makes sense for OTRv4.

@olabini
Copy link
Contributor

olabini commented Sep 20, 2018

This involves looking at whether it makes sense, which policies makes sense, and also whether we should move some of this functionality away from libotr-ng to pidgin-otrng.

@claucece claucece self-assigned this Sep 26, 2018
@claucece
Copy link
Member

After investigating a little bit from the plugin perspective:

  • Alice (on device 1101) starts an OTR conversation with Bob (on device 1201) and Bob (on device 1201).
  • Bob (on device 1202 and 1201) receives the DAKE from Alice, but only one device receives data messages (not sure how this is chosen).

This also happens:

  • Alice (on device 1101) has an OTR conversation with Bob (on device 1201).
  • Bob (on device 1202) starts a new OTR conversation with Alice (still on device 1101).
  • Alice can send messages only to device 1202, and only receive from device 1201.

@claucece
Copy link
Member

So, for this case, apparently this is what happens:

If your application allows the same user to be logged in multiple times from different locations, it should probably be aware of instance tags. A user can maintain multiple concurrent OTR conversations with a buddy who is logged in multiple times. Only one of the buddy's sessions can be a client who is running OTR protocol version 2. When a user has a conversation with a buddy who is running OTR protocol version 2, the conversation is associated with a ConnContext that lists "their_instance" as OTRL_INSTAG_MASTER (which has a value of 0) (This is not for our case). Each version 3 conversation with the same buddy will have its own ConnContext, which you can differentiate by the value in the
"their_instance" field.

In the linked list of ConnContexts, the master context for a buddy is always listed immediately before its children. Fingerprints are only stored with the master context. Given a ConnContext associated to a
conversation with a buddy, you can easily iterate over all the contexts for that buddy by doing the following:

void example_something_happened(ConnContext * context) {
    ConnContext * context_iter = context->m_context;
    
    while (context_iter && context_iter->m_context == context->m_context) {
	/* Something you wish to affect all contexts of a particular buddy */
	context_iter = context_iter->next;
    }

If a user has multiple OTR sessions with the same buddy, your application will likely want to provide some way for the user to select which instance to send outgoing messages to. You can detect when a user has multiple OTR sessions with the same buddy by iterating over the ConnContexts of a buddy when a conversation has gone secure and checking whether more than one is not in plaintext state. You specify which instance outgoing messages are directed to in otrl_message_sending:

gcry_error_t otrl_message_sending(OtrlUserState us,
	const OtrlMessageAppOps *ops,
	void *opdata, const char *accountname, const char *protocol,
	const char *recipient, otrl_instag_t instag, const char *original_msg,
	OtrlTLV *tlvs, char **messagep, OtrlFragmentPolicy fragPolicy,
	ConnContext **contextp,
	void (*add_appdata)(void *data, ConnContext *context),
	void *data);

Instead of an actual instance tag, you can specify a meta instance tag (e.g., if the user has not made an explicit selection). Here are the list of meta instance tags, as defined in instag.h:

#define OTRL_INSTAG_BEST 1 /* Most secure, based on: conv status,
* then fingerprint status, then most recent. /
#define OTRL_INSTAG_RECENT 2 /
Most recent of the two meta instances below */
#define OTRL_INSTAG_RECENT_RECEIVED 3
#define OTRL_INSTAG_RECENT_SENT 4

OTRL_INSTAG_BEST choses the instance that has the best conv status, then fingerprint status (in the event of a tie), then most recent (similarly in the event of a tie). When calculating how recent an instance has been active, OTRL_INSTAG_BEST is limited by a one second resolution.
OTRL_INSTAG_RECENT* does not have this limitation, but due to inherent uncertainty in some networks, libotr's notion of the most recent may not always agree with the remote network. It is important to understand this limitation due to the issue noted in the next paragraph.

Note that instances do add some uncertainty when dealing with networks that only deliver messages to the most recently active session for a buddy who is logged in multiple times. If you have a particular instance selected, and the IM network is simply not going to deliver to that particular instance, there isn't too much libotr can do. In this case, you may want your application to warn when a user has selected an instance that is not the most recent.

Do you think is something wanted? @olabini

Let's discuss this on Monday as well.

@claucece
Copy link
Member

claucece commented Oct 1, 2018

Furthermore, this is also the idea:

- The plugin now supports multiple OTR conversations with the same
  buddy who is logged in at multiple locations. In this case, a new
  OTR menu will appear, which allows you to select which session an
  outgoing message is indended for. Note that concurrent SMP
  authentications with the same buddy who is logged in multiple times
  is not yet supported (starting a second authentication will end the
  first).

@claucece claucece added this to the October milestone Oct 2, 2018
@claucece claucece modified the milestones: October, November Nov 4, 2018
@claucece
Copy link
Member

claucece commented Nov 6, 2018

So, we decided to have 'policies' for instance tags:

  1. Best: send to the device which has trusted authentication, and it is the most recent one of them.
  2. Recent received: send to the device from which it was recently received.
  3. Recent sent: send to the device from which it was recently sent.

Should be the same for retrieving prekey ensembles.

We can also show this in the UI.

@olabini olabini removed this from the November milestone Mar 11, 2019
@claucece
Copy link
Member

I'm leaving this for someone to take it as I'm focusing on #179 . I'll take it after that or someone else can take it.

@claucece claucece removed their assignment Mar 20, 2019
@claucece claucece added this to the architecture milestone Oct 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
architecture discuss importance high An issue that is absolutely necessary to have done before final release pidgin plugin
Projects
None yet
Development

No branches or pull requests

4 participants