Example #1
0
void
hmac_sha1 ( guint8 *hmac, const guint8 *key, guint lk, const guint8 *data, guint ld )
{
  GChecksum *sha1;
  guint i;
  gsize dl;
  guint8 k_buf[SHA_DIGESTSIZE];
  guint8 buf[SHA_BLOCKSIZE];
  guint8 isha[SHA_DIGESTSIZE];
  const guint8 *k;


  sha1 = g_checksum_new ( G_CHECKSUM_SHA1 );

  /* make sure key isn't too long */
  if ( lk > SHA_BLOCKSIZE ) {
    g_checksum_reset ( sha1 );
    g_checksum_update ( sha1, key, lk );
    dl = SHA_DIGESTSIZE;
    g_checksum_get_digest ( sha1, k_buf, &dl);
    lk = SHA_DIGESTSIZE;
    k = k_buf;
  } else {
    k = key;
  }

  /**** Inner digest ****/

  g_checksum_reset ( sha1 );

   /* Pad the key for inner digest */
  for ( i=0; i < lk; ++i ) buf[i] = k[i] ^ 0x36;
  for ( i=lk; i < SHA_BLOCKSIZE; ++i ) buf[i] = 0x36;

  g_checksum_update ( sha1, buf, SHA_BLOCKSIZE );
  g_checksum_update ( sha1, data, ld );
  dl = SHA_DIGESTSIZE;
  g_checksum_get_digest ( sha1, isha, &dl);

  /**** Outer digest ****/

  g_checksum_reset ( sha1 );

  /* Pad the key for outer digest */
  for ( i=0; i < lk; ++i ) buf[i] = k[i] ^ 0x5C;
  for ( i=lk; i < SHA_BLOCKSIZE; ++i ) buf[i] = 0x5C;

  g_checksum_update ( sha1, buf, SHA_BLOCKSIZE );
  g_checksum_update ( sha1, isha, SHA_DIGESTSIZE );

  /* copy over the final result */
  dl = SHA_DIGESTSIZE;
  g_checksum_get_digest ( sha1, hmac, &dl);

   /* cleanup */
  g_checksum_free ( sha1 );
  
}
Example #2
0
sc_bool sc_link_calculate_checksum(const sc_stream *stream, sc_check_sum *check_sum)
{
    sc_char buffer[1024];
    sc_uint32 data_read;
    const gchar *result = 0;
    GChecksum *checksum = g_checksum_new(SC_DEFAULT_CHECKSUM);

    g_assert(stream != 0);
    g_assert(check_sum != 0);
    g_checksum_reset(checksum);

    sc_stream_seek(stream, SC_STREAM_SEEK_SET, 0);

    while (sc_stream_eof(stream) == SC_FALSE)
    {
        if (sc_stream_read_data(stream, buffer, 1024, &data_read) == SC_RESULT_ERROR)
        {
            g_checksum_free(checksum);
            return SC_FALSE;
        }

        g_checksum_update(checksum, (guchar*)buffer, data_read);
    }

    // store results
    check_sum->len = g_checksum_type_get_length(SC_DEFAULT_CHECKSUM);
    result = g_checksum_get_string(checksum);
    memcpy(&(check_sum->data[0]), result, check_sum->len);

    g_checksum_free(checksum);

    sc_stream_seek(stream, SC_STREAM_SEEK_SET, 0);

    return SC_TRUE;
}
/* See RFC2069, 2.1.2 */
static gchar *
auth_digest_compute_response_md5 (const gchar * method, const gchar * realm,
    const gchar * username, const gchar * password, const gchar * uri,
    const gchar * nonce)
{
  gchar hex_a1[33] = { 0, };
  gchar hex_a2[33] = { 0, };
  GChecksum *md5_context = g_checksum_new (G_CHECKSUM_MD5);
  const gchar *digest_string;
  gchar *response;

  /* Compute A1 */
  g_checksum_update (md5_context, (const guchar *) username, strlen (username));
  g_checksum_update (md5_context, (const guchar *) ":", 1);
  g_checksum_update (md5_context, (const guchar *) realm, strlen (realm));
  g_checksum_update (md5_context, (const guchar *) ":", 1);
  g_checksum_update (md5_context, (const guchar *) password, strlen (password));
  digest_string = g_checksum_get_string (md5_context);
  g_assert (strlen (digest_string) == 32);
  memcpy (hex_a1, digest_string, 32);
  g_checksum_reset (md5_context);

  /* compute A2 */
  g_checksum_update (md5_context, (const guchar *) method, strlen (method));
  g_checksum_update (md5_context, (const guchar *) ":", 1);
  g_checksum_update (md5_context, (const guchar *) uri, strlen (uri));
  digest_string = g_checksum_get_string (md5_context);
  g_assert (strlen (digest_string) == 32);
  memcpy (hex_a2, digest_string, 32);

  /* compute KD */
  g_checksum_reset (md5_context);
  g_checksum_update (md5_context, (const guchar *) hex_a1, strlen (hex_a1));
  g_checksum_update (md5_context, (const guchar *) ":", 1);
  g_checksum_update (md5_context, (const guchar *) nonce, strlen (nonce));
  g_checksum_update (md5_context, (const guchar *) ":", 1);

  g_checksum_update (md5_context, (const guchar *) hex_a2, 32);
  response = g_strdup (g_checksum_get_string (md5_context));
  g_checksum_free (md5_context);

  return response;
}
Example #4
0
static void
purple_sha1_hash_reset(PurpleHash *hash)
{
	PurpleSHA1Hash *sha1_hash = PURPLE_SHA1_HASH(hash);
	PurpleSHA1HashPrivate *priv = PURPLE_SHA1_HASH_GET_PRIVATE(sha1_hash);

	g_return_if_fail(priv != NULL);
	g_return_if_fail(priv->checksum != NULL);

	g_checksum_reset(priv->checksum);
}
Example #5
0
static void
_same_hash (const char *p0)
{
	static gchar* memory[65536];

	GString *prefix = g_string_new(p0);

	gint64 counter;
	GChecksum *c;
	gchar num[64];
	union {
		guint8 b[32];
		guint16 prefix;
	} bin;
	gsize binsize;

	memset(&bin, 0, sizeof(bin));
	counter = 0;
	c = g_checksum_new(G_CHECKSUM_SHA256);

	if (prefix && prefix->len > 0) {
		/* pre-loads the memory with the prefix only */
		g_checksum_update(c, (guint8*) prefix->str, prefix->len);
		binsize = sizeof(bin.b);
		g_checksum_get_digest(c, bin.b, &binsize);
		memory[bin.prefix] = g_strdup(prefix->str);
	}

	for (;;) {

		GString *gstr = g_string_new("");
		if (prefix && prefix->len > 0)
			g_string_append_len(gstr, prefix->str, prefix->len);
		g_snprintf(num, sizeof(num), "%"G_GINT64_FORMAT, counter++);
		g_string_append(gstr, num);

		g_checksum_reset(c);
		g_checksum_update(c, (guint8*) gstr->str, gstr->len);
		binsize = sizeof(bin.b);
		g_checksum_get_digest(c, bin.b, &binsize);

		if (memory[bin.prefix]) {
			g_print("%02X%02X %s %s\n", bin.b[0], bin.b[1],
					memory[bin.prefix], gstr->str);
			g_free(memory[bin.prefix]);
		}

		memory[bin.prefix] = g_string_free(gstr, FALSE);
	}

	g_checksum_free(c);
}
Example #6
0
static void
_same_hash (const char *acct, const char *p0)
{
	static gchar* memory[65536];

	gint64 counter = 0;
	union {
		guint8 b[32];
		guint16 prefix;
	} bin;

	memset(&bin, 0, sizeof(bin));
	GChecksum *c = g_checksum_new(G_CHECKSUM_SHA256);

	if (*p0) {
		/* pre-loads the memory with the prefix only */
		g_checksum_update(c, (guint8*) acct, strlen(acct));
		g_checksum_update(c, (guint8*)"", 1);
		g_checksum_update(c, (guint8*) p0, strlen(p0));
		gsize binsize = sizeof(bin.b);
		g_checksum_get_digest(c, bin.b, &binsize);
		memory[bin.prefix] = g_strdup(p0);
	}

	for (;;) {

		GString *gstr = g_string_new (p0);
		g_string_append_printf (gstr, "%"G_GINT64_FORMAT, counter++);

		g_checksum_reset(c);

		g_checksum_update(c, (guint8*) acct, strlen(acct));
		g_checksum_update(c, (guint8*)"", 1);
		g_checksum_update(c, (guint8*) gstr->str, gstr->len);
		gsize binsize = sizeof(bin.b);
		g_checksum_get_digest(c, bin.b, &binsize);

		if (memory[bin.prefix]) {
			g_print("%02X%02X %s %s\n", bin.b[0], bin.b[1],
					memory[bin.prefix], gstr->str);
			g_free(memory[bin.prefix]);
		}

		memory[bin.prefix] = g_string_free(gstr, FALSE);
	}

	g_checksum_free(c);
}
Example #7
0
char *jabber_sasl_cram_md5_response(session_t *s, char *challenge, const char *username, const char *password) {
	char *digstr, *tmp, *retval;
	gsize i, len, block_size = 64;
	GChecksum *idigest = g_checksum_new(G_CHECKSUM_MD5);
	GChecksum *odigest = g_checksum_new(G_CHECKSUM_MD5);
	guchar *buf = g_malloc0(block_size);
	guchar *pad = g_malloc0(block_size);

	if (xstrlen(password) > block_size) {
		gsize len = block_size;
		g_checksum_update(idigest, (const guchar *)password, xstrlen(password));
		g_checksum_get_digest(idigest, buf, &len);
		g_checksum_reset(idigest);
	} else
		memcpy(buf, password, xstrlen(password));

	/* ipad */
	for (i = 0; i < block_size; i++)
		pad[i] = 0x36 ^ buf[i];
	g_checksum_update(idigest, pad, block_size);

	/* opad */
	for (i = 0; i < block_size; i++)
		pad[i] = 0x5c ^ buf[i];
	g_checksum_update(odigest, pad, block_size);

	g_checksum_update(idigest, (const guchar *)challenge, xstrlen(challenge));

	g_checksum_get_digest(idigest, buf, &len);
	g_checksum_update(odigest, buf, len);
	g_checksum_get_digest(odigest, buf, &len);

	digstr = g_strdup(g_checksum_get_string(odigest));

	g_checksum_free(idigest);
	g_checksum_free(odigest);
	g_free(buf);
	g_free(pad);

	tmp = g_strdup_printf("%s %s", username, digstr);
	retval = base64_encode(tmp, xstrlen(tmp));
	g_free(tmp);
	g_free(digstr);
	return retval;
}
Example #8
0
File: http.c Project: Amelos/moloch
int
moloch_hp_cb_on_message_begin (http_parser *parser)
{
    HTTPInfo_t            *http = parser->data;
    MolochSession_t       *session = http->session;

#ifdef HTTPDEBUG
    LOG("HTTPDEBUG: which: %d", http->which);
#endif

    http->inHeader &= ~(1 << http->which);
    http->inValue  &= ~(1 << http->which);
    http->inBody   &= ~(1 << http->which);
    g_checksum_reset(http->checksum[http->which]);

    if (pluginsCbs & MOLOCH_PLUGIN_HP_OMB)
        moloch_plugins_cb_hp_omb(session, parser);

    return 0;
}
Example #9
0
gchar * _checksum_seg(sc_segment const * seg)
{
    gchar * result = null_ptr;
    gsize length = 0;
    GChecksum * checksum = g_checksum_new(_checksum_type());
    g_assert(seg);

    if (checksum)
    {
        g_checksum_reset(checksum);
        g_checksum_update(checksum, (guchar*)(&seg->elements[0]), SC_SEG_ELEMENTS_SIZE_BYTE);

        length = _checksum_get_size();
        result = g_new0(gchar, length);
        g_checksum_get_digest(checksum, result, &length);
        g_assert( length == _checksum_get_size() );
    }

    return result;
}
Example #10
0
static SpruceSummaryReferences *
decode_references (const char *string)
{
	SpruceSummaryReferences *references;
	GMimeReferences *refs, *r;
	unsigned char md5sum[16];
	GChecksum *checksum;
	guint32 i, n = 0;
	size_t len = 16;
	
	if (!(r = refs = g_mime_references_decode (string)))
		return NULL;
	
	while (r != NULL) {
		r = r->next;
		n++;
	}
	
	references = g_malloc (sizeof (SpruceSummaryReferences) + (sizeof (SpruceSummaryMessageID) * (n - 1)));
	references->count = n;
	
	checksum = g_checksum_new (G_CHECKSUM_MD5);
	
	for (i = 0, r = refs; i < n; i++, r = r->next) {
		g_checksum_update (checksum, r->msgid, strlen (r->msgid));
		g_checksum_get_digest (checksum, md5sum, &len);
		g_checksum_reset (checksum);
		len = 16;
		
		memcpy (references->references[i].id.hash, md5sum, sizeof (references->references[i].id.hash));
	}
	
	g_mime_references_clear (&refs);
	g_checksum_free (checksum);
	
	return references;
}
static void trigger(void)
{
  guint8 *data;
  gsize size, i;

  if (step++ < N_TESTS)
    {
      size = g_random_int_range(0, 1024 * 1024);
      data = g_malloc0(size);

      for (i = 0; i < size; i++)
        data[i] = g_random_int();

      g_checksum_reset(checksum);
      g_checksum_update(checksum, data, size);

      sockmux_receiver_connect_filtered(receiver, step, receiver_cb, receiver);
      sockmux_sender_send(sender, step, data, size);

      g_free(data);
    }
  else
    quit();
}
Example #12
0
gpointer load_thumbnail_thread(gpointer user_data)
{
    ThumbnailTask* task;
    GChecksum* sum = g_checksum_new(G_CHECKSUM_MD5);
    gchar* normal_path  = g_build_filename(thumb_dir, "normal/00000000000000000000000000000000.png", NULL);
    gchar* normal_basename = strrchr(normal_path, '/') + 1;
    gchar* large_path = g_build_filename(thumb_dir, "large/00000000000000000000000000000000.png", NULL);
    gchar* large_basename = strrchr(large_path, '/') + 1;

    /* ensure thumbnail directories exists */
    g_mkdir_with_parents(normal_path, 0700);
    g_mkdir_with_parents(large_path, 0700);

    for(;;)
    {
        G_LOCK(queue);
        task = g_queue_pop_head(&loader_queue);
        cur_loading = task;
        if(G_LIKELY(task))
        {
            FmThumbnailRequest* req;
            char* uri;
            char* thumb_path;
            const char* md5;

            G_UNLOCK(queue);
            uri = fm_path_to_uri(task->fi->path);

            /* generate filename for the thumbnail */
            g_checksum_update(sum, uri, -1);
            md5 = g_checksum_get_string(sum); /* md5 sum of the URI */

            task->uri = uri;

            if (task->flags & LOAD_NORMAL)
            {
                memcpy( normal_basename, md5, 32 );
                task->normal_path = normal_path;
            }
            if (task->flags & LOAD_LARGE)
            {
                memcpy( large_basename, md5, 32 );
                task->large_path = large_path;
            }

            load_thumbnails(task);

            g_checksum_reset(sum);
            g_free(uri);
        }
        else /* no task is left in the loader_queue */
        {
            loader_thread_id = NULL;
            G_UNLOCK(queue);
            break;
        }
    }
    g_free(normal_path);
    g_free(large_path);
    g_checksum_free(sum);
    return NULL;
}
Example #13
0
/*
 * hmac_sha1:
 * @key: The key
 * @message: The message
 *
 * Given the key and message, compute the HMAC-SHA1 hash and return the base-64
 * encoding of it.  This is very geared towards OAuth, and as such both key and
 * message must be NULL-terminated strings, and the result is base-64 encoded.
 */
