diff options
author | michele papalini <micpapal+fdio@cisco.com> | 2017-02-23 17:01:34 +0100 |
---|---|---|
committer | Michele Papalini <micpapal+fdio@cisco.com> | 2017-02-23 17:23:19 +0000 |
commit | c580a00aac271a524e5a75b35f4b91c174ed227b (patch) | |
tree | feddc15a9f1a4eb319d950f8d6330ac2b91e3d99 /metis/ccnx/forwarder/metis/command-line/metis_control/metisControl_main.c | |
parent | 9b30fc10fb1cbebe651e5a107e8ca5b24de54675 (diff) |
Initial commit: sb-forwarder, metis.
Change-Id: I65ee3c851a6901929ef4417ad80d34bca0dce445
Signed-off-by: michele papalini <micpapal+fdio@cisco.com>
Diffstat (limited to 'metis/ccnx/forwarder/metis/command-line/metis_control/metisControl_main.c')
-rw-r--r-- | metis/ccnx/forwarder/metis/command-line/metis_control/metisControl_main.c | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/metis/ccnx/forwarder/metis/command-line/metis_control/metisControl_main.c b/metis/ccnx/forwarder/metis/command-line/metis_control/metisControl_main.c new file mode 100644 index 00000000..067ed9c9 --- /dev/null +++ b/metis/ccnx/forwarder/metis/command-line/metis_control/metisControl_main.c @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <config.h> + +#include <stdbool.h> +#include <stdint.h> +#include <strings.h> +#include <stdlib.h> +#include <stdio.h> +#include <getopt.h> + +#include <LongBow/runtime.h> +#include <string.h> + +#include <parc/security/parc_Security.h> +#include <parc/security/parc_IdentityFile.h> + +#include <parc/algol/parc_Memory.h> +#include <parc/algol/parc_SafeMemory.h> +#include <parc/algol/parc_List.h> +#include <parc/algol/parc_ArrayList.h> + +#include <ccnx/api/control/cpi_ManageLinks.h> + +#include <ccnx/api/control/cpi_Forwarding.h> +#include <ccnx/forwarder/metis/core/metis_Forwarder.h> +#include <ccnx/forwarder/metis/core/metis_Dispatcher.h> + +#include <ccnx/api/ccnx_Portal/ccnx_Portal.h> +#include <ccnx/api/ccnx_Portal/ccnx_PortalRTA.h> + +#include <ccnx/common/ccnx_KeystoreUtilities.h> +#include <ccnx/transport/common/transport_MetaMessage.h> + +#include <ccnx/forwarder/metis/metis_About.h> +#include <ccnx/forwarder/metis/config/metis_ControlState.h> +#include <ccnx/forwarder/metis/config/metisControl_Root.h> + +#include <errno.h> + +typedef struct metis_control_main_state { + KeystoreParams *keystoreParams; + CCNxPortal *controlPortal; + MetisControlState *controlState; +} MetisControlMainState; + +static void +_displayForwarderLogo(void) +{ + printf("%s\n", metisAbout_About()); + + printf(" __ __ _ _\n"); + printf(" | \\/ | ___ | |_ (_) ___\n"); + printf(" | |\\/| | / _ \\| __|| |/ __|\n"); + printf(" | | | || __/| |_ | |\\__ \\\n"); + printf(" |_| |_| \\___| \\__||_||___/\n"); + + printf("\n"); +} + +static void +_displayUsage(char *programName) +{ + printf("Usage: %s -h\n", programName); + printf(" %s [--k|--keystore <keystore file name>] [--p|--password <keystore password>] [commands]\n", programName); + printf("\n"); + printf("Metis is the CCNx 1.0 forwarder, which runs on each end system and as a software forwarder\n"); + printf("on intermediate systems. metis_control is the program to configure the forwarder, metis_daemon.\n"); + printf("\n"); + printf("Options:\n"); + printf("-h = This help screen\n"); + printf("-k | --keystore = Specify the path of the PKCS12 keystore (default ~/.ccnx/.ccnx_keystore.p12)\n"); + printf("-p | --password = keystore password (default to prompt user)\n"); + printf("commands = configuration line to send to metis (use 'help' for list)\n"); + printf("\n"); +} + +static int +_parseArgs(int argc, char *argv[], char **keystorePath, char **keystorePassword, PARCList *commandList) +{ + static struct option longFormOptions[] = { + { "help", no_argument, 0, 'h' }, + { "keystore", required_argument, 0, 'k' }, + { "password", required_argument, 0, 'p' }, + { 0, 0, 0, 0 } + }; + + int c; + + while (1) { + // getopt_long stores the option index here. + int optionIndex = 0; + + c = getopt_long(argc, argv, "hk:p:", longFormOptions, &optionIndex); + + // Detect the end of the options. + if (c == -1) { + break; + } + + switch (c) { + case 'k': + *keystorePath = optarg; + break; + + case 'p': + *keystorePassword = optarg; + break; + + case 'h': + default: + _displayUsage(argv[0]); + return 0; + } + } + + // Any remaining parameters get put in the command list. + if (optind < argc) { + while (optind < argc) { + parcList_Add(commandList, argv[optind]); + optind++; + } + } + + return 1; +} + +static CCNxMetaMessage * +_writeAndReadMessage(void *mainStatePtr, CCNxMetaMessage *msg) +{ + assertNotNull(mainStatePtr, "Parameter mainStatePtr must be non-null"); + assertNotNull(msg, "Parameter msg must be non-null"); + + MetisControlMainState *mainState = mainStatePtr; + + if (ccnxPortal_Send(mainState->controlPortal, msg, CCNxStackTimeout_Never)) { + CCNxMetaMessage *result = ccnxPortal_Receive(mainState->controlPortal, CCNxStackTimeout_Never); + assertTrue(result != NULL, "Error reading response from Portal: (%d) %s\nb", errno, strerror(errno)); + + return result; + } + + return NULL; +} + +static CCNxPortal * +_createPortalWithKeystore(const char *keystoreName, const char *keystorePassword) +{ + PARCIdentityFile *identityFile = parcIdentityFile_Create(keystoreName, keystorePassword); + PARCIdentity *identity = parcIdentity_Create(identityFile, PARCIdentityFileAsPARCIdentity); + CCNxPortalFactory *portalFactory = ccnxPortalFactory_Create(identity); + + CCNxPortal *result = ccnxPortalFactory_CreatePortal(portalFactory, ccnxPortalRTA_Message); + + ccnxPortalFactory_Release(&portalFactory); + parcIdentity_Release(&identity); + parcIdentityFile_Release(&identityFile); + + return result; +} + +static MetisControlMainState +_openKeyStore(char *keystorePath, char *keystorePassword) +{ + MetisControlMainState mainState; + + if (keystorePassword == NULL) { + keystorePassword = ccnxKeystoreUtilities_ReadPassword(); + + mainState.keystoreParams = ccnxKeystoreUtilities_OpenFile(keystorePath, keystorePassword); + parcMemory_Deallocate((void *) &keystorePassword); + } else { + mainState.keystoreParams = ccnxKeystoreUtilities_OpenFile(keystorePath, keystorePassword); + } + + return mainState; +} + +int +main(int argc, char *argv[]) +{ + _displayForwarderLogo(); + + if (argc == 2 && strcmp("-h", argv[1]) == 0) { + _displayUsage(argv[0]); + exit(EXIT_SUCCESS); + } + + char *keystorePath = NULL; + char *keystorePassword = NULL; + + PARCList *commands = parcList(parcArrayList_Create(NULL), PARCArrayListAsPARCList); + + // Extract optional keystore and password, and optional commands. + if (!_parseArgs(argc, argv, &keystorePath, &keystorePassword, commands)) { + parcList_Release(&commands); + exit(EXIT_FAILURE); + } + + if (keystorePath == NULL) { + printf("No keystore specified. Will try default.\n"); + } else { + printf("Using keystore: %s\n", keystorePath); + } + + parcSecurity_Init(); + + MetisControlMainState mainState = _openKeyStore(keystorePath, keystorePassword); + if (mainState.keystoreParams == NULL) { + printf("Could not open keystore '%s'\n", keystorePath == NULL ? "~/.ccnx/.ccnx_keystore.p12" : keystorePath); + exit(EXIT_FAILURE); + } + + mainState.controlPortal = _createPortalWithKeystore(ccnxKeystoreUtilities_GetFileName(mainState.keystoreParams), + ccnxKeystoreUtilities_GetPassword(mainState.keystoreParams)); + parcSecurity_Fini(); + + mainState.controlState = metisControlState_Create(&mainState, _writeAndReadMessage); + + metisControlState_RegisterCommand(mainState.controlState, metisControlRoot_HelpCreate(mainState.controlState)); + metisControlState_RegisterCommand(mainState.controlState, metisControlRoot_Create(mainState.controlState)); + + if (parcList_Size(commands) > 0) { + metisControlState_DispatchCommand(mainState.controlState, commands); + } else { + metisControlState_Interactive(mainState.controlState); + } + + parcList_Release(&commands); + + metisControlState_Destroy(&mainState.controlState); + + keystoreParams_Destroy(&mainState.keystoreParams); + + ccnxPortal_Release(&mainState.controlPortal); + + return EXIT_SUCCESS; +} |