Skip to content

Commit

Permalink
Add Jingle: XEP-0166, XEP-0234, XEP-0261, XEP-0047
Browse files Browse the repository at this point in the history
Jingle is a session negotiation protocol,
it can not transfer data by itself,
but it enables us to transfer data
over negotiated channels.

To transfer files over Jingle, the IBB is a required channel,
it's very stable (over XMPP), but it's slow.

It's planned to add Socks5 and over protocols in the future
updates,
but for now this is a minimal setup to use the Jingle for file transfer.

Special thanks to the @jubalh and @jaeckel for their support and
contributions.
  • Loading branch information
H3rnand3zzz committed Sep 18, 2023
1 parent 0de0594 commit 99b327d
Show file tree
Hide file tree
Showing 19 changed files with 2,043 additions and 21 deletions.
4 changes: 4 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ core_sources = \
src/chatlog.c src/chatlog.h \
src/database.h src/database.c \
src/log.h src/profanity.c src/common.h \
src/xmpp/jingle.c src/xmpp/jingle.h src/xmpp/ibb.c src/xmpp/ibb.h \
src/profanity.h src/xmpp/chat_session.c \
src/xmpp/chat_session.h src/xmpp/muc.c src/xmpp/muc.h src/xmpp/jid.h src/xmpp/jid.c \
src/xmpp/chat_state.h src/xmpp/chat_state.c \
Expand Down Expand Up @@ -84,6 +85,7 @@ unittest_sources = \
src/xmpp/resource.c src/xmpp/resource.h \
src/xmpp/chat_state.h src/xmpp/chat_state.c \
src/xmpp/roster_list.c src/xmpp/roster_list.h \
src/xmpp/jingle.c src/xmpp/jingle.h src/xmpp/ibb.c src/xmpp/ibb.h \
src/xmpp/xmpp.h src/xmpp/form.c \
src/ui/ui.h \
src/otr/otr.h \
Expand Down Expand Up @@ -127,6 +129,8 @@ unittest_sources = \
tests/unittests/xmpp/stub_vcard.c \
tests/unittests/xmpp/stub_avatar.c \
tests/unittests/xmpp/stub_ox.c \
tests/unittests/xmpp/stub_connection.c \
tests/unittests/xmpp/stub_iq.c \
tests/unittests/xmpp/stub_xmpp.c \
tests/unittests/xmpp/stub_message.c \
tests/unittests/ui/stub_ui.c tests/unittests/ui/stub_ui.h \
Expand Down
44 changes: 44 additions & 0 deletions profanity.doap
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@
</xmpp:SupportedXep>
</implements>

<!-- XEP-0047: In-Band Bytestreams -->
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource='https://xmpp.org/extensions/xep-0045.html'/>
<xmpp:status>complete</xmpp:status>
<xmpp:version>2.0.1</xmpp:version>
<xmpp:since>DEV</xmpp:since>
<xmpp:note xml:lang='en'></xmpp:note>
</xmpp:SupportedXep>
</implements>

<!-- XEP-0048: Bookmarks -->
<implements>
<xmpp:SupportedXep>
Expand Down Expand Up @@ -255,6 +266,17 @@
</xmpp:SupportedXep>
</implements>

<!-- XEP-0166: Jingle -->
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource='https://xmpp.org/extensions/xep-0166.html'/>
<xmpp:status>partial</xmpp:status>
<xmpp:version>1.1.2</xmpp:version>
<xmpp:since>DEV</xmpp:since>
<xmpp:note xml:lang='en'></xmpp:note>
</xmpp:SupportedXep>
</implements>

<!-- XEP-0184: Message Delivery Receipts -->
<implements>
<xmpp:SupportedXep>
Expand Down Expand Up @@ -310,6 +332,17 @@
</xmpp:SupportedXep>
</implements>

<!-- XEP-0234: Jingle File Transfer -->
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource='https://xmpp.org/extensions/xep-0234.html'/>
<xmpp:status>partial</xmpp:status>
<xmpp:version>0.19.1</xmpp:version>
<xmpp:since>DEV</xmpp:since>
<xmpp:note xml:lang='en'></xmpp:note>
</xmpp:SupportedXep>
</implements>

<!-- XEP-0245: The /me Command -->
<implements>
<xmpp:SupportedXep>
Expand Down Expand Up @@ -343,6 +376,17 @@
</xmpp:SupportedXep>
</implements>

<!-- XEP-0261: Jingle In-Band Bytestreams Transport Method -->
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource='https://xmpp.org/extensions/xep-0261.html'/>
<xmpp:status>partial</xmpp:status>
<xmpp:version>1.0</xmpp:version>
<xmpp:since>DEV</xmpp:since>
<xmpp:note xml:lang='en'></xmpp:note>
</xmpp:SupportedXep>
</implements>

