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

📄 connect.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 3 页
字号:
/*     This file is part of GNUnet.     (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 Christian Grothoff (and other contributing authors)     GNUnet is free software; you can redistribute it and/or modify     it under the terms of the GNU General Public License as published     by the Free Software Foundation; either version 2, or (at your     option) any later version.     GNUnet is distributed in the hope that it will be useful, but     WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     General Public License for more details.     You should have received a copy of the GNU General Public License     along with GNUnet; see the file COPYING.  If not, write to the     Free Software Foundation, Inc., 59 Temple Place - Suite 330,     Boston, MA 02111-1307, USA.*//** * @file session/connect.c * @brief module responsible for the sessionkey exchange *   which establishes a session with another peer * @author Christian Grothoff */#include "platform.h"#include "gnunet_util.h"#include "gnunet_protocols.h"#include "gnunet_transport_service.h"#include "gnunet_identity_service.h"#include "gnunet_pingpong_service.h"#include "gnunet_session_service.h"#include "gnunet_stats_service.h"#include "gnunet_topology_service.h"#include "cache.h"#define hello_HELPER_TABLE_START_SIZE 64#define DEBUG_SESSION GNUNET_NO#define EXTRA_CHECKS ALLOW_EXTRA_CHECKSstatic GNUNET_CoreAPIForPlugins *coreAPI;static GNUNET_Identity_ServiceAPI *identity;static GNUNET_Transport_ServiceAPI *transport;static GNUNET_Pingpong_ServiceAPI *pingpong;static GNUNET_Topology_ServiceAPI *topology;static GNUNET_Stats_ServiceAPI *stats;static struct GNUNET_Mutex *lock;static struct GNUNET_GE_Context *ectx;static int stat_skeySent;static int stat_skeyRejected;static int stat_skeyAccepted;static int stat_sessionEstablished;static int stat_pongSent;static int stat_pingSent;/** * @brief message for session key exchange. */typedef struct{  GNUNET_MessageHeader header;  /**   * time when this key was created  (network byte order)   * Must be the first field after the header since   * the signature starts at this offset.   */  GNUNET_Int32Time creationTime;  /**   * The encrypted session key.  May ALSO contain   * encrypted PINGs and PONGs.   */  GNUNET_RSA_EncryptedData key;  /**   * Who is the intended recipient?   */  GNUNET_PeerIdentity target;  /**   * GNUNET_RSA_Signature of the stuff above.   */  GNUNET_RSA_Signature signature;} P2P_setkey_MESSAGE;#if DEBUG_SESSION/** * Not thread-safe, only use for debugging! */static const char *printSKEY (const GNUNET_AES_SessionKey * sk){  static char r[512];  static char t[12];  int i;  strcpy (r, "");  for (i = 0; i < GNUNET_SESSIONKEY_LEN; i++)    {      GNUNET_snprintf (t, 12, "%02x", sk->key[i]);      strcat (r, t);    }  return r;}#endif/** * We received a GNUNET_RSA_sign of life from this host. * * @param hostId the peer that gave a GNUNET_RSA_sign of live */static voidnotifyPONG (void *arg){  GNUNET_PeerIdentity *hostId = arg;#if DEBUG_SESSION  GNUNET_EncName enc;#endif  GNUNET_GE_ASSERT (ectx, hostId != NULL);#if DEBUG_SESSION  IF_GELOG (ectx,            GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST,            GNUNET_hash_to_enc (&hostId->hashPubKey, &enc));  GNUNET_GE_LOG (ectx,                 GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST,                 "Received `%s' from `%s', marking session as up.\n", "PONG",                 &enc);#endif  GNUNET_GE_ASSERT (ectx, hostId != NULL);  if (stats != NULL)    stats->change (stat_sessionEstablished, 1);  coreAPI->p2p_connection_confirm (hostId);  GNUNET_free (hostId);}/** * Check if the received session key is properly signed * and if connections to this peer are allowed according * to policy. * * @param hostId the sender of the key * @param sks the session key message * @return GNUNET_SYSERR if invalid, GNUNET_OK if valid, GNUNET_NO if *  connections are disallowed */static intverifySKS (const GNUNET_PeerIdentity * hostId, const P2P_setkey_MESSAGE * sks){  const GNUNET_RSA_Signature *signature = &sks->signature;  char *limited;  GNUNET_EncName enc;  if ((sks == NULL) || (hostId == NULL))    {      GNUNET_GE_BREAK (ectx, 0);      return GNUNET_SYSERR;    }  /* check if we are allowed to accept connections     from that peer */  limited = NULL;  GNUNET_GC_get_configuration_value_string (coreAPI->cfg,                                            "GNUNETD", "LIMIT-ALLOW", "",                                            &limited);  if (strlen (limited) > 0)    {      GNUNET_hash_to_enc (&hostId->hashPubKey, &enc);      if (NULL == strstr (limited, (char *) &enc))        {#if DEBUG_SESSION          GNUNET_GE_LOG (ectx,                         GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST,                         "Connection from peer `%s' was rejected (not allowed).\n",                         &enc);#endif          GNUNET_free (limited);          return GNUNET_NO;        }    }  GNUNET_free (limited);  limited = NULL;  GNUNET_GC_get_configuration_value_string (coreAPI->cfg,                                            "GNUNETD", "LIMIT-DENY", "",                                            &limited);  if (strlen (limited) > 0)    {      GNUNET_hash_to_enc (&hostId->hashPubKey, &enc);      if (NULL != strstr (limited, (char *) &enc))        {#if DEBUG_SESSION          GNUNET_GE_LOG (ectx,                         GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST,                         "Connection from peer `%s' was rejected (explicitly denied).\n",                         &enc);#endif          GNUNET_free (limited);          return GNUNET_NO;        }    }  GNUNET_free (limited);  if (GNUNET_OK != identity->verifyPeerSignature (hostId,                                                  sks,                                                  sizeof (P2P_setkey_MESSAGE)                                                  -                                                  sizeof                                                  (GNUNET_RSA_Signature),                                                  signature))    {#if DEBUG_SESSION      GNUNET_EncName enc;      IF_GELOG (ectx,                GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_REQUEST,                GNUNET_hash_to_enc (&hostId->hashPubKey, &enc));      GNUNET_GE_LOG (ectx,                     GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_REQUEST,                     _("Session key from peer `%s' could not be verified.\n"),                     &enc);#endif      return GNUNET_SYSERR;     /*reject! */    }  return GNUNET_OK;             /* ok */}/** * Force creation of a new Session key for the given host. * * @param hostId the identity of the other host * @param sk the GNUNET_AES_SessionKey to use * @param created the timestamp to use * @param ping optional PING to include (otherwise NULL) * @param pong optional PONG to include (otherwise NULL) * @param ret the address where to write the signed *        session key message * @return message on success, NULL on failure */static P2P_setkey_MESSAGE *makeSessionKeySigned (const GNUNET_PeerIdentity * hostId,                      const GNUNET_AES_SessionKey * sk,                      GNUNET_Int32Time created,                      const GNUNET_MessageHeader * ping,                      const GNUNET_MessageHeader * pong){  GNUNET_MessageHello *foreignHello;  int size;  P2P_setkey_MESSAGE *msg;  char *pt;  GNUNET_EncName enc;  GNUNET_PeerIdentity hc;  GNUNET_GE_ASSERT (ectx, sk != NULL);  foreignHello =    identity->identity2Hello (hostId, GNUNET_TRANSPORT_PROTOCOL_NUMBER_ANY,                              GNUNET_YES);  /* create and encrypt sessionkey */  if (NULL == foreignHello)    {      GNUNET_hash_to_enc (&hostId->hashPubKey, &enc);      GNUNET_GE_LOG (ectx,                     GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_REQUEST,                     _("Cannot encrypt sessionkey, peer `%s' not known!\n"),                     &enc);      return NULL;              /* other host not known */    }  identity->getPeerIdentity (&foreignHello->publicKey, &hc);  if ((0 != memcmp (&hc,                    hostId,                    sizeof (GNUNET_PeerIdentity))) ||      (0 != memcmp (&hc,                    &foreignHello->senderIdentity,                    sizeof (GNUNET_PeerIdentity))))    {      GNUNET_GE_BREAK_OP (NULL,                          0 == memcmp (&hc,                                       &foreignHello->senderIdentity,                                       sizeof (GNUNET_PeerIdentity)));      GNUNET_GE_BREAK_OP (NULL,                          0 == memcmp (&hc, hostId,                                       sizeof (GNUNET_PeerIdentity)));      GNUNET_GE_BREAK_OP (NULL, 0);      GNUNET_free (foreignHello);      return NULL;    }  size = sizeof (P2P_setkey_MESSAGE);  if (ping != NULL)    size += ntohs (ping->size);  if (pong != NULL)    size += ntohs (pong->size);  if (GNUNET_OK !=      GNUNET_session_cache_get (&hc,                                created,                                sk, size, (GNUNET_MessageHeader **) & msg))    {      msg = GNUNET_malloc (size);      msg->target = *hostId;      if (GNUNET_SYSERR == GNUNET_RSA_encrypt (sk,                                               sizeof (GNUNET_AES_SessionKey),                                               &foreignHello->publicKey,                                               &msg->key))        {

⌨️ 快捷键说明

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