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_info1(ctx->logger, "Checking authorized password %d.", i); if (!d) { Log_critical1(ctx->logger, "Not a dictionary type.", i); exit(-1); } String* passwd = Dict_getString(d, String_CONST("password")); if (!passwd) { Log_critical1(ctx->logger, "Must specify a password.", 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_info1(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); } }
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); }
/* * ======== myIdleFxn ======== * Background idle function that is called repeatedly * from within BIOS_start() thread. */ Void myIdleFxn(Void) { if (isrFlag == TRUE) { isrFlag = FALSE; /* * Print the current value of tickCount to a log buffer. */ Log_info1("Tick Count = %d\n", tickCount); } }
/**************************************************************************** * Test task ***************************************************************************/ void task_led_toggle(void) { while (1) { Semaphore_pend(sem_led_blink, BIOS_WAIT_FOREVER);// wait for LEDSem to be posted by ISR HAL_toggleGpio(halHandle, GPIO_Number_34); i16ToggleCount += 1; // keep track of #toggles Log_info1("LED TOGGLED [%u] TIMES",i16ToggleCount); // store #toggles to Log display } }
/* * ======== myIdleFxn ======== * Background idle function that is called repeatedly * from within BIOS_start() thread. */ Void myIdleFxn(Void) { if (tenTicks == TRUE) { tenTicks = FALSE; /* * Print the current value of tickCount to a log buffer. */ Log_info1("10 ticks. Tick Count = %d\n", tickCount); } }
/* * ======== mySwiFxn ======== * Swi function that peforms the non realtime-constrained * portion of the work associated with the timer interrupt. */ Void mySwiFxn(UArg arg) { /* * Print the current value of tickCount to a log buffer. */ Log_info1("Tick Count = %d\n", tickCount); /* every 10 timer interrupts send a signal to background */ if ((tickCount % 10) == 0) { tenTicks = TRUE; /* tell background that new data is available */ } }
/* * DataService_RegisterAppCBs - Registers the application callback function. * Only call this function once. * * appCallbacks - pointer to application callbacks. */ bStatus_t DataService_RegisterAppCBs( DataServiceCBs_t *appCallbacks ) { if ( appCallbacks ) { pAppCBs = appCallbacks; Log_info1("Registered callbacks to application. Struct %p", (IArg)appCallbacks); return ( SUCCESS ); } else { Log_warning0("Null pointer given for app callbacks."); return ( FAILURE ); } }
static void security(List* config, struct Log* logger, struct ExceptionHandler* eh) { if (!config) { return; } bool nofiles = false; for (int i = 0; i < List_size(config); i++) { String* s = List_getString(config, i); if (s && String_equals(s, BSTR("nofiles"))) { nofiles = true; } } char* user = setUser(config); if (user) { Log_info1(logger, "Changing user to [%s]\n", user); Security_setUser(user, logger, eh); } if (nofiles) { Log_info(logger, "Setting max open files to zero.\n"); Security_noFiles(eh); } }
/* * DataService_AddService- Initializes the DataService service by registering * GATT attributes with the GATT server. * * rspTaskId - The ICall Task Id that should receive responses for Indications. */ extern bStatus_t DataService_AddService( uint8_t rspTaskId ) { uint8_t status; // Allocate Client Characteristic Configuration table ds_StreamConfig = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) * linkDBNumConns ); if ( ds_StreamConfig == NULL ) { return ( bleMemAllocError ); } // Initialize Client Characteristic Configuration attributes GATTServApp_InitCharCfg( INVALID_CONNHANDLE, ds_StreamConfig ); // Register GATT attribute list and CBs with GATT Server App status = GATTServApp_RegisterService( Data_ServiceAttrTbl, GATT_NUM_ATTRS( Data_ServiceAttrTbl ), GATT_MAX_ENCRYPT_KEY_SIZE, &Data_ServiceCBs ); Log_info1("Registered service, %d attributes", (IArg)GATT_NUM_ATTRS( Data_ServiceAttrTbl )); ds_icall_rsp_task_id = rspTaskId; return ( status ); }
int main(int argc, char** argv) { #ifdef Log_KEYS fprintf(stderr, "Log_LEVEL = KEYS, EXPECT TO SEE PRIVATE KEYS IN YOUR LOGS!\n"); #endif Crypto_init(); assert(argc > 0); if (argc == 1) { // no arguments if (isatty(STDIN_FILENO)) { // We were started from a terminal // The chances an user wants to type in a configuration // bij hand are pretty slim so we show him the usage return usage(argv[0]); } else { // We assume stdin is a configuration file and that we should // start routing } } if (argc == 2) { // one argument if (strcmp(argv[1], "--help") == 0) { return usage(argv[0]); } else if (strcmp(argv[1], "--genconf") == 0) { return genconf(); } else if (strcmp(argv[1], "--getcmds") == 0) { // Performed after reading the configuration } else if (strcmp(argv[1], "--pidfile") == 0) { // Performed after reading the configuration } else { fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], argv[1]); fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]); return -1; } } if (argc > 2) { // more than one argument? fprintf(stderr, "%s: too many arguments\n", argv[0]); fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]); return -1; } struct Context context; memset(&context, 0, sizeof(struct Context)); context.base = event_base_new(); // Allow it to allocate 4MB context.allocator = MallocAllocator_new(1<<22); struct Reader* reader = FileReader_new(stdin, context.allocator); Dict config; if (JsonBencSerializer_get()->parseDictionary(reader, context.allocator, &config)) { fprintf(stderr, "Failed to parse configuration.\n"); return -1; } if (argc == 2 && strcmp(argv[1], "--getcmds") == 0) { return getcmds(&config); } if (argc == 2 && strcmp(argv[1], "--pidfile") == 0) { pidfile(&config); return 0; } char* user = setUser(Dict_getList(&config, BSTR("security"))); // Admin Dict* adminConf = Dict_getDict(&config, BSTR("admin")); if (adminConf) { admin(adminConf, user, &context); } // Logging struct Writer* logwriter = FileWriter_new(stdout, context.allocator); struct Log logger = { .writer = logwriter }; context.logger = &logger; struct Address myAddr; uint8_t privateKey[32]; parsePrivateKey(&config, &myAddr, privateKey); context.eHandler = AbortHandler_INSTANCE; context.switchCore = SwitchCore_new(context.logger, context.allocator); context.ca = CryptoAuth_new(&config, context.allocator, privateKey, context.base, context.logger); context.registry = DHTModules_new(context.allocator); ReplyModule_register(context.registry, context.allocator); // Router Dict* routerConf = Dict_getDict(&config, BSTR("router")); registerRouter(routerConf, myAddr.key, &context); SerializationModule_register(context.registry, context.allocator); // Authed passwords. List* authedPasswords = Dict_getList(&config, BSTR("authorizedPasswords")); if (authedPasswords) { authorizedPasswords(authedPasswords, &context); } // Interfaces. Dict* interfaces = Dict_getDict(&config, BSTR("interfaces")); Dict* udpConf = Dict_getDict(interfaces, BSTR("UDPInterface")); if (udpConf) { configureUDP(udpConf, &context); } if (udpConf == NULL) { fprintf(stderr, "No interfaces configured to connect to.\n"); return -1; } // pid file String* pidFile = Dict_getString(&config, BSTR("pidFile")); if (pidFile) { Log_info1(context.logger, "Writing pid of process to [%s].\n", pidFile->bytes); FILE* pf = fopen(pidFile->bytes, "w"); if (!pf) { Log_critical2(context.logger, "Failed to open pid file [%s] for writing, errno=%d\n", pidFile->bytes, errno); return -1; } fprintf(pf, "%d", getpid()); fclose(pf); } Ducttape_register(&config, privateKey, context.registry, context.routerModule, context.routerIf, context.switchCore, context.base, context.allocator, context.logger); uint8_t address[53]; Base32_encode(address, 53, myAddr.key, 32); Log_info1(context.logger, "Your address is: %s.k\n", address); uint8_t myIp[40]; Address_printIp(myIp, &myAddr); Log_info1(context.logger, "Your IPv6 address is: %s\n", myIp); // Security. security(Dict_getList(&config, BSTR("security")), context.logger, context.eHandler); event_base_loop(context.base, 0); // Never reached. return 0; }
/** * This is called as sendMessage() by the switch. * There is only one switch interface which sends all traffic. * message is aligned on the beginning of the switch header. */ static uint8_t incomingFromSwitch(struct Message* message, struct Interface* switchIf) { struct Ducttape* context = switchIf->senderContext; struct Headers_SwitchHeader* switchHeader = (struct Headers_SwitchHeader*) message->bytes; Message_shift(message, -Headers_SwitchHeader_SIZE); // The label comes in reversed from the switch because the switch doesn't know that we aren't // another switch ready to parse more bits, bit reversing the label yields the source address. switchHeader->label_be = Bits_bitReverse64(switchHeader->label_be); if (Headers_getMessageType(switchHeader) == Headers_SwitchHeader_TYPE_CONTROL) { uint8_t labelStr[20]; uint64_t label = Endian_bigEndianToHost64(switchHeader->label_be); AddrTools_printPath(labelStr, label); if (message->length < Control_HEADER_SIZE) { Log_info1(context->logger, "dropped runt ctrl packet from [%s]", labelStr); return Error_NONE; } else { Log_debug1(context->logger, "ctrl packet from [%s]", labelStr); } struct Control* ctrl = (struct Control*) message->bytes; bool pong = false; if (ctrl->type_be == Control_ERROR_be) { if (message->length < Control_Error_MIN_SIZE) { Log_info1(context->logger, "dropped runt error packet from [%s]", labelStr); return Error_NONE; } Log_info2(context->logger, "error packet from [%s], error type [%d]", labelStr, Endian_bigEndianToHost32(ctrl->content.error.errorType_be)); RouterModule_brokenPath(Endian_bigEndianToHost64(switchHeader->label_be), context->routerModule); uint8_t causeType = Headers_getMessageType(&ctrl->content.error.cause); if (causeType == Headers_SwitchHeader_TYPE_CONTROL) { if (message->length < Control_Error_MIN_SIZE + Control_HEADER_SIZE) { Log_info1(context->logger, "error packet from [%s] containing runt cause packet", labelStr); return Error_NONE; } struct Control* causeCtrl = (struct Control*) &(&ctrl->content.error.cause)[1]; if (causeCtrl->type_be != Control_PING_be) { Log_info3(context->logger, "error packet from [%s] caused by [%s] packet ([%d])", labelStr, Control_typeString(causeCtrl->type_be), Endian_bigEndianToHost16(causeCtrl->type_be)); } else { Log_debug2(context->logger, "error packet from [%s] in response to ping, length: [%d].", labelStr, message->length); // errors resulting from pings are forwarded back to the pinger. pong = true; } } else if (causeType != Headers_SwitchHeader_TYPE_DATA) { Log_info1(context->logger, "error packet from [%s] containing cause of unknown type [%d]", labelStr); } } else if (ctrl->type_be == Control_PONG_be) { pong = true; } else if (ctrl->type_be == Control_PING_be) { ctrl->type_be = Control_PONG_be; Message_shift(message, Headers_SwitchHeader_SIZE); switchIf->receiveMessage(message, switchIf); } else { Log_info2(context->logger, "control packet of unknown type from [%s], type [%d]", labelStr, Endian_bigEndianToHost16(ctrl->type_be)); } if (pong) { // Shift back over the header Message_shift(message, Headers_SwitchHeader_SIZE); context->switchPingerIf->receiveMessage(message, context->switchPingerIf); } return Error_NONE; } uint8_t* herKey = extractPublicKey(message, switchHeader->label_be, context->logger); int herAddrIndex; if (herKey) { uint8_t herAddrStore[16]; AddressCalc_addressForPublicKey(herAddrStore, herKey); if (herAddrStore[0] != 0xFC) { Log_debug(context->logger, "Got message from peer whose address is not in fc00::/8 range.\n"); return 0; } herAddrIndex = AddressMapper_put(switchHeader->label_be, herAddrStore, &context->addrMap); } else { herAddrIndex = AddressMapper_indexOf(switchHeader->label_be, &context->addrMap); if (herAddrIndex == -1) { uint64_t label = Endian_bigEndianToHost64(switchHeader->label_be); struct Node* n = RouterModule_getNode(label, context->routerModule); if (n) { herAddrIndex = AddressMapper_put(switchHeader->label_be, n->address.ip6.bytes, &context->addrMap); } else { #ifdef Log_DEBUG uint8_t switchAddr[20]; AddrTools_printPath(switchAddr, Endian_bigEndianToHost64(switchHeader->label_be)); Log_debug1(context->logger, "Dropped traffic packet from unknown node. (%s)\n", &switchAddr); #endif return 0; } } } // If the source address is the same as the router address, no third layer of crypto. context->routerAddress = context->addrMap.entries[herAddrIndex].address; // This is needed so that the priority and other information // from the switch header can be passed on properly. context->switchHeader = switchHeader; context->session = SessionManager_getSession(context->routerAddress, herKey, context->sm); // This goes to incomingFromCryptoAuth() // then incomingFromRouter() then core() context->layer = OUTER_LAYER; context->session->receiveMessage(message, context->session); return 0; }
/** * This is called as sendMessage() by the switch. * There is only one switch interface which sends all traffic. * message is aligned on the beginning of the switch header. */ static uint8_t incomingFromSwitch(struct Message* message, struct Interface* switchIf) { struct Context* context = switchIf->senderContext; struct Headers_SwitchHeader* switchHeader = (struct Headers_SwitchHeader*) message->bytes; Message_shift(message, -Headers_SwitchHeader_SIZE); // The label comes in reversed from the switch because the switch doesn't know that we aren't // another switch ready to parse more bits, bit reversing the label yields the source address. switchHeader->label_be = Bits_bitReverse64(switchHeader->label_be); if (Headers_getMessageType(switchHeader) == MessageType_CONTROL) { struct Control* ctrl = (struct Control*) (switchHeader + 1); if (ctrl->type_be == Control_ERROR_be) { if (memcmp(&ctrl->content.error.cause.label_be, &switchHeader->label_be, 8)) { Log_warn(context->logger, "Different label for cause than return packet, this shouldn't happen. " "Perhaps a packet was corrupted.\n"); return 0; } uint32_t errType_be = ctrl->content.error.errorType_be; if (errType_be == Endian_bigEndianToHost32(Error_MALFORMED_ADDRESS)) { Log_info(context->logger, "Got malformed-address error, removing route.\n"); RouterModule_brokenPath(switchHeader->label_be, context->routerModule); return 0; } Log_info1(context->logger, "Got error packet, error type: %d", Endian_bigEndianToHost32(errType_be)); } return 0; } uint8_t* herKey = extractPublicKey(message, switchHeader->label_be, context->logger); int herAddrIndex; if (herKey) { uint8_t herAddrStore[16]; AddressCalc_addressForPublicKey(herAddrStore, herKey); if (herAddrStore[0] != 0xFC) { Log_debug(context->logger, "Got message from peer whose address is not in fc00::/8 range.\n"); return 0; } herAddrIndex = AddressMapper_put(switchHeader->label_be, herAddrStore, &context->addrMap); } else { herAddrIndex = AddressMapper_indexOf(switchHeader->label_be, &context->addrMap); if (herAddrIndex == -1) { struct Node* n = RouterModule_getNode(switchHeader->label_be, context->routerModule); if (n) { herAddrIndex = AddressMapper_put(switchHeader->label_be, n->address.ip6.bytes, &context->addrMap); } else { #ifdef Log_DEBUG uint8_t switchAddr[20]; struct Address addr; addr.networkAddress_be = switchHeader->label_be; Address_printNetworkAddress(switchAddr, &addr); Log_debug1(context->logger, "Dropped traffic packet from unknown node. (%s)\n", &switchAddr); #endif return 0; } } } uint8_t* herAddr = context->addrMap.addresses[herAddrIndex]; // This is needed so that the priority and other information // from the switch header can be passed on properly. context->switchHeader = switchHeader; context->session = SessionManager_getSession(herAddr, herKey, context->sm); // This goes to incomingFromCryptoAuth() // then incomingFromRouter() then core() context->layer = OUTER_LAYER; context->session->receiveMessage(message, context->session); return 0; }