diff --git a/src/command/command.c b/src/command/command.c index c89bcb05..669fb066 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -106,6 +106,7 @@ static char * _time_autocomplete(ProfWin *window, const char * const input); static char * _receipts_autocomplete(ProfWin *window, const char * const input); static char * _help_autocomplete(ProfWin *window, const char * const input); static char * _wins_autocomplete(ProfWin *window, const char * const input); +static char * _tls_autocomplete(ProfWin *window, const char * const input); GHashTable *commands = NULL; @@ -187,19 +188,25 @@ static struct cmd_t command_defs[] = }, { "/tls", - cmd_tls, parse_args, 0, 0, NULL, + cmd_tls, parse_args, 1, 3, NULL, CMD_TAGS( CMD_TAG_CONNECTION) CMD_SYN( "/tls allow", "/tls always", - "/tls deny") + "/tls deny", + "/tls certpath", + "/tls certpath set ", + "/tls certpath clear") CMD_DESC( "Handle TLS certificates. ") CMD_ARGS( - { "allow", "Allow connection to continue with an invalid TLS certificate." }, - { "always", "Always allow connections with this invalid TLS certificate." }, - { "deny", "Terminate TLS connection." }) + { "allow", "Allow connection to continue with an invalid TLS certificate." }, + { "always", "Always allow connections with this invalid TLS certificate." }, + { "deny", "Terminate TLS connection." }, + { "certpath", "Show the trusted certificate path." }, + { "certpath set ", "Specify filesystem path containing trusted certificates." }, + { "certpath clear", "Clear the trusted certificate path." }) CMD_NOEXAMPLES }, @@ -1692,6 +1699,7 @@ static Autocomplete receipts_ac; static Autocomplete pgp_ac; static Autocomplete pgp_log_ac; static Autocomplete tls_ac; +static Autocomplete tls_certpath_ac; /* * Initialise command autocompleter and history @@ -2092,6 +2100,11 @@ cmd_init(void) autocomplete_add(tls_ac, "allow"); autocomplete_add(tls_ac, "always"); autocomplete_add(tls_ac, "deny"); + autocomplete_add(tls_ac, "certpath"); + + tls_certpath_ac = autocomplete_new(); + autocomplete_add(tls_certpath_ac, "set"); + autocomplete_add(tls_certpath_ac, "clear"); } void @@ -2157,6 +2170,7 @@ cmd_uninit(void) autocomplete_free(pgp_ac); autocomplete_free(pgp_log_ac); autocomplete_free(tls_ac); + autocomplete_free(tls_certpath_ac); } gboolean @@ -2338,6 +2352,7 @@ cmd_reset_autocomplete(ProfWin *window) autocomplete_reset(pgp_ac); autocomplete_reset(pgp_log_ac); autocomplete_reset(tls_ac); + autocomplete_reset(tls_certpath_ac); if (window->type == WIN_CHAT) { ProfChatWin *chatwin = (ProfChatWin*)window; @@ -2550,8 +2565,8 @@ _cmd_complete_parameters(ProfWin *window, const char * const input) } } - gchar *cmds[] = { "/prefs", "/disco", "/close", "/subject", "/room", "/tls" }; - Autocomplete completers[] = { prefs_ac, disco_ac, close_ac, subject_ac, room_ac, tls_ac }; + gchar *cmds[] = { "/prefs", "/disco", "/close", "/subject", "/room" }; + Autocomplete completers[] = { prefs_ac, disco_ac, close_ac, subject_ac, room_ac }; for (i = 0; i < ARRAY_SIZE(cmds); i++) { result = autocomplete_param_with_ac(input, cmds[i], completers[i], TRUE); @@ -2591,6 +2606,7 @@ _cmd_complete_parameters(ProfWin *window, const char * const input) g_hash_table_insert(ac_funcs, "/time", _time_autocomplete); g_hash_table_insert(ac_funcs, "/receipts", _receipts_autocomplete); g_hash_table_insert(ac_funcs, "/wins", _wins_autocomplete); + g_hash_table_insert(ac_funcs, "/tls", _tls_autocomplete); int len = strlen(input); char parsed[len+1]; @@ -3497,6 +3513,24 @@ _wins_autocomplete(ProfWin *window, const char * const input) return NULL; } +static char * +_tls_autocomplete(ProfWin *window, const char * const input) +{ + char *result = NULL; + + result = autocomplete_param_with_ac(input, "/tls certpath", tls_certpath_ac, TRUE); + if (result) { + return result; + } + + result = autocomplete_param_with_ac(input, "/tls", tls_ac, TRUE); + if (result) { + return result; + } + + return result; +} + static char * _receipts_autocomplete(ProfWin *window, const char * const input) { diff --git a/src/command/commands.c b/src/command/commands.c index 5ec0dd1f..f0320ba0 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -159,8 +159,36 @@ cmd_execute_alias(ProfWin *window, const char * const inp, gboolean *ran) gboolean cmd_tls(ProfWin *window, const char * const command, gchar **args) { - cons_bad_cmd_usage(command); - return TRUE; + if (g_strcmp0(args[0], "certpath") == 0) { + if (g_strcmp0(args[1], "set") == 0) { + if (args[2] == NULL) { + cons_bad_cmd_usage(command); + return TRUE; + } + prefs_set_string(PREF_CERT_PATH, args[2]); + cons_show("Certificate path set to: %s", args[2]); + return TRUE; + } else if (g_strcmp0(args[1], "clear") == 0) { + prefs_set_string(PREF_CERT_PATH, NULL); + cons_show("Certificate path cleared"); + return TRUE; + } else if (args[1] == NULL) { + char *path = prefs_get_string(PREF_CERT_PATH); + if (path) { + cons_show("Trusted certificate path: %s", path); + prefs_free_string(path); + } else { + cons_show("No trusted certificate path set."); + } + return TRUE; + } else { + cons_bad_cmd_usage(command); + return TRUE; + } + } else { + cons_bad_cmd_usage(command); + return TRUE; + } } gboolean diff --git a/src/config/preferences.c b/src/config/preferences.c index e11b4cf2..3584b457 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -686,6 +686,7 @@ _get_group(preference_t pref) case PREF_CARBONS: case PREF_RECEIPTS_SEND: case PREF_RECEIPTS_REQUEST: + case PREF_CERT_PATH: return PREF_GROUP_CONNECTION; case PREF_OTR_LOG: case PREF_OTR_POLICY: @@ -818,6 +819,8 @@ _get_key(preference_t pref) return "enc.warn"; case PREF_PGP_LOG: return "log"; + case PREF_CERT_PATH: + return "certpath"; default: return NULL; } diff --git a/src/config/preferences.h b/src/config/preferences.h index 432137b3..9718cfcb 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -103,7 +103,8 @@ typedef enum { PREF_RESOURCE_MESSAGE, PREF_INPBLOCK_DYNAMIC, PREF_ENC_WARN, - PREF_PGP_LOG + PREF_PGP_LOG, + PREF_CERT_PATH, } preference_t; typedef struct prof_alias_t { diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index c6d04079..e4a5bb32 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -419,6 +419,11 @@ _jabber_connect(const char * const fulljid, const char * const passwd, xmpp_conn_disable_tls(jabber_conn.conn); } + char *cert_path = prefs_get_string(PREF_CERT_PATH); + if (cert_path) { + xmpp_conn_tlscert_path(jabber_conn.conn, cert_path); + } + #ifdef HAVE_LIBMESODE int connect_status = xmpp_connect_client(jabber_conn.conn, altdomain, port, _connection_certfail_cb, _connection_handler, jabber_conn.ctx);