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