Esempio n. 1
0
int path_match(path_t p1, path_t p2)
{
  if(!p1 || !p2) return 0;
  if(p1 == p2) return 1;
  if(util_cmp(p1->type,p2->type) != 0) return 0;
  if(strstr(p1->type,"ipv"))
  {
    if(util_cmp(p1->ip, p2->ip) == 0 && p1->port == p2->port) return 1;
  }else{
    if(util_cmp(p1->id, p2->id) == 0) return 1;
  }
  return 0;
}
Esempio n. 2
0
int main(void)
{
  switch_t s;
  chan_t c;
  packet_t p;
  path_t in;
  int sock;

  crypt_init();
  s = switch_new(0);

  if(util_loadjson(s) != 0 || (sock = util_server(0,1000)) <= 0)
  {
    printf("failed to startup %s or %s\n", strerror(errno), crypt_err());
    return -1;
  }

  printf("loaded hashname %s\n",s->id->hexname);

  // create/send a ping packet  
  c = chan_new(s, bucket_get(s->seeds, 0), "link", 0);
  p = chan_packet(c);
  chan_send(c, p);
  util_sendall(s,sock);

  in = path_new("ipv4");
  while(util_readone(s, sock, in) == 0)
  {
    switch_loop(s);

    while((c = switch_pop(s)))
    {
      printf("channel active %d %s %s\n",c->state,c->hexid,c->to->hexname);
      if(util_cmp(c->type,"connect") == 0) ext_connect(c);
      if(util_cmp(c->type,"link") == 0) ext_link(c);
      if(util_cmp(c->type,"path") == 0) ext_path(c);
      while((p = chan_pop(c)))
      {
        printf("unhandled channel packet %.*s\n", p->json_len, p->json);      
        packet_free(p);
      }
      if(c->state == ENDED) chan_free(c);
    }

    util_sendall(s,sock);
  }

  perror("exiting");
  return 0;
}
Esempio n. 3
0
int main(int argc, char **argv)
{
  hashname_t hn;
  
  fail_unless(e3x_init(NULL) == 0);

  hn = hashname_vchar("uvabrvfqacyvgcu8kbrrmk9apjbvgvn2wjechqr3vf9c1zm3hv7g");
  fail_unless(!hn);

  hn = hashname_vchar("jvdoio6kjvf3yqnxfvck43twaibbg4pmb7y3mqnvxafb26rqllwa");
  fail_unless(hn);
  fail_unless(strlen(hashname_char(hn)) == 52);
  hashname_free(hn);

  // create intermediate fixture
  lob_t im = lob_new();
  lob_set(im,"1a","ym7p66flpzyncnwkzxv2qk5dtosgnnstgfhw6xj2wvbvm7oz5oaq");
  lob_set(im,"3a","bmxelsxgecormqjlnati6chxqua7wzipxliw5le35ifwxlge2zva");
  hn = hashname_vkey(im, 0);
  fail_unless(hn);
  fail_unless(util_cmp(hashname_char(hn),"jvdoio6kjvf3yqnxfvck43twaibbg4pmb7y3mqnvxafb26rqllwa") == 0);

  lob_t keys = lob_new();
  lob_set(keys,"1a","vgjz3yjb6cevxjomdleilmzasbj6lcc7");
  lob_set(keys,"3a","hp6yglmmqwcbw5hno37uauh6fn6dx5oj7s5vtapaifrur2jv6zha");
  hn = hashname_vkeys(keys);
  fail_unless(hn);
  fail_unless(util_cmp(hashname_char(hn),"jvdoio6kjvf3yqnxfvck43twaibbg4pmb7y3mqnvxafb26rqllwa") == 0);

  fail_unless(hashname_id(NULL,NULL) == 0);
  fail_unless(hashname_id(im,keys) == 0x3a);
  lob_t test = lob_new();
  lob_set(test,"1a","test");
  lob_set(test,"2a","test");
  fail_unless(hashname_id(keys,test) == 0x1a);
  
  // check short utils
  hn = hashname_schar("uvabrvfq");
  fail_unless(hn);
  fail_unless(hashname_isshort(hn));
  fail_unless(util_cmp(hashname_short(hn),"uvabrvfq") == 0);

  return 0;
}
Esempio n. 4
0
File: tcp4.c Progetto: fd/telehash-c
pipe_t tcp4_path(link_t link, lob_t path)
{
  net_tcp4_t net;
  char *ip;
  int port;

  // just sanity check the path first
  if(!link || !path) return NULL;
  if(!(net = xht_get(link->mesh->index, MUID))) return NULL;
  if(util_cmp("tcp4",lob_get(path,"type"))) return NULL;
  if(!(ip = lob_get(path,"ip"))) return LOG("missing ip");
  if((port = lob_get_int(path,"port")) <= 0) return LOG("missing port");
  return tcp4_pipe(net, ip, port);
}
Esempio n. 5
0
// create our generic callback linked list entry
on_t on_get(mesh_t mesh, char *id)
{
  on_t on;
  
  if(!mesh || !id) return LOG("bad args");
  for(on = mesh->on; on; on = on->next) if(util_cmp(on->id,id) == 0) return on;

  if(!(on = malloc(sizeof (struct on_struct)))) return LOG("OOM");
  memset(on, 0, sizeof(struct on_struct));
  on->id = strdup(id);
  on->next = mesh->on;
  mesh->on = on;
  return on;
}
Esempio n. 6
0
// get paths from host and query
lob_t util_uri_paths(lob_t uri)
{
  uint32_t i;
  uint16_t port;
  uint8_t *buf;
  size_t len;
  char *key, *value;
  lob_t paths, query = lob_linked(uri);
  if(!query) return NULL;
  paths = NULL;
  
  // gen paths from host/port
  if((port = lob_get_uint(uri,"port")))
  {
    key = lob_get(uri,"host");
    paths = lob_chain(paths);
    lob_set(paths,"type","upd4");
    lob_set(paths,"ip",key);
    lob_set_uint(paths,"port",port);
    paths = lob_chain(paths);
    lob_set(paths,"type","tcp4");
    lob_set(paths,"ip",key);
    lob_set_uint(paths,"port",port);
  }

  // loop through all keyval pairs to find paths
  buf = NULL;
  for(i=0;(key = lob_get_index(query,i));i+=2)
  {
    value = lob_get_index(query,i+1);
    if(util_cmp(key,"paths") != 0 || !value) continue;
    len = base32_decode_floor(strlen(value));
    buf = util_reallocf(buf,len);
    if(!buf) continue;
    if(base32_decode(value,strlen(value),buf,len) < len) continue;
    paths = lob_link(lob_parse(buf,len), paths);
  }
  free(buf);
  
  return paths;
}
Esempio n. 7
0
// create hashname from intermediate values as hex/base32 key/value pairs
hashname_t hashname_key(lob_t key, uint8_t csid)
{
  unsigned int i, start;
  uint8_t hash[64];
  char *id, *value, hexid[3];
  hashname_t hn = NULL;
  if(!key) return LOG("invalid args");
  util_hex(&csid, 1, hexid);

  // get in sorted order
  lob_sort(key);

  // loop through all keys rolling up
  for(i=0;(id = lob_get_index(key,i));i+=2)
  {
    value = lob_get_index(key,i+1);
    if(strlen(id) != 2 || !util_ishex(id,2) || !value) continue; // skip non-id keys
    
    // hash the id
    util_unhex(id,2,hash+32);
    start = (i == 0) ? 32 : 0; // only first one excludes previous rollup
    e3x_hash(hash+start,(32-start)+1,hash); // hash in place

    // get the value from the body if matching csid arg
    if(util_cmp(id, hexid) == 0)
    {
      if(key->body_len == 0) return LOG("missing key body");
      // hash the body
      e3x_hash(key->body,key->body_len,hash+32);
    }else{
      if(strlen(value) != 52) return LOG("invalid value %s %d",value,strlen(value));
      if(base32_decode(value,52,hash+32,32) != 32) return LOG("base32 decode failed %s",value);
    }
    e3x_hash(hash,64,hash);
  }
  if(!i || i % 2 != 0) return LOG("invalid keys %d",i);
  
  hn = hashname_new(hash);
  return hn;
}
Esempio n. 8
0
// intermediate hashes in the json, if id is given it is attached as BODY instead
lob_t hashname_im(lob_t keys, uint8_t id)
{
  uint32_t i;
  size_t len;
  uint8_t *buf, hash[32];
  char *key, *value, hex[3];
  lob_t im;

  if(!keys) return LOG("bad args");

  // loop through all keys and create intermediates
  im = lob_new();
  buf = NULL;
  util_hex(&id,1,hex);
  for(i=0;(key = lob_get_index(keys,i));i+=2)
  {
    value = lob_get_index(keys,i+1);
    if(strlen(key) != 2 || !value) continue; // skip non-csid keys
    len = base32_decode_floor(strlen(value));
    // save to body raw or as a base32 intermediate value
    if(id && util_cmp(hex,key) == 0)
    {
      lob_body(im,NULL,len);
      if(base32_decode(value,strlen(value),im->body,len) != len) continue;
      lob_set_raw(im,key,0,"true",4);
    }else{
      buf = util_reallocf(buf,len);
      if(!buf) return lob_free(im);
      if(base32_decode(value,strlen(value),buf,len) != len) continue;
      // store the hash intermediate value
      e3x_hash(buf,len,hash);
      lob_set_base32(im,key,hash,32);
    }
  }
  if(buf) free(buf);
  return im;
}
Esempio n. 9
0
char *path_json(path_t p)
{
  int len;
  char *json;
  
  if(!p) return NULL;
  if(p->json) free(p->json);
  len = 12+strlen(p->type);
  if(p->ip) len += strlen(p->ip)+8+13;
  if(p->id) len += strlen(p->id)+8;
  len = len * 2; // double for any worst-case escaping
  if(!(p->json = malloc(len))) return NULL;
  json = p->json;
  memset(json,0,len);
  sprintf(json, "{\"type\":%c%s%c",'"',p->type,'"');
  if(strstr("ipv4 ipv6", p->type))
  {
    if(*p->ip) sprintf(json+strlen(json), ",\"ip\":%c%s%c",'"',p->ip,'"');
    if(p->port) sprintf(json+strlen(json), ",\"port\":%hu", p->port);
  }
  if(p->id)
  {
    if(util_cmp("http",p->type)==0) strcpy(json+strlen(json), ",\"http\":\"");
    else strcpy(json+strlen(json), ",\"id\":\"");
    len = 0;
    while(p->id[len])
    {
      if(p->id[len] == '"') json[strlen(json)] = '\\';
      json[strlen(json)] = p->id[len];
      len++;
    }
    strcpy(json+strlen(json), "\"");
  }
  json[strlen(json)] = '}';
  return p->json;
}
Esempio n. 10
0
int main(int argc, char **argv)
{
  lob_t packet;
  packet = lob_new();
  fail_unless(packet);
  lob_free(packet);

  uint8_t buf[1024];
  char *hex = "001d7b2274797065223a2274657374222c22666f6f223a5b22626172225d7d616e792062696e61727921";
  uint8_t len = strlen(hex)/2;
  util_unhex(hex,strlen(hex),buf);
  packet = lob_parse(buf,len);
  fail_unless(packet);
  fail_unless(lob_len(packet));
  fail_unless(packet->head_len == 29);
  fail_unless(packet->body_len == 11);
  fail_unless(util_cmp(lob_get(packet,"type"),"test") == 0);
  fail_unless(util_cmp(lob_get(packet,"foo"),"[\"bar\"]") == 0);
  
  lob_free(packet);
  packet = lob_new();
  lob_set_base32(packet,"32",buf,len);
  fail_unless(lob_get(packet,"32"));
  fail_unless(strlen(lob_get(packet,"32")) == (base32_encode_length(len)-1));
  lob_t bin = lob_get_base32(packet,"32");
  fail_unless(bin);
  fail_unless(bin->body_len == len);

  lob_set(packet,"key","value");
  fail_unless(lob_keys(packet) == 2);

  // test sorting
  lob_set(packet,"zz","value");
  lob_set(packet,"a","value");
  lob_set(packet,"z","value");
  lob_sort(packet);
  fail_unless(util_cmp(lob_get_index(packet,0),"32") == 0);
  fail_unless(util_cmp(lob_get_index(packet,2),"a") == 0);
  fail_unless(util_cmp(lob_get_index(packet,4),"key") == 0);
  fail_unless(util_cmp(lob_get_index(packet,6),"z") == 0);
  fail_unless(util_cmp(lob_get_index(packet,8),"zz") == 0);
  lob_free(packet);
  
  // minimal comparison test
  lob_t a = lob_new();
  lob_set(a,"foo","bar");
  lob_t b = lob_new();
  lob_set(b,"foo","bar");
  fail_unless(lob_cmp(a,b) == 0);
  lob_set(b,"bar","foo");
  fail_unless(lob_cmp(a,b) != 0);

  // lots of basic list testing
  lob_t list = lob_new();
  lob_t item = lob_new();
  fail_unless(lob_push(list,item));
  fail_unless(lob_pop(list) == item);
  list = item->next;
  fail_unless((list = lob_unshift(list,item)));
  fail_unless(lob_shift(list) == item);
  list = item->next;
  fail_unless(lob_push(list,item));
  fail_unless(list->next == item);
  lob_t insert = lob_new();
  fail_unless(lob_insert(list,list,insert));
  fail_unless(list->next == insert);
  fail_unless(insert->next == item);
  fail_unless(lob_splice(list,insert));
  fail_unless(list->next == item);

  lob_t array = lob_array(list);
  fail_unless(array);
  fail_unless(util_cmp(lob_json(array),"[,]") == 0);

  fail_unless(lob_freeall(list) == NULL);

  // simple index testing
  lob_t index = lob_new();
  lob_t c1 = lob_new();
  lob_set(c1,"id","c1");
  lob_push(index,c1);
  lob_t c2 = lob_new();
  lob_set(c2,"id","c2");
  lob_push(index,c2);
  fail_unless(lob_match(index,"id","c1") == c1);
  fail_unless(lob_match(index,"id","c2") == c2);
  
  float f = 42.42;
  lob_t ft = lob_new();
  lob_head(ft,(uint8_t*)"{\"foo\":42.42}",13);
  fail_unless(lob_get_float(ft,"foo") == f);
  lob_set_float(ft,"bar2",f,2);
  fail_unless(lob_get_float(ft,"bar2") == f);
  lob_set_float(ft,"bar1",f,1);
  fail_unless(lob_get_cmp(ft,"bar1","42.4") == 0);
  lob_set_float(ft,"bar0",f,0);
  fail_unless(lob_get_int(ft,"bar0") == 42);
  LOG("floats %s",lob_json(ft));

  return 0;
}
Esempio n. 11
0
// process any unencrypted handshake packet
link_t mesh_receive_handshake(mesh_t mesh, lob_t handshake, pipe_t pipe)
{
  uint32_t now;
  hashname_t from;
  link_t link;

  if(!mesh || !handshake) return LOG("bad args");
  if(!lob_get(handshake,"id"))
  {
    LOG("bad handshake, no id: %s",lob_json(handshake));
    lob_free(handshake);
    return NULL;
  }
  now = util_sys_seconds();
  
  // normalize handshake
  handshake->id = now; // save when we cached it
  if(!lob_get(handshake,"type")) lob_set(handshake,"type","link"); // default to link type
  if(!lob_get_uint(handshake,"at")) lob_set_uint(handshake,"at",now); // require an at
  LOG("handshake at %d id %s",now,lob_get(handshake,"id"));
  
  // validate/extend link handshakes immediately
  if(util_cmp(lob_get(handshake,"type"),"link") == 0)
  {
    // get the csid
    uint8_t csid = 0;
    lob_t outer;
    if((outer = lob_linked(handshake)))
    {
      csid = outer->head[0];
    }else if(lob_get(handshake,"csid")){
      util_unhex(lob_get(handshake,"csid"),2,&csid);
    }
    if(!csid)
    {
      LOG("bad link handshake, no csid: %s",lob_json(handshake));
      lob_free(handshake);
      return NULL;
    }
    char hexid[3] = {0};
    util_hex(&csid, 1, hexid);
      
    // get attached hashname
    lob_t tmp = lob_parse(handshake->body, handshake->body_len);
    from = hashname_vkey(tmp, csid);
    if(!from)
    {
      LOG("bad link handshake, no hashname: %s",lob_json(handshake));
      lob_free(tmp);
      lob_free(handshake);
      return NULL;
    }
    lob_set(handshake,"csid",hexid);
    lob_set(handshake,"hashname",hashname_char(from));
    lob_set_raw(handshake,hexid,2,"true",4); // intermediate format
    lob_body(handshake, tmp->body, tmp->body_len); // re-attach as raw key
    lob_free(tmp);

    // short-cut, if it's a key from an existing link, pass it on
    // TODO: using mesh_linked here is a stack issue during loopback peer test!
    if((link = mesh_linkid(mesh,from))) return link_receive_handshake(link, handshake, pipe);
    LOG("no link found for handshake from %s",hashname_char(from));

    // extend the key json to make it compatible w/ normal patterns
    tmp = lob_new();
    lob_set_base32(tmp,hexid,handshake->body,handshake->body_len);
    lob_set_raw(handshake,"keys",0,(char*)tmp->head,tmp->head_len);
    lob_free(tmp);
    // add the path if one
    if(pipe && pipe->path)
    {
      char *paths = malloc(pipe->path->head_len+3);
      sprintf(paths,"[%.*s]",(int)pipe->path->head_len,(char*)pipe->path->head);
      lob_set_raw(handshake,"paths",0,paths,pipe->path->head_len+2);
      free(paths);
    }
  }

  // always add to the front of the cached list if needed in the future
  mesh->cached = lob_unshift(mesh->cached, handshake);

  // tell anyone listening about the newly discovered handshake
  mesh_discover(mesh, handshake, pipe);
  
  return NULL;
}
Esempio n. 12
0
int main(int argc, char **argv)
{
	lob_t id;
	mesh_t mesh;
  lob_t opts = lob_new();
  fail_unless(e3x_init(opts) == 0);
  fail_unless(!e3x_err());

  // need cs1a support to continue testing
  e3x_cipher_t cs = e3x_cipher_set(0x1a,NULL);
  if(!cs) return 0;

  cs = e3x_cipher_set(0,"1a");
  fail_unless(cs);
  fail_unless(cs->id == CS_1a);
  
  uint8_t buf[32];
  fail_unless(e3x_rand(buf,32));

  char hex[65];
  util_hex(e3x_hash((uint8_t*)"foo",3,buf),32,hex);
  fail_unless(strcmp(hex,"2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae") == 0);

  id = util_fjson("/Users/chrigel/.id.json");
  if(!id) return -1;

  lob_t secrets = lob_get_json(id,"secrets");
  fail_unless(secrets);
  fail_unless(lob_get(secrets,"1a"));
  lob_t keys = lob_get_json(id,"keys");
  fail_unless(keys);
  fail_unless(lob_get(keys,"1a"));
  LOG("generated key %s secret %s",lob_get(keys,"1a"),lob_get(secrets,"1a"));

  local_t localA = cs->local_new(keys,secrets);
  fail_unless(localA);

  remote_t remoteA = cs->remote_new(lob_get_base32(keys,"1a"), NULL);
  fail_unless(remoteA);

  // create another to start testing real packets
  lob_t secretsB = e3x_generate();
  fail_unless(lob_linked(secretsB));
  printf("XX %s\n",lob_json(lob_linked(secretsB)));
  local_t localB = cs->local_new(lob_linked(secretsB),secretsB);
  fail_unless(localB);
  remote_t remoteB = cs->remote_new(lob_get_base32(lob_linked(secretsB),"1a"), NULL);
  fail_unless(remoteB);

  // generate a message
  lob_t messageAB = lob_new();
  lob_set_int(messageAB,"a",42);
  lob_t outerAB = cs->remote_encrypt(remoteB,localA,messageAB);
  fail_unless(outerAB);
  fail_unless(lob_len(outerAB) == 42);

  // decrypt and verify it
  lob_t innerAB = cs->local_decrypt(localB,outerAB);
  fail_unless(innerAB);
  fail_unless(lob_get_int(innerAB,"a") == 42);
  fail_unless(cs->remote_verify(remoteA,localB,outerAB) == 0);

  ephemeral_t ephemBA = cs->ephemeral_new(remoteA,outerAB);
  fail_unless(ephemBA);
  
  lob_t channelBA = lob_new();
  lob_set(channelBA,"type","foo");
  lob_t couterBA = cs->ephemeral_encrypt(ephemBA,channelBA);
  fail_unless(couterBA);
  fail_unless(lob_len(couterBA) == 42);

  lob_t outerBA = cs->remote_encrypt(remoteA,localB,messageAB);
  fail_unless(outerBA);
  ephemeral_t ephemAB = cs->ephemeral_new(remoteB,outerBA);
  fail_unless(ephemAB);

  lob_t cinnerAB = cs->ephemeral_decrypt(ephemAB,couterBA);
  fail_unless(cinnerAB);
  fail_unless(util_cmp(lob_get(cinnerAB,"type"),"foo") == 0);

  return 0;
}