Browse Source

...

generate_api
Volker Birk 4 years ago
parent
commit
dc0a6e7325
18 changed files with 137 additions and 436 deletions
  1. +0
    -1
      Makefile
  2. +6
    -1
      asn.1/Makefile
  3. +0
    -1
      src/keymanagement.c
  4. +23
    -37
      src/map_asn1.c
  5. +6
    -13
      src/message_api.c
  6. +8
    -103
      src/pEpEngine.c
  7. +2
    -2
      src/pEpEngine.h
  8. +9
    -7
      src/pEp_internal.h
  9. +1
    -0
      src/platform_unix.h
  10. +5
    -0
      src/platform_windows.h
  11. +7
    -15
      src/sync.c
  12. +23
    -203
      src/sync.h
  13. +30
    -16
      src/sync_actions.c
  14. +0
    -34
      src/sync_app.h
  15. +5
    -2
      sync/Makefile
  16. +4
    -0
      sync/fsm.yml2
  17. +3
    -0
      sync/gen_actions.ysl2
  18. +5
    -1
      sync/gen_statemachine.ysl2

+ 0
- 1
Makefile View File

@ -22,7 +22,6 @@ endif
.PHONY: all
all:
$(MAKE) -C sync
$(MAKE) -C asn.1 generate
$(MAKE) -C asn.1
$(MAKE) -C src all


+ 6
- 1
asn.1/Makefile View File

