Commit e13ec2da authored by Andrea Schaefer's avatar Andrea Schaefer
Browse files

Merge remote-tracking branch 'gdkr/dev' into librem5

parents b550d2d8 d82c8b49
Pipeline #30220 passed with stages
in 2 minutes and 5 seconds
......@@ -171,7 +171,10 @@ $(BDIR)/test_lurch_api: $(OBJECTS_W_COVERAGE) $(VENDOR_LIBS) $(BDIR)/test_lurch_
-Wl,--wrap=jabber_pep_publish \
-Wl,--wrap=purple_account_get_connection \
-Wl,--wrap=omemo_storage_chatlist_delete \
-Wl,--wrap=omemo_storage_chatlist_save
-Wl,--wrap=omemo_storage_chatlist_save \
-Wl,--wrap=axc_key_load_public_own \
-Wl,--wrap=axc_key_load_public_addr \
-Wl,--wrap=lurch_util_fp_get_printable
bash -c "set -o pipefail; $@ 2>&1 | grep -Ev ".*CRITICAL.*" | tr -s '\n'" # filter annoying and irrelevant glib output
test: $(OBJECTS_W_COVERAGE) $(VENDOR_LIBS) $(TEST_TARGETS)
......
Subproject commit 3c8268172829996ec1f1e7b7a12df5c63ceb0ef1
Subproject commit e3b2125eb630e7137ea2b904bf4ddc6bdc106092
......@@ -37,8 +37,6 @@
#define JABBER_MAX_LEN_DOMAIN 1023
#define JABBER_MAX_LEN_BARE JABBER_MAX_LEN_NODE + JABBER_MAX_LEN_DOMAIN + 1
#define LURCH_ACC_SETTING_INITIALIZED "lurch_initialised"
#define LURCH_ERR_STRING_ENCRYPT "There was an error encrypting the message and it was not sent. " \
"You can try again, or try to find the problem by looking at the debug log."
#define LURCH_ERR_STRING_DECRYPT "There was an error decrypting an OMEMO message addressed to this device. " \
......@@ -146,6 +144,9 @@ static char * lurch_queue_make_key_string_s(const char * name, const char * devi
* Does the first-time install of the axc DB.
* As specified in OMEMO, it checks if the generated device ID already exists.
* Therefore, it should be called at a point in time when other entries exist.
*
* If an initialized DB already exists, this function exits with success without doing anything.
* This is checked by trying to retrieve the device ID from it.
*
* @param uname The username.
* @return 0 on success, negative on error.
......@@ -996,7 +997,6 @@ static void lurch_pep_own_devicelist_request_handler(JabberStream * js_p, const
int len = 0;
PurpleAccount * acc_p = (void *) 0;
char * uname = (void *) 0;
int install = 0;
axc_context * axc_ctx_p = (void *) 0;
uint32_t own_id = 0;
int needs_publishing = 1;
......@@ -1007,9 +1007,7 @@ static void lurch_pep_own_devicelist_request_handler(JabberStream * js_p, const
acc_p = purple_connection_get_account(js_p->gc);
uname = lurch_util_uname_strip(purple_account_get_username(acc_p));
install = (purple_account_get_bool(acc_p, LURCH_ACC_SETTING_INITIALIZED, FALSE)) ? 0 : 1;
if (install && !uninstall) {
if (!uninstall) {
purple_debug_info("lurch", "%s: %s\n", __func__, "preparing installation...");
ret_val = lurch_axc_prepare(uname);
if (ret_val) {
......@@ -1092,10 +1090,6 @@ static void lurch_pep_own_devicelist_request_handler(JabberStream * js_p, const
goto cleanup;
}
if (install && !uninstall) {
purple_account_set_bool(acc_p, LURCH_ACC_SETTING_INITIALIZED, TRUE);
}
ret_val = lurch_devicelist_process(uname, dl_p, js_p);
if (ret_val) {
err_msg_dbg = g_strdup_printf("failed to process the devicelist");
......@@ -1157,25 +1151,24 @@ cleanup:
/**
* Set as callback for the "account connected" signal.
* Requests the own devicelist, as that requires an active connection (as
* opposed to just registering PEP handlers).
* Also inits the msg queue hashtable.
* Requests the own devicelist, as that requires an active connection (as opposed to just registering PEP handlers).
*/
static void lurch_account_connect_cb(PurpleAccount * acc_p) {
int ret_val = 0;
char * uname = (void *) 0;
JabberStream * js_p = (void *) 0;
char * uname = (void *) 0;
char * dl_ns = (void *) 0;
// purple_account_set_bool(acc_p, LURCH_ACC_SETTING_INITIALIZED, FALSE);
js_p = purple_connection_get_protocol_data(purple_account_get_connection(acc_p));
if (strncmp(purple_account_get_protocol_id(acc_p), JABBER_PROTOCOL_ID, strlen(JABBER_PROTOCOL_ID))) {
return;
}
// remove unused account preferences
purple_account_remove_setting(acc_p, "lurch_initialised");
ret_val = omemo_devicelist_get_pep_node_name(&dl_ns);
if (ret_val) {
purple_debug_error("lurch", "%s: %s (%i)\n", __func__, "failed to get devicelist pep node name", ret_val);
......@@ -2204,7 +2197,6 @@ static PurpleCmdRet lurch_cmd_func(PurpleConversation * conv_p,
}
uninstall = 1;
purple_account_set_bool(purple_conversation_get_account(conv_p), LURCH_ACC_SETTING_INITIALIZED, FALSE);
dl_node_p = xmlnode_from_str(temp_msg_1, -1);
jabber_pep_publish(purple_connection_get_protocol_data(purple_conversation_get_gc(conv_p)), dl_node_p);
msg = g_strdup_printf("Published devicelist minus this device's ID. "
......
......@@ -73,4 +73,21 @@ void lurch_api_enable_im_handler(PurpleAccount * acc_p, const char * contact_bar
*
* Disables OMEMO for the specified contact.
*/
void lurch_api_disable_im_handler(PurpleAccount * acc_p, const char * contact_bare_jid, void (*cb)(int32_t err, void * user_data_p), void * user_data_p);
\ No newline at end of file
void lurch_api_disable_im_handler(PurpleAccount * acc_p, const char * contact_bare_jid, void (*cb)(int32_t err, void * user_data_p), void * user_data_p);
/**
* SIGNAL: lurch-fp-get
*
* Gets the this device's fingerprint in a printable format.
*/
void lurch_api_fp_get_handler(PurpleAccount * acc_p, void (*cb)(int32_t err, const char * fp_printable, void * user_data_p), void * user_data_p);
/**
* SIGNAL: lurch-fp-list
*
* Gets the fingerprints of all devices belonging to the specified account and creates a device-ID-to-fingerprint table.
* This is based on sessions, so if there is an entry in the OMEMO devicelist, but no libsignal session yet, the value will be NULL.
* If the whole devicelist is empty, i.e. the account is not an OMEMO user, the whole table will be NULL.
* Watch out as this is not a valid GHashTable.
*/
void lurch_api_fp_list_handler(PurpleAccount * acc_p, void (*cb)(int32_t err, GHashTable * id_fp_table, void * user_data_p), void * user_data_p);
\ No newline at end of file
......@@ -32,12 +32,14 @@ int __wrap_omemo_storage_user_devicelist_retrieve(const char * user, const char
int __wrap_axc_get_device_id(axc_context * ctx_p, uint32_t * id_p) {
uint32_t id;
int ret_val;
id = mock_type(uint32_t);
*id_p = id;
return EXIT_SUCCESS;
ret_val = mock_type(int);
return ret_val;
}
void __wrap_jabber_pep_publish(JabberStream * js_p, xmlnode * publish_node_p) {
......@@ -51,7 +53,7 @@ void __wrap_jabber_pep_publish(JabberStream * js_p, xmlnode * publish_node_p) {
check_expected_ptr(device_node_p->next);
}
PurpleConnection * __wrap_purple_account_get_connection(PurpleAccount * acc_p) {
void __wrap_purple_account_get_connection(PurpleAccount * acc_p) {
function_called();
}
......@@ -71,6 +73,41 @@ int __wrap_omemo_storage_chatlist_save(const char * chat, const char * db_fn) {
return ret_val;
}
int __wrap_axc_key_load_public_own(axc_context * ctx_p, axc_buf ** pubkey_data_pp) {
void * pubkey_data_p;
int ret_val;
pubkey_data_p = mock_ptr_type(void *);
*pubkey_data_pp = pubkey_data_p;
ret_val = mock_type(int);
return ret_val;
}
int __wrap_axc_key_load_public_addr(const char * name, uint32_t device_id, axc_context * ctx_p, axc_buf ** pubkey_data_pp) {
void * pubkey_data_p;
int ret_val;
check_expected(name);
check_expected(device_id);
pubkey_data_p = mock_ptr_type(void *);
*pubkey_data_pp = pubkey_data_p;
ret_val = mock_type(int);
return ret_val;
}
char * __wrap_lurch_util_fp_get_printable(axc_buf * key_buf_p) {
function_called();
check_expected(key_buf_p);
char * ret_val;
ret_val = mock_ptr_type(char *);
return ret_val;
}
void lurch_api_id_list_handler_cb_mock(int32_t err, GList * id_list, void * user_data_p) {
check_expected(err);
......@@ -117,6 +154,7 @@ static void test_lurch_api_id_list_handler(void ** state) {
uint32_t test_own_id = 1337;
will_return(__wrap_axc_get_device_id, test_own_id);
will_return(__wrap_axc_get_device_id, EXIT_SUCCESS);
expect_value(lurch_api_id_list_handler_cb_mock, err, 0);
expect_value(lurch_api_id_list_handler_cb_mock, first_id, test_own_id);
......@@ -308,6 +346,181 @@ static void test_lurch_api_disable_im_handler_err(void ** state) {
lurch_api_disable_im_handler((void *) "ignored", contact_bare_jid, lurch_api_disable_im_handler_cb_mock, test_user_data);
}
void lurch_api_fp_get_handler_cb_mock(int32_t err, const char * fp_printable, void * user_data_p) {
check_expected(err);
check_expected(fp_printable);
check_expected(user_data_p);
}
/**
* Loads the account's public identity key and returns a fingerprint suitable for display.
*/
static void test_lurch_api_fp_get_handler(void ** state) {
(void) state;
const char * test_jid = "me-testing@test.org/resource";
will_return(__wrap_purple_account_get_username, test_jid);
axc_buf * mock_key_buf_own = axc_buf_create(NULL, 0);
will_return(__wrap_axc_key_load_public_own, mock_key_buf_own);
will_return(__wrap_axc_key_load_public_own, EXIT_SUCCESS);
expect_function_call(__wrap_lurch_util_fp_get_printable);
expect_value(__wrap_lurch_util_fp_get_printable, key_buf_p, mock_key_buf_own);
char * mock_fp_own = g_strdup("MOCK FINGERPRINT");
will_return(__wrap_lurch_util_fp_get_printable, mock_fp_own);
char * test_user_data = "TEST USER DATA";
expect_value(lurch_api_fp_get_handler_cb_mock, err, EXIT_SUCCESS);
expect_string(lurch_api_fp_get_handler_cb_mock, fp_printable, mock_fp_own);
expect_value(lurch_api_fp_get_handler_cb_mock, user_data_p, test_user_data);
lurch_api_fp_get_handler(NULL, lurch_api_fp_get_handler_cb_mock, test_user_data);
}
/**
* Calls the callback with the return code in case of an error.
*/
static void test_lurch_api_fp_get_handler_err(void ** state) {
(void) state;
const char * test_jid = "me-testing@test.org/resource";
will_return(__wrap_purple_account_get_username, test_jid);
will_return(__wrap_axc_key_load_public_own, NULL);
will_return(__wrap_axc_key_load_public_own, EXIT_FAILURE);
char * test_user_data = "TEST USER DATA";
expect_value(lurch_api_fp_get_handler_cb_mock, err, EXIT_FAILURE);
expect_value(lurch_api_fp_get_handler_cb_mock, fp_printable, NULL);
expect_value(lurch_api_fp_get_handler_cb_mock, user_data_p, test_user_data);
lurch_api_fp_get_handler(NULL, lurch_api_fp_get_handler_cb_mock, test_user_data);
}
/**
* Mock callback that checks whether the given table is the same as the expected table passed through the user data.
*/
static void lurch_api_fp_list_handler_cb_mock(int32_t err, GHashTable * id_fp_table, void * user_data_p) {
check_expected(err);
if (err) {
return;
}
GHashTable * expected_table = (GHashTable *) user_data_p;
GHashTableIter iter;
gpointer key, value;
char * generated_fp = (void *) 0;
g_hash_table_iter_init (&iter, expected_table);
while (g_hash_table_iter_next (&iter, &key, &value)) {
generated_fp = g_hash_table_lookup(id_fp_table, key);
// assert_non_null(generated_fp);
assert_ptr_equal(generated_fp, value);
generated_fp = (void *) 0;
}
}
/**
* Loads the devicelist, then each device's public key, then gets their fingerprints, and finally puts everything
* into a single table of device ID to fingerprint.
*/
static void test_lurch_api_fp_list_handler(void ** state) {
(void) state;
const char * bare_jid = "me-testing@test.org";
const char * test_jid = "me-testing@test.org/resource";
will_return_always(__wrap_purple_account_get_username, test_jid);
char * devicelist = "<items node='urn:xmpp:omemo:0:devicelist'>"
"<item>"
"<list xmlns='urn:xmpp:omemo:0'>"
"<device id='4223' />"
"<device id='1337' />"
"<device id='1338' />"
"</list>"
"</item>"
"</items>";
omemo_devicelist * dl_p;
omemo_devicelist_import(devicelist, test_jid, &dl_p);
will_return(__wrap_omemo_storage_user_devicelist_retrieve, dl_p);
will_return(__wrap_omemo_storage_user_devicelist_retrieve, EXIT_SUCCESS);
uint32_t test_own_id = 1337;
will_return(__wrap_axc_get_device_id, test_own_id);
will_return(__wrap_axc_get_device_id, EXIT_SUCCESS);
int id_4223 = 4223;
expect_string(__wrap_axc_key_load_public_addr, name, bare_jid);
expect_value(__wrap_axc_key_load_public_addr, device_id, id_4223);
char * mock_key_4223 = "FAKE KEY 4223";
axc_buf * mock_key_buf_4223 = axc_buf_create((unsigned char *) mock_key_4223, strlen(mock_key_4223));
will_return(__wrap_axc_key_load_public_addr, mock_key_buf_4223);
will_return(__wrap_axc_key_load_public_addr, 1);
expect_function_call(__wrap_lurch_util_fp_get_printable);
expect_value(__wrap_lurch_util_fp_get_printable, key_buf_p, mock_key_buf_4223);
char * mock_fp_4223 = g_strdup("FAKE FP 4223");
will_return(__wrap_lurch_util_fp_get_printable, mock_fp_4223);
int id_1338 = 1338;
expect_string(__wrap_axc_key_load_public_addr, name, bare_jid);
expect_value(__wrap_axc_key_load_public_addr, device_id, id_1338);
char * mock_key_1338 = "FAKE KEY 1338";
axc_buf * mock_key_buf_1338 = axc_buf_create((unsigned char *) mock_key_1338, strlen(mock_key_1338));
will_return(__wrap_axc_key_load_public_addr, mock_key_buf_1338);
will_return(__wrap_axc_key_load_public_addr, 0);
axc_buf * mock_key_buf_own = axc_buf_create(NULL, 0);
will_return(__wrap_axc_key_load_public_own, mock_key_buf_own);
will_return(__wrap_axc_key_load_public_own, EXIT_SUCCESS);
char * mock_fp_own = g_strdup("MOCK FINGERPRINT");
expect_function_call(__wrap_lurch_util_fp_get_printable);
expect_value(__wrap_lurch_util_fp_get_printable, key_buf_p, mock_key_buf_own);
will_return(__wrap_lurch_util_fp_get_printable, mock_fp_own);
GHashTable * expected_table = g_hash_table_new(g_int_hash, g_int_equal);
g_hash_table_insert(expected_table, &test_own_id, mock_fp_own);
g_hash_table_insert(expected_table, &id_4223, mock_fp_4223);
g_hash_table_insert(expected_table, &id_1338, NULL);
expect_value(lurch_api_fp_list_handler_cb_mock, err, EXIT_SUCCESS);
lurch_api_fp_list_handler(NULL, lurch_api_fp_list_handler_cb_mock, expected_table);
}
/**
* Calls the callback with the return code in case of an error.
*/
static void test_lurch_api_fp_list_handler_err(void ** state) {
(void) state;
const char * bare_jid = "me-testing@test.org";
const char * test_jid = "me-testing@test.org/resource";
will_return_always(__wrap_purple_account_get_username, test_jid);
char * devicelist = "<items node='urn:xmpp:omemo:0:devicelist'>"
"<item>"
"<list xmlns='urn:xmpp:omemo:0'>"
"</list>"
"</item>"
"</items>";
omemo_devicelist * dl_p;
omemo_devicelist_import(devicelist, test_jid, &dl_p);
will_return(__wrap_omemo_storage_user_devicelist_retrieve, dl_p);
will_return(__wrap_omemo_storage_user_devicelist_retrieve, EXIT_SUCCESS);
uint32_t id_which_does_not_matter = 123;
will_return(__wrap_axc_get_device_id, id_which_does_not_matter);
will_return(__wrap_axc_get_device_id, EXIT_FAILURE);
expect_value(lurch_api_fp_list_handler_cb_mock, err, EXIT_FAILURE);
lurch_api_fp_list_handler(NULL, lurch_api_fp_list_handler_cb_mock, NULL);
}
int main(void) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_lurch_api_id_list_handler),
......@@ -317,7 +530,11 @@ int main(void) {
cmocka_unit_test(test_lurch_api_enable_im_handler),
cmocka_unit_test(test_lurch_api_enable_im_handler_err),
cmocka_unit_test(test_lurch_api_disable_im_handler),
cmocka_unit_test(test_lurch_api_disable_im_handler_err)
cmocka_unit_test(test_lurch_api_disable_im_handler_err),
cmocka_unit_test(test_lurch_api_fp_get_handler),
cmocka_unit_test(test_lurch_api_fp_get_handler_err),
cmocka_unit_test(test_lurch_api_fp_list_handler),
cmocka_unit_test(test_lurch_api_fp_list_handler_err)
};
return cmocka_run_group_tests_name("lurch_api", tests, NULL, NULL);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment