⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 identity.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 3 页
字号:
                        &hosts_[i]->identity, sizeof (GNUNET_PeerIdentity))))        {          entry = hosts_[i];          for (j = 0; j < entry->protocolCount; j++)            {              if (protocol == entry->protocols[j])                {                  entry->protocols[j]                    = entry->protocols[entry->protocolCount - 1];                  GNUNET_array_grow (entry->protocols,                                     entry->protocolCount,                                     entry->protocolCount - 1);                }            }          for (j = 0; j < entry->helloCount; j++)            {              if (protocol == ntohs (entry->hellos[j]->protocol))                {                  GNUNET_free (entry->hellos[j]);                  entry->hellos[j] = entry->hellos[entry->helloCount - 1];                  GNUNET_array_grow (entry->hellos,                                     entry->helloCount,                                     entry->helloCount - 1);                }            }          /* also remove hello file itself */          fn = getHostFileName (identity, protocol);          if (0 != UNLINK (fn))            GNUNET_GE_LOG_STRERROR_FILE (ectx,                                         GNUNET_GE_WARNING | GNUNET_GE_USER |                                         GNUNET_GE_BULK, "unlink", fn);          GNUNET_free (fn);          if (entry->protocolCount == 0)            {              if (entry->helloCount > 0)                {                  for (j = 0; j < entry->helloCount; j++)                    GNUNET_free (entry->hellos[j]);                  GNUNET_array_grow (entry->hellos, entry->helloCount, 0);                }              hosts_[i] = hosts_[--numberOfHosts_];              GNUNET_free (entry);            }          GNUNET_mutex_unlock (lock_);          GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);          return;               /* deleted */        }    }  GNUNET_mutex_unlock (lock_);}/** * Bind a host address (hello) to a hostId. * @param msg the verified (!) hello message */static voidbindAddress (const GNUNET_MessageHello * msg){  char *fn;  char *buffer;  GNUNET_MessageHello *oldMsg;  int size;  HostEntry *host;  int i;  GNUNET_PeerIdentity have;  getPeerIdentity (&msg->publicKey, &have);  if (0 != memcmp (&have, &msg->senderIdentity, sizeof (GNUNET_PeerIdentity)))    {      GNUNET_GE_BREAK (NULL, 0);      return;    }  GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);  GNUNET_GE_ASSERT (ectx, msg != NULL);  fn = getHostFileName (&msg->senderIdentity, ntohs (msg->protocol));  buffer = GNUNET_malloc (GNUNET_MAX_BUFFER_SIZE);  if (GNUNET_disk_file_test (ectx, fn) == GNUNET_YES)    {      size = GNUNET_disk_file_read (ectx, fn, GNUNET_MAX_BUFFER_SIZE, buffer);      if (size >= sizeof (GNUNET_MessageHello))        {          oldMsg = (GNUNET_MessageHello *) buffer;          if ((unsigned int) size == GNUNET_sizeof_hello (oldMsg))            {              if (ntohl (oldMsg->expiration_time) >                  ntohl (msg->expiration_time))                {                  GNUNET_free (fn);                  GNUNET_free (buffer);                  return;       /* have more recent hello in stock */                }            }        }    }  GNUNET_disk_file_write (ectx, fn, msg, GNUNET_sizeof_hello (msg), "644");  GNUNET_free (fn);  GNUNET_free (buffer);  GNUNET_mutex_lock (lock_);  addHostToKnown (&msg->senderIdentity, ntohs (msg->protocol));  host = findHost (&msg->senderIdentity);  GNUNET_GE_ASSERT (ectx, host != NULL);  for (i = 0; i < host->helloCount; i++)    {      if (msg->protocol == host->hellos[i]->protocol)        {          GNUNET_free (host->hellos[i]);          host->hellos[i] = NULL;          break;        }    }  if (i == host->helloCount)    GNUNET_array_grow (host->hellos, host->helloCount, host->helloCount + 1);  host->hellos[i] = GNUNET_malloc (GNUNET_sizeof_hello (msg));  memcpy (host->hellos[i], msg, GNUNET_sizeof_hello (msg));  GNUNET_mutex_unlock (lock_);  GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);}/** * Obtain the public key and address of a known host.  If no specific * protocol is specified (GNUNET_TRANSPORT_PROTOCOL_NUMBER_ANY), hellos for cheaper * protocols are returned with preference (randomness!). * * @param hostId the host id * @param protocol the protocol that we need, *        GNUNET_TRANSPORT_PROTOCOL_NUMBER_ANY if we do not care which protocol * @param tryTemporaryList is it ok to check the unverified hellos? * @param result where to store the result * @returns GNUNET_SYSERR on failure, GNUNET_OK on success */static GNUNET_MessageHello *identity2Hello (const GNUNET_PeerIdentity * hostId,                unsigned short protocol, int tryTemporaryList){  GNUNET_MessageHello *result;  HostEntry *host;  char *fn;  GNUNET_MessageHello buffer;  GNUNET_PeerIdentity have;  int size;  int i;  int j;  GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);  GNUNET_mutex_lock (lock_);  if (GNUNET_YES == tryTemporaryList)    {      /* ok, then first try temporary hosts         (in memory, cheapest!) */      for (i = 0; i < MAX_TEMP_HOSTS; i++)        {          host = &tempHosts[i];          if ((host->helloCount > 0) &&              (0 ==               memcmp (hostId, &host->identity,                       sizeof (GNUNET_PeerIdentity))))            {              if (protocol == GNUNET_TRANSPORT_PROTOCOL_NUMBER_ANY)                {                  j =                    GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK,                                       host->helloCount);                }              else                {                  j = 0;                  while ((j < host->helloCount) &&                         (host->protocols[j] != protocol))                    j++;                }              if (j == host->helloCount)                {                  /* not found */                  GNUNET_mutex_unlock (lock_);                  return NULL;                }              result = GNUNET_malloc (GNUNET_sizeof_hello (host->hellos[j]));              memcpy (result, host->hellos[j],                      GNUNET_sizeof_hello (host->hellos[j]));              GNUNET_mutex_unlock (lock_);              return result;            }        }    }  host = findHost (hostId);  if ((host == NULL) || (host->protocolCount == 0))    {      GNUNET_mutex_unlock (lock_);      return NULL;    }  if (protocol == GNUNET_TRANSPORT_PROTOCOL_NUMBER_ANY)    protocol =      host->protocols[GNUNET_random_u32                      (GNUNET_RANDOM_QUALITY_WEAK, host->protocolCount)];  for (i = 0; i < host->helloCount; i++)    {      if (ntohs (host->hellos[i]->protocol) == protocol)        {          result = GNUNET_malloc (GNUNET_sizeof_hello (host->hellos[i]));          memcpy (result,                  host->hellos[i], GNUNET_sizeof_hello (host->hellos[i]));          GNUNET_mutex_unlock (lock_);          return result;        }    }  /* do direct read */  fn = getHostFileName (hostId, protocol);  if (1 != GNUNET_disk_file_test (ectx, fn))    {      GNUNET_free (fn);      GNUNET_mutex_unlock (lock_);      return NULL;    }  size =    GNUNET_disk_file_read (ectx, fn, sizeof (GNUNET_MessageHello), &buffer);  if (size != sizeof (GNUNET_MessageHello))    {      if (0 == UNLINK (fn))        GNUNET_GE_LOG (ectx,                       GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK,                       _                       ("Removed file `%s' containing invalid HELLO data.\n"),                       fn);      else        GNUNET_GE_LOG_STRERROR_FILE (ectx,                                     GNUNET_GE_ERROR | GNUNET_GE_ADMIN |                                     GNUNET_GE_USER | GNUNET_GE_BULK,                                     "unlink", fn);      GNUNET_free (fn);      GNUNET_mutex_unlock (lock_);      return NULL;    }  result = GNUNET_malloc (GNUNET_sizeof_hello (&buffer));  size =    GNUNET_disk_file_read (ectx, fn, GNUNET_sizeof_hello (&buffer), result);  getPeerIdentity (&result->publicKey, &have);  if (((unsigned int) size != GNUNET_sizeof_hello (&buffer)) ||      (0 != memcmp (&have,                    hostId,                    sizeof (GNUNET_PeerIdentity))) ||      (0 !=       memcmp (&have, &result->senderIdentity, sizeof (GNUNET_PeerIdentity))))    {      if (0 == UNLINK (fn))        GNUNET_GE_LOG (ectx,                       GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK,                       _                       ("Removed file `%s' containing invalid HELLO data.\n"),                       fn);      else        GNUNET_GE_LOG_STRERROR_FILE (ectx,                                     GNUNET_GE_ERROR | GNUNET_GE_ADMIN |                                     GNUNET_GE_USER | GNUNET_GE_BULK,                                     "unlink", fn);      GNUNET_free (fn);      GNUNET_free (result);      GNUNET_mutex_unlock (lock_);      return NULL;    }  GNUNET_free (fn);  GNUNET_array_grow (host->hellos, host->helloCount, host->helloCount + 1);  host->hellos[host->helloCount - 1]    = GNUNET_malloc (GNUNET_sizeof_hello (&buffer));  memcpy (host->hellos[host->helloCount - 1],          result, GNUNET_sizeof_hello (&buffer));  GNUNET_mutex_unlock (lock_);  return result;}/** * @param signer the identity of the host that *        presumably signed the message * @param message the signed message * @param size the size of the message * @param sig the signature * @return GNUNET_OK on success, GNUNET_SYSERR on error (verification failed) */static intverifyPeerSignature (const GNUNET_PeerIdentity * signer,                     const void *message, int size,                     const GNUNET_RSA_Signature * sig){  GNUNET_MessageHello *hello;  int res;  hello =    identity2Hello (signer, GNUNET_TRANSPORT_PROTOCOL_NUMBER_ANY, GNUNET_YES);  if (hello == NULL)    {#if DEBUG_IDENTITY      GNUNET_EncName enc;      IF_GELOG (ectx,                GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK,                GNUNET_hash_to_enc (&signer->hashPubKey, &enc));      GNUNET_GE_LOG (ectx,                     GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK,                     _                     ("Signature failed verification: peer `%s' not known.\n"),                     &enc);#endif      return GNUNET_SYSERR;    }  res = GNUNET_RSA_verify (message, size, sig, &hello->publicKey);  if (res == GNUNET_SYSERR)    GNUNET_GE_LOG (ectx,                   GNUNET_GE_ERROR | GNUNET_GE_REQUEST | GNUNET_GE_DEVELOPER |                   GNUNET_GE_USER,                   _("Signature failed verification: signature invalid.\n"));  GNUNET_free (hello);  return res;}/** * Blacklist a host. This method is called if a host * failed to respond to a connection attempt. * * @param identity the ID of the peer to blacklist * @param desperation how desperate are we to connect? [0,MAXHOSTS] * @param strict should we reject incoming connection attempts as well? * @return GNUNET_OK on success GNUNET_SYSERR on error */static intblacklistHost (const GNUNET_PeerIdentity * identity,               unsigned int desperation, int strict){  GNUNET_EncName hn;  HostEntry *entry;  int i;  GNUNET_CronTime now;  GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);  GNUNET_mutex_lock (lock_);  entry = findHost (identity);  if (entry == NULL)    {      for (i = 0; i < MAX_TEMP_HOSTS; i++)        {          if (0 == memcmp (identity,                           &tempHosts[i].identity,                           sizeof (GNUNET_PeerIdentity)))            {              entry = &tempHosts[i];              break;            }        }    }  if (entry == NULL)    {      GNUNET_mutex_unlock (lock_);      return GNUNET_SYSERR;    }  now = GNUNET_get_time ();  if ((entry->strict == GNUNET_YES) && (strict == GNUNET_NO))    {      /* stronger blacklisting in place! */      GNUNET_mutex_unlock (lock_);      return GNUNET_OK;    }  if (strict)    {      entry->delta = desperation * GNUNET_CRON_SECONDS;    }  else    {      if (entry->until < now)        entry->delta =          GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK,                             1 + desperation * GNUNET_CRON_SECONDS);      else        entry->delta +=          GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK,                             1 + desperation * GNUNET_CRON_SECONDS);    }  if (entry->delta > 4 * GNUNET_CRON_HOURS)    entry->delta = 4 * GNUNET_CRON_HOURS;  entry->until = now + entry->delta;  entry->strict = strict;  GNUNET_hash_to_enc (&identity->hashPubKey, &hn);#if DEBUG_IDENTITY  GNUNET_GE_LOG (ectx,                 GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_DEVELOPER,                 "Blacklisting host `%s' for %llu seconds"                 " until %llu (strict=%d).\n",                 &hn, entry->delta / GNUNET_CRON_SECONDS, entry->until,                 strict);#endif  GNUNET_mutex_unlock (lock_);  return GNUNET_OK;}/** * Is the host currently blacklisted (i.e. we refuse to talk)? * * @param identity host to check * @return GNUNET_YES if true, else GNUNET_NO */static intisBlacklisted (const GNUNET_PeerIdentity * identity, int strict){  GNUNET_CronTime now;  HostEntry *entry;  GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);  GNUNET_mutex_lock (lock_);  entry = findHost (identity);  if (entry == NULL)    {      GNUNET_mutex_unlock (lock_);      return GNUNET_NO;    }  now = GNUNET_get_time ();  if ((now < entry->until)      && ((entry->strict == GNUNET_YES) || (strict == GNUNET_NO)))    {#if DEBUG_IDENTITY      GNUNET_EncName enc;      IF_GELOG (ectx,                GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK,                GNUNET_hash_to_enc (&identity->hashPubKey, &enc));      GNUNET_GE_LOG (ectx,                     GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK,                     _                     ("Peer `%s' is currently strictly blacklisted (for another %llums).\n"),                     &enc, entry->until - now);#endif      GNUNET_mutex_unlock (lock_);      return GNUNET_YES;    }  else    {      GNUNET_mutex_unlock (lock_);      return GNUNET_NO;    }}/** * Whitelist a host. This method is called if a host * successfully established a connection. It typically * resets the exponential backoff to the smallest value. * @return GNUNET_OK on success GNUNET_SYSERR on error */static intwhitelistHost (const GNUNET_PeerIdentity * identity){  HostEntry *entry;  int i;  GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);  GNUNET_mutex_lock (lock_);  entry = findHost (identity);  if (entry == NULL)    {      for (i = 0; i < MAX_TEMP_HOSTS; i++)        {          if (0 == memcmp (identity,                           &tempHosts[i].identity,                           sizeof (GNUNET_PeerIdentity)))            {              entry = &tempHosts[i];              break;            }        }    }  if (entry == NULL)    {      GNUNET_mutex_unlock (lock_);      return GNUNET_SYSERR;    }  entry->delta = 30 * GNUNET_CRON_SECONDS;  entry->until = 0;  entry->strict = GNUNET_NO;  GNUNET_mutex_unlock (lock_);  return GNUNET_OK;}/** * Call a method for each known host. * * @param callback the method to call for each host * @param now the time to use for excluding hosts *        due to blacklisting, use 0 *        to go through all hosts. * @param data an argument to pass to the method * @return the number of hosts matching */static intforEachHost (GNUNET_CronTime now, GNUNET_HostProcessor callback, void *data){  int i;  int j;  int count;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -