예제 #1
0
/** 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));
}
예제 #2
0
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;
}
예제 #3
0
파일: CryptoAuth.c 프로젝트: cmotc/cjdns
/**
 * 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;
}
예제 #4
0
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;
}
예제 #5
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;
}
예제 #6
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);
}
예제 #7
0
파일: CryptoAuth.c 프로젝트: cmotc/cjdns
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;
}
예제 #8
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);
}
예제 #9
0
파일: CryptoAuth.c 프로젝트: AVert/cjdns
/**
 * 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;
}
예제 #10
0
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);
            }
        }
    }
}
예제 #11
0
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;
}
예제 #12
0
파일: SearchRunner.c 프로젝트: kpcyrd/cjdns
/**
 * 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++;
}
예제 #13
0
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);
}
예제 #14
0
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;
}
예제 #15
0
파일: SearchRunner.c 프로젝트: FSFTN/cjdns
/**
 * 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++;
}
예제 #16
0
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;
}
예제 #17
0
/** 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;
        }
    }
}
예제 #18
0
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);
}
예제 #19
0
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));
}
예제 #20
0
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;
}
예제 #21
0
파일: Ducttape.c 프로젝트: wpapper/cjdns
/**
 * 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;
}
예제 #22
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);
}
예제 #23
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;
        }
    }
}
예제 #24
0
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;
}
예제 #25
0
파일: SearchRunner.c 프로젝트: kpcyrd/cjdns
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);
    }
}
예제 #26
0
파일: Base32_test.c 프로젝트: AdUser/cjdns
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;
}
예제 #27
0
파일: AdminLog.c 프로젝트: CSRedRat/cjdns
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);
}
예제 #28
0
파일: Ducttape.c 프로젝트: lgierth/cjdns
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);
    }
예제 #29
0
파일: TAPDevice.c 프로젝트: cmotc/cjdns
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;
}
예제 #30
0
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));