@ -24,7 +24,12 @@ Sync.c: sync.asn1 keysync.asn1 pEp.asn1
sync.asn1 keysync.asn1 pEp.asn1:
cp -f ../sync/generated/*.asn1 ../asn.1
.PHONY: clean
.PHONY: clean install uninstall
clean:
rm -f *.a *.o *.c *.h *.sample sync.asn1 keysync.asn1
install:
uninstall:

+ 0
- 1
src/keymanagement.c View File

@ -12,7 +12,6 @@
#include "pEp_internal.h"
#include "keymanagement.h"
#include "sync_fsm.h"
#include "blacklist.h"
static bool key_matches_address(PEP_SESSION session, const char* address,


+ 23
- 37
src/map_asn1.c View File

@ -23,9 +23,8 @@ Identity_t *Identity_from_Struct(
return NULL;
if (ident->address) {
result->address = OCTET_STRING_new_fromBuf(&asn_DEF_UTF8String,
ident->address, -1);
if (ident->address && !result->address)
int r = OCTET_STRING_fromBuf(&result->address, ident->address, -1);
if (r)
goto enomem;
}
@ -35,25 +34,19 @@ Identity_t *Identity_from_Struct(
}
if (ident->user_id) {
result->user_id = OCTET_STRING_new_fromBuf(&asn_DEF_UTF8String,
ident->user_id, -1);
if (ident->user_id && !result->user_id)
int r = OCTET_STRING_fromBuf(&result->user_id, ident->user_id, -1);
if (r)
goto enomem;
}
if (ident->username) {
result->username = OCTET_STRING_new_fromBuf(&asn_DEF_UTF8String,
ident->username, -1);
if (ident->username && !result->username)
int r = OCTET_STRING_fromBuf(&result->username, ident->username, -1);
if (r)
goto enomem;
}
if (ident->comm_type != PEP_ct_unknown) {
result->comm_type = malloc(sizeof(long));
assert(result->comm_type);
if (!result->comm_type)
goto enomem;
*result->comm_type = ident->comm_type;
result->comm_type = ident->comm_type;
}
if (ident->lang[0]) {
@ -91,37 +84,30 @@ pEp_identity *Identity_to_Struct(Identity_t *ident, pEp_identity *result)
if (!result)
return NULL;
if (ident->address) {
result->address = strndup((char *) ident->address->buf,
ident->address->size);
assert(result->address);
if (!result->address)
goto enomem;
}
result->address = strndup((char *) ident->address.buf,
ident->address.size);
assert(result->address);
if (!result->address)
goto enomem;
result->fpr = strndup((char *) ident->fpr.buf, ident->fpr.size);
assert(result->fpr);
if (!result->fpr)
goto enomem;
if (ident->user_id) {
result->user_id = strndup((char *) ident->user_id->buf,
ident->user_id->size);
assert(result->user_id);
if (!result->user_id)
goto enomem;
}
result->user_id = strndup((char *) ident->user_id.buf,
ident->user_id.size);
assert(result->user_id);
if (!result->user_id)
goto enomem;
if (ident->username) {
result->username = strndup((char *) ident->username->buf,
ident->username->size);
assert(result->username);
if (!result->username)
goto enomem;
}
result->username = strndup((char *) ident->username.buf,
ident->username.size);
assert(result->username);
if (!result->username)
goto enomem;
if (ident->comm_type)
result->comm_type = (PEP_comm_type) *ident->comm_type;
result->comm_type = (PEP_comm_type) ident->comm_type;
if (ident->lang.size == 2) {
result->lang[0] = ident->lang.buf[0];


+ 6
- 13
src/message_api.c View File

@ -14,13 +14,6 @@
#include <math.h>
#ifndef _MIN
#define _MIN(A, B) ((B) > (A) ? (A) : (B))
#endif
#ifndef _MAX
#define _MAX(A, B) ((B) > (A) ? (B) : (A))
#endif
// These are globals used in generating message IDs and should only be
// computed once, as they're either really constants or OS-dependent
@ -463,7 +456,7 @@ static char* message_id_prand_part(void) {
const int DESIRED_BITS = 64;
num_bits = _MIN(num_bits, DESIRED_BITS);
num_bits = MIN(num_bits, DESIRED_BITS);
int i;
@ -482,9 +475,9 @@ static char* message_id_prand_part(void) {
output_value |= temp_val;
i -= _MIN(num_bits, i);
i -= MIN(num_bits, i);
bitshift = _MIN(num_bits, i);
bitshift = MIN(num_bits, i);
output_value <<= bitshift;
bitmask = get_bitmask(bitshift);
}
@ -1322,7 +1315,7 @@ static PEP_comm_type _get_comm_type(
else if (ident->comm_type == PEP_ct_mistrusted)
return PEP_ct_mistrusted;
else
return _MIN(max_comm_type, ident->comm_type);
return MIN(max_comm_type, ident->comm_type);
}
else {
return PEP_ct_unknown;
@ -3217,7 +3210,7 @@ DYNAMIC_API PEP_STATUS _decrypt_message(
case PEP_DECRYPTED:
case PEP_DECRYPTED_AND_VERIFIED:
if (decrypt_status <= PEP_DECRYPTED_AND_VERIFIED)
decrypt_status = _MIN(decrypt_status, _decrypt_in_pieces_status);
decrypt_status = MIN(decrypt_status, _decrypt_in_pieces_status);
break;
case PEP_STATUS_OK:
break;
@ -3605,7 +3598,7 @@ DYNAMIC_API PEP_STATUS outgoing_message_rating(
*rating = PEP_rating_undefined;
}
else
*rating = _MAX(_rating(max_comm_type, PEP_rating_undefined),
*rating = MAX(_rating(max_comm_type, PEP_rating_undefined),
PEP_rating_unencrypted);
return PEP_STATUS_OK;


+ 8
- 103
src/pEpEngine.c View File

@ -379,23 +379,14 @@ static const char* sql_get_default_own_userid =
// Sequence
static const char *sql_sequence_value1 =
"insert or replace into sequences (name, value, own) "
"insert or replace into sequences (name, value) "
"values (?1, "
" (select coalesce((select value + 1 from sequences "
" where name = ?1), 1 )), "
" (select coalesce((select own or ?2 from sequences "
" where name = ?1), ?2))) ; ";
" where name = ?1), 1 ))); ";
static const char *sql_sequence_value2 =
"select value, own from sequences where name = ?1 ;";
static const char *sql_sequence_value3 =
"insert or replace into sequences (name, value, own) "
"values (?1, "
" ?2, "
" (select coalesce((select own or ?3 from sequences "
" where name = ?1), ?3))) ; ";
// Revocation tracking
static const char *sql_set_revoked =
"insert or replace into revoked_keys ("
@ -698,8 +689,7 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
// sequences
"create table if not exists sequences(\n"
" name text primary key,\n"
" value integer default 0,\n"
" own integer default 0\n"
" value integer default 0\n"
");\n"
"create table if not exists revoked_keys (\n"
" revoked_fpr text primary key,\n"
@ -774,9 +764,6 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
else if (table_contains_column(_session, "identity", "is_own") > 0) {
version = 6;
}
else if (table_contains_column(_session, "sequences", "own") > 0) {
version = 3;
}
else if (table_contains_column(_session, "pgp_keypair", "flags") > 0) {
version = 2;
}
@ -842,18 +829,6 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
assert(int_result == SQLITE_OK);
}
if (version < 3) {
int_result = sqlite3_exec(
_session->db,
"alter table sequences\n"
" add column own integer default 0;\n",
NULL,
NULL,
NULL
);
assert(int_result == SQLITE_OK);
}
if (version < 5) {
int_result = sqlite3_exec(
_session->db,
@ -1267,11 +1242,6 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value3,
(int)strlen(sql_sequence_value3), &_session->sequence_value3,
NULL);
assert(int_result == SQLITE_OK);
// Revocation tracking
int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
@ -1464,8 +1434,6 @@ DYNAMIC_API void release(PEP_SESSION session)
sqlite3_finalize(session->sequence_value1);
if (session->sequence_value2)
sqlite3_finalize(session->sequence_value2);
if (session->sequence_value3)
sqlite3_finalize(session->sequence_value3);
if (session->set_revoked)
sqlite3_finalize(session->set_revoked);
if (session->get_revoked)
@ -3637,7 +3605,7 @@ static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
}
static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
const char *name, int own)
const char *name)
{
assert(session && name);
if (!(session && name))
@ -3645,7 +3613,6 @@ static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
sqlite3_reset(session->sequence_value1);
sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
sqlite3_bind_int(session->sequence_value1, 2, own);
int result = sqlite3_step(session->sequence_value1);
assert(result == SQLITE_DONE);
sqlite3_reset(session->sequence_value1);
@ -3655,26 +3622,6 @@ static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
return PEP_CANNOT_INCREASE_SEQUENCE;
}
static PEP_STATUS _set_sequence_value(PEP_SESSION session,
const char *name, int32_t value, int own)
{
assert(session && name && value > 0);
if (!(session && name && value > 0))
return PEP_ILLEGAL_VALUE;
sqlite3_reset(session->sequence_value3);
sqlite3_bind_text(session->sequence_value3, 1, name, -1, SQLITE_STATIC);
sqlite3_bind_int(session->sequence_value3, 2, value);
sqlite3_bind_int(session->sequence_value3, 3, own);
int result = sqlite3_step(session->sequence_value3);
assert(result == SQLITE_DONE);
sqlite3_reset(session->sequence_value3);
if (result == SQLITE_DONE)
return PEP_STATUS_OK;
else
return PEP_CANNOT_SET_SEQUENCE_VALUE;
}
DYNAMIC_API PEP_STATUS sequence_value(
PEP_SESSION session,
char *name,
@ -3685,56 +3632,14 @@ DYNAMIC_API PEP_STATUS sequence_value(
int result;
assert(session);
assert(name && value && *value >= 0);
assert(name && value);
if (!(session && name && value && *value >= 0))
if (!(session && name && name[0] && value))
return PEP_ILLEGAL_VALUE;
int own = 0;
if (!name[0]) {
pEpUUID uuid;
uuid_generate_random(uuid);
uuid_unparse_upper(uuid, name);
own = 1;
}
else {
if (name == session->sync_session->sync_uuid ||
strcmp(name, session->sync_session->sync_uuid) == 0)
own = 1;
}
if (*value) {
sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
int32_t old_value = 0;
status = _get_sequence_value(session, name, &old_value);
if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
{
sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
return status;
}
if (old_value >= *value) {
sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
return PEP_SEQUENCE_VIOLATED;
}
else {
status = _set_sequence_value(session, name, *value, own);
if (status == PEP_STATUS_OK) {
result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
if (result == SQLITE_OK)
return PEP_STATUS_OK;
else
return PEP_COMMIT_FAILED;
} else {
sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
return status;
}
}
}
assert(*value == 0);
*value = 0;
sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
status = _increment_sequence_value(session, name, own);
status = _increment_sequence_value(session, name);
if (status == PEP_STATUS_OK) {
status = _get_sequence_value(session, name, value);
}


+ 2
- 2
src/pEpEngine.h View File

@ -97,8 +97,8 @@ typedef enum {
PEP_CANNOT_SET_SEQUENCE_VALUE = 0x0972,
PEP_OWN_SEQUENCE = 0x097f,
PEP_SYNC_STATEMACHINE_ERROR = 0x0980,
PEP_SYNC_NO_TRUST = 0x0981,
PEP_STATEMACHINE_ERROR = 0x0980,
PEP_NO_TRUST = 0x0981,
PEP_STATEMACHINE_INVALID_STATE = 0x0982,
PEP_STATEMACHINE_INVALID_EVENT = 0x0983,
PEP_STATEMACHINE_INVALID_CONDITION = 0x0984,


+ 9
- 7
src/pEp_internal.h View File

@ -107,6 +107,7 @@
#include "cryptotech.h"
#include "transport.h"
#include "sync.h"
#include "Sync_func.h"
#define NOT_IMPLEMENTED assert(0); return PEP_UNKNOWN_ERROR;
@ -182,7 +183,6 @@ struct _pEpSession {
// sequence value
sqlite3_stmt *sequence_value1;
sqlite3_stmt *sequence_value2;
sqlite3_stmt *sequence_value3;
// revoked keys
sqlite3_stmt *set_revoked;
@ -207,13 +207,15 @@ struct _pEpSession {
inject_sync_msg_t inject_sync_msg;
retrieve_next_sync_msg_t retrieve_next_sync_msg;
// key sync
// pEp Sync
pEpSession* sync_session;
DeviceState_state sync_state;
void* sync_state_payload;
char sync_uuid[37];
time_t LastCannotDecrypt;
time_t LastUpdateRequest;
struct Sync_state_s sync_state;
struct own_Sync_state_s own_sync_state;
// void* sync_state_payload;
// char sync_uuid[37];
// time_t LastCannotDecrypt;
// time_t LastUpdateRequest;
// runtime config


+ 1
- 0
src/platform_unix.h View File

@ -9,6 +9,7 @@
#include <unistd.h>
#include <strings.h>
#include <sys/select.h>
#include <sys/param.h>
#include <regex.h>
#ifndef ANDROID


+ 5
- 0
src/platform_windows.h View File

@ -30,6 +30,11 @@ extern "C" {
#define RTLD_LAZY 1
#define mode_t int
#ifndef MIN
#define MIN(A, B) ((A)>(B) ? (B) : (A))
#define MAX(A, B) ((A)>(B) ? (A) : (B))
#endif
void *dlopen(const char *filename, int flag);
int dlclose(void *handle);
void *dlsym(void *handle, const char *symbol);


+ 7
- 15
src/sync.c View File

@ -7,7 +7,7 @@
#include <assert.h>
#include "asn1_helper.h"
#include "../asn.1/DeviceGroup-Protocol.h"
#include "KeySync_fsm.h"
// receive_sync_msg is defined in the sync_impl
@ -30,10 +30,6 @@ DYNAMIC_API PEP_STATUS register_sync_callbacks(
if (!(session && management && messageToSend && notifyHandshake && inject_sync_msg && retrieve_next_sync_msg))
return PEP_ILLEGAL_VALUE;
pEpUUID uuid;
uuid_generate_random(uuid);
uuid_unparse_upper(uuid, session->sync_uuid);
session->sync_management = management;
session->messageToSend = messageToSend;
session->notifyHandshake = notifyHandshake;
@ -41,9 +37,7 @@ DYNAMIC_API PEP_STATUS register_sync_callbacks(
session->retrieve_next_sync_msg = retrieve_next_sync_msg;
// start state machine
session->sync_state = InitState;
time_t unused = 0;
PEP_STATUS status = fsm_DeviceState_inject(session, Init, NULL, NULL, &unused);
PEP_STATUS status = inject_Sync_event(session, Sync_PR_keysync, Init);
if (status != PEP_STATUS_OK)
unregister_sync_callbacks(session);
@ -95,7 +89,7 @@ int call_inject_sync_msg(PEP_SESSION session, void *msg)
DYNAMIC_API void unregister_sync_callbacks(PEP_SESSION session) {
// stop state machine
session->sync_state = DeviceState_state_NONE;
memset(&session->sync_state, 0, sizeof(session->sync_state));
// unregister
session->sync_management = NULL;
@ -107,7 +101,7 @@ DYNAMIC_API void unregister_sync_callbacks(PEP_SESSION session) {
DYNAMIC_API PEP_STATUS deliverHandshakeResult(
PEP_SESSION session,
Identity partner,
pEp_identity *partner,
sync_handshake_result result
)
{
@ -117,7 +111,7 @@ DYNAMIC_API PEP_STATUS deliverHandshakeResult(
PEP_STATUS status = PEP_STATUS_OK;
DeviceState_event event;
int event;
bool need_partner = false;
switch (result) {
@ -126,14 +120,12 @@ DYNAMIC_API PEP_STATUS deliverHandshakeResult(
break;
case SYNC_HANDSHAKE_ACCEPTED:
{
event = HandshakeAccepted;
need_partner = true;
event = Accept;
break;
}
case SYNC_HANDSHAKE_REJECTED:
{
event = HandshakeRejected;
need_partner = true;
event = Reject;
break;
}
default:


+ 23
- 203
src/sync.h View File

@ -1,217 +1,37 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
/*
====================================
Engine/adapter/app KeySync interface
====================================
Engine | Adapter | App
| |
. . . . . . . . . . . .|. . . . . . . . . . . . . . .|. . Attached session .
,---------, | |
,-| decrypt |<--------------------------------------- Incomming message
| | message | | |
| '---------' | |
| ,----------, | |
|-| myself |<-------------------------------------- Create new account
| | (keygen) | | |
| '----------' | |
| ,-----------, | |
|-| deliver |<------------------------------------------- Accept/reject
| | handshake | | KeySync | handshake
| | result | | Message |
| '-----------' | Queue |
| | ,---, |
'-----------------------inject_sync_msg---->| | |
. . . . . . . . . . . .|. . . . . . . . . . . |---| .|. . . . Sync session .
* * * * * * * * * * * * * * * *| |* |
| |---| |
* ,------------------retrieve_next_sync_msg-| |* |
,-v--------, | '---' |
* | Driver | | * |
'----------' | |
* ||'-event-----, | * |
|'--partner--,| | |
* '---extra---,|| | SYNC THREAD *<-------------- Start Sync
,---vvv---, | |
* ,----| FSM | | * |
| '---------' | |
* | ,-------, | * |
'->|actions|---------messageToSend-------------------> Send mail to self
* '-------' | * |
'-------------notifyHandshake-----------------> Ask for handshake
* | * | display group status
| |
* * * * * * * * |* * * * * * * * * * |
| |
Emails to self
--------------
With e-mail as a transport KeySync message handling is done when an incoming
email to self is passed to decrypt_message(), assuming that all incoming email
messages are passed to decrypt_massage().
In case of an email containing a KeySync paload, KeySync may consume or ignore
the message. decrypt_message() signals this to the app with decrypt flags
PEP_decrypt_flag_consume and PEP_decrypt_flag_ignore.
In case of PEP_decrypt_flag_consume, app should delete the message.
In case of PEP_decrypt_flag_ignore, app should ignore message.
In both cases, message should be hidden.
States, events, actions
-----------------------
In the engine, KeySync is implemented through a finite state machine (FSM) [1].
KeySync state machine is driven [2] by events, triggering actions [3] and
transitions to new states.
Events happen on :
- decryption of email messages
- key generation
- user interaction through the app
- timeout when staying too long in some particular states.
[1] sync/devicegroup.fsm , src/sync_fsm.c (generated)
[2] src/sync_driver.c (generated)
[3] src/sync_actions.c , src/sync_send_actions.c (generated)
Sync session, attached sessions
-------------------------------
To use KeySync, the adapter has to create a session dedicated to handle the
protocol, register some callbacks [4] to the engine, and then call protocol's
event consumer loop [5] in a dedicated thread. KeySync actions are executed as
callback invoked from that thread.
When a session is attached [6] to a KeySync session, decryption of pEp email
messages in the attached session may trigger operations in KeySync session. In
case of an adapter capable to serve multiple apps, each app is associated to a
different KeySync session, and sessions created for use in that app are
attached to that session.
Adapters present different approaches regarding session and client abstraction,
and may not propose to explicitely create or attach session or sync session.
[4] register_sync_callbacks()
[5] do_sync_protocol()
[6] attach_sync_session()
KeySync Messages and queue
--------------------------
KeySync messages [7], not to be confused with pEp (email) messages, are either
directly events to be processed by the state machine, or KeySync payloads
collected from decrypted messages.
KeySync messages can be emitted by different sessions, and could naturally come
from different threads. They must be serialized in a locked queue.
KeySync messages queue is implemented by adapter, along with thread handling
KeySync protocol.
Attached sessions inject [8] KeySync messages in the queue. Protocol loop
retrieves [9] them from the queue. KeySync message is received [10] by the
state machine, where event, partner and extra parameters are eventually deduced
from payload.
A state timeout event is a particular case. It doesn't traverse the queue, and
isn't emitted by a session. It is triggered by a timeout on the retrieve
operation. Value of the timeout is determined when entering a new state, and is
passed as a parameter of the call to the blocking queue retrieve operation on
next protocol loop iteraton.
[7] type sync_msg_t
[8] callback inject_sync_msg
[9] callback retrieve_next_sync_msg
[10] receive_sync_msg() (src/sync_impl.c)
Application callbacks
---------------------
Some Keysync actions require the application to act, through callbacks :
- messageToSend : send pEp messages through app's transport.
Messages are already encrypted and just need to be passed as-is to
transport for transmission, as for messages returned by encrypt_message().
- notifyHandshake : display KeySync status and handshake to the user.
notifyHandshake callback receives 2 identities, 'me' and 'partner', together
with a sync_handshake_signal enum :
// this module is for being used WITHOUT the Transport API in transport.h
// DO NOT USE IT WHEN USING Transport API!
SYNC_NOTIFY_INIT_ADD_OUR_DEVICE :
Device (me) is sole, about to enter a group (partner).
App displays trustwords, and requests user accept or reject
App calls deliverHandshakeResult with user's answer
#pragma once
SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE :
Device (me) is grouped, another device (partner) wants to join group.
App displays trustwords, and requests user accept or reject
App calls deliverHandshakeResult with user's answer
#include "message.h"
SYNC_NOTIFY_INIT_FORM_GROUP :
Device (me) is forming a group, including another device (partner)
App displays trustwords, and requests user accept or reject
App calls deliverHandshakeResult with user's answer
#ifdef __cplusplus
extern "C" {
#endif
SYNC_NOTIFY_INIT_MOVE_OUR_DEVICE
Device (me) is grouped and will leave current group to join another
device's (partner) group.
App displays trustwords, and requests user accept or reject
App calls deliverHandshakeResult with user's answer
typedef enum _sync_handshake_signal {
SYNC_NOTIFY_UNDEFINED = 0,
// request show handshake dialog
SYNC_NOTIFY_INIT_ADD_OUR_DEVICE,
SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE,
SYNC_NOTIFY_INIT_FORM_GROUP,
SYNC_NOTIFY_INIT_MOVE_OUR_DEVICE,
SYNC_NOTIFY_TIMEOUT :
KeySync operation timed out.
Identities are set reflecting peers involved in aborted operation.
App displays error message. No feedback to engine.
// handshake process timed out
SYNC_NOTIFY_TIMEOUT,
// handshake accepted by user
SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED,
New device was added to group.
App displays message. No feedback to engine.
SYNC_NOTIFY_ACCEPTED_GROUP_CREATED
New group created.
App displays message. No feedback to engine.
SYNC_NOTIFY_ACCEPTED_DEVICE_MOVED
New device was moved from one group to another.
App displays message. No feedback to engine.
To deliver handshake result back to engine once user reacted,
deliver_handshake_result is used. Result can be :
SYNC_HANDSHAKE_CANCEL
Gives no answer. User doesn't know id TrustWord are good or bad.
For example in case peering device is away.
Handshake will re-appear later.
SYNC_NOTIFY_ACCEPTED_GROUP_CREATED,
SYNC_NOTIFY_ACCEPTED_DEVICE_MOVED,
SYNC_HANDSHAKE_ACCEPTED
Trustwords match with other device and user accepts handshake.
SYNC_HANDSHAKE_REJECTED
Trustwords do not match with any device and user rejects handshake.
*/
#pragma once
#include "message.h"
#include "sync_fsm.h"
#include "sync_app.h"
// this module is for being used WITHOUT the Transport API in transport.h
// DO NOT USE IT WHEN USING Transport API!
#ifdef __cplusplus
extern "C" {
#endif
// handshake dialog must be closed
SYNC_NOTIFY_OVERTAKEN
} sync_handshake_signal;
// messageToSend() - send a message
//
@ -262,7 +82,7 @@ typedef enum _sync_handshake_result {
DYNAMIC_API PEP_STATUS deliverHandshakeResult(
PEP_SESSION session,
Identity partner,
pEp_identity *partner,
sync_handshake_result result
);


+ 30
- 16
src/sync_actions.c View File

@ -1,6 +1,9 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include "pEp_internal.h"
#include "map_asn1.h"
#include "Sync_impl.h"
#include "KeySync_fsm.h"
@ -11,7 +14,7 @@ PEP_STATUS deviceGrouped(PEP_SESSION session, bool *result)
return PEP_ILLEGAL_VALUE;
static const char *sql = "select count(*) from identity where user_id = '"PEP_OWN_USERID"' and (flags & 4) = 4;";
static const size_t len = strlen(sql);
static const size_t len = sizeof("select count(*) from identity where user_id = '"PEP_OWN_USERID"' and (flags & 4) = 4;");
sqlite3_stmt *_sql;
int int_result = sqlite3_prepare_v2(session->db, sql, (int) len, &_sql, NULL);
assert(int_result == SQLITE_OK);
@ -115,7 +118,7 @@ PEP_STATUS openChallenge(PEP_SESSION session)
pEpUUID c;
uuid_generate_random(c);
OCTET_STRING_fromBuf(&session->own_sync_state.challenge, c, 16);
OCTET_STRING_fromBuf(&session->own_sync_state.challenge, (char *) c, 16);
return PEP_STATUS_OK;
}
@ -147,7 +150,7 @@ PEP_STATUS openTransaction(PEP_SESSION session)
pEpUUID c;
uuid_generate_random(c);
OCTET_STRING_fromBuf(&session->own_sync_state.transaction, c, 16);
OCTET_STRING_fromBuf(&session->own_sync_state.transaction, (char *) c, 16);
return PEP_STATUS_OK;
}
@ -184,6 +187,7 @@ PEP_STATUS showSoleHandshake(PEP_SESSION session)
if (!session->sync_state.basic.from)
return PEP_ILLEGAL_VALUE;
pEp_identity *from = session->sync_state.basic.from;
pEp_identity *me = NULL;
PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
assert(status == PEP_STATUS_OK);
@ -196,14 +200,14 @@ PEP_STATUS showSoleHandshake(PEP_SESSION session)
return PEP_ILLEGAL_VALUE;
}
pEp_identity *partner = identity_dup(session->sync_state.basic.from);
pEp_identity *partner = identity_dup(from);
if (!partner) {
free_identity(me);
return PEP_OUT_OF_MEMORY;
}
PEP_STATUS status = session->notifyHandshake(
session->sync_management, me, partner, SYNC_NOTIFY_INIT_FORM_GROUP);
status = session->notifyHandshake(session->sync_management, me,
partner, SYNC_NOTIFY_INIT_FORM_GROUP);
if (status)
return status;
@ -258,7 +262,14 @@ PEP_STATUS ownKeysAreGroupKeys(PEP_SESSION session)
" join trust on id = trust.user_id"
" and pgp_keypair_fpr = identity.main_key_id"
" where identity.user_id = '" PEP_OWN_USERID "';";
static const size_t len = strlen(sql);
static const size_t len = sizeof("select fpr, username, comm_type, lang,"
" identity.flags | pgp_keypair.flags"
" from identity"
" join person on id = identity.user_id"
" join pgp_keypair on fpr = identity.main_key_id"
" join trust on id = trust.user_id"
" and pgp_keypair_fpr = identity.main_key_id"
" where identity.user_id = '" PEP_OWN_USERID "';");
sqlite3_stmt *_sql;
int int_result = sqlite3_prepare_v2(session->db, sql, (int) len, &_sql, NULL);
assert(int_result == SQLITE_OK);
@ -269,6 +280,7 @@ PEP_STATUS ownKeysAreGroupKeys(PEP_SESSION session)
if (!il)
return PEP_OUT_OF_MEMORY;
pEp_identity *from = session->sync_state.basic.from;
identity_list *_il = il;
int result;
@ -278,9 +290,9 @@ PEP_STATUS ownKeysAreGroupKeys(PEP_SESSION session)
switch (result) {
case SQLITE_ROW:
_identity = new_identity(
address,
from->address,
(const char *) sqlite3_column_text(_sql, 0),
user_id,
from->user_id,
(const char *) sqlite3_column_text(_sql, 1)
);
assert(_identity);
@ -315,7 +327,7 @@ PEP_STATUS ownKeysAreGroupKeys(PEP_SESSION session)
default:
free_identity_list(il);
return PEP_UNKOWN_ERROR;
return PEP_UNKNOWN_ERROR;
}
} while (result != SQLITE_DONE);
@ -341,6 +353,7 @@ PEP_STATUS showJoinGroupHandshake(PEP_SESSION session)
if (!session->sync_state.basic.from)
return PEP_ILLEGAL_VALUE;
pEp_identity *from = session->sync_state.basic.from;
pEp_identity *me = NULL;
PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
assert(status == PEP_STATUS_OK);
@ -353,14 +366,14 @@ PEP_STATUS showJoinGroupHandshake(PEP_SESSION session)
return PEP_ILLEGAL_VALUE;
}
pEp_identity *partner = identity_dup(session->sync_state.basic.from);
pEp_identity *partner = identity_dup(from);
if (!partner) {
free_identity(me);
return PEP_OUT_OF_MEMORY;
}
PEP_STATUS status = session->notifyHandshake(
session->sync_management, me, partner, SYNC_NOTIFY_INIT_ADD_OUR_DEVICE);
status = session->notifyHandshake(session->sync_management, me,
partner, SYNC_NOTIFY_INIT_ADD_OUR_DEVICE);
if (status)
return status;
@ -381,6 +394,7 @@ PEP_STATUS showGroupedHandshake(PEP_SESSION session)
if (!session->sync_state.basic.from)
return PEP_ILLEGAL_VALUE;
pEp_identity *from = session->sync_state.basic.from;
pEp_identity *me = NULL;
PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
assert(status == PEP_STATUS_OK);
@ -393,14 +407,14 @@ PEP_STATUS showGroupedHandshake(PEP_SESSION session)
return PEP_ILLEGAL_VALUE;
}
pEp_identity *partner = identity_dup(session->sync_state.basic.from);
pEp_identity *partner = identity_dup(from);
if (!partner) {
free_identity(me);
return PEP_OUT_OF_MEMORY;
}
PEP_STATUS status = session->notifyHandshake(
session->sync_management, me, partner, SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE);
status = session->notifyHandshake(session->sync_management, me,
partner, SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE);
if (status)
return status;


+ 0
- 34
src/sync_app.h View File

@ -1,34 +0,0 @@
//
// sync_app.h
// pEpEngine
//
// Created by Dirk Zimmermann on 16.05.17.
// Copyright © 2017 Edouard Tisserant. All rights reserved.
//
#ifndef sync_app_h
#define sync_app_h
// TODO add this to generated code.
typedef enum _sync_handshake_signal {
SYNC_NOTIFY_UNDEFINED = 0,
// request show handshake dialog
SYNC_NOTIFY_INIT_ADD_OUR_DEVICE,
SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE,
SYNC_NOTIFY_INIT_FORM_GROUP,
SYNC_NOTIFY_INIT_MOVE_OUR_DEVICE,
// handshake process timed out
SYNC_NOTIFY_TIMEOUT,
// handshake accepted by user
SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED,
SYNC_NOTIFY_ACCEPTED_GROUP_CREATED,
SYNC_NOTIFY_ACCEPTED_DEVICE_MOVED,
// handshake dialog must be closed
SYNC_NOTIFY_OVERTAKEN
} sync_handshake_signal;
#endif /* sync_app_h */

+ 5
- 2
sync/Makefile View File

@ -6,8 +6,8 @@ include ../default.conf
all: .codegen
.codegen: .statemachines .actions .codecs .messages
cp -f generated/*.c generated/*.h ../src
touch .codegen
make copy
.actions: sync.fsm gen_actions.ysl2 fsm.yml2 functions.ysl2 cond_act.yml2
$(YML2_PROC) -y gen_actions.ysl2 $< -o $@
@ -21,13 +21,16 @@ all: .codegen
.messages: sync.fsm gen_messages.ysl2 fsm.yml2 functions.ysl2
$(YML2_PROC) -y gen_messages.ysl2 $< -o $@
.PHONY: clean
.PHONY: clean copy
clean:
rm -f *.xml *.xsl \
$(pathsub generated/%, ../src/% $(wildcard generated/*.*)) \
../generated/* .statemachines .actions .codecs .messages *.dot *.svg
copy:
cp -f generated/*.c generated/*.h ../src
%.xml: %.fsm
yml2c $< -o $@


+ 4
- 0
sync/fsm.yml2 View File

@ -26,6 +26,10 @@ decl state @name (timeout=0);
decl event @name, on is event;
// external events can have IDs
decl external @name (id);
// a transistion moves the statemachine to another state
decl transition @target, go is transition;


+ 3
- 0
sync/gen_actions.ysl2 View File

@ -29,6 +29,9 @@ tstylesheet {
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include "pEp_internal.h"
#include "map_asn1.h"
#include "«@name»_impl.h"
`` for "fsm" | #include "«@name»_fsm.h"


+ 5
- 1
sync/gen_statemachine.ysl2 View File

@ -326,8 +326,12 @@ tstylesheet {
const "name", "@name";
|> «$name» = «/protocol/fsm/message[@name=$name]/@id»,
}
for "func:distinctName(state/event[not(not(../../external/@name=@name))])" {
const "name", "@name";
|> «$name» = «/protocol/fsm/external[@name=$name]/@id»,
}
|> «@name»_event_Extra = Extra,
for "func:distinctName(state/event[not(../../message/@name=@name)])" {
for "func:distinctName(state/event[not(../../message/@name=@name or ../../external/@name=@name)])" {
if "@name!='Init'"
|> «@name»`if "position()!=last()" > , `
}


Loading…
Cancel
Save