static void ccn_publish_client_mountpoint() { dropbear_log(LOG_WARNING,"Enter ccn_publish_client_mountpoint"); int result; struct ccn_charbuf *mountpoint; char client_id_str[6]; char *client_name_str = NULL; mountpoint = ccn_charbuf_create(); if( mountpoint == NULL ) dropbear_exit("Failed to allocate client mountpoint charbuf"); client_name_str = strdup((const char*)cli_opts.ccnxdomain); strcat(client_name_str,"/ssh/"); sprintf(client_id_str,"%6d",rand()); strcat(client_name_str,client_id_str); cli_opts.ccnxdomain = client_name_str; result = ccn_name_from_uri(mountpoint,cli_opts.ccnxdomain); if( result < 0 ) dropbear_exit("Can't resolve client domain"); dropbear_log(LOG_WARNING,"Listening at"); print_ccnb_charbuf(mountpoint); result = ccn_set_interest_filter(cli_opts.ssh_ccn,mountpoint,&newServerAction); }
int andana_server_connect(struct andana_server *server) { int res; res = ccn_proxy_connect(server->proxy); if (res != 0) { return(res); } struct ccn_charbuf *session_namespace = ccn_charbuf_create(); ccn_charbuf_append_charbuf(session_namespace, server->proxy->filter); ccn_name_append_str(session_namespace, "CREATESESSION"); server->session_handler.p = &andana_server_session_listener; server->session_handler.data = server; res = ccn_set_interest_filter(server->proxy->handle, session_namespace, &(server->session_handler)); ccn_charbuf_destroy(&session_namespace); return(res); }
/** * Base loop for the background CCN task * * This is the main execution loop for the background task responsible for * interacting with the CCN network. It is from this point that many of the above methods are * called to work the inbound messages from ccnx as well as sending out the data messages. * * \param data the task context information setup by the parent sink element thread */ static void ccn_event_thread (void *data) { Gstccnxsink *me = (Gstccnxsink *) data; struct ccn_charbuf *filtName; struct ccn_charbuf *temp; int res = 0; GST_DEBUG ("CCNxSink event: *** event thread starting"); temp = ccn_charbuf_create (); filtName = ccn_charbuf_create (); /* A closure is what defines what to do when an inbound interest arrives */ if ((me->ccn_closure = calloc (1, sizeof (struct ccn_closure))) == NULL) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("closure alloc failed")); return; } /* We setup the closure to contain the sink element context reference, and also tell it what function to call */ me->ccn_closure->data = me; me->ccn_closure->p = new_interests; me->timeouts = 0; ccn_charbuf_append (filtName, me->name->buf, me->name->length); /* This call will set up a handler for interests we expect to get from clients */ // hDump(DUMP_ADDR(filtName->buf), DUMP_SIZE(filtName->length)); ccn_set_interest_filter (me->ccn, filtName, me->ccn_closure); GST_DEBUG ("CCNxSink event: interest filter registered\n"); /* Some debugging information */ temp->length = 0; ccn_uri_append (temp, me->name->buf, me->name->length, TRUE); GST_DEBUG ("CCNxSink event: using uri: %s\n", ccn_charbuf_as_string (temp)); /* Now that the interest is registered, we loop around waiting for something to do */ /* We pass control to ccnx for a while so it can work with any incoming or outgoing data */ /* and then we check our fifo queue for work to do. That's about it! */ /* We check to see if any problems have caused our ccnd connection to fail, and we reconnect */ while (res >= 0) { GST_DEBUG ("CCNxSink event: *** looping"); res = ccn_run (me->ccn, 50); check_fifo (me); if (res < 0 && ccn_get_connection_fd (me->ccn) == -1) { GST_DEBUG ("CCNxSink event: need to reconnect..."); /* Try reconnecting, after a bit of delay */ msleep ((30 + (getpid () % 30)) * 1000); res = ccn_connect (me->ccn, ccndHost ()); } } GST_DEBUG ("CCNxSink event: *** event thread ending"); }
int GroupManager::ccn_open() { ccn_charbuf *interest_filter_path; interest_filter_path = ccn_charbuf_create(); if (interest_filter_path == NULL ) { DPRINT("Failed to allocate or initialize interest filter path"); return -1; } ccn_name_from_uri(interest_filter_path, (const char *) BROADCAST_PREFIX); ccn_name_append_str(interest_filter_path, confName.toLocal8Bit().constData()); ccn_name_append_str(interest_filter_path, "speaker-list"); ccn_set_interest_filter(ccn, interest_filter_path, req_closure); ccn_charbuf_destroy(&interest_filter_path); ccn_charbuf *leave_filter = ccn_charbuf_create(); ccn_name_from_uri(leave_filter, (const char *) BROADCAST_PREFIX); ccn_name_append_str(leave_filter, confName.toLocal8Bit().constData()); ccn_name_append_str(leave_filter, "leave"); ccn_set_interest_filter(ccn, leave_filter, leave_closure); ccn_charbuf_destroy(&leave_filter); return 0; }
/** * Close the seqwriter, which will be freed. */ int ccn_seqw_close(struct ccn_seqwriter *w) { if (w == NULL || w->cl.data != w) return(-1); w->closed = 1; w->interests_possibly_pending = 1; w->batching = 0; ccn_seqw_write(w, NULL, 0); ccn_set_interest_filter(w->h, w->nb, NULL); return(0); }
void CcnCC_registerControlPrefix(CcnCC self) { if (self->regControlPrefix) return; struct ccn_charbuf* prefix = ccn_charbuf_create(); ccn_name_from_uri(prefix, "ccnx:/ccnx/ndnld"); ccn_name_append(prefix, self->ccndid, CCNDID_length); ccn_name_append_str(prefix, "control"); struct ccn_closure* action = (struct ccn_closure*)calloc(1, sizeof(struct ccn_closure)); action->data = self; action->p = &CcnCC_controlInterest; ccn_set_interest_filter(self->ccnh, prefix, action); ccn_charbuf_destroy(&prefix); }
/** * Create a seqwriter for writing data to a versioned, segmented stream. * * @param name is a ccnb-encoded Name. It will be provided with a version * based on the current time unless it already ends in a version * component. */ struct ccn_seqwriter * ccn_seqw_create(struct ccn *h, struct ccn_charbuf *name) { struct ccn_seqwriter *w = NULL; struct ccn_charbuf *nb = NULL; struct ccn_charbuf *nv = NULL; int res; w = calloc(1, sizeof(*w)); if (w == NULL) return(NULL); nb = ccn_charbuf_create(); ccn_charbuf_append(nb, name->buf, name->length); nv = ccn_charbuf_create(); ccn_charbuf_append(nv, name->buf, name->length); res = ccn_create_version(h, nv, CCN_V_NOW, 0, 0); if (res < 0 || nb == NULL) { ccn_charbuf_destroy(&nv); ccn_charbuf_destroy(&nb); free(w); return(NULL); } w->cl.p = &seqw_incoming_interest; w->cl.data = w; w->nb = nb; w->nv = nv; w->buffer = ccn_charbuf_create(); w->h = h; w->seqnum = 0; w->interests_possibly_pending = 1; res = ccn_set_interest_filter(h, nb, &(w->cl)); if (res < 0) { ccn_charbuf_destroy(&w->nb); ccn_charbuf_destroy(&w->nv); ccn_charbuf_destroy(&w->buffer); free(w); return(NULL); } return(w); }
PUBLIC void ccnr_uri_listen(struct ccnr_handle *ccnr, struct ccn *ccn, const char *uri, ccn_handler p, intptr_t intdata) { struct ccn_charbuf *name; struct ccn_charbuf *uri_modified = NULL; struct ccn_closure *closure; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; size_t offset; name = ccn_charbuf_create(); ccn_name_from_uri(name, uri); comps = ccn_indexbuf_create(); if (ccn_name_split(name, comps) < 0) abort(); if (ccn_name_comp_get(name->buf, comps, 1, &comp, &comp_size) >= 0) { if (comp_size == 32 && 0 == memcmp(comp, CCNR_ID_TEMPL, 32)) { /* Replace placeholder with our ccnr_id */ offset = comp - name->buf; memcpy(name->buf + offset, ccnr->ccnr_id, 32); uri_modified = ccn_charbuf_create(); ccn_uri_append(uri_modified, name->buf, name->length, 1); uri = (char *)uri_modified->buf; } } closure = calloc(1, sizeof(*closure)); closure->p = p; closure->data = ccnr; closure->intdata = intdata; ccn_set_interest_filter(ccn, name, closure); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&uri_modified); ccn_indexbuf_destroy(&comps); }
int ccn_proxy_connect(struct ccn_proxy *proxy) { DEBUG_PRINT("IN %d %s\n", __LINE__, __func__); if ((proxy->handle = ccn_create()) == NULL) { DEBUG_PRINT("OUT %d %s failed to create %s ccn handle\n", __LINE__, __func__, proxy->handle_name->buf); return(-1); } if (ccn_connect(proxy->handle, NULL) == -1) { DEBUG_PRINT("OUT %d %s failed to connect %s ccn handle\n", __LINE__, __func__, proxy->handle_name->buf); return(-2); } DEBUG_PRINT("%d %s setting up interest handler\n", __LINE__, __func__); ccn_set_interest_filter(proxy->handle, proxy->filter, proxy->int_handler); DEBUG_PRINT("%d %s interest printer setup\n", __LINE__, __func__); DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__); return(0); }
static int write_slice(struct ccn *h, struct ccns_slice *slice, struct ccn_charbuf *name) { struct ccn_charbuf *content = NULL; unsigned char *cbuf = NULL; size_t clength = 0; struct ccn_charbuf *sw = NULL; struct ccn_charbuf *templ = NULL; struct ccn_charbuf *cob = NULL; struct ccn_signing_params sparm = CCN_SIGNING_PARAMS_INIT; struct ccn_closure *wc = NULL; int res; sw = ccn_charbuf_create_n(32 + name->length); if (sw == NULL) { res = -1; goto Cleanup; } ccn_charbuf_append_charbuf(sw, name); ccn_name_chop(sw, NULL, -1); // remove segment number ccn_name_from_uri(sw, "%C1.R.sw"); ccn_name_append_nonce(sw); // create and sign the content object cob = ccn_charbuf_create(); if (cob == NULL) { res = -1; goto Cleanup; } if (slice != NULL) { content = ccn_charbuf_create(); if (content == NULL) { res = -1; goto Cleanup; } res = append_slice(content, slice); if (res < 0) goto Cleanup; cbuf = content->buf; clength = content->length; } else { sparm.type = CCN_CONTENT_GONE; } sparm.sp_flags = CCN_SP_FINAL_BLOCK; res = ccn_sign_content(h, cob, name, &sparm, cbuf, clength); if (res < 0) goto Cleanup; // establish handler for interest in the slice content object wc = calloc(1, sizeof(*wc)); if (wc == NULL) { res = -1; goto Cleanup; } wc->p = &write_interest_handler; wc->data = cob; res = ccn_set_interest_filter(h, name, wc); if (res < 0) goto Cleanup; templ = make_scope1_template(); if (templ == NULL) { res = -1; goto Cleanup; } res = ccn_get(h, sw, templ, 1000, NULL, NULL, NULL, 0); if (res < 0) goto Cleanup; ccn_run(h, 1000); // give the repository a chance to fetch the data if (wc->intdata != 1) { res = -1; goto Cleanup; } res = 0; Cleanup: ccn_set_interest_filter(h, name, NULL); if (wc != NULL) free(wc); ccn_charbuf_destroy(&cob); ccn_charbuf_destroy(&content); ccn_charbuf_destroy(&sw); ccn_charbuf_destroy(&templ); return (res); }
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; }
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); }
int main(int argc, char** argv) { int res = 0; struct ccn* ccn_pub; struct ccn* ccn_rec; // Will hold the public/private key used for signing struct ccn_pkey* public_key = NULL; struct ccn_pkey* private_key = NULL; int complete=0; int outstanding_interests=0; // We need two ccn handles because the same handle cannot be used // to answer interests it issues. // ccn_pub = ccn_create(); if (ccn_connect(ccn_pub, NULL) == -1) { fprintf(stderr, "Could not connect to ccnd"); return(1); } ccn_rec = ccn_create(); if (ccn_connect(ccn_rec, NULL) == -1) { fprintf(stderr, "Could not connect to ccnd"); return(1); } // Closure to handle upcalls struct ccn_closure *cl = NULL; cl = (struct ccn_closure*) calloc(1, sizeof(struct ccn_closure)); cl->p = &packet_handler; handler_data h_data = { &complete, &outstanding_interests, &public_key, &ccn_pub, &ccn_rec}; cl->data = &h_data; // Setup our one test name without signature // The nonce here is just a random string, to avoid content store caching struct ccn_charbuf* name; name = ccn_charbuf_create(); ccn_name_from_uri(name, TEST_URI); ccn_name_append_nonce(name); fprintf(stderr, "Our name: %s/<nonce>\n", TEST_URI); // Set up a filter for interests in that name res = ccn_set_interest_filter(ccn_pub, name, cl); if (res < 0) { fprintf(stderr, "Failed to register interest (res == %d)\n", res); return(1); } // Get our default keys -- Why do we have to do all this work?? // Borrowed from ccn_client.c struct ccn_signing_params name_sp = CCN_SIGNING_PARAMS_INIT; struct ccn_signing_params p = CCN_SIGNING_PARAMS_INIT; struct ccn_keystore *keystore = NULL; struct ccn_charbuf *timestamp = NULL; struct ccn_charbuf *finalblockid = NULL; struct ccn_charbuf *keylocator = NULL; unsigned char* public_key_digest = NULL; size_t public_key_digest_length = 0; res = ccn_chk_signing_params(ccn_pub, &name_sp, &p, ×tamp, &finalblockid, &keylocator); if (res < 0) return(res); // For this test, use our default signing keys get_default_keys(ccn_pub, &p, &keystore, &public_key, &public_key_digest, &public_key_digest_length, &private_key); // We'll need a KeyLocator for our ContentObject // So continue borrowed code /* Construct a key locator containing the key itself */ build_keylocator_from_key(&keylocator, public_key); // And a SignedInfo too struct ccn_charbuf *signed_info = ccn_charbuf_create(); res = ccn_signed_info_create(signed_info, public_key_digest, public_key_digest_length, timestamp, p.type, p.freshness, 0, /* FinalBlockID is optional */ keylocator); // * Test using interests for a name that has one more component than our registered prefix // This is more representative of real apps... // 20-May-2011 ccn_name_append_str(name, "some stuff in a name component"); ccn_name_append_nonce(name); ccn_name_append_nonce(name); // Sign the interest struct ccn_charbuf *name_signed = ccn_charbuf_create(); sign_interest(name_signed, name, signed_info, NULL /* default digest alg */, private_key); // Express the signed interest from a different ccn handle so we get the packet res = ccn_express_interest(ccn_rec, name_signed, cl, NULL); // TODO: AnswerOriginKind could limit to signed interest? outstanding_interests++; // Express an interest with an incorrect namespace struct ccn_charbuf *name_signed_copy = ccn_charbuf_create(); ccn_charbuf_append_charbuf(name_signed_copy, name_signed); size_t k = name->length + 10; // Seek into the namespace part of the buffer name_signed_copy->buf[k] = name_signed_copy->buf[k] + 1; res = ccn_express_interest(ccn_rec, name_signed_copy, cl, NULL); // TODO: AnswerOriginKind could limit to signed interest? outstanding_interests++; // Express an interest with bogus signature name_signed_copy = ccn_charbuf_create(); ccn_charbuf_append_charbuf(name_signed_copy, name_signed); k = name->length + 30; // Seek into the signature part of the buffer name_signed_copy->buf[k] = name_signed_copy->buf[k] + 1; res = ccn_express_interest(ccn_rec, name_signed_copy, cl, NULL); // TODO: AnswerOriginKind could limit to signed interest? outstanding_interests++; if (res < 0) { fprintf(stderr, "Error expressing interest (res == %d)\n", res); } cl = NULL; // freed by ccn? while(!complete && outstanding_interests>0) { // Not sure how to handle two ccn_runs? ccn_run(ccn_rec, 100); /* stop if we run dry for .1 sec */ ccn_run(ccn_pub, 100); /* stop if we run dry for .1 sec */ fflush(stdout); } ccn_charbuf_destroy(×tamp); ccn_charbuf_destroy(&keylocator); ccn_charbuf_destroy(&finalblockid); ccn_charbuf_destroy(&signed_info); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&name_signed); ccn_charbuf_destroy(&name_signed_copy); ccn_destroy(&ccn_pub); ccn_destroy(&ccn_rec); fflush(stderr); return(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); }