1 /*
2 * client_events.c
3 * vim: expandtab:ts=4:sts=4:sw=4
4 *
5 * Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
6 * Copyright (C) 2019 - 2021 Michael Vetter <jubalh@iodoru.org>
7 *
8 * This file is part of Profanity.
9 *
10 * Profanity is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * Profanity is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with Profanity. If not, see <https://www.gnu.org/licenses/>.
22 *
23 * In addition, as a special exception, the copyright holders give permission to
24 * link the code of portions of this program with the OpenSSL library under
25 * certain conditions as described in each individual source file, and
26 * distribute linked combinations including the two.
27 *
28 * You must obey the GNU General Public License in all respects for all of the
29 * code used other than OpenSSL. If you modify file(s) with this exception, you
30 * may extend this exception to your version of the file(s), but you are not
31 * obligated to do so. If you do not wish to do so, delete this exception
32 * statement from your version. If you delete this exception statement from all
33 * source files in the program, then also delete it here.
34 *
35 */
36
37 #include "config.h"
38
39 #include <stdlib.h>
40 #include <glib.h>
41
42 #include "log.h"
43 #include "database.h"
44 #include "config/preferences.h"
45 #include "event/common.h"
46 #include "plugins/plugins.h"
47 #include "ui/window_list.h"
48 #include "xmpp/chat_session.h"
49 #include "xmpp/xmpp.h"
50
51 #ifdef HAVE_LIBOTR
52 #include "otr/otr.h"
53 #endif
54
55 #ifdef HAVE_LIBGPGME
56 #include "pgp/gpg.h"
57 #endif
58
59 #ifdef HAVE_OMEMO
60 #include "omemo/omemo.h"
61 #endif
62
63 jabber_conn_status_t
cl_ev_connect_jid(const char * const jid,const char * const passwd,const char * const altdomain,const int port,const char * const tls_policy,const char * const auth_policy)64 cl_ev_connect_jid(const char* const jid, const char* const passwd, const char* const altdomain, const int port, const char* const tls_policy, const char* const auth_policy)
65 {
66 cons_show("Connecting as %s", jid);
67 return session_connect_with_details(jid, passwd, altdomain, port, tls_policy, auth_policy);
68 }
69
70 jabber_conn_status_t
cl_ev_connect_account(ProfAccount * account)71 cl_ev_connect_account(ProfAccount* account)
72 {
73 if (account->resource) {
74 cons_show("Connecting with account %s as %s/%s", account->name, account->jid, account->resource);
75 } else if (g_strcmp0(account->name, account->jid) == 0) {
76 cons_show("Connecting with account %s", account->name);
77 } else {
78 cons_show("Connecting with account %s as %s", account->name, account->jid);
79 }
80
81 return session_connect_with_account(account);
82 }
83
84 void
cl_ev_disconnect(void)85 cl_ev_disconnect(void)
86 {
87 char* mybarejid = connection_get_barejid();
88 cons_show("%s logged out successfully.", mybarejid);
89 free(mybarejid);
90
91 ui_close_all_wins();
92 ev_disconnect_cleanup();
93 // on intentional disconnect reset the counter
94 ev_reset_connection_counter();
95 }
96
97 void
cl_ev_presence_send(const resource_presence_t presence_type,const int idle_secs)98 cl_ev_presence_send(const resource_presence_t presence_type, const int idle_secs)
99 {
100 char* signed_status = NULL;
101
102 #ifdef HAVE_LIBGPGME
103 char* account_name = session_get_account_name();
104 ProfAccount* account = accounts_get_account(account_name);
105 if (account->pgp_keyid) {
106 char* msg = connection_get_presence_msg();
107 signed_status = p_gpg_sign(msg, account->pgp_keyid);
108 }
109 account_free(account);
110 #endif
111
112 presence_send(presence_type, idle_secs, signed_status);
113
114 free(signed_status);
115 }
116
117 void
cl_ev_send_msg_correct(ProfChatWin * chatwin,const char * const msg,const char * const oob_url,gboolean correct_last_msg)118 cl_ev_send_msg_correct(ProfChatWin* chatwin, const char* const msg, const char* const oob_url, gboolean correct_last_msg)
119 {
120 chat_state_active(chatwin->state);
121
122 gboolean request_receipt = prefs_get_boolean(PREF_RECEIPTS_REQUEST);
123
124 char* plugin_msg = plugins_pre_chat_message_send(chatwin->barejid, msg);
125 if (plugin_msg == NULL) {
126 return;
127 }
128
129 char* replace_id = NULL;
130 if (correct_last_msg) {
131 replace_id = chatwin->last_msg_id;
132 }
133
134 if (chatwin->is_omemo) {
135 #ifdef HAVE_OMEMO
136 char* id = omemo_on_message_send((ProfWin*)chatwin, plugin_msg, request_receipt, FALSE, replace_id);
137 if (id != NULL) {
138 chat_log_omemo_msg_out(chatwin->barejid, plugin_msg, NULL);
139 log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_OMEMO);
140 chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_OMEMO, request_receipt, replace_id);
141 free(id);
142 }
143 #endif
144 } else if (chatwin->is_ox) {
145 #ifdef HAVE_LIBGPGME
146 // XEP-0373: OpenPGP for XMPP
147 char* id = message_send_chat_ox(chatwin->barejid, plugin_msg, request_receipt, replace_id);
148 if (id != NULL) {
149 chat_log_pgp_msg_out(chatwin->barejid, plugin_msg, NULL);
150 log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_OX);
151 chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_OX, request_receipt, replace_id);
152 free(id);
153 }
154 #endif
155 } else if (chatwin->pgp_send) {
156 #ifdef HAVE_LIBGPGME
157 char* id = message_send_chat_pgp(chatwin->barejid, plugin_msg, request_receipt, replace_id);
158 if (id != NULL) {
159 chat_log_pgp_msg_out(chatwin->barejid, plugin_msg, NULL);
160 log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_PGP);
161 chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PGP, request_receipt, replace_id);
162 free(id);
163 }
164 #endif
165 } else {
166 gboolean handled = FALSE;
167 #ifdef HAVE_LIBOTR
168 handled = otr_on_message_send(chatwin, plugin_msg, request_receipt, replace_id);
169 #endif
170 if (!handled) {
171 char* id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id);
172 chat_log_msg_out(chatwin->barejid, plugin_msg, NULL);
173 log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_NONE);
174 chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id);
175 free(id);
176 }
177 }
178
179 plugins_post_chat_message_send(chatwin->barejid, plugin_msg);
180 free(plugin_msg);
181 return;
182 }
183
184 void
cl_ev_send_msg(ProfChatWin * chatwin,const char * const msg,const char * const oob_url)185 cl_ev_send_msg(ProfChatWin* chatwin, const char* const msg, const char* const oob_url)
186 {
187 cl_ev_send_msg_correct(chatwin, msg, oob_url, FALSE);
188 }
189
190 void
cl_ev_send_muc_msg_corrected(ProfMucWin * mucwin,const char * const msg,const char * const oob_url,gboolean correct_last_msg)191 cl_ev_send_muc_msg_corrected(ProfMucWin* mucwin, const char* const msg, const char* const oob_url, gboolean correct_last_msg)
192 {
193 char* plugin_msg = plugins_pre_room_message_send(mucwin->roomjid, msg);
194 if (plugin_msg == NULL) {
195 return;
196 }
197
198 char* replace_id = NULL;
199 if (correct_last_msg) {
200 replace_id = mucwin->last_msg_id;
201 }
202
203 #ifdef HAVE_OMEMO
204 if (mucwin->is_omemo) {
205 char* id = omemo_on_message_send((ProfWin*)mucwin, plugin_msg, FALSE, TRUE, replace_id);
206 groupchat_log_omemo_msg_out(mucwin->roomjid, plugin_msg);
207 log_database_add_outgoing_muc(id, mucwin->roomjid, plugin_msg, replace_id, PROF_MSG_ENC_OMEMO);
208 mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_OMEMO, replace_id);
209 free(id);
210 } else {
211 char* id = message_send_groupchat(mucwin->roomjid, plugin_msg, oob_url, replace_id);
212 groupchat_log_msg_out(mucwin->roomjid, plugin_msg);
213 log_database_add_outgoing_muc(id, mucwin->roomjid, plugin_msg, replace_id, PROF_MSG_ENC_NONE);
214 mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_NONE, replace_id);
215 free(id);
216 }
217
218 plugins_post_room_message_send(mucwin->roomjid, plugin_msg);
219 free(plugin_msg);
220 return;
221 #endif
222
223 #ifndef HAVE_OMEMO
224 char* id = message_send_groupchat(mucwin->roomjid, plugin_msg, oob_url, replace_id);
225 groupchat_log_msg_out(mucwin->roomjid, plugin_msg);
226 log_database_add_outgoing_muc(id, mucwin->roomjid, plugin_msg, replace_id, PROF_MSG_ENC_NONE);
227 mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_NONE, replace_id);
228 free(id);
229
230 plugins_post_room_message_send(mucwin->roomjid, plugin_msg);
231 free(plugin_msg);
232 return;
233 #endif
234 }
235
236 void
cl_ev_send_muc_msg(ProfMucWin * mucwin,const char * const msg,const char * const oob_url)237 cl_ev_send_muc_msg(ProfMucWin* mucwin, const char* const msg, const char* const oob_url)
238 {
239 cl_ev_send_muc_msg_corrected(mucwin, msg, oob_url, FALSE);
240 }
241
242 void
cl_ev_send_priv_msg(ProfPrivateWin * privwin,const char * const msg,const char * const oob_url)243 cl_ev_send_priv_msg(ProfPrivateWin* privwin, const char* const msg, const char* const oob_url)
244 {
245 if (privwin->occupant_offline) {
246 privwin_message_occupant_offline(privwin);
247 } else if (privwin->room_left) {
248 privwin_message_left_room(privwin);
249 } else {
250 char* plugin_msg = plugins_pre_priv_message_send(privwin->fulljid, msg);
251 Jid* jidp = jid_create(privwin->fulljid);
252
253 char* id = message_send_private(privwin->fulljid, plugin_msg, oob_url);
254 chat_log_msg_out(jidp->barejid, plugin_msg, jidp->resourcepart);
255 log_database_add_outgoing_muc_pm(id, privwin->fulljid, plugin_msg, NULL, PROF_MSG_ENC_NONE);
256 privwin_outgoing_msg(privwin, plugin_msg);
257 free(id);
258
259 plugins_post_priv_message_send(privwin->fulljid, plugin_msg);
260
261 free(plugin_msg);
262 jid_destroy(jidp);
263 }
264 }
265