sync/cond_act_sync.yml2
author Volker Birk <vb@pep-project.org>
Fri, 03 May 2019 10:40:31 +0200
branchsync
changeset 3609 548e7dd045e5
parent 3605 27595b58666d
child 3722 0f31947b826d
permissions -rw-r--r--
fixing some string alloc problems
vb@2831
     1
// This file is under GNU General Public License 3.0
vb@2831
     2
// see LICENSE.txt
vb@2831
     3
vb@2831
     4
// generate conditions and actions
vb@2831
     5
vb@3512
     6
// Copyleft (c) 2017-2019, p≡p foundation
vb@2831
     7
vb@2831
     8
// Written by Volker Birk
vb@2831
     9
vb@2831
    10
vb@2844
    11
include ./sql_func.yml2
vb@2831
    12
vb@2831
    13
// condition: PEP_STATUS «@name»(PEP_SESSION session, bool *result)
vb@2831
    14
vb@2831
    15
condition deviceGrouped {
vb@2831
    16
    call "exec_sql_int" with "sql"
vb@3525
    17
        > "select count(*) from identity where is_own = 1 and (flags & 0x100) = 0x100;"
vb@2831
    18
    |> *result = _result > 0;
vb@2831
    19
}
vb@2831
    20
vb@2902
    21
condition weAreFirst
vb@2902
    22
||
vb@2902
    23
    TID_t *t1 = &session->sync_state.keysync.challenge;
vb@2902
    24
    TID_t *t2 = &session->own_sync_state.challenge;
vb@2902
    25
vb@2905
    26
    *result = _TID_greater(t1, t2);
vb@2902
    27
||
vb@2902
    28
vb@2831
    29
condition partnerIsGrouped
vb@2831
    30
|> *result = session->sync_state.keysync.is_group;
vb@2831
    31
vb@2831
    32
condition challengeAccepted
vb@2831
    33
||
vb@2831
    34
    TID_t *t1 = &session->sync_state.keysync.challenge;
vb@2831
    35
    TID_t *t2 = &session->own_sync_state.challenge;
vb@2831
    36
vb@2831
    37
    *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
vb@2831
    38
||
vb@2831
    39
vb@3514
    40
condition sameChallenge
vb@3514
    41
||
vb@3514
    42
    TID_t *t1 = &session->sync_state.keysync.challenge;
vb@3514
    43
    TID_t *t2 = &session->own_sync_state.challenge;
vb@3514
    44
vb@3514
    45
    *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
vb@3514
    46
||
vb@3514
    47
vb@3510
    48
condition sameTransaction
vb@3510
    49
||
vb@3550
    50
    TID_t *t1 = &session->sync_state.keysync.negotiation;
vb@3550
    51
    TID_t *t2 = &session->own_sync_state.negotiation;
vb@3510
    52
vb@3591
    53
    // test if TID is identical
vb@3510
    54
    *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
vb@3510
    55
||
vb@3510
    56
vb@3591
    57
condition sameTransactionAndPartner
vb@3591
    58
||
vb@3591
    59
    TID_t *t1 = &session->sync_state.keysync.negotiation;
vb@3591
    60
    TID_t *t2 = &session->own_sync_state.negotiation;
vb@3591
    61
vb@3591
    62
    const char *s1 = session->sync_state.common.signature_fpr;
vb@3591
    63
    const char *s2 = session->own_sync_state.signature_fpr;
vb@3591
    64
vb@3591
    65
    // test if TID is identical
vb@3591
    66
    *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0
vb@3591
    67
    // and test if we're talking to the same sender
vb@3591
    68
            && s1 && s2 && strcmp(s1, s2) == 0;
vb@3591
    69
||
vb@3591
    70
vb@2831
    71
condition keyElectionWon
vb@2831
    72
||
vb@2838
    73
    pEp_identity *from = session->sync_state.common.from;
vb@3389
    74
    char *signature_fpr = session->sync_state.common.signature_fpr;
