From 0b404b02603ec914788fe2e1afebac12ba8aa7df Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Thu, 24 Oct 2013 12:31:35 +1030 Subject: [PATCH] Implement id list command --- commandline.c | 121 +++++++++++++++++++++++++++++++++++++++----------- keyring.c | 2 +- mdp_client.h | 19 ++++++-- overlay_mdp.c | 58 +++++++++++++++++++++++- tests/keyring | 105 +++++++++++++++++++++++++++---------------- 5 files changed, 237 insertions(+), 68 deletions(-) diff --git a/commandline.c b/commandline.c index 39a01c10..dd758fc0 100644 --- a/commandline.c +++ b/commandline.c @@ -2097,6 +2097,24 @@ static int app_keyring_set_tag(const struct cli_parsed *parsed, struct cli_conte return r; } +ssize_t mdp_poll_recv(int mdp_sock, time_ms_t timeout, struct mdp_header *rev_header, unsigned char *payload, size_t buffer_size) +{ + time_ms_t now = gettime_ms(); + if (now>timeout) + return -2; + int p=mdp_poll(mdp_sock, timeout - now); + if (p<0) + return WHY_perror("mdp_poll"); + if (p==0) + return -2; + ssize_t len = mdp_recv(mdp_sock, rev_header, payload, buffer_size); + if (len<0) + return WHY_perror("mdp_recv"); + if (rev_header->flags & MDP_FLAG_ERROR) + return WHY("Operation failed, check the log for more information"); + return len; +} + static int handle_pins(const struct cli_parsed *parsed, struct cli_context *context, int revoke) { const char *pin, *sid_hex; @@ -2111,8 +2129,8 @@ static int handle_pins(const struct cli_parsed *parsed, struct cli_context *cont int mdp_sock = mdp_socket(); set_nonblock(mdp_sock); - unsigned char payload[1200]; - struct mdp_identity_request *request = (struct mdp_identity_request *)payload; + unsigned char request_payload[1200]; + struct mdp_identity_request *request = (struct mdp_identity_request *)request_payload; if (revoke){ request->action=ACTION_LOCK; @@ -2124,50 +2142,39 @@ static int handle_pins(const struct cli_parsed *parsed, struct cli_context *cont if (pin && *pin){ request->type=TYPE_PIN; int pin_len = strlen(pin)+1; - if (pin_len+len > sizeof(payload)) + if (pin_len+len > sizeof(request_payload)) return WHY("Supplied pin is too long"); - bcopy(pin, &payload[len], pin_len); + bcopy(pin, &request_payload[len], pin_len); len+=pin_len; }else if(sid_hex && *sid_hex){ request->type=TYPE_SID; sid_t sid; if (str_to_sid_t(&sid, sid_hex) == -1) return WHY("str_to_sid_t() failed"); - bcopy(sid.binary, &payload[len], sizeof(sid)); + bcopy(sid.binary, &request_payload[len], sizeof(sid)); len+=sizeof(sid); } - if (!mdp_send(mdp_sock, &header, payload, len)){ + if (!mdp_send(mdp_sock, &header, request_payload, len)){ WHY_perror("mdp_send"); goto end; } time_ms_t timeout=gettime_ms()+500; while(1){ - time_ms_t now = gettime_ms(); - if (now>timeout) + struct mdp_header rev_header; + unsigned char response_payload[1600]; + ssize_t len = mdp_poll_recv(mdp_sock, timeout, &rev_header, response_payload, sizeof(response_payload)); + if (len==-1) break; - int p=mdp_poll(mdp_sock, timeout - now); - if (p<0){ - WHY_perror("mdp_poll"); - break; - } - if (p==0){ + if (len==-2){ WHYF("Timeout while waiting for response"); break; } - struct mdp_header rev_header; - unsigned char payload[1600]; - ssize_t len = mdp_recv(mdp_sock, &rev_header, payload, sizeof(payload)); - if (len<0){ - WHY_perror("mdp_recv"); - continue; - } - if (rev_header.flags & MDP_FLAG_OK) + if (rev_header.flags & MDP_FLAG_OK){ ret=0; - if (rev_header.flags & MDP_FLAG_ERROR) - WHY("Operation failed, check the log for more information"); - break; + break; + } } end: mdp_close(mdp_sock); @@ -2184,6 +2191,68 @@ int app_id_pin(const struct cli_parsed *parsed, struct cli_context *context) return handle_pins(parsed, context, 0); } +int app_id_list(const struct cli_parsed *parsed, struct cli_context *context) +{ + const char *tag, *value; + if (cli_arg(parsed, "tag", &tag, NULL, "") == -1 || + cli_arg(parsed, "value", &value, NULL, "") == -1 ) + return -1; + + int ret=-1; + struct mdp_header header={ + .remote.port=MDP_SEARCH_IDS, + }; + int mdp_sock = mdp_socket(); + set_nonblock(mdp_sock); + + unsigned char request_payload[1200]; + size_t len=0; + + if (tag && *tag){ + size_t value_len=0; + if (value && *value) + value_len = strlen(value); + len = sizeof(request_payload); + if (keyring_pack_tag(request_payload, &len, tag, (unsigned char*)value, value_len)) + goto end; + } + + if (!mdp_send(mdp_sock, &header, request_payload, len)){ + WHY_perror("mdp_send"); + goto end; + } + + time_ms_t timeout=gettime_ms()+500; + while(1){ + struct mdp_header rev_header; + unsigned char response_payload[1600]; + ssize_t len = mdp_poll_recv(mdp_sock, timeout, &rev_header, response_payload, sizeof(response_payload)); + DEBUGF("mdp_poll_recv = %zd", len); + if (len==-1) + break; + if (len==-2){ + WHYF("Timeout while waiting for response"); + break; + } + + if (len>=SID_SIZE){ + sid_t *id = (sid_t*)response_payload; + cli_field_name(context, "sid", ":"); + cli_put_hexvalue(context, id->binary, sizeof(sid_t), "\n"); + // TODO receive and decode other details about this identity + } + + if (rev_header.flags & MDP_FLAG_OK){ + ret=0; + break; + } + } + +end: + mdp_close(mdp_sock); + return ret; +} + int app_id_self(const struct cli_parsed *parsed, struct cli_context *context) { int mdp_sockfd; @@ -2739,6 +2808,8 @@ struct cli_schema command_line_options[]={ "Set the DID for the specified SID (must supply PIN to unlock the SID record in the keyring)"}, {app_keyring_set_tag,{"keyring", "set","tag" KEYRING_PIN_OPTIONS,"","","",NULL}, 0, "Set a named tag for the specified SID (must supply PIN to unlock the SID record in the keyring)"}, + {app_id_list, {"id", "list", "[]", "[]", NULL}, 0, + "Search unlocked identities based on an optional tag and value"}, {app_id_self,{"id","self|peers|allpeers",NULL}, 0, "Return identity(s) as URIs of own node, or of known routable peers, or all known peers"}, {app_id_pin, {"id", "enter", "pin", "", NULL}, 0, diff --git a/keyring.c b/keyring.c index f64cab09..ca558a95 100644 --- a/keyring.c +++ b/keyring.c @@ -1496,7 +1496,7 @@ int keyring_find_did(const keyring_file *k, int *cn, int *in, int *kp, const cha int keyring_unpack_tag(const unsigned char *packed, size_t packed_len, const char **name, const unsigned char **value, size_t *length) { size_t i; - for (i=0;icontexts[cn]->identities[in]; + unsigned char reply_payload[1200]; + int ofs=0; + + bcopy(id->subscriber->sid.binary, &reply_payload[ofs], sizeof(id->subscriber->sid)); + ofs+=sizeof(id->subscriber->sid); + + // TODO return other details of this identity + + mdp_reply2(client, header, 0, reply_payload, ofs); + kp++; + } + mdp_reply_ok(client, header); + return 0; +} + static void mdp_poll2(struct sched_ent *alarm) { if (alarm->poll.revents & POLLIN) { @@ -1049,7 +1099,7 @@ static void mdp_poll2(struct sched_ent *alarm) ssize_t len = recvwithttl(alarm->poll.fd, buffer, sizeof(buffer), &ttl, (struct sockaddr *)&addr, &client.addrlen); - if (len<=sizeof(struct mdp_header)){ + if (len