sequences

doc_update_sequoia
Volker Birk 7 years ago
parent 33c301c880
commit 66bb4020a0

@ -52,6 +52,7 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
// Sequence
static const char *sql_sequence_value1;
static const char *sql_sequence_value2;
static const char *sql_sequence_value3;
// Revocation tracking
static const char *sql_set_revoked;
@ -128,14 +129,14 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
sqlite3_busy_timeout(_session->system_db, 1000);
// increment this when patching DDL
#define _DDL_USER_VERSION "2"
#define _DDL_USER_VERSION "3"
if (in_first) {
int_result = sqlite3_exec(
_session->db,
"create table if not exists version_info (\n"
" id integer primary key,\n"
" timestamp integer default (datetime('now')) ,\n"
" timestamp integer default (datetime('now')),\n"
" version text,\n"
" comment text\n"
");\n",
@ -143,24 +144,11 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
NULL,
NULL
);
if (int_result == SQLITE_OK) {
int_result = sqlite3_exec(
_session->db,
"pragma user_version = "_DDL_USER_VERSION";\n"
"insert or replace into version_info (id, version)"
"values (1, '" PEP_ENGINE_VERSION "');",
NULL,
NULL,
NULL
);
assert(int_result == SQLITE_OK);
}
int_result = sqlite3_exec(
_session->db,
"PRAGMA application_id = 0x23423423;\n"
"create table if not exists log (\n"
" timestamp integer default (datetime('now')) ,\n"
" timestamp integer default (datetime('now')),\n"
" title text not null,\n"
" entity text not null,\n"
" description text,\n"
@ -176,7 +164,7 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
" created integer,\n"
" expires integer,\n"
" comment text,\n"
" flags integer default (0)\n"
" flags integer default 0\n"
");\n"
"create index if not exists pgp_keypair_expires on pgp_keypair (\n"
" expires\n"
@ -200,7 +188,7 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
" references pgp_keypair (fpr)\n"
" on delete set null,\n"
" comment text,\n"
" flags integer default (0),"
" flags integer default 0,"
" primary key (address, user_id)\n"
");\n"
"create table if not exists trust (\n"
@ -221,7 +209,8 @@ 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"
" value integer default 0,\n"
" own integer default 0\n"
");\n"
"create table if not exists revoked_keys (\n"
" revoked_fpr text primary key,\n"
@ -251,7 +240,7 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
int_result = sqlite3_exec(
_session->db,
"alter table identity\n"
" add column flags integer default (0);\n",
" add column flags integer default 0;\n",
NULL,
NULL,
NULL
@ -263,7 +252,7 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
int_result = sqlite3_exec(
_session->db,
"alter table pgp_keypair\n"
" add column flags integer default (0);\n"
" add column flags integer default 0;\n"
"alter table person\n"
" add column device_group text;\n",
NULL,
@ -273,6 +262,18 @@ 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 < atoi(_DDL_USER_VERSION)) {
int_result = sqlite3_exec(
_session->db,
@ -286,6 +287,19 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
assert(int_result == SQLITE_OK);
}
if (version <= atoi(_DDL_USER_VERSION)) {
int_result = sqlite3_exec(
_session->db,
"pragma user_version = "_DDL_USER_VERSION";\n"
"insert or replace into version_info (id, version)"
"values (1, '" PEP_ENGINE_VERSION "');",
NULL,
NULL,
NULL
);
assert(int_result == SQLITE_OK);
}
sql_log = "insert into log (title, entity, description, comment)"
"values (?1, ?2, ?3, ?4);";
@ -374,6 +388,7 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
"(select coalesce((select value + 1 from sequences "
"where name = ?1), 1 ))) ; ";
sql_sequence_value2 = "select value from sequences where name = ?1 ;";
sql_sequence_value3 = "update sequences set value = ?1 where name = ?2 ;";
sql_set_revoked = "insert or replace into revoked_keys ("
" revoked_fpr, replacement_fpr, revocation_date) "
@ -489,6 +504,11 @@ 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,
@ -600,6 +620,8 @@ 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)
@ -1684,49 +1706,79 @@ the_end:
return status;
}
static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
int32_t *value)
{
PEP_STATUS status = PEP_STATUS_OK;
sqlite3_reset(session->sequence_value2);
sqlite3_bind_text(session->sequence_value2, 1, name, -1,
SQLITE_STATIC);
int result = sqlite3_step(session->sequence_value2);
switch (result) {
case SQLITE_ROW: {
int32_t _value = (int32_t)
sqlite3_column_int64(session->sequence_value2, 0);
*value = _value;
break;
}
default:
status = PEP_UNKNOWN_ERROR;
}
sqlite3_reset(session->sequence_value2);
return status;
}
static PEP_STATUS _increment_sequence_value(PEP_SESSION session, const char *name)
{
sqlite3_reset(session->sequence_value1);
sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
int result = sqlite3_step(session->sequence_value1);
assert(result == SQLITE_DONE);
sqlite3_reset(session->sequence_value1);
if (result == SQLITE_DONE)
return PEP_STATUS_OK;
else
return PEP_CANNOT_INCREASE_SEQUENCE;
}
DYNAMIC_API PEP_STATUS sequence_value(
PEP_SESSION session,
const char *name,
char *name,
int32_t *value
)
{
PEP_STATUS status = PEP_STATUS_OK;
int result;
assert(session);
assert(name);
assert(value);
assert(name && value && *value >= 0);
if (!(session && name && value))
if (!(session && name && value && *value >= 0))
return PEP_ILLEGAL_VALUE;
*value = 0;
sqlite3_reset(session->sequence_value1);
sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
result = sqlite3_step(session->sequence_value1);
assert(result == SQLITE_DONE);
sqlite3_reset(session->sequence_value1);
if (result != SQLITE_DONE) {
status = PEP_UNKNOWN_ERROR;
if (!name[0]) {
unsigned char uuid[16];
uuid_generate_random(uuid);
uuid_unparse_upper(uuid, name);
}
else {
sqlite3_reset(session->sequence_value2);
sqlite3_bind_text(session->sequence_value2, 1, name, -1,
SQLITE_STATIC);
result = sqlite3_step(session->sequence_value2);
switch (result) {
case SQLITE_ROW: {
int32_t _value = (int32_t)
sqlite3_column_int64(session->sequence_value2, 0);
*value = _value;
break;
}
default:
status = PEP_UNKNOWN_ERROR;
}
sqlite3_reset(session->sequence_value2);
if (*value) {
int32_t old_value = 0;
status = _get_sequence_value(session, name, &old_value);
if (status != PEP_STATUS_OK)
return status;
if (old_value >= *value)
return PEP_SEQUENCE_VIOLATED;
else
return PEP_STATUS_OK;
}
assert(*value == 0);
status = _increment_sequence_value(session, name);
if (status == PEP_STATUS_OK)
status = _get_sequence_value(session, name, value);
return status;
}

@ -75,6 +75,9 @@ typedef enum {
PEP_SYNC_NO_TRUSTWORDS_CALLBACK = 0x0901,
PEP_SYNC_ILLEGAL_MESSAGE = 0x0902,
PEP_SEQUENCE_VIOLATED = 0x0970,
PEP_CANNOT_INCREASE_SEQUENCE = 0x0971,
PEP_SYNC_STATEMACHINE_ERROR = 0x0980,
PEP_STATEMACHINE_INVALID_STATE = 0x0982,
PEP_STATEMACHINE_INVALID_EVENT = 0x0983,
@ -859,12 +862,18 @@ DYNAMIC_API PEP_STATUS get_phrase(
//
// parameters:
// session (in) session handle
// name (in) name of sequence
// value (out) value of sequence
// name (inout) name of sequence or char[37] set to {0, }
// for new own sequence
// value (inout) value of sequence value to test or 0 for
// getting next value
//
// returns:
// PEP_STATUS_OK if sequence not violated
// PEP_SEQUENCE_VIOLATED if sequence violated
DYNAMIC_API PEP_STATUS sequence_value(
PEP_SESSION session,
const char *name,
char *name,
int32_t *value
);

@ -120,6 +120,7 @@ typedef struct _pEpSession {
// sequence value
sqlite3_stmt *sequence_value1;
sqlite3_stmt *sequence_value2;
sqlite3_stmt *sequence_value3;
// sequence value
sqlite3_stmt *set_revoked;

@ -138,7 +138,7 @@ PEP_STATUS unicast_msg(
msg->header.version.major = SYNC_VERSION_MAJOR;
msg->header.version.minor = SYNC_VERSION_MINOR;
int32_t seq;
int32_t seq = 0;
status = sequence_value(session, "DeviceGroup", &seq);
if (status != PEP_STATUS_OK)
goto error;

@ -30,6 +30,8 @@ PEP_STATUS multicast_self_msg(
DeviceGroup_Protocol_t *msg
);
bool is_double(DeviceGroup_Protocol_t *msg);
#ifdef __cplusplus
}
#endif

@ -18,18 +18,38 @@ int main() {
// sequence test code
int32_t value1;
PEP_STATUS status2 = sequence_value(session, "test", &value1);
int32_t value1 = 0;
char *name1 = strdup("test");
assert(name1);
PEP_STATUS status2 = sequence_value(session, name1, &value1);
assert(status2 == PEP_STATUS_OK);
cout << "test sequence: " << value1 << "\n";
int32_t value2;
PEP_STATUS status3 = sequence_value(session, "test", &value2);
int32_t value2 = 0;
PEP_STATUS status3 = sequence_value(session, name1, &value2);
assert(status3 == PEP_STATUS_OK);
cout << "test sequence: " << value2 << "\n";
assert(value2 == value1 + 1);
free(name1);
cout << "testing sequence violation\n";
int32_t value3 = value2 - 1;
PEP_STATUS status4 = sequence_value(session, name1, &value3);
assert(status4 == PEP_SEQUENCE_VIOLATED);
cout << "testing sequence non-violation\n";
int32_t value4 = value2 + 1;
PEP_STATUS status5 = sequence_value(session, name1, &value4);
assert(status5 == PEP_STATUS_OK);
cout << "testing UUID generation\n";
int32_t value5 = 0;
char name2[37] = { 0, };
PEP_STATUS status6 = sequence_value(session, name2, &value5);
assert(status6 == PEP_STATUS_OK);
cout << "UUID created: " << name2 << "\n";
cout << "calling release()\n";
release(session);

Loading…
Cancel
Save