vb@2831
    75
vb@3389
    76
    assert(from && from->address && from->address[0] && from->user_id &&
vb@3389
    77
            from->user_id[0]);
vb@3389
    78
    if (!(from && from->address && from->address[0] && from->user_id &&
vb@3389
    79
            from->user_id[0]))
vb@2831
    80
        return PEP_ILLEGAL_VALUE;
vb@2831
    81
vb@2831
    82
    pEp_identity *me = NULL;
vb@2901
    83
    PEP_STATUS status = get_identity(session, from->address, from->user_id, &me);
vb@2831
    84
    assert(status == PEP_STATUS_OK);
vb@2831
    85
    if (status)
vb@2831
    86
        return status;
vb@2831
    87
vb@2831
    88
    assert(me->fpr && me->fpr[0]);
vb@2831
    89
    if (!(me->fpr && me->fpr[0])) {
vb@2831
    90
        free_identity(me);
vb@2831
    91
        return PEP_ILLEGAL_VALUE;
vb@2831
    92
    }
vb@2831
    93
vb@3389
    94
    size_t len = MIN(strlen(signature_fpr), strlen(me->fpr));
vb@3389
    95
    *result = strncasecmp(signature_fpr, me->fpr, len) > 0;
vb@2831
    96
    free_identity(me);
vb@2831
    97
||
vb@2831
    98
vb@2831
    99
// action: PEP_STATUS «@name»(PEP_SESSION session)
vb@2831
   100
vb@2831
   101
function "new_UUID" {
vb@2831
   102
    param "dst";
vb@2831
   103
    ||
vb@2831
   104
        pEpUUID c;
vb@2831
   105
        uuid_generate_random(c);
vb@2831
   106
vb@2831
   107
        OCTET_STRING_fromBuf(«$dst», (char *) c, 16);
vb@2831
   108
    ||
vb@2831
   109
}
vb@2831
   110
vb@2831
   111
function "copy_UUID" {
vb@2831
   112
    param "src", param "dst";
vb@2831
   113
    ||
vb@3605
   114
        {
vb@3605
   115
            TID_t *src = «$src»;
vb@3605
   116
            TID_t *dst = «$dst»;
vb@2831
   117
vb@3605
   118
            assert(src->size == 16);
vb@3605
   119
            if (!(src->size == 16))
vb@3605
   120
                return PEP_UNKNOWN_ERROR;
vb@2831
   121
vb@3605
   122
            OCTET_STRING_fromBuf(dst, (char *) src->buf, src->size);
vb@3605
   123
        }
vb@3605
   124
    ||
vb@3605
   125
}
vb@3605
   126
vb@3605
   127
function "xor_UUID" {
vb@3605
   128
    param "src", param "dst";
vb@3605
   129
    ||
vb@3605
   130
        {
vb@3605
   131
            TID_t *src = «$src»;
vb@3605
   132
            TID_t *dst = «$dst»;
vb@3605
   133
vb@3605
   134
            assert(src->size == 16 && dst->size == 16);
vb@3605
   135
            if (!(src->size == 16 && dst->size == 16))
vb@3605
   136
                return PEP_UNKNOWN_ERROR;
vb@3605
   137
vb@3605
   138
            for (int i=0; i < src->size; ++i)
vb@3605
   139
                dst->buf[i] ^= src->buf[i];
vb@3605
   140
        }
vb@2831
   141
    ||
vb@2831
   142
}
vb@2831
   143
vb@3601
   144
action newChallenge {
vb@3601
   145
    // random new challenge
vb@2831
   146
    call "new_UUID" with "dst" > &session->own_sync_state.challenge
vb@3601
   147
    // store a copy of this challenge
vb@3601
   148
    call "copy_UUID" {
vb@3601
   149
        with "src" > &session->own_sync_state.challenge
vb@3601
   150
        with "dst" > &session->sync_state.common.challenge
vb@3601
   151
    }
vb@3601
   152
}
vb@2831
   153
