feat: Add /force-encryption command and update message handling
All checks were successful
CI / Check spelling (pull_request) Successful in 18s
CI / Check coding style (pull_request) Successful in 34s
CI / Linux (ubuntu) (pull_request) Successful in 14m5s
CI / Linux (debian) (pull_request) Successful in 14m5s
CI / Linux (arch) (pull_request) Successful in 14m53s
All checks were successful
CI / Check spelling (pull_request) Successful in 18s
CI / Check coding style (pull_request) Successful in 34s
CI / Linux (ubuntu) (pull_request) Successful in 14m5s
CI / Linux (debian) (pull_request) Successful in 14m5s
CI / Linux (arch) (pull_request) Successful in 14m53s
Implement /force-encryption command to configure forced encryption settings with on|off and policy resend-to-confirm|block options. The changes enhance user experience by clarifying encryption requirements and providing actionable commands. Users can now press Enter again to confirm unencrypted messages in resend-to-confirm mode.
This commit is contained in:
@@ -2729,6 +2729,7 @@ static const struct cmd_t command_defs[] = {
|
||||
{ "os on|off", "Choose whether to include the OS name if a user asks for software information (XEP-0092)." }
|
||||
)
|
||||
CMD_EXAMPLES(
|
||||
"/privacy",
|
||||
"/privacy logging off",
|
||||
"/privacy os off")
|
||||
},
|
||||
@@ -2744,6 +2745,31 @@ static const struct cmd_t command_defs[] = {
|
||||
"Redraw user interface. Can be used when some other program interrupted profanity or wrote to the same terminal and the interface looks \"broken\"." )
|
||||
},
|
||||
|
||||
{ CMD_PREAMBLE("/force-encryption",
|
||||
parse_args, 1, 3, &cons_encryption_setting)
|
||||
CMD_MAINFUNC(cmd_force_encryption)
|
||||
CMD_TAGS(
|
||||
CMD_TAG_CHAT)
|
||||
CMD_SYN(
|
||||
"/force-encryption",
|
||||
"/force-encryption on|off",
|
||||
"/force-encryption policy resend-to-confirm|block")
|
||||
CMD_DESC(
|
||||
"Configure forced encryption for outgoing messages in CProof. "
|
||||
"When enabled, restricts sending unencrypted messages based on the specified policy. "
|
||||
"Run without arguments to display current settings.")
|
||||
CMD_ARGS(
|
||||
{ "on|off", "Enable or disable forced encryption. When enabled, restricts unencrypted messages per the policy. When disabled, allows sending unencrypted messages without restrictions." },
|
||||
{ "policy resend-to-confirm|block", "Set the policy for unencrypted messages when forced encryption is enabled. 'resend-to-confirm' requires pressing Enter again to confirm sending an unencrypted message (default). 'block' prevents sending unencrypted messages entirely." }
|
||||
)
|
||||
CMD_EXAMPLES(
|
||||
"/force-encryption",
|
||||
"/force-encryption on",
|
||||
"/force-encryption off",
|
||||
"/force-encryption policy resend-to-confirm",
|
||||
"/force-encryption policy block")
|
||||
},
|
||||
|
||||
// NEXT-COMMAND (search helper)
|
||||
};
|
||||
|
||||
|
||||
@@ -10633,3 +10633,22 @@ cmd_vcard_save(ProfWin* window, const char* const command, gchar** args)
|
||||
cons_show("User vCard uploaded");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
cmd_force_encryption(ProfWin* window, const char* const command, gchar** args)
|
||||
{
|
||||
if (g_strv_length(args) == 1 && (g_strcmp0(args[0], "on") == 0 || g_strcmp0(args[0], "off") == 0)) {
|
||||
_cmd_set_boolean_preference(args[0], "Forces encryption", PREF_FORCE_ENCRYPTION);
|
||||
} else if (g_strv_length(args) == 2 && g_strcmp0(args[0], "policy") == 0) {
|
||||
if (g_strcmp0(args[1], "resend-to-confirm") != 0 && g_strcmp0(args[1], "block") != 0) {
|
||||
cons_show_error("Invalid policy: \"%s\". See '/help force-encryption' for details.", args[1]);
|
||||
return TRUE;
|
||||
}
|
||||
prefs_set_string(PREF_FORCE_ENCRYPTION_MODE, args[1]);
|
||||
cons_show("Force encryption policy has been set to \"%s\".", args[1]);
|
||||
} else {
|
||||
cons_bad_cmd_usage(command);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -269,5 +269,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_force_encryption(ProfWin* window, const char* const command, gchar** args);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1792,6 +1792,8 @@ _get_group(preference_t pref)
|
||||
case PREF_OUTGOING_STAMP:
|
||||
case PREF_INCOMING_STAMP:
|
||||
case PREF_MOOD:
|
||||
case PREF_FORCE_ENCRYPTION:
|
||||
case PREF_FORCE_ENCRYPTION_MODE:
|
||||
return PREF_GROUP_UI;
|
||||
case PREF_STATES:
|
||||
case PREF_OUTTYPE:
|
||||
@@ -2150,6 +2152,10 @@ _get_key(preference_t pref)
|
||||
return "strophe.sm.enabled";
|
||||
case PREF_STROPHE_SM_RESEND:
|
||||
return "strophe.sm.resend";
|
||||
case PREF_FORCE_ENCRYPTION:
|
||||
return "force-encryption.enabled";
|
||||
case PREF_FORCE_ENCRYPTION_MODE:
|
||||
return "force-encryption.policy";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -2204,6 +2210,7 @@ _get_default_boolean(preference_t pref)
|
||||
case PREF_STROPHE_SM_RESEND:
|
||||
return TRUE;
|
||||
case PREF_PGP_PUBKEY_AUTOIMPORT:
|
||||
case PREF_FORCE_ENCRYPTION:
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2310,6 +2317,8 @@ _get_default_string(preference_t pref)
|
||||
return "0";
|
||||
case PREF_DBLOG:
|
||||
return "on";
|
||||
case PREF_FORCE_ENCRYPTION_MODE:
|
||||
return "resend-to-confirm";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -187,6 +187,8 @@ typedef enum {
|
||||
PREF_STROPHE_SM_RESEND,
|
||||
PREF_VCARD_PHOTO_CMD,
|
||||
PREF_STATUSBAR_TABMODE,
|
||||
PREF_FORCE_ENCRYPTION,
|
||||
PREF_FORCE_ENCRYPTION_MODE
|
||||
} preference_t;
|
||||
|
||||
typedef struct prof_alias_t
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "config/preferences.h"
|
||||
#include "event/common.h"
|
||||
#include "plugins/plugins.h"
|
||||
#include "ui/inputwin.h"
|
||||
#include "ui/window_list.h"
|
||||
#include "xmpp/chat_session.h"
|
||||
#include "xmpp/session.h"
|
||||
@@ -129,6 +130,38 @@ cl_ev_presence_send(const resource_presence_t presence_type, const int idle_secs
|
||||
presence_send(presence_type, idle_secs, signed_status);
|
||||
}
|
||||
|
||||
// Checks if an unencrypted message can be sent based on encryption preferences.
|
||||
// Returns TRUE if allowed, FALSE if blocked.
|
||||
static gboolean
|
||||
_allow_unencrypted_message(ProfChatWin* chatwin, const char* const msg)
|
||||
{
|
||||
if (!prefs_get_boolean(PREF_FORCE_ENCRYPTION)) {
|
||||
return TRUE; // Encryption not enforced
|
||||
}
|
||||
|
||||
auto_gchar gchar* force_enc_mode = prefs_get_string(PREF_FORCE_ENCRYPTION_MODE);
|
||||
|
||||
if (g_strcmp0(force_enc_mode, "block") == 0) {
|
||||
win_println((ProfWin*)chatwin, THEME_ERROR, "-", "Message not sent: encryption required. Enable (omemo/pgp/otr) encryption or /force-encryption off.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_strcmp0(force_enc_mode, "resend-to-confirm") == 0) {
|
||||
// We do not use chatwin->last_message because it should be set only if it's sent.
|
||||
guint msg_hash = g_str_hash(msg);
|
||||
if (msg_hash != chatwin->last_attempted_msg_hash) {
|
||||
win_println((ProfWin*)chatwin, THEME_ERROR, "-", "Message not sent: encryption required. Enable (omemo/pgp/otr) encryption or press Enter again to send without encryption. Use /force-encryption off to disable this protection.");
|
||||
chatwin->last_attempted_msg_hash = msg_hash;
|
||||
inp_set_line(msg); // reset message to prevent the need to retype it
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
win_println((ProfWin*)chatwin, THEME_ERROR, "-", "Message not sent: invalid encryption mode (%s). Use '/force-encryption policy resend-to-confirm'.", force_enc_mode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
cl_ev_send_msg_correct(ProfChatWin* chatwin, const char* const msg, const char* const oob_url, gboolean correct_last_msg)
|
||||
{
|
||||
@@ -177,7 +210,7 @@ cl_ev_send_msg_correct(ProfChatWin* chatwin, const char* const msg, const char*
|
||||
#ifdef HAVE_LIBOTR
|
||||
handled = otr_on_message_send(chatwin, message, request_receipt, replace_id);
|
||||
#endif
|
||||
if (!handled) {
|
||||
if (!handled && _allow_unencrypted_message(chatwin, message)) {
|
||||
auto_char char* id = message_send_chat(chatwin->barejid, message, oob_url, request_receipt, replace_id);
|
||||
chat_log_msg_out(chatwin->barejid, message, NULL);
|
||||
log_database_add_outgoing_chat(id, chatwin->barejid, message, replace_id, PROF_MSG_ENC_NONE);
|
||||
|
||||
@@ -2891,3 +2891,11 @@ cons_privacy_setting(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cons_encryption_setting(void)
|
||||
{
|
||||
cons_show("Force encryption : %sabled", prefs_get_boolean(PREF_FORCE_ENCRYPTION) ? "en" : "dis");
|
||||
|
||||
cons_show("Force encryption mode : %s", prefs_get_string(PREF_FORCE_ENCRYPTION_MODE));
|
||||
}
|
||||
|
||||
@@ -294,6 +294,14 @@ inp_get_line(void)
|
||||
return line;
|
||||
}
|
||||
|
||||
void
|
||||
inp_set_line(const char* const new_line)
|
||||
{
|
||||
rl_replace_line(new_line, 1);
|
||||
rl_point = rl_end;
|
||||
_inp_redisplay();
|
||||
}
|
||||
|
||||
char*
|
||||
inp_get_password(void)
|
||||
{
|
||||
|
||||
@@ -46,5 +46,6 @@ void inp_win_resize(void);
|
||||
void inp_put_back(void);
|
||||
char* inp_get_password(void);
|
||||
char* inp_get_line(void);
|
||||
void inp_set_line(const char* const new_line);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -351,6 +351,7 @@ void cons_theme_properties(void);
|
||||
void cons_theme_colours(void);
|
||||
void cons_show_tlscert(const TLSCertificate* cert);
|
||||
void cons_show_tlscert_summary(const TLSCertificate* cert);
|
||||
void cons_encryption_setting(void);
|
||||
|
||||
void cons_alert(ProfWin* alert_origin_window);
|
||||
void cons_remove_alert(ProfWin* window);
|
||||
|
||||
@@ -188,6 +188,7 @@ typedef struct prof_chat_win_t
|
||||
char* last_message;
|
||||
char* last_msg_id;
|
||||
gboolean has_attention;
|
||||
guint last_attempted_msg_hash;
|
||||
} ProfChatWin;
|
||||
|
||||
typedef struct prof_muc_win_t
|
||||
|
||||
@@ -164,6 +164,7 @@ win_create_chat(const char* const barejid)
|
||||
new_win->last_message = NULL;
|
||||
new_win->last_msg_id = NULL;
|
||||
new_win->has_attention = FALSE;
|
||||
new_win->last_attempted_msg_hash = 0;
|
||||
new_win->memcheck = PROFCHATWIN_MEMCHECK;
|
||||
|
||||
return &new_win->window;
|
||||
|
||||
@@ -675,6 +675,11 @@ inp_readline(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
inp_set_line(const char* const new_line)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
inp_nonblocking(gboolean reset)
|
||||
{
|
||||
@@ -1157,6 +1162,11 @@ cons_privacy_setting(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
cons_encryption_setting(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
cons_show_bookmarks_ignore(gchar** list, gsize len)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user