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