コード例 #1
0
ファイル: cjdroute.c プロジェクト: Ralith/cjdns
static uint8_t serverFirstIncoming(struct Message* msg, struct Interface* iface)
{
    struct UDPInterfaceContext* uictx = (struct UDPInterfaceContext*) iface->receiverContext;

    struct Interface* udpDefault = UDPInterface_getDefaultInterface(uictx->udpContext);
    assert(udpDefault);
    UDPInterface_bindToCurrentEndpoint(udpDefault);

    struct User* u = CryptoAuth_getUser(iface);
    assert(u);
    // Add it to the switch, this will change the receiveMessage for this interface.
    struct Address addr;
    memset(&addr, 0, sizeof(struct Address));
    SwitchCore_addInterface(iface, u->trust, &addr.networkAddress_be, uictx->context->switchCore);

    uint8_t* herKey = CryptoAuth_getHerPublicKey(iface);
    memcpy(addr.key, herKey, 32);
    uint8_t printedAddr[60];
    Address_print(printedAddr, &addr);
    Log_info1(uictx->context->logger,
              "Node %s has connected to us.\n",
              printedAddr);

    // Prepare for the next connection.
    struct Interface* newUdpDefault = UDPInterface_getDefaultInterface(uictx->udpContext);
    struct Interface* newAuthedUdpDefault =
        CryptoAuth_wrapInterface(newUdpDefault, NULL, true, true, uictx->context->ca);
    newAuthedUdpDefault->receiveMessage = serverFirstIncoming;
    newAuthedUdpDefault->receiverContext = uictx;

    // Send the message on to the switch so the first message isn't lost.
    return iface->receiveMessage(msg, iface);
}
コード例 #2
0
ファイル: CryptoAuth_benchmark.c プロジェクト: Arceliar/cjdns
static inline void sendMessages(struct Context* ctx,
                                int count,
                                int size,
                                const char* type,
                                bool authPackets)
{
    printf("Test sending %d %d byte\t%s packets.\tpacket auth %s",
           count, size, type, ((authPackets) ? "enabled." : "disabled."));

    ctx->cif2 = CryptoAuth_wrapInterface(&ctx->if2, NULL, false, authPackets, ctx->ca2);
    ctx->cif1 = CryptoAuth_wrapInterface(&ctx->if1, publicKey, false, authPackets, ctx->ca1);
    uint64_t startTime = Time_hrtime();
    if (type != HELLO) {
        setupMessage(ctx, size);
        ctx->cif1->sendMessage(&ctx->message, ctx->cif1);
        if (type == TRAFFIC) {
            setupMessage(ctx, size);
            ctx->cif2->sendMessage(&ctx->message, ctx->cif2);
        }
    }
    for (int i = 0; i < count; i++) {
        setupMessage(ctx, size);
        if (type == KEY) {
            ctx->cif2->sendMessage(&ctx->message, ctx->cif2);
        } else {
            ctx->cif1->sendMessage(&ctx->message, ctx->cif1);
        }
    }
    uint64_t endTimes = Time_hrtime();
    uint64_t time = (endTimes - startTime) / 1000000;
    uint64_t kbSent = (size * count * 8) / 1024;

    // same as kbSent / (time / 1024) (converting time to seconds)
    uint64_t kbps = (kbSent * 1024) / time;

    printf("\tFinished in %dms. %d Kb/s\n\n", (int)time, (int)kbps);
}
コード例 #3
0
ファイル: cjdroute.c プロジェクト: Ralith/cjdns
static void configureUDP(Dict* config, struct Context* ctx)
{
    String* bindStr = Dict_getString(config, BSTR("bind"));
    char* bindAddress = bindStr ? bindStr->bytes : NULL;

    struct UDPInterface* udpContext =
        UDPInterface_new(ctx->base, bindAddress, ctx->allocator, ctx->eHandler, ctx->logger);

    if (bindStr) {
        struct Interface* udpDefault = UDPInterface_getDefaultInterface(udpContext);
        struct Interface* authedDef =
            CryptoAuth_wrapInterface(udpDefault, NULL, true, true, ctx->ca);

        struct UDPInterfaceContext* uictx =
            ctx->allocator->malloc(sizeof(struct UDPInterfaceContext), ctx->allocator);
        uictx->context = ctx;
        uictx->udpContext = udpContext;
        authedDef->receiveMessage = serverFirstIncoming;
        authedDef->receiverContext = uictx;
    }

    Dict* connectTo = Dict_getDict(config, BSTR("connectTo"));
    if (connectTo) {
        struct Dict_Entry* entry = *connectTo;
        while (entry != NULL) {
            String* key = (String*) entry->key;
            if (entry->val->type != Object_DICT) {
                fprintf(stderr,
                        "interfaces.UDPInterface.connectTo: entry %s is not a dictionary type.\n",
                        key->bytes);
                abort();
            }
            Dict* value = entry->val->as.dictionary;

            udpConnectTo(key, value, udpContext, ctx);

            entry = entry->next;
        }
    }
}
コード例 #4
0
ファイル: cjdroute.c プロジェクト: Ralith/cjdns
static void udpConnectTo(String* connectToAddress,
                         Dict* config,
                         struct UDPInterface* udpContext,
                         struct Context* ctx)
{
    String* password = Dict_getString(config, BSTR("password"));
    int64_t* authType = Dict_getInt(config, BSTR("authType"));
    String* publicKey = Dict_getString(config, BSTR("publicKey"));
    int64_t* trust = Dict_getInt(config, BSTR("trust"));

