- {
- GNUNET_SCHEDULER_cancel (pc->h->sched, pc->upload_task);
- pc->upload_task = GNUNET_SCHEDULER_NO_TASK;
- }
- if (pc->serialization != NULL)
- {
- GNUNET_FS_remove_sync_file_ (pc->h, GNUNET_FS_SYNC_PATH_MASTER_PUBLISH, pc->serialization);
- GNUNET_free (pc->serialization);
- pc->serialization = NULL;
- }
- GNUNET_FS_file_information_inspect (pc->fi,
- &fip_signal_stop,
- pc);
- if (GNUNET_YES == pc->in_network_wait)
- {
- pc->in_network_wait = GNUNET_SYSERR;
- return;
- }
- publish_cleanup (pc, NULL);
-}
-
-
-/**
- * Context for the KSK publication.
- */
-struct PublishKskContext
-{
-
- /**
- * Keywords to use.
- */
- struct GNUNET_FS_Uri *ksk_uri;
-
- /**
- * Global FS context.
- */
- struct GNUNET_FS_Handle *h;
-
- /**
- * The master block that we are sending
- * (in plaintext), has "mdsize+slen" more
- * bytes than the struct would suggest.
- */
- struct KBlock *kb;
-
- /**
- * Buffer of the same size as "kb" for
- * the encrypted version.
- */
- struct KBlock *cpy;
-
- /**
- * Handle to the datastore, NULL if we are just
- * simulating.
- */
- struct GNUNET_DATASTORE_Handle *dsh;
-
- /**
- * Function to call once we're done.
- */
- GNUNET_FS_PublishContinuation cont;
-
- /**
- * Closure for cont.
- */
- void *cont_cls;
-
- /**
- * When should the KBlocks expire?
- */
- struct GNUNET_TIME_Absolute expirationTime;
-
- /**
- * Size of the serialized metadata.
- */
- ssize_t mdsize;
-
- /**
- * Size of the (CHK) URI as a string.
- */
- size_t slen;
-
- /**
- * Keyword that we are currently processing.
- */
- unsigned int i;
-
- /**
- * Anonymity level for the KBlocks.
- */
- uint32_t anonymity;
-
- /**
- * Priority for the KBlocks.
- */
- uint32_t priority;
-};
-
-
-/**
- * Continuation of "GNUNET_FS_publish_ksk" that performs
- * the actual publishing operation (iterating over all
- * of the keywords).
- *
- * @param cls closure of type "struct PublishKskContext*"
- * @param tc unused
- */
-static void
-publish_ksk_cont (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc);
-
-
-/**
- * Function called by the datastore API with
- * the result from the PUT request.
- *
- * @param cls closure of type "struct PublishKskContext*"
- * @param success GNUNET_OK on success
- * @param msg error message (or NULL)
- */
-static void
-kb_put_cont (void *cls,
- int success,
- const char *msg)
-{
- struct PublishKskContext *pkc = cls;
-
- if (GNUNET_OK != success)
- {
- if (NULL != pkc->dsh)
- {
- GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
- pkc->dsh = NULL;
- }
- GNUNET_free (pkc->cpy);
- GNUNET_free (pkc->kb);
- pkc->cont (pkc->cont_cls,
- NULL,
- msg);
- GNUNET_FS_uri_destroy (pkc->ksk_uri);
- GNUNET_free (pkc);
- return;
- }
- GNUNET_SCHEDULER_add_continuation (pkc->h->sched,
- &publish_ksk_cont,
- pkc,
- GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-}
-
-
-/**
- * Continuation of "GNUNET_FS_publish_ksk" that performs the actual
- * publishing operation (iterating over all of the keywords).
- *
- * @param cls closure of type "struct PublishKskContext*"
- * @param tc unused
- */
-static void
-publish_ksk_cont (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct 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;
-
-
- if ( (pkc->i == pkc->ksk_uri->data.ksk.keywordCount) ||
- (NULL == pkc->dsh) )
- {
- if (NULL != pkc->dsh)
- {
- GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
- pkc->dsh = NULL;
- }
- GNUNET_free (pkc->cpy);
- GNUNET_free (pkc->kb);
- pkc->cont (pkc->cont_cls,
- pkc->ksk_uri,
- NULL);
- GNUNET_FS_uri_destroy (pkc->ksk_uri);
- GNUNET_free (pkc);
- return;
- }
- keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++];
- /* 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);
- GNUNET_DATASTORE_put (pkc->dsh,
- 0,
- &query,
- pkc->mdsize +
- sizeof (struct KBlock) +
- pkc->slen,
- pkc->cpy,
- GNUNET_BLOCK_TYPE_KBLOCK,
- pkc->priority,
- pkc->anonymity,
- pkc->expirationTime,
- -2, 1,
- GNUNET_CONSTANTS_SERVICE_TIMEOUT,
- &kb_put_cont,
- pkc);
-}
-
-
-/**
- * Publish a CHK under various keywords on GNUnet.
- *
- * @param h handle to the file sharing subsystem
- * @param ksk_uri keywords to use
- * @param meta metadata to use
- * @param uri URI to refer to in the KBlock
- * @param expirationTime when the KBlock expires
- * @param anonymity anonymity level for the KBlock
- * @param priority priority for the KBlock
- * @param options publication options
- * @param cont continuation
- * @param cont_cls closure for cont
- */
-void
-GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h,
- const struct GNUNET_FS_Uri *ksk_uri,
- const struct GNUNET_CONTAINER_MetaData *meta,
- const struct GNUNET_FS_Uri *uri,
- struct GNUNET_TIME_Absolute expirationTime,
- uint32_t anonymity,
- uint32_t priority,
- enum GNUNET_FS_PublishOptions options,
- GNUNET_FS_PublishContinuation cont,
- void *cont_cls)
-{
- struct PublishKskContext *pkc;
- char *uris;
- size_t size;
- char *kbe;
- char *sptr;
-
- pkc = GNUNET_malloc (sizeof (struct PublishKskContext));
- pkc->h = h;
- pkc->expirationTime = expirationTime;
- pkc->anonymity = anonymity;
- pkc->priority = priority;
- pkc->cont = cont;
- pkc->cont_cls = cont_cls;
- if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
- {
- pkc->dsh = GNUNET_DATASTORE_connect (h->cfg,
- h->sched);
- if (pkc->dsh == NULL)
- {
- cont (cont_cls, NULL, _("Could not connect to datastore."));
- GNUNET_free (pkc);
- return;
- }
- }
- if (meta == NULL)
- pkc->mdsize = 0;
- else
- pkc->mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
- GNUNET_assert (pkc->mdsize >= 0);
- uris = GNUNET_FS_uri_to_string (uri);
- pkc->slen = strlen (uris) + 1;
- size = pkc->mdsize + sizeof (struct KBlock) + pkc->slen;
- if (size > MAX_KBLOCK_SIZE)
- {
- size = MAX_KBLOCK_SIZE;
- pkc->mdsize = size - sizeof (struct KBlock) - pkc->slen;
- }
- pkc->kb = GNUNET_malloc (size);
- kbe = (char *) &pkc->kb[1];
- memcpy (kbe, uris, pkc->slen);
- GNUNET_free (uris);
- sptr = &kbe[pkc->slen];
- if (meta != NULL)
- pkc->mdsize = GNUNET_CONTAINER_meta_data_serialize (meta,
- &sptr,
- pkc->mdsize,
- GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
- if (pkc->mdsize == -1)
- {
- GNUNET_break (0);
- GNUNET_free (pkc->kb);
- if (pkc->dsh != NULL)
- {
- GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
- pkc->dsh = NULL;
- }
- cont (cont_cls, NULL, _("Internal error."));
- GNUNET_free (pkc);
- return;
- }
- size = sizeof (struct KBlock) + pkc->slen + pkc->mdsize;
-
- pkc->cpy = GNUNET_malloc (size);
- pkc->cpy->purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
- sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
- pkc->mdsize +
- pkc->slen);
- pkc->cpy->purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK);
- pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri);
- GNUNET_SCHEDULER_add_continuation (h->sched,
- &publish_ksk_cont,
- pkc,
- GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-}
-
-
-/**
- * Context for the SKS publication.
- */
-struct PublishSksContext
-{
-
- /**
- * Global FS context.
- */
- struct GNUNET_FS_Uri *uri;
-
- /**
- * Handle to the datastore.
- */
- struct GNUNET_DATASTORE_Handle *dsh;
-
- /**
- * Function to call once we're done.
- */
- GNUNET_FS_PublishContinuation cont;
-
- /**
- * Closure for cont.
- */
- void *cont_cls;
-
-};
-
-
-/**
- * Function called by the datastore API with
- * the result from the PUT (SBlock) request.
- *
- * @param cls closure of type "struct PublishSksContext*"
- * @param success GNUNET_OK on success
- * @param msg error message (or NULL)
- */
-static void
-sb_put_cont (void *cls,
- int success,
- const char *msg)
-{
- struct PublishSksContext *psc = cls;
-
- if (NULL != psc->dsh)
- {
- GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO);
- psc->dsh = NULL;
- }
- if (GNUNET_OK != success)
- psc->cont (psc->cont_cls,
- NULL,
- msg);
- else
- psc->cont (psc->cont_cls,
- psc->uri,
- NULL);
- GNUNET_FS_uri_destroy (psc->uri);
- GNUNET_free (psc);