Example #1
0
// verify a signature against a public sas key.
int crypto_verify_signature(unsigned char *sas_key, 
			    unsigned char *content, int content_len, 
			    unsigned char *signature_block, int signature_len)
{
  IN();
  
  if (signature_len!=SIGNATURE_BYTES)
    RETURN(WHY("Invalid signature length"));
  
  /* reconstitute signed message by putting hash at end of signature */
  unsigned char reassembled[signature_len + content_len];
  bcopy(signature_block, reassembled, signature_len);
  bcopy(content, &reassembled[signature_len], content_len);
  
  /* verify signature.
   Note that crypto_sign_open requires m to be as large as signature, even
   though it will not need the whole length eventually -- it does use the 
   full length and will overwrite the end of a short buffer. */
  unsigned char message[sizeof(reassembled)+64];
  unsigned long long  mlen=0;
  int result
  =crypto_sign_edwards25519sha512batch_open(message,&mlen,
					    reassembled,sizeof(reassembled),
					    sas_key);
  
  if (result)
    RETURN(WHY("Signature verification failed"));
  RETURN(0);
}
Example #2
0
int single_packet_encapsulation(struct overlay_buffer *b, struct overlay_frame *frame){
  overlay_interface *interface=frame->interface;
  int interface_number = interface - overlay_interfaces;
  struct decode_context context;
  bzero(&context, sizeof(struct decode_context));
  
  if (frame->source_full)
    my_subscriber->send_full=1;
  int seq = interface->sequence_number++;
  if (overlay_packet_init_header(frame->packet_version, ENCAP_SINGLE, &context, b, NULL, 0, interface_number, seq))
    return WHY("Failed to init header");

  struct broadcast *broadcast=NULL;
  if ((!frame->destination) && !is_all_matching(frame->broadcast_id.id,BROADCAST_LEN,0))
    broadcast = &frame->broadcast_id;

  if (overlay_frame_build_header(frame->packet_version, &context, b,
				 frame->queue, frame->type, 
				 frame->modifiers, frame->ttl, frame->mdp_sequence & 0xFF,
				 broadcast, frame->next_hop, 
				 frame->destination, frame->source))
    return WHY("Failed to build header");
  
  if (ob_append_buffer(b, frame->payload))
    return WHY("Failed to append payload");
  
  return 0;
}
Example #3
0
int extractRequest(unsigned char *packet,int *packet_ofs,int packet_len,
		   int *itemId,int *instance,unsigned char *value,
		   int *start_offset,int *bytes,int *flags)
{
  if (*packet_ofs<0||(*packet_ofs)+6>=packet_len) 
    return WHY("mal-formed request packet (packet too short/bad offset)");

  *itemId=packet[(*packet_ofs)++];

  if ((*itemId)&0x80) *instance=packet[(*packet_ofs)++]; else *instance=0;
  if (*instance==0xff) *instance=-1;

  *start_offset=packet[(*packet_ofs)++]<<8;
  *start_offset|=packet[(*packet_ofs)++];

  *bytes=packet[(*packet_ofs)++]<<8;
  *bytes|=packet[(*packet_ofs)++];

  *flags=packet[(*packet_ofs)++];
  if (debug&DEBUG_PACKETFORMATS) DEBUGF("Write flags = 0x%02x",*flags);

  if (*packet_ofs<0||(*packet_ofs)+(*bytes)>=packet_len)
    {
      if (debug&DEBUG_PACKETFORMATS) DEBUGF("Packet offset is %d, length is %d, and asked for %d bytes",*packet_ofs,packet_len,*bytes);
      return WHY("mal-formed request packet (too short for claimed data)");
    }

  bcopy(&packet[*packet_ofs],value,*bytes);
  (*packet_ofs)+=*bytes;

  return 0;
}
Example #4
0
int unpackageVariableSegment(unsigned char *data,int dlen,int flags,struct response *r)
{
  r->response_len=0;
  if (dlen<7) return WHY("unpackageVariableSegment() fed insufficient data");
  
  r->var_id=data[r->response_len++];
  if (r->var_id&0x80) r->var_instance=data[r->response_len++]; else r->var_instance=0;
  if (r->var_instance==0xff) r->var_instance=-1;

  r->value_len=data[r->response_len++]<<8;
  r->value_len|=data[r->response_len++];

  r->value_offset=data[r->response_len++]<<8;
  r->value_offset|=data[r->response_len++];

  r->value_bytes=data[r->response_len++]<<8;
  r->value_bytes|=data[r->response_len++];

  r->response=&data[r->response_len];

  r->response_len+=r->value_bytes;

  if (flags!=WITHOUTDATA)
    if (r->response_len>dlen) 
      return WHY("unpackageVariableSegment() fed insufficient or corrupt data");
  
  return 0;
}
Example #5
0
int prepareGateway(char *spec)
{
    if ((!strcasecmp(spec,"potato"))||(!strcasecmp(spec,"meshpotato"))||(!strcasecmp(spec,"mp"))||(!strcasecmp(spec,"mp1"))) {
        /* Setup for mesh potato */
        asterisk_extensions_conf="/etc/asterisk/gatewayextensions.conf";
        asterisk_binary="/usr/sbin/asterisk";
        temp_file="/var/dnatemp.out";
        cmd_file="/var/dnatemp.cmd";
        shell="/bin/sh";
        return 0;
    } else if ((!strcasecmp(spec,"android"))||(!strcasecmp(spec,"batphone"))) {
        /* Setup for android -- this is default, so don't change anything */
        return 0;
    } else if (!strncasecmp(spec,"custom:",7)) {
        char a[1024],b[1024],c[1024],d[1024],e[1024];
        if (sscanf(spec,"custom:%[^:]:%[^:]:%[^:]:%[^:]:%[^:]",a,b,c,d,e)!=5) return WHY("Invalid custom gateway specification");
        asterisk_extensions_conf=strdup(a);
        asterisk_binary=strdup(b);
        temp_file=strdup(c);
        cmd_file=strdup(d);
        shell=strdup(e);
        return 0;
    }
    else
        return WHY("Invalid gateway specification");
}
Example #6
0
int ob_makespace(overlay_buffer *b,int bytes)
{
  if (b->sizeLimit!=-1) {
    if (b->length+bytes>b->sizeLimit) {
      if (debug&DEBUG_PACKETFORMATS) WHY("Asked to make space beyond size limit");
      return -1; 
    }
  }
  if (b->length+bytes>=b->allocSize)
    {
      int newSize=b->length+bytes;
      if (newSize<64) newSize=64;
      if (newSize&63) newSize+=64-(newSize&63);
      if (newSize>1024) {
	if (newSize&1023) newSize+=1024-(newSize&1023);
      }
      if (newSize>65536) {
	if (newSize&65535) newSize+=65536-(newSize&65535);
      }
      unsigned char *r=realloc(b->bytes,newSize);
      if (!r) return WHY("realloc() failed");
      b->bytes=r;
      b->allocSize=newSize;
      return 0;
    }
  else
    return 0;
}
Example #7
0
int overlay_payload_enqueue(int q,overlay_frame *p)
{
  /* Add payload p to queue q.

     Queues get scanned from first to last, so we should append new entries
     on the end of the queue.

     Complain if there are too many frames in the queue.
  */

  if (q<0||q>=OQ_MAX) return WHY("Invalid queue specified");
  if (!p) return WHY("Cannot queue NULL");

  if (overlay_tx[q].length>=overlay_tx[q].maxLength) return WHY("Queue congested");
  
  overlay_frame *l=overlay_tx[q].last;
  if (l) l->next=p;
  p->prev=l;
  p->next=NULL;
  p->enqueued_at=overlay_gettime_ms();

  overlay_tx[q].last=p;
  if (!overlay_tx[q].first) overlay_tx[q].first=p;
  overlay_tx[q].length++;
  
  return 0;
}
Example #8
0
int rhizome_finish_sqlstatement(sqlite3_stmt *statement)
{
  /* Do actual insert, and abort if it fails */
  int dud=0;
  int r;
  r=sqlite3_step(statement);
  switch(r) {
  case SQLITE_DONE: case SQLITE_ROW: case SQLITE_OK:
    break;
  default:
    WHY("sqlite3_step() failed.");
    WHY(sqlite3_errmsg(rhizome_db));
    dud++;
    sqlite3_finalize(statement);
  }

  if ((!dud)&&((r=sqlite3_finalize(statement))!=SQLITE_OK)) {
    WHY("sqlite3_finalize() failed.");
    WHY(sqlite3_errmsg(rhizome_db));
    dud++;
  }

  if (dud)  return WHY("SQLite3 could not complete statement.");
  return 0;
}
Example #9
0
int packetOk(struct overlay_interface *interface, unsigned char *packet, size_t len,
	     unsigned char *transaction_id,int ttl,
	     struct sockaddr *recvaddr, size_t recvaddrlen,int parseP)
{
  if (len<HEADERFIELDS_LEN) return WHY("Packet is too short");

  if (packet[0]==0x41&&packet[1]==0x10) 
    {
      return packetOkDNA(packet,len,transaction_id,ttl,recvaddr,recvaddrlen,parseP);
    }

  if (packet[0]==0x4F&&packet[1]==0x10) 
    {
      if (interface!=NULL)
	{
	  return packetOkOverlay(interface,packet,len,transaction_id,ttl,
				 recvaddr,recvaddrlen,parseP);
	}
      else
	/* We ignore overlay mesh packets in simple server mode, which is indicated by interface==-1 */
	return WHY("Ignoring overlay mesh packet");
    }

  return WHY("Packet type not recognised.");
}
Example #10
0
int rhizome_manifest_check_file(rhizome_manifest *m_in)
{
  long long gotfile = 0;
  if (sqlite_exec_int64(&gotfile, "SELECT COUNT(*) FROM FILES WHERE ID='%s' and datavalid=1;", m_in->fileHexHash) != 1) {
    WHYF("Failed to count files");
    return 0;
  }
  if (gotfile) {
    DEBUGF("Skipping file checks for bundle, as file is already in the database");
    return 0;
  }

  /* Find out whether the payload is expected to be encrypted or not */
  m_in->payloadEncryption=rhizome_manifest_get_ll(m_in, "crypt");
  
  /* Check payload file is accessible and discover its length, then check that it matches
     the file size stored in the manifest */
  long long mfilesize = rhizome_manifest_get_ll(m_in, "filesize");
  m_in->fileLength = 0;
  if (m_in->dataFileName[0]) {
    struct stat stat;
    if (lstat(m_in->dataFileName,&stat) == -1) {
      if (errno != ENOENT || mfilesize != 0)
	return WHYF_perror("stat(%s)", m_in->dataFileName);
    } else {
      m_in->fileLength = stat.st_size;
    }
  }
  if (debug & DEBUG_RHIZOME)
    DEBUGF("filename=%s, fileLength=%lld", m_in->dataFileName, m_in->fileLength);
  if (mfilesize != -1 && mfilesize != m_in->fileLength) {
    WHYF("Manifest.filesize (%lld) != actual file size (%lld)", mfilesize, m_in->fileLength);
    return -1;
  }

  /* If payload is empty, ensure manifest has not file hash, otherwis compute the hash of the
     payload and check that it matches manifest. */
  const char *mhexhash = rhizome_manifest_get(m_in, "filehash", NULL, 0);
  if (m_in->fileLength != 0) {
    char hexhashbuf[RHIZOME_FILEHASH_STRLEN + 1];
    if (rhizome_hash_file(m_in,m_in->dataFileName, hexhashbuf))
      return WHY("Could not hash file.");
    memcpy(&m_in->fileHexHash[0], &hexhashbuf[0], sizeof hexhashbuf);
    m_in->fileHashedP = 1;
    if (!mhexhash) return WHY("manifest contains no file hash");
    if (mhexhash && strcmp(m_in->fileHexHash, mhexhash)) {
      WHYF("Manifest.filehash (%s) does not match payload hash (%s)", mhexhash, m_in->fileHexHash);
      return -1;
    }
  } else {
    if (mhexhash != NULL) {
      WHYF("Manifest.filehash (%s) should be absent for empty payload", mhexhash);
      return -1;
    }
  }

  return 0;
}
Example #11
0
int ob_limitsize(overlay_buffer *b,int bytes)
{
  if (!b) return WHY("Asked to limit size of NULL");
  if (b->length>bytes) return WHY("Length of data in buffer already exceeds size limit");
  if (b->checkpointLength>bytes) return WHY("Checkpointed length of data in buffer already exceeds size limit");
  if (bytes<0) return WHY("Cant limit buffer to a negative size");
  b->sizeLimit=bytes;
  return 0;
}
Example #12
0
int overlay_mdp_recv(overlay_mdp_frame *mdp, int port, int *ttl) 
{
  char mdp_socket_name[101];
  unsigned char recvaddrbuffer[1024];
  struct sockaddr *recvaddr=(struct sockaddr *)recvaddrbuffer;
  unsigned int recvaddrlen=sizeof(recvaddrbuffer);
  struct sockaddr_un *recvaddr_un;
  
  if (!FORM_SERVAL_INSTANCE_PATH(mdp_socket_name, "mdp.socket"))
    return WHY("Could not find mdp socket");
  mdp->packetTypeAndFlags=0;
  
  /* Check if reply available */
  set_nonblock(mdp_client_socket);
  ssize_t len = recvwithttl(mdp_client_socket,(unsigned char *)mdp, sizeof(overlay_mdp_frame),ttl,recvaddr,&recvaddrlen);
  set_block(mdp_client_socket);
  
  recvaddr_un=(struct sockaddr_un *)recvaddr;
  /* Null terminate received address so that the stat() call below can succeed */
  if (recvaddrlen<1024) recvaddrbuffer[recvaddrlen]=0;
  if (len>0) {
    /* Make sure recvaddr matches who we sent it to */
    if (strncmp(mdp_socket_name, recvaddr_un->sun_path, sizeof(recvaddr_un->sun_path))) {
      /* Okay, reply was PROBABLY not from the server, but on OSX if the path
       has a symlink in it, it is resolved in the reply path, but might not
       be in the request path (mdp_socket_name), thus we need to stat() and
       compare inode numbers etc */
      struct stat sb1,sb2;
      if (stat(mdp_socket_name,&sb1)) return WHY("stat(mdp_socket_name) failed, so could not verify that reply came from MDP server");
      if (stat(recvaddr_un->sun_path,&sb2)) return WHY("stat(ra->sun_path) failed, so could not verify that reply came from MDP server");
      if ((sb1.st_ino!=sb2.st_ino)||(sb1.st_dev!=sb2.st_dev))
	return WHY("Reply did not come from server");
    }
    
    // silently drop incoming packets for the wrong port number
    if (port>0 && port != mdp->in.dst.port){
      WARNF("Ignoring packet for port %d",mdp->in.dst.port);
      return -1;
    }
    
    int expected_len = overlay_mdp_relevant_bytes(mdp);
    
    if (len < expected_len){
      return WHYF("Expected packet length of %d, received only %lld bytes", expected_len, (long long) len);
    }
    
    /* Valid packet received */
    return 0;
  } else 
  /* no packet received */
    return -1;
  
}
Example #13
0
int op_free(struct overlay_frame *p)
{
  if (!p) return WHY("Asked to free NULL");
  if (p->prev&&p->prev->next==p) return WHY("p->prev->next still points here");
  if (p->next&&p->next->prev==p) return WHY("p->next->prev still points here");
  p->prev=NULL;
  p->next=NULL;
  if (p->payload) ob_free(p->payload);
  p->payload=NULL;
  free(p);
  return 0;
}
Example #14
0
unsigned int ob_get_int(overlay_buffer *b,int offset)
{
  if (!b) return WHY("b is NULL");
  if (offset<0) return WHY("passed illegal offset (<0)");
  if ((offset+sizeof(unsigned int))>b->length) return WHY("passed offset too large");

  // Some platforms require alignment
  if (((unsigned long long)&b->bytes[offset])&3) {
    unsigned char bb[4];
    bcopy(&b->bytes[offset],&bb[0],4);
    return ntohl(*(unsigned int *)&bb[0]);
  } else
    return ntohl(*((unsigned int *)&b->bytes[offset]));
}
Example #15
0
int overlay_route_make_neighbour(overlay_node *n)
{
  if (!n) return WHY("n is NULL");

  /* If it is already a neighbour, then return */
  if (n->neighbour_id) return 0;

  /* If address is local don't both making it a neighbour */
  if (overlay_address_is_local(n->sid)) return 0;

  /* It isn't yet a neighbour, so find or free a neighbour slot */
  /* slot 0 is reserved, so skip it */
  if (!overlay_neighbour_count) overlay_neighbour_count=1;
  if (overlay_neighbour_count<overlay_max_neighbours) {
    /* Use next free neighbour slot */
    n->neighbour_id=overlay_neighbour_count++;
  } else {
    /* Evict an old neighbour */
    int nid=1+random()%(overlay_max_neighbours-1);
    if (overlay_neighbours[nid].node) overlay_neighbours[nid].node->neighbour_id=0;
    n->neighbour_id=nid;
  }
  bzero(&overlay_neighbours[n->neighbour_id],sizeof(overlay_neighbour));
  overlay_neighbours[n->neighbour_id].node=n;

  return 0;
}
Example #16
0
unsigned int overlay_route_hash_sid(unsigned char *sid)
{
  /* Calculate the bin number of an address (sid) from the sid. */
  if (!overlay_route_hash_bytes) return WHY("overlay_route_hash_bytes==0");
  unsigned int bin=0;
  int byte=0;
  int i;
  for(i=0;i<overlay_route_hash_bytes;i++) {
    bin=bin^((sid[overlay_route_hash_order[i]])<<(8*byte));
    byte++;
    if (byte>=overlay_bin_bytes) byte=0;
  }

  /* Mask out extranous bits to return only a valid bin number */
  bin&=(overlay_bin_count-1);
  if (debug&DEBUG_OVERLAYROUTING) {
    int zeroes=0;
    fprintf(stderr,"The following address resolves to bin #%d\n",bin);
    for(i=0;i<SID_SIZE;i++) { fprintf(stderr,"%02x",sid[i]); if (!sid[i]) zeroes++; }
    fprintf(stderr,"\n");
    if (zeroes>8) {
      fprintf(stderr,"Looks like corrupt memory or packet to me!\n");
    }
  }
  return bin;
}
Example #17
0
/* Ticking neighbours is easy; we just pretend we have heard from them again,
   and recalculate the score that way, which already includes a mechanism for
   taking into account the age of the most recent observation */
