📄 connect.c
字号:
GNUNET_GE_BREAK_OP (ectx, 0); GNUNET_free (foreignHello); GNUNET_free (msg); return NULL; /* encrypt failed */ } /* complete header */ msg->header.size = htons (size); msg->header.type = htons (GNUNET_P2P_PROTO_SET_KEY); msg->creationTime = htonl (created); GNUNET_GE_ASSERT (ectx, GNUNET_SYSERR != identity->signData (msg, sizeof (P2P_setkey_MESSAGE) - sizeof (GNUNET_RSA_Signature), &msg->signature)); GNUNET_session_cache_put (&hc, created, sk, &msg->header); } GNUNET_free (foreignHello);#if EXTRA_CHECKS /* verify signature/SKS */ GNUNET_GE_ASSERT (ectx, GNUNET_SYSERR != verifySKS (coreAPI->my_identity, msg));#endif size = 0; if (ping != NULL) size += ntohs (ping->size); if (pong != NULL) size += ntohs (pong->size); if (size > 0) { pt = GNUNET_malloc (size); size = 0; if (ping != NULL) { memcpy (&pt[size], ping, ntohs (ping->size)); size += ntohs (ping->size); } if (pong != NULL) { memcpy (&pt[size], pong, ntohs (pong->size)); size += ntohs (pong->size); }#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Encrypting %d bytes of %s%s with key %s and IV %u\n", size, (ping == NULL) ? "" : "PING", (pong == NULL) ? "" : "PONG", printSKEY (sk), *(int *) &msg->signature);#endif GNUNET_GE_ASSERT (ectx, -1 != GNUNET_AES_encrypt (pt, size, sk, (const GNUNET_AES_InitializationVector *) &msg->signature, (char *) &msg[1])); GNUNET_free (pt); } return msg;}/** * Perform a session key exchange. First sends a hello * and then the new SKEY (in two plaintext packets). When called, the * semaphore of at the given index must already be down * * @param receiver peer to exchange a key with * @param tsession session to use for the exchange (maybe NULL) * @param pong pong to include (maybe NULL) */static intexchangeKey (const GNUNET_PeerIdentity * receiver, GNUNET_TSession * tsession, GNUNET_MessageHeader * pong){ GNUNET_MessageHello *hello; P2P_setkey_MESSAGE *skey; GNUNET_AES_SessionKey sk; GNUNET_Int32Time age; GNUNET_MessageHeader *ping; GNUNET_PeerIdentity *sndr; GNUNET_EncName enc; GNUNET_GE_ASSERT (ectx, receiver != NULL); if ((tsession != NULL) && (0 != memcmp (&tsession->peer, receiver, sizeof (GNUNET_PeerIdentity)))) { GNUNET_GE_BREAK (ectx, 0); tsession = NULL; } if ((topology != NULL) && (topology->allowConnectionFrom (receiver) == GNUNET_SYSERR)) return GNUNET_SYSERR; GNUNET_hash_to_enc (&receiver->hashPubKey, &enc); /* then try to connect on the transport level */ if ((tsession == NULL) || (transport->associate (tsession, __FILE__) == GNUNET_SYSERR)) tsession = transport->connect_freely (receiver, GNUNET_YES, __FILE__); if (tsession == NULL) {#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Key exchange with `%s' failed: could not connect.\n", &enc);#endif return GNUNET_SYSERR; /* failed to connect */ } /* create our ping */ sndr = GNUNET_malloc (sizeof (GNUNET_PeerIdentity)); *sndr = *receiver; ping = pingpong->pingUser (receiver, ¬ifyPONG, sndr, GNUNET_NO, rand ()); if (ping == NULL) { GNUNET_free (sndr); transport->disconnect (tsession, __FILE__); return GNUNET_SYSERR; } /* get or create our session key */ if (GNUNET_OK != coreAPI->p2p_session_key_get (receiver, &sk, &age, GNUNET_YES)) { age = GNUNET_get_time_int32 (NULL); GNUNET_AES_create_session_key (&sk); coreAPI->p2p_session_key_set (&sk, receiver, age, GNUNET_YES);#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Created fresh sessionkey `%s' for peer `%s'.\n", printSKEY (&sk), &enc);#endif } /* build SKEY message */ skey = makeSessionKeySigned (receiver, &sk, age, ping, pong); GNUNET_free (ping); if (skey == NULL) { transport->disconnect (tsession, __FILE__); return GNUNET_SYSERR; } /* create hello */ hello = transport->hello_create (tsession->ttype); if (NULL == hello) hello = transport->hello_create (GNUNET_TRANSPORT_PROTOCOL_NUMBER_ANY); if (NULL == hello) { char *tports; tports = NULL; GNUNET_GC_get_configuration_value_string (coreAPI->cfg, "GNUNETD", "TRANSPORTS", NULL, &tports); GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE, _ ("Could not create any HELLO for myself (have transports `%s')!\n"), tports); GNUNET_free_non_null (tports); }#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Sending session key to peer `%s'.\n", &enc);#endif if (stats != NULL) { stats->change (stat_pingSent, 1); stats->change (stat_skeySent, 1); /* pong, if present, is accounted for by caller */ } if (hello != NULL) { coreAPI->plaintext_send (tsession, (const char *) hello, GNUNET_sizeof_hello (hello)); GNUNET_free (hello); hello = NULL; coreAPI->plaintext_send (tsession, (const char *) skey, ntohs (skey->header.size)); } GNUNET_free (skey); if (0 != memcmp (receiver, &tsession->peer, sizeof (GNUNET_PeerIdentity))) { GNUNET_GE_BREAK (NULL, 0); } else { coreAPI->p2p_transport_session_offer (receiver, tsession); } transport->disconnect (tsession, __FILE__); return GNUNET_OK;}/** * Accept a session-key that has been sent by another host. * The other host must be known (public key). Notifies * the core about the new session key and possibly * triggers sending a session key ourselves (if not * already done). * * @param sender the identity of the sender host * @param tsession the transport session handle * @param msg message with the session key * @return GNUNET_SYSERR or GNUNET_OK */static intacceptSessionKey (const GNUNET_PeerIdentity * sender, const GNUNET_MessageHeader * msg, GNUNET_TSession * tsession){ GNUNET_AES_SessionKey key; GNUNET_MessageHeader *ping; GNUNET_MessageHeader *pong; int size; int load; int pos; char *plaintext; GNUNET_EncName enc; int ret; const GNUNET_RSA_Signature *sig; const P2P_setkey_MESSAGE *newMsg; const void *end; if (sender == NULL) { GNUNET_GE_BREAK (NULL, 0); return GNUNET_SYSERR; } GNUNET_hash_to_enc (&sender->hashPubKey, &enc); if ((topology != NULL) && (topology->allowConnectionFrom (sender) == GNUNET_SYSERR)) {#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Topology rejected session key from peer `%s'.\n", &enc);#endif return GNUNET_SYSERR; } if (0 == memcmp (&sender->hashPubKey, &coreAPI->my_identity->hashPubKey, sizeof (GNUNET_HashCode))) { GNUNET_GE_BREAK (ectx, 0); return GNUNET_SYSERR; }#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Received session key from peer `%s'.\n", &enc);#endif if ((ntohs (msg->size) < sizeof (P2P_setkey_MESSAGE)) || (!(((ntohs (msg->size) == sizeof (P2P_setkey_MESSAGE)) || (ntohs (msg->size) == sizeof (P2P_setkey_MESSAGE) + pingpong->ping_size) || (ntohs (msg->size) == sizeof (P2P_setkey_MESSAGE) + pingpong->ping_size * 2))))) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_DEVELOPER | GNUNET_GE_USER | GNUNET_GE_BULK, _ ("Session key received from peer `%s' has invalid format (discarded).\n"), &enc); return GNUNET_SYSERR; } load = GNUNET_cpu_get_load (ectx, coreAPI->cfg); if ((GNUNET_OK != coreAPI->p2p_session_key_get (sender, NULL, NULL, GNUNET_YES)) && ((GNUNET_YES == identity->isBlacklisted (sender, GNUNET_NO)) || ((coreAPI->p2p_connections_iterate (NULL, NULL) >= 3) && (load > GNUNET_IDLE_LOAD_THRESHOLD)))) {#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Received session key from peer `%s', but that peer is not allowed to connect right now!\n", &enc);#endif return GNUNET_SYSERR; /* other peer initiated but is listed as not allowed => discard */ } newMsg = (const P2P_setkey_MESSAGE *) msg; if (0 != memcmp (&coreAPI->my_identity->hashPubKey, &newMsg->target.hashPubKey, sizeof (GNUNET_HashCode))) { GNUNET_EncName ta; GNUNET_hash_to_enc (&newMsg->target.hashPubKey, &ta); GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_DEVELOPER | GNUNET_GE_USER | GNUNET_GE_BULK, _ ("Session key received from peer `%s' is for `%s' and not for me!\n"), &enc, &ta); return GNUNET_SYSERR; /* not for us! */ } ret = verifySKS (sender, newMsg); if (GNUNET_OK != ret) {#if DEBUG_SESSION if (ret == GNUNET_SYSERR) GNUNET_GE_LOG (ectx, GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_REQUEST | GNUNET_GE_DEVELOPER, "Signature of session key from `%s' failed" " verification (discarded).\n", &enc);#endif if (stats != NULL) stats->change (stat_skeyRejected, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -