diff options
-rw-r--r-- | CONTRIBUTING.md | 2 | ||||
-rw-r--r-- | Dockerfile.debian | 3 | ||||
-rwxr-xr-x | ci-build.sh | 12 | ||||
-rw-r--r-- | src/command/cmd_defs.c | 26 | ||||
-rw-r--r-- | src/command/cmd_funcs.c | 65 | ||||
-rw-r--r-- | src/command/cmd_funcs.h | 1 | ||||
-rw-r--r-- | src/xmpp/connection.c | 360 | ||||
-rw-r--r-- | src/xmpp/connection.h | 2 | ||||
-rw-r--r-- | src/xmpp/session.c | 2 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 37 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 1 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 5 | ||||
-rw-r--r-- | tests/unittests/xmpp/stub_xmpp.c | 12 | ||||
-rw-r--r-- | themes/snikket | 82 |
14 files changed, 600 insertions, 10 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7eb92846..91e2b55c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -60,6 +60,6 @@ scan-view ... ### Finding typos We include a `.codespellrc` configuration file for `codespell` in the root directory. -Before comitting it might make sense to run `codespell` to see if you made any typos. +Before committing it might make sense to run `codespell` to see if you made any typos. You can run the `make spell` command for this. diff --git a/Dockerfile.debian b/Dockerfile.debian index 501a0348..4b8f0596 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -25,7 +25,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libxss-dev \ make \ pkg-config \ - python-dev \ + python3-dev \ + python-dev-is-python3 \ libsqlite3-dev RUN mkdir -p /usr/src/{stabber,libmesode,profanity} diff --git a/ci-build.sh b/ci-build.sh index 2d615a9a..e7574b1e 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -45,11 +45,11 @@ case $(uname | tr '[:upper:]' '[:lower:]') in "--enable-notifications --enable-icons-and-clipboard --enable-otr --enable-pgp --enable-omemo --enable-plugins --enable-c-plugins --enable-python-plugins --with-xscreensaver" - "--disable-notifications --disable-icons --disable-otr --disable-pgp + "--disable-notifications --disable-icons-and-clipboard --disable-otr --disable-pgp --disable-omemo --disable-plugins --disable-c-plugins --disable-python-plugins --without-xscreensaver" "--disable-notifications" - "--disable-icons" + "--disable-icons-and-clipboard" "--disable-otr" "--disable-pgp" "--disable-omemo" @@ -67,11 +67,11 @@ case $(uname | tr '[:upper:]' '[:lower:]') in "--enable-notifications --enable-icons-and-clipboard --enable-otr --enable-pgp --enable-omemo --enable-plugins --enable-c-plugins --enable-python-plugins" - "--disable-notifications --disable-icons --disable-otr --disable-pgp + "--disable-notifications --disable-icons-and-clipboard --disable-otr --disable-pgp --disable-omemo --disable-plugins --disable-c-plugins --disable-python-plugins" "--disable-notifications" - "--disable-icons" + "--disable-icons-and-clipboard" "--disable-otr" "--disable-pgp" "--disable-omemo" @@ -95,11 +95,11 @@ case $(uname | tr '[:upper:]' '[:lower:]') in "--enable-notifications --enable-icons-and-clipboard --enable-otr --enable-pgp --enable-omemo --enable-plugins --enable-c-plugins --enable-python-plugins" - "--disable-notifications --disable-icons --disable-otr --disable-pgp + "--disable-notifications --disable-icons-and-clipboard --disable-otr --disable-pgp --disable-omemo --disable-plugins --disable-c-plugins --disable-python-plugins" "--disable-notifications" - "--disable-icons" + "--disable-icons-and-clipboard" "--disable-otr" "--disable-pgp" "--disable-omemo" diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 85631a34..7bc4a1ff 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -2653,6 +2653,32 @@ static struct cmd_t command_defs[] = { CMD_NOEXAMPLES }, + { "/register", + parse_args, 2, 6, NULL, + CMD_NOSUBFUNCS + CMD_MAINFUNC(cmd_register) + CMD_TAGS( + CMD_TAG_CONNECTION) + CMD_SYN( + "/register <username> <server> [port <port>] [tls force|allow|trust|legacy|disable]") + CMD_DESC( + "Register an account on a server.") + CMD_ARGS( + { "<username>", "Username to register with." }, + { "<server>", "Server to register account on." }, + { "port <port>", "The port to use if different to the default (5222, or 5223 for SSL)." }, + { "tls force", "Force TLS connection, and fail if one cannot be established. This is the default behavior." }, + { "tls allow", "Use TLS for the connection if it is available." }, + { "tls trust", "Force TLS connection and trust the server's certificate." }, + { "tls legacy", "Use legacy TLS for the connection. This forces TLS just after the TCP connection is established. Use when a server doesn't support STARTTLS." }, + { "tls disable", "Disable TLS for the connection." }) + CMD_EXAMPLES( + "/register odin valhalla.edda ", + "/register freyr vanaheimr.edda port 5678", + "/register me 127.0.0.1 tls disable", + "/register someuser my.xmppserv.er port 5443 tls force") + }, + // NEXT-COMMAND (search helper) }; diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index fdf6e3d9..3ce45a93 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -9598,3 +9598,68 @@ cmd_silence(ProfWin* window, const char* const command, gchar** args) return TRUE; } + +gboolean +cmd_register(ProfWin* window, const char* const command, gchar** args) +{ + gchar* opt_keys[] = { "port", "tls", "auth", NULL }; + gboolean parsed; + + GHashTable* options = parse_options(&args[2], opt_keys, &parsed); + if (!parsed) { + cons_bad_cmd_usage(command); + cons_show(""); + options_destroy(options); + return TRUE; + } + + char* tls_policy = g_hash_table_lookup(options, "tls"); + if (tls_policy && (g_strcmp0(tls_policy, "force") != 0) && (g_strcmp0(tls_policy, "allow") != 0) && (g_strcmp0(tls_policy, "trust") != 0) && (g_strcmp0(tls_policy, "disable") != 0) && (g_strcmp0(tls_policy, "legacy") != 0)) { + cons_bad_cmd_usage(command); + cons_show(""); + options_destroy(options); + return TRUE; + } + + int port = 0; + if (g_hash_table_contains(options, "port")) { + char* port_str = g_hash_table_lookup(options, "port"); + char* err_msg = NULL; + gboolean res = strtoi_range(port_str, &port, 1, 65535, &err_msg); + if (!res) { + cons_show(err_msg); + cons_show(""); + free(err_msg); + port = 0; + options_destroy(options); + return TRUE; + } + } + + char* username = args[0]; + char* server = args[1]; + + char* passwd = ui_ask_password(false); + char* confirm_passwd = ui_ask_password(true); + + if (g_strcmp0(passwd, confirm_passwd) == 0) { + log_info("Attempting to register account %s on server %s.", username, server); + connection_register(server, port, tls_policy, username, passwd); + } else { + cons_show("The two passwords do not match."); + } + + if (connection_get_status() == JABBER_DISCONNECTED) { + cons_show_error("Connection attempt to server %s port %d failed.", server, port); + log_info("Connection attempt to server %s port %d failed.", server, port); + return TRUE; + } + + free(passwd); + free(confirm_passwd); + + options_destroy(options); + + log_info("we are leaving the registration process"); + return TRUE; +} diff --git a/src/command/cmd_funcs.h b/src/command/cmd_funcs.h index cf6ec5bf..5e2a7876 100644 --- a/src/command/cmd_funcs.h +++ b/src/command/cmd_funcs.h @@ -248,5 +248,6 @@ gboolean cmd_mam(ProfWin* window, const char* const command, gchar** args); gboolean cmd_editor(ProfWin* window, const char* const command, gchar** args); gboolean cmd_correct_editor(ProfWin* window, const char* const command, gchar** args); gboolean cmd_silence(ProfWin* window, const char* const command, gchar** args); +gboolean cmd_register(ProfWin* window, const char* const command, gchar** args); #endif diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 30ef0a9e..5570fb1a 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -58,6 +58,7 @@ #include "event/server_events.h" #include "xmpp/connection.h" #include "xmpp/session.h" +#include "xmpp/stanza.h" #include "xmpp/iq.h" #include "ui/ui.h" @@ -77,6 +78,12 @@ typedef struct prof_conn_t GHashTable* requested_features; } ProfConnection; +typedef struct +{ + const char* username; + const char* password; +} prof_reg_t; + static ProfConnection conn; static gchar* profanity_instance_id = NULL; static gchar* prof_identifier = NULL; @@ -245,6 +252,341 @@ connection_connect(const char* const jid, const char* const passwd, const char* return conn.conn_status; } +static int +iq_reg2_cb(xmpp_conn_t* xmpp_conn, xmpp_stanza_t* stanza, void* userdata) +{ + const char* type; + + (void)userdata; + + type = xmpp_stanza_get_type(stanza); + if (!type || strcmp(type, "error") == 0) { + char* error_message = stanza_get_error_message(stanza); + cons_show_error("Server error: %s", error_message); + log_debug("Registration error: %s", error_message); + goto quit; + } + + if (strcmp(type, "result") != 0) { + log_debug("Expected type 'result', but got %s.", type); + goto quit; + } + + cons_show("Registration successful."); + log_info("Registration successful."); + goto quit; + +quit: + xmpp_disconnect(xmpp_conn); + + return 0; +} + +static int +iq_reg_cb(xmpp_conn_t* xmpp_conn, xmpp_stanza_t* stanza, void* userdata) +{ + prof_reg_t* reg = (prof_reg_t*)userdata; + xmpp_stanza_t* registered = NULL; + xmpp_stanza_t* query; + const char* type; + + type = xmpp_stanza_get_type(stanza); + if (!type || strcmp(type, "error") == 0) { + char* error_message = stanza_get_error_message(stanza); + cons_show_error("Server error: %s", error_message); + log_debug("Registration error: %s", error_message); + xmpp_disconnect(xmpp_conn); + goto quit; + } + + if (strcmp(type, "result") != 0) { + log_debug("Expected type 'result', but got %s.", type); + xmpp_disconnect(xmpp_conn); + goto quit; + } + + query = xmpp_stanza_get_child_by_name(stanza, "query"); + if (query) + registered = xmpp_stanza_get_child_by_name(query, "registered"); + if (registered != NULL) { + cons_show_error("Already registered."); + log_debug("Already registered."); + xmpp_disconnect(xmpp_conn); + goto quit; + } + xmpp_stanza_t* iq = stanza_register_new_account(conn.xmpp_ctx, reg->username, reg->password); + xmpp_id_handler_add(xmpp_conn, iq_reg2_cb, xmpp_stanza_get_id(iq), reg); + xmpp_send(xmpp_conn, iq); + +quit: + return 0; +} + +static int +_register_handle_error(xmpp_conn_t* xmpp_conn, xmpp_stanza_t* stanza, void* userdata) +{ + (void)stanza; + (void)userdata; + + char* error_message = stanza_get_error_message(stanza); + cons_show_error("Server error: %s", error_message); + log_debug("Registration error: %s", error_message); + xmpp_disconnect(xmpp_conn); + + return 0; +} + +static int +_register_handle_proceedtls_default(xmpp_conn_t* xmpp_conn, + xmpp_stanza_t* stanza, + void* userdata) +{ + const char* name = xmpp_stanza_get_name(stanza); + + (void)userdata; + + if (strcmp(name, "proceed") == 0) { + log_debug("Proceeding with TLS."); + if (xmpp_conn_tls_start(xmpp_conn) == 0) { + xmpp_handler_delete(xmpp_conn, _register_handle_error); + xmpp_conn_open_stream_default(xmpp_conn); + } else { + log_debug("TLS failed."); + /* failed tls spoils the connection, so disconnect */ + xmpp_disconnect(xmpp_conn); + } + } + return 0; +} + +static int +_register_handle_missing_features(xmpp_conn_t* xmpp_conn, void* userdata) +{ + (void)userdata; + + log_debug("Timeout"); + xmpp_disconnect(xmpp_conn); + + return 0; +} + +static int +_register_handle_features(xmpp_conn_t* xmpp_conn, xmpp_stanza_t* stanza, void* userdata) +{ + prof_reg_t* reg = (prof_reg_t*)userdata; + xmpp_ctx_t* ctx = conn.xmpp_ctx; + xmpp_stanza_t* child; + xmpp_stanza_t* iq; + char* domain; + + xmpp_timed_handler_delete(xmpp_conn, _register_handle_missing_features); + + /* secure connection if possible */ + child = xmpp_stanza_get_child_by_name(stanza, "starttls"); + if (child && (strcmp(xmpp_stanza_get_ns(child), XMPP_NS_TLS) == 0)) { + log_debug("Server supports TLS. Attempting to establish..."); + child = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(child, "starttls"); + xmpp_stanza_set_ns(child, XMPP_NS_TLS); + xmpp_handler_add(xmpp_conn, _register_handle_proceedtls_default, XMPP_NS_TLS, NULL, + NULL, NULL); + xmpp_send(xmpp_conn, child); + xmpp_stanza_release(child); + return 0; + } + + /* check whether server supports in-band registration */ + child = xmpp_stanza_get_child_by_name(stanza, "register"); + if (!child) { + log_debug("Server does not support in-band registration."); + cons_show_error("Server does not support in-band registration, aborting."); + xmpp_disconnect(xmpp_conn); + return 0; + } + + log_debug("Server supports in-band registration. Attempting registration."); + + domain = strdup(conn.domain); + iq = xmpp_iq_new(ctx, "get", "reg1"); + xmpp_stanza_set_to(iq, domain); + child = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(child, "query"); + xmpp_stanza_set_ns(child, STANZA_NS_REGISTER); + xmpp_stanza_add_child(iq, child); + + xmpp_handler_add(xmpp_conn, iq_reg_cb, STANZA_NS_REGISTER, "iq", NULL, reg); + xmpp_send(xmpp_conn, iq); + + xmpp_free(ctx, domain); + xmpp_stanza_release(child); + xmpp_stanza_release(iq); + + return 0; +} + +static void +_register_handler(xmpp_conn_t* xmpp_conn, + xmpp_conn_event_t status, + int error, + xmpp_stream_error_t* stream_error, + void* userdata) +{ + conn.conn_last_event = status; + + prof_reg_t* reg = (prof_reg_t*)userdata; + int secured; + + (void)error; + (void)stream_error; + + switch (status) { + + case XMPP_CONN_RAW_CONNECT: + log_debug("Raw connection established."); + xmpp_conn_open_stream_default(xmpp_conn); + conn.conn_status = JABBER_RAW_CONNECTED; + break; + + case XMPP_CONN_CONNECT: + log_debug("Connected."); + secured = xmpp_conn_is_secured(xmpp_conn); + conn.conn_status = JABBER_CONNECTED; + log_debug("Connection is %s.\n", + secured ? "secured" : "NOT secured"); + + Jid* my_jid = jid_create(xmpp_conn_get_jid(xmpp_conn)); + conn.domain = strdup(my_jid->domainpart); + jid_destroy(my_jid); + + xmpp_handler_add(xmpp_conn, _register_handle_error, XMPP_NS_STREAMS, "error", NULL, + NULL); + xmpp_handler_add(xmpp_conn, _register_handle_features, XMPP_NS_STREAMS, "features", + NULL, reg); + xmpp_timed_handler_add(xmpp_conn, _register_handle_missing_features, 5000, + NULL); + break; + + case XMPP_CONN_DISCONNECT: + log_debug("Disconnected"); + conn.conn_status = JABBER_DISCONNECTED; + break; + + default: + break; + } +} + +jabber_conn_status_t +connection_register(const char* const altdomain, int port, const char* const tls_policy, + const char* const username, const char* const password) +{ + long flags; + + Jid* jidp = jid_create(altdomain); + if (jidp == NULL) { + log_error("Malformed JID not able to connect: %s", altdomain); + conn.conn_status = JABBER_DISCONNECTED; + return conn.conn_status; + } + + _compute_identifier(jidp->barejid); + jid_destroy(jidp); + + if (conn.xmpp_log) { + free(conn.xmpp_log); + } + conn.xmpp_log = _xmpp_get_file_logger(); + + if (conn.xmpp_conn) { + xmpp_conn_release(conn.xmpp_conn); + } + if (conn.xmpp_ctx) { + xmpp_ctx_free(conn.xmpp_ctx); + } + conn.xmpp_ctx = xmpp_ctx_new(NULL, conn.xmpp_log); + if (conn.xmpp_ctx == NULL) { + log_warning("Failed to get libstrophe ctx during connect"); + return JABBER_DISCONNECTED; + } + conn.xmpp_conn = xmpp_conn_new(conn.xmpp_ctx); + if (conn.xmpp_conn == NULL) { + log_warning("Failed to get libstrophe conn during connect"); + return JABBER_DISCONNECTED; + } + xmpp_conn_set_jid(conn.xmpp_conn, altdomain); + + flags = xmpp_conn_get_flags(conn.xmpp_conn); + + if (!tls_policy || (g_strcmp0(tls_policy, "force") == 0)) { + flags |= XMPP_CONN_FLAG_MANDATORY_TLS; + } else if (g_strcmp0(tls_policy, "trust") == 0) { + flags |= XMPP_CONN_FLAG_MANDATORY_TLS; + flags |= XMPP_CONN_FLAG_TRUST_TLS; + } else if (g_strcmp0(tls_policy, "disable") == 0) { + flags |= XMPP_CONN_FLAG_DISABLE_TLS; + } else if (g_strcmp0(tls_policy, "legacy") == 0) { + flags |= XMPP_CONN_FLAG_LEGACY_SSL; + } + + xmpp_conn_set_flags(conn.xmpp_conn, flags); + + /* Print debug logs that can help when users share the logs */ + if (flags != 0) { + log_debug("Connecting with flags (0x%lx):", flags); +#define LOG_FLAG_IF_SET(name) \ + if (flags & name) { \ + log_debug(" " #name); \ + } + LOG_FLAG_IF_SET(XMPP_CONN_FLAG_MANDATORY_TLS); + LOG_FLAG_IF_SET(XMPP_CONN_FLAG_TRUST_TLS); + LOG_FLAG_IF_SET(XMPP_CONN_FLAG_DISABLE_TLS); + LOG_FLAG_IF_SET(XMPP_CONN_FLAG_LEGACY_SSL); +#undef LOG_FLAG_IF_SET + } + + prof_reg_t* reg; + + reg = calloc(1, sizeof(*reg)); + if (reg == NULL) { + log_warning("Failed to allocate registration data struct during connect"); + return JABBER_DISCONNECTED; + } + + reg->username = strdup(username); + reg->password = strdup(password); + +#ifdef HAVE_LIBMESODE + char* cert_path = prefs_get_tls_certpath(); + if (cert_path) { + xmpp_conn_tlscert_path(conn.xmpp_conn, cert_path); + free(cert_path); + } + + int connect_status = xmpp_connect_raw( + conn.xmpp_conn, + altdomain, + port, + _connection_certfail_cb, + _register_handler, + reg); +#else + int connect_status = xmpp_connect_raw( + conn.xmpp_conn, + altdomain, + port, + _register_handler, + reg); +#endif + + if (connect_status == 0) { + conn.conn_status = JABBER_RAW_CONNECTING; + } else { + conn.conn_status = JABBER_DISCONNECTED; + } + + return conn.conn_status; +} + void connection_disconnect(void) { @@ -515,7 +857,6 @@ char* connection_create_stanza_id(void) { char* rndid = get_random_string(CON_RAND_ID_LEN); - assert(rndid != NULL); gchar* hmac = g_compute_hmac_for_string(G_CHECKSUM_SHA1, @@ -581,6 +922,23 @@ _connection_handler(xmpp_conn_t* const xmpp_conn, const xmpp_conn_event_t status break; + // raw connection success + case XMPP_CONN_RAW_CONNECT: + log_debug("Connection handler: XMPP_CONN_RAW_CONNECT"); + conn.conn_status = JABBER_RAW_CONNECTED; + + Jid* my_raw_jid = jid_create(xmpp_conn_get_jid(conn.xmpp_conn)); + log_debug("jid: %s", xmpp_conn_get_jid(conn.xmpp_conn)); + conn.domain = strdup(my_raw_jid->domainpart); + jid_destroy(my_raw_jid); + + conn.features_by_jid = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)g_hash_table_destroy); + g_hash_table_insert(conn.features_by_jid, strdup(conn.domain), g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL)); + + xmpp_conn_open_stream_default(xmpp_conn); + + break; + // disconnected case XMPP_CONN_DISCONNECT: log_debug("Connection handler: XMPP_CONN_DISCONNECT"); diff --git a/src/xmpp/connection.h b/src/xmpp/connection.h index cab579f7..79bee1d4 100644 --- a/src/xmpp/connection.h +++ b/src/xmpp/connection.h @@ -46,6 +46,8 @@ void connection_check_events(void); jabber_conn_status_t connection_connect(const char* const fulljid, const char* const passwd, const char* const altdomain, int port, const char* const tls_policy, const char* const auth_policy); +jabber_conn_status_t connection_register(const char* const altdomain, int port, const char* const tls_policy, + const char* const username, const char* const password); void connection_disconnect(void); void connection_set_disconnected(void); diff --git a/src/xmpp/session.c b/src/xmpp/session.c index e81d55ae..046d4fd2 100644 --- a/src/xmpp/session.c +++ b/src/xmpp/session.c @@ -261,6 +261,8 @@ session_process_events(void) switch (conn_status) { case JABBER_CONNECTED: case JABBER_CONNECTING: + case JABBER_RAW_CONNECTED: + case JABBER_RAW_CONNECTING: case JABBER_DISCONNECTING: connection_check_events(); break; diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 81a41bed..3a1cb4a5 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -2750,6 +2750,43 @@ stanza_change_password(xmpp_ctx_t* ctx, const char* const user, const char* cons } xmpp_stanza_t* +stanza_register_new_account(xmpp_ctx_t* ctx, const char* const user, const char* const password) +{ + char* id = connection_create_stanza_id(); + xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id); + free(id); + + xmpp_stanza_t* register_new_account = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(register_new_account, STANZA_NAME_QUERY); + xmpp_stanza_set_ns(register_new_account, STANZA_NS_REGISTER); + + xmpp_stanza_t* username_st = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(username_st, STANZA_NAME_USERNAME); + xmpp_stanza_t* username_text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(username_text, user); + xmpp_stanza_add_child(username_st, username_text); + xmpp_stanza_release(username_text); + + xmpp_stanza_t* password_st = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(password_st, STANZA_NAME_PASSWORD); + xmpp_stanza_t* password_text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(password_text, password); + xmpp_stanza_add_child(password_st, password_text); + xmpp_stanza_release(password_text); + + xmpp_stanza_add_child(register_new_account, username_st); + xmpp_stanza_release(username_st); + + xmpp_stanza_add_child(register_new_account, password_st); + xmpp_stanza_release(password_st); + + xmpp_stanza_add_child(iq, register_new_account); + xmpp_stanza_release(register_new_account); + + return iq; +} + +xmpp_stanza_t* stanza_request_voice(xmpp_ctx_t* ctx, const char* const room) { char* id = connection_create_stanza_id(); diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index c58395bb..bd61f2f4 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -409,6 +409,7 @@ void stanza_free_caps(XMPPCaps* caps); xmpp_stanza_t* stanza_create_avatar_retrieve_data_request(xmpp_ctx_t* ctx, const char* stanza_id, const char* const item_id, const char* const jid); xmpp_stanza_t* stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate, const char* const lastid); xmpp_stanza_t* stanza_change_password(xmpp_ctx_t* ctx, const char* const user, const char* const password); +xmpp_stanza_t* stanza_register_new_account(xmpp_ctx_t* ctx, const char* const user, const char* const password); xmpp_stanza_t* stanza_request_voice(xmpp_ctx_t* ctx, const char* const room); xmpp_stanza_t* stanza_create_approve_voice(xmpp_ctx_t* ctx, const char* const id, const char* const jid, const char* const node, DataForm* form); xmpp_stanza_t* stanza_create_muc_register_nick(xmpp_ctx_t* ctx, const char* const id, const char* const jid, const char* const node, DataForm* form); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 4c49eb8b..bb561080 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -76,7 +76,9 @@ typedef enum { JABBER_CONNECTING, JABBER_CONNECTED, JABBER_DISCONNECTING, - JABBER_DISCONNECTED + JABBER_DISCONNECTED, + JABBER_RAW_CONNECTING, + JABBER_RAW_CONNECTED } jabber_conn_status_t; typedef enum { @@ -183,6 +185,7 @@ void session_init(void); jabber_conn_status_t session_connect_with_details(const char* const jid, const char* const passwd, const char* const altdomain, const int port, const char* const tls_policy, const char* const auth_policy); jabber_conn_status_t session_connect_with_account(const ProfAccount* const account); + void session_disconnect(void); void session_shutdown(void); void session_process_events(void); diff --git a/tests/unittests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c index 4ecb8f79..847ce82a 100644 --- a/tests/unittests/xmpp/stub_xmpp.c +++ b/tests/unittests/xmpp/stub_xmpp.c @@ -144,6 +144,18 @@ connection_get_profanity_identifier(void) return "profident"; } +jabber_conn_status_t +connection_register(const char* const altdomain, int port, const char* const tls_policy, + const char* const username, const char* const password) +{ + check_expected(altdomain); + check_expected(port); + check_expected(tls_policy); + check_expected(username); + check_expected(password); + return mock_type(jabber_conn_status_t); +} + // message functions char* message_send_chat(const char* const barejid, const char* const msg, const char* const oob_url, gboolean request_receipt, const char* const replace_id) diff --git a/themes/snikket b/themes/snikket new file mode 100644 index 00000000..ac5290bb --- /dev/null +++ b/themes/snikket @@ -0,0 +1,82 @@ +[colours] +bkgnd=orange1 +cmd.wins.unread=yellow +titlebar=darkblue +titlebar.text=orange1 +titlebar.brackets=orange3 +titlebar.unencrypted=orange3 +titlebar.encrypted=orange1 +titlebar.untrusted=red +titlebar.trusted=orange1 +titlebar.online=orange1 +titlebar.offline=white +titlebar.away=wheat4 +titlebar.chat=yellow +titlebar.dnd=red +titlebar.xa=darkorange3 +statusbar=darkblue +statusbar.text=orange1 +statusbar.brackets=default +statusbar.active=default +statusbar.new=yellow +statusbar.current=orange1 +statusbar.time=orange3 +main.text=darkblue +main.text.me=blue +main.text.them=blue3 +main.splash=darkblue +main.help.header=blue1 +main.text.history=darkblue +main.time=navyblue +input.text=darkblue +subscribed=darkblue +unsubscribed=blue3 +otr.started.trusted=green +otr.started.untrusted=yellow +otr.ended=red +otr.trusted=green +otr.untrusted=yellow +online=blue3 +away=wheat4 +chat=blue3 +dnd=red +xa=darkorange3 +offline=yellow +incoming=yellow +mention=yellow +trigger=yellow +typing=yellow +gone=orange4 +error=red +roominfo=blue1 +roommention=blue1 +roommention.term=blue +roomtrigger=blue1 +roomtrigger.term=blue +me=blue1 +them=blue3 +roster.header=blue1 +roster.chat=blue3 +roster.online=blue3 +roster.away=wheat4 +roster.xa=darkorange3 +roster.dnd=red +roster.offline=deepskyblue4 +roster.chat.active=blue3 +roster.online.active=blue3 +roster.away.active=wheat4 +roster.xa.active=darkorange3 +roster.dnd.active=yellow +roster.offline.active=default +roster.chat.unread=blue3 +roster.online.unread=blue3 +roster.away.unread=wheat4 +roster.xa.unread=darkorange3 +roster.dnd.unread=red +roster.offline.unread=deepskyblue4 +roster.room=blue3 +roster.room.unread=darkblue +roster.room.mention=deepskyblue3 +roster.room.trigger=blue1 +occupants.header=blue1 +receipt.sent=blue3 |