    #define FAIL_IF_NULL(cannotBeNull, fieldName) \
        if (!cannotBeNull) {                                                     \
            fprintf(stderr,                                                      \
                    "interfaces.UDPInterface['%s']." fieldName " is not set, "   \
                    "this field is mandatory.\n",                                \
                    connectToAddress->bytes);                                    \
            exit(-1);                                                            \
        }

    FAIL_IF_NULL(password, "password")
    FAIL_IF_NULL(authType, "authType")
    FAIL_IF_NULL(publicKey, "publicKey")
    FAIL_IF_NULL(trust, "trust")

    #undef FAIL_IF_NULL

    #define CHECK_RANGE(number, min, max) \
        if (number < min || number > max) {                                           \
        fprintf(stderr,                                                               \
                "interfaces.UDPInterface['%s'].number must be between min and max\n", \
                connectToAddress->bytes);                                             \
        exit(-1);                                                                     \
    }

    CHECK_RANGE(*authType, 1, 255)
    CHECK_RANGE(*trust, 0, INT64_MAX)

    #undef CHECK_RANGE

    uint8_t pkBytes[32];
    if (publicKey->len < 52 || Base32_decode(pkBytes, 32, (uint8_t*)publicKey->bytes, 52) != 32) {
        fprintf(stderr,
                "interfaces.UDPInterface['%s'].publicKey could not be parsed.\n",
                connectToAddress->bytes);
        exit(-1);
    }
    uint8_t addressBytes[16];
    AddressCalc_addressForPublicKey(addressBytes, pkBytes);
    if (addressBytes[0] != 0xFC) {
        fprintf(stderr,
                "interfaces.UDPInterface['%s'].publicKey\n( %s )\nis not in FC00/8 range, "
                "it was probably mistranscribed.\n",
                connectToAddress->bytes,
                publicKey->bytes);
        exit(-1);
    }

    struct Interface* udp =
        UDPInterface_addEndpoint(udpContext, connectToAddress->bytes, ctx->eHandler);
    struct Interface* authedUdp = CryptoAuth_wrapInterface(udp, pkBytes, false, true, ctx->ca);
    CryptoAuth_setAuth(password, *authType, authedUdp);