vb@3601
   154
action replyChallenge call "copy_UUID" {
vb@2831
   155
    with "src" > &session->sync_state.keysync.challenge
vb@2831
   156
    with "dst" > &session->own_sync_state.challenge
vb@2831
   157
}
vb@2831
   158
vb@3601
   159
action useOwnChallenge call "copy_UUID" {
vb@3601
   160
    with "src" > &session->sync_state.common.challenge
vb@3601
   161
    with "dst" > &session->own_sync_state.challenge
vb@3601
   162
}
vb@3601
   163
vb@3591
   164
action newTransaction {
vb@3510
   165
||
vb@3590
   166
    // sender key must be stable while transaction
vb@3591
   167
    assert(session->sync_state.common.signature_fpr);
vb@3591
   168
    free(session->own_sync_state.signature_fpr);
vb@3591
   169
    session->own_sync_state.signature_fpr
vb@3591
   170
            = strdup(session->sync_state.common.signature_fpr);
vb@3591
   171
    assert(session->own_sync_state.signature_fpr);
vb@3591
   172
    if (!session->own_sync_state.signature_fpr)
vb@3591
   173
        return PEP_OUT_OF_MEMORY;
vb@3590
   174
vb@3510
   175
||
vb@3605
   176
    call "copy_UUID" {
vb@3605
   177
        with "src" > &session->sync_state.keysync.challenge
vb@3605
   178
        with "dst" > &session->sync_state.keysync.negotiation
vb@3605
   179
    }
vb@3605
   180
    call "xor_UUID" {
vb@3605
   181
        with "src" > &session->own_sync_state.challenge
vb@3605
   182
        with "dst" > &session->sync_state.keysync.negotiation
vb@3605
   183
    }
vb@3591
   184
    call "copy_UUID" {
vb@3591
   185
        with "src" > &session->sync_state.keysync.negotiation
vb@3591
   186
        with "dst" > &session->own_sync_state.negotiation
vb@3591
   187
    }
vb@3510
   188
}
vb@3510
   189
vb@3510
   190
action closeTransaction
vb@3510
   191
||
vb@3550
   192
    memset(session->sync_state.keysync.negotiation.buf, 0,
vb@3550
   193
            session->sync_state.keysync.negotiation.size);
vb@3594
   194
    memset(session->own_sync_state.negotiation.buf, 0,
vb@3594
   195
            session->own_sync_state.negotiation.size);
vb@3510
   196
||
vb@2831
   197
vb@3591
   198
action storeTransaction {
vb@3591
   199
||
vb@3591
   200
    // sender key must be stable while transaction
vb@3591
   201
    assert(session->sync_state.common.signature_fpr);
vb@3591
   202
    free(session->own_sync_state.signature_fpr);
vb@3591
   203
    session->own_sync_state.signature_fpr
vb@3591
   204
            = strdup(session->sync_state.common.signature_fpr);
vb@3591
   205
    assert(session->own_sync_state.signature_fpr);
vb@3591
   206
    if (!session->own_sync_state.signature_fpr)
vb@3591
   207
        return PEP_OUT_OF_MEMORY;
vb@3591
   208
vb@3591
   209
||
vb@3591
   210
    call "copy_UUID" {
vb@3591
   211
        with "src" > &session->sync_state.keysync.negotiation
vb@3591
   212
        with "dst" > &session->own_sync_state.negotiation
vb@3591
   213
    }
vb@2831
   214
}
vb@2831
   215
vb@2831
   216
