1
1
mirror of https://github.com/profanity-im/profanity.git synced 2025-02-02 15:08:15 -05:00

Merge branch 'master' into plugins

Conflicts:
	src/command/command.c
	src/command/commands.c
	src/server_events.c
This commit is contained in:
James Booth 2014-04-23 23:01:58 +01:00
commit 677fe16df0
13 changed files with 166 additions and 30 deletions

View File

@ -20,6 +20,9 @@ Show version information.
.BI "\-h, \-\-help" .BI "\-h, \-\-help"
Show help on command line arguments. Show help on command line arguments.
.TP .TP
.BI "\-a, \-\-account"
Auto connect to an account on startup.
.TP
.BI "\-d, \-\-disable-tls" .BI "\-d, \-\-disable-tls"
Disable TLS for servers that either don't support it, or claim to but do not Disable TLS for servers that either don't support it, or claim to but do not
complete the handshake. complete the handshake.

View File

@ -593,9 +593,9 @@ static struct cmd_t command_defs[] =
{ "/otr", { "/otr",
cmd_otr, parse_args, 1, 2, NULL, cmd_otr, parse_args, 1, 2, NULL,
{ "/otr gen|myfp|theirfp|start|end|trust|untrust|log|warn|libver", "Off The Record encryption commands.", { "/otr gen|myfp|theirfp|start|end|trust|untrust|log|warn|libver|policy", "Off The Record encryption commands.",
{ "/otr gen|myfp|theirfp|start|end|trust|untrust|log|warn|libver", { "/otr gen|myfp|theirfp|start|end|trust|untrust|log|warn|libver|policy",
"-------------------------------------------------------------", "--------------------------------------------------------------------",
"gen - Generate your private key.", "gen - Generate your private key.",
"myfp - Show your fingerprint.", "myfp - Show your fingerprint.",
"theirfp - Show contacts fingerprint.", "theirfp - Show contacts fingerprint.",
@ -606,6 +606,7 @@ static struct cmd_t command_defs[] =
"log - How to log OTR messages, options are 'on', 'off' and 'redact', with redaction being the default.", "log - How to log OTR messages, options are 'on', 'off' and 'redact', with redaction being the default.",
"warn - Show when unencrypted messaging is being used in the title bar, options are 'on' and 'off' with 'on' being the default.", "warn - Show when unencrypted messaging is being used in the title bar, options are 'on' and 'off' with 'on' being the default.",
"libver - Show which version of the libotr library is being used.", "libver - Show which version of the libotr library is being used.",
"policy - manual, opportunistic or always.",
NULL } } }, NULL } } },
{ "/outtype", { "/outtype",
@ -884,6 +885,7 @@ static Autocomplete group_ac;
static Autocomplete bookmark_ac; static Autocomplete bookmark_ac;
static Autocomplete otr_ac; static Autocomplete otr_ac;
static Autocomplete otr_log_ac; static Autocomplete otr_log_ac;
static Autocomplete otr_policy_ac;
static Autocomplete connect_property_ac; static Autocomplete connect_property_ac;
static Autocomplete statuses_ac; static Autocomplete statuses_ac;
static Autocomplete statuses_setting_ac; static Autocomplete statuses_setting_ac;
@ -1072,12 +1074,18 @@ cmd_init(void)
autocomplete_add(otr_ac, "log"); autocomplete_add(otr_ac, "log");
autocomplete_add(otr_ac, "warn"); autocomplete_add(otr_ac, "warn");
autocomplete_add(otr_ac, "libver"); autocomplete_add(otr_ac, "libver");
autocomplete_add(otr_ac, "policy");
otr_log_ac = autocomplete_new(); otr_log_ac = autocomplete_new();
autocomplete_add(otr_log_ac, "on"); autocomplete_add(otr_log_ac, "on");
autocomplete_add(otr_log_ac, "off"); autocomplete_add(otr_log_ac, "off");
autocomplete_add(otr_log_ac, "redact"); autocomplete_add(otr_log_ac, "redact");
otr_policy_ac = autocomplete_new();
autocomplete_add(otr_policy_ac, "manual");
autocomplete_add(otr_policy_ac, "opportunistic");
autocomplete_add(otr_policy_ac, "always");
connect_property_ac = autocomplete_new(); connect_property_ac = autocomplete_new();
autocomplete_add(connect_property_ac, "server"); autocomplete_add(connect_property_ac, "server");
autocomplete_add(connect_property_ac, "port"); autocomplete_add(connect_property_ac, "port");
@ -1133,6 +1141,7 @@ cmd_uninit(void)
autocomplete_free(bookmark_ac); autocomplete_free(bookmark_ac);
autocomplete_free(otr_ac); autocomplete_free(otr_ac);
autocomplete_free(otr_log_ac); autocomplete_free(otr_log_ac);
autocomplete_free(otr_policy_ac);
autocomplete_free(connect_property_ac); autocomplete_free(connect_property_ac);
autocomplete_free(statuses_ac); autocomplete_free(statuses_ac);
autocomplete_free(statuses_setting_ac); autocomplete_free(statuses_setting_ac);
@ -1254,6 +1263,7 @@ cmd_reset_autocomplete()
autocomplete_reset(bookmark_ac); autocomplete_reset(bookmark_ac);
autocomplete_reset(otr_ac); autocomplete_reset(otr_ac);
autocomplete_reset(otr_log_ac); autocomplete_reset(otr_log_ac);
autocomplete_reset(otr_policy_ac);
autocomplete_reset(connect_property_ac); autocomplete_reset(connect_property_ac);
autocomplete_reset(statuses_ac); autocomplete_reset(statuses_ac);
autocomplete_reset(statuses_setting_ac); autocomplete_reset(statuses_setting_ac);
@ -1347,6 +1357,11 @@ cmd_execute_default(const char * const inp)
char *plugin_message = plugins_on_message_send(recipient_jid, inp); char *plugin_message = plugins_on_message_send(recipient_jid, inp);
#ifdef PROF_HAVE_LIBOTR #ifdef PROF_HAVE_LIBOTR
if ((strcmp(prefs_get_string(PREF_OTR_POLICY), "always") == 0) && !otr_is_secure(recipient)) {
cons_show_error("Failed to send message. Please check OTR policy");
return TRUE;
}
if (otr_is_secure(recipient)) { if (otr_is_secure(recipient)) {
char *encrypted = otr_encrypt_message(recipient, plugin_message); char *encrypted = otr_encrypt_message(recipient, plugin_message);
if (encrypted != NULL) { if (encrypted != NULL) {
@ -1754,6 +1769,11 @@ _otr_autocomplete(char *input, int *size)
return result; return result;
} }
result = autocomplete_param_with_ac(input, size, "/otr policy", otr_policy_ac);
if (result != NULL) {
return result;
}
result = autocomplete_param_with_func(input, size, "/otr warn", result = autocomplete_param_with_func(input, size, "/otr warn",
prefs_autocomplete_boolean_choice); prefs_autocomplete_boolean_choice);
if (result != NULL) { if (result != NULL) {

View File

@ -24,6 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <glib.h> #include <glib.h>
#include <libotr/proto.h>
#include "chat_session.h" #include "chat_session.h"
#include "command/commands.h" #include "command/commands.h"
@ -969,7 +970,24 @@ cmd_msg(gchar **args, struct cmd_help_t help)
cons_show_error("Failed to encrypt and send message,"); cons_show_error("Failed to encrypt and send message,");
} }
} else { } else {
message_send(plugin_message, usr_jid); char *policy = prefs_get_string(PREF_OTR_POLICY);
if (strcmp(policy, "always") == 0) {
cons_show_error("Failed to send message. Please check OTR policy");
return TRUE;
} else if (strcmp(policy, "opportunistic") == 0) {
char *otr_base_tag = OTRL_MESSAGE_TAG_BASE;
char *otr_v2_tag = OTRL_MESSAGE_TAG_V2;
int N = strlen(otr_base_tag) + strlen(otr_v2_tag) + strlen(plugin_message) + 1;
char *temp = (char *) malloc( (unsigned) N*sizeof(char *) );
strcpy( temp , plugin_message );
strcat( temp , otr_base_tag);
strcat( temp, otr_v2_tag);
message_send(temp, usr_jid);
free(temp);
} else {
message_send(plugin_message, usr_jid);
}
ui_outgoing_msg("me", usr_jid, plugin_message); ui_outgoing_msg("me", usr_jid, plugin_message);
if (((win_type == WIN_CHAT) || (win_type == WIN_CONSOLE)) && prefs_get_boolean(PREF_CHLOG)) { if (((win_type == WIN_CHAT) || (win_type == WIN_CONSOLE)) && prefs_get_boolean(PREF_CHLOG)) {
@ -2634,6 +2652,27 @@ cmd_otr(gchar **args, struct cmd_help_t help)
char *version = otr_libotr_version(); char *version = otr_libotr_version();
cons_show("Using libotr version %s", version); cons_show("Using libotr version %s", version);
return TRUE; return TRUE;
} else if (strcmp(args[0], "policy") == 0) {
if (args[1] == NULL) {
char *policy = prefs_get_string(PREF_OTR_POLICY);
cons_show("OTR policy is now set to: %s", policy);
return TRUE;
}
char *choice = args[1];
if (g_strcmp0(choice, "manual") == 0) {
prefs_set_string(PREF_OTR_POLICY, "manual");
cons_show("OTR policy is now set to: manual");
} else if (g_strcmp0(choice, "opportunistic") == 0) {
prefs_set_string(PREF_OTR_POLICY, "opportunistic");
cons_show("OTR policy is now set to: opportunistic");
} else if (g_strcmp0(choice, "always") == 0) {
prefs_set_string(PREF_OTR_POLICY, "always");
cons_show("OTR policy is now set to: always");
} else {
cons_show("OTR policy can be set to: manual, opportunistic or always.");
}
return TRUE;
} }
if (jabber_get_connection_status() != JABBER_CONNECTED) { if (jabber_get_connection_status() != JABBER_CONNECTED) {

View File

@ -45,6 +45,7 @@
#define PREF_GROUP_PRESENCE "presence" #define PREF_GROUP_PRESENCE "presence"
#define PREF_GROUP_CONNECTION "connection" #define PREF_GROUP_CONNECTION "connection"
#define PREF_GROUP_ALIAS "alias" #define PREF_GROUP_ALIAS "alias"
#define PREF_GROUP_OTR_POLICY "policy"
static gchar *prefs_loc; static gchar *prefs_loc;
static GKeyFile *prefs; static GKeyFile *prefs;
@ -409,6 +410,8 @@ _get_group(preference_t pref)
case PREF_LOG_ROTATE: case PREF_LOG_ROTATE:
case PREF_LOG_SHARED: case PREF_LOG_SHARED:
return PREF_GROUP_LOGGING; return PREF_GROUP_LOGGING;
case PREF_OTR_POLICY:
return PREF_GROUP_OTR_POLICY;
case PREF_AUTOAWAY_CHECK: case PREF_AUTOAWAY_CHECK:
case PREF_AUTOAWAY_MODE: case PREF_AUTOAWAY_MODE:
case PREF_AUTOAWAY_MESSAGE: case PREF_AUTOAWAY_MESSAGE:
@ -479,6 +482,8 @@ _get_key(preference_t pref)
return "otr"; return "otr";
case PREF_OTR_WARN: case PREF_OTR_WARN:
return "otr.warn"; return "otr.warn";
case PREF_OTR_POLICY:
return "otr.policy";
case PREF_LOG_ROTATE: case PREF_LOG_ROTATE:
return "rotate"; return "rotate";
case PREF_LOG_SHARED: case PREF_LOG_SHARED:
@ -513,6 +518,8 @@ _get_default_string(preference_t pref)
return "off"; return "off";
case PREF_OTR_LOG: case PREF_OTR_LOG:
return "redact"; return "redact";
case PREF_OTR_POLICY:
return "manual";
case PREF_STATUSES_CONSOLE: case PREF_STATUSES_CONSOLE:
case PREF_STATUSES_CHAT: case PREF_STATUSES_CHAT:
case PREF_STATUSES_MUC: case PREF_STATUSES_MUC:

View File

@ -64,7 +64,8 @@ typedef enum {
PREF_OTR_LOG, PREF_OTR_LOG,
PREF_OTR_WARN, PREF_OTR_WARN,
PREF_LOG_ROTATE, PREF_LOG_ROTATE,
PREF_LOG_SHARED PREF_LOG_SHARED,
PREF_OTR_POLICY
} preference_t; } preference_t;
typedef struct prof_alias_t { typedef struct prof_alias_t {

View File

@ -69,7 +69,7 @@ main(int argc, char **argv)
{ {
{ "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Show version information", NULL }, { "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Show version information", NULL },
{ "disable-tls", 'd', 0, G_OPTION_ARG_NONE, &disable_tls, "Disable TLS", NULL }, { "disable-tls", 'd', 0, G_OPTION_ARG_NONE, &disable_tls, "Disable TLS", NULL },
{ "account", 'a', 0, G_OPTION_ARG_STRING, &account_name, "Auto connect to an account on start-up" }, { "account", 'a', 0, G_OPTION_ARG_STRING, &account_name, "Auto connect to an account on startup" },
{ "log",'l', 0, G_OPTION_ARG_STRING, &log, "Set logging levels, DEBUG, INFO (default), WARN, ERROR", "LEVEL" }, { "log",'l', 0, G_OPTION_ARG_STRING, &log, "Set logging levels, DEBUG, INFO (default), WARN, ERROR", "LEVEL" },
{ NULL } { NULL }
}; };

View File

@ -297,6 +297,26 @@ muc_get_room_nick(const char * const room)
} }
} }
/*
* Return password for the specified room
* The password is owned by the chat room and should not be modified or freed
*/
char *
muc_get_room_password(const char * const room)
{
if (rooms != NULL) {
ChatRoom *chat_room = g_hash_table_lookup(rooms, room);
if (chat_room != NULL) {
return chat_room->password;
} else {
return NULL;
}
} else {
return NULL;
}
}
/* /*
* Returns TRUE if the specified nick exists in the room's roster * Returns TRUE if the specified nick exists in the room's roster
*/ */

View File

@ -37,7 +37,8 @@ void muc_leave_room(const char * const room);
gboolean muc_room_is_active(const char * const room); gboolean muc_room_is_active(const char * const room);
gboolean muc_room_is_autojoin(const char * const room); gboolean muc_room_is_autojoin(const char * const room);
GList* muc_get_active_room_list(void); GList* muc_get_active_room_list(void);
char * muc_get_room_nick(const char * const room); char* muc_get_room_nick(const char * const room);
char* muc_get_room_password(const char * const room);
void muc_set_room_pending_nick_change(const char * const room, const char * const new_nick); void muc_set_room_pending_nick_change(const char * const room, const char * const new_nick);
gboolean muc_is_room_pending_nick_change(const char * const room); gboolean muc_is_room_pending_nick_change(const char * const room);

View File

@ -34,7 +34,7 @@ otrlib_policy(void)
char * char *
otrlib_start_query(void) otrlib_start_query(void)
{ {
return "?OTR?v2?"; return "?OTR?v2? This user has requested an Off-the-Record private conversation. However, you do not have a plugin to support that. See http://otr.cypherpunks.ca/ for more information.";
} }
static int static int

View File

@ -35,7 +35,7 @@ otrlib_policy(void)
char * char *
otrlib_start_query(void) otrlib_start_query(void)
{ {
return "?OTR?v2?"; return "?OTR?v2? This user has requested an Off-the-Record private conversation. However, you do not have a plugin to support that. See http://otr.cypherpunks.ca/ for more information.";
} }
static const char* static const char*

View File

@ -35,6 +35,7 @@
#ifdef PROF_HAVE_LIBOTR #ifdef PROF_HAVE_LIBOTR
#include "otr/otr.h" #include "otr/otr.h"
#include <libotr/proto.h>
#endif #endif
#include "ui/ui.h" #include "ui/ui.h"
@ -95,6 +96,18 @@ handle_login_account_success(char *account_name)
ui_handle_login_account_success(account); ui_handle_login_account_success(account);
// attempt to rejoin rooms with passwords
GList *curr = muc_get_active_room_list();
while (curr != NULL) {
char *password = muc_get_room_password(curr->data);
if (password != NULL) {
char *nick = muc_get_room_nick(curr->data);
presence_join_room(curr->data, nick, password);
}
curr = g_list_next(curr);
}
g_list_free(curr);
log_info("%s logged in successfully", account->jid); log_info("%s logged in successfully", account->jid);
account_free(account); account_free(account);
} }
@ -218,25 +231,52 @@ handle_incoming_message(char *from, char *message, gboolean priv)
#ifdef PROF_HAVE_LIBOTR #ifdef PROF_HAVE_LIBOTR
gboolean was_decrypted = FALSE; gboolean was_decrypted = FALSE;
char *decrypted; char *newmessage;
char *policy = prefs_get_string(PREF_OTR_POLICY);
char *whitespace_base = strstr(message,OTRL_MESSAGE_TAG_BASE);
if (!priv) { if (!priv) {
decrypted = otr_decrypt_message(from, message, &was_decrypted); //check for OTR whitespace (opportunistic or always)
if (strcmp(policy, "opportunistic") == 0 || strcmp(policy, "always") == 0) {
if (whitespace_base) {
if (strstr(message, OTRL_MESSAGE_TAG_V2) || strstr(message, OTRL_MESSAGE_TAG_V1)) {
// Remove whitespace pattern for proper display in UI
// Handle both BASE+TAGV1/2(16+8) and BASE+TAGV1+TAGV2(16+8+8)
int tag_length = 24;
if (strstr(message, OTRL_MESSAGE_TAG_V2) && strstr(message, OTRL_MESSAGE_TAG_V1)) {
tag_length = 32;
}
memmove(whitespace_base, whitespace_base+tag_length, tag_length);
char *otr_query_message = otr_start_query();
cons_show("OTR Whitespace pattern detected. Attempting to start OTR session...");
message_send(otr_query_message, from);
}
}
}
newmessage = otr_decrypt_message(from, message, &was_decrypted);
// internal OTR message // internal OTR message
if (decrypted == NULL) { if (newmessage == NULL) {
return; return;
} }
} else { } else {
decrypted = message; newmessage = message;
} }
if (priv) { if (priv) {
Jid *jid = jid_create(from); Jid *jid = jid_create(from);
char *room = jid->barejid; char *room = jid->barejid;
char *nick = jid->resourcepart; char *nick = jid->resourcepart;
plugin_message = plugins_on_private_message_received(room, nick, decrypted); plugin_message = plugins_on_private_message_received(room, nick, newmessage);
jid_destroy(jid); jid_destroy(jid);
} else { } else {
plugin_message = plugins_on_message_received(from, decrypted); plugin_message = plugins_on_message_received(from, newmessage);
}
if (strcmp(policy, "always") == 0 && !was_decrypted && !whitespace_base) {
char *otr_query_message = otr_start_query();
cons_show("Attempting to start OTR session...");
message_send(otr_query_message, from);
} }
ui_incoming_msg(from, plugin_message, NULL, priv); ui_incoming_msg(from, plugin_message, NULL, priv);
@ -257,7 +297,7 @@ handle_incoming_message(char *from, char *message, gboolean priv)
} }
if (!priv) if (!priv)
otr_free_message(decrypted); otr_free_message(newmessage);
#else #else
if (priv) { if (priv) {
Jid *jid = jid_create(from); Jid *jid = jid_create(from);

View File

@ -209,22 +209,28 @@ _jabber_shutdown(void)
static void static void
_jabber_process_events(void) _jabber_process_events(void)
{ {
// run xmpp event loop if connected, connecting or disconnecting int reconnect_sec;
if (jabber_conn.conn_status == JABBER_CONNECTED int elapsed_sec;
|| jabber_conn.conn_status == JABBER_CONNECTING
|| jabber_conn.conn_status == JABBER_DISCONNECTING) {
xmpp_run_once(jabber_conn.ctx, 10);
// check timer and reconnect if disconnected and timer set switch (jabber_conn.conn_status)
} else if (prefs_get_reconnect() != 0) { {
if ((jabber_conn.conn_status == JABBER_DISCONNECTED) && case JABBER_CONNECTED:
(reconnect_timer != NULL)) { case JABBER_CONNECTING:
if (g_timer_elapsed(reconnect_timer, NULL) > prefs_get_reconnect()) { case JABBER_DISCONNECTING:
_jabber_reconnect(); xmpp_run_once(jabber_conn.ctx, 10);
break;
case JABBER_DISCONNECTED:
reconnect_sec = prefs_get_reconnect();
if ((reconnect_sec != 0) && (reconnect_timer != NULL)) {
elapsed_sec = g_timer_elapsed(reconnect_timer, NULL);
if (elapsed_sec > reconnect_sec) {
_jabber_reconnect();
}
} }
} break;
default:
break;
} }
} }
static GList * static GList *

View File

@ -522,4 +522,3 @@ message_init_module(void)
message_send_inactive = _message_send_inactive; message_send_inactive = _message_send_inactive;
message_send_gone = _message_send_gone; message_send_gone = _message_send_gone;
} }