Exemple #1
0
static enum ccn_upcall_res
seqw_incoming_interest(
                       struct ccn_closure *selfp,
                       enum ccn_upcall_kind kind,
                       struct ccn_upcall_info *info)
{
    int res;
    struct ccn_charbuf *cob = NULL;
    struct ccn_seqwriter *w = selfp->data;
    
    if (w == NULL || selfp != &(w->cl))
        abort();
    switch (kind) {
        case CCN_UPCALL_FINAL:
            ccn_charbuf_destroy(&w->nb);
            ccn_charbuf_destroy(&w->nv);
            ccn_charbuf_destroy(&w->buffer);
            ccn_charbuf_destroy(&w->cob0);
            free(w);
            break;
        case CCN_UPCALL_INTEREST:
            if (w->closed || w->buffer->length > 0) {
                cob = seqw_next_cob(w);
                if (cob == NULL)
                    return(CCN_UPCALL_RESULT_OK);
                if (ccn_content_matches_interest(cob->buf, cob->length,
                                                 1, NULL,
                                                 info->interest_ccnb,
                                                 info->pi->offset[CCN_PI_E],
                                                 info->pi)) {
                    w->interests_possibly_pending = 0;
                    res = ccn_put(info->h, cob->buf, cob->length);
                    if (res >= 0) {
                        w->buffer->length = 0;
                        w->seqnum++;
                        return(CCN_UPCALL_RESULT_INTEREST_CONSUMED);
                    }
                }
                ccn_charbuf_destroy(&cob);
            }
            if (w->cob0 != NULL) {
                cob = w->cob0;
                if (ccn_content_matches_interest(cob->buf, cob->length,
                                                 1, NULL,
                                                 info->interest_ccnb,
                                                 info->pi->offset[CCN_PI_E],
                                                 info->pi)) {
                    w->interests_possibly_pending = 0;
                    ccn_put(info->h, cob->buf, cob->length);
                    return(CCN_UPCALL_RESULT_INTEREST_CONSUMED);
                }
            }
            w->interests_possibly_pending = 1;
            break;
        default:
            break;
    }
    return(CCN_UPCALL_RESULT_OK);
}
Exemple #2
0
/**
 * Write some data to a seqwriter.
 *
 * This is roughly analogous to a write(2) call in non-blocking mode.
 *
 * The current implementation returns an error and refuses the new data if
 * it does not fit in the current buffer.
 * That is, there are no partial writes.
 * In this case, the caller should ccn_run() for a little while and retry.
 * 
 * It is also an error to attempt to write more than 4096 bytes.
 *
 * @returns the size written, or -1 for an error.  In case of an error,
 *          the caller may test ccn_geterror() for values of EAGAIN or
 *          EINVAL from errno.h.
 */
int
ccn_seqw_write(struct ccn_seqwriter *w, const void *buf, size_t size)
{
    struct ccn_charbuf *cob = NULL;
    int res;
    int ans;
    
    if (w == NULL || w->cl.data != w)
        return(-1);
    if (w->buffer == NULL || size > MAX_DATA_SIZE)
        return(ccn_seterror(w->h, EINVAL));
    ans = size;
    if (size + w->buffer->length > MAX_DATA_SIZE)
        ans = ccn_seterror(w->h, EAGAIN);
    else if (size != 0)
        ccn_charbuf_append(w->buffer, buf, size);
    if (w->interests_possibly_pending &&
        (w->batching == 0 || ans == -1)) {
        cob = seqw_next_cob(w);
        if (cob != NULL) {
            res = ccn_put(w->h, cob->buf, cob->length);
            if (res >= 0) {
                if (w->seqnum == 0) {
                    w->cob0 = cob;
                    cob = NULL;
                }
                w->buffer->length = 0;
                w->seqnum++;
                w->interests_possibly_pending = 0;
            }
            ccn_charbuf_destroy(&cob);
        }
    }
    return(ans);
}
Exemple #3
0
enum ccn_upcall_res
incoming_interest(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    struct ccn_charbuf *cob = selfp->data;
    int res;
    
    switch (kind) {
        case CCN_UPCALL_FINAL:
            break;
        case CCN_UPCALL_INTEREST:
            if (ccn_content_matches_interest(cob->buf, cob->length,
                    1, NULL,
                    info->interest_ccnb, info->pi->offset[CCN_PI_E],
                    info->pi)) {
                res = ccn_put(info->h, cob->buf, cob->length);
                if (res >= 0) {
                    selfp->intdata = 1;
                    ccn_set_run_timeout(info->h, 0);
                    return(CCN_UPCALL_RESULT_INTEREST_CONSUMED);
                }
            }
            break;
        default:
            break;
    }
    return(CCN_UPCALL_RESULT_OK);
}
Exemple #4
0
int NdnMediaProcess::doPendingSend()
{
    int res = 0;

	struct buf_list  *p;
	struct buf_list *b = localUdb->data_buf.buflist;
	if (b != NULL) {
		p = b->link;
		if (b != NULL && b->buf != NULL) {
			/*
			int c = 0;
			while (pthread_mutex_trylock(&ccn_mutex) != 0) {
				c++;
				if (c > 10000000) {
					fprintf(stderr, "cannot obtain lock! %s:%d\n", __FILE__, __LINE__);
					std::exit(1);
				}
			}
			*/
			pthread_mutex_lock(&ccn_mutex);
			res = ccn_put(ndnState.ccn, b->buf, b->len);
			pthread_mutex_unlock(&ccn_mutex);
			free(b->buf);
			b->len = 0;
			b->buf = NULL;
		}
		free(b);
		localUdb->data_buf.buflist = p;
	}
    return res;
}
Exemple #5
0
void CcnCC_sendContent(CcnCC self, struct ccn_charbuf* name, TimeSpan expires, void* data, size_t size) {
	struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
	if (expires >= 0) {
		sp.template_ccnb = ccn_charbuf_create();
		ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG);
		ccnb_tagged_putf(sp.template_ccnb, CCN_DTAG_FreshnessSeconds, "%ld", expires / 1000);
		sp.sp_flags |= CCN_SP_TEMPL_FRESHNESS;
		ccn_charbuf_append_closer(sp.template_ccnb);
	}
	struct ccn_charbuf* content = ccn_charbuf_create();
	if (0 == ccn_sign_content(self->ccnh, content, name, &sp, data, size)) {
		ccn_put(self->ccnh, content->buf, content->length);
	}
	ccn_charbuf_destroy(&sp.template_ccnb);
	ccn_charbuf_destroy(&content);
}
Exemple #6
0
enum ccn_upcall_res
ccn_proxy_server_decap_interest(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    enum ccn_upcall_res upcall_res = CCN_UPCALL_RESULT_ERR;
    struct ccn_proxy_server* server = selfp->data;
    struct ccn_proxy* proxy = server->proxy;
    // struct ccn_proxy *proxy = (selfp->data)->proxy;
    int i, res;
    unsigned char* random = NULL;
    struct ccn_charbuf* request_name;
    struct ccn_indexbuf* request_comps;
    struct ccn_charbuf* signed_info;
    struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;

    random = (unsigned char*)malloc(RESP_SIZE * sizeof(unsigned char));
    for (i = 0; i < RESP_SIZE; i++) random[i] = rand() % 256;

    handled++;
    printf("random buffer created - creating signed object: %d\n", handled);

    // Create a valid, signed ContentObject
    request_name = NULL;
    request_comps = NULL;
    res = ccn_util_extract_name(info->interest_ccnb, info->interest_comps, &request_name, &request_comps);
    signed_info = ccn_charbuf_create();
    sp.type = CCN_CONTENT_DATA;
    res = ccn_sign_content(proxy->handle, signed_info, request_name, &sp, random, RESP_SIZE);

    // Drop the content object into the socket (handle) to be sent back downstream
    res = ccn_put(proxy->handle, signed_info->buf, signed_info->length);
    if (res < 0)
    {
        ccn_perror(proxy->handle, NULL);
        printf("WTF?!?!?!\n");
    }
    else
    {
        printf("successfully put content object in the socket\n");
    }

    // // TODO: need to fill up random buffer and then inject it using ccn_put

    return(CCN_UPCALL_RESULT_OK);
}
Exemple #7
0
static enum ccn_upcall_res
write_interest_handler (struct ccn_closure *selfp,
                        enum ccn_upcall_kind kind,
                        struct ccn_upcall_info *info) {
    struct ccn_charbuf *cob = selfp->data;
    struct ccn *h = info->h;

    if (kind != CCN_UPCALL_INTEREST)
        return(CCN_UPCALL_RESULT_OK);
    if (ccn_content_matches_interest(cob->buf, cob->length, 1, NULL,
                                     info->interest_ccnb,
                                     info->pi->offset[CCN_PI_E],
                                     info->pi)) {
        ccn_put(info->h, cob->buf, cob->length);
        selfp->intdata = 1;
        ccn_set_run_timeout(h, 0);
        return(CCN_UPCALL_RESULT_INTEREST_CONSUMED);
    }
    return(CCN_UPCALL_RESULT_OK);
}
Exemple #8
0
// handling incoming interest when it is incoming / received
static enum ccn_upcall_res incoming_interest (
		struct ccn_closure *selfp,
		enum ccn_upcall_kind kind,
		struct ccn_upcall_info *info)
{
	struct ccn_charbuf *cob = selfp -> data;
	int res;

	switch (kind) {
	case CCN_UPCALL_FINAL:              // handler is about to be deregistered
		printf("deregistering handler...\n");
		return CCN_UPCALL_RESULT_OK;

	case CCN_UPCALL_INTEREST:           // incoming interest; cob is content, info is incoming interest
		if (ccn_content_matches_interest(cob -> buf, cob -> length, 1, NULL, info -> interest_ccnb, info -> pi -> offset[CCN_PI_E], info -> pi)) {
			res = ccn_put(info->h, cob->buf, cob->length);
			if (res >= 0) {
				selfp -> intdata = 1;
				ccn_set_run_timeout(info->h, 0);
				return (CCN_UPCALL_RESULT_INTEREST_CONSUMED);
			}
		}
		break;

	//case CCN_UPCALL_CONSUMED_INTEREST:  // incoming interest, someone has answered
	//case CCN_UPCALL_CONTENT:            // incoming verified content
	//case CCN_UPCALL_INTEREST_TIMED_OUT:  // interest timed out
	//case CCN_UPCALL_CONTENT_UNVERIFIED:  // content that has not been verified
	//case CCN_UPCALL_CONTENT_BAD:         // verification failed

	default:
		printf("Unexpected response.\n");
		return CCN_UPCALL_RESULT_ERR;
	}
	return (CCN_UPCALL_RESULT_OK);
}
Exemple #9
0
/**
 * Call-back from the CCN network that something has arrived
 *
 * We get notified that a client has interests in things we are producing.
 * This function will do some basic checking to see what exactly the client has
 * an interest in, and will produce what is appropriate.
 * Currently the things we produce are:
 * \li last block - we resend the last block we have published for a given name
 * \li last segment - we produce a data message that only contains the latest segment number we used
 *
 * \param	selfp		-> a context structure we created when registering this call-back
 * \param	kind		specifies the type of call-back being processed, see the \b switch statement
 * \param	info		context information about the call-back itself; interests, data, etc.
 * \return a response as to how successful we were in processing the call-back
 * \retval CCN_UPCALL_RESULT_OK		things went well
 * \retval CCN_UPCALL_RESULT_VERIFY	need to verify the contents of what we received
 * \retval CCN_UPCALL_RESULT_REEXPRESS an interest timedout waiting for data, so we try again
 * \retval CCN_UPCALL_RESULT_ERR	some error was encountered
 */
