src/sync.h
author Krista Bennett <krista@pep-project.org>
Fri, 04 May 2018 16:30:21 +0200
branchlocal_cpptest
changeset 2652 43b913f99a27
parent 2287 026ab4dae779
child 2830 d6f044e43e1a
permissions -rw-r--r--
Shelving broken things to break other things
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 /*
     5 ====================================
     6 Engine/adapter/app KeySync interface 
     7 ====================================
     8 
     9 
    10          Engine         |          Adapter            |          App
    11                         |                             |
    12  . . . . . . . . . . . .|. . . . . . . . . . . . . . .|. . Attached session .  
    13      ,---------,        |                             |
    14    ,-| decrypt |<--------------------------------------- Incomming message 
    15    | | message |        |                             |
    16    | '---------'        |                             |
    17    | ,----------,       |                             |
    18    |-| myself   |<-------------------------------------- Create new account
    19    | | (keygen) |       |                             |
    20    | '----------'       |                             |
    21    | ,-----------,      |                             |
    22    |-| deliver   |<------------------------------------------- Accept/reject
    23    | | handshake |      |                     KeySync |            handshake
    24    | | result    |      |                     Message |
    25    | '-----------'      |                      Queue  |
    26    |                    |                      ,---,  |
    27    '-----------------------inject_sync_msg---->|   |  |
    28  . . . . . . . . . . . .|. . . . . . . . . . . |---| .|. . . . Sync session .  
    29  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *|   |* | 
    30                         |                      |---|  | 
    31  *   ,------------------retrieve_next_sync_msg-|   |* | 
    32    ,-v--------,         |                      '---'  | 
    33  * | Driver   |         |                           * |
    34    '----------'         |                             |
    35  *  ||'-event-----,     |                           * |
    36     |'--partner--,|     |                             |
    37  *  '---extra---,||     |           SYNC THREAD     *<-------------- Start Sync
    38             ,---vvv---, |                             |
    39  *     ,----|   FSM   | |                           * |
    40        |    '---------' |                             |
    41  *     |  ,-------,     |                           * |
    42        '->|actions|---------messageToSend-------------------> Send mail to self
    43  *        '-------'     |                           * |
    44               '-------------notifyHandshake-----------------> Ask for handshake
    45  *                      |                           * |    display group status
    46                         |                             |
    47  *  *  *  *  *  *  *  * |*  *  *  *  *  *  *  *  *  * |
    48                         |                             |
    49 
    50 Emails to self
    51 --------------
    52 
    53 With e-mail as a transport KeySync message handling is done when an incoming 
    54 email to self is passed to decrypt_message(), assuming that all incoming email
    55 messages are passed to decrypt_massage(). 
    56 
    57 In case of an email containing a KeySync paload, KeySync may consume or ignore
    58 the message. decrypt_message() signals this to the app with decrypt flags
    59 PEP_decrypt_flag_consume and PEP_decrypt_flag_ignore.
    60 
    61 In case of PEP_decrypt_flag_consume, app should delete the message.
    62 In case of PEP_decrypt_flag_ignore, app should ignore message.
    63 In both cases, message should be hidden.
    64 
    65 States, events, actions
    66 -----------------------
    67 
    68 In the engine, KeySync is implemented through a finite state machine (FSM) [1].
    69 KeySync state machine is driven [2] by events, triggering actions [3] and
    70 transitions to new states.
    71 
    72 Events happen on :
    73 
    74  - decryption of email messages
    75 
    76  - key generation
    77 
    78  - user interaction through the app 
    79 
    80  - timeout when staying too long in some particular states.
    81 
    82 [1] sync/devicegroup.fsm , src/sync_fsm.c (generated)
    83 [2] src/sync_driver.c (generated)
    84 [3] src/sync_actions.c , src/sync_send_actions.c (generated)
    85 
    86 Sync session, attached sessions
    87 -------------------------------
    88 
    89 To use KeySync, the adapter has to create a session dedicated to handle the
    90 protocol, register some callbacks [4] to the engine, and then call protocol's
    91 event consumer loop [5] in a dedicated thread. KeySync actions are executed as
    92 callback invoked from that thread.
    93 
    94 When a session is attached [6] to a KeySync session, decryption of pEp email
    95 messages in the attached session may trigger operations in KeySync session. In
    96 case of an adapter capable to serve multiple apps, each app is associated to a
    97 different KeySync session, and sessions created for use in that app are
    98 attached to that session.
    99 
   100 Adapters present different approaches regarding session and client abstraction,
   101 and may not propose to explicitely create or attach session or sync session.
   102 
   103 [4] register_sync_callbacks()
   104 [5] do_sync_protocol()
   105 [6] attach_sync_session()
   106 
   107 KeySync Messages and queue
   108 --------------------------
   109 
   110 KeySync messages [7], not to be confused with pEp (email) messages, are either
   111 directly events to be processed by the state machine, or KeySync payloads
   112 collected from decrypted messages. 
   113 
   114 KeySync messages can be emitted by different sessions, and could naturally come
   115 from different threads. They must be serialized in a locked queue. 
   116 KeySync messages queue is implemented by adapter, along with thread handling
   117 KeySync protocol. 
   118 
   119 Attached sessions inject [8] KeySync messages in the queue. Protocol loop
   120 retrieves [9] them from the queue. KeySync message is received [10] by the
   121 state machine, where event, partner and extra parameters are eventually deduced
   122 from payload.
   123 
   124 A state timeout event is a particular case. It doesn't traverse the queue, and
   125 isn't emitted by a session. It is triggered by a timeout on the retrieve
   126 operation. Value of the timeout is determined when entering a new state, and is
   127 passed as a parameter of the call to the blocking queue retrieve operation on 
   128 next protocol loop iteraton.
   129 
   130 [7] type sync_msg_t
   131 [8] callback inject_sync_msg
   132 [9] callback retrieve_next_sync_msg
   133 [10] receive_sync_msg() (src/sync_impl.c)
   134 
   135 Application callbacks
   136 ---------------------
   137 
   138 Some Keysync actions require the application to act, through callbacks :
   139 
   140  - messageToSend : send pEp messages through app's transport. 
   141    Messages are already encrypted and just need to be passed as-is to
   142    transport for transmission, as for messages returned by encrypt_message().
   143 
   144  - notifyHandshake : display KeySync status and handshake to the user.
   145    notifyHandshake callback receives 2 identities, 'me' and 'partner', together
   146    with a sync_handshake_signal enum :
   147 
   148     SYNC_NOTIFY_INIT_ADD_OUR_DEVICE :
   149         Device (me) is sole, about to enter a group (partner).
   150         App displays trustwords, and requests user accept or reject
   151         App calls deliverHandshakeResult with user's answer
   152 
   153     SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE :
   154         Device (me) is grouped, another device (partner) wants to join group.
   155         App displays trustwords, and requests user accept or reject
   156         App calls deliverHandshakeResult with user's answer
   157 
   158     SYNC_NOTIFY_INIT_FORM_GROUP :
   159         Device (me) is forming a group, including another device (partner)
   160         App displays trustwords, and requests user accept or reject
   161         App calls deliverHandshakeResult with user's answer
   162 
   163     SYNC_NOTIFY_INIT_MOVE_OUR_DEVICE
   164         Device (me) is grouped and will leave current group to join another
   165         device's (partner) group.
   166         App displays trustwords, and requests user accept or reject
   167         App calls deliverHandshakeResult with user's answer
   168 
   169 
   170     SYNC_NOTIFY_TIMEOUT :
   171         KeySync operation timed out.
   172         Identities are set reflecting peers involved in aborted operation.
   173         App displays error message. No feedback to engine.
   174 
   175     SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED,
   176         New device was added to group.
   177         App displays message. No feedback to engine.
   178 
   179     SYNC_NOTIFY_ACCEPTED_GROUP_CREATED
   180         New group created.
   181         App displays message. No feedback to engine.
   182 
   183     SYNC_NOTIFY_ACCEPTED_DEVICE_MOVED
   184         New device was moved from one group to another.
   185         App displays message. No feedback to engine.
   186 
   187    To deliver handshake result back to engine once user reacted,
   188    deliver_handshake_result is used. Result can be :
   189 
   190     SYNC_HANDSHAKE_CANCEL
   191         Gives no answer. User doesn't know id TrustWord are good or bad.
   192         For example in case peering device is away.
   193         Handshake will re-appear later.
   194 
   195     SYNC_HANDSHAKE_ACCEPTED
   196         Trustwords match with other device and user accepts handshake.
   197 
   198     SYNC_HANDSHAKE_REJECTED
   199         Trustwords do not match with any device and user rejects handshake.
   200 */
   201 
   202 #pragma once
   203 
   204 #include "message.h"
   205 #include "sync_fsm.h"
   206 #include "sync_app.h"
   207 
   208 // this module is for being used WITHOUT the Transport API in transport.h
   209 // DO NOT USE IT WHEN USING Transport API!
   210 
   211 
   212 #ifdef __cplusplus
   213 extern "C" {
   214 #endif
   215 
   216 // messageToSend() - send a message
   217 //
   218 //  parameters:
   219 //      obj (in)        object handle (implementation defined)
   220 //      msg (in)        message struct with message to send
   221 //
   222 //  return value:
   223 //      PEP_STATUS_OK or any other value on error
   224 //
   225 //  caveat:
   226 //      the ownership of msg goes to the callee
   227 
   228 typedef PEP_STATUS (*messageToSend_t)(void *obj, message *msg);
   229 
   230 // notifyHandshake() - notify UI about sync handshaking process
   231 //
   232 //  parameters:
   233 //      obj (in)        object handle (implementation defined)
   234 //      me (in)         own identity
   235 //      partner (in)    identity of partner
   236 //      signal (in)     reason of the notification
   237 //
   238 //  return value:
   239 //      PEP_STATUS_OK or any other value on error
   240 //
   241 //  caveat:
   242 //      ownership of self and partner go to the callee
   243 
   244 typedef PEP_STATUS (*notifyHandshake_t)(
   245         void *obj,
   246         pEp_identity *me,
   247         pEp_identity *partner,
   248         sync_handshake_signal signal
   249     );
   250 
   251 typedef enum _sync_handshake_result {
   252     SYNC_HANDSHAKE_CANCEL = -1,
   253     SYNC_HANDSHAKE_ACCEPTED = 0,
   254     SYNC_HANDSHAKE_REJECTED = 1
   255 } sync_handshake_result;
   256 
   257 // deliverHandshakeResult() - give the result of the handshake dialog
   258 //
   259 //  parameters:
   260 //      session (in)        session handle
   261 //      result (in)         handshake result
   262 
   263 DYNAMIC_API PEP_STATUS deliverHandshakeResult(
   264         PEP_SESSION session,
   265         Identity partner,
   266         sync_handshake_result result
   267     );
   268 
   269 // sync_msg_t - items queued for serialized handling by protocol engine
   270 typedef struct _sync_msg_t sync_msg_t;
   271 
   272 // inject_sync_msg - inject sync protocol message
   273 //
   274 //  parameters:
   275 //      msg (in)            message to inject
   276 //      management (in)     application defined
   277 //
   278 //  *** BEWARE: msg is 1st parameter, obj is second!!! ***
   279 //  return value:
   280 //      0 if msg could be stored successfully or nonzero otherwise
   281 
   282 typedef int (*inject_sync_msg_t)(void *msg, void *management);
   283 
   284 
   285 // retrieve_next_sync_msg - receive next sync message
   286 //
   287 //  parameters:
   288 //      management (in)     application defined
   289 //      timeout (in,out)    do not wait longer than timeout for message
   290 //                          timeout == NULL or *timeout == 0 is blocking
   291 //
   292 //  return value:
   293 //      next message, then timeout[out] == remaining time
   294 //      NULL and timeout[out] != 0 for timeout occurence
   295 //      NULL and timeout[out] == 0 for termination
   296 
   297 typedef void *(*retrieve_next_sync_msg_t)(void *management, time_t *timeout);
   298 
   299 
   300 // register_sync_callbacks() - register adapter's callbacks
   301 //
   302 //  parameters:
   303 //      session (in)                session where to store obj handle
   304 //      management (in)             application defined
   305 //      messageToSend (in)          callback for sending message
   306 //      notifyHandshake (in)        callback for doing the handshake
   307 //      retrieve_next_sync_msg (in) callback for receiving sync messages
   308 //
   309 //  return value:
   310 //      PEP_STATUS_OK or any other value on errror
   311 //
   312 //  caveat:
   313 //      call that BEFORE you're using any other part of the engine
   314 
   315 DYNAMIC_API PEP_STATUS register_sync_callbacks(
   316         PEP_SESSION session,
   317         void *management,
   318         messageToSend_t messageToSend,
   319         notifyHandshake_t notifyHandshake,
   320         inject_sync_msg_t inject_sync_msg,
   321         retrieve_next_sync_msg_t retrieve_next_sync_msg
   322     );
   323 
   324 // attach_sync_session() - attach session to a session running keysync state machine 
   325 //
   326 //  parameters:
   327 //      session (in)                session to attach
   328 //      sync_session (in)           session running keysync
   329 //
   330 //  return value:
   331 //      PEP_STATUS_OK or any other value on errror
   332 //
   333 //  caveat:
   334 //      register_sync_callbacks must have been called on sync_session
   335 //      call that BEFORE you're using that session in any other part of the engine
   336 
   337 DYNAMIC_API PEP_STATUS attach_sync_session(
   338         PEP_SESSION session,
   339         PEP_SESSION sync_session
   340     );
   341 
   342 // detach_sync_session() - detach previously attached sync session
   343 //
   344 //  parameters:
   345 //      session (in)                session to detach 
   346 
   347 DYNAMIC_API PEP_STATUS detach_sync_session(PEP_SESSION session);
   348 
   349 // unregister_sync_callbacks() - unregister adapter's callbacks
   350 //
   351 //  parameters:
   352 //      session (in)                session to unregister
   353 
   354 DYNAMIC_API void unregister_sync_callbacks(PEP_SESSION session);
   355 
   356 // do_sync_protocol() - function to be run on an extra thread
   357 //
   358 //  parameters:
   359 //      session                 pEp session to use
   360 //      retrieve_next_sync_msg  pointer to retrieve_next_identity() callback
   361 //                              which returns at least a valid address field in
   362 //                              the identity struct
   363 //      obj                     application defined sync object
   364 //
   365 //  return value:
   366 //      PEP_STATUS_OK if thread has to terminate successfully or any other
   367 //      value on failure
   368 //
   369 //  caveat:
   370 //      to ensure proper working of this library, a thread has to be started
   371 //      with this function immediately after initialization
   372 
   373 DYNAMIC_API PEP_STATUS do_sync_protocol(
   374         PEP_SESSION session,
   375         void *obj
   376     );
   377 
   378 // free_sync_msg() - free sync_msg_t struct when not passed to do_sync_protocol  
   379 //
   380 //  parameters:
   381 //      sync_msg (in)            pointer to sync_msg_t struct to free.
   382 //                               pointer can be NULL.
   383 
   384 DYNAMIC_API void free_sync_msg(sync_msg_t *sync_msg);
   385 
   386 // decode_sync_msg() - decode sync message from PER into XER
   387 //
   388 //  parameters:
   389 //      data (in)               PER encoded data
   390 //      size (in)               size of PER encoded data
   391 //      text (out)              XER text of the same sync message
   392 
   393 DYNAMIC_API PEP_STATUS decode_sync_msg(
   394         const char *data,
   395         size_t size,
   396         char **text
   397     );
   398 
   399 
   400 // encode_sync_msg() - encode sync message from XER into PER
   401 //
   402 //  parameters:
   403 //      text (in)               string with XER text of the sync message
   404 //      data (out)              PER encoded data
   405 //      size (out)              size of PER encoded data
   406 
   407 DYNAMIC_API PEP_STATUS encode_sync_msg(
   408         const char *text,
   409         char **data,
   410         size_t *size
   411     );
   412 
   413 
   414 #ifdef __cplusplus
   415 }
   416 #endif
   417