src/sync_actions.c
author Edouard Tisserant <edouard@pep-project.org>
Tue, 22 Nov 2016 14:57:53 +0100
changeset 1413 41c869ac1c48
parent 1297 78f5f9894fbd
child 1459 ab329d7db8d7
permissions -rw-r--r--
ENGINE-140 #comment prevent to accept excluded identity from devices where identity haven't been excluded
     1 // Actions for DeviceState state machine
     2 
     3 #include <assert.h>
     4 #include "pEp_internal.h"
     5 #include "message.h"
     6 #include "sync_fsm.h"
     7 #include "map_asn1.h"
     8 #include "baseprotocol.h"
     9 
    10 // conditions
    11 
    12 static const char *sql_stored_group_keys =
    13         "select count(device_group) from person where id = '" PEP_OWN_USERID "';"; 
    14 
    15 static int _stored_group_keys(void *_gc, int count, char **text, char **name)
    16 {
    17     assert(_gc);
    18     assert(count == 1);
    19     assert(text && text[0]);
    20     if (!(_gc && count == 1 && text && text[0]))
    21         return -1;
    22 
    23     bool *gc = (bool *) _gc;
    24     *gc = atoi(text[0]) != 0;
    25     return 0;
    26 }
    27 
    28 int storedGroupKeys(PEP_SESSION session)
    29 {
    30     assert(session);
    31     if (!session)
    32         return invalid_condition; // error
    33 
    34     bool gc = false;
    35     int int_result = sqlite3_exec(
    36         session->db,
    37         sql_stored_group_keys,
    38         _stored_group_keys,
    39         &gc,
    40         NULL
    41     );
    42     assert(int_result == SQLITE_OK);
    43     if (int_result != SQLITE_OK)
    44         return invalid_condition; // error
    45 
    46     if (gc)
    47         return 1;
    48     else
    49         return 0;
    50 }
    51 
    52 int keyElectionWon(PEP_SESSION session, Identity partner)
    53 {
    54     assert(session);
    55     assert(partner);
    56     if (!(session && partner))
    57         return invalid_condition; // error
    58 
    59     // an already existing group always wins
    60 
    61     if (storedGroupKeys(session)) {
    62         assert(!(partner->flags & PEP_idf_devicegroup));
    63         return 1;
    64     }
    65 
    66     if (partner->flags & PEP_idf_devicegroup)
    67         return 0;
    68 
    69     Identity me = NULL;
    70     PEP_STATUS status = get_identity(session, partner->address, PEP_OWN_USERID,
    71             &me);
    72     if (status == PEP_OUT_OF_MEMORY)
    73         return invalid_out_of_memory;
    74     if (status != PEP_STATUS_OK)
    75         return invalid_condition; // error
    76 
    77     int result = invalid_condition; // error state has to be overwritten
    78 
    79     time_t own_created;
    80     time_t partners_created;
    81 
    82     status = key_created(session, me->fpr, &own_created);
    83     if (status != PEP_STATUS_OK)
    84         goto the_end;
    85 
    86     status = key_created(session, partner->fpr, &partners_created);
    87     if (status != PEP_STATUS_OK)
    88         goto the_end;
    89 
    90     if (own_created > partners_created)
    91         result = 0;
    92     else
    93         result = 1;
    94 
    95 the_end:
    96     free_identity(me);
    97     return result;
    98 }
    99 
   100 // showHandshake() - trigger the handshake dialog of the application
   101 //
   102 //  params:
   103 //      session (in)        session handle
   104 //      state (in)          state the state machine is in
   105 //      partner (in)        partner to communicate with
   106 //
   107 //  returns:
   108 //      PEP_STATUS_OK or any other value on error
   109 
   110 PEP_STATUS showHandshake(
   111         PEP_SESSION session,
   112         DeviceState_state state,
   113         Identity partner,
   114         void *extra
   115     )
   116 {
   117     PEP_STATUS status = PEP_STATUS_OK;
   118 
   119     assert(session);
   120     assert(partner);
   121     assert(extra == NULL);
   122 
   123     if (!(session && partner))
   124         return PEP_ILLEGAL_VALUE;
   125 
   126     assert(session->showHandshake);
   127     if (!session->showHandshake)
   128         return PEP_SYNC_NO_TRUSTWORDS_CALLBACK;
   129 
   130     // showHandshake take ownership of given identities
   131     pEp_identity *me = NULL;
   132     status = get_identity(session, partner->address, PEP_OWN_USERID, &me);
   133     if (status != PEP_STATUS_OK)
   134         goto error;
   135     
   136     pEp_identity *_partner = NULL;
   137     _partner = identity_dup(partner);
   138     if (_partner == NULL){
   139         status = PEP_OUT_OF_MEMORY;
   140         goto error;
   141     }
   142 
   143     status = session->showHandshake(session->sync_obj, me, _partner);
   144     if (status != PEP_STATUS_OK)
   145         goto error;
   146 
   147     return status;
   148 
   149 error:
   150     free_identity(me);
   151     return status;
   152 }
   153 
   154 
   155 // acceptHandshake() - stores acception of partner
   156 //
   157 //  params:
   158 //      session (in)        session handle
   159 //      state (in)          state the state machine is in
   160 //      partner (in)        partner to communicate with
   161 //
   162 //  returns:
   163 //      PEP_STATUS_OK or any other value on error
   164 
   165 PEP_STATUS acceptHandshake(
   166         PEP_SESSION session,
   167         DeviceState_state state,
   168         Identity partner,
   169         void *extra
   170     )
   171 {
   172     PEP_STATUS status = PEP_STATUS_OK;
   173 
   174     assert(session);
   175     assert(partner);
   176     assert(extra == NULL);
   177     if (!(session && partner))
   178         return PEP_ILLEGAL_VALUE;
   179 
   180     status = trust_personal_key(session, partner);
   181 
   182     return status;
   183 }
   184 
   185 
   186 // rejectHandshake() - stores rejection of partner
   187 //
   188 //  params:
   189 //      session (in)        session handle
   190 //      state (in)          state the state machine is in
   191 //      partner (in)        partner to communicate with
   192 //
   193 //  returns:
   194 //      PEP_STATUS_OK or any other value on error
   195 
   196 PEP_STATUS rejectHandshake(
   197         PEP_SESSION session,
   198         DeviceState_state state,
   199         Identity partner,
   200         void *extra
   201     )
   202 {
   203     PEP_STATUS status = PEP_STATUS_OK;
   204 
   205     assert(session);
   206     assert(partner);
   207     assert(extra == NULL);
   208     if (!(session && partner))
   209         return PEP_ILLEGAL_VALUE;
   210 
   211     status = set_identity_flags(session, partner,
   212             partner->flags | PEP_idf_not_for_sync);
   213 
   214     return status;
   215 }
   216 
   217 
   218 // storeGroupKeys() - 
   219 //
   220 //  params:
   221 //      session (in)        session handle
   222 //      state (in)          state the state machine is in
   223 //      partner (in)        partner to communicate with
   224 //      _group_keys (in)    group keys received from partner
   225 //
   226 //  returns:
   227 //      PEP_STATUS_OK or any other value on error
   228 
   229 PEP_STATUS storeGroupKeys(
   230         PEP_SESSION session,
   231         DeviceState_state state,
   232         Identity partner,
   233         void *_group_keys
   234     )
   235 {
   236     PEP_STATUS status = PEP_STATUS_OK;
   237 
   238     assert(session);
   239     assert(partner);
   240     assert(_group_keys);
   241     if (!(session && partner && _group_keys))
   242         return PEP_ILLEGAL_VALUE;
   243 
   244     identity_list *group_keys = (identity_list *) _group_keys;
   245 
   246     for (identity_list *il = group_keys; il && il->ident; il = il->next) {
   247 
   248         // Check that identity isn't excluded from sync.
   249         pEp_identity *stored_identity;
   250         status = get_identity(session, il->ident->address, PEP_OWN_USERID,
   251                 &stored_identity);
   252         if (status == PEP_STATUS_OK) {
   253             if(stored_identity->flags & PEP_idf_not_for_sync){
   254                 free_identity(stored_identity);
   255                 continue;
   256             }
   257             free_identity(stored_identity);
   258         }
   259 
   260         free(il->ident->user_id);
   261         il->ident->user_id = strdup(PEP_OWN_USERID);
   262         assert(il->ident->user_id);
   263         if (!il->ident->user_id)
   264             goto enomem;
   265         status = set_identity(session, il->ident);
   266         if (status != PEP_STATUS_OK)
   267             break;
   268     }
   269 
   270     free_identity_list(group_keys);
   271     
   272     return status;
   273 
   274 enomem:
   275     status = PEP_OUT_OF_MEMORY;
   276     free_identity_list(group_keys);
   277     return status;
   278 }
   279 
   280 // enterGroup() - 
   281 //
   282 //  params:
   283 //      session (in)        session handle
   284 //      state (in)          state the state machine is in
   285 //      partner (in)        ignored
   286 //      extra (in)          ignored
   287 //
   288 //  returns:
   289 //      PEP_STATUS_OK or any other value on error
   290 
   291 PEP_STATUS enterGroup(
   292         PEP_SESSION session,
   293         DeviceState_state state,
   294         Identity partner,
   295         void *extra
   296     )
   297 {
   298     PEP_STATUS status = PEP_STATUS_OK;
   299 
   300     assert(session);
   301 
   302     // groups have no uuid for now
   303     status = set_device_group(session, "1");
   304     
   305     return status;
   306 }