1 // This file is under GNU General Public License 3.0
4 // generate conditions and actions
6 // Copyleft (c) 2017-2019, p≡p foundation
8 // Written by Volker Birk
11 include ./sql_func.yml2
13 // condition: PEP_STATUS «@name»(PEP_SESSION session, bool *result)
15 condition deviceGrouped {
16 call "exec_sql_int" with "sql"
17 > "select count(*) from identity where is_own = 1 and (flags & 0x100) = 0x100;"
18 |> *result = _result > 0;
23 TID_t *t1 = &session->sync_state.keysync.challenge;
24 TID_t *t2 = &session->own_sync_state.challenge;
26 *result = _TID_greater(t1, t2);
29 condition partnerIsGrouped
30 |> *result = session->sync_state.keysync.is_group;
32 condition challengeAccepted
34 TID_t *t1 = &session->sync_state.keysync.challenge;
35 TID_t *t2 = &session->own_sync_state.challenge;
37 *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
40 condition sameChallenge
42 TID_t *t1 = &session->sync_state.keysync.challenge;
43 TID_t *t2 = &session->own_sync_state.challenge;
45 *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
48 condition sameTransaction
50 TID_t *t1 = &session->sync_state.keysync.negotiation;
51 TID_t *t2 = &session->own_sync_state.negotiation;
53 // test if TID is identical
54 *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
57 condition sameTransactionAndPartner
59 TID_t *t1 = &session->sync_state.keysync.negotiation;
60 TID_t *t2 = &session->own_sync_state.negotiation;
62 const char *s1 = session->sync_state.common.signature_fpr;
63 const char *s2 = session->own_sync_state.signature_fpr;
65 // test if TID is identical
66 *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0
67 // and test if we're talking to the same sender
68 && s1 && s2 && strcmp(s1, s2) == 0;
71 condition keyElectionWon
73 pEp_identity *from = session->sync_state.common.from;
74 char *signature_fpr = session->sync_state.common.signature_fpr;
76 assert(from && from->address && from->address[0] && from->user_id &&
78 if (!(from && from->address && from->address[0] && from->user_id &&
80 return PEP_ILLEGAL_VALUE;
82 pEp_identity *me = NULL;
83 PEP_STATUS status = get_identity(session, from->address, from->user_id, &me);
84 assert(status == PEP_STATUS_OK);
88 assert(me->fpr && me->fpr[0]);
89 if (!(me->fpr && me->fpr[0])) {
91 return PEP_ILLEGAL_VALUE;
94 size_t len = MIN(strlen(signature_fpr), strlen(me->fpr));
95 *result = strncasecmp(signature_fpr, me->fpr, len) > 0;
99 // action: PEP_STATUS «@name»(PEP_SESSION session)
101 function "new_UUID" {
105 uuid_generate_random(c);
107 OCTET_STRING_fromBuf(«$dst», (char *) c, 16);
111 function "copy_UUID" {
112 param "src", param "dst";
118 assert(src->size == 16);
119 if (!(src->size == 16))
120 return PEP_UNKNOWN_ERROR;
122 OCTET_STRING_fromBuf(dst, (char *) src->buf, src->size);
127 function "xor_UUID" {
128 param "src", param "dst";
134 assert(src->size == 16 && dst->size == 16);
135 if (!(src->size == 16 && dst->size == 16))
136 return PEP_UNKNOWN_ERROR;
138 for (int i=0; i < src->size; ++i)
139 dst->buf[i] ^= src->buf[i];
144 action newChallenge {
145 // random new challenge
146 call "new_UUID" with "dst" > &session->own_sync_state.challenge
147 // store a copy of this challenge
149 with "src" > &session->own_sync_state.challenge
150 with "dst" > &session->sync_state.common.challenge
154 action replyChallenge call "copy_UUID" {
155 with "src" > &session->sync_state.keysync.challenge
156 with "dst" > &session->own_sync_state.challenge
159 action useOwnChallenge call "copy_UUID" {
160 with "src" > &session->sync_state.common.challenge
161 with "dst" > &session->own_sync_state.challenge
164 action newTransaction {
166 // sender key must be stable while transaction
167 assert(session->sync_state.common.signature_fpr);
168 free(session->own_sync_state.signature_fpr);
169 session->own_sync_state.signature_fpr
170 = strdup(session->sync_state.common.signature_fpr);
171 assert(session->own_sync_state.signature_fpr);
172 if (!session->own_sync_state.signature_fpr)
173 return PEP_OUT_OF_MEMORY;
177 with "src" > &session->sync_state.keysync.challenge
178 with "dst" > &session->sync_state.keysync.negotiation
181 with "src" > &session->own_sync_state.challenge
182 with "dst" > &session->sync_state.keysync.negotiation
185 with "src" > &session->sync_state.keysync.negotiation
186 with "dst" > &session->own_sync_state.negotiation
190 action closeTransaction
192 memset(session->sync_state.keysync.negotiation.buf, 0,
193 session->sync_state.keysync.negotiation.size);
194 memset(session->own_sync_state.negotiation.buf, 0,
195 session->own_sync_state.negotiation.size);
198 action storeTransaction {
200 // sender key must be stable while transaction
201 assert(session->sync_state.common.signature_fpr);
202 free(session->own_sync_state.signature_fpr);
203 session->own_sync_state.signature_fpr
204 = strdup(session->sync_state.common.signature_fpr);
205 assert(session->own_sync_state.signature_fpr);
206 if (!session->own_sync_state.signature_fpr)
207 return PEP_OUT_OF_MEMORY;
211 with "src" > &session->sync_state.keysync.negotiation
212 with "dst" > &session->own_sync_state.negotiation
216 function "show_handshake" {
219 assert(session->notifyHandshake);
220 if (!session->notifyHandshake)
221 return PEP_SYNC_NO_NOTIFY_CALLBACK;
225 when "$type = 'SYNC_NOTIFY_TIMEOUT' or $type = 'SYNC_NOTIFY_SOLE' or $type = 'SYNC_NOTIFY_IN_GROUP'"
227 pEp_identity *me = new_identity(NULL, NULL, NULL, NULL);
228 pEp_identity *partner = new_identity(NULL, NULL, NULL, NULL);
229 assert(me && partner);
230 if (!(me && partner)) {
232 free_identity(partner);
233 return PEP_OUT_OF_MEMORY;
236 PEP_STATUS status = session->notifyHandshake(me, partner, «$type»);
242 assert(session->sync_state.common.from);
243 if (!session->sync_state.common.from)
244 return PEP_ILLEGAL_VALUE;
246 pEp_identity *from = session->sync_state.common.from;
247 pEp_identity *me = NULL;
248 PEP_STATUS status = get_identity(session, from->address, from->user_id, &me);
249 assert(status == PEP_STATUS_OK);
253 assert(me->fpr && me->fpr[0]);
254 if (!(me->fpr && me->fpr[0])) {
256 return PEP_ILLEGAL_VALUE;
259 pEp_identity *partner = identity_dup(from);
262 return PEP_OUT_OF_MEMORY;
265 assert(session->sync_state.common.signature_fpr);
266 if (session->sync_state.common.signature_fpr) {
268 partner->fpr = strdup(session->sync_state.common.signature_fpr);
271 free_identity(partner);
272 return PEP_OUT_OF_MEMORY;
276 status = session->notifyHandshake(me, partner, «$type»);
283 action showSoleHandshake
284 call "show_handshake" with "type" > SYNC_NOTIFY_INIT_FORM_GROUP
286 action showJoinGroupHandshake
287 call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OUR_DEVICE
289 action showGroupedHandshake
290 call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE
292 action hideHandshakeDialog
293 call "show_handshake" with "type" > SYNC_NOTIFY_OVERTAKEN
295 action showDeviceAdded
296 call "show_handshake" with "type" > SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED
298 action showGroupCreated
299 call "show_handshake" with "type" > SYNC_NOTIFY_ACCEPTED_GROUP_CREATED
302 call "show_handshake" with "type" > SYNC_NOTIFY_SOLE
304 action showBeingInGroup
305 call "show_handshake" with "type" > SYNC_NOTIFY_IN_GROUP
308 call "show_handshake" with "type" > SYNC_NOTIFY_TIMEOUT
310 action prepareOwnKeys
312 stringlist_t *own_keys;
313 PEP_STATUS status = _own_keys_retrieve(session, &own_keys, PEP_idf_not_for_sync, true);
317 if (session->own_sync_state.own_keys)
318 free_stringlist(session->own_sync_state.own_keys);
319 session->own_sync_state.own_keys = own_keys;
322 status = _own_identities_retrieve(session, &il, PEP_idf_not_for_sync);
326 IdentityList_from_identity_list(il, &session->sync_state.keysync.ownIdentities);
327 free_identity_list(il);
332 identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.ownIdentities, NULL);
334 return PEP_OUT_OF_MEMORY;
336 // BUG: this should be a transaction and been rolled back completely on error
337 for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
338 PEP_STATUS status = set_identity(session, _il->ident);
340 free_identity_list(il);
345 free_identity_list(il);
348 action ownKeysAreGroupKeys
350 PEP_STATUS status = PEP_STATUS_OK;
352 // set flag for current keys
353 for (identity_list *il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
354 if (!(il->ident->flags && PEP_idf_not_for_sync)) {
355 status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
362 action receivedKeysAreGroupKeys
364 PEP_STATUS status = PEP_STATUS_OK;
366 // set flag for current keys
367 for (identity_list *il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
368 if (!(il->ident->flags && PEP_idf_not_for_sync)) {
369 status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
375 identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.ownIdentities, NULL);
377 return PEP_OUT_OF_MEMORY;
379 for (il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
380 // replace partner's user_id with own user_id
381 free(il->ident->user_id);
382 il->ident->user_id = strdup(session->sync_state.common.from->user_id);
383 if (!il->ident->user_id) {
384 free_identity_list(il);
385 return PEP_OUT_OF_MEMORY;
388 status = myself(session, il->ident);
390 free_identity_list(il);
394 status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
396 free_identity_list(il);
401 free_identity_list(il);
406 assert(session->sync_state.common.from && session->sync_state.common.signature_fpr);
407 if (!(session->sync_state.common.from && session->sync_state.common.signature_fpr))
408 return PEP_ILLEGAL_VALUE;
410 pEp_identity *ident = session->sync_state.common.from;
412 ident->fpr = strdup(session->sync_state.common.signature_fpr);
415 return PEP_OUT_OF_MEMORY;
417 PEP_STATUS status = trust_own_key(session, ident);
421 OCTET_STRING_fromBuf(&session->sync_state.keysync.key, ident->fpr, strlen(ident->fpr));
424 action untrustThisKey
426 assert(session->sync_state.common.from && session->sync_state.common.signature_fpr);
427 if (!(session->sync_state.common.from && session->sync_state.common.signature_fpr))
428 return PEP_ILLEGAL_VALUE;
430 pEp_identity *ident = session->sync_state.common.from;
432 ident->fpr = strdup(session->sync_state.common.signature_fpr);
435 return PEP_OUT_OF_MEMORY;
437 PEP_STATUS status = key_reset_trust(session, ident);
441 OCTET_STRING_fromBuf(&session->sync_state.keysync.key, "", 0);
444 action tellWeAreGrouped
446 session->sync_state.keysync.is_group = true;
449 action tellWeAreNotGrouped
451 session->sync_state.keysync.is_group = false;