diff --git a/src/command/command.c b/src/command/command.c index bb440bbf..f2883efc 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -50,6 +50,7 @@ #include "config/accounts.h" #include "config/preferences.h" #include "config/theme.h" +#include "config/tlscerts.h" #include "contact.h" #include "roster_list.h" #include "jid.h" @@ -196,6 +197,7 @@ static struct cmd_t command_defs[] = "/tls always", "/tls deny", "/tls trusted", + "/tls revoke ", "/tls certpath", "/tls certpath set ", "/tls certpath clear") @@ -205,7 +207,8 @@ static struct cmd_t command_defs[] = { "allow", "Allow connection to continue with an invalid TLS certificate." }, { "always", "Always allow connections with this invalid TLS certificate." }, { "deny", "Terminate TLS connection." }, - { "trusted", "List manually trusted certificates." }, + { "trusted", "List manually trusted certificates (with /tls always)." }, + { "revoke", "Remove a manually trusted certificate." }, { "certpath", "Show the trusted certificate path." }, { "certpath set ", "Specify filesystem path containing trusted certificates." }, { "certpath clear", "Clear the trusted certificate path." }) @@ -2103,6 +2106,7 @@ cmd_init(void) autocomplete_add(tls_ac, "always"); autocomplete_add(tls_ac, "deny"); autocomplete_add(tls_ac, "trusted"); + autocomplete_add(tls_ac, "revoke"); autocomplete_add(tls_ac, "certpath"); tls_certpath_ac = autocomplete_new(); @@ -2286,6 +2290,7 @@ cmd_reset_autocomplete(ProfWin *window) muc_invites_reset_ac(); accounts_reset_all_search(); accounts_reset_enabled_search(); + tlscerts_reset_ac(); prefs_reset_boolean_choice(); presence_reset_sub_request_search(); #ifdef HAVE_LIBGPGME @@ -3521,6 +3526,11 @@ _tls_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; + result = autocomplete_param_with_func(input, "/tls revoke", tlscerts_complete); + if (result) { + return result; + } + result = autocomplete_param_with_ac(input, "/tls certpath", tls_certpath_ac, TRUE); if (result) { return result; diff --git a/src/command/commands.c b/src/command/commands.c index 94734563..3f695cc1 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -198,6 +198,8 @@ cmd_tls(ProfWin *window, const char * const command, gchar **args) if (curr) { cons_show("Trusted certificates:"); cons_show(""); + } else { + cons_show("No trustes certificates found."); } while (curr) { TLSCertificate *cert = curr->data; @@ -224,6 +226,18 @@ cmd_tls(ProfWin *window, const char * const command, gchar **args) } g_list_free_full(certs, (GDestroyNotify)tlscerts_free); return TRUE; + } else if (g_strcmp0(args[0], "revoke") == 0) { + if (args[1] == NULL) { + cons_bad_cmd_usage(command); + } else { + gboolean res = tlscerts_revoke(args[1]); + if (res) { + cons_show("Trusted certificate revoked: %s", args[1]); + } else { + cons_show("Could not find certificate: %s", args[0]); + } + } + return TRUE; } else { cons_bad_cmd_usage(command); return TRUE; diff --git a/src/config/tlscerts.c b/src/config/tlscerts.c index 7d2220cf..3d0a0b24 100644 --- a/src/config/tlscerts.c +++ b/src/config/tlscerts.c @@ -41,6 +41,7 @@ #include "config/tlscerts.h" #include "log.h" #include "common.h" +#include "tools/autocomplete.h" static gchar *tlscerts_loc; static GKeyFile *tlscerts; @@ -48,6 +49,8 @@ static GKeyFile *tlscerts; static gchar* _get_tlscerts_file(void); static void _save_tlscerts(void); +static Autocomplete certs_ac; + void tlscerts_init(void) { @@ -60,6 +63,16 @@ tlscerts_init(void) tlscerts = g_key_file_new(); g_key_file_load_from_file(tlscerts, tlscerts_loc, G_KEY_FILE_KEEP_COMMENTS, NULL); + + certs_ac = autocomplete_new(); + gsize len = 0; + gchar **groups = g_key_file_get_groups(tlscerts, &len); + + int i = 0; + for (i = 0; i < g_strv_length(groups); i++) { + autocomplete_add(certs_ac, groups[i]); + } + g_strfreev(groups); } gboolean @@ -146,6 +159,8 @@ tlscerts_add(TLSCertificate *cert) return; } + autocomplete_add(certs_ac, cert->fingerprint); + if (cert->domain) { g_key_file_set_string(tlscerts, cert->fingerprint, "domain", cert->domain); } @@ -165,6 +180,31 @@ tlscerts_add(TLSCertificate *cert) _save_tlscerts(); } +gboolean +tlscerts_revoke(const char * const fingerprint) +{ + gboolean result = g_key_file_remove_group(tlscerts, fingerprint, NULL); + if (result) { + autocomplete_remove(certs_ac, fingerprint); + } + + _save_tlscerts(); + + return result; +} + +char * +tlscerts_complete(const char * const prefix) +{ + return autocomplete_complete(certs_ac, prefix, TRUE); +} + +void +tlscerts_reset_ac(void) +{ + autocomplete_reset(certs_ac); +} + void tlscerts_free(TLSCertificate *cert) { @@ -183,6 +223,7 @@ tlscerts_close(void) { g_key_file_free(tlscerts); tlscerts = NULL; + autocomplete_free(certs_ac); } static gchar * diff --git a/src/config/tlscerts.h b/src/config/tlscerts.h index 56e81dd6..b8a15c5b 100644 --- a/src/config/tlscerts.h +++ b/src/config/tlscerts.h @@ -54,10 +54,16 @@ gboolean tlscerts_exists(const char * const fingerprint); void tlscerts_add(TLSCertificate *cert); +gboolean tlscerts_revoke(const char * const fingerprint); + void tlscerts_free(TLSCertificate *cert); GList* tlscerts_list(void); +char* tlscerts_complete(const char * const prefix); + +void tlscerts_reset_ac(void); + void tlscerts_close(void); #endif