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