comparison mcabber/mcabber/xmpp.c @ 2348:87cc62145c76

Refactor carbon message handling (franky) Send MDR for forwarded messages when a bare JID is used.
author Mikael Berthe <mikael@lilotux.net>
date Sun, 06 Sep 2020 17:33:54 +0200
parents db8de1b464d3
children f35b17fd1e73
comparison
equal deleted inserted replaced
2347:db8de1b464d3 2348:87cc62145c76
1069 { 1069 {
1070 const char *from = lm_message_get_from(m); 1070 const char *from = lm_message_get_from(m);
1071 char *bjid; 1071 char *bjid;
1072 const char *res; 1072 const char *res;
1073 LmMessageNode *x; 1073 LmMessageNode *x;
1074 LmMessageNode *message_node = m->node;
1074 const char *body = NULL; 1075 const char *body = NULL;
1075 const char *enc = NULL; 1076 const char *enc = NULL;
1076 const char *subject = NULL; 1077 const char *subject = NULL;
1077 time_t timestamp = 0L; 1078 time_t timestamp = 0L;
1078 LmMessageSubType mstype; 1079 LmMessageSubType mstype;
1080 1081
1081 if (!from) { 1082 if (!from) {
1082 scr_LogPrint(LPRINT_DEBUG, "handle_messages: message with missing from attribute"); 1083 scr_LogPrint(LPRINT_DEBUG, "handle_messages: message with missing from attribute");
1083 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; 1084 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
1084 } 1085 }
1086
1085 // Get the bare-JID/room (bjid) and the resource/nickname (res) 1087 // Get the bare-JID/room (bjid) and the resource/nickname (res)
1086 bjid = jidtodisp(from); 1088 bjid = jidtodisp(from);
1087 res = jid_get_resource_name(from); 1089 res = jid_get_resource_name(from);
1088 1090
1089 mstype = lm_message_get_sub_type(m); 1091 mstype = lm_message_get_sub_type(m);
1090 // Timestamp? 1092 // Timestamp?
1091 timestamp = lm_message_node_get_timestamp(m->node); 1093 timestamp = lm_message_node_get_timestamp(message_node);
1092 1094
1093 if (mstype == LM_MESSAGE_SUB_TYPE_ERROR) { 1095 if (mstype == LM_MESSAGE_SUB_TYPE_ERROR) {
1094 x = lm_message_node_get_child(m->node, "error"); 1096 x = lm_message_node_get_child(message_node, "error");
1095 display_server_error(x, from); 1097 display_server_error(x, from);
1096 #ifdef XEP0085 1098 #ifdef XEP0085
1097 // If the XEP85/22 support is probed, set it back to unknown so that 1099 // If the XEP85/22 support is probed, set it back to unknown so that
1098 // we probe it again. 1100 // we probe it again.
1099 chatstates_reset_probed(bjid, res); 1101 chatstates_reset_probed(bjid, res);
1100 #endif 1102 #endif
1101 } else { 1103 } else {
1102 handle_state_events(bjid, res, m->node); 1104 handle_state_events(bjid, res, message_node);
1103 } 1105 }
1104 1106
1105 // Check for carbons! 1107 // Check for carbons!
1106 x = lm_message_node_find_xmlns(m->node, NS_CARBONS_2); 1108 x = lm_message_node_find_xmlns(message_node, NS_CARBONS_2);
1107 gboolean carbons = FALSE; 1109 gboolean carbons = FALSE;
1108 if (x && (!g_strcmp0(x->name, "received") || !g_strcmp0(x->name, "sent"))) { 1110 if (x && (!g_strcmp0(x->name, "received") || !g_strcmp0(x->name, "sent"))) {
1109 LmMessageNode *xenc; 1111 LmMessageNode *xenc;
1110 const char *carbon_name = x->name; 1112 const char *carbon_name = x->name;
1111 carbons = TRUE; 1113 carbons = TRUE;
1125 scr_LogPrint(LPRINT_LOGNORM, 1127 scr_LogPrint(LPRINT_LOGNORM,
1126 "Could not read carbon message! Please file a bug."); 1128 "Could not read carbon message! Please file a bug.");
1127 goto handle_messages_return; 1129 goto handle_messages_return;
1128 } 1130 }
1129 1131
1130 xenc = lm_message_node_find_xmlns(x, NS_ENCRYPTED); 1132 // We should now consider the forwarded node...
1133 message_node = x;
1134
1135 xenc = lm_message_node_find_xmlns(message_node, NS_ENCRYPTED);
1131 if (xenc) 1136 if (xenc)
1132 enc = lm_message_node_get_value(xenc); 1137 enc = lm_message_node_get_value(xenc);
1133 1138
1134 body = lm_message_node_get_child_value(x, "body"); 1139 body = lm_message_node_get_child_value(message_node, "body");
1135 subject = lm_message_node_get_child_value(x, "subject"); 1140 subject = lm_message_node_get_child_value(message_node, "subject");
1136 ns_signed = lm_message_node_find_xmlns(x, NS_SIGNED); 1141 ns_signed = lm_message_node_find_xmlns(message_node, NS_SIGNED);
1137 1142 const char *to = lm_message_node_get_attribute(message_node, "to");
1138 // Parse a message that is send to one of our other resources 1143 from = lm_message_node_get_attribute(message_node, "from");
1144 if (!from) {
1145 scr_LogPrint(LPRINT_LOGNORM, "Malformed carbon copy (missing 'from' attribute).");
1146 goto handle_messages_return;
1147 }
1148 if (!to) {
1149 scr_LogPrint(LPRINT_LOGNORM, "Malformed carbon copy (missing 'to' attribute).");
1150 goto handle_messages_return;
1151 }
1152
1153 // Parse a message that is sent to one of our other resources
1139 if (!g_strcmp0(carbon_name, "received")) { 1154 if (!g_strcmp0(carbon_name, "received")) {
1140 from = lm_message_node_get_attribute(x, "from");
1141 if (!from) {
1142 scr_LogPrint(LPRINT_LOGNORM, "Malformed carbon copy!");
1143 goto handle_messages_return;
1144 }
1145 g_free(bjid); 1155 g_free(bjid);
1146 bjid = jidtodisp(from); 1156 bjid = jidtodisp(from);
1147 res = jid_get_resource_name(from); 1157 res = jid_get_resource_name(from);
1148 1158
1149 // Try to handle forwarded chat state messages 1159 // Try to handle forwarded chat state messages
1150 handle_state_events(from, res, x); 1160 handle_state_events(from, res, message_node);
1151 1161
1152 scr_LogPrint(LPRINT_DEBUG, "Received incoming carbon from <%s>", from); 1162 scr_LogPrint(LPRINT_DEBUG, "Received incoming carbon from <%s>", from);
1153 1163
1154 } else if (!g_strcmp0(carbon_name, "sent")) { 1164 } else if (!g_strcmp0(carbon_name, "sent")) {
1155 #ifdef HAVE_GPGME 1165 #ifdef HAVE_GPGME
1156 char *decrypted_pgp = NULL; 1166 char *decrypted_pgp = NULL;
1157 #endif 1167 #endif
1158 guint encrypted = 0; 1168 guint encrypted = 0;
1159 const char *to = lm_message_node_get_attribute(x, "to"); 1169
1160 if (!to) {
1161 scr_LogPrint(LPRINT_LOGNORM, "Malformed carbon copy!");
1162 goto handle_messages_return;
1163 }
1164 g_free(bjid); 1170 g_free(bjid);
1165 bjid = jidtodisp(to); 1171 bjid = jidtodisp(to);
1166 1172
1167 #ifdef HAVE_GPGME 1173 #ifdef HAVE_GPGME
1168 if (gpg_enabled()) { 1174 if (gpg_enabled()) {
1191 g_free(decrypted_pgp); 1197 g_free(decrypted_pgp);
1192 #endif 1198 #endif
1193 goto handle_messages_return; 1199 goto handle_messages_return;
1194 } 1200 }
1195 } else { // Not a Carbon 1201 } else { // Not a Carbon
1196 subject = lm_message_node_get_child_value(m->node, "subject"); 1202 subject = lm_message_node_get_child_value(message_node, "subject");
1197 body = lm_message_node_get_child_value(m->node, "body"); 1203 body = lm_message_node_get_child_value(message_node, "body");
1198 x = lm_message_node_find_xmlns(m->node, NS_ENCRYPTED); 1204 x = lm_message_node_find_xmlns(message_node, NS_ENCRYPTED);
1199 if (x) 1205 if (x)
1200 enc = lm_message_node_get_value(x); 1206 enc = lm_message_node_get_value(x);
1201 ns_signed = lm_message_node_find_xmlns(m->node, NS_SIGNED); 1207 ns_signed = lm_message_node_find_xmlns(message_node, NS_SIGNED);
1202 } 1208 }
1203 1209
1204 // Only process messages that have a body or a subject 1210 // Only process messages that have a body or a subject
1205 if (body || subject) { 1211 if (body || subject) {
1206 gotmessage(mstype, from, body, enc, subject, timestamp, 1212 gotmessage(mstype, from, body, enc, subject, timestamp,
1207 ns_signed, carbons); 1213 ns_signed, carbons);
1208 } 1214 }
1209 1215
1210 // Handle XEP 184 1216 // Handle XEP 184
1211 { 1217 {
1212 LmMessageNode *xep184 = lm_message_node_find_xmlns(m->node, NS_RECEIPTS); 1218 LmMessageNode *xep184 = lm_message_node_find_xmlns(message_node, NS_RECEIPTS);
1213 if (xep184) { 1219 if (xep184) {
1214 if(!g_strcmp0("request", xep184->name) && 1220 if(!g_strcmp0("request", xep184->name)
1215 (roster_getsubscription(bjid) & sub_from)) { 1221 && !jid_equal(lm_connection_get_jid(lconnection), from)
1222 && (roster_getsubscription(bjid) & sub_from)) {
1216 // Report received message if message delivery receipt was requested 1223 // Report received message if message delivery receipt was requested
1217 const gchar *mid; 1224 const gchar *mid;
1218 LmMessageNode *y; 1225 LmMessageNode *y;
1219 LmMessage *rcvd = lm_message_new(from, LM_MESSAGE_TYPE_MESSAGE); 1226 LmMessage *rcvd = lm_message_new(from, LM_MESSAGE_TYPE_MESSAGE);
1220 mid = lm_message_get_id(m); 1227 mid = lm_message_node_get_attribute(message_node, "id");
1221 // For backward compatibility (XEP184 < v.1.1): 1228 // For backward compatibility (XEP184 < v.1.1):
1222 lm_message_node_set_attribute(rcvd->node, "id", mid); 1229 lm_message_node_set_attribute(rcvd->node, "id", mid);
1223 y = lm_message_node_add_child(rcvd->node, "received", NULL); 1230 y = lm_message_node_add_child(rcvd->node, "received", NULL);
1224 lm_message_node_set_attribute(y, "xmlns", NS_RECEIPTS); 1231 lm_message_node_set_attribute(y, "xmlns", NS_RECEIPTS);
1225 lm_message_node_set_attribute(y, "id", mid); 1232 lm_message_node_set_attribute(y, "id", mid);
1229 // receipt acknowledged 1236 // receipt acknowledged
1230 const char *id = lm_message_node_get_attribute(xep184, "id"); 1237 const char *id = lm_message_node_get_attribute(xep184, "id");
1231 // This is for backward compatibility; if the remote client didn't add 1238 // This is for backward compatibility; if the remote client didn't add
1232 // the id as an attribute of the 'received' tag, we use the message id: 1239 // the id as an attribute of the 'received' tag, we use the message id:
1233 if (!id) 1240 if (!id)
1234 id = lm_message_get_id(m); 1241 id = lm_message_node_get_attribute(message_node, "id");
1235 scr_remove_receipt_flag(bjid, id); 1242 scr_remove_receipt_flag(bjid, id);
1236 1243
1237 #ifdef MODULES_ENABLE 1244 #ifdef MODULES_ENABLE
1238 { 1245 {
1239 hk_arg_t args[] = { 1246 hk_arg_t args[] = {
1246 } 1253 }
1247 } 1254 }
1248 } 1255 }
1249 1256
1250 { 1257 {
1251 LmMessageNode *muc_message = lm_message_node_find_xmlns(m->node, NS_MUC_USER); 1258 LmMessageNode *muc_message = lm_message_node_find_xmlns(message_node, NS_MUC_USER);
1252 if (muc_message && !strcmp(muc_message->name, "x")) 1259 if (muc_message && !strcmp(muc_message->name, "x"))
1253 got_muc_message(from, muc_message, timestamp); 1260 got_muc_message(from, muc_message, timestamp);
1254 } 1261 }
1255 1262
1256 { 1263 {
1257 LmMessageNode *muc_invite = lm_message_node_find_xmlns(m->node, NS_X_CONFERENCE); 1264 LmMessageNode *muc_invite = lm_message_node_find_xmlns(message_node, NS_X_CONFERENCE);
1258 1265
1259 if (muc_invite && !strcmp(muc_invite->name, "x")) { 1266 if (muc_invite && !strcmp(muc_invite->name, "x")) {
1260 const char *jid = lm_message_node_get_attribute(muc_invite, "jid"); 1267 const char *jid = lm_message_node_get_attribute(muc_invite, "jid");
1261 if (jid) { 1268 if (jid) {
1262 const char *reason = lm_message_node_get_attribute(muc_invite, "reason"); 1269 const char *reason = lm_message_node_get_attribute(muc_invite, "reason");