sync/cond_act_sync.yml2
author Volker Birk <vb@pep.foundation>
Wed, 29 Aug 2018 21:55:04 +0200
branchsync
changeset 2905 1856a40d0cb5
parent 2902 5692b0768f9e
child 2907 92f22b19b09e
permissions -rw-r--r--
...
     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, 2018, 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 = true 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 weAreSecond
    30 ||
    31     TID_t *t1 = &session->sync_state.keysync.challenge;
    32     TID_t *t2 = &session->own_sync_state.challenge;
    33 
    34     *result = !_TID_greater(t1, t2);
    35 ||
    36 
    37 condition partnerIsGrouped
    38 |> *result = session->sync_state.keysync.is_group;
    39 
    40 condition challengeAccepted
    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 keyElectionWon
    49 ||
    50     pEp_identity *from = session->sync_state.common.from;
    51 
    52     assert(from && from->fpr && from->fpr[0] && from->address &&
    53             from->address[0] && from->user_id && from->user_id[0]);
    54     if (!(from && from->fpr && from->fpr[0] && from->address &&
    55             from->address[0] && from->user_id && from->user_id[0]))
    56         return PEP_ILLEGAL_VALUE;
    57 
    58     pEp_identity *me = NULL;
    59     PEP_STATUS status = get_identity(session, from->address, from->user_id, &me);
    60     assert(status == PEP_STATUS_OK);
    61     if (status)
    62         return status;
    63 
    64     assert(me->fpr && me->fpr[0]);
    65     if (!(me->fpr && me->fpr[0])) {
    66         free_identity(me);
    67         return PEP_ILLEGAL_VALUE;
    68     }
    69 
    70     size_t len = MIN(strlen(from->fpr), strlen(me->fpr));
    71     *result = strncasecmp(from->fpr, me->fpr, len) > 0;
    72     free_identity(me);
    73 ||
    74 
    75 // action: PEP_STATUS «@name»(PEP_SESSION session)
    76 
    77 function "new_UUID" {
    78     param "dst";
    79     ||
    80         pEpUUID c;
    81         uuid_generate_random(c);
    82 
    83         OCTET_STRING_fromBuf(«$dst», (char *) c, 16);
    84     ||
    85 }
    86 
    87 function "copy_UUID" {
    88     param "src", param "dst";
    89     ||
    90         TID_t *src = «$src»;
    91         TID_t *dst = «$dst»;
    92 
    93         assert(src->size == 16);
    94         if (!(src->size == 16))
    95             return PEP_UNKNOWN_ERROR;
    96 
    97         OCTET_STRING_fromBuf(dst, (char *) src->buf, src->size);
    98     ||
    99 }
   100 
   101 action openChallenge
   102     call "new_UUID" with "dst" > &session->own_sync_state.challenge
   103 
   104 action storeChallenge call "copy_UUID" {
   105     with "src" > &session->sync_state.keysync.challenge
   106     with "dst" > &session->own_sync_state.challenge
   107 }
   108 
   109 action openTransaction
   110     call "new_UUID" with "dst" > &session->own_sync_state.transaction
   111 
   112 action storeTransaction call "copy_UUID" {
   113     with "src" > &session->sync_state.keysync.transaction
   114     with "dst" >  &session->own_sync_state.transaction
   115 }
   116 
   117 function "show_handshake" {
   118     param "type";
   119     ||
   120         assert(session->notifyHandshake);
   121         if (!session->notifyHandshake)
   122             return PEP_SYNC_NO_NOTIFY_CALLBACK;
   123      
   124         assert(session->sync_state.common.from);
   125         if (!session->sync_state.common.from)
   126             return PEP_ILLEGAL_VALUE;
   127 
   128         pEp_identity *from = session->sync_state.common.from;
   129         pEp_identity *me = NULL;
   130         PEP_STATUS status = get_identity(session, from->address, from->user_id, &me);
   131         assert(status == PEP_STATUS_OK);
   132         if (status)
   133             return status;
   134 
   135         assert(me->fpr && me->fpr[0]);
   136         if (!(me->fpr && me->fpr[0])) {
   137             free_identity(me);
   138             return PEP_ILLEGAL_VALUE;
   139         }
   140 
   141         pEp_identity *partner = identity_dup(from);
   142         if (!partner) {
   143             free_identity(me);
   144             return PEP_OUT_OF_MEMORY;
   145         }
   146 
   147         status = session->notifyHandshake(session->sync_management, me,
   148                 partner, «$type»);
   149         if (status)
   150             return status;
   151     ||
   152 }
   153 
   154 action showSoleHandshake
   155     call "show_handshake" with "type" > SYNC_NOTIFY_INIT_FORM_GROUP
   156 
   157 action showJoinGroupHandshake
   158     call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OUR_DEVICE
   159 
   160 action showGroupedHandshake
   161     call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE
   162 
   163 action saveGroupKeys
   164 ||
   165     identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.identities, NULL);
   166     if (!il)
   167         return PEP_OUT_OF_MEMORY;
   168     
   169     // BUG: this should be a transaction and been rolled back completely on error
   170     for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
   171         PEP_STATUS status = set_identity(session, _il->ident);
   172         if (status) {
   173             free_identity_list(il);
   174             return status;
   175         }
   176     }
   177 
   178     free_identity_list(il);
   179 ||
   180 
   181 action ownKeysAreGroupKeys {
   182     call "init_sql" with "sql" {
   183         ||
   184         "select fpr, username, comm_type, lang,"
   185                 "   identity.flags | pgp_keypair.flags"
   186                 "   from identity"
   187                 "   join person on id = identity.user_id"
   188                 "   join pgp_keypair on fpr = identity.main_key_id"
   189                 "   join trust on id = trust.user_id"
   190                 "       and pgp_keypair_fpr = identity.main_key_id"
   191                 "   where identity.is_own = true ;"
   192         ||
   193     }
   194 
   195     ||
   196         identity_list *il = new_identity_list(NULL);
   197         if (!il)
   198             return PEP_OUT_OF_MEMORY;
   199 
   200         pEp_identity *from = session->sync_state.common.from;
   201         identity_list *_il = il;
   202 
   203         int result;
   204         do {
   205             result = sqlite3_step(_sql);
   206             pEp_identity *_identity = NULL;
   207             switch (result) {
   208             case SQLITE_ROW:
   209                 _identity = new_identity(
   210                         from->address,
   211                         (const char *) sqlite3_column_text(_sql, 0),
   212                         from->user_id,
   213                         (const char *) sqlite3_column_text(_sql, 1)
   214                         );
   215                 assert(_identity);
   216                 if (_identity == NULL)
   217                     return PEP_OUT_OF_MEMORY;
   218 
   219                 _identity->comm_type = (PEP_comm_type)
   220                     sqlite3_column_int(_sql, 2);
   221                 const char* const _lang = (const char *)
   222                     sqlite3_column_text(_sql, 3);
   223                 if (_lang && _lang[0]) {
   224                     assert(_lang[0] >= 'a' && _lang[0] <= 'z');
   225                     assert(_lang[1] >= 'a' && _lang[1] <= 'z');
   226                     assert(_lang[2] == 0);
   227                     _identity->lang[0] = _lang[0];
   228                     _identity->lang[1] = _lang[1];
   229                     _identity->lang[2] = 0;
   230                 }
   231                 _identity->flags = (unsigned int)
   232                     sqlite3_column_int(_sql, 4);
   233 
   234                 _il = identity_list_add(_il, _identity);
   235                 if (!_il) {
   236                     free_identity_list(il);
   237                     free_identity(_identity);
   238                     return PEP_OUT_OF_MEMORY;
   239                 }
   240                 break;
   241 
   242             case SQLITE_DONE:
   243                 break;
   244 
   245             default:
   246                 free_identity_list(il);
   247                 return PEP_UNKNOWN_ERROR;
   248             }
   249         } while (result != SQLITE_DONE);
   250 
   251         IdentityList_t *r = IdentityList_from_identity_list(il, &session->sync_state.keysync.identities);
   252         free_identity_list(il);
   253         if (!r)
   254             return PEP_OUT_OF_MEMORY;
   255     ||
   256 }
   257 
   258 action disable;
   259