function "show_handshake" {
vb@2831
   217
    param "type";
vb@2831
   218
    ||
vb@2831
   219
        assert(session->notifyHandshake);
vb@2831
   220
        if (!session->notifyHandshake)
vb@2831
   221
            return PEP_SYNC_NO_NOTIFY_CALLBACK;
vb@2831
   222
     
vb@3525
   223
    ||
vb@3525
   224
    choose {
vb@3525
   225
    when "$type = 'SYNC_NOTIFY_TIMEOUT' or $type = 'SYNC_NOTIFY_SOLE' or $type = 'SYNC_NOTIFY_IN_GROUP'"
vb@3525
   226
    ||
vb@3525
   227
        pEp_identity *me = new_identity(NULL, NULL, NULL, NULL);
vb@3525
   228
        pEp_identity *partner = new_identity(NULL, NULL, NULL, NULL);
vb@3525
   229
        assert(me && partner);
vb@3525
   230
        if (!(me && partner)) {
vb@3525
   231
            free_identity(me);
vb@3525
   232
            free_identity(partner);
vb@3525
   233
            return PEP_OUT_OF_MEMORY;
vb@3525
   234
        }
vb@3525
   235
vb@3525
   236
        PEP_STATUS status = session->notifyHandshake(me, partner, «$type»);
vb@3525
   237
        if (status)
vb@3525
   238
            return status;
vb@3525
   239
    ||
vb@3525
   240
    otherwise
vb@3525
   241
    ||
vb@2838
   242
        assert(session->sync_state.common.from);
vb@2838
   243
        if (!session->sync_state.common.from)
vb@2831
   244
            return PEP_ILLEGAL_VALUE;
vb@2831
   245
vb@2838
   246
        pEp_identity *from = session->sync_state.common.from;
vb@2831
   247
        pEp_identity *me = NULL;
vb@2901
   248
        PEP_STATUS status = get_identity(session, from->address, from->user_id, &me);
vb@2831
   249
        assert(status == PEP_STATUS_OK);
vb@2831
   250
        if (status)
vb@2831
   251
            return status;
vb@2831
   252
vb@2831
   253
        assert(me->fpr && me->fpr[0]);
vb@2831
   254
        if (!(me->fpr && me->fpr[0])) {
vb@2831
   255
            free_identity(me);
vb@2831
   256
            return PEP_ILLEGAL_VALUE;
vb@2831
   257
        }
vb@2831
   258
vb@2831
   259
        pEp_identity *partner = identity_dup(from);
vb@2831
   260
        if (!partner) {
vb@2831
   261
            free_identity(me);
vb@2831
   262
            return PEP_OUT_OF_MEMORY;
vb@2831
   263
        }
vb@3365
   264
vb@3379
   265
        assert(session->sync_state.common.signature_fpr);
vb@3379
   266
        if (session->sync_state.common.signature_fpr) {
vb@3379
   267
            free(partner->fpr);
vb@3379
   268
            partner->fpr = strdup(session->sync_state.common.signature_fpr);
vb@3379
   269
            if (!partner->fpr) {
vb@3379
   270
                free_identity(me);
vb@3379
   271
                free_identity(partner);
vb@3379
   272
                return PEP_OUT_OF_MEMORY;
vb@3379
   273
            }
vb@3364
   274
        }
vb@2831
   275
vb@3047
   276
        status = session->notifyHandshake(me, partner, «$type»);
vb@2831
   277
        if (status)
vb@2831
   278
            return status;
vb@2831
   279
    ||
vb@3525
   280
    }
vb@2831
   281
}
vb@2831
   282
vb@2831
   283
action showSoleHandshake
vb@2831
   284
    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_FORM_GROUP
vb@2831
   285
vb@2831
   286
action showJoinGroupHandshake
vb@2831
   287
    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OUR_DEVICE
vb@2831
   288
vb@2831
   289
action showGroupedHandshake
vb@2831
   290
    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE
vb@2831
   291
vb@3522
   292
action hideHandshakeDialog
vb@3522
   293
    call "show_handshake" with "type" > SYNC_NOTIFY_OVERTAKEN
vb@3522
   294
vb@3524
   295
action showDeviceAdded
vb@3524
   296
    call "show_handshake" with "type" > SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED
vb@3524
   297
vb@3524
   298
