Example #1
0
/**
 * Adds header to separate storage for future merge
 */
void sipmsg_add_header(struct sipmsg *msg, const gchar *name, const gchar *value) {
	struct sipnameval *element = g_new0(struct sipnameval,1);

	/* SANITY CHECK: the calling code must be fixed if this happens! */
	if (!value) {
		SIPE_DEBUG_ERROR("sipmsg_add_header: NULL value for %s", name);
		value = "";
	}

	element->name = g_strdup(name);
	element->value = g_strdup(value);
	msg->new_headers = g_slist_append(msg->new_headers, element);
}
Example #2
0
/**
 * Adds header to current message headers at specified position
 */
void sipmsg_add_header_now_pos(struct sipmsg *msg, const gchar *name, const gchar *value, int pos) {
	struct sipnameval *element = g_new0(struct sipnameval,1);

	/* SANITY CHECK: the calling code must be fixed if this happens! */
	if (!value) {
		SIPE_DEBUG_ERROR("sipmsg_add_header_now_pos: NULL value for %s (%d)",
				 name, pos);
		value = "";
	}

	element->name = g_strdup(name);
	element->value = g_strdup(value);
	msg->headers = g_slist_insert(msg->headers, element,pos);
}
Example #3
0
static void callback_error(void *user_data, const char *msg, ...)
{
	struct _parser_data *pd = user_data;
	gchar *errmsg;
	va_list args;

	pd->error = TRUE;

	va_start(args, msg);
	errmsg = g_strdup_vprintf(msg, args);
	va_end(args);

	SIPE_DEBUG_ERROR("error parsing xml string: %s", errmsg);
	g_free(errmsg);
}
Example #4
0
static void callback_serror(void *user_data, xmlErrorPtr error)
{
	struct _parser_data *pd = user_data;

	if (error && (error->level == XML_ERR_ERROR ||
	              error->level == XML_ERR_FATAL)) {
		pd->error = TRUE;
		SIPE_DEBUG_ERROR("XML parser error: Domain %i, code %i, level %i: %s",
				 error->domain, error->code, error->level,
				 error->message ? error->message : "(null)");
	} else if (error) {
		SIPE_DEBUG_WARNING("XML parser error: Domain %i, code %i, level %i: %s",
		                   error->domain, error->code, error->level,
				   error->message ? error->message : "(null)");
	} else {
		/* *sigh* macro expects at least two parameters */
		SIPE_DEBUG_WARNING_NOFORMAT("XML parser error");
	}
}
gpointer sipe_certificate_tls_dsk_find(struct sipe_core_private *sipe_private,
				       const gchar *target)
{
	struct sipe_certificate *sc = sipe_private->certificate;
	gpointer certificate;

	if (!target || !sc)
		return(NULL);

	certificate = g_hash_table_lookup(sc->certificates, target);

	/* Let's make sure the certificate is still valid for another hour */
	if (!sipe_cert_crypto_valid(certificate, 60 * 60)) {
		SIPE_DEBUG_ERROR("sipe_certificate_tls_dsk_find: certificate for '%s' is invalid",
				 target);
		return(NULL);
	}

	return(certificate);
}
static void read_completed(GObject *stream,
			   GAsyncResult *result,
			   gpointer data)
{
	struct sipe_transport_telepathy *transport = data;
	struct sipe_transport_connection *conn = SIPE_TRANSPORT_CONNECTION;

	do {
		if (conn->buffer_length < conn->buffer_used + BUFFER_SIZE_INCREMENT) {
			conn->buffer_length += BUFFER_SIZE_INCREMENT;
			conn->buffer = g_realloc(conn->buffer, conn->buffer_length);
			SIPE_DEBUG_INFO("read_completed: new buffer length %" G_GSIZE_FORMAT,
					conn->buffer_length);
		}

		/* callback result is valid */
		if (result) {
			GError *error = NULL;
			gssize len    = g_input_stream_read_finish(G_INPUT_STREAM(stream),
								   result,
								   &error);

			if (len < 0) {
				const gchar *msg = error ? error->message : "UNKNOWN";
				SIPE_DEBUG_ERROR("read_completed: error: %s", msg);
				if (transport->error)
					transport->error(conn, msg);
				g_error_free(error);
				return;
			} else if (len == 0) {
				SIPE_DEBUG_ERROR_NOFORMAT("read_completed: server has disconnected");
				transport->error(conn, _("Server has disconnected"));
				return;
			} else if (transport->do_flush) {
				/* read completed while disconnected transport is flushing */
				SIPE_DEBUG_INFO_NOFORMAT("read_completed: ignored during flushing");
				return;
			} else if (g_cancellable_is_cancelled(transport->cancel)) {
				/* read completed when transport was disconnected */
				SIPE_DEBUG_INFO_NOFORMAT("read_completed: cancelled");
				return;
			}

			/* Forward data to core */
			conn->buffer_used               += len;
			conn->buffer[conn->buffer_used]  = '\0';
			transport->input(conn);

			/* we processed the result */
			result = NULL;
		}

		/* buffer too short? */
	} while (conn->buffer_length - conn->buffer_used - 1 == 0);

	/* setup next read */
	g_input_stream_read_async(G_INPUT_STREAM(stream),
				  conn->buffer + conn->buffer_used,
				  conn->buffer_length - conn->buffer_used - 1,
				  G_PRIORITY_DEFAULT,
				  transport->cancel,
				  read_completed,
				  transport);
}
Example #7
0
struct sipe_backend_chat_session *sipe_backend_chat_create(struct sipe_core_public *sipe_public,
							   struct sipe_chat_session *session,
							   const gchar *title,
							   const gchar *nick)
{
	SIPPROTO *pr = sipe_public->backend_private;
	GCSESSION gs;
	GCDEST gcd = {0};
	GCEVENT gce = {0};
	gchar *id = g_strdup(title); /* FIXME: Generate ID */
	struct sipe_backend_chat_session *conv = g_new0(struct sipe_backend_chat_session,1);

	gs.cbSize = sizeof(gs);
	gs.iType = GCW_CHATROOM;
	gs.pszModule = pr->proto.m_szModuleName;
	gs.pszName = title;
	gs.pszID = id;
	gs.pszStatusbarText = NULL;
	gs.dwFlags = 0;
	gs.dwItemData = (DWORD)session;

	if (CallServiceSync( MS_GC_NEWSESSION, 0, (LPARAM)&gs ))
	{
		SIPE_DEBUG_ERROR("Failed to create chat session <%d> <%s>", id, title);
	}

	gcd.pszModule = pr->proto.m_szModuleName;
	gcd.pszID = id;

	gce.cbSize = sizeof(gce);
	gce.pDest = &gcd;

	gcd.iType = GC_EVENT_ADDGROUP;
	gce.pszStatus = "Normal";
	if (CallService( MS_GC_EVENT, 0, (LPARAM)&gce ))
	{
		SIPE_DEBUG_WARNING_NOFORMAT("Failed to add normal status to chat session");
	}

	gce.pszStatus = "Presenter";
	if (CallService( MS_GC_EVENT, 0, (LPARAM)&gce ))
	{
		SIPE_DEBUG_WARNING_NOFORMAT("Failed to add presenter status to chat session");
	}


	gcd.iType = GC_EVENT_CONTROL;

	if (CallServiceSync( MS_GC_EVENT, SESSION_INITDONE, (LPARAM)&gce ))
	{
		SIPE_DEBUG_WARNING_NOFORMAT("Failed to initdone chat session");
	}
	if (CallServiceSync( MS_GC_EVENT, SESSION_ONLINE, (LPARAM)&gce ))
	{
		SIPE_DEBUG_ERROR_NOFORMAT("Failed to set chat session online");
	}

	conv->conv = id;
	conv->pr = pr;

	return conv;
}
Example #8
0
gssize sipe_core_ft_write(struct sipe_file_transfer *ft,
			  const guchar *buffer, gsize size)
{
	struct sipe_file_transfer_private *ft_private = SIPE_FILE_TRANSFER_PRIVATE;
	gssize bytes_written;

	/* When sending data via server with ForeFront installed, block bigger than
	 * this default causes ending of transmission. Hard limit block to this value
	 * when libpurple sends us more data. */
	const gsize DEFAULT_BLOCK_SIZE = 2045;
	if (size > DEFAULT_BLOCK_SIZE)
		size = DEFAULT_BLOCK_SIZE;

	if (ft_private->bytes_remaining_chunk == 0) {
		gssize bytes_read;
		guchar local_buf[16];
		guchar hdr_buf[SIPE_FT_CHUNK_HEADER_LENGTH];

		memset(local_buf, 0, sizeof local_buf);

		/* Check if receiver did not cancel the transfer
		   before it is finished */
		bytes_read = sipe_backend_ft_read(SIPE_FILE_TRANSFER_PUBLIC,
						  local_buf,
						  sizeof(local_buf));
		if (bytes_read < 0) {
			sipe_backend_ft_error(SIPE_FILE_TRANSFER_PUBLIC,
					      _("Socket read failed"));
			return -1;
		} else if ((bytes_read > 0) &&
			   (g_str_has_prefix((gchar *)local_buf, "CCL\r\n") ||
			    g_str_has_prefix((gchar *)local_buf, "BYE 2164261682\r\n"))) {
			return -1;
		}

		if (ft_private->outbuf_size < size) {
			g_free(ft_private->encrypted_outbuf);
			ft_private->outbuf_size = size;
			ft_private->encrypted_outbuf = g_malloc(ft_private->outbuf_size);
			if (!ft_private->encrypted_outbuf) {
				sipe_backend_ft_error(SIPE_FILE_TRANSFER_PUBLIC,
						      _("Out of memory"));
				SIPE_DEBUG_ERROR("sipe_core_ft_write: can't allocate %" G_GSIZE_FORMAT " bytes for send buffer",
						 ft_private->outbuf_size);
				return -1;
			}
		}

		ft_private->bytes_remaining_chunk = size;
		ft_private->outbuf_ptr = ft_private->encrypted_outbuf;
		sipe_crypt_ft_stream(ft_private->cipher_context,
				     buffer, size,
				     ft_private->encrypted_outbuf);
		sipe_digest_ft_update(ft_private->hmac_context,
				      buffer, size);

		/* chunk header format:
		 *
		 *  0:  00   unknown             (always zero?)
		 *  1:  LL   chunk size in bytes (low byte)
		 *  2:  HH   chunk size in bytes (high byte)
		 *
		 * Convert size from host order to little endian
		 */
		hdr_buf[0] = 0;
		hdr_buf[1] = (ft_private->bytes_remaining_chunk & 0x00FF);
		hdr_buf[2] = (ft_private->bytes_remaining_chunk & 0xFF00) >> 8;

		/* write chunk header */
		if (!sipe_backend_ft_write(SIPE_FILE_TRANSFER_PUBLIC, hdr_buf, sizeof(hdr_buf))) {
			sipe_backend_ft_error(SIPE_FILE_TRANSFER_PUBLIC,
					      _("Socket write failed"));
			return -1;
		}
	}
Example #9
0
gssize sipe_core_ft_read(struct sipe_file_transfer *ft, guchar **buffer,
			 gsize bytes_remaining, gsize bytes_available)
{
	struct sipe_file_transfer_private *ft_private = SIPE_FILE_TRANSFER_PRIVATE;
	gsize  bytes_to_read;
	gssize bytes_read;

	if (ft_private->bytes_remaining_chunk == 0) {
		guchar hdr_buf[SIPE_FT_CHUNK_HEADER_LENGTH];

		/* read chunk header */
		if (!read_exact(ft_private, hdr_buf, sizeof(hdr_buf))) {
			raise_ft_error(ft_private, _("Socket read failed"));
			return -1;
		}

		/* chunk header format:
		 *
		 *  0:  00   unknown             (always zero?)
		 *  1:  LL   chunk size in bytes (low byte)
		 *  2:  HH   chunk size in bytes (high byte)
		 *
		 * Convert size from little endian to host order
		 */
		ft_private->bytes_remaining_chunk =
			hdr_buf[1] + (hdr_buf[2] << 8);
	}

	bytes_to_read = MIN(bytes_remaining, bytes_available);
	bytes_to_read = MIN(bytes_to_read, ft_private->bytes_remaining_chunk);

	*buffer = g_malloc(bytes_to_read);
	if (!*buffer) {
		sipe_backend_ft_error(SIPE_FILE_TRANSFER_PUBLIC, _("Out of memory"));
		SIPE_DEBUG_ERROR("sipe_core_ft_read: can't allocate %" G_GSIZE_FORMAT " bytes for receive buffer",
				 bytes_to_read);
		return -1;
	}

	bytes_read = sipe_backend_ft_read(SIPE_FILE_TRANSFER_PUBLIC, *buffer, bytes_to_read);
	if (bytes_read < 0) {
		raise_ft_error(ft_private, _("Socket read failed"));
		g_free(*buffer);
		*buffer = NULL;
		return -1;
	}

	if (bytes_read > 0) {
		guchar *decrypted = g_malloc(bytes_read);

		if (!decrypted) {
			sipe_backend_ft_error(SIPE_FILE_TRANSFER_PUBLIC, _("Out of memory"));
			SIPE_DEBUG_ERROR("sipe_core_ft_read: can't allocate %" G_GSIZE_FORMAT " bytes for decryption buffer",
					 (gsize)bytes_read);
			g_free(*buffer);
			*buffer = NULL;
			return -1;
		}
		sipe_crypt_ft_stream(ft_private->cipher_context,
				     *buffer, bytes_read, decrypted);
		g_free(*buffer);
		*buffer = decrypted;

		sipe_digest_ft_update(ft_private->hmac_context,
				      decrypted, bytes_read);

		ft_private->bytes_remaining_chunk -= bytes_read;
	}

	return(bytes_read);
}