예제 #1
0
static void authorizedPasswords(List* list, struct Context* ctx)
{
    uint32_t count = List_size(list);
    for (uint32_t i = 0; i < count; i++) {
        Dict* d = List_getDict(list, i);
        Log_info(ctx->logger, "Checking authorized password %d.", i);
        if (!d) {
            Log_critical(ctx->logger, "Not a dictionary type %d.", i);
            exit(-1);
        }
        String* passwd = Dict_getString(d, String_CONST("password"));
        if (!passwd) {
            Log_critical(ctx->logger, "Must specify a password %d.", i);
            exit(-1);
        }
    }

    Log_info(ctx->logger, "Flushing existing authorized passwords");
    rpcCall(String_CONST("AuthorizedPasswords_flush"), NULL, ctx, ctx->alloc);

    for (uint32_t i = 0; i < count; i++) {
        Dict* d = List_getDict(list, i);
        String* passwd = Dict_getString(d, String_CONST("password"));
        Log_info(ctx->logger, "Adding authorized password #[%d].", i);

        Dict args = Dict_CONST(
            String_CONST("authType"), Int_OBJ(1), Dict_CONST(
            String_CONST("password"), String_OBJ(passwd), NULL
        ));
        struct Allocator* child = ctx->alloc->child(ctx->alloc);
        rpcCall(String_CONST("AuthorizedPasswords_add"), &args, ctx, child);
        child->free(child);
    }
}
예제 #2
0
static void lookup(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
{
    struct Context* ctx = vcontext;
    String* addrStr = Dict_getString(args, String_CONST("address"));
    char* err = NULL;
    uint8_t addr[16];
    uint8_t resultBuff[60];
    char* result = (char*) resultBuff;
    if (addrStr->len != 39) {
        err = "address wrong length";
    } else if (AddrTools_parseIp(addr, (uint8_t*) addrStr->bytes)) {
        err = "failed to parse address";
    } else {
        struct Node_Two* n = Router_lookup(ctx->router, addr);
        if (!n) {
            result = "not found";
        } else if (Bits_memcmp(addr, n->address.ip6.bytes, 16)) {
            Address_print(resultBuff, &n->address);
        } else {
            AddrTools_printPath(resultBuff, n->address.path);
        }
    }
    Dict response = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST((err) ? err : "none")), Dict_CONST(
        String_CONST("result"), String_OBJ(String_CONST(result)), NULL
    ));
    Admin_sendMessage(&response, txid, ctx->admin);
}
예제 #3
0
static void newInterface2(struct Context* ctx,
                          struct Sockaddr* addr,
                          String* txid)
{
    struct Allocator* const alloc = Allocator_child(ctx->allocator);
    struct UDPInterface* udpIf = NULL;
    struct Jmp jmp;
    Jmp_try(jmp) {
        udpIf = UDPInterface_new(ctx->eventBase, addr, alloc, &jmp.handler, ctx->logger, ctx->ic);
    } Jmp_catch {
        String* errStr = String_CONST(jmp.message);
        Dict out = Dict_CONST(String_CONST("error"), String_OBJ(errStr), NULL);
        Admin_sendMessage(&out, txid, ctx->admin);
        Allocator_free(alloc);
    }

    // sizeof(struct UDPInterface*) the size of a pointer.
    ctx->ifaces = Allocator_realloc(ctx->allocator,
                                    ctx->ifaces,
                                    sizeof(struct UDPInterface*) * (ctx->ifCount + 1));
    ctx->ifaces[ctx->ifCount] = udpIf;

    Dict out = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST(
        String_CONST("interfaceNumber"), Int_OBJ(ctx->ifCount), NULL
    ));

    Admin_sendMessage(&out, txid, ctx->admin);
    ctx->ifCount++;
}
예제 #4
0
static void sendResponse(int conn, String* txid, struct Admin* admin)
{
    Dict resp = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST(
        String_CONST("connection"), Int_OBJ(conn), NULL
    ));
    Admin_sendMessage(&resp, txid, admin);
}
예제 #5
0
static void adminPeerStats(Dict* args, void* vcontext, String* txid)
{
    struct Context* context = vcontext;
    struct Allocator* alloc = Allocator_child(context->alloc);
    struct InterfaceController_peerStats* stats = NULL;

    int64_t* page = Dict_getInt(args, String_CONST("page"));
    int i = (page) ? *page * ENTRIES_PER_PAGE : 0;

    int count = context->ic->getPeerStats(context->ic, alloc, &stats);

    String* bytesIn = String_CONST("bytesIn");
    String* bytesOut = String_CONST("bytesOut");
    String* pubKey = String_CONST("publicKey");
    String* state = String_CONST("state");
    String* last = String_CONST("last");
    String* switchLabel = String_CONST("switchLabel");
    String* isIncoming = String_CONST("isIncoming");

    List* list = NULL;
    for (int counter=0; i < count && counter++ < ENTRIES_PER_PAGE; i++) {
        Dict* d = Dict_new(alloc);
        Dict_putInt(d, bytesIn, stats[i].bytesIn, alloc);
        Dict_putInt(d, bytesOut, stats[i].bytesOut, alloc);
        Dict_putString(d, pubKey, Key_stringify(stats[i].pubKey, alloc), alloc);

        String* stateString = String_new(InterfaceController_stateString(stats[i].state), alloc);
        Dict_putString(d, state, stateString, alloc);

        Dict_putInt(d, last, stats[i].timeOfLastMessage, alloc);

        uint8_t labelStack[20];
        AddrTools_printPath(labelStack, stats[i].switchLabel);
        Dict_putString(d, switchLabel, String_new((char*)labelStack, alloc), alloc);

        Dict_putInt(d, isIncoming, stats[i].isIncomingConnection, alloc);

        list = List_addDict(list, d, alloc);
    }

    Dict response = Dict_CONST(
        String_CONST("peers"), List_OBJ(list), Dict_CONST(
        String_CONST("total"), Int_OBJ(count), NULL
    ));

    if (i < count) {
      response = Dict_CONST(
        String_CONST("more"), Int_OBJ(1), response
      );
    }

    Admin_sendMessage(&response, txid, context->admin);

    Allocator_free(alloc);
}
예제 #6
0
파일: AdminLog.c 프로젝트: CSRedRat/cjdns
static void subscribe(Dict* args, void* vcontext, String* txid)
{
    struct AdminLog* log = (struct AdminLog*) vcontext;
    String* levelName = Dict_getString(args, String_CONST("level"));
    enum Log_Level level = (levelName) ? Log_levelForName(levelName->bytes) : Log_Level_DEBUG;
    int64_t* lineNumPtr = Dict_getInt(args, String_CONST("line"));
    String* fileStr = Dict_getString(args, String_CONST("file"));
    const char* file = (fileStr && fileStr->len > 0) ? fileStr->bytes : NULL;
    char* error = "2+2=5";
    if (level == Log_Level_INVALID) {
        level = Log_Level_KEYS;
    }
    if (lineNumPtr && *lineNumPtr < 0) {
        error = "Invalid line number, must be positive or 0 to signify any line is acceptable.";
    } else if (log->subscriptionCount >= MAX_SUBSCRIPTIONS) {
        error = "Max subscription count reached.";
    } else {
        struct Subscription* sub = &log->subscriptions[log->subscriptionCount];
        sub->level = level;
        sub->alloc = Allocator_child(log->alloc);
        if (file) {
            int i;
            for (i = 0; i < FILE_NAME_COUNT; i++) {
                if (log->fileNames[i] && !strcmp(log->fileNames[i], file)) {
                    file = log->fileNames[i];
                    sub->internalName = true;
                    break;
                }
            }
            if (i == FILE_NAME_COUNT) {
                file = String_new(file, sub->alloc)->bytes;
                sub->internalName = false;
            }
        }
        sub->file = file;
        sub->lineNum = (lineNumPtr) ? *lineNumPtr : 0;
        sub->txid = String_clone(txid, sub->alloc);
        Random_bytes(log->rand, (uint8_t*) sub->streamId, 8);
        uint8_t streamIdHex[20];
        Hex_encode(streamIdHex, 20, sub->streamId, 8);
        Dict response = Dict_CONST(
            String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST(
            String_CONST("streamId"), String_OBJ(String_CONST((char*)streamIdHex)), NULL
        ));
        Admin_sendMessage(&response, txid, log->admin);
        log->subscriptionCount++;
        return;
    }

    Dict response = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST(error)), NULL
    );
    Admin_sendMessage(&response, txid, log->admin);
}
예제 #7
0
/** @return a string representing the address and port to connect to. */
static void initAngel(struct Pipe* asClientPipe,
                      struct Interface* asCoreIface,
                      char* asCorePipeName,
                      struct EventBase* eventBase,
                      struct Log* logger,
                      struct Allocator* alloc,
                      struct Random* rand)
{
    Dict admin = Dict_CONST(
        String_CONST("bind"), String_OBJ(String_CONST("127.0.0.1")), Dict_CONST(
        String_CONST("corePipeName"), String_OBJ(String_CONST(asCorePipeName)), Dict_CONST(
        String_CONST("pass"), String_OBJ(String_CONST("abcd")), NULL
    )));
    Dict message = Dict_CONST(
        String_CONST("admin"), Dict_OBJ(&admin), NULL
    );

    struct Allocator* tempAlloc = Allocator_child(alloc);

    struct Message* toAngel = Message_new(0, 1024, tempAlloc);
    BencMessageWriter_write(&message, toAngel, NULL);

    Log_info(logger, "Writing intial configuration to angel on [%s]", asClientPipe->name);
    Interface_sendMessage(&asClientPipe->iface, toAngel);

    // This is client->angel->core data, we can throw this away.
    //struct Message* angelToCore =
    InterfaceWaiter_waitForData(asCoreIface, eventBase, tempAlloc, NULL);

    // unterminated string
    //Log_info(logger, "Init message from angel to core: [%s]", angelToCore->bytes);

    // Send response on behalf of core.
    Dict* coreToAngelResp = Dict_new(tempAlloc);
    Dict_putString(coreToAngelResp, String_CONST("error"), String_CONST("none"), tempAlloc);
    struct Message* coreToAngelMsg = Message_new(0, 256, tempAlloc);
    BencMessageWriter_write(coreToAngelResp, coreToAngelMsg, NULL);
    Interface_sendMessage(asCoreIface, coreToAngelMsg);

    // This is angel->client data, it will tell us which port was bound.
    struct Message* angelToClient =
        InterfaceWaiter_waitForData(&asClientPipe->iface, eventBase, tempAlloc, NULL);

