/** * 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); }
/** * 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); }
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); }
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); }
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; }
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; } }
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); }