static enum ccn_upcall_res
new_interests (struct ccn_closure *selfp,
    enum ccn_upcall_kind kind, struct ccn_upcall_info *info)
{
  Gstccnxsink *me = GST_CCNXSINK (selfp->data);
  struct ccn_charbuf *cb;
  struct ccn_charbuf *sname = NULL;
  const unsigned char *cp1, *cp2;
  size_t sz1;
  size_t sz2;
  long lastSeq;
  struct ccn_signing_params myparams;
  unsigned int i;
  int rc;


  GST_DEBUG ("something has arrived!");
  GST_DEBUG ("matched is: %d", info->matched_comps);    // number of filter components that were matched by the interest
  cb = interestAsUri (info);
  GST_DEBUG ("as URI: %s", ccn_charbuf_as_string (cb));
  ccn_charbuf_destroy (&cb);

  myparams = me->sp;

  /* Some debugging stuff */
  for (i = 0; i < 10; ++i) {
    const unsigned char *cp;
    size_t sz;
    GST_DEBUG ("%3d: ", i);
    if (0 > ccn_name_comp_get (info->interest_ccnb, info->interest_comps, i,
            &cp, &sz)) {
      // fprintf(stderr, "could not get comp\n");
      break;
    } else {
      // hDump( DUMP_ADDR( cp ), DUMP_SIZE( sz ) );
    }
  }

  switch (kind) {

    case CCN_UPCALL_FINAL:
      GST_LOG_OBJECT (me, "CCN upcall final %p", selfp);
      return (0);

    case CCN_UPCALL_INTEREST_TIMED_OUT:
      if (selfp != me->ccn_closure) {
        GST_LOG_OBJECT (me, "CCN Interest timed out on dead closure %p", selfp);
        return (0);
      }
      GST_LOG_OBJECT (me, "CCN upcall reexpress -- timed out");
      if (me->timeouts > 5) {
        GST_LOG_OBJECT (me, "CCN upcall reexpress -- too many reexpressions");
        return (0);
      }
      me->timeouts++;
      return (CCN_UPCALL_RESULT_REEXPRESS);

    case CCN_UPCALL_CONTENT_UNVERIFIED:
      if (selfp != me->ccn_closure) {
        GST_LOG_OBJECT (me, "CCN unverified content on dead closure %p", selfp);
        return (0);
      }
      return (CCN_UPCALL_RESULT_VERIFY);

    case CCN_UPCALL_CONTENT:
      if (selfp != me->ccn_closure) {
        GST_LOG_OBJECT (me, "CCN content on dead closure %p", selfp);
        return (0);
      }
      break;

    case CCN_UPCALL_CONTENT_BAD:
      GST_LOG_OBJECT (me,
          "Content signature verification failed! Discarding.\n");
      return (CCN_UPCALL_RESULT_ERR);

    case CCN_UPCALL_CONSUMED_INTEREST:
      GST_LOG_OBJECT (me, "Upcall consumed interest\n");
      return (CCN_UPCALL_RESULT_ERR);   /* no data */

      /* Here is the most interesting case...when an interest arrives */
    case CCN_UPCALL_INTEREST:
      GST_INFO ("We got an interest\n");
      myparams.freshness = 1;   /* meta data is old very quickly */

      /* See if any meta information is sought */
      for (i = 0;; ++i) {
        if (0 > ccn_name_comp_get (info->interest_ccnb, info->interest_comps, i,
                &cp1, &sz1)) {
          cp1 = NULL;
          break;
        } else {
          if (!strncmp ((const char *) cp1, "_meta_", 6)) {     // OK, found meta, now which one is needed?
            if (0 > ccn_name_comp_get (info->interest_ccnb,
                    info->interest_comps, i + 1, &cp2, &sz2)) {
              GST_LOG_OBJECT (me,
                  "CCN interest received with invalid meta request");
              cp1 = NULL;
            }
            break;
          }                     // Component not meta, keep looking
        }
      }                         // At this point, i is left pointing at '_meta_' or at the end of component list

      if (cp1) {
        // hDump( DUMP_ADDR(cp1), DUMP_SIZE(sz1) );
        // hDump( DUMP_ADDR(cp2), DUMP_SIZE(sz2) );
        if (strncmp ((const char *) cp2, ".segment", 8))
          goto Exit_Interest;   /* not a match */

        /* publish what segment we are up to in reply to the meta request */
        lastSeq = me->segment - 1;
        GST_INFO ("sending meta data....segment: %d", lastSeq);

        sname = ccn_charbuf_create ();
        ccn_name_init (sname);
        rc = ccn_name_append_components (sname, info->interest_ccnb,
            info->interest_comps->buf[0], info->interest_comps->buf[i + 2]);
        if (rc < 0)
          goto Error_Interest;
        // rc = ccn_create_version(me->ccn, sname, CCN_V_REPLACE | CCN_V_NOW | CCN_V_HIGH, 0, 0);
        // if (rc < 0) goto Error_Interest;
        me->temp->length = 0;
        rc = ccn_sign_content (me->ccn, me->temp, sname, &myparams,
            &lastSeq, sizeof (lastSeq));
        // hDump(DUMP_ADDR(sname->buf), DUMP_SIZE(sname->length));
        if (rc != 0) {
          GST_LOG_OBJECT (me, "Failed to encode ContentObject (rc == %d)\n",
              rc);
          goto Error_Interest;
        }

        GST_INFO ("sending meta data...");
        // hDump(DUMP_ADDR(me->temp->buf), DUMP_SIZE(me->temp->length));
        rc = ccn_put (me->ccn, me->temp->buf, me->temp->length);
        me->temp->length = 0;
        if (rc < 0) {
          GST_LOG_OBJECT (me, "ccn_put failed (res == %d)\n", rc);
          goto Error_Interest;
        }
        GST_INFO ("meta data sent");

      } else
        goto Exit_Interest;     /* do not have _meta_ */

    Exit_Interest:
      ccn_charbuf_destroy (&sname);
      break;

    Error_Interest:
      ccn_charbuf_destroy (&sname);
      return CCN_UPCALL_RESULT_ERR;


    default:
      GST_LOG_OBJECT (me, "CCN upcall result error");
      return (CCN_UPCALL_RESULT_ERR);
  }


  me->timeouts = 0;


  return (CCN_UPCALL_RESULT_OK);

}
Exemple #10
0
/**
 * Send out a message onto the CCNx network
 *
 * Once a data buffer is ready to be sent onto the network, there are
 * a few more steps involved in preparing it for thta journey.
 * The CCN stack dictates that all data content messages must contain
 * a proper name, and be signed by the sender.
 * \todo some day we should also encrypt the data; I don't think it is now
 * Much of the information we need to accomplish the message preperation is
 * found in the element context or as one of the parameters.
 *
 * Most of the work is dealing with changing from the internal buffer size and
 * the message size of the CCN network.
 * We chop things up as needed and send each data message out, properly named and signed.
 * The naming will include the timestamp as well as a segment number.
 * If there are some partial bytes left over, that do not fill a CCN message packet,
 * we retain those to be sent out on the next call to this method.
 * The bytes are kept in the element context as is other pertinent information.
 *
 * \param me
 * \param data		pointer to the data buffer to send
 * \param size		number of bytes to send in the message
 * \param ts		timestamp to use on the outbound message
 * \return a GST flow return value indicating the result of our attempt
 * \retval GST_FLOW_OK everything went well
 * \retval GST_FLOW_ERROR something went wrong
 */