    uint64_t switchAddr_be;
    SwitchCore_addInterface(authedUdp, *trust, &switchAddr_be, ctx->switchCore);
    struct Address addr;
    memset(&addr, 0, sizeof(struct Address));
    memcpy(addr.key, pkBytes, 32);
    addr.networkAddress_be = switchAddr_be;
    RouterModule_addNode(&addr, ctx->routerModule);
}
コード例 #5
0
static int reconnectionNewEndpointTest(struct InterfaceController* ifController,
                                       uint8_t* pk,
                                       struct Message** fromSwitchPtr,
                                       struct Allocator* alloc,
                                       struct EventBase* eventBase,
                                       struct Log* logger,
                                       struct Interface* routerIf,
                                       struct Random* rand)
{
    struct Message* message;
    struct Interface iface = {
        .sendMessage = messageFromInterface,
        .senderContext = &message,
        .allocator = alloc
    };

    uint8_t* buffer = Allocator_malloc(alloc, 512);

    struct Message* outgoing =
        &(struct Message) { .length = 0, .padding = 512, .bytes = buffer + 512 };

    struct CryptoAuth* externalCa = CryptoAuth_new(alloc, NULL, eventBase, logger, rand);
    struct Interface* wrapped = CryptoAuth_wrapInterface(&iface, pk, NULL, false, "", externalCa);
    CryptoAuth_setAuth(String_CONST("passwd"), 1, wrapped);

    struct Interface icIface = {
        .allocator = alloc,
        .sendMessage = messageFromInterface,
        .senderContext = &message
    };

    InterfaceController_registerPeer(ifController, NULL, NULL, true, false, &icIface);

    uint8_t hexBuffer[1025];

    for (int i = 0; i < 4; i++) {

        outgoing->length = 0;
        outgoing->padding = 512;
        outgoing->bytes = buffer + 512;
        Message_shift(outgoing, 12, NULL);
        Bits_memcpyConst(outgoing->bytes, "hello world", 12);

        Message_shift(outgoing, SwitchHeader_SIZE, NULL);
        Bits_memcpyConst(outgoing->bytes, (&(struct SwitchHeader) {
            .label_be = Endian_hostToBigEndian64(1),
            .lowBits_be = 0
        }), SwitchHeader_SIZE);

        wrapped->sendMessage(outgoing, wrapped);

        *fromSwitchPtr = NULL;

        icIface.receiveMessage(outgoing, &icIface);

        message = *fromSwitchPtr;
        Assert_true(message);
        Assert_true(message->length == 24);

        Hex_encode(hexBuffer, 1025, message->bytes, message->length);
        printf("%s\n", hexBuffer);

        // Need to bounce the packets back when connecting after the first try.
        // This is needed to establish the CryptoAuth session and make the InterfaceController
        // merge the endpoints.
        if (i > 0) {
            // Reverse the bits to reverse the path:
            uint64_t path;
            Bits_memcpyConst(&path, message->bytes, 8);
            path = Bits_bitReverse64(path);
            Bits_memcpyConst(message->bytes, &path, 8);

            printf("sending back response.\n");
            routerIf->receiveMessage(message, routerIf);
            printf("forwarding response to external cryptoAuth.\n");
            iface.receiveMessage(message, &iface);
            printf("forwarded.\n");
        } else {
            printf("not responding because we don't want to establish a connection yet.\n");
        }
    }