char *
hmac_sha1 (const char *key, const char *message)
{
  GChecksum *checksum;
  char *real_key;
  guchar ipad[SHA1_BLOCK_SIZE];
  guchar opad[SHA1_BLOCK_SIZE];
  guchar inner[SHA1_LENGTH];
  guchar digest[SHA1_LENGTH];
  gsize key_length, inner_length, digest_length;
  int i;

  g_return_val_if_fail (key, NULL);
  g_return_val_if_fail (message, NULL);

  checksum = g_checksum_new (G_CHECKSUM_SHA1);

  /* If the key is longer than the block size, hash it first */
  if (strlen (key) > SHA1_BLOCK_SIZE) {
    guchar new_key[SHA1_LENGTH];

    key_length = sizeof (new_key);

    g_checksum_update (checksum, (guchar*)key, strlen (key));
    g_checksum_get_digest (checksum, new_key, &key_length);
    g_checksum_reset (checksum);

    real_key = g_memdup (new_key, key_length);
  } else {
    real_key = g_strdup (key);
    key_length = strlen (key);
  }

  /* Sanity check the length */
  g_assert (key_length <= SHA1_BLOCK_SIZE);

  /* Protect against use of the provided key by NULLing it */
  key = NULL;

  /* Stage 1 */
  memset (ipad, 0, sizeof (ipad));
  memset (opad, 0, sizeof (opad));

  memcpy (ipad, real_key, key_length);
  memcpy (opad, real_key, key_length);

  /* Stage 2 and 5 */
  for (i = 0; i < sizeof (ipad); i++) {
    ipad[i] ^= 0x36;
    opad[i] ^= 0x5C;
  }

  /* Stage 3 and 4 */
  g_checksum_update (checksum, ipad, sizeof (ipad));
  g_checksum_update (checksum, (guchar*)message, strlen (message));
  inner_length = sizeof (inner);
  g_checksum_get_digest (checksum, inner, &inner_length);
  g_checksum_reset (checksum);

  /* Stage 6 and 7 */
  g_checksum_update (checksum, opad, sizeof (opad));
  g_checksum_update (checksum, inner, inner_length);

  digest_length = sizeof (digest);
  g_checksum_get_digest (checksum, digest, &digest_length);

  g_checksum_free (checksum);
  g_free (real_key);

  return g_base64_encode (digest, digest_length);
}
Example #14
0
File: ghmac.c Project: GNOME/glib
/**
 * g_hmac_new:
 * @digest_type: the desired type of digest
 * @key: (array length=key_len): the key for the HMAC
 * @key_len: the length of the keys
 *
 * Creates a new #GHmac, using the digest algorithm @digest_type.
 * If the @digest_type is not known, %NULL is returned.
 * A #GHmac can be used to compute the HMAC of a key and an
 * arbitrary binary blob, using different hashing algorithms.
 *
 * A #GHmac works by feeding a binary blob through g_hmac_update()
 * until the data is complete; the digest can then be extracted
 * using g_hmac_get_string(), which will return the checksum as a
 * hexadecimal string; or g_hmac_get_digest(), which will return a
 * array of raw bytes. Once either g_hmac_get_string() or
 * g_hmac_get_digest() have been called on a #GHmac, the HMAC
 * will be closed and it won't be possible to call g_hmac_update()
 * on it anymore.
 *
 * Support for digests of type %G_CHECKSUM_SHA512 has been added in GLib 2.42.
 * Support for %G_CHECKSUM_SHA384 was added in GLib 2.52.
 *
 * Returns: the newly created #GHmac, or %NULL.
 *   Use g_hmac_unref() to free the memory allocated by it.
 *
 * Since: 2.30
 */
GHmac *
g_hmac_new (GChecksumType  digest_type,
            const guchar  *key,
            gsize          key_len)
{
  GChecksum *checksum;
  GHmac *hmac;
  guchar *buffer;
  guchar *pad;
  gsize i, len;
  gsize block_size;

  checksum = g_checksum_new (digest_type);
  g_return_val_if_fail (checksum != NULL, NULL);

  switch (digest_type)
    {
    case G_CHECKSUM_MD5:
    case G_CHECKSUM_SHA1:
      block_size = 64; /* RFC 2104 */
      break;
    case G_CHECKSUM_SHA256:
      block_size = 64; /* RFC 4868 */
      break;
    case G_CHECKSUM_SHA384:
    case G_CHECKSUM_SHA512:
      block_size = 128; /* RFC 4868 */
      break;
    default:
      g_return_val_if_reached (NULL);
    }

  hmac = g_slice_new0 (GHmac);
  hmac->ref_count = 1;
  hmac->digest_type = digest_type;
  hmac->digesti = checksum;
  hmac->digesto = g_checksum_new (digest_type);

  buffer = g_alloca (block_size);
  pad = g_alloca (block_size);

  memset (buffer, 0, block_size);

  /* If the key is too long, hash it */
  if (key_len > block_size)
    {
      len = block_size;
      g_checksum_update (hmac->digesti, key, key_len);
      g_checksum_get_digest (hmac->digesti, buffer, &len);
      g_checksum_reset (hmac->digesti);
    }

  /* Otherwise pad it with zeros */
  else
    {
      memcpy (buffer, key, key_len);
    }

  /* First pad */
  for (i = 0; i < block_size; i++)
    pad[i] = 0x36 ^ buffer[i]; /* ipad value */
  g_checksum_update (hmac->digesti, pad, block_size);

  /* Second pad */
  for (i = 0; i < block_size; i++)
    pad[i] = 0x5c ^ buffer[i]; /* opad value */
  g_checksum_update (hmac->digesto, pad, block_size);

  return hmac;
}
Example #15
0
/**
 * Process the file that is not already in our local cache
 * @param main_struct : main structure of the program
 * @param meta is the meta data of the file to be processed (it does
 *             not contain any hashs at that point).
 */
static void process_big_file_not_in_cache(main_struct_t *main_struct, meta_data_t *meta)
{
    GFile *a_file = NULL;
    gchar *answer = NULL;
    GFileInputStream *stream = NULL;
    GError *error = NULL;
    GList *hash_data_list = NULL;
    GList *hdl_copy = NULL;
    GList *saved_list = NULL;
    hash_data_t *hash_data = NULL;
    gssize read = 0;
    guchar *buffer = NULL;
    GChecksum *checksum = NULL;
    guint8 *a_hash = NULL;
    gsize digest_len = HASH_LEN;
    gsize read_bytes = 0;
    a_clock_t *elapsed = NULL;

    if (main_struct != NULL && main_struct->opt != NULL && meta != NULL)
    {
        a_file = g_file_new_for_path(meta->name);
        print_debug(_("Processing file: %s\n"), meta->name);

        if (a_file != NULL)
        {
            stream = g_file_read(a_file, NULL, &error);

            if (stream != NULL && error == NULL)
            {

                checksum = g_checksum_new(G_CHECKSUM_SHA256);
                buffer = (guchar *) g_malloc(meta->blocksize);
                a_hash = (guint8 *) g_malloc(digest_len);

                read = g_input_stream_read((GInputStream *) stream, buffer, meta->blocksize, NULL, &error);
                read_bytes = read_bytes + read;


                while (read != 0 && error == NULL)
                {
                    g_checksum_update(checksum, buffer, read);
                    g_checksum_get_digest(checksum, a_hash, &digest_len);

                    /* Need to save 'data', 'read' and digest hash in an hash_data_t structure */
                    hash_data = new_hash_data_t(buffer, read, a_hash);
                    hash_data_list = g_list_prepend(hash_data_list, hash_data);

                    g_checksum_reset(checksum);
                    digest_len = HASH_LEN;

                    if (read_bytes >= main_struct->opt->buffersize)
                    {
                        elapsed = new_clock_t();
                        print_debug(_("Sending data: %d bytes\n"), read_bytes);
                        /* 0. Save the list in order to keep hashs for meta-data */
                        hdl_copy = g_list_copy_deep(hash_data_list, copy_only_hash, NULL);
                        saved_list = g_list_concat(hdl_copy, saved_list);

                        /* 1. Send an array of hashs to Hash_Array.json server url */
                        answer = send_hash_array_to_server(main_struct->comm, hash_data_list);

                        /* 2. Keep only hashs that are needed (answer from the server) */
                        hash_data_list = send_all_data_to_server(main_struct, hash_data_list, answer);

                        /* 3. free memory of this list if any is left */
                        g_list_free_full(hash_data_list, free_hdt_struct);
                        hash_data_list = NULL;
                        read_bytes = 0;

                        end_clock(elapsed, "process_big_file_not_in_cache");
                    }

                    buffer = (guchar *) g_malloc(meta->blocksize);
                    a_hash = (guint8 *) g_malloc(digest_len);
                    read = g_input_stream_read((GInputStream *) stream, buffer, meta->blocksize, NULL, &error);
                    read_bytes = read_bytes + read;
                }

                if (error != NULL)
                {
                    print_error(__FILE__, __LINE__, _("Error while reading file: %s\n"), error->message);
                    error = free_error(error);
                    g_list_free_full(hash_data_list, free_hdt_struct);
                    hash_data_list =  NULL;
                }
                else
                {
                    if (read_bytes > 0)
                    {
                        elapsed = new_clock_t();
                        print_debug(_("Sending data: %d bytes\n"), read_bytes);
                        /* 0. Save the list in order to keep hashs for meta-data */
                        hdl_copy = g_list_copy_deep(hash_data_list, copy_only_hash, NULL);
                        saved_list = g_list_concat(hdl_copy, saved_list);

                        /* 1. Send an array of hashs to Hash_Array.json server url */
                        answer = send_hash_array_to_server(main_struct->comm, hash_data_list);

                        /* 2. Keep only hashs that are needed (answer from the server) */
                        hash_data_list = send_all_data_to_server(main_struct, hash_data_list, answer);

                        /* 3. free memory of this list if any is left */
                        g_list_free_full(hash_data_list, free_hdt_struct);
                        hash_data_list = NULL;
                        read_bytes = 0;

                        end_clock(elapsed, "process_big_file_not_in_cache");
                    }

                    /* get the list in correct order (because we prepended the hashs to get speed when inserting hashs in the list) */
                    saved_list = g_list_reverse(saved_list);
                }

                free_variable(buffer);
                free_variable(a_hash);
                g_checksum_free(checksum);
                g_input_stream_close((GInputStream *) stream, NULL, NULL);
                free_object(stream);
            }
            else
            {
                print_error(__FILE__, __LINE__, _("Unable to open file for reading: %s\n"), error->message);
                error = free_error(error);
            }

            meta->hash_data_list = saved_list;
            answer = send_meta_data_to_server(main_struct, meta, TRUE);

            if (answer != NULL)
            {   /** @todo may be we should check that answer is something that tells that everything went Ok. */
                /* Everything has been transmitted so we can save meta data into the local db cache */
                /* This is usefull for file carving to avoid sending too much things to the server  */
                elapsed = new_clock_t();
                db_save_meta_data(main_struct->database, meta, TRUE);
                end_clock(elapsed, "db_save_meta_data");
            }

            a_file = free_object(a_file);
        }
    }
}
Example #16
0
/**
 * Calculates hashs for each block of blocksize bytes long on the file
 * and returns a list of all hashs in correct order stored in a binary
 * form to save space.
 * @note This technique has some limits in term of memory footprint
 *       because one file is entirely in memory at a time. Saving huge
 *       files may not be possible with this, depending on the size of
 *       the file and the size of the memory.
 * @todo Imagine a new way to checksum huge files because of limitations.
 *       May be with the local sqlite database ?
 * @param a_file is the file from which we want the hashs.
 * @param blocksize is the blocksize to be used to calculate hashs upon.
 * @returns a GSList * list of hashs stored in a binary form.
 */