int overlay_route_tick_neighbour(int neighbour_id,long long now)
{
  if (overlay_route_recalc_neighbour_metrics(&overlay_neighbours[neighbour_id],now)) 
    WHY("overlay_route_recalc_neighbour_metrics() failed");
  
  return 0;
}
Example #18
0
int overlay_payload_verify(overlay_frame *p)
{
  /* Make sure that an incoming payload has a valid signature from the sender.
     This is used to prevent spoofing */

  return WHY("function not implemented");
}
Example #19
0
int rhizome_manifest_bind_id(rhizome_manifest *m_in, const unsigned char *authorSid)
{
  rhizome_manifest_createid(m_in);
  /* The ID is implicit in transit, but we need to store it in the file, so that reimporting
     manifests on receiver nodes works easily.  We might implement something that strips the id
     variable out of the manifest when sending it, or some other scheme to avoid sending all the
     extra bytes. */
  char id[RHIZOME_MANIFEST_ID_STRLEN + 1];
  rhizome_bytes_to_hex_upper(m_in->cryptoSignPublic, id, RHIZOME_MANIFEST_ID_BYTES);
  rhizome_manifest_set(m_in, "id", id);
  if (authorSid) {
    /* Set the BK using the provided authorship information.
       Serval Security Framework defines BK as being:
       BK = privateKey XOR sha512(RS##BID), where BID = cryptoSignPublic, 
       and RS is the rhizome secret for the specified author. 
       The nice thing about this specification is that:
       privateKey = BK XOR sha512(RS##BID), so the same function can be used
       to encrypt and decrypt the BK field. */
    unsigned char bkbytes[RHIZOME_BUNDLE_KEY_BYTES];
    if (rhizome_bk_xor(authorSid, m_in->cryptoSignPublic, m_in->cryptoSignSecret, bkbytes) == 0) {
      char bkhex[RHIZOME_BUNDLE_KEY_STRLEN + 1];
      (void) tohex(bkhex, bkbytes, RHIZOME_BUNDLE_KEY_BYTES);
      if (debug&DEBUG_RHIZOME) DEBUGF("set BK=%s", bkhex);
      rhizome_manifest_set(m_in, "BK", bkhex);
    } else {
      return WHY("Failed to set BK");
    }
  }
  return 0;
}
Example #20
0
int op_append_type(overlay_buffer *headers,overlay_frame *p)
{
  unsigned char c[3];
  switch(p->type&OF_TYPE_FLAG_BITS)
    {
    case OF_TYPE_FLAG_NORMAL:
      c[0]=p->type|p->modifiers;
      if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"type resolves to %02x\n",c[0]);
      if (ob_append_bytes(headers,c,1)) return -1;
      break;
    case OF_TYPE_FLAG_E12:
      c[0]=(p->type&OF_MODIFIER_BITS)|OF_TYPE_EXTENDED12;
      c[1]=(p->type>>4)&0xff;
      if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"type resolves to %02x%02x\n",c[0],c[1]);
      if (ob_append_bytes(headers,c,2)) return -1;
      break;
    case OF_TYPE_FLAG_E20:
      c[0]=(p->type&OF_MODIFIER_BITS)|OF_TYPE_EXTENDED20;
      c[1]=(p->type>>4)&0xff;
      c[2]=(p->type>>12)&0xff;
      if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"type resolves to %02x%02x%02x\n",c[0],c[1],c[2]);
      if (ob_append_bytes(headers,c,3)) return -1;
      break;
    default: 
      /* Don't know this type of frame */
      WHY("Asked for format frame with unknown TYPE_FLAG bits");
      return -1;
    }
  return 0;
}
Example #21
0
static int rhizome_server_set_response(rhizome_http_request *r, const struct http_response *h)
{
  strbuf b = strbuf_local((char *) r->buffer, r->buffer_size);
  strbuf_build_http_response(b, h);
  if (r->buffer == NULL || strbuf_overrun(b)) {
    // Need a bigger buffer
    if (r->buffer)
      free(r->buffer);
    r->buffer_size = strbuf_count(b) + 1;
    r->buffer = malloc(r->buffer_size);
    if (r->buffer == NULL) {
      WHYF_perror("malloc(%u)", r->buffer_size);
      r->buffer_size = 0;
      return WHY("Cannot send response, out of memory");
    }
    strbuf_init(b, (char *) r->buffer, r->buffer_size);
    strbuf_build_http_response(b, h);
    if (strbuf_overrun(b))
      return WHYF("Bug! Cannot send response, buffer not big enough");
  }
  r->buffer_length = strbuf_len(b);
  r->buffer_offset = 0;
  r->request_type |= RHIZOME_HTTP_REQUEST_FROMBUFFER;
  if (debug & DEBUG_RHIZOME_TX)
    DEBUGF("Sending HTTP response: %s", alloca_toprint(120, (const char *)r->buffer, r->buffer_length));
  return 0;
}
Example #22
0
/*
  En/Decrypting a block requires use of the first 32 bytes of the block to provide
  salt.  The next 64 bytes constitute a message authentication code (MAC) that is
  used to verify the validity of the block.  The verification occurs in a higher
  level function, and all we need to know here is that we shouldn't decrypt the
  first 96 bytes of the block.
*/
int keyring_munge_block(unsigned char *block,int len /* includes the first 96 bytes */,
			unsigned char *KeyRingSalt,int KeyRingSaltLen,
			const char *KeyRingPin, const char *PKRPin)
{
  int exit_code=1;
  unsigned char hashKey[crypto_hash_sha512_BYTES];
  unsigned char hashNonce[crypto_hash_sha512_BYTES];

  unsigned char work[65536];
  int ofs;

  if (len<96) return WHY("block too short");

  unsigned char *PKRSalt=&block[0];
  int PKRSaltLen=32;

#if crypto_stream_xsalsa20_KEYBYTES>crypto_hash_sha512_BYTES
#error crypto primitive key size too long -- hash needs to be expanded
#endif
#if crypto_stream_xsalsa20_NONCEBYTES>crypto_hash_sha512_BYTES
#error crypto primitive nonce size too long -- hash needs to be expanded
#endif

  /* Generate key and nonce hashes from the various inputs */
#define APPEND(b,l) if (ofs+(l)>=65536) { WHY("Input too long"); goto kmb_safeexit; } bcopy((b),&work[ofs],(l)); ofs+=(l)

  /* Form key as hash of various concatenated inputs.
     The ordering and repetition of the inputs is designed to make rainbow tables
     infeasible */
  ofs=0;
  APPEND(PKRSalt,PKRSaltLen);
  APPEND(PKRPin,strlen(PKRPin));
  APPEND(PKRSalt,PKRSaltLen);
  APPEND(KeyRingPin,strlen(KeyRingPin));
  crypto_hash_sha512(hashKey,work,ofs);

  /* Form the nonce as hash of various other concatenated inputs */
  ofs=0;
  APPEND(KeyRingPin,strlen(KeyRingPin));
  APPEND(KeyRingSalt,KeyRingSaltLen);
  APPEND(KeyRingPin,strlen(KeyRingPin));
  APPEND(PKRPin,strlen(PKRPin));
  crypto_hash_sha512(hashNonce,work,ofs);

  /* Now en/de-crypt the remainder of the block. 
     We do this in-place for convenience, so you should not pass in a mmap()'d
     lump. */
  crypto_stream_xsalsa20_xor(&block[96],&block[96],len-96,
			     hashNonce,hashKey);
  exit_code=0;

 kmb_safeexit:
  /* Wipe out all sensitive structures before returning */
  ofs=0;
  bzero(&work[0],65536);
  bzero(&hashKey[0],crypto_hash_sha512_BYTES);
  bzero(&hashNonce[0],crypto_hash_sha512_BYTES);
  return exit_code;
#undef APPEND
}
Example #23
0
static void reply_timeout(struct sched_ent *alarm)
{
  if (awaiting_reply) {
    WHY("DNAHELPER reply timeout");
    dna_helper_kill();
  }
}
Example #24
0
// load a unicast address from configuration
int load_subscriber_address(struct subscriber *subscriber)
{
  if (subscriber_is_reachable(subscriber)&REACHABLE)
    return 0;
  int i = config_host_list__get(&config.hosts, (const sid_t*)subscriber->sid);
  // No unicast configuration? just return.
  if (i == -1)
    return 1;
  const struct config_host *hostc = &config.hosts.av[i].value;
  overlay_interface *interface = NULL;
  if (*hostc->interface){
    interface = overlay_interface_find_name(hostc->interface);
    if (!interface)
      return WHY("Can't fund configured interface");
  }
  struct sockaddr_in addr;
  bzero(&addr, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr = hostc->address;
  addr.sin_port = htons(hostc->port);
  if (addr.sin_addr.s_addr==INADDR_NONE){
    if (interface || overlay_interface_get_default()){
      if (resolve_name(hostc->host, &addr.sin_addr))
	return -1;
    }else{
      // interface isnt up yet
      return 1;
    }
  }
  if (config.debug.overlayrouting)
    DEBUGF("Loaded address %s:%d for %s", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), alloca_tohex_sid(subscriber->sid));
  return overlay_send_probe(subscriber, addr, interface, OQ_MESH_MANAGEMENT);
}
Example #25
0
int overlay_mdp_client_init()
{
  if (mdp_client_socket==-1) {
    /* Open socket to MDP server (thus connection is always local) */
    if (0) WHY("Use of abstract name space socket for Linux not implemented");
    
    mdp_client_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
    if (mdp_client_socket < 0) {
      WHY_perror("socket");
      return WHY("Could not open socket to MDP server");
    }
    
    /* We must bind to a temporary file name */
    struct sockaddr_un name;
    unsigned int random_value;
    if (urandombytes((unsigned char *)&random_value,sizeof(int)))
      return WHY("urandombytes() failed");
    name.sun_family = AF_UNIX;
    if (overlay_mdp_client_socket_path_len==-1) {
      char fmt[1024];
      if (!FORM_SERVAL_INSTANCE_PATH(fmt, "mdp-client-%d-%08x.socket"))
	return WHY("Could not form MDP client socket name");
      snprintf(overlay_mdp_client_socket_path,1024,fmt,getpid(),random_value);
      overlay_mdp_client_socket_path_len=strlen(overlay_mdp_client_socket_path)+1;
      if(config.debug.io) DEBUGF("MDP client socket name='%s'",overlay_mdp_client_socket_path);
    }
    if (overlay_mdp_client_socket_path_len > sizeof(name.sun_path) - 1)
      FATALF("MDP socket path too long (%d > %d)", overlay_mdp_client_socket_path_len, sizeof(name.sun_path) - 1);
    
    bcopy(overlay_mdp_client_socket_path,name.sun_path,
	  overlay_mdp_client_socket_path_len);
    unlink(name.sun_path);
    int len = 1 + strlen(name.sun_path) + sizeof(name.sun_family) + 1;
    int r=bind(mdp_client_socket, (struct sockaddr *)&name, len);
    if (r) {
      WHY_perror("bind");
      return WHY("Could not bind MDP client socket to file name");
    }
    
    int send_buffer_size=128*1024;
    if (setsockopt(mdp_client_socket, SOL_SOCKET, SO_RCVBUF, 
		   &send_buffer_size, sizeof(send_buffer_size)) == -1)
      WARN_perror("setsockopt");
  }
  
  return 0;
}
Example #26
0
int packetOkDNA(unsigned char *packet,int len,unsigned char *transaction_id,
		int recvttl,
		struct sockaddr *recvaddr, size_t recvaddrlen, int parseP)
{
  /* Make sure that the packet is meant for us, and is not mal-formed */
  int version;
  int cipher;
  int length;
  int payloadRotation;