    // check everything except the label
    Assert_true(!CString_strcmp((char*)hexBuffer+16, "0000000068656c6c6f20776f726c6400"));
    // check label: make sure the interface has been switched back into position 0.
    uint64_t label_be;
    Hex_decode((uint8_t*) &label_be, 8, hexBuffer, 16);
    uint64_t rev_label = Bits_bitReverse64(Endian_bigEndianToHost64(label_be));
    // check label is decoded to 0
    Assert_true(0 == NumberCompress_getDecompressed(rev_label,
                                                      NumberCompress_bitsUsedForLabel(rev_label)));
    // check no other bits are set
    uint64_t out = NumberCompress_getCompressed(0, NumberCompress_bitsUsedForLabel(rev_label));
    Assert_true(rev_label == out);
    return 0;
}
コード例 #6
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));
コード例 #7
0
    printf("\nSetting up:\n");
    struct Allocator* allocator = MallocAllocator_new(1048576);
    textBuff = Allocator_malloc(allocator, BUFFER_SIZE);
    struct Writer* logwriter = FileWriter_new(stdout, allocator);
    struct Log* logger = WriterLog_new(logwriter, allocator);
    struct Random* rand = Random_new(allocator, logger, NULL);

    struct EventBase* base = EventBase_new(allocator);

    ca1 = CryptoAuth_new(allocator, NULL, base, logger, rand);
    if1 = Allocator_clone(allocator, (&(struct Interface) {
        .sendMessage = sendMessageToIf2,
        .receiveMessage = recvMessageOnIf2,
        .allocator = allocator
    }));
    cif1 = CryptoAuth_wrapInterface(if1, publicKey, false, false, ca1);
    cif1->receiveMessage = recvMessageOnIf1;


    ca2 = CryptoAuth_new(allocator, privateKey, base, logger, rand);
    if (password) {
        String passStr = {.bytes=(char*)password,.len=strlen((char*)password)};
        CryptoAuth_setAuth(&passStr, 1, cif1);
        CryptoAuth_addUser(&passStr, 1, userObj, ca2);
    }
    if2 = Allocator_clone(allocator, (&(struct Interface) {
        .sendMessage = sendMessageToIf1,
        .allocator = allocator
    }));
    cif2 = CryptoAuth_wrapInterface(if2, NULL, false, authenticatePackets, ca2);
    cif2->receiveMessage = recvMessageOnIf2;
