Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Librem5
lurch
Commits
108a7a5a
Commit
108a7a5a
authored
Feb 21, 2020
by
Andrea Schaefer
Browse files
Merge branch 'dev' of
https://github.com/gkdr/lurch
into dev
parents
f0f83e86
664709cf
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
.appveyor.yml
View file @
108a7a5a
...
...
@@ -11,10 +11,10 @@ build_script:
-
sh
:
make
test_script
:
-
sh
:
CMOCKA_MESSAGE_OUTPUT=XML CMOCKA_XML_FILE=build/cmocka_results.xml make test
-
sh
:
CMOCKA_MESSAGE_OUTPUT=XML CMOCKA_XML_FILE=build/cmocka_results
_%g
.xml make test
--ignore-errors
after_test
:
-
sh
:
curl -v -F "file=@$APPVEYOR_BUILD_FOLDER/
build/cmocka_results.xml
" "https://ci.appveyor.com/api/testresults/junit/$APPVEYOR_JOB_ID"
-
sh
:
find build/ -type f -name *.xml -exec
curl -v -F "file=@$APPVEYOR_BUILD_FOLDER/
{}
" "https://ci.appveyor.com/api/testresults/junit/$APPVEYOR_JOB_ID"
\;
-
sh
:
bash <(curl -s https://codecov.io/bash) -g test/ -B $APPVEYOR_REPO_BRANCH -b $APPVEYOR_BUILD_VERSION
artifacts
:
...
...
Makefile
View file @
108a7a5a
...
...
@@ -58,13 +58,7 @@ PLUGIN_CPPFLAGS=-DPURPLE_PLUGINS
# -D_BSD_SOURCE can be removed once nobody uses glibc <= 2.18 any more
CPPFLAGS
+=
-D_XOPEN_SOURCE
=
700
-D_BSD_SOURCE
-D_DEFAULT_SOURCE
LDFLAGS
+=
-ldl
-lm
$(PKGCFG_L)
$(LJABBER)
-Wl
,-rpath,
$(PURPLE_PLUGIN_DIR)
LDFLAGS_T
=
$(LDFLAGS)
-lpurple
-lcmocka
\
-Wl
,--wrap
=
purple_user_dir
\
-Wl
,--wrap
=
purple_prefs_get_bool
\
-Wl
,--wrap
=
purple_prefs_get_int
\
-Wl
,--wrap
=
purple_debug_error
\
-Wl
,--wrap
=
purple_debug_info
\
-Wl
,--wrap
=
purple_debug_misc
\
LDFLAGS_T
=
$(LDFLAGS)
-lpurple
-lcmocka
### directories
#
...
...
@@ -95,6 +89,7 @@ OBJECTS := $(patsubst $(SDIR)/%.c, $(BDIR)/%.o, $(SOURCES))
OBJECTS_W_COVERAGE
:=
$(
patsubst
$(SDIR)
/%.c,
$(BDIR)
/%_w_coverage.o,
$(SOURCES)
)
TEST_SOURCES
:=
$(
wildcard
$(TDIR)
/test_
*
.c
)
TEST_OBJECTS
:=
$(
patsubst
$(TDIR)
/test_%.c,
$(BDIR)
/test_%.o,
$(TEST_SOURCES)
)
TEST_TARGETS
:=
$(
patsubst
$(TDIR)
/test_%.c,
$(BDIR)
/test_%,
$(TEST_SOURCES)
)
VENDOR_LIBS
=
$(LOMEMO_PATH)
$(AXC_PATH)
$(AX_PATH)
...
...
@@ -157,9 +152,41 @@ tarball: | clean-all $(BDIR)
mv
$(TARBALL_FILE_NAME)
$(TARBALL_DIR_NAME)
/
mv
$(TARBALL_DIR_NAME)
$(BDIR)
/
test
:
$(TEST_OBJECTS) $(OBJECTS_W_COVERAGE) $(VENDOR_LIBS)
$(CC)
$(CFLAGS)
$(CPPFLAGS)
-O0
--coverage
$^
$(PURPLE_DIR)
/libjabber.so.0
-o
$(BDIR)
/
$@
$(LDFLAGS_T)
-
$(BDIR)
/
$@
2>&1 |
grep
-Ev
".*CRITICAL.*"
|
tr
-s
'\n'
# filter annoying and irrelevant glib output
$(BDIR)/test_lurch_util
:
$(OBJECTS_W_COVERAGE) $(VENDOR_LIBS) $(BDIR)/test_lurch_util.o
$(CC)
$(CFLAGS)
$(CPPFLAGS)
-O0
--coverage
$^
$(PURPLE_DIR)
/libjabber.so.0
-o
$@
$(LDFLAGS_T)
\
-Wl
,--wrap
=
purple_user_dir
\
-Wl
,--wrap
=
purple_prefs_get_bool
\
-Wl
,--wrap
=
purple_prefs_get_int
\
-Wl
,--wrap
=
purple_debug_error
\
-Wl
,--wrap
=
purple_debug_info
\
-Wl
,--wrap
=
purple_debug_misc
\
-Wl
,--wrap
=
purple_base16_encode_chunked
bash
-c
"set -o pipefail;
$@
2>&1 | grep -Ev "
.
*
CRITICAL.
*
" | tr -s '
\n
'"
# filter annoying and irrelevant glib output
$(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
=
purple_account_get_connection
\
-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
test
:
$(OBJECTS_W_COVERAGE) $(VENDOR_LIBS) $(TEST_TARGETS)
coverage
:
test
gcovr
-r
.
--html
--html-details
-o
build/coverage.html
...
...
libomemo
@
e3b2125e
Compare
3c826817
...
e3b2125e
Subproject commit
3c8268172829996ec1f1e7b7a12df5c63ceb0ef1
Subproject commit
e3b2125eb630e7137ea2b904bf4ddc6bdc106092
src/lurch.c
View file @
108a7a5a
...
...
@@ -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
);
...
...
@@ -2142,7 +2135,6 @@ static PurpleCmdRet lurch_cmd_func(PurpleConversation * conv_p,
uint32_t
id
=
0
;
uint32_t
remove_id
=
0
;
axc_buf
*
key_buf_p
=
(
void
*
)
0
;
gchar
*
fp
=
(
void
*
)
0
;
char
*
fp_printable
=
(
void
*
)
0
;
omemo_devicelist
*
own_dl_p
=
(
void
*
)
0
;
omemo_devicelist
*
other_dl_p
=
(
void
*
)
0
;
...
...
@@ -2205,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. "
...
...
@@ -2302,8 +2293,7 @@ static PurpleCmdRet lurch_cmd_func(PurpleConversation * conv_p,
goto
cleanup
;
}
fp
=
purple_base16_encode_chunked
(
axc_buf_get_data
(
key_buf_p
),
axc_buf_get_len
(
key_buf_p
));
fp_printable
=
lurch_util_fp_get_printable
(
fp
);
fp_printable
=
lurch_util_fp_get_printable
(
key_buf_p
);
msg
=
g_strdup_printf
(
"This device's fingerprint is:
\n
%s
\n
"
"You should make sure that your conversation partner gets displayed the same for this device."
,
fp_printable
);
}
else
if
(
!
g_strcmp0
(
args
[
2
],
"conv"
))
{
...
...
@@ -2314,8 +2304,7 @@ static PurpleCmdRet lurch_cmd_func(PurpleConversation * conv_p,
goto
cleanup
;
}
fp
=
purple_base16_encode_chunked
(
axc_buf_get_data
(
key_buf_p
),
axc_buf_get_len
(
key_buf_p
));
fp_printable
=
lurch_util_fp_get_printable
(
fp
);
fp_printable
=
lurch_util_fp_get_printable
(
key_buf_p
);
temp_msg_1
=
g_strdup_printf
(
"The devices participating in this conversation and their fingerprints are as follows:
\n
"
"This device's (%s:%i) fingerprint:
\n
%s
\n
"
,
uname
,
id
,
fp_printable
);
...
...
@@ -2337,9 +2326,7 @@ static PurpleCmdRet lurch_cmd_func(PurpleConversation * conv_p,
continue
;
}
g_free
(
fp
);
fp
=
purple_base16_encode_chunked
(
axc_buf_get_data
(
key_buf_p
),
axc_buf_get_len
(
key_buf_p
));
fp_printable
=
lurch_util_fp_get_printable
(
fp
);
fp_printable
=
lurch_util_fp_get_printable
(
key_buf_p
);
axc_buf_free
(
key_buf_p
);
key_buf_p
=
(
void
*
)
0
;
...
...
@@ -2371,9 +2358,7 @@ static PurpleCmdRet lurch_cmd_func(PurpleConversation * conv_p,
continue
;
}
g_free
(
fp
);
fp
=
purple_base16_encode_chunked
(
axc_buf_get_data
(
key_buf_p
),
axc_buf_get_len
(
key_buf_p
));
fp_printable
=
lurch_util_fp_get_printable
(
fp
);
fp_printable
=
lurch_util_fp_get_printable
(
key_buf_p
);
axc_buf_free
(
key_buf_p
);
key_buf_p
=
(
void
*
)
0
;
...
...
@@ -2475,7 +2460,6 @@ cleanup:
axc_context_destroy_all
(
axc_ctx_p
);
g_free
(
msg
);
axc_buf_free
(
key_buf_p
);
g_free
(
fp
);
g_free
(
fp_printable
);
omemo_devicelist_destroy
(
own_dl_p
);
omemo_devicelist_destroy
(
other_dl_p
);
...
...
src/lurch_api.c
View file @
108a7a5a
...
...
@@ -2,6 +2,7 @@
#include
<glib.h>
#include
<purple.h>
#include
"chat.h"
#include
"pep.h"
#include
"axc.h"
...
...
@@ -185,12 +186,49 @@ 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
;
axc_context
*
axc_ctx_p
=
(
void
*
)
0
;
axc_buf
*
key_buf_p
=
(
void
*
)
0
;
gchar
*
fp
=
(
void
*
)
0
;
char
*
fp_printable
=
(
void
*
)
0
;
uname
=
lurch_util_uname_strip
(
purple_account_get_username
(
acc_p
));
...
...
@@ -207,20 +245,18 @@ void lurch_api_fp_get_handler(PurpleAccount * acc_p, void (*cb)(int32_t err, con
goto
cleanup
;
}
fp
=
purple_base16_encode_chunked
(
axc_buf_get_data
(
key_buf_p
),
axc_buf_get_len
(
key_buf_p
));
fp_printable
=
lurch_util_fp_get_printable
(
fp
);
fp_printable
=
lurch_util_fp_get_printable
(
key_buf_p
);
cleanup:
cb
(
ret_val
,
fp_printable
,
user_data_p
);
g_free
(
fp_printable
);
g_free
(
fp
);
axc_buf_free
(
key_buf_p
);
axc_context_destroy_all
(
axc_ctx_p
);
}
/**
* Given a list of IDs, retrieves the public keys from the libsignal sessions and creates hash table with ID to fingerprint pairs.
* Given a list of IDs, retrieves the public keys from the libsignal sessions and creates
a
hash table with ID to fingerprint pairs.
* If there is an entry in the devicelist, but no session yet, the fingerprint cannot be retrieved this way and the value will be NULL.
* g_hash_table_destroy() the table when done with it.
*/
...
...
@@ -230,7 +266,6 @@ static int32_t lurch_api_fp_create_table(const char * jid, axc_context * axc_ct
const
GList
*
curr_p
=
(
void
*
)
0
;
uint32_t
curr_device_id
=
0
;
axc_buf
*
key_buf_p
=
(
void
*
)
0
;
gchar
*
fp
=
(
void
*
)
0
;
id_fp_table
=
g_hash_table_new_full
(
g_int_hash
,
g_int_equal
,
NULL
,
g_free
);
...
...
@@ -247,13 +282,10 @@ static int32_t lurch_api_fp_create_table(const char * jid, axc_context * axc_ct
continue
;
}
fp
=
purple_base16_encode_chunked
(
axc_buf_get_data
(
key_buf_p
),
axc_buf_get_len
(
key_buf_p
));
(
void
)
g_hash_table_insert
(
id_fp_table
,
curr_p
->
data
,
lurch_util_fp_get_printable
(
fp
));
(
void
)
g_hash_table_insert
(
id_fp_table
,
curr_p
->
data
,
lurch_util_fp_get_printable
(
key_buf_p
));
axc_buf_free
(
key_buf_p
);
key_buf_p
=
(
void
*
)
0
;
g_free
(
fp
);
fp
=
(
void
*
)
0
;
ret_val
=
0
;
}
...
...
@@ -276,7 +308,6 @@ void lurch_api_fp_list_handler(PurpleAccount * acc_p, void (*cb)(int32_t err, GH
axc_context
*
axc_ctx_p
=
(
void
*
)
0
;
GHashTable
*
id_fp_table
=
(
void
*
)
0
;
axc_buf
*
key_buf_p
=
(
void
*
)
0
;
gchar
*
fp
=
(
void
*
)
0
;
ret_val
=
lurch_api_id_list_get_own
(
acc_p
,
&
own_id_list
);
if
(
ret_val
)
{
...
...
@@ -306,10 +337,7 @@ void lurch_api_fp_list_handler(PurpleAccount * acc_p, void (*cb)(int32_t err, GH
goto
cleanup
;
}
fp
=
purple_base16_encode_chunked
(
axc_buf_get_data
(
key_buf_p
),
axc_buf_get_len
(
key_buf_p
));
(
void
)
g_hash_table_insert
(
id_fp_table
,
own_id_list
->
data
,
lurch_util_fp_get_printable
(
fp
));
g_free
(
fp
);
fp
=
(
void
*
)
0
;
(
void
)
g_hash_table_insert
(
id_fp_table
,
own_id_list
->
data
,
lurch_util_fp_get_printable
(
key_buf_p
));
cleanup:
cb
(
ret_val
,
id_fp_table
,
user_data_p
);
...
...
@@ -319,7 +347,6 @@ cleanup:
axc_context_destroy_all
(
axc_ctx_p
);
g_hash_table_destroy
(
id_fp_table
);
axc_buf_free
(
key_buf_p
);
g_free
(
fp
);
}
// returns NULL as hash table if devicelist is empty
...
...
@@ -434,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
);
...
...
@@ -454,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"
,
...
...
@@ -472,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
,
...
...
@@ -483,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
,
...
...
@@ -563,4 +679,4 @@ void lurch_api_unload() {
purple_signal_unregister
(
plugins_handle_p
,
signal_name
);
}
}
\ No newline at end of file
}
src/lurch_api.h
View file @
108a7a5a
...
...
@@ -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
*
...
...
@@ -43,4 +49,88 @@ typedef enum {
* - Emit the signal using the plugin system handle as the instance and pass the necessary data.
* If you do it wrong, there will be no compiler errors and the pointers are gibberish, so take care.
* You can easily get the plugin system handle anywhere by calling purple_plugins_get_handle().
*/
\ No newline at end of file
*/
/**
* SIGNAL: lurch-id-list
*
* Gets the specified account's OMEMO devicelist and passes it to the callback as a GList containing uint32_t *.
* To access the actual ID, cast the data member to a uint32_t * and dereference it.
* This device's ID will be the first item in the list.
*/
void
lurch_api_id_list_handler
(
PurpleAccount
*
acc_p
,
void
(
*
cb
)(
int32_t
err
,
GList
*
id_list
,
void
*
user_data_p
),
void
*
user_data_p
);
/**
* SIGNAL: lurch-id-remove
*
* Removes the specified OMEMO device ID from the specified account's devicelist.
*/
void
lurch_api_id_remove_handler
(
PurpleAccount
*
acc_p
,
uint32_t
device_id
,
void
(
*
cb
)(
int32_t
err
,
void
*
user_data_p
),
void
*
user_data_p
);
/**
* SIGNAL: lurch-enable-im
*
* Enables OMEMO for the specified contact.
*/
void
lurch_api_enable_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-disable-im
*
* 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
);
/**
* 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
*
* 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
);
/**
* 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
);
src/lurch_cmd_ui.c
View file @
108a7a5a
...
...
@@ -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
;