action showGroupCreated
vb@3524
   299
    call "show_handshake" with "type" > SYNC_NOTIFY_ACCEPTED_GROUP_CREATED
vb@3524
   300
vb@3525
   301
action showBeingSole
vb@3525
   302
    call "show_handshake" with "type" > SYNC_NOTIFY_SOLE
vb@3525
   303
vb@3525
   304
action showBeingInGroup
vb@3525
   305
    call "show_handshake" with "type" > SYNC_NOTIFY_IN_GROUP
vb@3525
   306
vb@2914
   307
timeout KeySync
vb@2913
   308
    call "show_handshake" with "type" > SYNC_NOTIFY_TIMEOUT
vb@2913
   309
vb@3390
   310
action prepareOwnKeys
vb@3390
   311
||
vb@3390
   312
    stringlist_t *own_keys;
krista@3583
   313
    PEP_STATUS status = _own_keys_retrieve(session, &own_keys, PEP_idf_not_for_sync, true);
vb@3390
   314
    if (status)
vb@3390
   315
        return status;
vb@3390
   316
vb@3594
   317
    if (session->own_sync_state.own_keys)
vb@3594
   318
        free_stringlist(session->own_sync_state.own_keys);
vb@3594
   319
    session->own_sync_state.own_keys = own_keys;
vb@3394
   320
vb@3394
   321
    identity_list *il;
vb@3394
   322
    status = _own_identities_retrieve(session, &il, PEP_idf_not_for_sync);
vb@3394
   323
    if (status)
vb@3394
   324
        return status;
vb@3394
   325
vb@3394
   326
    IdentityList_from_identity_list(il, &session->sync_state.keysync.ownIdentities);
vb@3609
   327
    free_identity_list(il);
vb@3390
   328
||
vb@3390
   329
vb@2831
   330
action saveGroupKeys
vb@2831
   331
||
vb@3390
   332
    identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.ownIdentities, NULL);
vb@2831
   333
    if (!il)
vb@2831
   334
        return PEP_OUT_OF_MEMORY;
vb@2831
   335
    
vb@2831
   336
    // BUG: this should be a transaction and been rolled back completely on error
vb@2831
   337
    for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
vb@2831
   338
        PEP_STATUS status = set_identity(session, _il->ident);
vb@2831
   339
        if (status) {
vb@2831
   340
            free_identity_list(il);
vb@2831
   341
            return status;
vb@2831
   342
        }
vb@2831
   343
    }
vb@2831
   344
vb@2831
   345
    free_identity_list(il);
vb@2831
   346
||
vb@2831
   347
vb@3434
   348
action ownKeysAreGroupKeys
vb@3434
   349
||
vb@3434
   350
    PEP_STATUS status = PEP_STATUS_OK;
vb@3434
   351
vb@3434
   352
    // set flag for current keys
vb@3594
   353
    for (identity_list *il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
vb@3434
   354
        if (!(il->ident->flags && PEP_idf_not_for_sync)) {
vb@3434
   355
            status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
vb@3434
   356
            if (status)
vb@3434
   357
                return status;
vb@3434
   358
        }
vb@2831
   359
    }
vb@3434
   360
||
vb@2831
   361
vb@3525
   362
action receivedKeysAreGroupKeys
vb@3525
   363
||
vb@3525
   364
    PEP_STATUS status = PEP_STATUS_OK;
vb@3527
   365
vb@3527
   366
    // set flag for current keys
vb@3594
   367
    for (identity_list *il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
vb@3527
   368
        if (!(il->ident->flags && PEP_idf_not_for_sync)) {
vb@3527
   369
            status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
vb@3527
   370
            if (status)
vb@3527
   371
                return status;
vb@3527
   372
        }
vb@3527
   373
    }
vb@3527
   374
vb@3525
   375
    identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.ownIdentities, NULL);
vb@3525
   376
    if (!il)
vb@3525
   377
        return PEP_OUT_OF_MEMORY;