    uint8_t lastByte = angelToClient->bytes[angelToClient->length-1];
    angelToClient->bytes[angelToClient->length-1] = '\0';
    printf("Response from angel to client: [%s%c]\n", angelToClient->bytes, (char)lastByte);

    Allocator_free(tempAlloc);

    return;
}
예제 #8
0
static void dumpTable_send(struct Context* ctx,
                           struct List_Item* last,
                           bool isMore,
                           String* txid)
{
    Dict table = Dict_CONST(String_CONST("routingTable"), List_OBJ(&last), NULL);
    if (isMore) {
        table = Dict_CONST(String_CONST("more"), Int_OBJ(1), table);
    } else {
        // the self route is synthetic so add 1 to the count.
        table = Dict_CONST(String_CONST("count"), Int_OBJ(ctx->store->size + 1), table);
    }
    Admin_sendMessage(&table, txid, ctx->admin);
}
예제 #9
0
static void listConnections(Dict* args, void* vcontext, String* txid)
{
    struct Context* context = vcontext;
    struct Allocator* alloc;
    BufferAllocator_STACK(alloc, 1024);
    List* l = NULL;
    for (int i = 0; i < (int)context->ipTun->connectionList.count; i++) {
        l = List_addInt(l, context->ipTun->connectionList.connections[i].number, alloc);
    }
    Dict resp = Dict_CONST(
        String_CONST("connections"), List_OBJ(l), Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST("none")), NULL
    ));
    Admin_sendMessage(&resp, txid, context->admin);
}
예제 #10
0
파일: Hermes.c 프로젝트: lgierth/cjdns
static void timeout(void* vrequest)
{
    struct Request* req = Identity_check((struct Request*) vrequest);
    Dict resp = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("timeout")), NULL);
    req->onResponse(&resp, req->onResponseContext);
    Allocator_free(req->alloc);
}
예제 #11
0
파일: Admin.c 프로젝트: sjmackenzie/cjdns
static bool checkArgs(Dict* args, struct Function* func, String* txid, struct Admin* admin)
{
    struct Dict_Entry* entry = *func->args;
    String* error = NULL;
    uint8_t buffer[1024];
    struct Allocator* alloc = BufferAllocator_new(buffer, 1024);
    while (entry != NULL) {
        String* key = (String*) entry->key;
        Assert_true(entry->val->type == Object_DICT);
        Dict* value = entry->val->as.dictionary;
        entry = entry->next;
        if (*Dict_getInt(value, String_CONST("required")) == 0) {
            continue;
        }
        String* type = Dict_getString(value, String_CONST("type"));
        if ((type == STRING && !Dict_getString(args, key))
            || (type == DICT && !Dict_getDict(args, key))
            || (type == INTEGER && !Dict_getInt(args, key))
            || (type == LIST && !Dict_getList(args, key)))
        {
            error = String_printf(alloc,
                                  "Entry [%s] is required and must be of type [%s]",
                                  key->bytes,
                                  type->bytes);
            break;
        }
    }
    if (error) {
        Dict d = Dict_CONST(String_CONST("error"), String_OBJ(error), NULL);
        Admin_sendMessage(&d, txid, admin);
    }
    return !error;
}
예제 #12
0
파일: Admin_test.c 프로젝트: AdUser/cjdns
static void adminFunc(Dict* input, void* vcontext, String* txid, struct Allocator* requestAlloc)
{
    struct Context* ctx = vcontext;
    ctx->called = true;
    Dict d = Dict_CONST(String_CONST("called!"), Int_OBJ(1), NULL);
    Admin_sendMessage(&d, txid, ctx->framework->admin);
}
예제 #13
0
static void ethInterfaceSetBeacon(int ifNum, Dict* eth, struct Context* ctx)
{
    int64_t* beaconP = Dict_getInt(eth, String_CONST("beacon"));
    if (beaconP) {
        int64_t beacon = *beaconP;
        if (beacon > 3 || beacon < 0) {
            Log_error(ctx->logger, "interfaces.ETHInterface.beacon may only be 0, 1,or 2");
        } else {
            // We can cast beacon to an int here because we know it's small enough
            Log_info(ctx->logger, "Setting beacon mode on ETHInterface to [%d].", (int) beacon);
            Dict d = Dict_CONST(String_CONST("interfaceNumber"), Int_OBJ(ifNum),
                     Dict_CONST(String_CONST("state"), Int_OBJ(beacon), NULL));
            rpcCall(String_CONST("ETHInterface_beacon"), &d, ctx, ctx->alloc);
        }
    }
}
예제 #14
0
static void newInterface2(struct Context* ctx,
                          struct Sockaddr* addr,
                          String* txid,
                          struct Allocator* requestAlloc)
{
    struct Allocator* const alloc = Allocator_child(ctx->alloc);
    struct UDPAddrIface* udpIf = NULL;
    struct Jmp jmp;
    Jmp_try(jmp) {
        udpIf = UDPAddrIface_new(ctx->eventBase, addr, alloc, &jmp.handler, ctx->logger);
    } Jmp_catch {
        String* errStr = String_CONST(jmp.message);
        Dict out = Dict_CONST(String_CONST("error"), String_OBJ(errStr), NULL);
        Admin_sendMessage(&out, txid, ctx->admin);
        Allocator_free(alloc);
        return;
    }