コード例 #8
0
                                                         struct SessionManager* sm)
{
    int ifaceIndex = Map_OfSessionsByIp6_indexForKey((struct Ip6*)lookupKey, &sm->ifaceMap);
    if (ifaceIndex == -1) {
        // Make sure cleanup() doesn't get behind.
        cleanup(sm);

        struct Allocator* ifAllocator = Allocator_child(sm->allocator);
        struct Interface* outsideIf =
            ifAllocator->clone(sizeof(struct Interface), ifAllocator, &(struct Interface) {
                .sendMessage = sm->encryptedOutgoing,
                .senderContext = sm->interfaceContext,
                .allocator = ifAllocator
            });
        struct Interface* insideIf =
            CryptoAuth_wrapInterface(outsideIf, cryptoKey, false, true, sm->cryptoAuth);
        insideIf->receiveMessage = sm->decryptedIncoming;
        insideIf->receiverContext = sm->interfaceContext;

        struct SessionManager_Session s = {
            .lastMessageTime = Time_currentTimeSeconds(sm->eventBase),

            // Create a trick interface which pretends to be on both sides of the crypto.
            .iface = {
                .sendMessage = insideIf->sendMessage,
                .senderContext = insideIf->senderContext,
                .receiveMessage = outsideIf->receiveMessage,
                .receiverContext = outsideIf->receiverContext,
                .allocator = ifAllocator
            }
        };
コード例 #9
0
ファイル: CryptoAuth_test.c プロジェクト: AdUser/cjdns
    printf("\nSetting up:\n");
    struct Allocator* allocator = MallocAllocator_new(1048576);
    textBuff = Allocator_malloc(allocator, BUFFER_SIZE);
    struct Writer* logwriter = FileWriter_new(stdout, allocator);
    struct Log* logger = WriterLog_new(logwriter, allocator);
    struct Random* rand = Random_new(allocator, logger, NULL);

    struct EventBase* base = EventBase_new(allocator);

    ca1 = CryptoAuth_new(allocator, NULL, base, logger, rand);
    if1 = Allocator_clone(allocator, (&(struct Interface) {
        .sendMessage = sendMessageToIf2,
        .receiveMessage = recvMessageOnIf2,
        .allocator = allocator
    }));
    cif1 = CryptoAuth_wrapInterface(if1, publicKey, NULL, false, "cif1", ca1);
    cif1->receiveMessage = recvMessageOnIf1;


    ca2 = CryptoAuth_new(allocator, privateKey, base, logger, rand);
    if (password) {
        String passStr = {.bytes=(char*)password,.len=strlen((char*)password)};
        CryptoAuth_setAuth(&passStr, 1, cif1);
        CryptoAuth_addUser(&passStr, 1, String_new(userObj, allocator), ca2);
    }
    if2 = Allocator_clone(allocator, (&(struct Interface) {
        .sendMessage = sendMessageToIf1,
        .allocator = allocator
    }));
    cif2 = CryptoAuth_wrapInterface(if2, NULL, NULL, false, "cif2", ca2);
    cif2->receiveMessage = recvMessageOnIf2;
コード例 #10
0
static int registerPeer(struct InterfaceController* ifController,
                        uint8_t herPublicKey[32],
                        String* password,
                        bool requireAuth,
                        bool transient,
                        struct Interface* externalInterface)
{
    struct Context* ic = Identity_cast((struct Context*) ifController);

    Log_debug(ic->logger, "registerPeer [%p] total [%u]",
              (void*)externalInterface, ic->peerMap.count);
    if (Map_OfIFCPeerByExernalIf_indexForKey(&externalInterface, &ic->peerMap) > -1) {
        Log_debug(ic->logger, "Skipping registerPeer [%p] because peer is already registered",
                  (void*)externalInterface);
        return 0;
    }

    uint8_t ip6[16];
    if (herPublicKey) {
        AddressCalc_addressForPublicKey(ip6, herPublicKey);
        if (!AddressCalc_validAddress(ip6)) {
            return InterfaceController_registerPeer_BAD_KEY;
        }
    }

    struct Allocator* epAllocator = externalInterface->allocator;
    struct IFCPeer* ep = Allocator_calloc(epAllocator, sizeof(struct IFCPeer), 1);
    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 not supply a valid password to connect
    // we will set the connection state to HANDSHAKE because we don't
    // want the connection to be trashed after the first invalid packet.
    if (!requireAuth) {
        ep->state = InterfaceController_PeerState_HANDSHAKE;
    }

    ep->cryptoAuthIf =
        CryptoAuth_wrapInterface(externalInterface, herPublicKey, requireAuth, true, 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->transient = transient;

    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));
コード例 #11
0
ファイル: SessionManager.c プロジェクト: lgierth/cjdns
                        .allocator = ifAlloc
                    },
                },
                .sm = sm
            }));
        Identity_set(ss);

        ss->pub.timeOfCreation = Time_currentTimeMilliseconds(sm->eventBase);

        // const hack
        Bits_memcpyConst((void*)&ss->pub.external.senderContext, &ss, sizeof(char*));

        Bits_memcpyConst(ss->pub.ip6, lookupKey, 16);
        ss->pub.internal = CryptoAuth_wrapInterface(&ss->pub.external,
                                                    cryptoKey,
                                                    lookupKey,
                                                    false,
                                                    "inner",
                                                    sm->cryptoAuth);

        ss->pub.internal->receiveMessage = receiveMessage;
        ss->pub.internal->receiverContext = ss;

        ifaceIndex = Map_OfSessionsByIp6_put((struct Ip6*)lookupKey, &ss, &sm->ifaceMap);

        ss->pub.receiveHandle_be =
            Endian_hostToBigEndian32(sm->ifaceMap.handles[ifaceIndex] + sm->first);

    } else {
        uint8_t* herPubKey =
            CryptoAuth_getHerPublicKey(sm->ifaceMap.values[ifaceIndex]->pub.internal);
        if (Bits_isZero(herPubKey, 32) && cryptoKey) {