vb@3525
   378
vb@3594
   379
    for (il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
vb@3525
   380
        // replace partner's user_id with own user_id
vb@3525
   381
        free(il->ident->user_id);
vb@3525
   382
        il->ident->user_id = strdup(session->sync_state.common.from->user_id);
vb@3525
   383
        if (!il->ident->user_id) {
vb@3525
   384
            free_identity_list(il);
vb@3525
   385
            return PEP_OUT_OF_MEMORY;
vb@3525
   386
        }
vb@3525
   387
vb@3525
   388
        status = myself(session, il->ident);
vb@3525
   389
        if (status) {
vb@3525
   390
            free_identity_list(il);
vb@3525
   391
            return status;
vb@3525
   392
        }
vb@3525
   393
vb@3525
   394
        status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
vb@3525
   395
        if (status) {
vb@3525
   396
            free_identity_list(il);
vb@3525
   397
            return status;
vb@3525
   398
        }
vb@3525
   399
    }
vb@3525
   400
vb@3525
   401
    free_identity_list(il);
vb@3525
   402
||
vb@3406
   403
vb@3516
   404
action trustThisKey
vb@3516
   405
||
vb@3516
   406
    assert(session->sync_state.common.from && session->sync_state.common.signature_fpr);
vb@3516
   407
    if (!(session->sync_state.common.from && session->sync_state.common.signature_fpr))
vb@3516
   408
        return PEP_ILLEGAL_VALUE;
vb@3516
   409
vb@3516
   410
    pEp_identity *ident = session->sync_state.common.from;
vb@3516
   411
    free(ident->fpr);
vb@3516
   412
    ident->fpr = strdup(session->sync_state.common.signature_fpr);
vb@3516
   413
    assert(ident->fpr);
vb@3516
   414
    if (!ident->fpr)
vb@3516
   415
        return PEP_OUT_OF_MEMORY;
vb@3516
   416
vb@3516
   417
    PEP_STATUS status = trust_own_key(session, ident);
vb@3516
   418
    if (status)
vb@3516
   419
        return status;
vb@3523
   420
vb@3523
   421
    OCTET_STRING_fromBuf(&session->sync_state.keysync.key, ident->fpr, strlen(ident->fpr));
vb@3516
   422
||
vb@3516
   423
vb@3524
   424
action untrustThisKey
vb@3524
   425
||
vb@3524
   426
    assert(session->sync_state.common.from && session->sync_state.common.signature_fpr);
vb@3524
   427
    if (!(session->sync_state.common.from && session->sync_state.common.signature_fpr))
vb@3524
   428
        return PEP_ILLEGAL_VALUE;
vb@3524
   429
vb@3524
   430
    pEp_identity *ident = session->sync_state.common.from;
vb@3524
   431
    free(ident->fpr);
vb@3524
   432
    ident->fpr = strdup(session->sync_state.common.signature_fpr);
vb@3524
   433
    assert(ident->fpr);
vb@3524
   434
    if (!ident->fpr)
vb@3524
   435
        return PEP_OUT_OF_MEMORY;
vb@3524
   436
vb@3524
   437
    PEP_STATUS status = key_reset_trust(session, ident);
vb@3524
   438
    if (status)
vb@3524
   439
        return status;
vb@3524
   440
vb@3524
   441
    OCTET_STRING_fromBuf(&session->sync_state.keysync.key, "", 0);
vb@3524
   442
||
vb@3524
   443
vb@3518
   444
action tellWeAreGrouped
vb@3518
   445
||
vb@3518
   446
    session->sync_state.keysync.is_group = true;
vb@3518
   447
||
vb@3518
   448
vb@3518
   449
action tellWeAreNotGrouped
vb@3518
   450
||
vb@3518
   451
    session->sync_state.keysync.is_group = false;
vb@3518
   452
||
vb@3518
   453
vb@2831
   454
action disable;
vb@2831
   455