  version=(packet[2]<<8)|packet[3];
  length=(packet[4]<<8)|packet[5];
  cipher=(packet[6]<<8)|packet[7];
  if (version!=1) return WHY("Unknown packet format version");
  if (cipher!=0) return WHY("Unknown packet cipher");
  if (length!=len) return WHY("Packet length incorrect");

  if (cipher) 
	  if (packetDecipher(packet,len,cipher)) 
		  return WHY("Could not decipher packet");

  /* Make sure the transaction ID matches */
  if (transaction_id)
    {
      int i;
	  for(i=0;i<TRANSID_SIZE;i++)
		if (packet[OFS_TRANSIDFIELD+i]!=transaction_id[i])
		  return WHY("transaction ID mismatch");
    }
  
  /* Unrotate the payload */
  payloadRotation=packet[OFS_ROTATIONFIELD];
  {
    unsigned char temp[256];
    bcopy(&packet[len-payloadRotation],&temp[0],payloadRotation);
    bcopy(&packet[HEADERFIELDS_LEN],&packet[HEADERFIELDS_LEN+payloadRotation],
	  len-(HEADERFIELDS_LEN)-payloadRotation);
    bcopy(&temp[0],&packet[HEADERFIELDS_LEN],payloadRotation);
  }

  if (debug&DEBUG_PACKETFORMATS) {
    DEBUG("Packet passes sanity checks and is ready for decoding");
    dump("unrotated packet",packet,len);
  }

