Mercurial > ~mikael > mcabber > hg
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"); |