mcabber/mcabber/xmpp.c
changeset 2348 87cc62145c76
parent 2347 db8de1b464d3
child 2359 f35b17fd1e73
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");