  if (parseP) return process_packet(packet,len,recvttl,recvaddr,recvaddrlen); else return 0;
}
int
dna_helper_enqueue(struct subscriber *source, mdp_port_t source_port, const char *did)
{
  if (config.debug.dnahelper)
    DEBUGF("DNAHELPER request did=%s sid=%s", did, alloca_tohex_sid_t(source->sid));
  if (dna_helper_pid == 0)
    return 0;
  // Only try to restart a DNA helper process if the previous one is well and truly gone.
  if (dna_helper_pid == -1 && dna_helper_stdin == -1 && dna_helper_stdout == -1 && dna_helper_stderr == -1) {
    if (dna_helper_start() == -1) {
      /* Something broke, bail out */
      return WHY("DNAHELPER start failed");
    }
  }
  /* Write request to dna helper.
     Request takes form:  SID-of-Requestor|DID|\n
     By passing the requestor's SID to the helper, we don't need to maintain
     any state, as all we have to do is wait for responses from the helper,
     which will include the requestor's SID.
  */
  if (dna_helper_stdin == -1)
    return 0;
  if (request_bufptr && request_bufptr != request_buffer) {
    WARNF("DNAHELPER currently sending request %s -- dropping new request", request_buffer);
    return 0;
  }
  if (awaiting_reply) {
    WARN("DNAHELPER currently awaiting reply -- dropping new request");
    return 0;
  }
  char buffer[sizeof request_buffer];
  strbuf b = strbuf_local(request_bufptr == request_buffer ? buffer : request_buffer, sizeof buffer);
  strbuf_tohex(b, SID_STRLEN, source->sid.binary);
  strbuf_putc(b, '|');
  strbuf_puts(b, did);
  strbuf_putc(b, '|');
  strbuf_putc(b, '\n');
  if (strbuf_overrun(b)) {
    WHYF("DNAHELPER request buffer overrun: %s -- request not sent", strbuf_str(b));
    request_bufptr = request_bufend = NULL;
  } else {
    if (strbuf_str(b) != request_buffer) {
      if (strcmp(strbuf_str(b), request_buffer) != 0)
	WARNF("DNAHELPER overwriting unsent request %s", request_buffer);
      strcpy(request_buffer, strbuf_str(b));
    }
    request_bufptr = request_buffer;
    request_bufend = request_buffer + strbuf_len(b);
    request_source = source;
    request_port = source_port;
    strncpy(request_did, did, sizeof request_did);
    request_did[sizeof request_did - 1] = '\0';
  }
  if (dna_helper_started) {
    sched_requests.poll.fd = dna_helper_stdin;
    watch(&sched_requests);
  }
  return 1;
}
Example #28
0
unsigned char *overlay_get_my_sid()
{

  /* Make sure we can find our SID */
  int zero=0;
  if (!findHlr(hlr,&zero,NULL,NULL)) { WHY("Could not find first entry in HLR"); return NULL; }
  return &hlr[zero+4];
}
Example #29
0
int ob_append_byte(overlay_buffer *b,unsigned char byte)
{
  if (ob_makespace(b,1)) return WHY("ob_makespace() failed");
  
  bcopy(&byte,&b->bytes[b->length],1);
  b->length++;
  return 0;
}
Example #30
0
int ob_append_bytes(overlay_buffer *b,unsigned char *bytes,int count)
{
  if (ob_makespace(b,count)) return WHY("ob_makespace() failed");
  
  bcopy(bytes,&b->bytes[b->length],count);
  b->length+=count;
  return 0;
}