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

Merge upstream changes

parents e753d5a0 108a7a5a
Pipeline #52767 passed with stages
in 4 minutes and 4 seconds
......@@ -166,14 +166,23 @@ $(BDIR)/test_lurch_util: $(OBJECTS_W_COVERAGE) $(VENDOR_LIBS) $(BDIR)/test_lurch
$(BDIR)/test_lurch_api: $(OBJECTS_W_COVERAGE) $(VENDOR_LIBS) $(BDIR)/test_lurch_api.o
$(CC) $(CFLAGS) $(CPPFLAGS) -O0 --coverage $^ $(PURPLE_DIR)/libjabber.so.0 -o $@ $(LDFLAGS_T) \
-Wl,--wrap=purple_account_get_username \
-Wl,--wrap=omemo_storage_user_devicelist_retrieve \
-Wl,--wrap=axc_get_device_id \
-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=purple_signal_register \
-Wl,--wrap=purple_signal_unregister \
-Wl,--wrap=purple_signal_connect \
-Wl,--wrap=purple_signal_disconnect \
-Wl,--wrap=purple_find_conversation_with_account \
-Wl,--wrap=jabber_pep_publish \
-Wl,--wrap=jabber_chat_find_by_conv \
-Wl,--wrap=axc_get_device_id \
-Wl,--wrap=axc_key_load_public_own \
-Wl,--wrap=axc_key_load_public_addr \
-Wl,--wrap=axc_session_exists_any \
-Wl,--wrap=omemo_storage_user_devicelist_retrieve \
-Wl,--wrap=omemo_storage_chatlist_delete \
-Wl,--wrap=omemo_storage_chatlist_save \
-Wl,--wrap=omemo_storage_chatlist_exists \
-Wl,--wrap=omemo_storage_user_devicelist_retrieve \
-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
......
......@@ -2,6 +2,7 @@
#include <glib.h>
#include <purple.h>
#include "chat.h"
#include "pep.h"
#include "axc.h"
......@@ -185,6 +186,44 @@ void lurch_api_disable_im_handler(PurpleAccount * acc_p, const char * contact_ba
g_free(db_fn_omemo);
}
void lurch_api_enable_chat_handler(PurpleAccount * acc_p, const char * full_conversation_name, void (*cb)(int32_t err, void * user_data_p), void * user_data_p) {
int32_t ret_val = 0;
char * uname = (void *) 0;
char * db_fn_omemo = (void *) 0;
uname = lurch_util_uname_strip(purple_account_get_username(acc_p));
db_fn_omemo = lurch_util_uname_get_db_fn(uname, LURCH_DB_NAME_OMEMO);
ret_val = omemo_storage_chatlist_save(full_conversation_name, db_fn_omemo);
if (ret_val) {
purple_debug_error(MODULE_NAME, "Failed to enable OMEMO for chat %s using DB %s.\n", full_conversation_name, db_fn_omemo);
}
cb(ret_val, user_data_p);
g_free(uname);
g_free(db_fn_omemo);
}
void lurch_api_disable_chat_handler(PurpleAccount * acc_p, const char * full_conversation_name, void (*cb)(int32_t err, void * user_data_p), void * user_data_p) {
int32_t ret_val = 0;
char * uname = (void *) 0;
char * db_fn_omemo = (void *) 0;
uname = lurch_util_uname_strip(purple_account_get_username(acc_p));
db_fn_omemo = lurch_util_uname_get_db_fn(uname, LURCH_DB_NAME_OMEMO);
ret_val = omemo_storage_chatlist_delete(full_conversation_name, db_fn_omemo);
if (ret_val) {
purple_debug_error(MODULE_NAME, "Failed to disable OMEMO for chat %s using DB %s.\n", full_conversation_name, db_fn_omemo);
}
cb(ret_val, user_data_p);
g_free(uname);
g_free(db_fn_omemo);
}
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) {
int32_t ret_val = 0;
char * uname = (void *) 0;
......@@ -422,6 +461,89 @@ cleanup:
axc_context_destroy_all(axc_ctx_p);
}
void lurch_api_status_chat_handler(PurpleAccount * acc_p, const char * full_conversation_name, void (*cb)(int32_t err, lurch_status_chat_t status, void * user_data_p), void * user_data_p) {
int32_t ret_val = 0;
lurch_status_chat_t status = LURCH_STATUS_CHAT_DISABLED;
char * uname = (void *) 0;
char * db_fn_omemo = (void *) 0;
PurpleConversation * conv_p = (void *) 0;
JabberChat * muc_p = (void *) 0;
GList * curr_item_p = (void *) 0;
JabberChatMember * curr_muc_member_p = (void *) 0;
char * curr_muc_member_bare_jid = (void *) 0;
omemo_devicelist * curr_dl_p = (void *) 0;
uname = lurch_util_uname_strip(purple_account_get_username(acc_p));
db_fn_omemo = lurch_util_uname_get_db_fn(uname, LURCH_DB_NAME_OMEMO);
conv_p = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, full_conversation_name, acc_p);
if (!conv_p) {
purple_debug_error(MODULE_NAME, "Could not find groupchat %s.\n", full_conversation_name);
ret_val = EXIT_FAILURE;
goto cleanup;
}
muc_p = jabber_chat_find_by_conv(conv_p);
if (!muc_p) {
purple_debug_error(MODULE_NAME, "Could not find the data for groupchat %s.\n", full_conversation_name);
ret_val = EXIT_FAILURE;
goto cleanup;
}
for (curr_item_p = g_hash_table_get_values(muc_p->members); curr_item_p; curr_item_p = curr_item_p->next) {
curr_muc_member_p = (JabberChatMember *) curr_item_p->data;
curr_muc_member_bare_jid = jabber_get_bare_jid(curr_muc_member_p->jid);
if (!curr_muc_member_bare_jid) {
purple_debug_warning(
MODULE_NAME,
"Could not get the JID of chat member with handle %s, which probably means the chat is anonymous.\n",
curr_muc_member_p->handle
);
status = LURCH_STATUS_CHAT_ANONYMOUS;
goto cleanup;
}
ret_val = omemo_storage_user_devicelist_retrieve(curr_muc_member_bare_jid, db_fn_omemo, &curr_dl_p);
if (ret_val) {
purple_debug_error(MODULE_NAME, "Could not retrieve the devicelist for %s from %s.\n", curr_muc_member_bare_jid, db_fn_omemo);
goto cleanup;
}
if (omemo_devicelist_is_empty(curr_dl_p)) {
purple_debug_warning(
MODULE_NAME,
"Could not find %s's devicelist in chat %s. The user is probably not in %s's contact list.\n",
curr_muc_member_bare_jid, full_conversation_name, uname
);
status = LURCH_STATUS_CHAT_NO_DEVICELIST;
goto cleanup;
}
g_free(curr_muc_member_bare_jid);
curr_muc_member_bare_jid = (void *) 0;
omemo_devicelist_destroy(curr_dl_p);
curr_dl_p = (void *) 0;
}
status = LURCH_STATUS_CHAT_OK;
cleanup:
cb(ret_val, status, user_data_p);
g_free(uname);
g_free(db_fn_omemo);
// if loop was exited early
g_free(curr_muc_member_bare_jid);
omemo_devicelist_destroy(curr_dl_p);
}
static void lurch_api_marshal_VOID__POINTER_INT_POINTER_POINTER(PurpleCallback cb, va_list args, void * data, void ** return_val) {
void * arg1 = va_arg(args, void *);
gint32 arg2 = va_arg(args, guint);
......@@ -442,13 +564,15 @@ typedef enum {
* When adding a new signal: increase this number and add the name, handler function, and handler function type
* to the respective array.
*/
#define NUM_OF_SIGNALS 8
#define NUM_OF_SIGNALS 11
const char * signal_names[NUM_OF_SIGNALS] = {
"lurch-id-list",
"lurch-id-remove",
"lurch-enable-im",
"lurch-disable-im",
"lurch-enable-chat",
"lurch-disable-chat",
"lurch-fp-get",
"lurch-fp-list",
"lurch-fp-other",
......@@ -460,6 +584,8 @@ const void * signal_handlers[NUM_OF_SIGNALS] = {
lurch_api_id_remove_handler,
lurch_api_enable_im_handler,
lurch_api_disable_im_handler,
lurch_api_enable_chat_handler,
lurch_api_disable_chat_handler,
lurch_api_fp_get_handler,
lurch_api_fp_list_handler,
lurch_api_fp_other_handler,
......@@ -471,6 +597,8 @@ const lurch_api_handler_t signal_handler_types[NUM_OF_SIGNALS] = {
LURCH_API_HANDLER_ACC_DID_CB_DATA,
LURCH_API_HANDLER_ACC_JID_CB_DATA,
LURCH_API_HANDLER_ACC_JID_CB_DATA,
LURCH_API_HANDLER_ACC_JID_CB_DATA,
LURCH_API_HANDLER_ACC_JID_CB_DATA,
LURCH_API_HANDLER_ACC_CB_DATA,
LURCH_API_HANDLER_ACC_CB_DATA,
LURCH_API_HANDLER_ACC_JID_CB_DATA,
......@@ -551,4 +679,4 @@ void lurch_api_unload() {
purple_signal_unregister(plugins_handle_p, signal_name);
}
}
\ No newline at end of file
}
......@@ -5,6 +5,20 @@
#define LURCH_ERR_NO_BUNDLE -1000010
#define LURCH_ERR_DEVICE_NOT_IN_LIST -1000100
typedef enum {
LURCH_STATUS_DISABLED = 0, // manually disabled
LURCH_STATUS_NOT_SUPPORTED, // no OMEMO support, i.e. there is no devicelist node
LURCH_STATUS_NO_SESSION, // OMEMO is supported, but there is no libsignal session yet
LURCH_STATUS_OK // OMEMO is supported and session exists
} lurch_status_t;
typedef enum {
LURCH_STATUS_CHAT_DISABLED = 0, // OMEMO was not manually enabled
LURCH_STATUS_CHAT_ANONYMOUS, // chat is anonymous, i.e. a member's JID could not be accessed
LURCH_STATUS_CHAT_NO_DEVICELIST, // a member's devicelist could not be accessed, probably because s/he is not a contact
LURCH_STATUS_CHAT_OK // in theory, OMEMO should work
} lurch_status_chat_t;
/**
* Initializes the API by registering the signals and signal handlers.
*/
......@@ -15,14 +29,6 @@ void lurch_api_init();
*/
void lurch_api_unload();
typedef enum {
LURCH_STATUS_DISABLED = 0, // manually disabled
LURCH_STATUS_NOT_SUPPORTED, // no OMEMO support, i.e. there is no devicelist node
LURCH_STATUS_NO_SESSION, // OMEMO is supported, but there is no libsignal session yet
LURCH_STATUS_OK // OMEMO is supported and session exists
} lurch_status_t;
/**
* USAGE
*
......@@ -75,6 +81,20 @@ void lurch_api_enable_im_handler(PurpleAccount * acc_p, const char * contact_bar
*/
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-enable-chat
*
* Enables OMEMO for the specified chat. The conversation name can be obtained by simply calling purple_conversation_get_name().
*/
void lurch_api_enable_chat_handler(PurpleAccount * acc_p, const char * full_conversation_name, void (*cb)(int32_t err, void * user_data_p), void * user_data_p);
/**
* SIGNAL: lurch-disable-chat
*
* Disables OMEMO for the specified chat.
*/
void lurch_api_disable_chat_handler(PurpleAccount * acc_p, const char * full_conversation_name, void (*cb)(int32_t err, void * user_data_p), void * user_data_p);
/**
* SIGNAL: lurch-fp-get
*
......@@ -90,4 +110,27 @@ void lurch_api_fp_get_handler(PurpleAccount * acc_p, void (*cb)(int32_t err, con
* 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
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);
/**
* SIGNAL: lurch-fp-other
*
* Same as above, but for the specified contact.
*/
void lurch_api_fp_other_handler(PurpleAccount * acc_p, const char * contact_bare_jid, void (*cb)(int32_t err, GHashTable * id_fp_table, void * user_data_p), void * user_data_p);
/**
* SIGNAL: lurch-status-im
*
* Checks the OMEMO status for the given contact. Result is one of lurch_status_t.
*/
void lurch_api_status_im_handler(PurpleAccount * acc_p, const char * contact_bare_jid, void (*cb)(int32_t err, lurch_status_t status, void * user_data_p), void * user_data_p);
/**
* SIGNAL: lurch-status-chat
*
* Checks the OMEMO status for a MUC.
* It not only looks up whether OMEMO was enabled, but also checks the preconditions for this feature, i.e.
* whether all chat members' JIDs are visible (non-anonymous) and their devicelists accessible (in contact list).
*/
void lurch_api_status_chat_handler(PurpleAccount * acc_p, const char * full_conversation_name, void (*cb)(int32_t err, lurch_status_chat_t status, void * user_data_p), void * user_data_p);
......@@ -175,6 +175,35 @@ void lurch_status_im_print(int32_t err, lurch_status_t status, void * user_data_
lurch_cmd_print(conv_p, msg);
}
void lurch_status_chat_print(int32_t err, lurch_status_chat_t status, void * user_data_p) {
PurpleConversation * conv_p = (PurpleConversation *) user_data_p;
const char * msg = (void *) 0;
if (err) {
lurch_cmd_print_err(conv_p, "Failed to get the conversation status. Check the debug log for details.");
return;
}
switch (status) {
case LURCH_STATUS_CHAT_DISABLED:
msg = "OMEMO was not enabled for this conversation. Type '/lurch enable' to switch it on.";
break;
case LURCH_STATUS_CHAT_ANONYMOUS:
msg = "Could not access the JID of at least one of the chat members. The MUC is probably set to anonymous.";
break;
case LURCH_STATUS_CHAT_NO_DEVICELIST:
msg = "Could not access the OMEMO devicelist of at least one of the chat members. Make sure every member is in every other member's contact list.";
break;
case LURCH_STATUS_CHAT_OK:
msg = "OMEMO is enabled for this conversation and everything should work. You can turn it off by typing '/lurch disable'.";
break;
default:
msg = "Received unknown status code.";
}
lurch_cmd_print(conv_p, msg);
}
static void lurch_cmd_id(PurpleConversation * conv_p, const char * arg, const char * param) {
PurpleAccount * acc_p = purple_conversation_get_account(conv_p);
void * plugins_handle = purple_plugins_get_handle();
......@@ -193,25 +222,49 @@ static void lurch_cmd_id(PurpleConversation * conv_p, const char * arg, const ch
}
static void lurch_cmd_enable(PurpleConversation * conv_p) {
char * bare_jid = (void *) 0;
void * plugins_handle = purple_plugins_get_handle();
PurpleConversationType conv_type = purple_conversation_get_type(conv_p);
char * conv_bare_jid = jabber_get_bare_jid(purple_conversation_get_name(conv_p));
PurpleAccount * acc_p = purple_conversation_get_account(conv_p);
const char * conv_name = purple_conversation_get_name(conv_p);
if (conv_type == PURPLE_CONV_TYPE_IM) {
purple_signal_emit(purple_plugins_get_handle(), "lurch-enable-im", purple_conversation_get_account(conv_p), conv_bare_jid, lurch_enable_print, conv_p);
switch (conv_type) {
case PURPLE_CONV_TYPE_IM:
bare_jid = jabber_get_bare_jid(conv_name);
purple_signal_emit(plugins_handle, "lurch-enable-im", acc_p, bare_jid, lurch_enable_print, conv_p);
break;
case PURPLE_CONV_TYPE_CHAT:
purple_signal_emit(plugins_handle, "lurch-enable-chat", acc_p, conv_name, lurch_enable_print, conv_p);
break;
default:
lurch_cmd_print_err(conv_p, "Conversation type not supported.");
break;
}
g_free(conv_bare_jid);
g_free(bare_jid);
}
static void lurch_cmd_disable(PurpleConversation * conv_p) {
char * bare_jid = (void *) 0;
void * plugins_handle = purple_plugins_get_handle();
PurpleConversationType conv_type = purple_conversation_get_type(conv_p);
char * conv_bare_jid = jabber_get_bare_jid(purple_conversation_get_name(conv_p));
PurpleAccount * acc_p = purple_conversation_get_account(conv_p);
const char * conv_name = purple_conversation_get_name(conv_p);
if (conv_type == PURPLE_CONV_TYPE_IM) {
purple_signal_emit(purple_plugins_get_handle(), "lurch-disable-im", purple_conversation_get_account(conv_p), conv_bare_jid, lurch_disable_print, conv_p);
switch (conv_type) {
case PURPLE_CONV_TYPE_IM:
bare_jid = jabber_get_bare_jid(conv_name);
purple_signal_emit(plugins_handle, "lurch-disable-im", acc_p, bare_jid, lurch_disable_print, conv_p);
break;
case PURPLE_CONV_TYPE_CHAT:
purple_signal_emit(plugins_handle, "lurch-disable-chat", acc_p, conv_name, lurch_disable_print, conv_p);
break;
default:
lurch_cmd_print_err(conv_p, "Conversation type not supported.");
break;
}
g_free(conv_bare_jid);
g_free(bare_jid);
}
static void lurch_cmd_fp(PurpleConversation * conv_p, const char * arg) {
......@@ -233,14 +286,25 @@ static void lurch_cmd_fp(PurpleConversation * conv_p, const char * arg) {
}
static void lurch_cmd_status(PurpleConversation * conv_p) {
char * bare_jid = (void *) 0;
const char * conv_name = purple_conversation_get_name(conv_p);
PurpleConversationType conv_type = purple_conversation_get_type(conv_p);
char * conv_bare_jid = jabber_get_bare_jid(purple_conversation_get_name(conv_p));
void * plugins_handle = purple_plugins_get_handle();
PurpleAccount * acc_p = purple_conversation_get_account(conv_p);
if (conv_type == PURPLE_CONV_TYPE_IM) {
purple_signal_emit(purple_plugins_get_handle(), "lurch-status-im", purple_conversation_get_account(conv_p), conv_bare_jid, lurch_status_im_print ,conv_p);
switch (conv_type) {
case PURPLE_CONV_TYPE_IM:
bare_jid = jabber_get_bare_jid(conv_name);
purple_signal_emit(plugins_handle, "lurch-status-im", acc_p, bare_jid, lurch_status_im_print, conv_p);
break;
case PURPLE_CONV_TYPE_CHAT:
purple_signal_emit(plugins_handle, "lurch-status-chat", acc_p, conv_name, lurch_status_chat_print, conv_p);
break;
default:
lurch_cmd_print_err(conv_p, "Conversation type not supported.");
}
g_free(conv_bare_jid);
g_free(bare_jid);
}
PurpleCmdRet lurch_cmd_func_v2(PurpleConversation * conv_p,
......@@ -267,4 +331,4 @@ PurpleCmdRet lurch_cmd_func_v2(PurpleConversation * conv_p,
}
return PURPLE_CMD_RET_OK;
}
\ No newline at end of file
}
This diff is collapsed.
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