static void run_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct CpsRunContext *crc = cls; ok = (int) crc->phase; switch (crc->phase) { case RP_PUT: #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "PUT", crc->i); #endif GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key); GNUNET_DATASTORE_put (datastore, 0, &crc->key, get_size (crc->i), get_data (crc->i), get_type (crc->i), get_priority (crc->i), get_anonymity (crc->i), 0, get_expiration (crc->i), 1, 1, TIMEOUT, &check_success, crc); crc->i++; if (crc->i == ITERATIONS) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Sleeping to give datastore time to clean up\n"); sleep (1); crc->phase = RP_GET; crc->i--; } break; case RP_GET: #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET", crc->i); #endif GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key); GNUNET_DATASTORE_get_key (datastore, crc->offset++, &crc->key, get_type (crc->i), 1, 1, TIMEOUT, &check_value, crc); break; case RP_GET_FAIL: #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET(f)", crc->i); #endif GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key); GNUNET_DATASTORE_get_key (datastore, crc->offset++, &crc->key, get_type (crc->i), 1, 1, TIMEOUT, &check_nothing, crc); break; case RP_DONE: GNUNET_assert (0 == crc->i); #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished, disconnecting\n"); #endif GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); ok = 0; } }
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *peer) { char *hostkey_file; struct GNUNET_TIME_Absolute et; endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,&endbadly, NULL); GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); GNUNET_free (hostkey_file); GNUNET_assert (privkey != NULL); GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); GNUNET_CRYPTO_hash(&pubkey, sizeof (pubkey), &zone); GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); privkey2 = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); GNUNET_free (hostkey_file); GNUNET_assert (privkey2 != NULL); GNUNET_CRYPTO_rsa_key_get_public(privkey2, &pubkey2); GNUNET_CRYPTO_hash(&pubkey2, sizeof (pubkey), &zone2); nsh = GNUNET_NAMESTORE_connect (cfg); GNUNET_break (NULL != nsh); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n"); GNUNET_asprintf(&s_name_1, "dummy1"); s_rd_1 = create_record(1); et.abs_value = s_rd_1[0].expiration_time; sig_1 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_1, s_rd_1, 1); GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_1, s_rd_1, &put_cont, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n"); GNUNET_asprintf(&s_name_2, "dummy2"); s_rd_2 = create_record(1); et.abs_value = s_rd_2[0].expiration_time; sig_2 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_2, s_rd_2, 1); GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_2, s_rd_2, &put_cont, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n"); /* name in different zone */ GNUNET_asprintf(&s_name_3, "dummy3"); s_rd_3 = create_record(1); et.abs_value = s_rd_3[0].expiration_time; sig_3 = GNUNET_NAMESTORE_create_signature(privkey2, et, s_name_3, s_rd_3, 1); GNUNET_NAMESTORE_record_put (nsh, &pubkey2, s_name_3, GNUNET_TIME_UNIT_FOREVER_ABS, 1, s_rd_3, sig_3, &put_cont, NULL); }
/** * Transmit a confirmation receipt to the chat service. * * @param cls closure, pointer to the 'struct GNUNET_CHAT_SendReceiptContext' * @param size number of bytes available in buf * @param buf where the callee should write the message * @return number of bytes written to buf */ static size_t transmit_acknowledge_request (void *cls, size_t size, void *buf) { struct GNUNET_CHAT_SendReceiptContext *src = cls; struct ConfirmationReceiptMessage *receipt; struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub_key; uint16_t msg_len; size_t msg_size; if (NULL == buf) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not transmit confirmation receipt\n")); return 0; } #if DEBUG_CHAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting confirmation receipt to the service\n"); #endif msg_size = sizeof (struct ConfirmationReceiptMessage); GNUNET_assert (size >= msg_size); receipt = buf; receipt->header.size = htons (msg_size); receipt->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_RECEIPT); receipt->reserved = htonl (0); receipt->sequence_number = src->received_msg->sequence_number; receipt->reserved2 = htonl (0); receipt->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); GNUNET_CRYPTO_rsa_key_get_public (src->chat_room->my_private_key, &pub_key); GNUNET_CRYPTO_hash (&pub_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &receipt->target); receipt->author = src->received_msg->sender; receipt->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_RECEIPT); receipt->purpose.size = htonl (msg_size - sizeof (struct GNUNET_MessageHeader) - sizeof (uint32_t) - sizeof (struct GNUNET_CRYPTO_RsaSignature)); msg_len = ntohs (src->received_msg->header.size) - sizeof (struct ReceiveNotificationMessage); GNUNET_CRYPTO_hash (&src->received_msg[1], msg_len, &receipt->content); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_rsa_sign (src->chat_room->my_private_key, &receipt->purpose, &receipt->signature)); GNUNET_free (src->received_msg); GNUNET_free (src); return msg_size; }
/** * Function called on each meta data item. Increments the * respective counter. * * @param cls the container multihashmap to update * @param plugin_name name of the plugin that produced this value; * special values can be used (i.e. '<zlib>' for zlib being * used in the main libextractor library and yielding * meta data). * @param type libextractor-type describing the meta data * @param format basic format information about data * @param data_mime_type mime-type of data (not of the original file); * can be NULL (if mime-type is not known) * @param data actual meta-data found * @param data_len number of bytes in data * @return GNUNET_OK to continue extracting / iterating */ static int add_to_meta_counter (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_len) { struct GNUNET_CONTAINER_MultiHashMap *map = cls; GNUNET_HashCode key; struct MetaCounter *cnt; GNUNET_CRYPTO_hash (data, data_len, &key); cnt = GNUNET_CONTAINER_multihashmap_get (map, &key); if (cnt == NULL) { cnt = GNUNET_malloc (sizeof (struct MetaCounter)); cnt->data = data; cnt->data_size = data_len; cnt->plugin_name = plugin_name; cnt->type = type; cnt->format = format; cnt->data_mime_type = data_mime_type; GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (map, &key, cnt, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); } cnt->count++; return 0; }
/** * @brief Get the channel of a peer. If not existing, create. * * @param peer the peer id * @return the #GNUNET_CADET_Channel used to send data to @a peer */ struct GNUNET_CADET_Channel * get_channel (const struct GNUNET_PeerIdentity *peer) { struct PeerContext *peer_ctx; struct GNUNET_HashCode port; peer_ctx = get_peer_ctx (peer); if (NULL == peer_ctx->send_channel) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to establish channel to peer %s\n", GNUNET_i2s (peer)); GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS, strlen (GNUNET_APPLICATION_PORT_RPS), &port); peer_ctx->send_channel = GNUNET_CADET_channel_create (cadet_handle, peer_ctx->send_channel_flags, /* context */ peer, &port, GNUNET_CADET_OPTION_RELIABLE); } GNUNET_assert (NULL != peer_ctx->send_channel); return peer_ctx->send_channel; }
/** * Get the number of matching bits that the given timestamp has to the given peer ID. * * @param timestamp time to generate key * @param id peer identity to compare with * @return number of matching bits */ static uint32_t get_matching_bits (struct GNUNET_TIME_Absolute timestamp, const struct GNUNET_PeerIdentity *id) { struct GNUNET_HashCode timestamp_hash; struct GNUNET_HashCode pid_hash; GNUNET_CRYPTO_hash (×tamp.abs_value_us, sizeof (timestamp.abs_value_us), ×tamp_hash); GNUNET_CRYPTO_hash (id, sizeof (struct GNUNET_PeerIdentity), &pid_hash); return GNUNET_CRYPTO_hash_matching_bits (×tamp_hash, &pid_hash); }
/** * Find a peer that would be reasonable for advertising. * * @param cls closure * @param pid identity of a peer * @param value 'struct Peer*' for the peer we are considering * @return #GNUNET_YES (continue iteration) */ static int find_advertisable_hello (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) { struct FindAdvHelloContext *fah = cls; struct Peer *pos = value; struct GNUNET_TIME_Relative rst_time; struct GNUNET_HashCode hc; size_t hs; if (pos == fah->peer) return GNUNET_YES; if (pos->hello == NULL) return GNUNET_YES; rst_time = GNUNET_TIME_absolute_get_remaining (pos->filter_expiration); if (0 == rst_time.rel_value_us) { /* time to discard... */ GNUNET_CONTAINER_bloomfilter_free (pos->filter); setup_filter (pos); } fah->next_adv = GNUNET_TIME_relative_min (rst_time, fah->next_adv); hs = GNUNET_HELLO_size (pos->hello); if (hs > fah->max_size) return GNUNET_YES; GNUNET_CRYPTO_hash (&fah->peer->pid, sizeof (struct GNUNET_PeerIdentity), &hc); if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (pos->filter, &hc)) fah->result = pos; return GNUNET_YES; }
/** * Creates a hash of the given key combination * */ void PEERSTORE_hash_key (const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, struct GNUNET_HashCode *ret) { size_t sssize; size_t psize; size_t ksize; size_t totalsize; void *block; void *blockptr; sssize = strlen (sub_system) + 1; psize = sizeof (struct GNUNET_PeerIdentity); ksize = strlen (key) + 1; totalsize = sssize + psize + ksize; block = GNUNET_malloc (totalsize); blockptr = block; memcpy (blockptr, sub_system, sssize); blockptr += sssize; memcpy (blockptr, peer, psize); blockptr += psize; memcpy (blockptr, key, ksize); GNUNET_CRYPTO_hash (block, totalsize, ret); GNUNET_free (block); }
/** * Function called to validate a reply or a request. For * request evaluation, simply pass "NULL" for the reply_block. * * @param cls closure * @param type block type * @param query original query (hash) * @param bf pointer to bloom filter associated with query; possibly updated (!) * @param bf_mutator mutation value for bf * @param xquery extrended query data (can be NULL, depending on type) * @param xquery_size number of bytes in xquery * @param reply_block response to validate * @param reply_block_size number of bytes in reply block * @return characterization of result */ static enum GNUNET_BLOCK_EvaluationResult block_plugin_template_evaluate (void *cls, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode * query, struct GNUNET_CONTAINER_BloomFilter **bf, int32_t bf_mutator, const void *xquery, size_t xquery_size, const void *reply_block, size_t reply_block_size) { struct GNUNET_HashCode chash; struct GNUNET_HashCode mhash; /* FIXME: check validity first... */ /* mandatory duplicate-detection code... */ if (NULL != bf) { GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash); if (NULL != *bf) { if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf, &mhash)) return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; } else { *bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 8, 64 /* BLOOMFILTER_K */); } GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash); } /* FIXME: other stuff here... */ return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; }
/** * We've paired up a client session with an incoming CADET request. * Initiate set intersection work. * * @param s client session to start intersection for */ static void start_intersection (struct BobServiceSession *s) { struct GNUNET_HashCode set_sid; GNUNET_CRYPTO_hash (&s->session_id, sizeof (struct GNUNET_HashCode), &set_sid); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got session with key %s and %u elements, starting intersection.\n", GNUNET_h2s (&s->session_id), (unsigned int) s->total); s->intersection_op = GNUNET_SET_prepare (&s->cadet->peer, &set_sid, NULL, GNUNET_SET_RESULT_REMOVED, &cb_intersection_element_removed, s); if (GNUNET_OK != GNUNET_SET_commit (s->intersection_op, s->intersection_set)) { GNUNET_break (0); s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE; prepare_client_end_notification (s); return; } GNUNET_SET_destroy (s->intersection_set); s->intersection_set = NULL; }
/** * Continuation of "GNUNET_FS_publish_ksk" that performs the actual * publishing operation (iterating over all of the keywords). * * @param cls closure of type "struct GNUNET_FS_PublishKskContext*" * @param tc unused */ static void publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_FS_PublishKskContext *pkc = cls; const char *keyword; GNUNET_HashCode key; GNUNET_HashCode query; struct GNUNET_CRYPTO_AesSessionKey skey; struct GNUNET_CRYPTO_AesInitializationVector iv; struct GNUNET_CRYPTO_RsaPrivateKey *pk; pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK; if ((pkc->i == pkc->ksk_uri->data.ksk.keywordCount) || (NULL == pkc->dsh)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "KSK PUT operation complete\n"); pkc->cont (pkc->cont_cls, pkc->ksk_uri, NULL); GNUNET_FS_publish_ksk_cancel (pkc); return; } keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under keyword `%s'\n", &keyword[1]); /* first character of keyword indicates if it is * mandatory or not -- ignore for hashing */ GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key); GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv); GNUNET_CRYPTO_aes_encrypt (&pkc->kb[1], pkc->slen + pkc->mdsize, &skey, &iv, &pkc->cpy[1]); pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&key); GNUNET_assert (NULL != pk); GNUNET_CRYPTO_rsa_key_get_public (pk, &pkc->cpy->keyspace); GNUNET_CRYPTO_hash (&pkc->cpy->keyspace, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &query); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_rsa_sign (pk, &pkc->cpy->purpose, &pkc->cpy->signature)); GNUNET_CRYPTO_rsa_key_free (pk); pkc->qre = GNUNET_DATASTORE_put (pkc->dsh, 0, &query, pkc->mdsize + sizeof (struct KBlock) + pkc->slen, pkc->cpy, GNUNET_BLOCK_TYPE_FS_KBLOCK, pkc->bo.content_priority, pkc->bo.anonymity_level, pkc->bo.replication_level, pkc->bo.expiration_time, -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT, &kb_put_cont, pkc); }
/** * Calculate when we would like to send the next HELLO to this * peer and ask for it. * * @param cls for which peer to schedule the HELLO */ static void schedule_next_hello (void *cls) { struct Peer *pl = cls; struct FindAdvHelloContext fah; struct GNUNET_MQ_Envelope *env; size_t want; struct GNUNET_TIME_Relative delay; struct GNUNET_HashCode hc; pl->hello_delay_task = NULL; GNUNET_assert (NULL != pl->mq); /* find applicable HELLOs */ fah.peer = pl; fah.result = NULL; fah.max_size = GNUNET_SERVER_MAX_MESSAGE_SIZE - 1; fah.next_adv = GNUNET_TIME_UNIT_FOREVER_REL; GNUNET_CONTAINER_multipeermap_iterate (peers, &find_advertisable_hello, &fah); pl->hello_delay_task = GNUNET_SCHEDULER_add_delayed (fah.next_adv, &schedule_next_hello, pl); if (NULL == fah.result) return; delay = GNUNET_TIME_absolute_get_remaining (pl->next_hello_allowed); if (0 != delay.rel_value_us) return; want = GNUNET_HELLO_size (fah.result->hello); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HELLO with %u bytes", (unsigned int) want); env = GNUNET_MQ_msg_copy (&fah.result->hello->header); GNUNET_MQ_send (pl->mq, env); /* avoid sending this one again soon */ GNUNET_CRYPTO_hash (&pl->pid, sizeof (struct GNUNET_PeerIdentity), &hc); GNUNET_CONTAINER_bloomfilter_add (fah.result->filter, &hc); GNUNET_STATISTICS_update (stats, gettext_noop ("# HELLO messages gossipped"), 1, GNUNET_NO); /* prepare to send the next one */ if (NULL != pl->hello_delay_task) GNUNET_SCHEDULER_cancel (pl->hello_delay_task); pl->next_hello_allowed = GNUNET_TIME_relative_to_absolute (HELLO_ADVERTISEMENT_MIN_FREQUENCY); pl->hello_delay_task = GNUNET_SCHEDULER_add_now (&schedule_next_hello, pl); }
/** * Calculate the DHT query for a given @a label in a given @a zone. * * @param pub public key of the zone * @param label label of the record * @param query hash to use for the query */ void GNUNET_GNSRECORD_query_from_public_key (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label, struct GNUNET_HashCode *query) { struct GNUNET_CRYPTO_EcdsaPublicKey pd; GNUNET_CRYPTO_ecdsa_public_key_derive (pub, label, "gns", &pd); GNUNET_CRYPTO_hash (&pd, sizeof (pd), query); }
/** * Main function that will be run by the scheduler. * * @param cls closure * @param args remaining command-line arguments * @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param c configuration */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { struct GNUNET_CRYPTO_RsaPrivateKey *priv; char *fn; cfg = c; if ( (NULL != args[0]) && (NULL == put_uri) && (args[0] == strcasestr (args[0], "gnunet://hello/")) ) { put_uri = GNUNET_strdup (args[0]); args++; } if (NULL != args[0]) { FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]); return; } if (NULL == (peerinfo = GNUNET_PEERINFO_connect (cfg))) { FPRINTF (stderr, "%s", _("Could not access PEERINFO service. Exiting.\n")); return; } if ( (GNUNET_YES == get_self) || (GNUNET_YES == get_uri) ) { /* load private key */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY", &fn)) { FPRINTF (stderr, _("Could not find option `%s:%s' in configuration.\n"), "GNUNETD", "HOSTKEYFILE"); return; } if (NULL == (priv = GNUNET_CRYPTO_rsa_key_create_from_file (fn))) { FPRINTF (stderr, _("Loading hostkey from `%s' failed.\n"), fn); GNUNET_free (fn); return; } GNUNET_free (fn); GNUNET_CRYPTO_rsa_key_get_public (priv, &my_public_key); GNUNET_CRYPTO_rsa_key_free (priv); GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key), &my_peer_identity.hashPubKey); } tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); }
/** * Transmit a send-message request to the chat service. * * @param cls closure, pointer to the 'struct GNUNET_CHAT_SendMessageContext' * @param size number of bytes available in buf * @param buf where the callee should write the message * @return number of bytes written to buf */ static size_t transmit_send_request (void *cls, size_t size, void *buf) { struct GNUNET_CHAT_SendMessageContext *smc = cls; struct TransmitRequestMessage *msg_to_send; size_t msg_size; if (NULL == buf) { #if DEBUG_CHAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Could not transmit a chat message\n"); #endif return 0; } #if DEBUG_CHAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting a chat message to the service\n"); #endif msg_size = strlen (smc->message) + sizeof (struct TransmitRequestMessage); GNUNET_assert (size >= msg_size); msg_to_send = buf; msg_to_send->header.size = htons (msg_size); msg_to_send->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_TRANSMIT_REQUEST); msg_to_send->msg_options = htonl (smc->options); msg_to_send->sequence_number = htonl (smc->sequence_number); msg_to_send->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); msg_to_send->reserved = htonl (0); if (NULL == smc->receiver) memset (&msg_to_send->target, 0, sizeof (GNUNET_HashCode)); else GNUNET_CRYPTO_hash (smc->receiver, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &msg_to_send->target); memcpy (&msg_to_send[1], smc->message, strlen (smc->message)); /** * Client don't encode private messages since public keys of other members are * stored on the service side. */ if (smc->options & GNUNET_CHAT_MSG_AUTHENTICATED) { msg_to_send->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); msg_to_send->purpose.size = htonl (msg_size - sizeof (struct GNUNET_MessageHeader) - sizeof (struct GNUNET_CRYPTO_RsaSignature)); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_rsa_sign (smc->chat_room->my_private_key, &msg_to_send->purpose, &msg_to_send->signature)); } GNUNET_free (smc->message); GNUNET_free (smc); return msg_size; }
/** * Get the namespace ID belonging to the given namespace name. * * @param cfg configuration to use * @param ns_uname unique (!) human-readable name for the namespace * @param nsid set to namespace ID based on 'ns_uname' * @return GNUNET_OK on success, GNUNET_SYSERR on failure */ int GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *ns_uname, struct GNUNET_HashCode * nsid) { size_t slen; uint64_t len; unsigned int idx; char *name; struct GNUNET_HashCode nh; char *fn; struct GNUNET_DISK_FileHandle *fh; idx = -1; slen = strlen (ns_uname); while ((slen > 0) && (1 != SSCANF (&ns_uname[slen - 1], "-%u", &idx))) slen--; if (slen == 0) return GNUNET_SYSERR; name = GNUNET_strdup (ns_uname); name[slen - 1] = '\0'; GNUNET_CRYPTO_hash (name, strlen (name), &nh); GNUNET_free (name); fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); GNUNET_assert (fn != NULL); if ((GNUNET_OK != GNUNET_DISK_file_test (fn) || (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) || ((idx + 1) * sizeof (struct GNUNET_HashCode) > len)) { GNUNET_free (fn); return GNUNET_SYSERR; } fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); GNUNET_free (fn); if (GNUNET_SYSERR == GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_HashCode), GNUNET_DISK_SEEK_SET)) { GNUNET_DISK_file_close (fh); return GNUNET_SYSERR; } if (sizeof (struct GNUNET_HashCode) != GNUNET_DISK_file_read (fh, nsid, sizeof (struct GNUNET_HashCode))) { GNUNET_DISK_file_close (fh); return GNUNET_SYSERR; } GNUNET_DISK_file_close (fh); return GNUNET_OK; }
/** * Return unique variant of the namespace name. * Use it after GNUNET_PSEUDONYM_get_info() to make sure * that name is unique. * * @param cfg configuration * @param nsid cryptographic ID of the namespace * @param name name to uniquify * @param suffix if not NULL, filled with the suffix value * @return NULL on failure (should never happen), name on success. * Free the name with GNUNET_free(). */ char * GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode * nsid, const char *name, unsigned int *suffix) { struct GNUNET_HashCode nh; uint64_t len; char *fn; struct GNUNET_DISK_FileHandle *fh; unsigned int i; unsigned int idx; char *ret; struct stat sbuf; GNUNET_CRYPTO_hash (name, strlen (name), &nh); fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); GNUNET_assert (fn != NULL); len = 0; if (0 == STAT (fn, &sbuf)) GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES)); fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); i = 0; idx = -1; while ((len >= sizeof (struct GNUNET_HashCode)) && (sizeof (struct GNUNET_HashCode) == GNUNET_DISK_file_read (fh, &nh, sizeof (struct GNUNET_HashCode)))) { if (0 == memcmp (&nh, nsid, sizeof (struct GNUNET_HashCode))) { idx = i; break; } i++; len -= sizeof (struct GNUNET_HashCode); } if (idx == -1) { idx = i; if (sizeof (struct GNUNET_HashCode) != GNUNET_DISK_file_write (fh, nsid, sizeof (struct GNUNET_HashCode))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn); } GNUNET_DISK_file_close (fh); ret = GNUNET_malloc (strlen (name) + 32); GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx); if (suffix != NULL) *suffix = idx; GNUNET_free (fn); return ret; }
/** * Main function that will be run by the scheduler. * * @param cls closure * @param args remaining command-line arguments * @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param cfg configuration */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_CRYPTO_RsaPrivateKey *pk; struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub; struct GNUNET_PeerIdentity pid; if (NULL == args[0]) { fprintf (stderr, _("No hostkey file specified on command line\n")); return; } if (0 != weak_random) GNUNET_CRYPTO_random_disable_entropy_gathering (); if (make_keys > 0) { create_keys (args[0]); return; } pk = GNUNET_CRYPTO_rsa_key_create_from_file (args[0]); if (NULL == pk) return; if (print_public_key) { char *s; GNUNET_CRYPTO_rsa_key_get_public (pk, &pub); s = GNUNET_CRYPTO_rsa_public_key_to_string (&pub); fprintf (stdout, "%s\n", s); GNUNET_free (s); } if (print_peer_identity) { struct GNUNET_CRYPTO_HashAsciiEncoded enc; GNUNET_CRYPTO_rsa_key_get_public (pk, &pub); GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey); GNUNET_CRYPTO_hash_to_enc (&pid.hashPubKey, &enc); fprintf (stdout, "%s\n", enc.encoding); } if (print_short_identity) { struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc; struct GNUNET_CRYPTO_ShortHashCode sh; GNUNET_CRYPTO_rsa_key_get_public (pk, &pub); GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &sh); GNUNET_CRYPTO_short_hash_to_enc (&sh, &enc); fprintf (stdout, "%s\n", enc.short_encoding); } GNUNET_CRYPTO_rsa_key_free (pk); }
static void finished_task (void *cls, const struct GNUNET_HashCode * res) { int *ret = cls; struct GNUNET_HashCode want; GNUNET_CRYPTO_hash (block, sizeof (block), &want); if (0 != memcmp (res, &want, sizeof (want))) *ret = 2; else *ret = 0; }
/** * Store an item in the datastore. * * @param cls closure with the `struct Plugin` * @param key key for the item * @param size number of bytes in data * @param data content stored * @param type type of the content * @param priority priority of the content * @param anonymity anonymity-level for the content * @param replication replication-level for the content * @param expiration expiration time for the content * @param cont continuation called with success or failure status * @param cont_cls continuation closure */ static void postgres_plugin_put (void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, PluginPutCont cont, void *cont_cls) { struct Plugin *plugin = cls; uint32_t utype = type; struct GNUNET_HashCode vhash; PGresult *ret; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_uint32 (&replication), GNUNET_PQ_query_param_uint32 (&utype), GNUNET_PQ_query_param_uint32 (&priority), GNUNET_PQ_query_param_uint32 (&anonymity), GNUNET_PQ_query_param_absolute_time (&expiration), GNUNET_PQ_query_param_auto_from_type (key), GNUNET_PQ_query_param_auto_from_type (&vhash), GNUNET_PQ_query_param_fixed_size (data, size), GNUNET_PQ_query_param_end }; GNUNET_CRYPTO_hash (data, size, &vhash); ret = GNUNET_PQ_exec_prepared (plugin->dbh, "put", params); if (GNUNET_OK != GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "put")) { cont (cont_cls, key, size, GNUNET_SYSERR, _("Postgress exec failure")); return; } PQclear (ret); plugin->env->duc (plugin->env->cls, size + GNUNET_DATASTORE_ENTRY_OVERHEAD); GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Stored %u bytes in database\n", (unsigned int) size); cont (cont_cls, key, size, GNUNET_OK, NULL); }
/** * Obtain the ego representing 'anonymous' users. * * @return handle for the anonymous user, must not be freed */ const struct GNUNET_IDENTITY_Ego * GNUNET_IDENTITY_ego_get_anonymous () { static struct GNUNET_IDENTITY_Ego anon; struct GNUNET_CRYPTO_EcdsaPublicKey pub; if (NULL != anon.pk) return &anon; anon.pk = (struct GNUNET_CRYPTO_EcdsaPrivateKey *) GNUNET_CRYPTO_ecdsa_key_get_anonymous (); GNUNET_CRYPTO_ecdsa_key_get_public (anon.pk, &pub); GNUNET_CRYPTO_hash (&pub, sizeof (pub), &anon.id); return &anon; }
/** * Get the peer identity from a HELLO message. * * @param hello the hello message * @param peer where to store the peer's identity * @return GNUNET_SYSERR if the HELLO was malformed */ int GNUNET_HELLO_get_id (const struct GNUNET_HELLO_Message *hello, struct GNUNET_PeerIdentity *peer) { uint16_t ret = ntohs (hello->header.size); if ((ret < sizeof (struct GNUNET_HELLO_Message)) || (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO)) return GNUNET_SYSERR; GNUNET_CRYPTO_hash (&hello->publicKey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &peer->hashPubKey); return GNUNET_OK; }
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { static char *session_str = "gnunet-consensus/test"; char *topology; int topology_cmp_result; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "testbed", "OVERLAY_TOPOLOGY", &topology)) { fprintf (stderr, "'OVERLAY_TOPOLOGY' not found in 'testbed' config section, " "seems like you passed the wrong configuration file\n"); return; } topology_cmp_result = strcasecmp (topology, "NONE"); GNUNET_free (topology); if (0 == topology_cmp_result) { fprintf (stderr, "'OVERLAY_TOPOLOGY' set to 'NONE', " "seems like you passed the wrong configuration file\n"); return; } if (num_peers < replication) { fprintf (stderr, "k must be <=n\n"); return; } start = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), consensus_delay); deadline = GNUNET_TIME_absolute_add (start, conclude_timeout); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "running gnunet-consensus\n"); GNUNET_CRYPTO_hash (session_str, strlen(session_str), &session_id); (void) GNUNET_TESTBED_test_run ("gnunet-consensus", cfgfile, num_peers, 0, controller_cb, NULL, test_master, NULL); }
/** * Compute hash over the public key. * * @param key public key to hash * @param hc where to store the hash code */ void GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_rsa_PublicKey *key, struct GNUNET_HashCode *hc) { char *buf; size_t buf_size; buf_size = GNUNET_CRYPTO_rsa_public_key_encode (key, &buf); GNUNET_CRYPTO_hash (buf, buf_size, hc); GNUNET_free (buf); }
static void mpz_randomize (gcry_mpi_t n, unsigned int nbits, struct GNUNET_HashCode * rnd) { struct GNUNET_HashCode hc; struct GNUNET_HashCode tmp; int bits_per_hc = sizeof (struct GNUNET_HashCode) * 8; int cnt; int i; GNUNET_assert (nbits > 0); cnt = (nbits + bits_per_hc - 1) / bits_per_hc; gcry_mpi_set_ui (n, 0); tmp = *rnd; for (i = 0; i < cnt; i++) { int j; if (i > 0) GNUNET_CRYPTO_hash (&hc, sizeof (struct GNUNET_HashCode), &tmp); for (j = 0; j < sizeof (struct GNUNET_HashCode) / sizeof (uint32_t); j++) { #if HAVE_GCRY_MPI_LSHIFT gcry_mpi_lshift (n, n, sizeof (uint32_t) * 8); #else gcry_mpi_mul_ui (n, n, 1 << (sizeof (uint32_t) * 4)); gcry_mpi_mul_ui (n, n, 1 << (sizeof (uint32_t) * 4)); #endif gcry_mpi_add_ui (n, n, ntohl (((uint32_t *) & tmp)[j])); } hc = tmp; } GNUNET_CRYPTO_hash (&hc, sizeof (struct GNUNET_HashCode), rnd); i = gcry_mpi_get_nbits (n); while (i > nbits) gcry_mpi_clear_bit (n, --i); }
/** * Main function that will be run by the scheduler. * * @param cls closure * @param args remaining command-line arguments * @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param c configuration */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { struct GNUNET_TIME_Relative timeout; struct GNUNET_TIME_Absolute expiration; GNUNET_HashCode key; cfg = c; if ((query_key == NULL) || (data == NULL)) { FPRINTF (stderr, "%s", _("Must provide KEY and DATA for DHT put!\n")); ret = 1; return; } dht_handle = GNUNET_DHT_connect (cfg, 1); if (dht_handle == NULL) { FPRINTF (stderr, _("Could not connect to %s service!\n"), "DHT"); ret = 1; return; } else if (verbose) FPRINTF (stderr, _("Connected to %s service!\n"), "DHT"); if (query_type == GNUNET_BLOCK_TYPE_ANY) /* Type of data not set */ query_type = GNUNET_BLOCK_TYPE_TEST; GNUNET_CRYPTO_hash (query_key, strlen (query_key), &key); timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, timeout_request); expiration = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, expiration_seconds)); if (verbose) FPRINTF (stderr, _("Issuing put request for `%s' with data `%s'!\n"), query_key, data); GNUNET_DHT_put (dht_handle, &key, replication, GNUNET_DHT_RO_NONE, query_type, strlen (data), data, expiration, timeout, &message_sent_cont, NULL); }
/** * Store an item in the datastore. * * @param cls closure * @param key key for the item * @param size number of bytes in data * @param data content stored * @param type type of the content * @param priority priority of the content * @param anonymity anonymity-level for the content * @param replication replication-level for the content * @param expiration expiration time for the content * @param msg set to error message * @return GNUNET_OK on success */ static int mysql_plugin_put (void *cls, const struct GNUNET_HashCode * key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, char **msg) { struct Plugin *plugin = cls; unsigned int irepl = replication; unsigned int ipriority = priority; unsigned int ianonymity = anonymity; unsigned long long lexpiration = expiration.abs_value_us; unsigned long long lrvalue = (unsigned long long) GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); unsigned long hashSize; unsigned long hashSize2; unsigned long lsize; struct GNUNET_HashCode vhash; if (size > MAX_DATUM_SIZE) { GNUNET_break (0); return GNUNET_SYSERR; } hashSize = sizeof (struct GNUNET_HashCode); hashSize2 = sizeof (struct GNUNET_HashCode); lsize = size; GNUNET_CRYPTO_hash (data, size, &vhash); if (GNUNET_OK != GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->insert_entry, NULL, MYSQL_TYPE_LONG, &irepl, GNUNET_YES, MYSQL_TYPE_LONG, &type, GNUNET_YES, MYSQL_TYPE_LONG, &ipriority, GNUNET_YES, MYSQL_TYPE_LONG, &ianonymity, GNUNET_YES, MYSQL_TYPE_LONGLONG, &lexpiration, GNUNET_YES, MYSQL_TYPE_LONGLONG, &lrvalue, GNUNET_YES, MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB, &vhash, hashSize2, &hashSize2, MYSQL_TYPE_BLOB, data, lsize, &lsize, -1)) return GNUNET_SYSERR; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Inserted value `%s' with size %u into gn090 table\n", GNUNET_h2s (key), (unsigned int) size); if (size > 0) plugin->env->duc (plugin->env->cls, size); return GNUNET_OK; }
/** * Test if a value matches the specification from the 'get' context * * @param gc query * @param value the value to check against the query * @return GNUNET_YES if the value matches */ static int match (const struct GetContext *gc, struct Value *value) { struct GNUNET_HashCode vh; if ( (gc->type != GNUNET_BLOCK_TYPE_ANY) && (gc->type != value->type) ) return GNUNET_NO; if (NULL != gc->vhash) { GNUNET_CRYPTO_hash (&value[1], value->size, &vh); if (0 != memcmp (&vh, gc->vhash, sizeof (struct GNUNET_HashCode))) return GNUNET_NO; } return GNUNET_YES; }
/** * Store a record in the peerstore. * Key is the combination of sub system and peer identity. * One key can store multiple values. * * @param cls closure (internal context for the plugin) * @param sub_system name of the GNUnet sub system responsible * @param peer peer identity * @param key record key string * @param value value to be stored * @param size size of value to be stored * @param expiry absolute time after which the record is (possibly) deleted * @param options options related to the store operation * @param cont continuation called when record is stored * @param cont_cls continuation closure * @return #GNUNET_OK on success, else #GNUNET_SYSERR and cont is not called */ static int peerstore_flat_store_record (void *cls, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, const void *value, size_t size, struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, GNUNET_PEERSTORE_Continuation cont, void *cont_cls) { struct Plugin *plugin = cls; struct GNUNET_HashCode hkey; struct GNUNET_PEERSTORE_Record *entry; const char *peer_id; entry = GNUNET_new (struct GNUNET_PEERSTORE_Record); entry->sub_system = GNUNET_strdup (sub_system); entry->key = GNUNET_strdup (key); entry->value = GNUNET_malloc (size); GNUNET_memcpy (entry->value, value, size); entry->value_size = size; entry->peer = GNUNET_new (struct GNUNET_PeerIdentity); GNUNET_memcpy (entry->peer, peer, sizeof (struct GNUNET_PeerIdentity)); entry->expiry = GNUNET_new (struct GNUNET_TIME_Absolute); entry->expiry->abs_value_us = expiry.abs_value_us; peer_id = GNUNET_i2s (peer); GNUNET_CRYPTO_hash (peer_id, strlen (peer_id), &hkey); if (GNUNET_PEERSTORE_STOREOPTION_REPLACE == options) { peerstore_flat_delete_records (cls, sub_system, peer, key); } GNUNET_CONTAINER_multihashmap_put (plugin->hm, &hkey, entry, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); if (NULL != cont) { cont (cont_cls, GNUNET_OK); } return GNUNET_OK; }
/** * If necessary, connect to the datastore and remove the KBlocks. * * @param uc context for the unindex operation. */ void GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc) { const char *keyword; const struct GNUNET_CRYPTO_EcdsaPrivateKey *anon; struct GNUNET_CRYPTO_EcdsaPublicKey anon_pub; struct GNUNET_CRYPTO_EcdsaPublicKey dpub; if (NULL == uc->dsh) uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg); if (NULL == uc->dsh) { uc->state = UNINDEX_STATE_ERROR; uc->emsg = GNUNET_strdup (_("Failed to connect to `datastore' service.")); GNUNET_FS_unindex_sync_ (uc); signal_unindex_error (uc); return; } if ( (NULL == uc->ksk_uri) || (uc->ksk_offset >= uc->ksk_uri->data.ksk.keywordCount) ) { unindex_finish (uc); return; } anon = GNUNET_CRYPTO_ecdsa_key_get_anonymous (); GNUNET_CRYPTO_ecdsa_key_get_public (anon, &anon_pub); keyword = &uc->ksk_uri->data.ksk.keywords[uc->ksk_offset][1]; GNUNET_CRYPTO_ecdsa_public_key_derive (&anon_pub, keyword, "fs-ublock", &dpub); GNUNET_CRYPTO_hash (&dpub, sizeof (dpub), &uc->uquery); uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh, uc->roff++, &uc->uquery, GNUNET_BLOCK_TYPE_FS_UBLOCK, 0 /* priority */, 1 /* queue size */, GNUNET_TIME_UNIT_FOREVER_REL, &process_kblock_for_unindex, uc); }