Ejemplo n.º 1
0
void sipmsg_free(struct sipmsg *msg) {
	sipe_utils_nameval_free(msg->headers);
	sipe_utils_nameval_free(msg->new_headers);
	g_free(msg->signature);
	g_free(msg->rand);
	g_free(msg->num);
	g_free(msg->responsestr);
	g_free(msg->method);
	g_free(msg->target);
	g_free(msg->body);
	g_free(msg);
}
Ejemplo n.º 2
0
void sipe_mime_parts_foreach(const gchar *type,
			     const gchar *body,
			     sipe_mime_parts_cb callback,
			     gpointer user_data)
{
	gchar *doc = g_strdup_printf("Content-Type: %s\r\n\r\n%s", type, body);
	PurpleMimeDocument *mime = purple_mime_document_parse(doc);

	if (mime) {
		GList* parts = purple_mime_document_get_parts(mime);

		while (parts) {
			const gchar *content_type = purple_mime_part_get_field(parts->data,
									       "Content-Type");
			if (content_type) {
				const gchar *content = purple_mime_part_get_data(parts->data);
				gsize length = purple_mime_part_get_length(parts->data);
				GSList *fields = mime_fields_to_nameval(parts->data);

				(*callback)(user_data, fields, content, length);

				sipe_utils_nameval_free(fields);
			}
			parts = parts->next;
		}
		purple_mime_document_free(mime);
	}
	g_free(doc);
}
Ejemplo n.º 3
0
static void gmime_callback(SIPE_UNUSED_PARAMETER GMimeObject *parent,
			   GMimeObject *part,
			   gpointer user_data)
{
	GMimeDataWrapper *data = g_mime_part_get_content_object((GMimePart *)part);

	if (data) {
		GMimeStream *stream = g_mime_data_wrapper_get_stream(data);

		if (stream) {
			ssize_t length = g_mime_stream_length(stream);

			if (length != -1) {
				gchar *content = g_malloc(length + 1);

				if (g_mime_stream_read(stream, content, length) == length) {
					struct gmime_callback_data *cd = user_data;
					GSList *fields = gmime_fields_to_nameval(part);

					(*(cd->callback))(cd->user_data, fields, content, length);

					sipe_utils_nameval_free(fields);
				}
				g_free(content);
			}
		}
	}
}
void process_incoming_message(struct sipe_core_private *sipe_private,
			      struct sipmsg *msg)
{
	gchar *from;
	const gchar *contenttype;
	gboolean found = FALSE;

	from = parse_from(sipmsg_find_header(msg, "From"));

	if (!from) return;

	SIPE_DEBUG_INFO("got message from %s: %s", from, msg->body);

	contenttype = sipmsg_find_header(msg, "Content-Type");
	if (g_str_has_prefix(contenttype, "text/plain")
	    || g_str_has_prefix(contenttype, "text/html")
	    || g_str_has_prefix(contenttype, "multipart/related")
	    || g_str_has_prefix(contenttype, "multipart/alternative"))
	{
		const gchar *callid = sipmsg_find_header(msg, "Call-ID");
		gchar *html = get_html_message(contenttype, msg->body);

		struct sip_session *session = sipe_session_find_chat_or_im(sipe_private,
									   callid,
									   from);
		if (session && session->chat_session) {
			if (session->chat_session->type == SIPE_CHAT_TYPE_CONFERENCE) { /* a conference */
				gchar *tmp = parse_from(sipmsg_find_header(msg, "Ms-Sender"));
				gchar *sender = parse_from(tmp);
				g_free(tmp);
				sipe_backend_chat_message(SIPE_CORE_PUBLIC,
							  session->chat_session->backend,
							  sender,
							  0,
							  html);
				g_free(sender);
			} else { /* a multiparty chat */
				sipe_backend_chat_message(SIPE_CORE_PUBLIC,
							  session->chat_session->backend,
							  from,
							  0,
							  html);
			}
		} else {
			sipe_backend_im_message(SIPE_CORE_PUBLIC,
						from,
						html);
		}
		g_free(html);
		sip_transport_response(sipe_private, msg, 200, "OK", NULL);
		found = TRUE;

	} else if (g_str_has_prefix(contenttype, "application/im-iscomposing+xml")) {
		sipe_xml *isc = sipe_xml_parse(msg->body, msg->bodylen);
		const sipe_xml *state;
		gchar *statedata;

		if (!isc) {
			SIPE_DEBUG_INFO_NOFORMAT("process_incoming_message: can not parse iscomposing");
			g_free(from);
			return;
		}

		state = sipe_xml_child(isc, "state");

		if (!state) {
			SIPE_DEBUG_INFO_NOFORMAT("process_incoming_message: no state found");
			sipe_xml_free(isc);
			g_free(from);
			return;
		}

		statedata = sipe_xml_data(state);
		if (statedata) {
			if (strstr(statedata, "active")) {
				sipe_backend_user_feedback_typing(SIPE_CORE_PUBLIC,
								  from);
			} else {
				sipe_backend_user_feedback_typing_stop(SIPE_CORE_PUBLIC,
								       from);
			}
			g_free(statedata);
		}
		sipe_xml_free(isc);
		sip_transport_response(sipe_private, msg, 200, "OK", NULL);
		found = TRUE;
	} else if (g_str_has_prefix(contenttype, "text/x-msmsgsinvite")) {
		const gchar *callid = sipmsg_find_header(msg, "Call-ID");
		struct sip_session *session = sipe_session_find_chat_or_im(sipe_private,
									   callid,
									   from);
		if (session) {
			struct sip_dialog *dialog = sipe_dialog_find(session, from);
			GSList *body = sipe_ft_parse_msg_body(msg->body);
			found = sipe_process_incoming_x_msmsgsinvite(sipe_private, dialog, body);
			sipe_utils_nameval_free(body);
			if (found) {
				sip_transport_response(sipe_private, msg, 200, "OK", NULL);
			}
		} else {
			sip_transport_response(sipe_private, msg, 481,
					       "Call Leg/Transaction Does Not Exist", NULL);
			found = TRUE;
		}
	}
	if (!found) {
		const gchar *callid = sipmsg_find_header(msg, "Call-ID");
		struct sip_session *session = sipe_session_find_chat_or_im(sipe_private,
									   callid,
									   from);
		if (session) {
			gchar *errmsg = g_strdup_printf(_("Received a message with unrecognized contents from %s"),
							from);
			sipe_user_present_error(sipe_private, session, errmsg);
			g_free(errmsg);
		}

		SIPE_DEBUG_INFO("got unknown mime-type '%s'", contenttype);
		sip_transport_response(sipe_private, msg, 415, "Unsupported media type", NULL);
	}
	g_free(from);
}