    struct AddrIface* ai = ctx->udpIf = &udpIf->generic;
    struct InterfaceController_Iface* ici =
        InterfaceController_newIface(ctx->ic, String_CONST("UDP"), alloc);
    Iface_plumb(&ici->addrIf, &ai->iface);

    Dict* out = Dict_new(requestAlloc);
    Dict_putString(out, String_CONST("error"), String_CONST("none"), requestAlloc);
    Dict_putInt(out, String_CONST("interfaceNumber"), ici->ifNum, requestAlloc);
    char* printedAddr = Sockaddr_print(ai->addr, requestAlloc);
    Dict_putString(out,
                   String_CONST("bindAddress"),
                   String_CONST(printedAddr),
                   requestAlloc);

    Admin_sendMessage(out, txid, ctx->admin);
}
예제 #15
0
static void ipTunnel(Dict* ifaceConf, struct Allocator* tempAlloc, struct Context* ctx)
{
    List* incoming = Dict_getList(ifaceConf, String_CONST("allowedConnections"));
    Dict* d;
    for (int i = 0; (d = List_getDict(incoming, i)) != NULL; i++) {
        String* key = Dict_getString(d, String_CONST("publicKey"));
        String* ip4 = Dict_getString(d, String_CONST("ip4Address"));
        String* ip6 = Dict_getString(d, String_CONST("ip6Address"));
        if (!key) {
            Log_critical(ctx->logger, "In router.ipTunnel.allowedConnections[%d]"
                                      "'publicKey' required.", i);
            exit(1);
        }
        if (!ip4 && !ip6) {
            Log_critical(ctx->logger, "In router.ipTunnel.allowedConnections[%d]"
                                       "either ip4Address or ip6Address required.", i);
            exit(1);
        }
        Log_debug(ctx->logger, "Allowing IpTunnel connections from [%s]", key->bytes);
        Dict_putString(d, String_CONST("publicKeyOfAuthorizedNode"), key, tempAlloc);
        rpcCall0(String_CONST("IpTunnel_allowConnection"), d, ctx, tempAlloc, true);
    }

    List* outgoing = Dict_getList(ifaceConf, String_CONST("outgoingConnections"));
    String* s;
    for (int i = 0; (s = List_getString(outgoing, i)) != NULL; i++) {
        Log_debug(ctx->logger, "Initiating IpTunnel connection to [%s]", s->bytes);
        Dict requestDict =
            Dict_CONST(String_CONST("publicKeyOfNodeToConnectTo"), String_OBJ(s), NULL);
        rpcCall0(String_CONST("IpTunnel_connectTo"), &requestDict, ctx, tempAlloc, true);
    }
}
예제 #16
0
static void sendError(char* error, String* txid, struct Admin* admin)
{
    Dict resp = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST(error)), NULL
    );
    Admin_sendMessage(&resp, txid, admin);
}
예제 #17
0
static void snapshot(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
{
    struct Allocator_admin_pvt* ctx = Identity_check((struct Allocator_admin_pvt*)vcontext);
    uint64_t* includeAllocations = Dict_getIntC(args, "includeAllocations");
    Allocator_snapshot(ctx->alloc, (includeAllocations && *includeAllocations != 0));
    Dict d = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL);
    Admin_sendMessage(&d, txid, ctx->admin);
}
예제 #18
0
파일: Core.c 프로젝트: marcuswanner/cjdns
static void adminMemory(Dict* input, void* vcontext, String* txid)
{
    struct MemoryContext* context = vcontext;
    Dict d = Dict_CONST(
        String_CONST("bytes"), Int_OBJ(MallocAllocator_bytesAllocated(context->allocator)), NULL
    );
    Admin_sendMessage(&d, txid, context->admin);
}
예제 #19
0
파일: Core.c 프로젝트: DevSlashNull/cjdns
static void adminExit(Dict* input, void* vcontext, String* txid, struct Allocator* requestAlloc)
{
    struct Context* context = Identity_check((struct Context*) vcontext);
    Log_info(context->logger, "Got request to exit");
    Dict d = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL);
    Admin_sendMessage(&d, txid, context->admin);
    Timeout_setTimeout(shutdown, context, 1, context->base, context->alloc);
}
예제 #20
0
static void list(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
{
    struct Context* context = (struct Context*) vcontext;
    struct Allocator* child = Allocator_child(context->allocator);

    List* users = CryptoAuth_getUsers(context->ca, child);
    uint32_t count = List_size(users);

    Dict response = Dict_CONST(
        String_CONST("total"), Int_OBJ(count), Dict_CONST(
        String_CONST("users"), List_OBJ(users), NULL
    ));

    Admin_sendMessage(&response, txid, context->admin);

    Allocator_free(child);
}
예제 #21
0
static void onAngelExitResponse(Dict* message, void* vcontext)
{
    struct Context* context = vcontext;
    Log_info(context->logger, "Angel stopped");
    Log_info(context->logger, "Exiting");
    Dict d = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL);
    Admin_sendMessage(&d, context->exitTxid, context->admin);
    exit(0);
}
예제 #22
0
파일: Core.c 프로젝트: AdUser/cjdns
static void onAngelExitResponse(Dict* message, void* vcontext)
{
    struct Context* context = vcontext;
    Log_info(context->logger, "Angel stopped");
    Log_info(context->logger, "Exiting");
    Dict d = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL);
    Admin_sendMessage(&d, context->exitTxid, context->admin);
    Timeout_setTimeout(shutdown, context, 1, context->base, context->allocator);
}
예제 #23
0
static void pingResponse(struct RouterModule_Promise* promise,
                         uint32_t lag,
                         struct Node* node,
                         Dict* responseDict)
{
    struct Ping* ping = Identity_cast((struct Ping*)promise->userData);

    uint8_t versionStr[40] = "old";
    String* version = String_CONST((char*)versionStr);
    String* versionBin = Dict_getString(responseDict, CJDHTConstants_VERSION);
    if (versionBin && versionBin->len == 20) {
        Hex_encode(versionStr, 40, (uint8_t*) versionBin->bytes, 20);
        version->len = 40;
    }
    int64_t* protocolVersion = Dict_getInt(responseDict, CJDHTConstants_PROTOCOL);
    int64_t pv = (protocolVersion) ? *protocolVersion : -1;

    Dict response = NULL;
    Dict verResponse = Dict_CONST(String_CONST("version"), String_OBJ(version), response);
    if (versionBin) {
        response = verResponse;
    }

    String* result = (responseDict) ? String_CONST("pong") : String_CONST("timeout");
    response = Dict_CONST(String_CONST("result"), String_OBJ(result), response);

    Dict protoResponse = Dict_CONST(String_CONST("protocol"), Int_OBJ(pv), response);
    if (protocolVersion) {
        response = protoResponse;
    }

    response = Dict_CONST(String_CONST("ms"), Int_OBJ(lag), response);

    char from[60] = "";
    if (node) {
        Address_print((uint8_t*)from, &node->address);
    }
    Dict fromResponse = Dict_CONST(String_CONST("from"), String_OBJ(String_CONST(from)), response);
    if (node) {
        response = fromResponse;
    }

    Admin_sendMessage(&response, ping->txid, ping->ctx->admin);
}
예제 #24
0
static void newInterface(Dict* args, void* vcontext, String* txid)
{
    struct Context* const ctx = vcontext;
    String* const bindAddress = Dict_getString(args, String_CONST("bindAddress"));
    struct Allocator* const alloc = ctx->allocator->child(ctx->allocator);

    struct UDPInterface* udpIf = NULL;
    struct Jmp jmp;
    Jmp_try(jmp) {
        char* const bindBytes = (bindAddress) ? bindAddress->bytes : NULL;
        udpIf = UDPInterface_new(
            ctx->eventBase, bindBytes, alloc, &jmp.handler, ctx->logger, ctx->ic);
    } Jmp_catch {
        String* errStr = String_CONST(jmp.message);
        Dict out = Dict_CONST(String_CONST("error"), String_OBJ(errStr), NULL);

        if (jmp.code == UDPInterface_new_SOCKET_FAILED
            || jmp.code == UDPInterface_new_BIND_FAILED)
        {
            char* err = strerror(EVUTIL_SOCKET_ERROR());
            Dict out2 = Dict_CONST(String_CONST("cause"), String_OBJ(String_CONST(err)), out);
            Admin_sendMessage(&out2, txid, ctx->admin);
        } else {
            Admin_sendMessage(&out, txid, ctx->admin);
        }

        alloc->free(alloc);
        return;
    }

    // sizeof(struct UDPInterface*) the size of a pointer.
    ctx->ifaces = ctx->allocator->realloc(ctx->ifaces,
                                          sizeof(struct UDPInterface*) * (ctx->ifCount + 1),
                                          ctx->allocator);
    ctx->ifaces[ctx->ifCount] = udpIf;

    Dict out = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST(
        String_CONST("interfaceNumber"), Int_OBJ(ctx->ifCount), NULL
    ));

    Admin_sendMessage(&out, txid, ctx->admin);
    ctx->ifCount++;
}
예제 #25
0
static void beginConnection(Dict* args, void* vcontext, String* txid)
{
    struct Context* ctx = vcontext;

    String* password = Dict_getString(args, String_CONST("password"));
    String* publicKey = Dict_getString(args, String_CONST("publicKey"));
    String* address = Dict_getString(args, String_CONST("address"));
    int64_t* interfaceNumber = Dict_getInt(args, String_CONST("interfaceNumber"));
    uint32_t ifNum = (interfaceNumber) ? ((uint32_t) *interfaceNumber) : 0;
    String* error = NULL;

    uint8_t pkBytes[32];

    if (ctx->ifCount == 0) {
        error = String_CONST("no interfaces are setup, call UDPInterface_new() first");

    } else if (interfaceNumber && (*interfaceNumber >= ctx->ifCount || *interfaceNumber < 0)) {
        error = String_CONST("invalid interfaceNumber");

    } else if (!publicKey
        || publicKey->len < 52
        || (publicKey->len > 52 && publicKey->bytes[52] != '.'))
    {
        error = String_CONST("publicKey must be 52 characters long.");

    } else if (Base32_decode(pkBytes, 32, (uint8_t*)publicKey->bytes, 52) != 32) {
        error = String_CONST("failed to parse publicKey.");

    } else {
        struct UDPInterface* udpif = ctx->ifaces[ifNum];
        switch (UDPInterface_beginConnection(address->bytes, pkBytes, password, udpif)) {
            case UDPInterface_beginConnection_OUT_OF_SPACE:
                error = String_CONST("no more space to register with the switch.");
                break;
            case UDPInterface_beginConnection_BAD_KEY:
                error = String_CONST("invalid cjdns public key.");
                break;
            case UDPInterface_beginConnection_BAD_ADDRESS:
                error = String_CONST("unable to parse ip address and port.");
                break;
            case UDPInterface_beginConnection_ADDRESS_MISMATCH:
                error = String_CONST("different address type than this socket is bound to.");
                break;
            case 0:
                error = String_CONST("none");
                break;
            default:
                error = String_CONST("unknown error");
        }
    }

    Dict out = Dict_CONST(String_CONST("error"), String_OBJ(error), NULL);
    Admin_sendMessage(&out, txid, ctx->admin);
}
예제 #26
0
static void newInterface(Dict* args, void* vcontext, String* txid)
{
    struct Context* ctx = vcontext;
    String* bindAddress = Dict_getString(args, String_CONST("bindAddress"));
    struct Sockaddr_storage addr;
    if (Sockaddr_parse((bindAddress) ? bindAddress->bytes : "0.0.0.0", &addr)) {
        Dict out = Dict_CONST(
            String_CONST("error"), String_OBJ(String_CONST("Failed to parse address")), NULL
        );
        Admin_sendMessage(&out, txid, ctx->admin);
        return;
    }
    newInterface2(ctx, &addr.addr, txid);
}
예제 #27
0
파일: Core.c 프로젝트: AdUser/cjdns
static void adminExit(Dict* input, void* vcontext, String* txid, struct Allocator* requestAlloc)
{
    struct Context* context = vcontext;
    Log_info(context->logger, "Got request to exit");
    Log_info(context->logger, "Stopping angel");
    context->exitTxid = String_clone(txid, context->allocator);
    Dict angelExit = Dict_CONST(String_CONST("q"), String_OBJ(String_CONST("Angel_exit")), NULL);
    Hermes_callAngel(&angelExit,
                     onAngelExitResponse,
                     context,
                     context->allocator,
                     NULL,
                     context->hermes);
}
예제 #28
0
static void authorizedPasswords(List* list, struct Context* ctx)
{
    uint32_t count = List_size(list);
    for (uint32_t i = 0; i < count; i++) {
        Dict* d = List_getDict(list, i);
        Log_info(ctx->logger, "Checking authorized password %d.", i);
        if (!d) {
            Log_critical(ctx->logger, "Not a dictionary type %d.", i);
            exit(-1);
        }
        String* passwd = Dict_getString(d, String_CONST("password"));
        if (!passwd) {
            Log_critical(ctx->logger, "Must specify a password %d.", i);
            exit(-1);
        }
    }

    for (uint32_t i = 0; i < count; i++) {
        struct Allocator* child = Allocator_child(ctx->alloc);
        Dict* d = List_getDict(list, i);
        String* passwd = Dict_getString(d, String_CONST("password"));
        String* user = Dict_getString(d, String_CONST("user"));
        if (!user) {
          user = String_printf(child, "password [%d]", i);
        }

        Log_info(ctx->logger, "Adding authorized password #[%d] for user [%s].", i, user->bytes);

        Dict args = Dict_CONST(
            String_CONST("authType"), Int_OBJ(1), Dict_CONST(
            String_CONST("password"), String_OBJ(passwd), Dict_CONST(
            String_CONST("user"), String_OBJ(user), NULL
        )));
        rpcCall(String_CONST("AuthorizedPasswords_add"), &args, ctx, child);
        Allocator_free(child);
    }
}
예제 #29
0
파일: Configurator.c 프로젝트: Kubuxu/cjdns
static void supernodes(List* supernodes, struct Allocator* tempAlloc, struct Context* ctx)
{
    if (!supernodes) {
        return;
    }
    String* s;
    for (int i = 0; (s = List_getString(supernodes, i)) != NULL; i++) {
        Log_debug(ctx->logger, "Loading supernode connection to [%s]", s->bytes);
        Dict reqDict = Dict_CONST(String_CONST("key"), String_OBJ(s), NULL);
        if (!Defined(SUBNODE)) {
            Log_debug(ctx->logger, "Skipping because SUBNODE is not enabled");
            continue;
        }
        rpcCall0(String_CONST("SupernodeHunter_addSnode"), &reqDict, ctx, tempAlloc, NULL, true);
    }
}
예제 #30
0
static void security(List* securityConf, struct Allocator* tempAlloc, struct Context* ctx)
{
    bool noFiles = false;
    for (int i = 0; i < List_size(securityConf); i++) {
        if (String_equals(String_CONST("nofiles"), List_getString(securityConf, i))) {
            noFiles = true;
        } else {
            Dict* userDict = List_getDict(securityConf, i);
            String* userName = Dict_getString(userDict, String_CONST("setuser"));
            if (userName) {
                Dict d = Dict_CONST(String_CONST("user"), String_OBJ(userName), NULL);
                // If this call returns an error, it is ok.
                rpcCall0(String_CONST("Security_setUser"), &d, ctx, tempAlloc, false);
            }
        }
    }
    if (noFiles) {
        Dict d = NULL;
        rpcCall(String_CONST("Security_noFiles"), &d, ctx, tempAlloc);
    }
}