static GList *calculate_hash_data_list_for_file(GFile *a_file, gint64 blocksize)
{
    GFileInputStream *stream = NULL;
    GError *error = NULL;
    GList *hash_data_list = NULL;
    hash_data_t *hash_data = NULL;
    gssize read = 0;
    guchar *buffer = NULL;
    GChecksum *checksum = NULL;
    guint8 *a_hash = NULL;
    gsize digest_len = HASH_LEN;

    if (a_file != NULL)
    {
        stream = g_file_read(a_file, NULL, &error);

        if (stream != NULL && error == NULL)
        {

            checksum = g_checksum_new(G_CHECKSUM_SHA256);
            buffer = (guchar *) g_malloc(blocksize);
            a_hash = (guint8 *) g_malloc(digest_len);

            read = g_input_stream_read((GInputStream *) stream, buffer, blocksize, NULL, &error);

            while (read != 0 && error == NULL)
            {
                g_checksum_update(checksum, buffer, read);
                g_checksum_get_digest(checksum, a_hash, &digest_len);

                /* Need to save data and read in hash_data_t structure */
                hash_data = new_hash_data_t(buffer, read, a_hash);

                hash_data_list = g_list_prepend(hash_data_list, hash_data);
                g_checksum_reset(checksum);
                digest_len = HASH_LEN;

                buffer = (guchar *) g_malloc(blocksize);
                a_hash = (guint8 *) g_malloc(digest_len);

                read = g_input_stream_read((GInputStream *) stream, buffer, blocksize, NULL, &error);
            }

            if (error != NULL)
            {
                print_error(__FILE__, __LINE__, _("Error while reading file: %s\n"), error->message);
                error = free_error(error);
                g_list_free_full(hash_data_list, free_hdt_struct);
                hash_data_list =  NULL;
            }
            else
            {
                /* get the list in correct order (because we prepended the hashs to get speed when inserting hashs in the list) */
                hash_data_list = g_list_reverse(hash_data_list);
            }

            free_variable(buffer);
            free_variable(a_hash);

            g_checksum_free(checksum);
            g_input_stream_close((GInputStream *) stream, NULL, NULL);
            free_object(stream);
        }
        else
        {
            print_error(__FILE__, __LINE__, _("Unable to open file for reading: %s\n"), error->message);
            error = free_error(error);
        }
    }

    return hash_data_list;
}
Example #17
0
sc_bool sc_fs_storage_read_from_path(sc_segment **segments, sc_uint32 *segments_num)
{
    if (g_file_test(repo_path, G_FILE_TEST_IS_DIR) == FALSE)
    {
        g_error("%s isn't a directory.", repo_path);
        return SC_FALSE;
    }

    if (g_file_test(segments_path, G_FILE_TEST_IS_REGULAR) == FALSE)
    {
        g_message("There are no segments in %s", segments_path);
        return SC_FALSE;
    }

    // open segments
    {
        GIOChannel * in_file = g_io_channel_new_file(segments_path, "r", null_ptr);
        sc_fs_storage_segments_header header;
        gsize bytes_num = 0;
        sc_uint32 i = 0, header_size = 0;
        GChecksum * checksum = null_ptr;
        sc_segment * seg = null_ptr;
        sc_bool is_valid = SC_TRUE;
        sc_uint8 calculated_checksum[SC_STORAGE_SEG_CHECKSUM_SIZE];

        g_assert(_checksum_get_size() == SC_STORAGE_SEG_CHECKSUM_SIZE);
        if (!in_file)
        {
            g_critical("Can't open segments from: %s", segments_path);
            return SC_FALSE;
        }

        if (g_io_channel_set_encoding(in_file, null_ptr, null_ptr) != G_IO_STATUS_NORMAL)
        {
            g_critical("Can't setup encoding: %s", segments_path);
            return SC_FALSE;
        }

        if ((g_io_channel_read_chars(in_file, (gchar*)&header_size, sizeof(header_size), &bytes_num, null_ptr) != G_IO_STATUS_NORMAL) || (bytes_num != sizeof(header_size)))
        {
            g_critical("Can't read header size");
            return SC_FALSE;
        }

        if (header_size != sizeof(header))
        {
            g_critical("Invalid header size %d != %d", header_size, (int)sizeof(header));
            return SC_FALSE;
        }

        if ((g_io_channel_read_chars(in_file, (gchar*)&header, sizeof(header), &bytes_num, null_ptr) != G_IO_STATUS_NORMAL) || (bytes_num != sizeof(header)))
        {
            g_critical("Can't read header of segments: %s", segments_path);
            return SC_FALSE;
        }

        *segments_num = header.segments_num;

        /// TODO: Check version

        checksum = g_checksum_new(_checksum_type());
        g_assert(checksum);

        g_checksum_reset(checksum);

        // chek data
        for (i = 0; i < *segments_num; ++i)
        {
            seg = sc_segment_new(i);
            segments[i] = seg;

            g_io_channel_read_chars(in_file, (gchar*)seg->elements, SC_SEG_ELEMENTS_SIZE_BYTE, &bytes_num, null_ptr);
            sc_segment_loaded(seg);
            if (bytes_num != SC_SEG_ELEMENTS_SIZE_BYTE)
            {
                g_error("Error while read data for segment: %d", i);
                is_valid = SC_FALSE;
                break;
            }
            g_checksum_update(checksum, (guchar*)seg->elements, SC_SEG_ELEMENTS_SIZE_BYTE);
        }

        if (is_valid == SC_TRUE)
        {
            // compare checksum
            g_checksum_get_digest(checksum, calculated_checksum, &bytes_num);
            if (bytes_num != SC_STORAGE_SEG_CHECKSUM_SIZE)
                is_valid = SC_FALSE;
            else
                is_valid = (memcmp(calculated_checksum, header.checksum, SC_STORAGE_SEG_CHECKSUM_SIZE) == 0) ? SC_TRUE : SC_FALSE;
        }

        if (is_valid == SC_FALSE)
        {
            *segments_num = 0;
            for (i = 0; i < SC_SEGMENT_MAX; ++i)
            {
                if (segments[i])
                {
                    sc_segment_free(segments[i]);
                    segments[i] = null_ptr;
                }
            }
        }

        g_checksum_free(checksum);
        g_io_channel_shutdown(in_file, FALSE, null_ptr);

        if (is_valid == SC_FALSE)
            return SC_FALSE;
    }

    g_message("Segments loaded: %u", *segments_num);

    g_assert(fm_engine != null_ptr);
    g_message("Check file memory state");
    sc_bool r = sc_fm_clean_state(fm_engine) == SC_RESULT_OK;

    if (r == SC_FALSE)
        g_error("File memory wasn't check properly");

    return r;
}
Example #18
0
sc_bool sc_fs_storage_write_to_path(sc_segment **segments)
{
    sc_uint32 idx = 0, header_size = 0;
    const sc_segment *segment = 0;
    sc_fs_storage_segments_header header;
    GChecksum * checksum = null_ptr;
    GIOChannel * output = null_ptr;
    gchar * tmp_filename = null_ptr;
    gsize bytes;
    sc_bool result = SC_TRUE;

    if (!g_file_test(repo_path, G_FILE_TEST_IS_DIR))
    {
        g_error("%s isn't a directory.", repo_path);
        return SC_FALSE;
    }

    // create temporary file

    output = _open_tmp_file(&tmp_filename);

    memset(&header, 0, sizeof(sc_fs_storage_segments_header));
    header.segments_num = 0;
    header.timestamp = g_get_real_time();
    header.version = sc_version_to_int(&SC_VERSION);

    g_io_channel_set_encoding(output, null_ptr, null_ptr);

    checksum = g_checksum_new(_checksum_type());
    g_checksum_reset(checksum);

    for (idx = 0; idx < SC_ADDR_SEG_MAX; idx++)
    {
        segment = segments[idx];
        if (segment == null_ptr)
            break; // stop save, because we allocate segment in order

        g_checksum_update(checksum, (guchar*)segment->elements, SC_SEG_ELEMENTS_SIZE_BYTE);
    }

    header.segments_num = idx;
    bytes = SC_STORAGE_SEG_CHECKSUM_SIZE;
    g_checksum_get_digest(checksum, header.checksum, &bytes);

    header_size = sizeof(header);
    if (g_io_channel_write_chars(output, (gchar*)&header_size, sizeof(header_size), &bytes, null_ptr) != G_IO_STATUS_NORMAL || bytes != sizeof(header_size))
    {
        g_error("Can't write header size: %s", tmp_filename);
        result = SC_FALSE;
        goto clean;
    }

    if (g_io_channel_write_chars(output, (gchar*)&header, header_size, &bytes, null_ptr) != G_IO_STATUS_NORMAL || bytes != header_size)
    {
        g_error("Can't write header: %s", tmp_filename);
        result = SC_FALSE;
        goto clean;
    }

    for (idx = 0; idx < header.segments_num; ++idx)
    {
        segment = segments[idx];
        g_assert(segment != null_ptr);

        if (g_io_channel_write_chars(output, (gchar*)segment->elements, SC_SEG_ELEMENTS_SIZE_BYTE, &bytes, null_ptr) != G_IO_STATUS_NORMAL || bytes != SC_SEG_ELEMENTS_SIZE_BYTE)
        {
            g_error("Can't write segment %d into %s", idx, tmp_filename);
            result = SC_FALSE;
            goto clean;
        }
    }

    if (result == SC_TRUE)
    {
        // rename main file
        if (g_file_test(tmp_filename, G_FILE_TEST_IS_REGULAR))
        {
            g_io_channel_shutdown(output, TRUE, NULL);
            output = null_ptr;

            if (g_rename(tmp_filename, segments_path) != 0)
            {
                g_error("Can't rename %s -> %s", tmp_filename, segments_path);
                result = SC_FALSE;
            }
        }

        // save file memory
        g_message("Save file memory state");
        if (sc_fm_save(fm_engine) != SC_RESULT_OK)
            g_critical("Error while saves file memory");
    }

    clean:
    {
        if (tmp_filename)
            g_free(tmp_filename);
        if (checksum)
            g_checksum_free(checksum);
        if (output)
            g_io_channel_shutdown(output, TRUE, null_ptr);
    }

    return result;
}