static GstFlowReturn
gst_ccnxsink_send (Gstccnxsink * me, guint8 * data, guint size, /*@unused@ */
    GstClockTime ts)
{
  struct ccn_charbuf *sname;    /* where we construct the name of this data message */
  struct ccn_charbuf *hold;     /* holds the last block published so we can properly manage memory */
  struct ccn_charbuf *temp;     /* where we construct the message to send */
  struct ccn_charbuf *signed_info;      /* signing data within the message */
  gint rc;                      /* return status on various calls */
  guint8 *xferStart;            /* points into the source buffer, data, as we packetize into CCN blocks */
  size_t bytesLeft;             /* keeps track of how much more we have to do */

  /* Initialize our local storage and allocate buffers we will need */
  xferStart = data;
  bytesLeft = size;
  sname = ccn_charbuf_create ();
  temp = ccn_charbuf_create ();
  signed_info = ccn_charbuf_create ();

  /* Hang onto this pointer so we can release the buffer as we exit this function */
  hold = me->lastPublish;

/*
 * I am hanging onto this code for now to handle the day when we want to encode the data.
 * I do not know why id did not work during development, but I am sure it is close to working 8-)
 * In the future, feel free to purge this if we never get around to using it.
 * Similarly for the code block that is down below a little bit.
 *
  if( me->keystore ) {
    signed_info->length = 0;
GST_LOG_OBJECT( me, "send - signing info\n" );
    rc = ccn_signed_info_create(signed_info
                                 , ccn_keystore_public_key_digest(me->keystore) //pubkeyid 
                                 , ccn_keystore_public_key_digest_length(me->keystore) //publisher_key_id_size 
                                 , NULL			//datetime
                                 , CCN_CONTENT_DATA	//type
                                 , me->expire		//freshness
                                 , NULL			//finalblockid
                                 , me->keylocator);
    // Put the keylocator in the first block only. 
    ccn_charbuf_destroy(&(me->keylocator));
    if (rc < 0) {
        GST_LOG_OBJECT(me, "Failed to create signed_info (rc == %d)\n", rc);
        goto Trouble;
    }
  }
	*/

  if (me->partial) {            /* We had some left over from the last send */
    size_t extra;
    uintmax_t seg;

    /* find out how much room we have left, and copy over the bytes we have, or need to fill the block */
    extra = CCN_CHUNK_SIZE - me->partial->length;
    if (extra > bytesLeft)
      extra = bytesLeft;
    GST_LOG_OBJECT (me, "send - had a partial left: %d\n", extra);
    ccn_charbuf_append (me->partial, xferStart, extra);

    /* Adjust count and pointer to reflect the bytes we have taken */
    bytesLeft -= extra;
    xferStart += extra;

    /* Filling to the size of the CCN packet means we need to send it out */
    if (me->partial->length == CCN_CHUNK_SIZE) {
      sname->length = 0;
      seg = me->segment++;

      /* build up a name starting with the prefix, then the sequence number */
      ccn_charbuf_append (sname, me->name->buf, me->name->length);
      ccn_name_append_numeric (sname, CCN_MARKER_SEQNUM, seg);
      temp->length = 0;

      /* Signing via this function does a lot of work. The result is a buffer, temp, that is ready to be sent */
      ccn_sign_content (me->ccn, temp, sname, &me->sp, me->partial->buf,
          CCN_CHUNK_SIZE);
      //  hDump( sname->buf, sname->length );
      /*
       * See the comment above about holding this code.
       *
       if( me->keystore ) {

       rc = ccn_encode_ContentObject(temp,
       sname,
       signed_info,
       me->partial->buf,
       CCN_CHUNK_SIZE,
       NULL,
       ccn_keystore_private_key(me->keystore));
       if (rc != 0) {
       GST_LOG_OBJECT( me, "Failed to encode ContentObject (rc == %d)\n", rc);
       goto Trouble;
       }
       */
      /* send the data message on its way */
      rc = ccn_put (me->ccn, temp->buf, temp->length);
      if (rc < 0) {
        GST_LOG_OBJECT (me, "ccn_put failed (rc == %d)\n", rc);
        goto Trouble;
      }
      /* free the buffer we used for the partial data */
      ccn_charbuf_destroy (&me->partial);
      me->partial = NULL;
/*
} else {
		GST_LOG_OBJECT( me, "No keystore. What should we do?\n" );
		goto Trouble;
	  }
*/
    }
  }

  /* No left over means we can send direct out of the data buffer */
  /* Now that we are done with the partial block, go and process the new data in much the same fashion */
  while (bytesLeft >= CCN_CHUNK_SIZE) {
    uintmax_t seg;
    GST_LOG_OBJECT (me, "send - bytesLeft: %d\n", bytesLeft);
    sname->length = 0;
    seg = me->segment++;
    ccn_charbuf_append (sname, me->name->buf, me->name->length);
    ccn_name_append_numeric (sname, CCN_MARKER_SEQNUM, seg);
    GST_LOG_OBJECT (me, "send - name is ready\n");
    temp->length = 0;

    ccn_sign_content (me->ccn, temp, sname, &me->sp, xferStart, CCN_CHUNK_SIZE);
    //  hDump( sname->buf, sname->length );
    /*
       if( me->keystore ) {

       GST_LOG_OBJECT( me, "send - encoding\n" );
       rc = ccn_encode_ContentObject(temp,
       sname,
       signed_info,
       xferStart,
       CCN_CHUNK_SIZE,
       NULL,
       ccn_keystore_private_key(me->keystore));
       if (rc != 0) {
       GST_LOG_OBJECT( me, "Failed to encode ContentObject (rc == %d)\n", rc);
       goto Trouble;
       }
     */
    GST_LOG_OBJECT (me, "send - putting\n");
    rc = ccn_put (me->ccn, temp->buf, temp->length);
    if (rc < 0) {
      GST_LOG_OBJECT (me, "ccn_put failed (rc == %d)\n", rc);
      goto Trouble;
    }
    /*
       } else {
       GST_LOG_OBJECT( me, "No keystore. What should we do?\n" );
       goto Trouble;
       }
     */
    GST_LOG_OBJECT (me, "send - adjusting buffers\n");
    /* msleep(5); */
    bytesLeft -= CCN_CHUNK_SIZE;
    xferStart += CCN_CHUNK_SIZE;
  }                             /* end of while() */

  if (bytesLeft) {              /* We have some left over for next time */
    GST_LOG_OBJECT (me, "send - for next time: %d\n", bytesLeft);
    me->partial = ccn_charbuf_create ();
    me->partial->length = 0;
    ccn_charbuf_append (me->partial, xferStart, bytesLeft);
  }

  /* Do proper memory management, then return */
  ccn_charbuf_destroy (&sname);
  me->lastPublish = temp;
  ccn_charbuf_destroy (&hold);
  ccn_charbuf_destroy (&signed_info);
  GST_LOG_OBJECT (me, "send - leaving length: %d\n", me->lastPublish->length);
  return GST_FLOW_OK;

Trouble:
  ccn_charbuf_destroy (&sname);
  ccn_charbuf_destroy (&temp);
  ccn_charbuf_destroy (&signed_info);
  return GST_FLOW_ERROR;
}
/**
 * Common interest handler
 */
PUBLIC enum ccn_upcall_res
ccnr_answer_req(struct ccn_closure *selfp,
                 enum ccn_upcall_kind kind,
                 struct ccn_upcall_info *info)
{
    struct ccn_charbuf *msg = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *keylocator = NULL;
    struct ccn_charbuf *signed_info = NULL;
    struct ccn_charbuf *reply_body = NULL;
    struct ccnr_handle *ccnr = NULL;
    int res = 0;
    int morecomps = 0;
    const unsigned char *final_comp = NULL;
    size_t final_size = 0;
    
    switch (kind) {
        case CCN_UPCALL_FINAL:
            free(selfp);
            return(CCN_UPCALL_RESULT_OK);
        case CCN_UPCALL_INTEREST:
            break;
        case CCN_UPCALL_CONSUMED_INTEREST:
            return(CCN_UPCALL_RESULT_OK);
        default:
            return(CCN_UPCALL_RESULT_ERR);
    }
    ccnr = (struct ccnr_handle *)selfp->data;
    if (CCNSHOULDLOG(ccnr, LM_128, CCNL_FINE))
        ccnr_debug_ccnb(ccnr, __LINE__, "ccnr_answer_req", NULL,
                        info->interest_ccnb, info->pi->offset[CCN_PI_E]);
    morecomps = selfp->intdata & MORECOMPS_MASK;
    if ((info->pi->answerfrom & CCN_AOK_NEW) == 0 &&
        selfp->intdata != OP_SERVICE)
        return(CCN_UPCALL_RESULT_OK);
    if (info->matched_comps >= info->interest_comps->n)
        goto Bail;
    if ((selfp->intdata & OPER_MASK) != OP_SERVICE &&
        info->pi->prefix_comps != info->matched_comps + morecomps)
        goto Bail;
    if (morecomps == 1) {
        res = ccn_name_comp_get(info->interest_ccnb, info->interest_comps,
                                info->matched_comps,
                                &final_comp, &final_size);
        if (res < 0)
            goto Bail;
    }
    if ((selfp->intdata & MUST_VERIFY) != 0) {
        struct ccn_parsed_ContentObject pco = {0};
        // XXX - probably should check for message origin BEFORE verify
        res = ccn_parse_ContentObject(final_comp, final_size, &pco, NULL);
        if (res < 0) {
            ccnr_debug_ccnb(ccnr, __LINE__, "co_parse_failed", NULL,
                            info->interest_ccnb, info->pi->offset[CCN_PI_E]);
            goto Bail;
        }
        res = ccn_verify_content(info->h, final_comp, &pco);
        if (res != 0) {
            ccnr_debug_ccnb(ccnr, __LINE__, "co_verify_failed", NULL,
                            info->interest_ccnb, info->pi->offset[CCN_PI_E]);
            goto Bail;
        }
    }
    switch (selfp->intdata & OPER_MASK) {
        case OP_SERVICE:
            if (ccnr->service_ccnb == NULL)
                ccnr->service_ccnb = ccnr_init_service_ccnb(ccnr, info->h, CCNRID_LOCAL_URI, 600);
            if (ccn_content_matches_interest(
                    ccnr->service_ccnb->buf,
                    ccnr->service_ccnb->length,
                    1,
                    NULL,
                    info->interest_ccnb,
                    info->pi->offset[CCN_PI_E],
                    info->pi
                )) {
                ccn_put(info->h, ccnr->service_ccnb->buf,
                                 ccnr->service_ccnb->length);
                res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
                goto Finish;
            }
            // XXX this needs refactoring.
            if (ccnr->neighbor_ccnb == NULL)
                ccnr->neighbor_ccnb = ccnr_init_service_ccnb(ccnr, info->h, CCNRID_NEIGHBOR_URI, 5);
            if (ccn_content_matches_interest(
                    ccnr->neighbor_ccnb->buf,
                    ccnr->neighbor_ccnb->length,
                    1,
                    NULL,
                    info->interest_ccnb,
                    info->pi->offset[CCN_PI_E],
                    info->pi
                )) {
                ccn_put(info->h, ccnr->neighbor_ccnb->buf,
                                 ccnr->neighbor_ccnb->length);
                res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
                goto Finish;
            }
            if (ccn_content_matches_interest(
                                             ccnr->policy_link_cob->buf,
                                             ccnr->policy_link_cob->length,
                                             1,
                                             NULL,
                                             info->interest_ccnb,
                                             info->pi->offset[CCN_PI_E],
                                             info->pi
                                             )) {
                ccn_put(info->h, ccnr->policy_link_cob->buf,
                        ccnr->policy_link_cob->length);
                res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
                goto Finish;
            }
            goto Bail;
            break;
        default:
            // No other OP_xxx are supported here
            goto Bail;
    }
Bail:
    res = CCN_UPCALL_RESULT_ERR;
Finish:
    ccn_charbuf_destroy(&msg);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&keylocator);
    ccn_charbuf_destroy(&reply_body);
    ccn_charbuf_destroy(&signed_info);
    return(res);
}
Exemple #12
0
int
andana_client_decap_content(struct ccn_closure *selfp,
                            enum ccn_upcall_kind kind,
                            struct ccn_upcall_info *info)
{
    int res;
    struct andana_client *client = selfp->data;

    struct andana_path **path_ptr;

    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;


    DEBUG_PRINT("Client Content handle called\n");


    switch (kind) {
    case CCN_UPCALL_CONTENT:           /**< incoming verified content */
        DEBUG_PRINT("Incoming verified content\n");
        break;
    case CCN_UPCALL_CONTENT_UNVERIFIED:/**< content that has not been verified */
        DEBUG_PRINT("Incoming unverified content\n");
        break;
    case CCN_UPCALL_CONTENT_BAD:        /**< verification failed */
        DEBUG_PRINT("Incoming bad content (verification failure)\n");
        break;

    case CCN_UPCALL_INTEREST_TIMED_OUT:/**< interest timed out */
    {
        const unsigned char *name = info->interest_ccnb + info->pi->offset[CCN_PI_B_Name];
        const size_t length =  info->pi->offset[CCN_PI_E_Name] - info->pi->offset[CCN_PI_B_Name];
        DEBUG_PRINT("Interest timed out\n");
        hashtb_start(client->name_to_path, e);
        hashtb_seek(e, name, length, 0);
        hashtb_delete(e);
        hashtb_end(e);

        return(CCN_UPCALL_RESULT_ERR);
    }
    case CCN_UPCALL_INTEREST:          /**< incoming interest */
    case CCN_UPCALL_CONSUMED_INTEREST: /**< incoming interest, someone has answered */
    case CCN_UPCALL_FINAL:             /**< handler is about to be deregistered */
    default:
        DEBUG_PRINT("upcall other kind = %d\n", kind);
        return(CCN_UPCALL_RESULT_ERR);
    }


    const unsigned char *content_name = info->content_ccnb + info->pco->offset[CCN_PCO_B_Name];
    const size_t name_length = info->pco->offset[CCN_PCO_E_Name] - info->pco->offset[CCN_PCO_B_Name];
    hashtb_start(client->name_to_path, e);
    res = hashtb_seek(e, content_name, name_length, 0);

    if (res == HT_NEW_ENTRY) {
        DEBUG_PRINT("ABORT %d %s Received unsolicited content?\n", __LINE__, __func__);
        abort();
    } else if (res == HT_OLD_ENTRY) {
        path_ptr = e->data;
        DEBUG_PRINT("Interest recording found old entry\n");
    } else {
        DEBUG_PRINT("Error in Interest insertion\n");
    }
    //	hashtb_end(e);

