diff --git a/src/command/command.c b/src/command/command.c index e75757bb..2b8b4d8b 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -207,6 +207,7 @@ static struct cmd_t command_defs[] = "/tls always", "/tls deny", "/tls cert", + "/tls trust", "/tls trusted", "/tls revoke ", "/tls certpath", @@ -216,11 +217,12 @@ static struct cmd_t command_defs[] = 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 TLS certificate." }, + { "always", "Always allow connections with TLS certificate." }, + { "deny", "Abort connection." }, { "cert", "Show the current TLS certificate." }, - { "trusted", "List manually trusted certificates (with /tls always)." }, + { "trust", "Add the current TLS certificate to manually trusted certiciates." }, + { "trusted", "List manually trusted certificates (with '/tls always' or '/tls trust')." }, { "revoke ", "Remove a manually trusted certificate." }, { "certpath", "Show the trusted certificate path." }, { "certpath set ", "Specify filesystem path containing trusted certificates." }, @@ -2223,6 +2225,7 @@ cmd_init(void) autocomplete_add(tls_ac, "always"); autocomplete_add(tls_ac, "deny"); autocomplete_add(tls_ac, "cert"); + autocomplete_add(tls_ac, "trust"); autocomplete_add(tls_ac, "trusted"); autocomplete_add(tls_ac, "revoke"); autocomplete_add(tls_ac, "certpath"); diff --git a/src/command/commands.c b/src/command/commands.c index 2c3ee1fa..1a74ebc1 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -193,6 +193,20 @@ cmd_tls(ProfWin *window, const char *const command, gchar **args) #else cons_show("Certificate path setting only supported when built with libmesode."); return TRUE; +#endif + } else if (g_strcmp0(args[0], "trust") == 0) { +#ifdef HAVE_LIBMESODE + TLSCertificate *cert = jabber_get_tls_peer_cert(); + if (!tlscerts_exists(cert->fingerprint)) { + cons_show("Adding %s to trusted certificates.", cert->fingerprint); + tlscerts_add(cert); + } else { + cons_show("Certificate %s already trusted.", cert->fingerprint); + } + return TRUE; +#else + cons_show("Manual certificate trust only supported when built with libmesode."); + return TRUE; #endif } else if (g_strcmp0(args[0], "trusted") == 0) { #ifdef HAVE_LIBMESODE diff --git a/src/event/server_events.c b/src/event/server_events.c index 58add417..d5022d35 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -47,6 +47,7 @@ #include "roster_list.h" #include "window_list.h" #include "config/tlscerts.h" +#include "profanity.h" #ifdef HAVE_LIBOTR #include "otr/otr.h" @@ -733,9 +734,9 @@ sv_ev_certfail(const char *const errormsg, TLSCertificate *cert) cons_show_error("TLS certificate verification failed: %s", errormsg); cons_show_tlscert(cert); cons_show(""); - cons_show("Use '/tls allow' to accept this certificate"); - cons_show("Use '/tls always' to accept this certificate permanently"); - cons_show("Use '/tls deny' to reject this certificate"); + cons_show("Use '/tls allow' to accept this certificate."); + cons_show("Use '/tls always' to accept this certificate permanently."); + cons_show("Use '/tls deny' to reject this certificate."); cons_show(""); ui_update(); @@ -743,10 +744,11 @@ sv_ev_certfail(const char *const errormsg, TLSCertificate *cert) while ((g_strcmp0(cmd, "/tls allow") != 0) && (g_strcmp0(cmd, "/tls always") != 0) - && (g_strcmp0(cmd, "/tls deny") != 0)) { - cons_show("Use '/tls allow' to accept this certificate"); - cons_show("Use '/tls always' to accept this certificate permanently"); - cons_show("Use '/tls deny' to reject this certificate"); + && (g_strcmp0(cmd, "/tls deny") != 0) + && (g_strcmp0(cmd, "/quit") != 0)) { + cons_show("Use '/tls allow' to accept this certificate."); + cons_show("Use '/tls always' to accept this certificate permanently."); + cons_show("Use '/tls deny' to reject this certificate."); cons_show(""); ui_update(); free(cmd); @@ -754,16 +756,23 @@ sv_ev_certfail(const char *const errormsg, TLSCertificate *cert) } if (g_strcmp0(cmd, "/tls allow") == 0) { + cons_show("Coninuing with connection."); tlscerts_set_current(cert->fingerprint); free(cmd); return 1; } else if (g_strcmp0(cmd, "/tls always") == 0) { + cons_show("Adding %s to trusted certificates.", cert->fingerprint); if (!tlscerts_exists(cert->fingerprint)) { tlscerts_add(cert); } free(cmd); return 1; + } else if (g_strcmp0(cmd, "/quit") == 0) { + prof_set_quit(); + free(cmd); + return 0; } else { + cons_show("Aborting connection."); free(cmd); return 0; } diff --git a/src/profanity.c b/src/profanity.c index a3afb3c2..6e973a72 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -90,6 +90,7 @@ resource_presence_t saved_presence; char *saved_status; static gboolean cont = TRUE; +static gboolean force_quit = FALSE; void prof_run(char *log_level, char *account_name) @@ -104,7 +105,7 @@ prof_run(char *log_level, char *account_name) saved_status = NULL; char *line = NULL; - while(cont) { + while(cont && !force_quit) { log_stderr_handler(); _check_autoaway(); @@ -127,6 +128,12 @@ prof_run(char *log_level, char *account_name) } } +void +prof_set_quit(void) +{ + force_quit = TRUE; +} + void prof_handle_idle(void) { diff --git a/src/profanity.h b/src/profanity.h index 123e2f00..f19f5f36 100644 --- a/src/profanity.h +++ b/src/profanity.h @@ -45,4 +45,6 @@ void prof_handle_activity(void); gboolean process_input(char *inp); +void prof_set_quit(void); + #endif