diff --git a/tools/aws_config_offline/CertificateConfigurator.html b/tools/aws_config_offline/CertificateConfigurator.html new file mode 100644 index 00000000000..25be752e95f --- /dev/null +++ b/tools/aws_config_offline/CertificateConfigurator.html @@ -0,0 +1,95 @@ + + + + + FreeRTOS.org Developer Demos Configuration Tool + + + + + + + + + + +
+
+
+
+
+

AWS Profile Configuration Tool

+

FreeRTOS.org Developer Demos

+
+
+
+
+
+

+ Enter Thing name and endpoint. Provide client certificate and private key PEM files + downloaded from the AWS IoT Console. +

+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+ +
+
+
+
+

+ + Save the generated header file to the + FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth folder + of the + demo project. +

+
+
+
+
+ Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/tools/aws_config_offline/js/aws_iot_demo_config_template.js b/tools/aws_config_offline/js/aws_iot_demo_config_template.js new file mode 100644 index 00000000000..782d76e983f --- /dev/null +++ b/tools/aws_config_offline/js/aws_iot_demo_config_template.js @@ -0,0 +1,260 @@ +var awsIotProfileTemplate = + `/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + */ + +#ifndef DEMO_CONFIG_H +#define DEMO_CONFIG_H + +/* FreeRTOS config include. */ +#include "FreeRTOSConfig.h" + +/**************************************************/ +/******* DO NOT CHANGE the following order ********/ +/**************************************************/ + +/* Include logging header files and define logging macros in the following order: + * 1. Include the header file "logging_levels.h". + * 2. Define the LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL macros depending on + * the logging configuration for DEMO. + * 3. Include the header file "logging_stack.h", if logging is enabled for DEMO. + */ + +#include "logging_levels.h" + +/* Logging configuration for the Demo. */ +#ifndef LIBRARY_LOG_NAME + #define LIBRARY_LOG_NAME "MQTTDemo" +#endif + +#ifndef LIBRARY_LOG_LEVEL + #define LIBRARY_LOG_LEVEL LOG_INFO +#endif +#include "logging_stack.h" + +/************ End of logging configuration ****************/ + +/** + * @brief The MQTT client identifier used in this example. Each client identifier + * must be unique; so edit as required to ensure that no two clients connecting to + * the same broker use the same client identifier. + * + * #define democonfigCLIENT_IDENTIFIER "insert here." + */ +#define democonfigCLIENT_IDENTIFIER + +/** + * @brief Endpoint of the MQTT broker to connect to. + * + * This demo application can be run with any MQTT broker, that supports mutual + * authentication. + * + * For AWS IoT MQTT broker, this is the Thing's REST API Endpoint. + * + * @note Your AWS IoT Core endpoint can be found in the AWS IoT console under + * Settings/Custom Endpoint, or using the describe-endpoint REST API (with + * AWS CLI command line tool). + * + * @note If you would like to setup an MQTT broker for running this demo, + * please see \`mqtt_broker_setup.txt\`. + * + * #define democonfigMQTT_BROKER_ENDPOINT "...insert here..." + */ +#define democonfigMQTT_BROKER_ENDPOINT + +/** + * @brief The port to use for the demo. + * + * In general, port 8883 is for secured MQTT connections. + * + * @note Port 443 requires use of the ALPN TLS extension with the ALPN protocol + * name. Using ALPN with this demo would require additional changes, including + * setting the \`pAlpnProtos\` member of the \`NetworkCredentials_t\` struct before + * forming the TLS connection. When using port 8883, ALPN is not required. + * + * #define democonfigMQTT_BROKER_PORT ( insert here. ) + */ +#define democonfigMQTT_BROKER_PORT ( 8883 ) + +/** + * @brief Server's root CA certificate. + * + * For AWS IoT MQTT broker, this certificate is used to identify the AWS IoT + * server and is publicly available. Refer to the AWS documentation available + * in the link below. + * https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html#server-authentication-certs + * + * @note This certificate should be PEM-encoded. + * + * Must include the PEM header and footer: + * "-----BEGIN CERTIFICATE-----\n"\ + * "...base64 data...\n"\ + * "-----END CERTIFICATE-----\n" + * + * #define democonfigROOT_CA_PEM "...insert here..." + */ +#define democonfigROOT_CA_PEM \\ + "-----BEGIN CERTIFICATE-----\\n" \\ + "MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\\n" \\ + "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\\n" \\ + "b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\\n" \\ + "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\\n" \\ + "b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\\n" \\ + "ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\\n" \\ + "9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\\n" \\ + "IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\\n" \\ + "VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\\n" \\ + "93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\\n" \\ + "jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\\n" \\ + "AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\\n" \\ + "A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\\n" \\ + "U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\\n" \\ + "N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\\n" \\ + "o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\\n" \\ + "5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\\n" \\ + "rqXRfboQnoZsG4q5WTP468SQvvG5\\n" \\ + "-----END CERTIFICATE-----\\n" + +/** + * @brief Client certificate. + * + * For AWS IoT MQTT broker, refer to the AWS documentation below for details + * regarding client authentication. + * https://docs.aws.amazon.com/iot/latest/developerguide/client-authentication.html + * + * @note This certificate should be PEM-encoded. + * + * Must include the PEM header and footer: + * "-----BEGIN CERTIFICATE-----\n"\ + * "...base64 data...\n"\ + * "-----END CERTIFICATE-----\n" + * + * #define democonfigCLIENT_CERTIFICATE_PEM "...insert here..." + */ +#define democonfigCLIENT_CERTIFICATE_PEM \\ + + +/** + * @brief PEM-encoded client private key. + * + * Must include the PEM header and footer: + * "-----BEGIN RSA PRIVATE KEY-----\\n"\\ + * "...base64 data...\\n"\\ + * "-----END RSA PRIVATE KEY-----\\n" + * + * #define democonfigCLIENT_PRIVATE_KEY_PEM "...insert here..." + */ +#define democonfigCLIENT_PRIVATE_KEY_PEM \\ + + +/** + * @brief An option to disable Server Name Indication. + * + * @note When using a local Mosquitto server setup, SNI needs to be disabled + * for an MQTT broker that only has an IP address but no hostname. However, + * SNI should be enabled whenever possible. + */ +#define democonfigDISABLE_SNI ( pdFALSE ) + +/** + * @brief Configuration that indicates if the demo connection is made to the AWS IoT Core MQTT broker. + * + * If username/password based authentication is used, the demo will use appropriate TLS ALPN and + * SNI configurations as required for the Custom Authentication feature of AWS IoT. + * For more information, refer to the following documentation: + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-auth.html#custom-auth-mqtt + * + * #define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 ) + */ +#define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 ) + +/** + * @brief The username value for authenticating client to the MQTT broker when + * username/password based client authentication is used. + * + * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for + * details regarding client authentication with a username and password. + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html + * An authorizer setup needs to be done, as mentioned in the above link, to use + * username/password based client authentication. + * + * #define democonfigCLIENT_USERNAME "...insert here..." + */ + +/** + * @brief The password value for authenticating client to the MQTT broker when + * username/password based client authentication is used. + * + * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for + * details regarding client authentication with a username and password. + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html + * An authorizer setup needs to be done, as mentioned in the above link, to use + * username/password based client authentication. + * + * #define democonfigCLIENT_PASSWORD "...insert here..." + */ + +/** + * @brief The name of the operating system that the application is running on. + * The current value is given as an example. Please update for your specific + * operating system. + */ +#define democonfigOS_NAME "FreeRTOS" + +/** + * @brief The version of the operating system that the application is running + * on. The current value is given as an example. Please update for your specific + * operating system version. + */ +#define democonfigOS_VERSION tskKERNEL_VERSION_NUMBER + +/** + * @brief The name of the hardware platform the application is running on. The + * current value is given as an example. Please update for your specific + * hardware platform. + */ +#define democonfigHARDWARE_PLATFORM_NAME "WinSim" + +/** + * @brief The name of the MQTT library used and its version, following an "@" + * symbol. + */ +#define democonfigMQTT_LIB "core-mqtt@1.0.0" + +/** + * @brief Set the stack size of the main demo task. + * + * In the Windows port, this stack only holds a structure. The actual + * stack is created by an operating system thread. + */ +#define democonfigDEMO_STACKSIZE configMINIMAL_STACK_SIZE + +/** + * @brief Size of the network buffer for MQTT packets. + */ +#define democonfigNETWORK_BUFFER_SIZE ( 1024U ) + +#endif /* DEMO_CONFIG_H */ +`; \ No newline at end of file diff --git a/tools/aws_config_offline/js/generator.js b/tools/aws_config_offline/js/generator.js new file mode 100644 index 00000000000..157a0f7a151 --- /dev/null +++ b/tools/aws_config_offline/js/generator.js @@ -0,0 +1,70 @@ + +// Check for the various File API support. +if (window.File && window.FileReader && window.FileList && window.Blob) { + // Success! All the File APIs are supported. +} else { + alert('Please use a web browser that supports HTML5 file APIs.') +} + +function formatCredentialTextForHeader(credentialText) { + // Replace any CR/LF pairs with a newline character. + credentialText = credentialText.replace(/\r\n/g, '\n') + + // Add line endings for C-language variable declaration. + credentialText = credentialText.replace(/\n/g, '\\n" \\\n "') + + // Remove '\n"' from the last line of the declaration and add a semicolon. + credentialText = credentialText.slice(0, -9) + '"\n' + return credentialText +} + +function generateCertificateConfigurationHeader() { + var pemCertificateText = '' + var pemPrivateKeyText = '' + var filename = 'demo_config.h' + var outputText = '' + + var readerCertificate = new FileReader() + var readerPrivateKey = new FileReader() + + // Start certificate read + readerCertificate.readAsText(pemInputFileCertificate.files[0]) + + // Define a handler to create appropriate client certificate file text. + readerCertificate.onload = function (e) { + pemCertificateText = e.target.result + + // Add C-language variable declaration plus EOL formatting. + pemCertificateText = ' "' + formatCredentialTextForHeader(pemCertificateText) + + // Because this is async, read next file inline. + readerPrivateKey.readAsText(pemInputFilePrivateKey.files[0]) + } + + // Define a handler to create appropriate private key file text. + readerPrivateKey.onload = function (e) { + pemPrivateKeyText = e.target.result + + // Add C-language variable declaration plus EOL formatting. + pemPrivateKeyText = ' "' + formatCredentialTextForHeader(pemPrivateKeyText) + + outputText = awsIotProfileTemplate + outputText = outputText.replace('', '"' + document.getElementById('AWSEndpoint').value + '"') + outputText = outputText.replace('', '"' + document.getElementById('thingName').value + '"') + outputText = outputText.replace('', pemCertificateText) + outputText = outputText.replace('', pemPrivateKeyText) + + // Because this is async, handle download generation inline. + var downloadBlob = new Blob([outputText], { type: 'text/plain' }) + if (window.navigator.msSaveOrOpenBlob) { + window.navigator.msSaveBlob(downloadBlob, filename) + } else { + var downloadLink = document.createElement('a') + downloadLink.href = window.URL.createObjectURL(downloadBlob) + downloadLink.download = filename + document.body.appendChild(downloadLink) + downloadLink.click() + document.body.removeChild(downloadLink) + } + } +} diff --git a/tools/aws_config_quick_start/.gitignore b/tools/aws_config_quick_start/.gitignore new file mode 100644 index 00000000000..08a6cdf7300 --- /dev/null +++ b/tools/aws_config_quick_start/.gitignore @@ -0,0 +1,5 @@ +__pycache__ +test* +*_id_file +*_pem_file +*.pyc diff --git a/tools/aws_config_quick_start/README.md b/tools/aws_config_quick_start/README.md new file mode 100644 index 00000000000..2ec371da1c1 --- /dev/null +++ b/tools/aws_config_quick_start/README.md @@ -0,0 +1,20 @@ +## Script to setup the AWS resources through command line + +This script automates the process of [Prerequisites](https://docs.aws.amazon.com/freertos/latest/userguide/freertos-prereqs.html) and the configuring the files `demo_config.h` to connect to AWS IoT. + +Make sure you have `aws cli` configured on your machine with access_key, secret_key and region. + +Open the file `configure.json` and fill in the following details: +* FreeRTOS_source_dir : The path of the FreeRTOS directory. By default, this is set to the top level of this repo (../..). +* thing_name : Name of the thing you want to create + +**Options to use with the script** +1. To setup your Thing, and update credentials file, type the command: `python SetupAWS.py setup` +2. To cleanup the Thing you created with the script, and revert changes in credentials file, type the command: `python SetupAWS.py cleanup` +3. To only create thing, certificate and policy, type the command: `python SetupAWS.py prereq` +4. To update the files `demo_config.h` with thing name and the certificate keys, type the command `python SetupAWS.py update_creds` +5. To delete the thing, certificate and policy created by the script, type the command: `python SetupAWS.py delete_prereq` +6. To revert the changes in the file `demo_config.h`, type the command: `python SetupAWS.py cleanup_creds` +7. To list your certificates, type the command: `python SetupAWS.py list_certificates` +8. To list your policies, type the command: `python SetupAWS.py list_policies` +9. To list your things, type the command: `python SetupAWS.py list_things` diff --git a/tools/aws_config_quick_start/SetupAWS.py b/tools/aws_config_quick_start/SetupAWS.py new file mode 100644 index 00000000000..cf6fff54867 --- /dev/null +++ b/tools/aws_config_quick_start/SetupAWS.py @@ -0,0 +1,235 @@ +#!/usr/bin/env python + +import os +import sys +import json +import pprint +import argparse +import boto3 +import misc +import certs +import thing +import policy + +pp = pprint.PrettyPrinter(indent=4) + + +def check_aws_configuration(): + mysession = boto3.session.Session() + if not mysession._session._config['profiles']: + print("AWS not configured. Please run `aws configure`.") + sys.exit(1) + + +def prereq(): + with open('configure.json') as configure_file: + json_text = json.load(configure_file) + + # Create a Thing + thing_name = json_text['thing_name'] + thing_obj = thing.Thing(thing_name) + if not thing_obj.create(): + + # Create a Certificate + cert_obj = certs.Certificate() + result = cert_obj.create() + + # Store certId + cert_id = result['certificateId'] + cert_id_filename = thing_name + '_cert_id_file.txt' + cert_id_file = open(cert_id_filename, 'w') + cert_id_file.write(cert_id) + cert_id_file_path = os.path.abspath(cert_id_filename) + os.chmod(cert_id_file_path, 0o444) + cert_id_file.close() + + # Store cert_pem as file + cert_pem = result['certificatePem'] + cert_pem_filename = thing_name + '_cert_pem_file.pem' + cert_pem_file = open(cert_pem_filename, 'w') + cert_pem_file.write(cert_pem) + cert_pem_file_path = os.path.abspath(cert_pem_filename) + os.chmod(cert_pem_file_path, 0o444) + cert_pem_file.close() + + # Store private key PEM as file + private_key_pem = result['keyPair']['PrivateKey'] + private_key_pem_filename = thing_name + '_private_key_pem_file.pem' + private_key_pem_file = open(private_key_pem_filename, 'w') + private_key_pem_file.write(private_key_pem) + private_key_pem_file_path = os.path.abspath(private_key_pem_filename) + os.chmod(private_key_pem_file_path, 0o444) + private_key_pem_file.close() + + # Create a Policy + policy_document = misc.create_policy_document() + policy_name = thing_name + '_amazon_freertos_policy' + policy_obj = policy.Policy(policy_name, policy_document) + policy_obj.create() + + # Attach certificate to Thing + cert_obj.attach_thing(thing_name) + + # Attach policy to certificate + cert_obj.attach_policy(policy_name) + + +def update_credential_file(): + with open('configure.json') as configure_file: + json_text = json.load(configure_file) + + source_dir = os.path.expanduser(json_text['FreeRTOS_source_dir']) + thing_name = json_text['thing_name'] + + # Read cert_pem from file + cert_pem_filename = thing_name + '_cert_pem_file.pem' + try: + cert_pem_file = open(cert_pem_filename, 'r') + except IOError: + print("{} file not found. Run prerequisite step" + .format(cert_pem_filename)) + sys.exit(1) + else: + cert_pem = cert_pem_file.read() + + # Read private_key_pem from file + private_key_pem_filename = thing_name + '_private_key_pem_file.pem' + try: + private_key_pem_file = open(private_key_pem_filename, 'r') + except IOError: + print("{} file not found. Run prerequisite step" + .format(private_key_pem_filename)) + sys.exit(1) + else: + private_key_pem = private_key_pem_file.read() + + # Modify 'demo_config.h' file + misc.write_client_credentials( + source_dir, + thing_name=thing_name, + client_certificate_pem=cert_pem, + client_private_key_pem=private_key_pem, + cleanup=False) + + +def delete_prereq(): + with open('configure.json') as configure_file: + json_text = json.load(configure_file) + + # Delete Thing + thing_name = json_text['thing_name'] + thing_obj = thing.Thing(thing_name) + if thing_obj.exists(): + thing_obj.delete() + + # Delete certificate + cert_id_filename = thing_name + '_cert_id_file.txt' + if os.path.exists(cert_id_filename): + cert_id_file = open(cert_id_filename, 'r') + cert_id = cert_id_file.read() + cert_obj = certs.Certificate(cert_id) + cert_obj.delete() + cert_id_file.close() + cert_id_file_path = os.path.abspath(cert_id_filename) + os.chmod(cert_id_file_path, 0o666) + os.remove(cert_id_filename) + + # Delete cert_pem file and private_key_pem file + cert_pem_filename = thing_name + '_cert_pem_file.pem' + if os.path.exists(cert_pem_filename): + cert_pem_file_path = os.path.abspath(cert_pem_filename) + os.chmod(cert_pem_file_path, 0o666) + os.remove(cert_pem_filename) + + private_key_pem_filename = thing_name + '_private_key_pem_file.pem' + if os.path.exists(private_key_pem_filename): + private_key_pem_file_path = os.path.abspath(private_key_pem_filename) + os.chmod(private_key_pem_file_path, 0o666) + os.remove(private_key_pem_filename) + + # Delete policy + policy_name = thing_name + '_amazon_freertos_policy' + policy_obj = policy.Policy(policy_name) + if policy_obj.exists(): + policy_obj.delete() + + +def cleanup_creds(): + with open('configure.json') as file: + json_text = json.load(file) + + source_dir = os.path.expanduser(json_text['FreeRTOS_source_dir']) + + # Cleanup 'demo_config.h' file + misc.write_client_credentials(source_dir, cleanup=True) + + +def setup(): + prereq() + update_credential_file() + print("Setup Completed") + + +def cleanup(): + delete_prereq() + cleanup_creds() + print("Cleanup Completed") + + +def list_certificates(): + client = boto3.client('iot') + certs = client.list_certificates()['certificates'] + pp.pprint(certs) + + +def list_things(): + client = boto3.client('iot') + things = client.list_things()['things'] + pp.pprint(things) + + +def list_policies(): + client = boto3.client('iot') + policies = client.list_policies()['policies'] + pp.pprint(policies) + + +if __name__ == "__main__": + + arg_parser = argparse.ArgumentParser() + subparsers = arg_parser.add_subparsers(help='Available commands', + dest='command') + subparsers.add_parser('setup', help='Setup AWS IoT') + subparsers.add_parser('cleanup', help='Cleanup AWS IoT') + subparsers.add_parser('list_certificates', help='List certificates') + subparsers.add_parser('list_things', help='List things') + subparsers.add_parser('list_policies', help='List policies') + subparsers.add_parser('prereq', help='Setup prerequisites for AWS IoT') + subparsers.add_parser('update_creds', help='Update credential files') + subparsers.add_parser('delete_prereq', help='Delete prerequisites created') + subparsers.add_parser('cleanup_creds', help='Cleanup credential files') + args = arg_parser.parse_args() + check_aws_configuration() + + if args.command == 'setup': + setup() + elif args.command == 'cleanup': + cleanup() + elif args.command == 'list_certificates': + list_certificates() + elif args.command == 'list_things': + list_things() + elif args.command == 'list_policies': + list_policies() + elif args.command == 'prereq': + prereq() + elif args.command == 'update_creds': + update_credential_file() + elif args.command == 'delete_prereq': + delete_prereq() + elif args.command == 'cleanup_creds': + cleanup_creds() + else: + print("Command does not exist") + + sys.exit(0) diff --git a/tools/aws_config_quick_start/certs.py b/tools/aws_config_quick_start/certs.py new file mode 100644 index 00000000000..1e29f4d9349 --- /dev/null +++ b/tools/aws_config_quick_start/certs.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python + +import boto3 +import json + + +class Certificate(): + + def __init__(self, certId=''): + self.id = certId + self.arn = '' + self.client = boto3.client('iot') + if (self.id != ''): + result = self.client.describe_certificate(certificateId=self.id) + self.arn = result['certificateDescription']['certificateArn'] + + def create(self): + assert not self.exists(), "Cert already exists" + cert = self.create_keys_and_certificate() + self.id = cert["certificateId"] + self.arn = cert["certificateArn"] + return cert + + def create_keys_and_certificate(self): + result = self.client.create_keys_and_certificate(setAsActive=True) + return result + + def delete(self): + cert_not_found = True + # Detach Policies attached to the cert + policies_attached = self.list_policies() + for policy in policies_attached: + self.detach_policy(policy['policyName']) + + # Detach Things attached to the cert + things_attached = self.list_things() + for thing in things_attached: + self.detach_thing(thing) + + # Update the status of the certificate to INACTIVE + try: + self.client.update_certificate(certificateId=self.id, + newStatus='INACTIVE') + cert_not_found = False + except self.client.exceptions.ResourceNotFoundException: + cert_not_found = True + return cert_not_found + + # Delete the certificate + try: + self.client.delete_certificate(certificateId=self.id) + cert_not_found = False + except self.client.exceptions.ResourceNotFoundException: + cert_not_found = True + return cert_not_found + + def exists(self): + if self.id == '': + return False + else: + return True + + def get_arn(self): + return self.arn + + def list_policies(self): + policies = self.client.list_principal_policies(principal=self.arn) + policies = policies['policies'] + return policies + + def attach_policy(self, policy_name): + self.client.attach_policy(policyName=policy_name, target=self.arn) + + def detach_policy(self, policy_name): + self.client.detach_policy(policyName=policy_name, target=self.arn) + + def list_things(self): + things = self.client.list_principal_things(principal=self.arn) + things = things['things'] + return things + + def attach_thing(self, thing_name): + self.client.attach_thing_principal(thingName=thing_name, + principal=self.arn) + + def detach_thing(self, thing_name): + self.client.detach_thing_principal(thingName=thing_name, + principal=self.arn) diff --git a/tools/aws_config_quick_start/configure.json b/tools/aws_config_quick_start/configure.json new file mode 100644 index 00000000000..9db4e7df2af --- /dev/null +++ b/tools/aws_config_quick_start/configure.json @@ -0,0 +1,4 @@ +{ + "FreeRTOS_source_dir": "../..", + "thing_name": "$thing_name" +} \ No newline at end of file diff --git a/tools/aws_config_quick_start/demo_config.templ b/tools/aws_config_quick_start/demo_config.templ new file mode 100644 index 00000000000..4053a8e98d3 --- /dev/null +++ b/tools/aws_config_quick_start/demo_config.templ @@ -0,0 +1,258 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + */ + +#ifndef DEMO_CONFIG_H +#define DEMO_CONFIG_H + +/* FreeRTOS config include. */ +#include "FreeRTOSConfig.h" + +/**************************************************/ +/******* DO NOT CHANGE the following order ********/ +/**************************************************/ + +/* Include logging header files and define logging macros in the following order: + * 1. Include the header file "logging_levels.h". + * 2. Define the LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL macros depending on + * the logging configuration for DEMO. + * 3. Include the header file "logging_stack.h", if logging is enabled for DEMO. + */ + +#include "logging_levels.h" + +/* Logging configuration for the Demo. */ +#ifndef LIBRARY_LOG_NAME + #define LIBRARY_LOG_NAME "MQTTDemo" +#endif + +#ifndef LIBRARY_LOG_LEVEL + #define LIBRARY_LOG_LEVEL LOG_INFO +#endif +#include "logging_stack.h" + +/************ End of logging configuration ****************/ + +/** + * @brief The MQTT client identifier used in this example. Each client identifier + * must be unique; so edit as required to ensure that no two clients connecting to + * the same broker use the same client identifier. + * + * #define democonfigCLIENT_IDENTIFIER "insert here." + */ +#define democonfigCLIENT_IDENTIFIER + +/** + * @brief Endpoint of the MQTT broker to connect to. + * + * This demo application can be run with any MQTT broker, that supports mutual + * authentication. + * + * For AWS IoT MQTT broker, this is the Thing's REST API Endpoint. + * + * @note Your AWS IoT Core endpoint can be found in the AWS IoT console under + * Settings/Custom Endpoint, or using the describe-endpoint REST API (with + * AWS CLI command line tool). + * + * @note If you would like to setup an MQTT broker for running this demo, + * please see \`mqtt_broker_setup.txt\`. + * + * #define democonfigMQTT_BROKER_ENDPOINT "...insert here..." + */ +#define democonfigMQTT_BROKER_ENDPOINT + +/** + * @brief The port to use for the demo. + * + * In general, port 8883 is for secured MQTT connections. + * + * @note Port 443 requires use of the ALPN TLS extension with the ALPN protocol + * name. Using ALPN with this demo would require additional changes, including + * setting the \`pAlpnProtos\` member of the \`NetworkCredentials_t\` struct before + * forming the TLS connection. When using port 8883, ALPN is not required. + * + * #define democonfigMQTT_BROKER_PORT ( insert here. ) + */ +#define democonfigMQTT_BROKER_PORT ( 8883 ) + +/** + * @brief Server's root CA certificate. + * + * For AWS IoT MQTT broker, this certificate is used to identify the AWS IoT + * server and is publicly available. Refer to the AWS documentation available + * in the link below. + * https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html#server-authentication-certs + * + * @note This certificate should be PEM-encoded. + * + * Must include the PEM header and footer: + * "-----BEGIN CERTIFICATE-----\n"\ + * "...base64 data...\n"\ + * "-----END CERTIFICATE-----\n" + * + * #define democonfigROOT_CA_PEM "...insert here..." + */ +#define democonfigROOT_CA_PEM \ + "-----BEGIN CERTIFICATE-----\n" \ + "MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n" \ + "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" \ + "b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n" \ + "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n" \ + "b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n" \ + "ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n" \ + "9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n" \ + "IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n" \ + "VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n" \ + "93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n" \ + "jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n" \ + "AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n" \ + "A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n" \ + "U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n" \ + "N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n" \ + "o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n" \ + "5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\n" \ + "rqXRfboQnoZsG4q5WTP468SQvvG5\n" \ + "-----END CERTIFICATE-----\n" + +/** + * @brief Client certificate. + * + * For AWS IoT MQTT broker, refer to the AWS documentation below for details + * regarding client authentication. + * https://docs.aws.amazon.com/iot/latest/developerguide/client-authentication.html + * + * @note This certificate should be PEM-encoded. + * + * Must include the PEM header and footer: + * "-----BEGIN CERTIFICATE-----\n"\ + * "...base64 data...\n"\ + * "-----END CERTIFICATE-----\n" + * + * #define democonfigCLIENT_CERTIFICATE_PEM "...insert here..." + */ +#define democonfigCLIENT_CERTIFICATE_PEM \ + + +/** + * @brief PEM-encoded client private key. + * + * Must include the PEM header and footer: + * "-----BEGIN RSA PRIVATE KEY-----\n"\ + * "...base64 data...\n"\ + * "-----END RSA PRIVATE KEY-----\n" + * + * #define democonfigCLIENT_PRIVATE_KEY_PEM "...insert here..." + */ +#define democonfigCLIENT_PRIVATE_KEY_PEM \ + + +/** + * @brief An option to disable Server Name Indication. + * + * @note When using a local Mosquitto server setup, SNI needs to be disabled + * for an MQTT broker that only has an IP address but no hostname. However, + * SNI should be enabled whenever possible. + */ +#define democonfigDISABLE_SNI ( pdFALSE ) + +/** + * @brief Configuration that indicates if the demo connection is made to the AWS IoT Core MQTT broker. + * + * If username/password based authentication is used, the demo will use appropriate TLS ALPN and + * SNI configurations as required for the Custom Authentication feature of AWS IoT. + * For more information, refer to the following documentation: + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-auth.html#custom-auth-mqtt + * + * #define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 ) + */ +#define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 ) + +/** + * @brief The username value for authenticating client to the MQTT broker when + * username/password based client authentication is used. + * + * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for + * details regarding client authentication with a username and password. + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html + * An authorizer setup needs to be done, as mentioned in the above link, to use + * username/password based client authentication. + * + * #define democonfigCLIENT_USERNAME "...insert here..." + */ + +/** + * @brief The password value for authenticating client to the MQTT broker when + * username/password based client authentication is used. + * + * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for + * details regarding client authentication with a username and password. + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html + * An authorizer setup needs to be done, as mentioned in the above link, to use + * username/password based client authentication. + * + * #define democonfigCLIENT_PASSWORD "...insert here..." + */ + +/** + * @brief The name of the operating system that the application is running on. + * The current value is given as an example. Please update for your specific + * operating system. + */ +#define democonfigOS_NAME "FreeRTOS" + +/** + * @brief The version of the operating system that the application is running + * on. The current value is given as an example. Please update for your specific + * operating system version. + */ +#define democonfigOS_VERSION tskKERNEL_VERSION_NUMBER + +/** + * @brief The name of the hardware platform the application is running on. The + * current value is given as an example. Please update for your specific + * hardware platform. + */ +#define democonfigHARDWARE_PLATFORM_NAME "WinSim" + +/** + * @brief The name of the MQTT library used and its version, following an "@" + * symbol. + */ +#define democonfigMQTT_LIB "core-mqtt@1.0.0" + +/** + * @brief Set the stack size of the main demo task. + * + * In the Windows port, this stack only holds a structure. The actual + * stack is created by an operating system thread. + */ +#define democonfigDEMO_STACKSIZE configMINIMAL_STACK_SIZE + +/** + * @brief Size of the network buffer for MQTT packets. + */ +#define democonfigNETWORK_BUFFER_SIZE ( 1024U ) + +#endif /* DEMO_CONFIG_H */ \ No newline at end of file diff --git a/tools/aws_config_quick_start/demo_config_empty.templ b/tools/aws_config_quick_start/demo_config_empty.templ new file mode 100644 index 00000000000..94fae967ecc --- /dev/null +++ b/tools/aws_config_quick_start/demo_config_empty.templ @@ -0,0 +1,251 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + */ + +#ifndef DEMO_CONFIG_H +#define DEMO_CONFIG_H + +/* FreeRTOS config include. */ +#include "FreeRTOSConfig.h" + +/**************************************************/ +/******* DO NOT CHANGE the following order ********/ +/**************************************************/ + +/* Include logging header files and define logging macros in the following order: + * 1. Include the header file "logging_levels.h". + * 2. Define the LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL macros depending on + * the logging configuration for DEMO. + * 3. Include the header file "logging_stack.h", if logging is enabled for DEMO. + */ + +#include "logging_levels.h" + +/* Logging configuration for the Demo. */ +#ifndef LIBRARY_LOG_NAME + #define LIBRARY_LOG_NAME "MQTTDemo" +#endif + +#ifndef LIBRARY_LOG_LEVEL + #define LIBRARY_LOG_LEVEL LOG_INFO +#endif +#include "logging_stack.h" + +/************ End of logging configuration ****************/ + +/** + * @brief The MQTT client identifier used in this example. Each client identifier + * must be unique; so edit as required to ensure that no two clients connecting to + * the same broker use the same client identifier. + * + * #define democonfigCLIENT_IDENTIFIER "insert here." + */ + +/** + * @brief Endpoint of the MQTT broker to connect to. + * + * This demo application can be run with any MQTT broker, that supports mutual + * authentication. + * + * For AWS IoT MQTT broker, this is the Thing's REST API Endpoint. + * + * @note Your AWS IoT Core endpoint can be found in the AWS IoT console under + * Settings/Custom Endpoint, or using the describe-endpoint REST API (with + * AWS CLI command line tool). + * + * @note If you would like to setup an MQTT broker for running this demo, + * please see \`mqtt_broker_setup.txt\`. + * + * #define democonfigMQTT_BROKER_ENDPOINT "...insert here..." + */ + +/** + * @brief The port to use for the demo. + * + * In general, port 8883 is for secured MQTT connections. + * + * @note Port 443 requires use of the ALPN TLS extension with the ALPN protocol + * name. Using ALPN with this demo would require additional changes, including + * setting the \`pAlpnProtos\` member of the \`NetworkCredentials_t\` struct before + * forming the TLS connection. When using port 8883, ALPN is not required. + * + * #define democonfigMQTT_BROKER_PORT ( insert here. ) + */ +#define democonfigMQTT_BROKER_PORT ( 8883 ) + +/** + * @brief Server's root CA certificate. + * + * For AWS IoT MQTT broker, this certificate is used to identify the AWS IoT + * server and is publicly available. Refer to the AWS documentation available + * in the link below. + * https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html#server-authentication-certs + * + * @note This certificate should be PEM-encoded. + * + * Must include the PEM header and footer: + * "-----BEGIN CERTIFICATE-----\n"\ + * "...base64 data...\n"\ + * "-----END CERTIFICATE-----\n" + * + * #define democonfigROOT_CA_PEM "...insert here..." + */ +#define democonfigROOT_CA_PEM \ + "-----BEGIN CERTIFICATE-----\\n" \\ + "MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\\n" \\ + "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\\n" \\ + "b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\\n" \\ + "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\\n" \\ + "b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\\n" \\ + "ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\\n" \\ + "9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\\n" \\ + "IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\\n" \\ + "VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\\n" \\ + "93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\\n" \\ + "jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\\n" \\ + "AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\\n" \\ + "A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\\n" \\ + "U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\\n" \\ + "N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\\n" \\ + "o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\\n" \\ + "5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\\n" \\ + "rqXRfboQnoZsG4q5WTP468SQvvG5\\n" \\ + "-----END CERTIFICATE-----\\n" + +/** + * @brief Client certificate. + * + * For AWS IoT MQTT broker, refer to the AWS documentation below for details + * regarding client authentication. + * https://docs.aws.amazon.com/iot/latest/developerguide/client-authentication.html + * + * @note This certificate should be PEM-encoded. + * + * Must include the PEM header and footer: + * "-----BEGIN CERTIFICATE-----\n"\ + * "...base64 data...\n"\ + * "-----END CERTIFICATE-----\n" + * + * #define democonfigCLIENT_CERTIFICATE_PEM "...insert here..." + */ + +/** + * @brief PEM-encoded client private key. + * + * Must include the PEM header and footer: + * "-----BEGIN RSA PRIVATE KEY-----\\n"\\ + * "...base64 data...\\n"\\ + * "-----END RSA PRIVATE KEY-----\\n" + * + * #define democonfigCLIENT_PRIVATE_KEY_PEM "...insert here..." + */ + +/** + * @brief An option to disable Server Name Indication. + * + * @note When using a local Mosquitto server setup, SNI needs to be disabled + * for an MQTT broker that only has an IP address but no hostname. However, + * SNI should be enabled whenever possible. + */ +#define democonfigDISABLE_SNI ( pdFALSE ) + +/** + * @brief Configuration that indicates if the demo connection is made to the AWS IoT Core MQTT broker. + * + * If username/password based authentication is used, the demo will use appropriate TLS ALPN and + * SNI configurations as required for the Custom Authentication feature of AWS IoT. + * For more information, refer to the following documentation: + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-auth.html#custom-auth-mqtt + * + * #define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 ) + */ + +/** + * @brief The username value for authenticating client to the MQTT broker when + * username/password based client authentication is used. + * + * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for + * details regarding client authentication with a username and password. + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html + * An authorizer setup needs to be done, as mentioned in the above link, to use + * username/password based client authentication. + * + * #define democonfigCLIENT_USERNAME "...insert here..." + */ + +/** + * @brief The password value for authenticating client to the MQTT broker when + * username/password based client authentication is used. + * + * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for + * details regarding client authentication with a username and password. + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html + * An authorizer setup needs to be done, as mentioned in the above link, to use + * username/password based client authentication. + * + * #define democonfigCLIENT_PASSWORD "...insert here..." + */ + +/** + * @brief The name of the operating system that the application is running on. + * The current value is given as an example. Please update for your specific + * operating system. + */ +#define democonfigOS_NAME "FreeRTOS" + +/** + * @brief The version of the operating system that the application is running + * on. The current value is given as an example. Please update for your specific + * operating system version. + */ +#define democonfigOS_VERSION tskKERNEL_VERSION_NUMBER + +/** + * @brief The name of the hardware platform the application is running on. The + * current value is given as an example. Please update for your specific + * hardware platform. + */ +#define democonfigHARDWARE_PLATFORM_NAME "WinSim" + +/** + * @brief The name of the MQTT library used and its version, following an "@" + * symbol. + */ +#define democonfigMQTT_LIB "core-mqtt@1.0.0" + +/** + * @brief Set the stack size of the main demo task. + * + * In the Windows port, this stack only holds a structure. The actual + * stack is created by an operating system thread. + */ +#define democonfigDEMO_STACKSIZE configMINIMAL_STACK_SIZE + +/** + * @brief Size of the network buffer for MQTT packets. + */ +#define democonfigNETWORK_BUFFER_SIZE ( 1024U ) + +#endif /* DEMO_CONFIG_H */ \ No newline at end of file diff --git a/tools/aws_config_quick_start/misc.py b/tools/aws_config_quick_start/misc.py new file mode 100644 index 00000000000..c610f1b392f --- /dev/null +++ b/tools/aws_config_quick_start/misc.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python + +import os +import boto3 + + +def describe_endpoint(): + client = boto3.client('iot') + endpoint = client.describe_endpoint(endpointType='iot:Data-ATS') + return endpoint['endpointAddress'] + + +def get_account_id(): + client = boto3.client('sts') + aws_account_id = client.get_caller_identity()['Account'] + return aws_account_id.strip('\n') + + +def get_aws_region(): + my_session = boto3.session.Session() + aws_region = my_session.region_name + return aws_region.strip('\n') + + +def create_policy_document(): + this_file_directory = os.getcwd() + policy_document = os.path.join(this_file_directory, + 'policy_document.templ') + region_name = str(get_aws_region()) + aws_account_id = str(get_account_id()) + with open(policy_document) as policy_document_file: + policy_document_text = policy_document_file.read() + + # Replace Account ID and AWS Region + policy_document_text = policy_document_text.replace('', + region_name) + policy_document_text = policy_document_text.replace('', + aws_account_id) + + return policy_document_text + + +def format_credential_keys_text(credential_text): + credential_text_lines = credential_text.split('\n') + formatted_credential_text_lines = [] + + for credential_text_line in credential_text_lines: + if credential_text_line.strip(): + formatted_credential_text_line = ' {:68s}'\ + .format('"' + credential_text_line + '\\n"') + formatted_credential_text_lines.append( + formatted_credential_text_line) + + formatted_credential_text = ' \\\n'.join(formatted_credential_text_lines) + return formatted_credential_text + + +def write_client_credentials( + source_dir, + thing_name='', + client_certificate_pem='', + client_private_key_pem='', + cleanup=False): + + file_to_modify = os.path.join(source_dir, + 'FreeRTOS-Plus', + 'Demo', + 'coreMQTT_Windows_Simulator', + 'MQTT_Mutual_Auth', + 'demo_config.h') + file_text = '' + + if cleanup: + filename = "demo_config_empty.templ" + with open(filename, 'r') as template_file: + file_text = template_file.read() + + else: + endpoint = describe_endpoint() + client_certificate_pem =\ + format_credential_keys_text(client_certificate_pem) + client_private_key_pem =\ + format_credential_keys_text(client_private_key_pem) + + filename = "demo_config.templ" + with open(filename, 'r') as template_file: + file_text = template_file.read() + file_text = file_text.replace("", + "\"" + endpoint + "\"") + file_text = file_text.replace("", + "\"" + thing_name + "\"") + file_text = file_text.replace("", + client_certificate_pem) + file_text = file_text.replace("", + client_private_key_pem) + + header_file = open(str(file_to_modify), 'w') + header_file.write(file_text) + header_file.close() diff --git a/tools/aws_config_quick_start/policy.py b/tools/aws_config_quick_start/policy.py new file mode 100644 index 00000000000..799efa29c30 --- /dev/null +++ b/tools/aws_config_quick_start/policy.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +import boto3 +import json + + +class Policy(): + def __init__(self, name, policy=''): + self.name = name + self.policy = policy + self.client = boto3.client('iot') + + def create(self): + assert not self.exists(), "Policy already exists" + self.client.create_policy(policyName=self.name, + policyDocument=self.policy) + + def delete(self): + assert self.exists(), "Policy does not exist, cannot be deleted" + self.client.delete_policy(policyName=self.name) + + def exists(self): + policies = self.client.list_policies()['policies'] + for policy in policies: + if self.name == policy['policyName']: + return True + return False diff --git a/tools/aws_config_quick_start/policy_document.templ b/tools/aws_config_quick_start/policy_document.templ new file mode 100644 index 00000000000..dd33f15a6cc --- /dev/null +++ b/tools/aws_config_quick_start/policy_document.templ @@ -0,0 +1,25 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "iot:Connect", + "Resource": "arn:aws:iot:::*" + }, + { + "Effect": "Allow", + "Action": "iot:Publish", + "Resource": "arn:aws:iot:::*" + }, + { + "Effect": "Allow", + "Action": "iot:Subscribe", + "Resource": "arn:aws:iot:::*" + }, + { + "Effect": "Allow", + "Action": "iot:Receive", + "Resource": "arn:aws:iot:::*" + } + ] +} \ No newline at end of file diff --git a/tools/aws_config_quick_start/thing.py b/tools/aws_config_quick_start/thing.py new file mode 100644 index 00000000000..07d81d7902a --- /dev/null +++ b/tools/aws_config_quick_start/thing.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +import boto3 +import json + + +class Thing(): + def __init__(self, name): + self.client = boto3.client('iot') + self.name = name + self.arn = '' + + def create(self): + assert not self.exists(), "Thing already exists" + result = self.client.create_thing(thingName=self.name) + self.arn = result['thingArn'] + + def delete(self): + assert self.exists(), "Thing does not exist" + principals = self.list_principals() + for principal in principals: + self.detach_principal(principal) + self.client.delete_thing(thingName=self.name) + + def exists(self): + list_of_things = self.client.list_things()['things'] + for thing in list_of_things: + if thing['thingName'] == self.name: + return True + return False + + def attach_principal(self, arn): + assert self.exists(), "Thing does not exist" + self.client.attach_thing_principal(thingName=self.name, principal=arn) + + def detach_principal(self, arn): + assert self.exists(), "Thing does not exist" + self.client.detach_thing_principal(thingName=self.name, principal=arn) + + def list_principals(self): + assert self.exists(), "Thing does not exist" + principals = self.client.list_thing_principals(thingName=self.name) + principals = principals['principals'] + return principals