    /* Inner content object (that we just extracted) should exactly
     * match the original requesting Interest. Decrypted and send it out
     */

    unsigned char *decrypted_content = NULL;
    size_t decrypted_length;

    unsigned char *content_ccnb = calloc(info->pco->offset[CCN_PCO_E], sizeof(unsigned char));
    memcpy(content_ccnb, info->content_ccnb, info->pco->offset[CCN_PCO_E]);

    res = andana_path_decrypt_decap(*path_ptr,
                                    content_ccnb,
                                    info->pco->offset[CCN_PCO_E],
                                    info->pco,
                                    &decrypted_content,
                                    &decrypted_length);

    if (res < 0) {
        hashtb_delete(e);
        hashtb_end(e);
        free(content_ccnb);
        free(decrypted_content);
        return(CCN_UPCALL_RESULT_ERR);
    }


    //	ccn_util_validate_content_object(decrypted_content, decrypted_length);

    res = ccn_put(client->proxy->handle, decrypted_content, decrypted_length);

    if (res < 0) {
        DEBUG_PRINT("Error sending parsed content object\n");
        abort();
    }

    //    andana_path_destroy(path_ptr);
    hashtb_delete(e);
    hashtb_end(e);
    free(content_ccnb);
    free(decrypted_content);
    //	andana_path_destroy(path_ptr);
    return(CCN_UPCALL_RESULT_OK);
}
Exemple #13
0
int
main(int argc, char **argv)
{
    const char *progname = argv[0];
    struct ccn *ccn = NULL;
    struct ccn_charbuf *root = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *temp = NULL;
    struct ccn_charbuf *templ = NULL;
    struct ccn_charbuf *signed_info = NULL;
    struct ccn_charbuf *keylocator = NULL;
    struct ccn_charbuf *finalblockid = NULL;
    struct ccn_keystore *keystore = NULL;
    long expire = -1;
    long blocksize = 1024;
    int i;
    int status = 0;
    int res;
    ssize_t read_res;
    unsigned char *buf = NULL;
    struct mydata mydata = { 0 };
    struct ccn_closure in_content = {.p=&incoming_content, .data=&mydata};
    struct ccn_closure in_interest = {.p=&incoming_interest, .data=&mydata};
    while ((res = getopt(argc, argv, "hx:b:")) != -1) {
        switch (res) {
            case 'x':
                expire = atol(optarg);
                if (expire <= 0)
                    usage(progname);
                break;
	    case 'b':
	        blocksize = atol(optarg);
                break;
            default:
            case 'h':
                usage(progname);
                break;
        }
    }
    argc -= optind;
    argv += optind;
    if (argv[0] == NULL)
        usage(progname);
    name = ccn_charbuf_create();
    res = ccn_name_from_uri(name, argv[0]);
    if (res < 0) {
        fprintf(stderr, "%s: bad ccn URI: %s\n", progname, argv[0]);
        exit(1);
    }
    if (argv[1] != NULL)
        fprintf(stderr, "%s warning: extra arguments ignored\n", progname);

    ccn = ccn_create();
    if (ccn_connect(ccn, NULL) == -1) {
        perror("Could not connect to ccnd");
        exit(1);
    }
    
    buf = calloc(1, blocksize);
    root = name;
    name = ccn_charbuf_create();
    temp = ccn_charbuf_create();
    templ = ccn_charbuf_create();
    signed_info = ccn_charbuf_create();
    keystore = ccn_keystore_create();
    temp->length = 0;
    ccn_charbuf_putf(temp, "%s/.ccnx/.ccnx_keystore", getenv("HOME"));
    res = ccn_keystore_init(keystore,
                            ccn_charbuf_as_string(temp),
                            "Th1s1sn0t8g00dp8ssw0rd.");
    if (res != 0) {
        printf("Failed to initialize keystore\n");
        exit(1);
    }
    
    name->length = 0;
    ccn_charbuf_append(name, root->buf, root->length);
    
    /* Set up a handler for interests */
    ccn_set_interest_filter(ccn, name, &in_interest);
    
    /* Initiate check to see whether there is already something there. */
    temp->length = 0;
    ccn_charbuf_putf(temp, "%d", 0);
    ccn_name_append(name, temp->buf, temp->length);
    templ->length = 0;
    ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
    ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
    ccn_charbuf_append_closer(templ); /* </Name> */
    ccn_charbuf_append_tt(templ, CCN_DTAG_MaxSuffixComponents, CCN_DTAG);
    ccn_charbuf_append_tt(templ, 1, CCN_UDATA);
    ccn_charbuf_append(templ, "1", 1);
    ccn_charbuf_append_closer(templ); /* </MaxSuffixComponents> */
    // XXX - use pubid
    ccn_charbuf_append_closer(templ); /* </Interest> */
    res = ccn_express_interest(ccn, name, &in_content, templ);
    if (res < 0) abort();
    
    /* Construct a key locator contining the key itself */
    keylocator = ccn_charbuf_create();
    ccn_charbuf_append_tt(keylocator, CCN_DTAG_KeyLocator, CCN_DTAG);
    ccn_charbuf_append_tt(keylocator, CCN_DTAG_Key, CCN_DTAG);
    res = ccn_append_pubkey_blob(keylocator, ccn_keystore_public_key(keystore));
    if (res < 0)
        ccn_charbuf_destroy(&keylocator);
    else {
        ccn_charbuf_append_closer(keylocator); /* </Key> */
        ccn_charbuf_append_closer(keylocator); /* </KeyLocator> */
    }
    
    for (i = 0;; i++) {
        read_res = read_full(0, buf, blocksize);
        if (read_res < 0) {
            perror("read");
            read_res = 0;
            status = 1;
        }
        signed_info->length = 0;
        if (read_res < blocksize) {
            temp->length = 0;
            ccn_charbuf_putf(temp, "%d", i);
            ccn_name_append(name, temp->buf, temp->length);
            finalblockid = ccn_charbuf_create();
            ccn_charbuf_append_tt(finalblockid, temp->length, CCN_BLOB);
            ccn_charbuf_append(finalblockid, temp->buf, temp->length);
        }
        res = ccn_signed_info_create(signed_info,
                                     /*pubkeyid*/ccn_keystore_public_key_digest(keystore),
                                     /*publisher_key_id_size*/ccn_keystore_public_key_digest_length(keystore),
                                     /*datetime*/NULL,
                                     /*type*/CCN_CONTENT_DATA,
                                     /*freshness*/ expire,
                                     finalblockid,
                                     keylocator);
        /* Put the keylocator in the first block only. */
        ccn_charbuf_destroy(&keylocator);
        if (res < 0) {
            fprintf(stderr, "Failed to create signed_info (res == %d)\n", res);
            exit(1);
        }
        name->length = 0;
        ccn_charbuf_append(name, root->buf, root->length);
        temp->length = 0;
        ccn_charbuf_putf(temp, "%d", i);
        ccn_name_append(name, temp->buf, temp->length);
        temp->length = 0;
        ccn_charbuf_append(temp, buf, read_res);
        temp->length = 0;
        res = ccn_encode_ContentObject(temp,
                                       name,
                                       signed_info,
                                       buf,
                                       read_res,
                                       NULL,
                                       ccn_keystore_private_key(keystore));
        if (res != 0) {
            fprintf(stderr, "Failed to encode ContentObject (res == %d)\n", res);
            exit(1);
        }
        if (i == 0) {
            /* Finish check for old content */
            if (mydata.content_received == 0)
                ccn_run(ccn, 100);
            if (mydata.content_received > 0) {
                fprintf(stderr, "%s: name is in use: %s\n", progname, argv[0]);
                exit(1);
            }
            mydata.outstanding++; /* the first one is free... */
        }
        res = ccn_put(ccn, temp->buf, temp->length);
        if (res < 0) {
            fprintf(stderr, "ccn_put failed (res == %d)\n", res);
            exit(1);
        }
        if (read_res < blocksize)
            break;
        if (mydata.outstanding > 0)
            mydata.outstanding--;
        else
            res = 10;
        res = ccn_run(ccn, res * 100);
        if (res < 0) {
            status = 1;
            break;
        }
    }
    
    free(buf);
    buf = NULL;
    ccn_charbuf_destroy(&root);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&temp);
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&finalblockid);
    ccn_keystore_destroy(&keystore);
    ccn_destroy(&ccn);
    exit(status);
}
Exemple #14
0
enum ccn_upcall_res
andana_server_session_listener(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    int res;
    struct andana_server *server = selfp->data;

    const unsigned char * const_encrypted = NULL;
    unsigned char *encrypted = NULL;
    size_t enc_size;

    /*
     * Extract the client's randomness (aka the symmetric key it sent us.
     * Should be the last component of the incoming Interest.
     */

    struct ccn_charbuf *request_name = NULL;
    struct ccn_indexbuf *request_comps = NULL;


    DEBUG_PRINT("IN %d %s\n", __LINE__, __func__);

    switch (kind) {
    case CCN_UPCALL_INTEREST:
        DEBUG_PRINT("%d %s received session request\n", __LINE__, __func__);
        break;
    case CCN_UPCALL_INTEREST_TIMED_OUT:
        DEBUG_PRINT("%d %s received session request time out\n", __LINE__, __func__);
        /* Fall through */
    default:
        DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__);
        return(CCN_UPCALL_RESULT_OK);
    }

    printf("here now mk?\n");

    res = ccn_util_extract_name(info->interest_ccnb, info->interest_comps, &request_name, &request_comps);

    if (res < 0) {
        DEBUG_PRINT("%d %s Failed to extract session request name\n", __LINE__, __func__);
        ccn_charbuf_destroy(&request_name);
        ccn_indexbuf_destroy(&request_comps);
        return(CCN_UPCALL_RESULT_ERR);
    }

    printf("passed util extract name\n");

    res = ccn_name_comp_get(request_name->buf,
                            request_comps,
                            (unsigned int)request_comps->n - 2,
                            &const_encrypted,
                            &enc_size);

    if (res < 0) {
        DEBUG_PRINT("%d %s Failed to extract session creation data\n", __LINE__, __func__);
        ccn_charbuf_destroy(&request_name);
        ccn_indexbuf_destroy(&request_comps);
        return(CCN_UPCALL_RESULT_ERR);
    }


    encrypted = calloc(enc_size, sizeof(unsigned char));

    printf("encryption size = %d\n", enc_size);
    if (encrypted == NULL) printf("invalid pointer return from calloc\n");

    memcpy(encrypted, const_encrypted, enc_size);

    struct ccn_pkey *symkey = NULL;
    struct ccn_charbuf *decrypted = NULL;
    struct ccn_indexbuf *decrypted_comps = ccn_indexbuf_create();

    printf("trying asymmetric decryption\n");

    ccn_crypto_name_asym_decrypt(server->privkey, encrypted, &symkey, &decrypted, &decrypted_comps);
    // ccn_crypto_name_sym_decrypt(server->node_key, encrypted, encrypted_size, &decrypted, &decrypted_comps);

    /*
cn_crypto_name_sym_decrypt(server->node_key,
                                    encrypted,
                                    encrypted_size,
                                    &symkey,
                                    &decrypted,
                                    &decrypted_comps);
    */

    printf("good - now creating a session\n");


    unsigned char *session_id = NULL;
    unsigned char *session_key = NULL;
    unsigned char *server_rand = NULL;

    /*
     * Create a new session id and session key using the client's randomness.
     * The server is also responsible for contributing randomness of its own for security.
     */

    createSession(&session_id,
                  &session_key,
                  &server_rand,
                  ccn_crypto_symkey_key(symkey),
                  (unsigned int)ccn_crypto_symkey_bytes(symkey),
                  ccn_crypto_symkey_key(server->node_key));

    printf("Session made!\n");

    /* Construct the response message using a ccn name (for convenience). */

    struct ccn_charbuf *session_info = ccn_charbuf_create();
    ccn_name_init(session_info);
    ccn_name_append(session_info, session_id, SESSIONID_LENGTH);
    ccn_name_append(session_info, session_key, SESSION_KEYLEN);
    ccn_name_append(session_info, server_rand, SESSIONRAND_LENGTH);

    /**
     * Encrypt the response message using the symmetric key
     * provided by the client and send it out.
     */

    unsigned char *enc_info = NULL;
    ccn_crypto_content_encrypt(symkey, session_info->buf, session_info->length, &enc_info, &enc_size);

    struct ccn_charbuf *signed_enc_info = ccn_charbuf_create();
    struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
    sp.type = CCN_CONTENT_DATA;


    res = ccn_sign_content(server->proxy->handle,
                           signed_enc_info,
                           request_name,
                           &sp,
                           enc_info,
                           enc_size);

    if (res < 0) {
        DEBUG_PRINT("%d %s Failed to signed session creation response\n", __LINE__, __func__);
    } else {
        res = ccn_put(server->proxy->handle, signed_enc_info->buf, signed_enc_info->length);
    }



    ccn_charbuf_destroy(&decrypted);
    ccn_indexbuf_destroy(&decrypted_comps);
    ccn_crypto_symkey_destroy(&symkey);
    free(session_id);
    free(session_key);
    free(server_rand);
    free(enc_info);
    ccn_charbuf_destroy(&signed_enc_info);

    if (res < 0) {
        DEBUG_PRINT("%d %s Error writing session creation response\n", __LINE__, __func__);
        return(CCN_UPCALL_RESULT_ERR);
    }

    DEBUG_PRINT("OUT %d %s Created new session. Response sent\n", __LINE__, __func__);

    return(CCN_UPCALL_RESULT_INTEREST_CONSUMED);
}
Exemple #15
0
enum ccn_upcall_res
andana_server_decap_interest(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    enum ccn_upcall_res upcall_res = CCN_UPCALL_RESULT_ERR;
    struct andana_server *server = selfp->data;

    struct ccn_proxy *proxy = server->proxy;

    struct ccn_charbuf *new_interest = NULL;
    struct ccn_charbuf *new_name = NULL;

    struct ccn_charbuf *orig_name = NULL;
    struct ccn_indexbuf *orig_name_indexbuf = NULL;
    int orig_name_ncomps;

    char is_session = 0;

    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;

    int res;


    DEBUG_PRINT("IN %d %s\n", __LINE__, __func__);

    switch (kind) {
    case CCN_UPCALL_INTEREST:
        DEBUG_PRINT("%d %s received interest\n", __LINE__, __func__);
        break;
    case CCN_UPCALL_INTEREST_TIMED_OUT:
        DEBUG_PRINT("%d %s received interest time out\n", __LINE__, __func__);
        /* Fall through */
    default:
        DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__);
        return(CCN_UPCALL_RESULT_OK);
    }


    /* Extract Name from Interest */

    orig_name_ncomps = ccn_util_extract_name(info->interest_ccnb,
                                             info->interest_comps,
                                             &orig_name,
                                             &orig_name_indexbuf);

