sync/cond_act_sync.yml2
author Volker Birk <vb@pep-project.org>
Sun, 14 Apr 2019 16:00:52 +0200
branchsync
changeset 3523 9555e664423f
parent 3522 c8e3e531d40a
child 3524 c87c6b4f3e08
permissions -rw-r--r--
if one in the group accepted that's valid for all
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 // generate conditions and actions
     5 
     6 // Copyleft (c) 2017-2019, p≡p foundation
     7 
     8 // Written by Volker Birk
     9 
    10 
    11 include ./sql_func.yml2
    12 
    13 // condition: PEP_STATUS «@name»(PEP_SESSION session, bool *result)
    14 
    15 condition deviceGrouped {
    16     call "exec_sql_int" with "sql"
    17         > "select count(*) from identity where is_own = 1 and (flags & 4) = 4;"
    18     |> *result = _result > 0;
    19 }
    20 
    21 condition weAreFirst
    22 ||
    23     TID_t *t1 = &session->sync_state.keysync.challenge;
    24     TID_t *t2 = &session->own_sync_state.challenge;
    25 
    26     *result = _TID_greater(t1, t2);
    27 ||
    28 
    29 condition partnerIsGrouped
    30 |> *result = session->sync_state.keysync.is_group;
    31 
    32 condition challengeAccepted
    33 ||
    34     TID_t *t1 = &session->sync_state.keysync.challenge;
    35     TID_t *t2 = &session->own_sync_state.challenge;
    36 
    37     *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
    38 ||
    39 
    40 condition sameChallenge
    41 ||
    42     TID_t *t1 = &session->sync_state.keysync.challenge;
    43     TID_t *t2 = &session->own_sync_state.challenge;
    44 
    45     *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
    46 ||
    47 
    48 condition sameTransaction
    49 ||
    50     TID_t *t1 = &session->sync_state.keysync.transaction;
    51     TID_t *t2 = &session->own_sync_state.transaction;
    52 
    53     *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
    54 ||
    55 
    56 condition keyElectionWon
    57 ||
    58     pEp_identity *from = session->sync_state.common.from;
    59     char *signature_fpr = session->sync_state.common.signature_fpr;
    60 
    61     assert(from && from->address && from->address[0] && from->user_id &&
    62             from->user_id[0]);
    63     if (!(from && from->address && from->address[0] && from->user_id &&
    64             from->user_id[0]))
    65         return PEP_ILLEGAL_VALUE;
    66 
    67     pEp_identity *me = NULL;
    68     PEP_STATUS status = get_identity(session, from->address, from->user_id, &me);
    69     assert(status == PEP_STATUS_OK);
    70     if (status)
    71         return status;
    72 
    73     assert(me->fpr && me->fpr[0]);
    74     if (!(me->fpr && me->fpr[0])) {
    75         free_identity(me);
    76         return PEP_ILLEGAL_VALUE;
    77     }
    78 
    79     size_t len = MIN(strlen(signature_fpr), strlen(me->fpr));
    80     *result = strncasecmp(signature_fpr, me->fpr, len) > 0;
    81     free_identity(me);
    82 ||
    83 
    84 // action: PEP_STATUS «@name»(PEP_SESSION session)
    85 
    86 function "new_UUID" {
    87     param "dst";
    88     ||
    89         pEpUUID c;
    90         uuid_generate_random(c);
    91 
    92         OCTET_STRING_fromBuf(«$dst», (char *) c, 16);
    93     ||
    94 }
    95 
    96 function "copy_UUID" {
    97     param "src", param "dst";
    98     ||
    99         TID_t *src = «$src»;
   100         TID_t *dst = «$dst»;
   101 
   102         assert(src->size == 16);
   103         if (!(src->size == 16))
   104             return PEP_UNKNOWN_ERROR;
   105 
   106         OCTET_STRING_fromBuf(dst, (char *) src->buf, src->size);
   107     ||
   108 }
   109 
   110 action newChallenge
   111     call "new_UUID" with "dst" > &session->own_sync_state.challenge
   112 
   113 action storeChallenge call "copy_UUID" {
   114     with "src" > &session->sync_state.keysync.challenge
   115     with "dst" > &session->own_sync_state.challenge
   116 }
   117 
   118 action openTransaction {
   119 ||
   120     for (int i=0; i<session->sync_state.keysync.transaction.size; ++i) {
   121         if (session->sync_state.keysync.transaction.buf[i])
   122             return PEP_STATUS_OK;
   123     }
   124 ||
   125     call "new_UUID" with "dst" > &session->sync_state.keysync.transaction
   126 }
   127 
   128 action closeTransaction
   129 ||
   130     memset(session->sync_state.keysync.transaction.buf, 0,
   131             session->sync_state.keysync.transaction.size);
   132 ||
   133 
   134 action storeTransaction call "copy_UUID" {
   135     with "src" > &session->sync_state.keysync.transaction
   136     with "dst" > &session->own_sync_state.transaction
   137 }
   138 
   139 function "show_handshake" {
   140     param "type";
   141     ||
   142         assert(session->notifyHandshake);
   143         if (!session->notifyHandshake)
   144             return PEP_SYNC_NO_NOTIFY_CALLBACK;
   145      
   146         assert(session->sync_state.common.from);
   147         if (!session->sync_state.common.from)
   148             return PEP_ILLEGAL_VALUE;
   149 
   150         pEp_identity *from = session->sync_state.common.from;
   151         pEp_identity *me = NULL;
   152         PEP_STATUS status = get_identity(session, from->address, from->user_id, &me);
   153         assert(status == PEP_STATUS_OK);
   154         if (status)
   155             return status;
   156 
   157         assert(me->fpr && me->fpr[0]);
   158         if (!(me->fpr && me->fpr[0])) {
   159             free_identity(me);
   160             return PEP_ILLEGAL_VALUE;
   161         }
   162 
   163         pEp_identity *partner = identity_dup(from);
   164         if (!partner) {
   165             free_identity(me);
   166             return PEP_OUT_OF_MEMORY;
   167         }
   168 
   169         assert(session->sync_state.common.signature_fpr);
   170         if (session->sync_state.common.signature_fpr) {
   171             free(partner->fpr);
   172             partner->fpr = strdup(session->sync_state.common.signature_fpr);
   173             if (!partner->fpr) {
   174                 free_identity(me);
   175                 free_identity(partner);
   176                 return PEP_OUT_OF_MEMORY;
   177             }
   178         }
   179 
   180         status = session->notifyHandshake(me, partner, «$type»);
   181         if (status)
   182             return status;
   183     ||
   184 }
   185 
   186 action showSoleHandshake
   187     call "show_handshake" with "type" > SYNC_NOTIFY_INIT_FORM_GROUP
   188 
   189 action showJoinGroupHandshake
   190     call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OUR_DEVICE
   191 
   192 action showGroupedHandshake
   193     call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE
   194 
   195 action hideHandshakeDialog
   196     call "show_handshake" with "type" > SYNC_NOTIFY_OVERTAKEN
   197 
   198 timeout KeySync
   199     call "show_handshake" with "type" > SYNC_NOTIFY_TIMEOUT
   200 
   201 action prepareOwnKeys
   202 ||
   203     stringlist_t *own_keys;
   204     PEP_STATUS status = _own_keys_retrieve(session, &own_keys, PEP_idf_not_for_sync);
   205     if (status)
   206         return status;
   207 
   208     if (session->sync_state.common.own_keys)
   209         free_stringlist(session->sync_state.common.own_keys);
   210     session->sync_state.common.own_keys = own_keys;
   211 
   212     identity_list *il;
   213     status = _own_identities_retrieve(session, &il, PEP_idf_not_for_sync);
   214     if (status)
   215         return status;
   216 
   217     IdentityList_from_identity_list(il, &session->sync_state.keysync.ownIdentities);
   218 ||
   219 
   220 action saveGroupKeys
   221 ||
   222     identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.ownIdentities, NULL);
   223     if (!il)
   224         return PEP_OUT_OF_MEMORY;
   225     
   226     // BUG: this should be a transaction and been rolled back completely on error
   227     for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
   228         PEP_STATUS status = set_identity(session, _il->ident);
   229         if (status) {
   230             free_identity_list(il);
   231             return status;
   232         }
   233     }
   234 
   235     free_identity_list(il);
   236 ||
   237 
   238 action ownKeysAreGroupKeys
   239 ||
   240     PEP_STATUS status = PEP_STATUS_OK;
   241 
   242     // set flag for current keys
   243     for (identity_list *il = session->sync_state.common.own_identities; il && il->ident ; il = il->next) {
   244         if (!(il->ident->flags && PEP_idf_not_for_sync)) {
   245             status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
   246             if (status)
   247                 return status;
   248         }
   249     }
   250 ||
   251 
   252 action receivedKeysAreGroupKeys;
   253 
   254 action trustThisKey
   255 ||
   256     assert(session->sync_state.common.from && session->sync_state.common.signature_fpr);
   257     if (!(session->sync_state.common.from && session->sync_state.common.signature_fpr))
   258         return PEP_ILLEGAL_VALUE;
   259 
   260     pEp_identity *ident = session->sync_state.common.from;
   261     free(ident->fpr);
   262     ident->fpr = strdup(session->sync_state.common.signature_fpr);
   263     assert(ident->fpr);
   264     if (!ident->fpr)
   265         return PEP_OUT_OF_MEMORY;
   266 
   267     PEP_STATUS status = trust_own_key(session, ident);
   268     if (status)
   269         return status;
   270 
   271     OCTET_STRING_fromBuf(&session->sync_state.keysync.key, ident->fpr, strlen(ident->fpr));
   272 ||
   273 
   274 action tellWeAreGrouped
   275 ||
   276     session->sync_state.keysync.is_group = true;
   277 ||
   278 
   279 action tellWeAreNotGrouped
   280 ||
   281     session->sync_state.keysync.is_group = false;
   282 ||
   283 
   284 action disable;
   285