コード例 #1
0
ファイル: mdp_client.c プロジェクト: Ivan-du-toit/batphone
int overlay_mdp_client_done()
{
  if (mdp_client_socket!=-1) {
    /* Tell MDP server to release all our bindings */
    overlay_mdp_frame mdp;
    mdp.packetTypeAndFlags=MDP_GOODBYE;
    overlay_mdp_send(&mdp,0,0);
  }
  
  if (overlay_mdp_client_socket_path_len>-1)
    unlink(overlay_mdp_client_socket_path);
  if (mdp_client_socket!=-1)
    close(mdp_client_socket);
  mdp_client_socket=-1;
  return 0;
}
コード例 #2
0
ファイル: mdp_client.c プロジェクト: Ivan-du-toit/batphone
// send a request to servald deamon to add a port binding
int overlay_mdp_bind(const sid_t *localaddr, int port) 
{
  overlay_mdp_frame mdp;
  mdp.packetTypeAndFlags=MDP_BIND|MDP_FORCE;
  bcopy(localaddr->binary, mdp.bind.sid, SID_SIZE);
  mdp.bind.port=port;
  int result=overlay_mdp_send(&mdp,MDP_AWAITREPLY,5000);
  if (result) {
    if (mdp.packetTypeAndFlags==MDP_ERROR)
      WHYF("Could not bind to MDP port %d: error=%d, message='%s'",
	   port,mdp.error.error,mdp.error.message);
    else
      WHYF("Could not bind to MDP port %d (no reason given)",port);
    return -1;
  }
  return 0;
}
コード例 #3
0
ファイル: rpc_helpers.c プロジェクト: adur1990/ServalRPC
// Function to check if a SID is reachable via MDP or MSP.
int _rpc_sid_is_reachable (sid_t sid) {
	// Create a MDP socket.
	int mdp_sockfd;
	if ((mdp_sockfd = mdp_socket()) < 0) {
		pfatal("Could not create MDP lookup socket. Aborting.");
		return -1;
	}

	// Init a mdp_frame
	overlay_mdp_frame mdp;
	bzero(&mdp,sizeof(mdp));

	// Set the packettype to get a routingtable.
	mdp.packetTypeAndFlags = MDP_ROUTING_TABLE;
	overlay_mdp_send(mdp_sockfd, &mdp, 0, 0);

	// Poll until there is nothing left.
	while (overlay_mdp_client_poll(mdp_sockfd, 200)) {
		// Create mdp_frame for incoming data. TTL is required but not needed...
		overlay_mdp_frame recv_frame;
		int ttl;
		if (overlay_mdp_recv(mdp_sockfd, &recv_frame, 0, &ttl)) {
      		continue;
  		}

		// Handle incoming data.
		int offset=0;
		while (offset + sizeof(struct overlay_route_record) <= recv_frame.out.payload_length) {
			// Make new route record struct where all needed information is stored in.
			struct overlay_route_record *record = &recv_frame.out.route_record;
			offset += sizeof(struct overlay_route_record);

			// If the record (aka SID) is reachable, and the record is the desired SID, return 1 and clean up.
			if ((record->reachable == REACHABLE_INDIRECT || record->reachable == REACHABLE_UNICAST || record->reachable == REACHABLE_BROADCAST || record->reachable == REACHABLE_SELF)
					&& !cmp_sid_t(&record->sid, &sid)) {
				mdp_close(mdp_sockfd);
				return 1;
			}
		}
	}
  mdp_close(mdp_sockfd);
  return 0;
}
コード例 #4
0
ファイル: mdp_client.c プロジェクト: Ivan-du-toit/batphone
int overlay_mdp_getmyaddr(unsigned index, sid_t *sid)
{
  overlay_mdp_frame a;
  memset(&a, 0, sizeof(a));
  
  a.packetTypeAndFlags=MDP_GETADDRS;
  a.addrlist.mode = MDP_ADDRLIST_MODE_SELF;
  a.addrlist.first_sid=index;
  a.addrlist.last_sid=OVERLAY_MDP_ADDRLIST_MAX_SID_COUNT;
  a.addrlist.frame_sid_count=MDP_MAX_SID_REQUEST;
  int result=overlay_mdp_send(&a,MDP_AWAITREPLY,5000);
  if (result) {
    if (a.packetTypeAndFlags == MDP_ERROR)
      DEBUGF("MDP Server error #%d: '%s'", a.error.error, a.error.message);
    return WHY("Failed to get local address list");
  }
  if ((a.packetTypeAndFlags&MDP_TYPE_MASK)!=MDP_ADDRLIST)
    return WHY("MDP Server returned something other than an address list");
  if (0) DEBUGF("local addr 0 = %s",alloca_tohex_sid(a.addrlist.sids[0]));
  bcopy(&a.addrlist.sids[0][0], sid->binary, sizeof sid->binary);
  return 0;
}
コード例 #5
0
ファイル: sas_request.c プロジェクト: SilverHammer/commotiond
int keyring_send_sas_request_client(const char *sid_str, 
				     const size_t sid_len,
				     char *sas_buf,
				     const size_t sas_buf_len){
  int sent, found = 0, ret = 0, mdp_sockfd = -1;
  int siglen=SID_SIZE+crypto_sign_edwards25519sha512batch_BYTES;
  sid_t srcsid;
  unsigned char dstsid[SID_SIZE] = {0};
  unsigned char signature[siglen];
  time_ms_t now = gettime_ms();
  
  CHECK_MEM(sas_buf);
  CHECK(sas_buf_len >= 2 * SAS_SIZE + 1, "Insufficient SAS buffer");
  
  CHECK(sid_len == 2 * SID_SIZE && __fromhexstr(dstsid, sid_str, SID_SIZE) == 0,
	"Invalid SID");
  
  CHECK((mdp_sockfd = overlay_mdp_client_socket()) >= 0,"Cannot create MDP socket");
  
  CHECK(overlay_mdp_getmyaddr(mdp_sockfd, 0, &srcsid) == 0, "Could not get local address");
  
  int client_port = 32768 + (random() & 32767);
  CHECK(overlay_mdp_bind(mdp_sockfd, &srcsid, client_port) == 0,
	"Failed to bind to client socket");
  
  /* request mapping (send request auth-crypted). */
  overlay_mdp_frame mdp;
  memset(&mdp,0,sizeof(mdp));  
  
  mdp.packetTypeAndFlags=MDP_TX;
  mdp.out.queue=OQ_MESH_MANAGEMENT;
  memmove(mdp.out.dst.sid.binary,dstsid,SID_SIZE);
  mdp.out.dst.port=MDP_PORT_KEYMAPREQUEST;
  mdp.out.src.port=client_port;
  memmove(mdp.out.src.sid.binary,srcsid.binary,SID_SIZE);
  mdp.out.payload_length=1;
  mdp.out.payload[0]=KEYTYPE_CRYPTOSIGN;
  
  sent = overlay_mdp_send(mdp_sockfd, &mdp, 0,0);
  if (sent) {
    DEBUG("Failed to send SAS resolution request: %d", sent);
    CHECK(mdp.packetTypeAndFlags != MDP_ERROR,"MDP Server error #%d: '%s'",mdp.error.error,mdp.error.message);
  }
  
  time_ms_t timeout = now + 5000;
  
  while(now<timeout) {
    time_ms_t timeout_ms = timeout - gettime_ms();
    int result = overlay_mdp_client_poll(mdp_sockfd, timeout_ms);
    
    if (result>0) {
      int ttl=-1;
      if (overlay_mdp_recv(mdp_sockfd, &mdp, client_port, &ttl)==0) {
	switch(mdp.packetTypeAndFlags&MDP_TYPE_MASK) {
	  case MDP_ERROR:
	    ERROR("overlay_mdp_recv: %s (code %d)", mdp.error.message, mdp.error.error);
	    break;
	  case MDP_TX:
	  {
	    DEBUG("Received SAS mapping response");
	    found = 1;
	    break;
	  }
	  break;
	  default:
	    DEBUG("overlay_mdp_recv: Unexpected MDP frame type 0x%x", mdp.packetTypeAndFlags);
	    break;
	}
	if (found) break;
      }
    }
    now=gettime_ms();
  }
  
  unsigned keytype = mdp.out.payload[0];
  
  CHECK(keytype == KEYTYPE_CRYPTOSIGN,"Ignoring SID:SAS mapping with unsupported key type %u", keytype);
  
  CHECK(mdp.out.payload_length >= 1 + SAS_SIZE,"Truncated key mapping announcement? payload_length: %d", mdp.out.payload_length);
  
  unsigned char *sas_public=&mdp.out.payload[1];
  unsigned char *compactsignature = &mdp.out.payload[1+SAS_SIZE];
  
  /* reconstitute signed SID for verification */
  memmove(&signature[0],&compactsignature[0],64);
  memmove(&signature[64],&mdp.out.src.sid.binary[0],SID_SIZE);
  
  CHECK(__tohex(sas_buf,sas_public,SAS_SIZE),"Failed to convert signing key");
  sas_buf[2*SAS_SIZE] = '\0';
  
  ret = 1;
  
error:
  if (mdp_sockfd != -1)
    overlay_mdp_client_close(mdp_sockfd);
  return ret;
}
コード例 #6
0
ファイル: crypto.c プロジェクト: hawkinswnaf/commotiond
static int keyring_send_sas_request_client(struct subscriber *subscriber){
  int sent, client_port, found = 0, ret = 0;
  int siglen=SID_SIZE+crypto_sign_edwards25519sha512batch_BYTES;
  unsigned char *srcsid[SID_SIZE] = {0}, *plain = NULL;
  unsigned char signature[siglen];
  time_ms_t now = gettime_ms();
  
  CHECK_ERR(overlay_mdp_getmyaddr(0,(sid_t *)srcsid) == 0,"Could not get local address");

  if (subscriber->sas_valid)
    return 1;
  
  CHECK_ERR(now >= subscriber->sas_last_request + 100,"Too soon to ask for SAS mapping again");
  
  CHECK_ERR(my_subscriber,"couldn't request SAS (I don't know who I am)");
  
  DEBUG("Requesting SAS mapping for SID=%s", alloca_tohex_sid(subscriber->sid));
  
  CHECK_ERR(overlay_mdp_bind((sid_t *)my_subscriber->sid,(client_port=32768+(random()&32767))) == 0,"Failed to bind to client socket");

/* request mapping (send request auth-crypted). */
  overlay_mdp_frame mdp;
  memset(&mdp,0,sizeof(mdp));  

  mdp.packetTypeAndFlags=MDP_TX;
  mdp.out.queue=OQ_MESH_MANAGEMENT;
  memmove(mdp.out.dst.sid,subscriber->sid,SID_SIZE);
  mdp.out.dst.port=MDP_PORT_KEYMAPREQUEST;
  mdp.out.src.port=client_port;
  memmove(mdp.out.src.sid,srcsid,SID_SIZE);
  mdp.out.payload_length=1;
  mdp.out.payload[0]=KEYTYPE_CRYPTOSIGN;
  
  sent = overlay_mdp_send(&mdp, 0,0);
  if (sent) {
    DEBUG("Failed to send SAS resolution request: %d", sent);
    CHECK_ERR(mdp.packetTypeAndFlags != MDP_ERROR,"MDP Server error #%d: '%s'",mdp.error.error,mdp.error.message);
  }
  
  time_ms_t timeout = now + 5000;

  while(now<timeout) {
    time_ms_t timeout_ms = timeout - gettime_ms();
    int result = overlay_mdp_client_poll(timeout_ms);
    
    if (result>0) {
      int ttl=-1;
      if (overlay_mdp_recv(&mdp, client_port, &ttl)==0) {
	switch(mdp.packetTypeAndFlags&MDP_TYPE_MASK) {
	  case MDP_ERROR:
	    ERROR("overlay_mdp_recv: %s (code %d)", mdp.error.message, mdp.error.error);
	    break;
	  case MDP_TX:
	  {
	    DEBUG("Received SAS mapping response");
	    found = 1;
	    break;
	  }
	  break;
	  default:
	    DEBUG("overlay_mdp_recv: Unexpected MDP frame type 0x%x", mdp.packetTypeAndFlags);
	    break;
	}
	if (found) break;
      }
    }
    now=gettime_ms();
    if (servalShutdown)
      break;
  }

  unsigned keytype = mdp.out.payload[0];
  
  CHECK_ERR(keytype == KEYTYPE_CRYPTOSIGN,"Ignoring SID:SAS mapping with unsupported key type %u", keytype);
  
  CHECK_ERR(mdp.out.payload_length >= 1 + SAS_SIZE,"Truncated key mapping announcement? payload_length: %d", mdp.out.payload_length);
  
  plain = (unsigned char*)calloc(mdp.out.payload_length,sizeof(unsigned char));
  unsigned long long plain_len=0;
  unsigned char *sas_public=&mdp.out.payload[1];
  unsigned char *compactsignature = &mdp.out.payload[1+SAS_SIZE];
  
  /* reconstitute signed SID for verification */
  memmove(&signature[0],&compactsignature[0],64);
  memmove(&signature[64],&mdp.out.src.sid[0],SID_SIZE);
  
  int r=crypto_sign_edwards25519sha512batch_open(plain,&plain_len,
						 signature,siglen,
						 sas_public);
  CHECK_ERR(r == 0,"SID:SAS mapping verification signature does not verify");

  /* These next two tests should never be able to fail, but let's just check anyway. */
  CHECK_ERR(plain_len == SID_SIZE,"SID:SAS mapping signed block is wrong length");
  CHECK_ERR(memcmp(plain, mdp.out.src.sid, SID_SIZE) == 0,"SID:SAS mapping signed block is for wrong SID");
  
  memmove(subscriber->sas_public, sas_public, SAS_SIZE);
  subscriber->sas_valid=1;
  subscriber->sas_last_request=now;
  ret = 1;
  
error:
  if (plain) free(plain);
  return ret;
}