#ifdef PROXYDEBUG
    ccn_util_print_pc_fmt(orig_name->buf, orig_name->length);
    DEBUG_PRINT("\n");

    DEBUG_PRINT("Name has %lu comps\n", orig_name_indexbuf->n-1);
#endif

    /*Decapsulate & decrypt Interest. */


    const unsigned char *const_encrypted = NULL;
    unsigned char *encrypted = NULL;
    size_t encrypted_size;

    if (orig_name_ncomps >= 2) {
        const unsigned char *session_check = NULL;
        size_t session_check_size;

        res = ccn_name_comp_get(orig_name->buf,
				orig_name_indexbuf,
				(unsigned int)server->SESSION_FLAG,
				&session_check,
				&session_check_size);

        if (res < 0) {
            DEBUG_PRINT("%d %s Error extracting session check component %lu\n", __LINE__, __func__, server->SESSION_FLAG);
            goto SessionFail;
        } else {
            DEBUG_PRINT("%d %s Extracted component %lu\n", __LINE__, __func__,server->SESSION_FLAG);
        }

        if (session_check_size == strlen("SESSION") &&
            memcmp(session_check, "SESSION", session_check_size) == 0) {

            DEBUG_PRINT("%d %s Session identified\n", __LINE__, __func__);
            is_session = 1;

        } else {
            DEBUG_PRINT("%d %s Not a session\n", __LINE__, __func__);
        }
    }



    /* Decrypt the name (contains a new name and an Interest template) */

    struct ccn_pkey *symkey = NULL;
    struct ccn_charbuf *decrypted = NULL;
    struct ccn_indexbuf *decrypted_comps = ccn_indexbuf_create();

    if (is_session) {

        res = ccn_name_comp_get(orig_name->buf,
				orig_name_indexbuf,
				(unsigned int)server->SESSION_ENC,
				&const_encrypted,
				&encrypted_size);

        if (res < 0) {
            DEBUG_PRINT("%d %s Error extracting encrypted session component %lu\n", __LINE__, __func__, server->SESSION_ENC);
            goto SessionParseFail;
        } else {
            DEBUG_PRINT("%d %s Extracted encrypted session component  %lu\n", __LINE__, __func__, server->SESSION_ENC);
        }

        encrypted = calloc(encrypted_size, sizeof(unsigned char));
        memcpy(encrypted, const_encrypted, encrypted_size);

        ccn_crypto_name_sym_decrypt(server->node_key,
                                    encrypted,
                                    encrypted_size,
                                    &symkey,
                                    &decrypted,
                                    &decrypted_comps);
    } else {

        ccn_name_comp_get(orig_name->buf, orig_name_indexbuf, (unsigned int)server->ENC, &const_encrypted, &encrypted_size);
        encrypted = calloc(encrypted_size, sizeof(unsigned char));
        memcpy(encrypted, const_encrypted, encrypted_size);

        ccn_crypto_name_asym_decrypt(server->privkey,
                                     encrypted,
                                     &symkey,
                                     &decrypted,
                                     &decrypted_comps);
    }

    size_t ncomps = decrypted_comps->n-1;
    const unsigned char *tmpl = NULL;
    size_t tmpl_size;

    res = ccn_name_comp_get(decrypted->buf, decrypted_comps, (unsigned int)ncomps - 1, &tmpl, &tmpl_size);

    if (res < 0) {
        DEBUG_PRINT("ABORT %d %s unable to retrieve component %d\n",
                    __LINE__, __func__, (int)ncomps);
        goto CompExtractFail;
    }

    /* Pull timestamp component (comp 0) */
    const unsigned char *ts_data = NULL;
    size_t ts_size;
    res = ccn_name_comp_get(decrypted->buf, decrypted_comps, 0, &ts_data, &ts_size);

    if (res < 0) {
        goto CompExtractFail;
    }

    struct timeval timestamp;
    ccn_util_extract_timestamp(ts_data, ts_size, &timestamp);

    struct timeval window = {.tv_sec = 1, .tv_usec = 600000};

    if (ccn_util_timestamp_window(&timestamp, &window) == 0) {
        /* Timestamp too far away, this may be a replay attack */
        DEBUG_PRINT("%d %s Timestamp too distant\n", __LINE__, __func__);
        goto TimestampFail;
    }

    new_name = ccn_charbuf_create();
    ccn_name_init(new_name);


    res = ccn_name_append_components(new_name,
                                     decrypted->buf,
                                     decrypted_comps->buf[1],
                                     decrypted_comps->buf[ncomps-1]);

    if (res < 0) {
        DEBUG_PRINT("ABORT %d %s unable to append components\n",
                    __LINE__, __func__);
        goto AppendCompFail;
    }


    /*Construct new Interest*/

    if (tmpl_size == 0) {
        /* Detected default template */
        DEBUG_PRINT("%d %s Using default Interest template\n", __LINE__, __func__);
        new_interest = NULL;
    } else {
        DEBUG_PRINT("%d %s Copying Interest template\n", __LINE__, __func__);
        new_interest = ccn_charbuf_create();
        ccn_charbuf_append(new_interest, tmpl, tmpl_size);
    }

    /*Map new name to that of the original Interest and the requested symkey */

    hashtb_start(server->cname_to_pair, e);
    res = hashtb_seek(e, new_name->buf, new_name->length, 0);

    if (res == HT_NEW_ENTRY) {
        struct andana_server_pair *p = andana_server_pair_init(orig_name, symkey);
        struct andana_server_pair **loc = e->data;
        *loc = p;
    } else if (res == HT_OLD_ENTRY) {
        DEBUG_PRINT("Interest recording found old entry\n");
        goto LookupFail;
    } else {
        DEBUG_PRINT("Error in Interest insertion\n");
        goto LookupFail;
    }





    DEBUG_PRINT("%d %s starting to write new interest\n", __LINE__, __func__);

    res = ccn_express_interest(proxy->handle, new_name, proxy->content_handler, new_interest);

    DEBUG_PRINT("%d %s done to writing new interest\n", __LINE__, __func__);

    if(res != 0) {
        DEBUG_PRINT("ABORT %d %s express interest res = %d\n", __LINE__, __func__, res);
        goto SendFail;
    }

    upcall_res = CCN_UPCALL_RESULT_OK;


SendFail:
LookupFail:

    if (upcall_res == CCN_UPCALL_RESULT_ERR) {
        hashtb_delete(e);
    }

    hashtb_end(e);

    if (new_interest != NULL) {
        ccn_charbuf_destroy(&new_interest);
    }

TimestampFail:
AppendCompFail:
    ccn_charbuf_destroy(&new_name);

CompExtractFail:
    ccn_charbuf_destroy(&decrypted);
    free(encrypted);
    ccn_crypto_symkey_destroy(&symkey);

SessionParseFail:
    ccn_indexbuf_destroy(&decrypted_comps);

SessionFail:
    ccn_charbuf_destroy(&orig_name);
    ccn_indexbuf_destroy(&orig_name_indexbuf);

    DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__);

    return(upcall_res);
}

/**
 * Encapsulate and encrypt returning content objects. Encryption
 * uses the ephemeral symmetric key provided by the user in the original
 * interest (stored in a pair).
 *
 * This node will naturally sign the outgoing content object, thus providing
 * verifiability.
 */