<!-- XEP-0280: Message Carbons -->
<implements>
<xmpp:SupportedXep>
Expand Down
26 changes: 24 additions & 2 deletions src/command/cmd_defs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2726,12 +2726,34 @@ static const struct cmd_t command_defs[] = {
"session_alarm to configure an alarm when more clients log in.")
CMD_ARGS(
{ "logging on|redact|off", "Switch chat logging. This will also disable logging in the internally used SQL database. Your messages will not be saved anywhere locally. This might have unintended consequences, such as not being able to decrypt OMEMO encrypted messages received later via MAM, and should be used with caution." },
{ "os on|off", "Choose whether to include the OS name if a user asks for software information (XEP-0092)." }
)
{ "os on|off", "Choose whether to include the OS name if a user asks for software information (XEP-0092)." })
CMD_EXAMPLES(
"/privacy logging off",
"/privacy os off")
},

{ CMD_PREAMBLE("/jingle", // TODO: autocomplete
parse_args, 2, 1000, NULL)
CMD_MAINFUNC(cmd_jingle)
CMD_TAGS(
CMD_TAG_CHAT)
CMD_SYN(
"/jingle session accept|reject|cancel [<session_id|jid>]",
"/jingle sendfiles [<jid>] <file1> <file2> ... <fileN>")
CMD_DESC(
"Manage Jingle sessions. "
"Jingle (XEP-0166) allows you to set up sessions for files transfer and A/V calls. "
"Currently only file transfer is supported. "
"WARNING: files are transfered in PLAIN TEXT format, it means that your "
"or your recipient's XMPP provider can access the file's content.")
CMD_ARGS(
{ "session accept|reject|cancel <session_id|jid>", "Accept/reject session upon the request from other user (e.g. accept file transfer) or to cancel ongoing session." },
{ "sendfiles <jid> <file1> <file2> ...", "Send a file(s) to recipient." })
CMD_EXAMPLES(
"/jingle session accept SESSION_ID",
"/jingle session reject [email protected]",
"/jingle sendfiles [email protected] meme.jpg naked_valkyrie.png") // TODO: remove joke before release
},
// NEXT-COMMAND (search helper)
};

Expand Down
102 changes: 102 additions & 0 deletions src/command/cmd_funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
#include "xmpp/connection.h"
#include "xmpp/contact.h"
#include "xmpp/jid.h"
#include "xmpp/jingle.h"
#include "xmpp/muc.h"
#include "xmpp/roster_list.h"
#include "xmpp/session.h"
Expand Down Expand Up @@ -10835,3 +10836,104 @@ cmd_vcard_save(ProfWin* window, const char* const command, gchar** args)
cons_show("User vCard uploaded");
return TRUE;
}

// TODO: Also list sessions
gboolean
cmd_jingle(ProfWin* window, const char* const command, gchar** args)
{
if (connection_get_status() != JABBER_CONNECTED) {
cons_show("You are not currently connected.");
return TRUE;
}

if (g_strcmp0(args[0], "session") == 0) {
const char* session_id = NULL;
// todo: check arg length

// if contains @, then it's a jid
if (g_strrstr(args[2], "@") != NULL) {
session_id = jingle_find_unique_session_by_jid(args[2]);
if (!session_id) {
return TRUE;
}
} else {
session_id = args[2];
}

const gchar* action = args[1];
if (g_strcmp0(action, "accept") == 0) {
if (jingle_accept_session(session_id)) {
cons_show("Successfully %sed the jingle session %s", action, session_id);
} else {
cons_show("Unable to %s the session.", action);
}
} else if (g_strcmp0(action, "reject") == 0) {
if (jingle_reject_session(session_id)) {
cons_show("Successfully %sed the jingle session %s", action, session_id);
} else {
cons_show("Unable to %s the session.", action);
}
} else if (g_strcmp0(action, "cancel") == 0) {
if (jingle_cancel_session(session_id)) {
cons_show("Successfully %sed the jingle session %s", action, session_id);
} else {
cons_show("Unable to %s the session.", action);
}
} else {
cons_show_error("Invalid session action.");
cons_bad_cmd_usage(command);
}

// /jingle sendfiles [<jid>] <file1> <file2> ... <fileN>
} else if (g_strcmp0(args[0], "sendfiles") == 0) {
auto_jid Jid* jid = jid_create(args[1]);
char* recipient = NULL;

if (!jid || !jid->resourcepart) {
if (window->type == WIN_CHAT) {
ProfChatWin* chatwin = (ProfChatWin*)window;
assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);

char* resource = NULL;
ChatSession* session = chat_session_get(chatwin->barejid);
if (chatwin->resource_override) {
resource = chatwin->resource_override;
} else if (session && session->resource) {
resource = session->resource;
}

if (resource) {
recipient = g_strdup_printf("%s/%s", chatwin->barejid, resource);
} else {
win_println(window, THEME_DEFAULT, "-", "[Jingle] Unable to fetch resource for the current window.");
return TRUE;
}

} else if (window->type == WIN_PRIVATE) {
ProfPrivateWin* privatewin = (ProfPrivateWin*)window;
assert(privatewin->memcheck == PROFPRIVATEWIN_MEMCHECK);
jid = jid_create(privatewin->fulljid);
if (!jid) {
win_println(window, THEME_DEFAULT, "-", "[Jingle] Unable to get jid.");
}
} else {
cons_show_error("Invalid JID provided. Please, provide correct full JID.");
return TRUE;
}
} else {
recipient = strdup(jid->fulljid);
}
GList* files = NULL;

for (int i = 2; args[i] != NULL; i++) {
files = g_list_append(files, args[i]);
}

jingle_send_files(recipient, files);
} else {
cons_show_error("Invalid action.");
cons_bad_cmd_usage(command);
}

