/** * We've received a notification about a change to our zone. * Forward to monitor callback. * * @param cls the zone monitor handle * @param lrm the message from the service. */ static void handle_result (void *cls, const struct RecordResultMessage *lrm) { struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls; size_t name_len; size_t rd_len; unsigned rd_count; const char *name_tmp; const char *rd_ser_tmp; rd_len = ntohs (lrm->rd_len); rd_count = ntohs (lrm->rd_count); name_len = ntohs (lrm->name_len); name_tmp = (const char *) &lrm[1]; rd_ser_tmp = (const char *) &name_tmp[name_len]; { struct GNUNET_GNSRECORD_Data rd[rd_count]; GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_records_deserialize (rd_len, rd_ser_tmp, rd_count, rd)); zm->monitor (zm->monitor_cls, &lrm->private_key, name_tmp, rd_count, rd); } }
/** * We've received a notification about a change to our zone. * Check that it is well-formed. * * @param cls the zone monitor handle * @param lrm the message from the service. */ static int check_result (void *cls, const struct RecordResultMessage *lrm) { size_t lrm_len; size_t exp_lrm_len; size_t name_len; size_t rd_len; unsigned rd_count; const char *name_tmp; const char *rd_ser_tmp; lrm_len = ntohs (lrm->gns_header.header.size); rd_len = ntohs (lrm->rd_len); rd_count = ntohs (lrm->rd_count); name_len = ntohs (lrm->name_len); exp_lrm_len = sizeof (struct RecordResultMessage) + name_len + rd_len; if (lrm_len != exp_lrm_len) { GNUNET_break (0); return GNUNET_SYSERR; } if (0 == name_len) { GNUNET_break (0); return GNUNET_SYSERR; } name_tmp = (const char *) &lrm[1]; if ((name_tmp[name_len -1] != '\0') || (name_len > MAX_NAME_LEN)) { GNUNET_break (0); return GNUNET_SYSERR; } rd_ser_tmp = (const char *) &name_tmp[name_len]; { struct GNUNET_GNSRECORD_Data rd[rd_count]; if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (rd_len, rd_ser_tmp, rd_count, rd)) { GNUNET_break (0); return GNUNET_SYSERR; } } return GNUNET_OK; }
/** * Check validity of message received from the GNS service * * @param cls the `struct GNUNET_GNS_Handle *` * @param loookup_msg the incoming message */ static int check_result (void *cls, const struct LookupResultMessage *lookup_msg) { size_t mlen = ntohs (lookup_msg->header.size) - sizeof (*lookup_msg); uint32_t rd_count = ntohl (lookup_msg->rd_count); struct GNUNET_GNSRECORD_Data rd[rd_count]; if (GNUNET_SYSERR == GNUNET_GNSRECORD_records_deserialize (mlen, (const char*) &lookup_msg[1], rd_count, rd)) { GNUNET_break (0); return GNUNET_SYSERR; } return GNUNET_OK; }
/** * Handler for messages received from the GNS service * * @param cls the `struct GNUNET_GNS_Handle *` * @param loookup_msg the incoming message */ static void handle_result (void *cls, const struct LookupResultMessage *lookup_msg) { struct GNUNET_GNS_Handle *handle = cls; size_t mlen = ntohs (lookup_msg->header.size) - sizeof (*lookup_msg); uint32_t rd_count = ntohl (lookup_msg->rd_count); struct GNUNET_GNSRECORD_Data rd[rd_count]; uint32_t r_id = ntohl (lookup_msg->id); struct GNUNET_GNS_LookupRequest *lr; GNUNET_GNS_LookupResultProcessor proc; void *proc_cls; LOG (GNUNET_ERROR_TYPE_DEBUG, "Received lookup reply from GNS service (%u records)\n", (unsigned int) rd_count); for (lr = handle->lookup_head; NULL != lr; lr = lr->next) if (lr->r_id == r_id) break; if (NULL == lr) return; proc = lr->lookup_proc; proc_cls = lr->proc_cls; GNUNET_CONTAINER_DLL_remove (handle->lookup_head, handle->lookup_tail, lr); GNUNET_free (lr); GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_records_deserialize (mlen, (const char*) &lookup_msg[1], rd_count, rd)); proc (proc_cls, rd_count, rd); }
/** * Decrypt block. * * @param block block to decrypt * @param zone_key public key of the zone * @param label the name for the records * @param proc function to call with the result * @param proc_cls closure for proc * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was * not well-formed */ int GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, const char *label, GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls) { size_t payload_len = ntohl (block->purpose.size) - sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) - sizeof (struct GNUNET_TIME_AbsoluteNBO); struct GNUNET_CRYPTO_SymmetricInitializationVector iv; struct GNUNET_CRYPTO_SymmetricSessionKey skey; if (ntohl (block->purpose.size) < sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO)) { GNUNET_break_op (0); return GNUNET_SYSERR; } derive_block_aes_key (&iv, &skey, label, zone_key); { char payload[payload_len]; uint32_t rd_count; GNUNET_break (payload_len == GNUNET_CRYPTO_symmetric_decrypt (&block[1], payload_len, &skey, &iv, payload)); memcpy (&rd_count, payload, sizeof (uint32_t)); rd_count = ntohl (rd_count); if (rd_count > 2048) { /* limit to sane value */ GNUNET_break_op (0); return GNUNET_SYSERR; } { struct GNUNET_GNSRECORD_Data rd[rd_count]; unsigned int i; unsigned int j; unsigned int k; struct GNUNET_TIME_Absolute now; if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof (uint32_t), &payload[sizeof (uint32_t)], rd_count, rd)) { GNUNET_break_op (0); return GNUNET_SYSERR; } /* hide expired records */ now = GNUNET_TIME_absolute_get (); j = 0; for (i=0;i<rd_count;i++) { if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) { /* encrypted blocks must never have relative expiration times, skip! */ GNUNET_break_op (0); continue; } if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)) { int include_record = GNUNET_YES; /* Shadow record, figure out if we have a not expired active record */ for (k=0;k<rd_count;k++) { if (k == i) continue; if (rd[i].expiration_time < now.abs_value_us) include_record = GNUNET_NO; /* Shadow record is expired */ if ((rd[k].record_type == rd[i].record_type) && (rd[k].expiration_time >= now.abs_value_us) && (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))) include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */ } if (GNUNET_YES == include_record) { rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW_RECORD; /* Remove Flag */ if (j != i) rd[j] = rd[i]; j++; } } else if (rd[i].expiration_time >= now.abs_value_us) { /* Include this record */ if (j != i) rd[j] = rd[i]; j++; } } rd_count = j; if (NULL != proc) proc (proc_cls, rd_count, (0 != rd_count) ? rd : NULL); } } return GNUNET_OK; }
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { size_t len; int c; int rd_count = 3; size_t data_len; struct GNUNET_GNSRECORD_Data src[rd_count]; memset(src, '\0', rd_count * sizeof (struct GNUNET_GNSRECORD_Data)); data_len = 0; for (c = 0; c < rd_count; c++) { src[c].record_type = c+1; src[c].data_size = data_len; src[c].data = GNUNET_malloc (data_len); /* Setting data to data_len * record_type */ memset ((char *) src[c].data, 'a', data_len); data_len += 10; } res = 0; len = GNUNET_GNSRECORD_records_get_size(rd_count, src); char rd_ser[len]; GNUNET_assert (len == GNUNET_GNSRECORD_records_serialize(rd_count, src, len, rd_ser)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serialized data len: %u\n",len); GNUNET_assert (rd_ser != NULL); struct GNUNET_GNSRECORD_Data dst[rd_count]; GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_records_deserialize (len, rd_ser, rd_count, dst)); GNUNET_assert (dst != NULL); for (c = 0; c < rd_count; c++) { if (src[c].data_size != dst[c].data_size) { GNUNET_break (0); res = 1; } if (src[c].expiration_time != dst[c].expiration_time) { GNUNET_break (0); res = 1; } if (src[c].flags != dst[c].flags) { GNUNET_break (0); res = 1; } if (src[c].record_type != dst[c].record_type) { GNUNET_break (0); res = 1; } size_t data_size = src[c].data_size; char data[data_size]; memset (data, 'a', data_size); if (0 != memcmp (data, dst[c].data, data_size)) { GNUNET_break (0); res = 1; } if (0 != memcmp (data, src[c].data, data_size)) { GNUNET_break (0); res = 1; } if (0 != memcmp (src[c].data, dst[c].data, src[c].data_size)) { GNUNET_break (0); res = 1; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Element [%i]: EQUAL\n", c); } for (c = 0; c < rd_count; c++) { GNUNET_free ((void *)src[c].data); } }