enum ccn_upcall_res
andana_server_encap_content(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    enum ccn_upcall_res upcall_res = CCN_UPCALL_RESULT_ERR;
    struct andana_server *server = selfp->data;
    struct ccn_proxy *proxy = server->proxy;

    struct ccn_charbuf *new_name = NULL;
    struct andana_server_pair **pair_ptr = NULL;
    struct ccn_charbuf *new_content = NULL;
    struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;

    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;

    int res;

    DEBUG_PRINT("IN %d %s\n",__LINE__, __func__);

    switch (kind) {
    case CCN_UPCALL_CONTENT:           /**< incoming verified content */
        DEBUG_PRINT("%d %s Incoming verified content\n",__LINE__, __func__);
        break;
    case CCN_UPCALL_CONTENT_UNVERIFIED:/**< content that has not been verified */
        DEBUG_PRINT("%d %s Incoming unverified content\n", __LINE__, __func__);
        break;
    case CCN_UPCALL_CONTENT_BAD:        /**< verification failed */
        DEBUG_PRINT("%d %s Incoming bad content (verification failure)\n", __LINE__, __func__);
        break;

    case CCN_UPCALL_INTEREST_TIMED_OUT:/**< interest timed out */
    {
        DEBUG_PRINT("OUT %d %s Interest timed out\n", __LINE__, __func__);

        const unsigned char *name = info->interest_ccnb + info->pi->offset[CCN_PI_B_Name];
        const size_t length =  info->pi->offset[CCN_PI_E_Name] - info->pi->offset[CCN_PI_B_Name];

        hashtb_start(server->cname_to_pair, e);
        hashtb_seek(e, name, length, 0);
        hashtb_delete(e);
        hashtb_end(e);

        return(CCN_UPCALL_RESULT_OK);
    }
    case CCN_UPCALL_FINAL:/**< handler is about to be deregistered */
        DEBUG_PRINT("OUT %d %s final upcall\n", __LINE__, __func__);
        return(CCN_UPCALL_RESULT_OK);

    case CCN_UPCALL_INTEREST:          /**< incoming interest */
    case CCN_UPCALL_CONSUMED_INTEREST: /**< incoming interest, someone has answered */
    default:
        DEBUG_PRINT("OUT %d %s upcall other kind = %d\n", __LINE__, __func__, kind);
        return(CCN_UPCALL_RESULT_ERR);
    }



    DEBUG_PRINT("%d %s Received content object\n", __LINE__, __func__);

    if (info->content_ccnb == NULL) {
        DEBUG_PRINT("OUT %d %s in content upcall, but no content, check kind: %d\n", __LINE__, __func__, kind);
        return(CCN_UPCALL_RESULT_OK);
    }

    /*Find name in Content Object*/

    new_name = ccn_charbuf_create();
    ccn_name_init(new_name);
    ccn_name_append_components(new_name, info->content_ccnb,
                               info->content_comps->buf[0], info->content_comps->buf[info->matched_comps]);

#ifdef PROXYDEBUG
    DEBUG_PRINT("name matches %d comps\n", info->matched_comps);
    ccn_util_print_pc_fmt(info->content_ccnb + info->pco->offset[CCN_PCO_B_Name],
                          info->pco->offset[CCN_PCO_E_Name] - info->pco->offset[CCN_PCO_B_Name]);
    DEBUG_PRINT("\n");
#endif

    pair_ptr = hashtb_lookup(server->cname_to_pair, new_name->buf, new_name->length);

    if(pair_ptr == NULL) {
        /* No match for name*/
#ifdef PROXYDEBUG
        DEBUG_PRINT("Unsolicited content object with name: ");
        ccn_util_print_pc_fmt(new_name->buf, new_name->length);
        DEBUG_PRINT("\n");
#endif
        goto LookupFail;
    }

    struct ccn_charbuf *orig_name = (*pair_ptr)->name;
    struct ccn_pkey *symkey = (*pair_ptr)->symkey;






    /*Created signed info for new content object*/
    unsigned char *encrypted_content = NULL;
    size_t encrypted_length;

    struct ccn_charbuf *content = ccn_charbuf_create();
    ccn_charbuf_append(content, info->content_ccnb, info->pco->offset[CCN_PCO_E]);

    ccn_crypto_content_encrypt(symkey, content->buf, content->length, &encrypted_content, &encrypted_length);

    new_content = ccn_charbuf_create();
    sp.type = CCN_CONTENT_DATA;

    res = ccn_sign_content(proxy->handle,
                           new_content,
                           orig_name,
                           &sp,
                           encrypted_content,
                           encrypted_length);


    if (ccn_util_validate_content_object(new_content->buf, new_content->length) != 0) {
        DEBUG_PRINT("ABORT %d %s Failed to validated signed content\n", __LINE__, __func__);
        abort();
        goto SignFail;
    } else {
        DEBUG_PRINT("OK %d %s signed content is valid\n", __LINE__, __func__);
    }


    if (res != 0) {
        DEBUG_PRINT("ABORT %d %s Failed to encode ContentObject (res == %d)\n", __LINE__, __func__, res);
        goto SignFail;
    }

    DEBUG_PRINT("%d %s starting content write\n", __LINE__, __func__);

    res = ccn_put(proxy->handle, new_content->buf, new_content->length);

    DEBUG_PRINT("%d %s done content write line\n", __LINE__, __func__);

    if (res < 0) {
        DEBUG_PRINT("ABORT %d %s ccn_put failed (res == %d)\n", __LINE__, __func__, res);
        goto SendFail;
    }

    DEBUG_PRINT("%d %s Reply sent\n", __LINE__, __func__);
    upcall_res = CCN_UPCALL_RESULT_OK;


SendFail:
    hashtb_start(server->cname_to_pair, e);
    hashtb_seek(e, new_name->buf, new_name->length, 0);
    hashtb_delete(e);
    hashtb_end(e);



SignFail:
    ccn_charbuf_destroy(&new_content);
    free(encrypted_content);
    ccn_charbuf_destroy(&content);

LookupFail:
    ccn_charbuf_destroy(&new_name);

    DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__);

    return(upcall_res);
}


/**
 * Clean up and destroy anonymous server object. Expect
 * to be called once at program close.
 *
 * @param pointer to anonymous server to be destroyed
 * @returns 0 (always)
 */

int
andana_server_destroy(struct andana_server **server)
{
    struct andana_server *s = *server;

    free(s->proxy->int_handler);
    free(s->proxy->content_handler);
    ccn_proxy_destroy(&(s->proxy));
    ccn_crypto_pubkey_destroy(&(s->privkey));
    hashtb_destroy(&(s->cname_to_pair));
    free(s);

    return(0);
}
Exemple #16
0
/**
 * Send data to the fdholder.
 *
 * No direct error result is provided; the fdholder state is updated as needed.
 */
