/** https://github.com/cjdelisle/cjdns/issues/179 */ static void test179(struct Allocator* alloc, struct Log* logger) { uint8_t buff[32] = {0}; uint8_t buff2[32] = {0}; struct Random* rand = Random_new(alloc, logger, NULL); struct Random* rand2 = Random_new(alloc, logger, NULL); Random_bytes(rand, buff, 32); Random_bytes(rand2, buff, 32); Assert_true(Bits_memcmp(buff, buff2, 32)); }
static Iface_DEFUN responseWithIpCallback(struct Message* message, struct Iface* iface) { struct RouteHeader* rh = (struct RouteHeader*) message->bytes; Assert_true(!Bits_memcmp(nodeCjdnsIp6, rh->ip6, 16)); Assert_true(!Bits_memcmp(fakePubKey, rh->publicKey, 32)); Message_shift(message, -(RouteHeader_SIZE + DataHeader_SIZE), NULL); struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->bytes; Assert_true(Headers_getIpVersion(ip) == 6); uint16_t length = Endian_bigEndianToHost16(ip->payloadLength_be); Assert_true(length + Headers_IP6Header_SIZE == message->length); Assert_true(ip->nextHeader == 17); Assert_true(Bits_isZero(ip->sourceAddr, 32)); Message_shift(message, -Headers_IP6Header_SIZE, NULL); struct Headers_UDPHeader* uh = (struct Headers_UDPHeader*) message->bytes; Assert_true(!Checksum_udpIp6(ip->sourceAddr, message->bytes, length)); Assert_true(uh->srcPort_be == 0); Assert_true(uh->destPort_be == 0); Assert_true(Endian_bigEndianToHost16(uh->length_be) + Headers_UDPHeader_SIZE == length); Message_shift(message, -Headers_UDPHeader_SIZE, NULL); // We can't check that the message is an exact match because the padding depends on the // alignment of the output but we can make sure the right content is there... // Message should start with "d0000" (with some number of zeros) char* expectedResponse = "9:addresses" "d" "3:ip6" "16:\xfd\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1" "9:ip6Prefix" "i128e" "e" "4:txid" "4:abcd" "e"; Assert_true(message->length >= (int32_t) CString_strlen(expectedResponse)); Assert_true(CString_strstr(message->bytes, expectedResponse)); called |= 2; return 0; }
/** * Search the authorized passwords for one matching this auth header. * * @param auth the auth header. * @param context the CryptoAuth engine to search in. * @return an Auth struct with a if one is found, otherwise NULL. */ static inline struct CryptoAuth_User* getAuth(union CryptoHeader_Challenge* auth, struct CryptoAuth_pvt* ca) { if (auth->challenge.type == 0) { return NULL; } int count = 0; for (struct CryptoAuth_User* u = ca->users; u; u = u->next) { count++; if (auth->challenge.type == 1 && !Bits_memcmp(auth->bytes, u->passwordHash, CryptoHeader_Challenge_KEYSIZE)) { return u; } else if (auth->challenge.type == 2 && !Bits_memcmp(auth->bytes, u->userNameHash, CryptoHeader_Challenge_KEYSIZE)) { return u; } } Log_debug(ca->logger, "Got unrecognized auth, password count = [%d]", count); return NULL; }
static Iface_DEFUN messageToTun(struct Message* msg, struct Iface* iface) { struct Context* ctx = Identity_check(((struct IfaceContext*)iface)->ctx); uint16_t type = TUNMessageType_pop(msg, NULL); if (type == Ethernet_TYPE_IP6) { struct Headers_IP6Header* ip = (struct Headers_IP6Header*) msg->bytes; Assert_true(Headers_getIpVersion(ip) == 6); Assert_true(!Bits_memcmp(ip->sourceAddr, ctx->sendingAddress, 16)); Message_shift(msg, -Headers_IP6Header_SIZE, NULL); ctx->called |= 4; } else if (type == Ethernet_TYPE_IP4) { struct Headers_IP4Header* ip = (struct Headers_IP4Header*) msg->bytes; Assert_true(Headers_getIpVersion(ip) == 4); Assert_true(!Bits_memcmp(ip->sourceAddr, ctx->sendingAddress, 4)); Message_shift(msg, -Headers_IP4Header_SIZE, NULL); ctx->called |= 1; } else { Assert_failure("unrecognized message type %u", (unsigned int)type); } Assert_true(msg->length == 12 && CString_strcmp(msg->bytes, "hello world") == 0); return 0; }
static uint8_t receiveMessage(struct Message* msg, struct Interface* iface) { struct Context* ctx = Identity_cast((struct Context*) iface->receiverContext); struct Sockaddr_storage source; Message_pop(msg, &source, ctx->targetAddr->addrLen, NULL); if (Bits_memcmp(&source, ctx->targetAddr, ctx->targetAddr->addrLen)) { Log_info(ctx->logger, "Got spurious message from [%s], expecting messages from [%s]", Sockaddr_print(&source.addr, msg->alloc), Sockaddr_print(ctx->targetAddr, msg->alloc)); return 0; } // we don't yet know with which message this data belongs, // the message alloc lives the length of the message reception. struct Allocator* alloc = Allocator_child(msg->alloc); struct Reader* reader = ArrayReader_new(msg->bytes, msg->length, alloc); Dict* d = Dict_new(alloc); if (StandardBencSerializer_get()->parseDictionary(reader, alloc, d)) { return 0; } String* txid = Dict_getString(d, String_CONST("txid")); if (!txid || txid->len != 8) { return 0; } // look up the result uint32_t handle = ~0u; Hex_decode((uint8_t*)&handle, 4, txid->bytes, 8); int idx = Map_OfRequestByHandle_indexForHandle(handle, &ctx->outstandingRequests); if (idx < 0) { return 0; } struct Request* req = ctx->outstandingRequests.values[idx]; // now this data will outlive the life of the message. Allocator_adopt(req->promise->alloc, alloc); req->res.responseDict = d; int len = (msg->length > AdminClient_MAX_MESSAGE_SIZE) ? AdminClient_MAX_MESSAGE_SIZE : msg->length; Bits_memset(req->res.messageBytes, 0, AdminClient_MAX_MESSAGE_SIZE); Bits_memcpy(req->res.messageBytes, msg->bytes, len); done(req, AdminClient_Error_NONE); return 0; }
static uint8_t receiveMessageTUN(struct Message* msg, struct Interface* iface) { receivedMessageTUNCount++; uint16_t ethertype = TUNMessageType_pop(msg); if (ethertype != Ethernet_TYPE_IP4) { printf("Spurious packet with ethertype [%u]\n", Endian_bigEndianToHost16(ethertype)); return 0; } struct Headers_IP4Header* header = (struct Headers_IP4Header*) msg->bytes; Assert_always(msg->length == Headers_IP4Header_SIZE + Headers_UDPHeader_SIZE + 12); Assert_always(!Bits_memcmp(header->destAddr, testAddrB, 4)); Assert_always(!Bits_memcmp(header->sourceAddr, testAddrA, 4)); Bits_memcpyConst(header->destAddr, testAddrA, 4); Bits_memcpyConst(header->sourceAddr, testAddrB, 4); TUNMessageType_push(msg, ethertype); return iface->sendMessage(msg, iface); }
int CryptoAuth_addUser_ipv6(String* password, String* login, uint8_t ipv6[16], struct CryptoAuth* cryptoAuth) { struct CryptoAuth_pvt* ca = Identity_check((struct CryptoAuth_pvt*) cryptoAuth); struct Allocator* alloc = Allocator_child(ca->allocator); struct CryptoAuth_User* user = Allocator_calloc(alloc, sizeof(struct CryptoAuth_User), 1); user->alloc = alloc; Identity_set(user); if (!login) { int i = 0; for (struct CryptoAuth_User* u = ca->users; u; u = u->next) { i++; } user->login = login = String_printf(alloc, "Anon #%d", i); } else { user->login = String_clone(login, alloc); } union CryptoHeader_Challenge ac; // Users specified with a login field might want to use authType 1 still. hashPassword(user->secret, &ac, login, password, 2); Bits_memcpyConst(user->userNameHash, ac.bytes, CryptoHeader_Challenge_KEYSIZE); hashPassword(user->secret, &ac, NULL, password, 1); Bits_memcpyConst(user->passwordHash, ac.bytes, CryptoHeader_Challenge_KEYSIZE); for (struct CryptoAuth_User* u = ca->users; u; u = u->next) { if (Bits_memcmp(user->secret, u->secret, 32)) { } else if (!login) { } else if (String_equals(login, u->login)) { Allocator_free(alloc); return CryptoAuth_addUser_DUPLICATE; } } if (ipv6) { Bits_memcpyConst(user->restrictedToip6, ipv6, 16); } // Add the user to the *end* of the list for (struct CryptoAuth_User** up = &ca->users; ; up = &(*up)->next) { if (!*up) { *up = user; break; } } return 0; }
void encryptRndNonceTest() { uint8_t buff[44]; Bits_memset(buff, 0, 44); uint8_t nonce[24]; Bits_memset(nonce, 0, 24); uint8_t secret[32]; Bits_memset(secret, 0, 32); struct Message m = { .bytes=&buff[32], .length=12, .padding=32}; strcpy((char*) m.bytes, "hello world"); Exports_encryptRndNonce(nonce, &m, secret); uint8_t* expected = (uint8_t*) "1391ac5d03ba9f7099bffbb6e6c69d67ae5bd79391a5b94399b293dc"; uint8_t output[57]; Hex_encode(output, 57, m.bytes, m.length); //printf("\n%s\n%s\n", (char*) expected, (char*) output); Assert_always(!Bits_memcmp(expected, output, 56)); Assert_always(!Exports_decryptRndNonce(nonce, &m, secret)); Assert_always(m.length == 12 && !Bits_memcmp(m.bytes, "hello world", m.length)); } void createNew() { uint8_t buff[BUFFER_SIZE]; struct Allocator* allocator = CanaryAllocator_new(BufferAllocator_new(buff, BUFFER_SIZE), NULL); struct CryptoAuth* ca = CryptoAuth_new(allocator, privateKey, eventBase, NULL, NULL); /*for (int i = 0; i < 32; i++) { printf("%.2x", ca->publicKey[i]); }*/ Assert_always(Bits_memcmp(ca->publicKey, publicKey, 32) == 0); }
/** * Search the authorized passwords for one matching this auth header. * * @param auth the auth header. * @param context the CryptoAuth engine to search in. * @return an Auth struct with a if one is found, otherwise NULL. */ static inline struct CryptoAuth_Auth* getAuth(union Headers_AuthChallenge auth, struct CryptoAuth_pvt* context) { if (auth.challenge.type != 1) { return NULL; } for (uint32_t i = 0; i < context->passwordCount; i++) { if (Bits_memcmp(auth.bytes, &context->passwords[i], Headers_AuthChallenge_KEYSIZE) == 0) { return &context->passwords[i]; } } Log_debug(context->logger, "Got unrecognized auth, password count = [%d]", context->passwordCount); return NULL; }
void InterfaceController_resetPeering(struct InterfaceController* ifController, uint8_t herPublicKey[32]) { struct InterfaceController_pvt* ic = Identity_check((struct InterfaceController_pvt*) ifController); for (int j = 0; j < ic->icis->length; j++) { struct InterfaceController_Iface_pvt* ici = ArrayList_OfIfaces_get(ic->icis, j); for (int i = 0; i < (int)ici->peerMap.count; i++) { struct Peer* peer = ici->peerMap.values[i]; if (!herPublicKey || !Bits_memcmp(herPublicKey, peer->caSession->herPublicKey, 32)) { CryptoAuth_reset(peer->caSession); } } } }
static int parseEmptyList() { char* test = "d" "2:hi" "le" "e"; struct Allocator* alloc = MallocAllocator_new(1<<20); struct Reader* reader = ArrayReader_new(test, CString_strlen(test), alloc); Dict d; int ret = StandardBencSerializer_get()->parseDictionary(reader, alloc, &d); char out[256]; struct Writer* w = ArrayWriter_new(out, 256, alloc); ret |= StandardBencSerializer_get()->serializeDictionary(w, &d); ret |= Bits_memcmp(test, out, CString_strlen(test)); Allocator_free(alloc); return ret; }
/** * Send a search request to the next node in this search. * This is called whenever a response comes in or after the global mean response time passes. */ static void searchStep(struct SearchRunner_Search* search) { struct SearchRunner_pvt* ctx = Identity_check((struct SearchRunner_pvt*)search->runner); struct Node_Two* node; struct SearchStore_Node* nextSearchNode; for (;;) { nextSearchNode = SearchStore_getNextNode(search->search); // If the number of requests sent has exceeded the max search requests, let's stop there. if (search->totalRequests >= MAX_REQUESTS_PER_SEARCH || nextSearchNode == NULL) { if (search->pub.callback) { search->pub.callback(&search->pub, 0, NULL, NULL); } Allocator_free(search->pub.alloc); return; } node = NodeStore_getBest(&nextSearchNode->address, ctx->nodeStore); if (!node) { continue; } if (node == ctx->nodeStore->selfNode) { continue; } if (Bits_memcmp(node->address.ip6.bytes, nextSearchNode->address.ip6.bytes, 16)) { continue; } break; } Assert_true(node != ctx->nodeStore->selfNode); Bits_memcpyConst(&search->lastNodeAsked, &node->address, sizeof(struct Address)); struct RouterModule_Promise* rp = RouterModule_newMessage(&node->address, 0, ctx->router, search->pub.alloc); Dict* message = Dict_new(rp->alloc); Dict_putString(message, CJDHTConstants_QUERY, CJDHTConstants_QUERY_FN, rp->alloc); Dict_putString(message, CJDHTConstants_TARGET, search->targetStr, rp->alloc); rp->userData = search; rp->callback = searchCallback; RouterModule_sendMessage(rp, message); search->totalRequests++; }
static void receiveHelloWithNoAuth() { struct Allocator* alloc = MallocAllocator_new(1<<20); struct Context* ctx = setUp(PRIVATEKEY, NULL, NULL, alloc); struct Message* msg = Message_new(132, 0, alloc); Assert_true(Hex_decode(msg->bytes, msg->length, "0000000000ffffffffffffff7fffffffffffffffffffffffffffffffffffffff" "ffffffffffffffff847c0d2c375234f365e660955187a3735a0f7613d1609d3a" "6a4d8c53aeaa5a22ea9cf275eee0185edf7f211192f12e8e642a325ed76925fe" "3c76d313b767a10aca584ca0b979dee990a737da7d68366fa3846d43d541de91" "29ea3e12", 132*2) > 0); Assert_true(!CryptoAuth_decrypt(ctx->sess, msg)); Assert_true(msg->length == HELLOWORLDLEN); Assert_true(Bits_memcmp(HELLOWORLD, msg->bytes, HELLOWORLDLEN) == 0); Allocator_free(alloc); //printf("bytes=%s length=%u\n", finalOut->bytes, finalOut->length); }
static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* addrIface) { struct Context* ctx = Identity_containerOf(addrIface, struct Context, addrIface); struct Sockaddr_storage source; Message_pop(msg, &source, ctx->targetAddr->addrLen, NULL); if (Bits_memcmp(&source, ctx->targetAddr, ctx->targetAddr->addrLen)) { Log_info(ctx->logger, "Got spurious message from [%s], expecting messages from [%s]", Sockaddr_print(&source.addr, msg->alloc), Sockaddr_print(ctx->targetAddr, msg->alloc)); return NULL; } // we don't yet know with which message this data belongs, // the message alloc lives the length of the message reception. struct Allocator* alloc = Allocator_child(msg->alloc); int origLen = msg->length; Dict* d = NULL; char* err = BencMessageReader_readNoExcept(msg, alloc, &d); if (err) { return NULL; } Message_shift(msg, origLen, NULL); String* txid = Dict_getString(d, String_CONST("txid")); if (!txid || txid->len != 8) { return NULL; } // look up the result uint32_t handle = ~0u; Hex_decode((uint8_t*)&handle, 4, txid->bytes, 8); int idx = Map_OfRequestByHandle_indexForHandle(handle, &ctx->outstandingRequests); if (idx < 0) { return NULL; } struct Request* req = ctx->outstandingRequests.values[idx]; // now this data will outlive the life of the message. Allocator_adopt(req->promise->alloc, alloc); req->res.responseDict = d; int len = (msg->length > AdminClient_MAX_MESSAGE_SIZE) ? AdminClient_MAX_MESSAGE_SIZE : msg->length; Bits_memset(req->res.messageBytes, 0, AdminClient_MAX_MESSAGE_SIZE); Bits_memcpy(req->res.messageBytes, msg->bytes, len); done(req, AdminClient_Error_NONE); return NULL; }
/** * Send a search request to the next node in this search. * This is called whenever a response comes in or after the global mean response time passes. */ static void searchStep(struct SearchRunner_Search* search) { struct SearchRunner_pvt* ctx = Identity_check((struct SearchRunner_pvt*)search->runner); struct SearchStore_Node* nextSearchNode; for (;;) { nextSearchNode = SearchStore_getNextNode(search->search); // If the number of requests sent has exceeded the max search requests, let's stop there. if (search->totalRequests >= search->maxRequests) { // fallthrough } else if (search->numFinds > 0 && search->totalRequests >= search->maxRequestsIfFound) { // fallthrough } else if (nextSearchNode == NULL) { // fallthrough } else { break; } if (search->pub.callback) { search->pub.callback(&search->pub, 0, NULL, NULL); } Allocator_free(search->pub.alloc); return; } Bits_memcpyConst(&search->lastNodeAsked, &nextSearchNode->address, sizeof(struct Address)); struct RouterModule_Promise* rp = RouterModule_newMessage(&nextSearchNode->address, 0, ctx->router, search->pub.alloc); Dict* message = Dict_new(rp->alloc); if (!Bits_memcmp(nextSearchNode->address.ip6.bytes, search->target.ip6.bytes, 16)) { Dict_putString(message, CJDHTConstants_QUERY, CJDHTConstants_QUERY_GP, rp->alloc); } else { Dict_putString(message, CJDHTConstants_QUERY, CJDHTConstants_QUERY_FN, rp->alloc); } Dict_putString(message, CJDHTConstants_TARGET, search->targetStr, rp->alloc); rp->userData = search; rp->callback = searchCallback; RouterModule_sendMessage(rp, message); search->totalRequests++; }
int InterfaceController_disconnectPeer(struct InterfaceController* ifController, uint8_t herPublicKey[32]) { struct InterfaceController_pvt* ic = Identity_check((struct InterfaceController_pvt*) ifController); for (int j = 0; j < ic->icis->length; j++) { struct InterfaceController_Iface_pvt* ici = ArrayList_OfIfaces_get(ic->icis, j); for (int i = 0; i < (int)ici->peerMap.count; i++) { struct Peer* peer = ici->peerMap.values[i]; if (!Bits_memcmp(herPublicKey, peer->caSession->herPublicKey, 32)) { Allocator_free(peer->alloc); return 0; } } } return InterfaceController_disconnectPeer_NOTFOUND; }
/** If there's already an endpoint with the same public key, merge the new one with the old one. */ static void moveEndpointIfNeeded(struct IFCPeer* ep, struct Context* ic) { Log_debug(ic->logger, "Checking for old sessions to merge with."); uint8_t* key = CryptoAuth_getHerPublicKey(ep->cryptoAuthIf); for (uint32_t i = 0; i < ic->peerMap.count; i++) { struct IFCPeer* thisEp = ic->peerMap.values[i]; uint8_t* thisKey = CryptoAuth_getHerPublicKey(thisEp->cryptoAuthIf); if (thisEp != ep && !Bits_memcmp(thisKey, key, 32)) { Log_info(ic->logger, "Moving endpoint to merge new session with old."); ep->switchLabel = thisEp->switchLabel; SwitchCore_swapInterfaces(&thisEp->switchIf, &ep->switchIf); Allocator_free(thisEp->external->allocator); return; } } }
static void onReply(Dict* msg, struct Address* src, struct MsgCore_Promise* prom) { struct ReachabilityCollector_pvt* rcp = Identity_check((struct ReachabilityCollector_pvt*) prom->userData); Assert_true(prom == rcp->msgOnWire); if (!src) { onReplyTimeout(prom); mkNextRequest(rcp); return; } struct Address_List* results = ReplySerializer_parse(src, msg, rcp->log, false, prom->alloc); uint64_t path = 1; struct PeerInfo* pi = NULL; for (int j = 0; j < rcp->piList->length; j++) { struct PeerInfo* pi0 = ArrayList_OfPeerInfo_get(rcp->piList, j); if (Address_isSameIp(&pi0->addr, src)) { pi = pi0; break; } } if (!pi) { Log_debug(rcp->log, "Got message from peer which is gone from list"); return; } for (int i = 0; i < results->length; i++) { path = results->elems[i].path; if (Bits_memcmp(results->elems[i].ip6.bytes, rcp->myAddr->ip6.bytes, 16)) { continue; } if (pi->pathThemToUs != path) { Log_debug(rcp->log, "Found back-route for [%s]", Address_toString(src, prom->alloc)->bytes); if (rcp->pub.onChange) { rcp->pub.onChange( &rcp->pub, src->ip6.bytes, path, src->path, 0, 0xffff, 0xffff, 0xffff); } } pi->pathThemToUs = path; pi->querying = false; return; } pi->pathToCheck = (results->length < 8) ? 1 : path; mkNextRequest(rcp); }
int parseEmptyList() { char* test = "d" "2:hi" "le" "e"; char buffer[512]; struct Allocator* alloc = BufferAllocator_new(buffer, 512); struct Reader* reader = ArrayReader_new(test, strlen(test), alloc); Dict d; int ret = StandardBencSerializer_get()->parseDictionary(reader, alloc, &d); if (ret) { return ret; } char out[256]; struct Writer* w = ArrayWriter_new(out, 256, alloc); ret = StandardBencSerializer_get()->serializeDictionary(w, &d); if (ret) { return ret; } return Bits_memcmp(test, out, strlen(test)); }
void* Bits_memmem(const void* haystack, size_t haystackLen, const void* needle, size_t needleLen) { uint8_t* needleC = (uint8_t*) needle; uint8_t* haystackC = (uint8_t*) haystack; uint8_t* stopAt = haystackC + haystackLen - needleLen; if (!(haystack && needle && haystackLen && needleLen)) { return NULL; } while (haystackC <= stopAt) { if (*haystackC == *needleC && !Bits_memcmp(haystackC, needleC, needleLen)) { return haystackC; } haystackC++; } return NULL; }
/** * Send an arbitrary message to a node. * * @param message to be sent, must be prefixed with IpTunnel_PacketInfoHeader. * @param iface an interface for which receiverContext is the ducttape. */ static uint8_t sendToNode(struct Message* message, struct Interface* iface) { struct Ducttape_pvt* context = Identity_cast((struct Ducttape_pvt*)iface->receiverContext); struct Ducttape_MessageHeader* dtHeader = getDtHeader(message, true); struct IpTunnel_PacketInfoHeader* header = (struct IpTunnel_PacketInfoHeader*) message->bytes; Message_shift(message, -IpTunnel_PacketInfoHeader_SIZE); struct Node* n = RouterModule_lookup(header->nodeIp6Addr, context->routerModule); if (n) { if (!Bits_memcmp(header->nodeKey, n->address.key, 32)) { // Found the node. #ifdef Log_DEBUG uint8_t nhAddr[60]; Address_print(nhAddr, &n->address); Log_debug(context->logger, "Sending arbitrary data to [%s]", nhAddr); #endif struct SessionManager_Session* session = SessionManager_getSession(n->address.ip6.bytes, n->address.key, context->sm); n->version = session->version = (n->version > session->version) ? n->version : session->version; dtHeader->switchLabel = n->address.path; return sendToRouter(message, dtHeader, session, context); } } #ifdef Log_DEBUG uint8_t printedIp6[40]; AddrTools_printIp(printedIp6, header->nodeIp6Addr); Log_debug(context->logger, "Couldn't find node [%s] for sending to.", printedIp6); #endif // Now lets trigger a search for this node. uint64_t now = Time_currentTimeMilliseconds(context->eventBase); if (context->timeOfLastSearch + context->timeBetweenSearches < now) { context->timeOfLastSearch = now; RouterModule_search(header->nodeIp6Addr, context->routerModule, context->alloc); } return 0; }
int main() { struct Allocator* alloc; BufferAllocator_STACK(alloc, 512); struct Random* rand = Random_new(alloc, NULL); uint8_t bytes[32]; Random_bytes(rand, bytes, 32); uint8_t base32[64]; Bits_memset(base32, 0, 64); Assert_always(Base32_encode(base32, 64, bytes, 32) == 52); //printf("base32 encoded: %s\n", base32); uint8_t bytes2[32]; Assert_always(Base32_decode(bytes2, 32, base32, 52) == 32); Assert_always(Bits_memcmp(bytes, bytes2, 32) == 0); }
/** If there's already an endpoint with the same public key, merge the new one with the old one. */ static void moveEndpointIfNeeded(struct Peer* ep) { struct InterfaceController_Iface_pvt* ici = ep->ici; Log_debug(ici->ic->logger, "Checking for old sessions to merge with."); for (uint32_t i = 0; i < ici->peerMap.count; i++) { struct Peer* thisEp = ici->peerMap.values[i]; if (thisEp != ep && !Bits_memcmp(thisEp->addr.key, ep->addr.key, 32)) { Log_info(ici->ic->logger, "Moving endpoint to merge new session with old."); ep->addr.path = thisEp->addr.path; SwitchCore_swapInterfaces(&thisEp->switchIf, &ep->switchIf); Assert_true(ep->switchIf.connectedIf->send); Assert_true(thisEp->switchIf.connectedIf->send); Allocator_free(thisEp->alloc); Assert_true(!thisEp->switchIf.connectedIf->send); Assert_true(ep->switchIf.connectedIf->send); return; } } }
int main() { struct Allocator* alloc = MallocAllocator_new(20000); struct Random* rand = Random_new(alloc, NULL, NULL); uint8_t bytes[32]; Random_bytes(rand, bytes, 32); uint8_t hex[65] = {0}; Assert_true(Hex_encode(hex, 65, bytes, 32) == 64); //printf("hex encoded: %s\n", hex); uint8_t bytes2[32]; Assert_true(Hex_decode(bytes2, 32, hex, 64) == 32); Assert_true(Bits_memcmp(bytes, bytes2, 32) == 0); Allocator_free(alloc); return 0; }
static void searchReplyCallback(struct RouterModule_Promise* promise, uint32_t lagMilliseconds, struct Address* from, Dict* result) { struct SearchRunner_Search* search = Identity_check((struct SearchRunner_Search*)promise->userData); struct Address_List* nodeList = ReplySerializer_parse(from, result, search->runner->logger, promise->alloc); for (int i = 0; nodeList && i < nodeList->length; i++) { if (isDuplicateEntry(nodeList, i)) { continue; } if (Address_closest(&search->target, &nodeList->elems[i], from) >= 0) { // Too much noise. //Log_debug(search->runner->logger, "Answer was further from the target than us.\n"); continue; } if (search->lastNodeAsked.path != from->path) { // old queries coming in late... continue; } struct Node_Two* nn = NodeStore_closestNode(search->runner->nodeStore, nodeList->elems[i].path); if (!nn || Bits_memcmp(nn->address.key, nodeList->elems[i].key, 32)) { RumorMill_addNode(search->runner->rumorMill, &nodeList->elems[i]); } nodeList->elems[i].path = NodeStore_optimizePath(search->runner->nodeStore, nodeList->elems[i].path); SearchStore_addNodeToSearch(&nodeList->elems[i], search->search); } }
int main() { struct Allocator* alloc = MallocAllocator_new(20000); struct Random* rand = Random_new(alloc, NULL, NULL); uint8_t bytes[32]; Random_bytes(rand, bytes, 32); uint8_t base32[64]; Bits_memset(base32, 0, 64); Assert_always(Base32_encode(base32, 64, bytes, 32) == 52); //printf("base32 encoded: %s\n", base32); uint8_t bytes2[32]; Assert_always(Base32_decode(bytes2, 32, base32, 52) == 32); Assert_always(Bits_memcmp(bytes, bytes2, 32) == 0); Allocator_free(alloc); return 0; }
static void unsubscribe(Dict* args, void* vcontext, String* txid) { struct AdminLog* log = (struct AdminLog*) vcontext; String* streamIdHex = Dict_getString(args, String_CONST("streamId")); uint8_t streamId[8]; char* error = NULL; if (streamIdHex->len != 16 || Hex_decode(streamId, 8, (uint8_t*)streamIdHex->bytes, 16) != 8) { error = "Invalid streamId."; } else { error = "No such subscription."; for (int i = 0; i < (int)log->subscriptionCount; i++) { if (!Bits_memcmp(streamId, log->subscriptions[i].streamId, 8)) { removeSubscription(log, &log->subscriptions[i]); error = "none"; break; } } } Dict response = Dict_CONST( String_CONST("error"), String_OBJ(String_CONST(error)), NULL ); Admin_sendMessage(&response, txid, log->admin); }
static int handleOutgoing(struct DHTMessage* dmessage, void* vcontext) { struct Ducttape_pvt* context = Identity_check((struct Ducttape_pvt*) vcontext); // Sending a message to yourself? // Short circuit because setting up a CA session with yourself causes problems. if (!Bits_memcmp(dmessage->address->key, context->myAddr.key, 32)) { struct Allocator* alloc = Allocator_child(context->alloc); Allocator_adopt(alloc, dmessage->binMessage->alloc); incomingDHT(dmessage->binMessage, dmessage->address, context); Allocator_free(alloc); return 0; } struct Message* msg = dmessage->binMessage; { Message_push(msg, (&(struct Headers_UDPHeader) { .srcPort_be = 0, .destPort_be = 0, .length_be = Endian_hostToBigEndian16(msg->length), .checksum_be = 0, }), Headers_UDPHeader_SIZE, NULL); }
static int is_tap_win32_dev(const char *guid) { HKEY netcard_key; LONG status; DWORD len; int i = 0; status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0, KEY_READ, &netcard_key); if (status != ERROR_SUCCESS) { return FALSE; } for (;;) { char enum_name[256]; char unit_string[256]; HKEY unit_key; char component_id_string[] = "ComponentId"; char component_id[256]; char net_cfg_instance_id_string[] = "NetCfgInstanceId"; char net_cfg_instance_id[256]; DWORD data_type; len = sizeof (enum_name); status = RegEnumKeyEx( netcard_key, i, enum_name, &len, NULL, NULL, NULL, NULL); if (status == ERROR_NO_MORE_ITEMS) { break; } else if (status != ERROR_SUCCESS) { return FALSE; } snprintf (unit_string, sizeof(unit_string), "%s\\%s", ADAPTER_KEY, enum_name); status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, unit_string, 0, KEY_READ, &unit_key); if (status != ERROR_SUCCESS) { return FALSE; } else { len = sizeof (component_id); status = RegQueryValueEx( unit_key, component_id_string, NULL, &data_type, (uint8_t*)component_id, &len); if (!(status != ERROR_SUCCESS || data_type != REG_SZ)) { len = sizeof (net_cfg_instance_id); status = RegQueryValueEx( unit_key, net_cfg_instance_id_string, NULL, &data_type, (uint8_t*)net_cfg_instance_id, &len); if (status == ERROR_SUCCESS && data_type == REG_SZ) { if (!Bits_memcmp(component_id, "tap", CString_strlen("tap")) && !strcmp (net_cfg_instance_id, guid)) { RegCloseKey (unit_key); RegCloseKey (netcard_key); return TRUE; } } } RegCloseKey (unit_key); } ++i; } RegCloseKey (netcard_key); return FALSE; }
int InterfaceController_registerPeer(struct InterfaceController* ifController, uint8_t herPublicKey[32], String* password, bool requireAuth, bool isIncomingConnection, struct Interface* externalInterface) { // This function is overridden by some tests... if (ifController->registerPeer) { return ifController->registerPeer(ifController, herPublicKey, password, requireAuth, isIncomingConnection, externalInterface); } struct InterfaceController_pvt* ic = Identity_check((struct InterfaceController_pvt*) ifController); if (Map_OfIFCPeerByExernalIf_indexForKey(&externalInterface, &ic->peerMap) > -1) { return 0; } Log_debug(ic->logger, "registerPeer [%p] total [%u]", (void*)externalInterface, ic->peerMap.count); uint8_t ip6[16]; if (herPublicKey) { AddressCalc_addressForPublicKey(ip6, herPublicKey); if (!AddressCalc_validAddress(ip6)) { return InterfaceController_registerPeer_BAD_KEY; } if (!Bits_memcmp(ic->ca->publicKey, herPublicKey, 32)) { // can't link with yourself, wiseguy return InterfaceController_registerPeer_BAD_KEY; } } else { Assert_true(requireAuth); } struct Allocator* epAllocator = externalInterface->allocator; struct InterfaceController_Peer* ep = Allocator_calloc(epAllocator, sizeof(struct InterfaceController_Peer), 1); ep->bytesOut = 0; ep->bytesIn = 0; ep->external = externalInterface; int setIndex = Map_OfIFCPeerByExernalIf_put(&externalInterface, &ep, &ic->peerMap); ep->handle = ic->peerMap.handles[setIndex]; Identity_set(ep); Allocator_onFree(epAllocator, closeInterface, ep); // If the other end need needs to supply a valid password to connect // we will set the connection state to UNAUTHENTICATED so that if the // packet is invalid, the connection will be dropped right away. if (requireAuth) { ep->state = InterfaceController_PeerState_UNAUTHENTICATED; } ep->cryptoAuthIf = CryptoAuth_wrapInterface(externalInterface, herPublicKey, NULL, requireAuth, "outer", ic->ca); ep->cryptoAuthIf->receiveMessage = receivedAfterCryptoAuth; ep->cryptoAuthIf->receiverContext = ep; // Always use authType 1 until something else comes along, then we'll have to refactor. if (password) { CryptoAuth_setAuth(password, 1, ep->cryptoAuthIf); } ep->isIncomingConnection = isIncomingConnection; Bits_memcpyConst(&ep->switchIf, (&(struct Interface) { .sendMessage = sendFromSwitch, // ifcontrollerForPeer uses this. // sendFromSwitch relies on the fact that the // switchIf is the same memory location as the Peer. .senderContext = ic, .allocator = epAllocator }), sizeof(struct Interface));