return TRUE;
}
1 change: 1 addition & 0 deletions src/command/cmd_funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,5 +268,6 @@ gboolean cmd_vcard_photo(ProfWin* window, const char* const command, gchar** arg
gboolean cmd_vcard_refresh(ProfWin* window, const char* const command, gchar** args);
gboolean cmd_vcard_set(ProfWin* window, const char* const command, gchar** args);
gboolean cmd_vcard_save(ProfWin* window, const char* const command, gchar** args);
gboolean cmd_jingle(ProfWin* window, const char* const command, gchar** args);

#endif
8 changes: 8 additions & 0 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,14 @@ strtoi_range(const char* str, int* saveptr, int min, int max, gchar** err_msg)
return TRUE;
}

gboolean
string_to_ul(const char* s, unsigned long* ul)
{
char* endptr;
*ul = strtoul(s, &endptr, 10);
return *endptr == '\0';
}

int
utf8_display_len(const char* const str)
{
Expand Down
1 change: 1 addition & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ gboolean create_dir(const char* name);
gboolean copy_file(const char* const src, const char* const target, const gboolean overwrite_existing);
char* str_replace(const char* string, const char* substr, const char* replacement);
gboolean strtoi_range(const char* str, int* saveptr, int min, int max, char** err_msg);
gboolean string_to_ul(const char* s, unsigned long* ul);
int utf8_display_len(const char* const str);

char* release_get_latest(void);
Expand Down
6 changes: 6 additions & 0 deletions src/profanity.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
#include "xmpp/chat_session.h"
#include "xmpp/chat_state.h"
#include "xmpp/contact.h"
#include "xmpp/ibb.h"
#include "xmpp/jingle.h"
#include "xmpp/roster_list.h"

#ifdef HAVE_LIBOTR
Expand Down Expand Up @@ -216,6 +218,8 @@ _init(char* log_level, char* config_file, char* log_file, char* theme_name)
#ifdef HAVE_GTK
tray_init();
#endif
jingle_init();
ibb_init();
inp_nonblocking(TRUE);
ui_resize();
}
Expand Down Expand Up @@ -251,6 +255,8 @@ _shutdown(void)
#ifdef HAVE_OMEMO
omemo_close();
#endif
jingle_close();
ibb_close();
chat_log_close();
theme_close();
accounts_close();
Expand Down
3 changes: 3 additions & 0 deletions src/xmpp/capabilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ caps_init(void)
g_hash_table_add(prof_features, strdup(STANZA_NS_CHATSTATES));
g_hash_table_add(prof_features, strdup(STANZA_NS_PING));
g_hash_table_add(prof_features, strdup(STANZA_NS_STABLE_ID));
g_hash_table_add(prof_features, strdup(STANZA_NS_JINGLE));
g_hash_table_add(prof_features, strdup(STANZA_NS_JINGLE_FT5));
g_hash_table_add(prof_features, strdup(STANZA_NS_JINGLE_TRANSPORTS_IBB));

if (prefs_get_boolean(PREF_RECEIPTS_SEND)) {
g_hash_table_add(prof_features, strdup(STANZA_NS_RECEIPTS));
Expand Down
Loading

0 comments on commit 99b327d

Please sign in to comment.