PUBLIC void
r_io_send(struct ccnr_handle *h,
          struct fdholder *fdholder,
          const void *data, size_t size,
          off_t *offsetp)
{
    ssize_t res;
    off_t offset = -1;
    
    if (offsetp != NULL)
        *offsetp = (off_t)-1;
    if ((fdholder->flags & CCNR_FACE_NOSEND) != 0)
        return;
    if (fdholder->outbuf != NULL) {
        ccn_charbuf_append(fdholder->outbuf, data, size);
        return;
    }
    if (fdholder == h->face0) {
        ccnr_meter_bump(h, fdholder->meter[FM_BYTO], size);
        ccn_dispatch_message(h->internal_client, (void *)data, size);
        r_dispatch_process_internal_client_buffer(h);
        return;
    }
    if ((fdholder->flags & CCNR_FACE_CCND) != 0) {
        /* Writes here need to go via the direct client's handle. */
        ccnr_meter_bump(h, fdholder->meter[FM_BYTO], size);
        res = ccn_put(h->direct_client, data, size);
        if (res < 0 && CCNSHOULDLOG(h, r_io_send, CCNL_WARNING))
            ccnr_msg(h, "ccn_put failed");
        if (res == 1 && CCNSHOULDLOG(h, r_io_send, CCNL_FINEST))
            ccnr_msg(h, "ccn_put deferred output for later send");
        return;
    }
    if ((fdholder->flags & CCNR_FACE_REPODATA) != 0) {
        offset = lseek(fdholder->filedesc, 0, SEEK_END);
        if (offset == (off_t)-1) {
            ccnr_msg(h, "lseek(%d): %s", fdholder->filedesc, strerror(errno));
            return;
        }
        if (offsetp != NULL)
            *offsetp = offset;
        if (fdholder->filedesc == h->active_out_fd) {
            if (offset != h->stable && h->stable != 0)
                ccnr_msg(h, "expected file size %ju, found %ju",
                    (uintmax_t)h->stable,
                    (uintmax_t)offset);
            h->stable = offset + size;
        }
    }
    if ((fdholder->flags & CCNR_FACE_DGRAM) == 0)
        res = write(fdholder->filedesc, data, size);
    else
        res = sendto(sending_fd(h, fdholder), data, size, 0,
                     (struct sockaddr *)fdholder->name->buf,
                     fdholder->name->length);
    if (res > 0)
        ccnr_meter_bump(h, fdholder->meter[FM_BYTO], res);
    if (res == size)
        return;
    if (res == -1) {
        res = handle_send_error(h, errno, fdholder, data, size);
        if (res == -1)
            return;
    }
    if ((fdholder->flags & CCNR_FACE_DGRAM) != 0) {
        ccnr_msg(h, "sendto short");
        return;
    }
    if ((fdholder->flags & CCNR_FACE_REPODATA) != 0) {
        // need to truncate back to last known good object then exit.
        ccnr_msg(h, "Unrecoverable write error writing to repository. Content NOT stored.");
        ftruncate(fdholder->filedesc, offset);
        h->running = 0;
        return;
    }
    fdholder->outbufindex = 0;
    fdholder->outbuf = ccn_charbuf_create();
    if (fdholder->outbuf == NULL) {
        ccnr_msg(h, "do_write: %s", strerror(errno));
        return;
    }
    ccn_charbuf_append(fdholder->outbuf,
                       ((const unsigned char *)data) + res, size - res);
}
Exemple #17
0
int NdnMediaProcess::sendNdnText(const char *text) {
#define CHARBUF_DESTROY \
    ccn_charbuf_destroy(&message);\
    ccn_charbuf_destroy(&path); \
    ccn_charbuf_destroy(&seq);

    UserDataBuf *userBuf = localUdb; 
	if (userBuf == NULL)
		return -1;
    int res = 0;
    int seq_num = -1;
    struct ccn_charbuf *message = ccn_charbuf_create();
    struct ccn_charbuf *path = ccn_charbuf_create();
    struct ccn_charbuf *seq = ccn_charbuf_create();
    
    ccn_name_init(path);
    
	seq_num = textSeq++;
	ccn_name_from_uri(path, localUdb->user_name.toLocal8Bit().constData());
	ccn_name_append_str(path, "text");
    
    if (seq_num < 0) {
        res = -1;
        CHARBUF_DESTROY;
        return res;
    }
    
    ccn_charbuf_putf(seq, "%ld", seq_num);
    ccn_name_append(path, seq->buf, seq->length);

    struct ccn_charbuf *signed_info = ccn_charbuf_create();
	if (cached_keystore == NULL)
		init_cached_keystore(); 
	ccn_charbuf *keylocator = ccn_charbuf_create();
	ccn_create_keylocator(keylocator, ccn_keystore_public_key(cached_keystore));
    /* Create signed_info */
    res = ccn_signed_info_create(signed_info,
                                 /* pubkeyid */ get_my_publisher_key_id(),
                                 /* publisher_key_id_size */ get_my_publisher_key_id_length(),
                                 /* datetime */ NULL,
                                 /* type */ CCN_CONTENT_DATA,
                                 /* freshness */ FRESHNESS,
				                 /* finalblockid */ NULL,
                                 /* keylocator */ keylocator);
    if (res != 0) {
	    fprintf(stderr, "signed_info_create failed %d (line %d)\n", res, __LINE__);
    }

	res = ccn_encode_ContentObject( /* out */ message,
				   path,
				   signed_info,
				   text, strlen(text),
				   /* keyLocator */ NULL, get_my_private_key());

    if (res != 0) {
        fprintf(stderr, "encode_ContentObject failed %d (line %d)\n", res, __LINE__);
        CHARBUF_DESTROY;
        return res;
    }

	ccn_charbuf_destroy(&signed_info);
	ccn_charbuf_destroy(&keylocator);
	pthread_mutex_lock(&ccn_mutex);
	res = ccn_put(ndnState.ccn, message->buf, message->length);
	pthread_mutex_unlock(&ccn_mutex);
}
Exemple #18
0
int main(void) {
	int res;
	struct ccn *ccn= NULL;
	struct ccn_charbuf *name = NULL;
	struct ccn_charbuf *result = NULL;
	struct ccn_closure in_interest = {.p=&incoming_interest};
	struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT; // Parameters for creating signed content objects.
	char rawcontentbuf[1024] = "";
	size_t content_size;

	// 1. Name
	name = ccn_charbuf_create();
	res = ccn_name_from_uri(name, URI);
	if (res < 0) {
		fprintf(stderr, "bad ccn URI: %s\n", URI);
		exit(1);
	}

	// 2. ccn_create, and ccn_connect
	ccn = ccn_create();
	res = ccn_connect(ccn, NULL);
	if (res < 0) {
		fprintf(stderr, "can't connect to ccnd: %d\n", res);
		ccn_perror(ccn, "ccn_connect");
		exit(1);
	}

	// 3. Create the signed content object, set up &sp - signing params;

	// Extend a Name with a new version stamp if requested
	/*int versioned = 0;
	const char *postver = NULL;
	memcmp(postver, "%00", 3);
	if (versioned) {
		res = ccn_create_version(ccn, name, CCN_V_REPLACE | CCN_V_NOW | CCN_V_HIGH, 0, 0);
		if (res < 0) {
			fprintf(stderr, "%s: ccn_create_version() failed\n");
			exit(1);
		}
		if (postver != NULL) {
			res = ccn_name_from_uri(name, postver);
			if (res < 0) {
				fprintf(stderr, "-V %s: invalid name suffix\n", postver);
				exit(0);
			}
		}
	} */

	// Ask for a FinalBlockID if appropriate
	/*int setfinal = 0;
	if (setfinal)
		sp.sp_flags |= CCN_SP_FINAL_BLOCK;
	*/

	// Set content type
	//sp.type = content_type;

	// Set freshness
	/* The template_ccnb may contain a ccnb-encoded SignedInfo to supply selected fields from under
	 * the direction of sp_flags.
	 */
	/*int expire = -1;
	if (expire >= 0) {
		if (sp.template_ccnb == NULL) {
			sp.template_ccnb = ccn_charbuf_create();
			ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG);
			}
		else if (sp.template_ccnb -> length > 0) {
			sp.template_ccnb -> length--;
		}
		ccnb_tagged_putf(sp.template_ccnb, CCN_DTAG_FreshnessSeconds, "%ld", expire);
		sp.sp_flags |= CCN_SP_TEMPL_FRESHNESS;
		ccn_charbuf_append_closer(sp.template_ccnb);
	}
	*/

	// Set key locator, if supplied
	/*const char *key_uri = NULL;
	//key_uri = optarg;
	if (key_uri != NULL) {
		struct ccn_charbuf *c = ccn_charbuf_create();
		res = ccn_name_from_uri(c, key_uri);
		if (res < 0) {
			fprintf(stderr, "%s is not a valid ccnx URI\n", key_uri);
			exit(1);
		}
		if (sp.template_ccnb == NULL) {
			sp.template_ccnb = ccn_charbuf_create();
			ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG);
		}
		else if (sp.template_ccnb -> length > 0) {
			sp.template_ccnb -> length--;
		}
		ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyLocator, CCN_DTAG);
		ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyName, CCN_DTAG);
		ccn_charbuf_append(sp.template_ccnb, c->buf, c->length);
		ccn_charbuf_append_closer(sp.template_ccnb);
		ccn_charbuf_append_closer(sp.template_ccnb);
		sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR;
		ccn_charbuf_append_closer(sp.template_ccnb);
		ccn_charbuf_destroy(&c);
	}
	*/

	// Set up a handler for interest
	ccn_set_interest_filter(ccn, name, &in_interest);


	// 4. Use ccn_sign_content to create the signed content object with composed &sp,
	// if (force) { ccn_put; } # ccn_get means send ccn binary. For normal clients, this should be a ContentObject sent in response to an Interest.
	// else { ccn_set_interest_filter; ccn_run; }

	result = ccn_charbuf_create();
	result -> length = 0;
	strcat(rawcontentbuf, CONTENTDATA);
	content_size = strlen(rawcontentbuf);
	//sp.sp_flags |= CCN_SP_FINAL_BLOCK;
	res = ccn_sign_content(ccn, result, name, &sp, rawcontentbuf, content_size);
	if (res < 0) {
		ccn_perror(ccn, "ccn_sign_content");
		exit(1);
	}

	printf("Content signed, trying to send the data...\n");
	res = ccn_put(ccn, result->buf, result->length);
	if (res < 0) {
		ccn_perror(ccn, "ccn_put");
		printf("Failed to send content object: res = %d\n", res);
		exit(1);
	}
	else
		printf("ccn_put done, content object sent.\n");

	// ccn_run serves as the event loop when timeout = -1
	res = ccn_run(ccn, -1);  // Loop here all the time until it is killed, then "Event loop..."
	printf("Event loop...\n");
	if (res < 0) {
		ccn_perror(ccn, "ccn_run");
		printf("Error: ccn_run\n");
		exit(1);
	}

	ccn_destroy(&ccn);
	ccn_charbuf_destroy(&name);
	ccn_charbuf_destroy(&result);
	ccn_charbuf_destroy(&sp.template_ccnb);
	printf("ccn handle is destroyed... \n");

	return 0;

}
Exemple #19
0
/* does that mean the last component is the implicit digest ? */
enum ccn_upcall_res
packet_handler(struct ccn_closure *selfp,
                 enum ccn_upcall_kind upcall_kind,
                 struct ccn_upcall_info *info)
{
	handler_data* h_data = (handler_data*) selfp->data; // Client data returned

	fprintf(stderr, "\nUpcall from %s handle\n", (info->h==(*h_data->ccn_rec))? "receiver":"publisher");
	ccn_set_run_timeout(info->h, 0); // Return to client faster

    switch(upcall_kind) {
    case CCN_UPCALL_FINAL:
        fprintf(stderr, "CCN_UPCALL_FINAL\n");
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_INTEREST_TIMED_OUT:
        fprintf(stderr, "CCN_UPCALL_INTEREST_TIMED_OUT\n");
        (*h_data->complete) = 1; 	      // End the main loop, some sort of problem
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_CONTENT:
        fprintf(stderr, "CCN_UPCALL_CONTENT\n");
        const unsigned char* content = NULL;
        size_t content_bytes = 0;
        ccn_ref_tagged_BLOB(CCN_DTAG_Content, info->content_ccnb,
							  info->pco->offset[CCN_PCO_B_Content],
							  info->pco->offset[CCN_PCO_E_Content],
							  &content, &content_bytes);
        fprintf(stderr, "\tContent: %s\n", content);
        (*h_data->outstanding_interests)--;
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_CONTENT_UNVERIFIED:
        fprintf(stderr, "CCN_UPCALL_CONTENT_UNVERIFIED\n");
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_CONTENT_BAD:
        fprintf(stderr, "CCN_UPCALL_CONTENT_BAD\n");
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_CONSUMED_INTEREST:
        fprintf(stderr, "CCN_UPCALL_CONSUMED_INTEREST\n");
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_INTEREST:
    	fprintf(stderr, "CCN_UPCALL_INTEREST, (matched comp  == %d)\n", info->matched_comps);
    	fprintf(stderr, "                     (interest comps == %zu)\n", info->interest_comps->n);
    	int res = 0;

    	// Corrected 20-May-2011 to support interests with additional components after prefix
    	//
    	if (info->interest_comps->n < 3) {	// Name + signature + implicit digest, minimum
    		fprintf(stderr, "\tnot enough components, %zu<3\n", info->interest_comps->n);
    	} else {
    	// Verify the interest
			res = verify_signed_interest(info->interest_ccnb, info->interest_comps,
										 info->interest_comps->n-2, info->interest_comps->buf[0], info->interest_comps->buf[info->interest_comps->n-2],
										   (*h_data->public_key));
			fprintf(stderr, "\tverify_signed_interest == %d (%s)\n", res, (res==1)?"verified":"unverified");
    	}
		// Based on the results,
		// create and send a reply using default key & algorithm for the receiving handle
		// to sign the content object.
		//
		char* reply_data = (res==1) ? "OK" : "AUTH_FAIL";	// A modest content.
		struct ccn_charbuf* reply = ccn_charbuf_create();
		struct ccn_charbuf* name = ccn_charbuf_create();
		struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
	    ccn_name_init(name); // Don't need to create a new name, could just index into the buffer.
	    res = ccn_name_append_components(name, info->interest_ccnb,
	    					info->interest_comps->buf[0], info->interest_comps->buf[info->interest_comps->n - 1]);
		ccn_sign_content(info->h, reply, name, &sp, (void*)reply_data, strlen(reply_data)+1);
		res = ccn_put(info->h, reply->buf, reply->length);
		ccn_charbuf_destroy(&reply);
		ccn_charbuf_destroy(&name);
		if (res >= 0) {
			fprintf (stderr, "\tReturned Content: %s\n", reply_data);
			return (CCN_UPCALL_RESULT_INTEREST_CONSUMED);
		}
        return (CCN_UPCALL_RESULT_OK);
    }
    return (CCN_UPCALL_RESULT_ERR);
}
Exemple #20
0
void GroupManager::incomingInterest(ccn_upcall_info *info) {
    int res;

    const char *data = NULL;
    const unsigned char *requester = NULL;
    const unsigned char *refresher = NULL;
    const unsigned char *filter = NULL;
    size_t filter_len = 0;

    ccn_charbuf *signed_info = NULL;
    ccn_charbuf *name = NULL;
    ccn_charbuf *content = NULL;

    RemoteUser *refreshUser = NULL;

    // requesterPrefix starts from index 4 to (info->interest_comps->n - 2)
    int nameEnd = 0;
	nameEnd = (info->interest_comps)->n - 2;

	/* construct reply data
	 * name format:
	 *   /ndn/broadcast/conference/conference-name/speaker-list/username
	 */
	signed_info = ccn_charbuf_create();
	struct ccn_charbuf *keylocator = ccn_charbuf_create();
	ccn_create_keylocator(keylocator, ccn_keystore_public_key(cached_keystore));
	res = ccn_signed_info_create(signed_info,
			/*pubkeyid*/ get_my_publisher_key_id(),
			/*publisher_key_id_size*/ get_my_publisher_key_id_length(),
			/*datetime*/ NULL,
			/*type*/ CCN_CONTENT_DATA,
			///*freshness*/ -1,
			/*freshness*/ FRESHNESS,
			/*finalblockid*/ NULL,
			/*keylocator*/ keylocator);
	if (res < 0) {
		DPRINT("FAILED TO CREATE signed_info (res == %d)", res);
	}

	name = ccn_charbuf_create();
	content = ccn_charbuf_create();
	ccn_name_init(name);
	ccn_name_append_components(name, info->interest_ccnb,
			info->interest_comps->buf[0], info->interest_comps->buf[nameEnd + 1]);
	// append own  username
	ccn_name_append_str(name, userName.toLocal8Bit().constData());
	// get user list, the caller need to free the data buffer allocated 
	int dlen = userListtoXml(&data);
	ccn_encode_ContentObject(content, name, signed_info,
			data, dlen, 
			NULL, get_my_private_key());
	// already have the lock, no need to trylock
	ccn_put(info->h, content->buf, content->length);
	ccn_charbuf_destroy(&signed_info);
	ccn_charbuf_destroy(&name);
	ccn_charbuf_destroy(&content);
	if (data != NULL) {
		free((void *)data);
		data = NULL;
	}
}
Exemple #21
0
int
main(int argc, char **argv)
{
    const char *progname = argv[0];
    struct ccn *ccn = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *pname = NULL;
    struct ccn_charbuf *temp = NULL;
    struct ccn_charbuf *extopt = NULL;
    long expire = -1;
    int versioned = 0;
    size_t blocksize = 8*1024;
    int status = 0;
    int res;
    ssize_t read_res;
    unsigned char *buf = NULL;
    enum ccn_content_type content_type = CCN_CONTENT_DATA;
    struct ccn_closure in_interest = {.p=&incoming_interest};
    const char *postver = NULL;
    const char *key_uri = NULL;
    int force = 0;
    int verbose = 0;
    int timeout = -1;
    int setfinal = 0;
    int prefixcomps = -1;
    int fd;
    struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
    
    while ((res = getopt(argc, argv, "e:fhk:lvV:p:t:w:x:")) != -1) {
        switch (res) {
            case 'e':
                if (extopt == NULL)
                    extopt = ccn_charbuf_create();
                fd = open(optarg, O_RDONLY);
                if (fd < 0) {
                    perror(optarg);
                    exit(1);
                }
                for (;;) {
                    read_res = read(fd, ccn_charbuf_reserve(extopt, 64), 64);
                    if (read_res <= 0)
                        break;
                    extopt->length += read_res;
                }
                if (read_res < 0)
                    perror(optarg);
                close(fd);
                break;
            case 'f':
                force = 1;
                break;
            case 'l':
                setfinal = 1; // set FinalBlockID to last comp of name
                break;
            case 'k':
                key_uri = optarg;
                break;
            case 'p':
                prefixcomps = atoi(optarg);
                if (prefixcomps < 0)
                    usage(progname);
                break;
            case 'x':
                expire = atol(optarg);
                if (expire <= 0)
                    usage(progname);
                break;
            case 'v':
                verbose = 1;
                break;
            case 'V':
                versioned = 1;
                postver = optarg;
                if (0 == memcmp(postver, "%00", 3))
                    setfinal = 1;
                break;
            case 'w':
                timeout = atol(optarg);
                if (timeout <= 0)
                    usage(progname);
                timeout *= 1000;
                break;
            case 't':
                if (0 == strcasecmp(optarg, "DATA")) {
                    content_type = CCN_CONTENT_DATA;
                    break;
                }
                if (0 == strcasecmp(optarg, "ENCR")) {
                    content_type = CCN_CONTENT_ENCR;
                    break;
                }
                if (0 == strcasecmp(optarg, "GONE")) {
                    content_type = CCN_CONTENT_GONE;
                    break;
                }
                if (0 == strcasecmp(optarg, "KEY")) {
                    content_type = CCN_CONTENT_KEY;
                    break;
                }
                if (0 == strcasecmp(optarg, "LINK")) {
                    content_type = CCN_CONTENT_LINK;
                    break;
                }
                if (0 == strcasecmp(optarg, "NACK")) {
                    content_type = CCN_CONTENT_NACK;
                    break;
                }
                content_type = atoi(optarg);
                if (content_type > 0 && content_type <= 0xffffff)
                    break;
                fprintf(stderr, "Unknown content type %s\n", optarg);
                /* FALLTHRU */
            default:
            case 'h':
                usage(progname);
                break;
        }
    }
    argc -= optind;
    argv += optind;
    if (argv[0] == NULL)
        usage(progname);
    name = ccn_charbuf_create();
    res = ccn_name_from_uri(name, argv[0]);
    if (res < 0) {
        fprintf(stderr, "%s: bad ccn URI: %s\n", progname, argv[0]);
        exit(1);
    }
    if (argv[1] != NULL)
        fprintf(stderr, "%s warning: extra arguments ignored\n", progname);
    
    /* Preserve the original prefix, in case we add versioning,
     * but trim it down if requested for the interest filter registration
     */
    pname = ccn_charbuf_create();
    ccn_charbuf_append(pname, name->buf, name->length);
    if (prefixcomps >= 0) {
        res = ccn_name_chop(pname, NULL, prefixcomps);
        if (res < 0) {
            fprintf(stderr, "%s: unable to trim name to %d component%s.\n",
                    progname, prefixcomps, prefixcomps == 1 ? "" : "s");
            exit(1);
        }
    }
    /* Connect to ccnd */
    ccn = ccn_create();
    if (ccn_connect(ccn, NULL) == -1) {
        perror("Could not connect to ccnd");
        exit(1);
    }

    /* Read the actual user data from standard input */
    buf = calloc(1, blocksize);
    read_res = read_full(0, buf, blocksize);
    if (read_res < 0) {
        perror("read");
        read_res = 0;
        status = 1;
    }
        
    /* Tack on the version component if requested */
    if (versioned) {
        res = ccn_create_version(ccn, name, CCN_V_REPLACE | CCN_V_NOW | CCN_V_HIGH, 0, 0);
        if (res < 0) {
            fprintf(stderr, "%s: ccn_create_version() failed\n", progname);
            exit(1);
        }
        if (postver != NULL) {
            res = ccn_name_from_uri(name, postver);
            if (res < 0) {
                fprintf(stderr, "-V %s: invalid name suffix\n", postver);
                exit(0);
            }
        }
    }
    temp = ccn_charbuf_create();
    
    /* Ask for a FinalBlockID if appropriate. */
    if (setfinal)
        sp.sp_flags |= CCN_SP_FINAL_BLOCK;
    
    if (res < 0) {
        fprintf(stderr, "Failed to create signed_info (res == %d)\n", res);
        exit(1);
    }
    
    /* Set content type */
    sp.type = content_type;
    
    /* Set freshness */
    if (expire >= 0) {
        if (sp.template_ccnb == NULL) {
            sp.template_ccnb = ccn_charbuf_create();
            ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG);
        }
        else if (sp.template_ccnb->length > 0) {
            sp.template_ccnb->length--;
        }
        ccnb_tagged_putf(sp.template_ccnb, CCN_DTAG_FreshnessSeconds, "%ld", expire);
        sp.sp_flags |= CCN_SP_TEMPL_FRESHNESS;
        ccn_charbuf_append_closer(sp.template_ccnb);
    }
    
    /* Set key locator, if supplied */
    if (key_uri != NULL) {
        struct ccn_charbuf *c = ccn_charbuf_create();
        res = ccn_name_from_uri(c, key_uri);
        if (res < 0) {
            fprintf(stderr, "%s is not a valid ccnx URI\n", key_uri);
            exit(1);
        }
        if (sp.template_ccnb == NULL) {
            sp.template_ccnb = ccn_charbuf_create();
            ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG);
        }
        else if (sp.template_ccnb->length > 0) {
            sp.template_ccnb->length--;
        }
        ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyLocator, CCN_DTAG);
        ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyName, CCN_DTAG);
        ccn_charbuf_append(sp.template_ccnb, c->buf, c->length);
        ccn_charbuf_append_closer(sp.template_ccnb);
        ccn_charbuf_append_closer(sp.template_ccnb);
        sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR;
        ccn_charbuf_append_closer(sp.template_ccnb);
        ccn_charbuf_destroy(&c);
    }

    if (extopt != NULL && extopt->length > 0) {
        if (sp.template_ccnb == NULL) {
            sp.template_ccnb = ccn_charbuf_create();
            ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG);
        }
        else if (sp.template_ccnb->length > 0) {
            sp.template_ccnb->length--;
        }
        ccnb_append_tagged_blob(sp.template_ccnb, CCN_DTAG_ExtOpt,
                                extopt->buf, extopt->length);
        sp.sp_flags |= CCN_SP_TEMPL_EXT_OPT;
        ccn_charbuf_append_closer(sp.template_ccnb);
    }
    
    /* Create the signed content object, ready to go */
    temp->length = 0;
    res = ccn_sign_content(ccn, temp, name, &sp, buf, read_res);
    if (res != 0) {
        fprintf(stderr, "Failed to encode ContentObject (res == %d)\n", res);
        exit(1);
    }
    if (read_res == blocksize) {
        read_res = read_full(0, buf, 1);
        if (read_res == 1) {
            fprintf(stderr, "%s: warning - truncated data\n", argv[0]);
            status = 1;
        }
    }
    free(buf);
    buf = NULL;
    if (force) {
        /* At user request, send without waiting to see an interest */
        res = ccn_put(ccn, temp->buf, temp->length);
        if (res < 0) {
            fprintf(stderr, "ccn_put failed (res == %d)\n", res);
            exit(1);
        }
    }
    else {
        in_interest.data = temp;
        /* Set up a handler for interests */
        res = ccn_set_interest_filter(ccn, pname, &in_interest);
        if (res < 0) {
            fprintf(stderr, "Failed to register interest (res == %d)\n", res);
            exit(1);
        }
        res = ccn_run(ccn, timeout);
        if (in_interest.intdata == 0) {
            if (verbose)
                fprintf(stderr, "Nobody's interested\n");
            exit(1);
        }
    }
    
    if (verbose) {
        struct ccn_charbuf *uri = ccn_charbuf_create();
        uri->length = 0;
        ccn_uri_append(uri, name->buf, name->length, 1);
        printf("wrote %s\n", ccn_charbuf_as_string(uri));
        ccn_charbuf_destroy(&uri);
    }
    ccn_destroy(&ccn);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&pname);
    ccn_charbuf_destroy(&temp);
    ccn_charbuf_destroy(&sp.template_ccnb);
    ccn_charbuf_destroy(&extopt);
    exit(status);
}