Compare commits

..

51 Commits

Author SHA1 Message Date
Mudit Vats 96f4c68ecc feat: Fix formatting 2021-08-16 17:48:53 -07:00
Mudit Vats 87ca74fdf3 feat: Treat data to/from RPS and AMT as binary. 2021-08-16 17:43:07 -07:00
Mudit Vats 185cdceadb feat: check for provisioning state on shbc failure and reset if necessary 2021-08-11 09:56:36 -07:00
Mudit Vats 706a512bc7 feat: tick up protocol minor version, always return response on shbc config so RPS can fall-back to non-shbc configuration. 2021-08-06 09:18:54 -07:00
Mudit Vats e0fe219646 feat: shbc configuration 2021-08-05 10:54:18 -07:00
Mike f0682c4588 Merge pull request #60 from open-amt-cloud-toolkit/fix_klockwork_opens
fix: klockwork reported success / failure check fix
2021-07-21 10:39:29 -07:00
Mudit Vats 913fa41b17 fix: klockwork reported success / failure check fix 2021-07-19 13:25:33 -07:00
Mike f6666d857b Merge pull request #55 from open-amt-cloud-toolkit/feature_wireless
feat: add AMT wireless adapter info to amtinfo LAN settings.
2021-07-07 10:46:44 -07:00
Mike e51dc9f1f7 Merge branch 'master' into feature_wireless 2021-07-07 10:20:14 -07:00
Mike a4929a2d08 Merge pull request #53 from open-amt-cloud-toolkit/update-readme
docs(readme): update readme
2021-07-07 10:20:01 -07:00
Mike 615e9156dc Merge branch 'master' into feature_wireless 2021-07-07 10:19:14 -07:00
Matt Primrose 373a560b1a Merge branch 'master' into update-readme 2021-07-06 17:17:08 -07:00
Matt Primrose 0f8050b6bf Merge pull request #56 from open-amt-cloud-toolkit/changelog_automation
ci(changelog): add automation for changelog generation
2021-07-06 17:16:43 -07:00
Matt Primrose c70335ae2e Merge branch 'master' into update-readme 2021-07-06 16:21:30 -07:00
Matt Primrose d94302543b Merge branch 'master' into changelog_automation 2021-07-06 16:20:35 -07:00
Matt Primrose dea97dec64 Merge pull request #59 from bill-mahoney/master
ci: update scanning
2021-07-06 16:18:24 -07:00
mpvats-intel cd2887a992 Merge branch 'master' into feature_wireless 2021-07-01 06:16:05 -07:00
Bill Mahoney 33abb9d2d2 ci: update scanning
Signed-off-by: Bill Mahoney <bill.mahoney@intel.com>
2021-06-30 11:18:27 -07:00
bwendlandt-intel 34981ad2c7 docs(readme): wording 2021-06-28 11:42:37 -07:00
Mike 17efe70b4e Merge pull request #57 from open-amt-cloud-toolkit/matt-primrose-patch-1
docs(security): added security.md file
2021-06-24 17:10:00 -07:00
Matt Primrose c2be90c8a7 docs(security): added SECURITY.md file 2021-06-24 14:44:31 -07:00
Matt Primrose b4c12d63b5 docs(security): added security.md file 2021-06-24 14:30:37 -07:00
Mike bea1eb22ef Merge branch 'master' into changelog_automation 2021-06-23 11:01:46 -07:00
Mike ec1374280b ci(changelog): add automation for changelog generation 2021-06-22 16:43:53 -07:00
Mudit Vats f7dc3f4faa feat: add AMT wireless adapter info to amtinfo LAN settings. 2021-06-22 15:37:11 -07:00
bwendlandt-intel 491f5087de docs(readme): update readme 2021-06-18 15:37:41 -07:00
mpvats-intel a968777550 Merge pull request #52 from open-amt-cloud-toolkit/examples_update
fix: update examples text and version
2021-06-03 09:03:18 -07:00
mpvats-intel db9605ab82 Merge branch 'master' into examples_update 2021-06-03 08:38:43 -07:00
Mike 91d7481264 Merge pull request #50 from bill-mahoney/daily-cleanup
ci: remove Jenkins chron
2021-06-03 08:25:17 -07:00
Mudit Vats cb24fae43a fix: update examples text and version 2021-06-01 15:32:57 -07:00
Bill Mahoney 4d551ef09d ci: remove Jenkins chron 2021-05-10 11:15:18 -07:00
Mike 39ddea389a Merge pull request #48 from open-amt-cloud-toolkit/docker
build(docker): revert to ubuntu 20.04
2021-05-06 12:07:01 -07:00
Mike 9aa745e5a2 build(docker): revert to ubuntu 20.04 2021-05-06 11:45:56 -07:00
Mike 38c8bc2384 Merge pull request #47 from open-amt-cloud-toolkit/add_missing_ca
fix(docker): add missing ca-certs
2021-05-05 22:34:30 -07:00
Mike 584ca67799 build(docker): bump to ubuntu-20.10 2021-05-05 16:31:58 -07:00
Mike cf7fac325f fix(docker): add missing ca-certs 2021-05-05 16:04:58 -07:00
Mike 8569684593 Merge pull request #40 from bill-mahoney/jenkins-feedback
ci: update build for scanning
2021-04-08 11:46:51 -07:00
Mike 1e72b281a5 Merge branch 'master' into jenkins-feedback 2021-04-06 09:56:45 -07:00
Mike 75673aa373 Merge pull request #43 from open-amt-cloud-toolkit/v1.2.0
docs: add changelog.md
2021-04-05 10:31:36 -07:00
Mike 5772e831ad docs: add changelog.md 2021-04-02 21:16:43 -07:00
Bill Mahoney 67202dc5d3 ci: update build for scanning
Signed-off-by: Bill Mahoney <bill.mahoney@intel.com>
2021-03-31 18:11:41 -07:00
mpvats-intel 6d490aec65 Merge pull request #39 from open-amt-cloud-toolkit/feature_update_version
feat: update RPC version to 1.2.0.
2021-03-29 14:58:30 -07:00
Mudit Vats 41f8f8553c feat: update RPC version to 1.2.0. 2021-03-29 14:35:21 -07:00
mpvats-intel bc1f8d0cfb Merge pull request #38 from open-amt-cloud-toolkit/feature_heatbeat
feat: add heartbeat capability
2021-03-23 16:25:05 -07:00
Mudit Vats a8e1bc89f0 feat: add heartbeat capability 2021-03-23 14:00:49 -07:00
Mike 5b5a480943 Merge pull request #36 from open-amt-cloud-toolkit/test
ci: breakout docker build for merge only
2021-03-16 16:00:42 -07:00
Mike a190a214f1 ci: breakout docker build for merge only 2021-03-16 15:29:52 -07:00
Mike 54b7550e31 Merge pull request #35 from rsdmike/dockersupport
feat(docker): add dockerfile support for RPC
2021-03-16 14:48:11 -07:00
Mike e4deeca506 feat(docker): add dockerfile support for RPC 2021-03-16 14:44:28 -07:00
trleasher-intel 365ad90adc Merge pull request #31 from open-amt-cloud-toolkit/fix_msg_cleanup
fix: use message status instead, cleanup message fields.
2021-02-23 09:27:01 -07:00
Mudit Vats 2984880b6e fix: use message status instead, cleanup message fields. 2021-02-23 08:25:46 -07:00
27 changed files with 677 additions and 144 deletions
+20
View File
@@ -0,0 +1,20 @@
name: Changelog Generator
on:
pull_request:
branches: [ master ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- run: docker run -v $PWD:/workdir quay.io/git-chglog/git-chglog --next-tag vNext --output CHANGELOG-new.md vNext..
- name: GitHub Upload Release Artifacts
uses: actions/upload-artifact@v2
with:
name: CHANGELOG-new.md
path: |
./CHANGELOG-new.md
-1
View File
@@ -42,7 +42,6 @@ jobs:
- name: Build RPC (Debug)
run: cd build && cmake --build . --config Debug
build-linux:
runs-on: ${{ matrix.os }}
strategy:
+29
View File
@@ -0,0 +1,29 @@
#*********************************************************************
# Copyright (c) Intel Corporation 2020
# SPDX-License-Identifier: Apache-2.0
#*********************************************************************/
name: Docker Image CI
on:
push:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build the Docker image
run: docker build -f "Dockerfile" --tag vprodemo.azurecr.io/rpc:${{ github.sha }} --tag vprodemo.azurecr.io/rpc:latest .
- name: Docker Login
uses: docker/login-action@v1.6.0
with:
registry: vprodemo.azurecr.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
logout: true
- name: Push the Docker image to the registry
run: docker push vprodemo.azurecr.io/rpc:${{ github.sha }}
- name: Push the Docker image to the registry
run: docker push vprodemo.azurecr.io/rpc:latest
+32
View File
@@ -1,3 +1,35 @@
<a name="v1.2.2"></a>
## [v1.2.2] - 2021-06-22
### Ci
- remove Jenkins chron
- **changelog:** add automation for changelog generation
### Fix
- update examples text and version
<a name="v1.2.1"></a>
## [v1.2.1] - 2021-05-06
### Fix
**docker:** add missing ca-certs
<a name="v1.2.0"></a>
## v1.2.0
### Ci
- breakout docker build for merge only
### Feat
- update RPC version to 1.2.0.
- BREAKING CHANGE: add heartbeat capability, bump RPC Protocol version to 4.0.0
- add unit test framework
- add hostname to activation info
- **docker:** add dockerfile support for RPC
### Fix
- use message status instead, cleanup message fields.
<a name="v1.1.0"></a>
## [v1.1.0] - 2021-02-09
+3 -1
View File
@@ -1,6 +1,6 @@
cmake_minimum_required (VERSION 3.1)
project (rpc VERSION 1.1.0)
project (rpc VERSION 1.2.1)
set (CMAKE_CXX_STANDARD 11)
@@ -100,6 +100,8 @@ add_executable (rpc
activation.cpp
shbc.h
shbc.cpp
heartbeat.h
heartbeat.cpp
lms.h
lms.cpp
main.cpp
+37
View File
@@ -0,0 +1,37 @@
#*********************************************************************
# Copyright (c) Intel Corporation 2021
# SPDX-License-Identifier: Apache-2.0
#*********************************************************************/
FROM ubuntu:20.04 AS rpc-builder
WORKDIR /
ARG DEBIAN_FRONTEND=noninteractive
RUN \
apt-get update -y -qq && \
apt install -y -qq \
git cmake build-essential libssl-dev zlib1g-dev \
curl unzip zip pkg-config ca-certificates
RUN git clone https://github.com/open-amt-cloud-toolkit/rpc.git
WORKDIR /rpc
RUN mkdir -p build
RUN git clone --branch 2020.11-1 https://github.com/microsoft/vcpkg.git
RUN cd vcpkg && ./bootstrap-vcpkg.sh
RUN ./vcpkg/vcpkg install cpprestsdk[websockets]
WORKDIR /rpc/build
RUN cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake ..
RUN cmake --build .
FROM ubuntu:20.04
LABEL license='SPDX-License-Identifier: Apache-2.0' \
copyright='Copyright (c) 2021: Intel'
WORKDIR /root
RUN \
apt-get update -y -qq && \
apt install -y -qq \
libssl-dev
COPY --from=rpc-builder /rpc/build/rpc .
ENTRYPOINT ["/root/rpc"]
Vendored
+154
View File
@@ -0,0 +1,154 @@
pipeline {
agent {
label 'docker-amt'
}
options {
buildDiscarder(logRotator(numToKeepStr: '5', daysToKeepStr: '30'))
timestamps()
timeout(unit: 'HOURS', time: 2)
}
stages {
stage ('Cloning Repository') {
steps {
script {
scmCheckout {
clean = true
}
}
}
}
stage('Static Code Scan - Protex') {
environment{
PROJECT_NAME = 'OpenAMT - RPC'
SCANNERS = 'protex'
}
steps {
rbheStaticCodeScan()
}
}
stage ('Parallel Builds') {
parallel {
stage ('Linux') {
agent { label 'docker-amt' }
stages {
stage('Build') {
agent {
docker {
image 'ubuntu:18.04'
reuseNode true
}
}
steps {
sh './scripts/jenkins-pre-build.sh'
sh './scripts/jenkins-build.sh'
stash includes: 'build/rpc', name: 'linux-rpc-app'
}
}
stage ('Archive') {
steps {
archiveArtifacts allowEmptyArchive: true, artifacts: 'build/rpc', caseSensitive: false, onlyIfSuccessful: true
}
}
}
}
stage ('Windows') {
agent { label 'openamt-win' }
stages{
stage ('Build') {
steps {
bat 'scripts\\jenkins-pre-build.cmd'
bat 'scripts\\jenkins-build.cmd'
// prepare stash for the binary scan
stash includes: '**/*.exe', name: 'win-rpc-app'
}
}
stage ('Archive') {
steps {
archiveArtifacts allowEmptyArchive: true, artifacts: 'build\\Release\\rpc.exe', caseSensitive: false, onlyIfSuccessful: true
}
}
}
}
}
}
stage('Prep Binary') {
steps {
sh 'mkdir -p ./bin'
dir('./bin') {
unstash 'linux-rpc-app'
unstash 'win-rpc-app'
}
}
}
stage('Linux Scans') {
environment{
PROJECT_NAME = 'OpenAMT - RPC - Linux'
SCANNERS = 'bdba,klocwork'
// protecode details
PROTECODE_BIN_DIR = './bin'
PROTECODE_INCLUDE_SUB_DIRS = true
// klocwork details
KLOCWORK_SCAN_TYPE = 'c++'
KLOCWORK_PRE_BUILD_SCRIPT = './scripts/jenkins-pre-build.sh'
KLOCWORK_BUILD_COMMAND = './scripts/jenkins-build.sh'
KLOCWORK_IGNORE_COMPILE_ERRORS = true
// publishArtifacts details
PUBLISH_TO_ARTIFACTORY = true
}
steps {
rbheStaticCodeScan()
dir('artifacts/Klockwork'){
sh 'cp kw_report.html kw_report_linux.html'
sh 'cp kw_report.csv kw_report_linux.csv'
archiveArtifacts allowEmptyArchive: true, artifacts: 'kw_report_linux.html'
archiveArtifacts allowEmptyArchive: true, artifacts: 'kw_report_linux.csv'
}
}
}
stage('Windows Scans'){
agent { label 'openamt-win' }
stages{
stage ('Windows Scans - klocwork') {
environment {
PROJECT_NAME = 'OpenAMT - RPC - Windows'
SCANNERS = 'klocwork'
// klocwork details
KLOCWORK_SCAN_TYPE = 'c++'
KLOCWORK_PRE_BUILD_SCRIPT = 'scripts\\jenkins-pre-build.cmd'
KLOCWORK_BUILD_COMMAND = 'scripts\\jenkins-build.cmd'
KLOCWORK_IGNORE_COMPILE_ERRORS = true
// publishArtifacts details
PUBLISH_TO_ARTIFACTORY = true
}
steps {
rbheStaticCodeScan()
dir('artifacts\\Klockwork'){
bat 'copy kw_report.html kw_report_windows.html'
bat 'copy kw_report.csv kw_report_windows.csv'
stash includes: 'kw_report_windows.*', name: 'win-kwreports'
archiveArtifacts allowEmptyArchive: true, artifacts: 'kw_report_windows.html'
archiveArtifacts allowEmptyArchive: true, artifacts: 'kw_report_windows.csv'
}
}
}
}
}
stage('Publish Artifacts'){
steps{
dir('artifacts/Klockwork'){
unstash 'win-kwreports'
}
publishArtifacts()
}
}
}
}
+3 -3
View File
@@ -479,6 +479,8 @@ typedef enum
CERT_HASH_ALGORITHM_MD5 = 0, // 16 bytes
CERT_HASH_ALGORITHM_SHA1, // 20 bytes
CERT_HASH_ALGORITHM_SHA256, // 32 bytes
CERT_HASH_ALGORITHM_SHA384, // 48 bytes
CERT_HASH_ALGORITHM_SHA224, // 28 bytes
CERT_HASH_ALGORITHM_SHA512, // 64 bytes
} CERT_HASH_ALGORITHM;
@@ -683,9 +685,7 @@ typedef struct _CFG_START_CONFIG_HBASED_REQUEST
typedef struct _CFG_START_CONFIG_HBASED_RESPONSE_INFO
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_STATUS Status;
CERT_HASH_ALGORITHM HashAlgorithm;
UINT8 HashAlgorithm;
UINT8 AMTCertHash[CERT_HASH_MAX_LENGTH];
} CFG_START_CONFIG_HBASED_RESPONSE_INFO;
+23 -6
View File
@@ -4,26 +4,43 @@
The Remote Provisioning Client (RPC) is an application that enables remote capabilities for Intel® AMT, such as as device activation and configuration. To accomplish this, RPC communicates with the Remote Provisioning Server (RPS) to activate and connect the edge device.
<br><br>
**For detailed documentation** about RPC or other features of the Open AMT Cloud Toolkit, see the [docs](https://open-amt-cloud-toolkit.github.io/docs/).
<br>
## Prerequisites
We leverage GitHub Actions as a means to build RPC automatically leveraging Github's CI/CD Infrastructure. This avoids having to deal with the challenges of getting your build environment just right on your local machine and allows you to get up and running much faster. Read more about GitHub Actions [here](https://github.blog/2019-08-08-github-actions-now-supports-ci-cd/#:~:text=GitHub%20Actions%20is%20an%20API,every%20step%20along%20the%20way.)
## Build the Remote Provisioning Client (RPC)
<p align="center">
<img src="assets/animations/forkandbuild.gif" width="650" />
</p>
1. Create a fork of the rpc repository [here](https://github.com/open-amt-cloud-toolkit/rpc/fork) or via the Fork button in the top-right corner of the rpc repository.
## Build the Remote Provisioning Client (RPC)
2. Click on "Actions" and Select "Build RPC (Native)" Workflow.
1. <a href="https://github.com/open-amt-cloud-toolkit/rpc/fork" target="_blank">Create a fork of rpc on GitHub.</a>
3. Click "Run Workflow", select branch "master", and click "Run Workflow".
2. Click on the **Actions** tab at the top and select **Build RPC (Native) Debug/Release**.
4. Grab a coffee. The build for Windows will take approximately 30 minutes and the build for Linux will take approximately 5 minutes.
3. Click the **Run Workflow** dropdown.
5. Once complete, click the completed job, and download the appropriate RPC for your OS under the "Artifacts" section.
4. Select the **Branch: master**, or a preferred version, from the **Use workflow from** dropdown.
5. By default, the Build Type should be **release**.
6. Click the **Run Workflow** button. Grab a coffee and take a break! The build time ranges from 15 to 20 minutes.
8. Once the download is complete, click the completed job which will feature a green checkmark.
9. Download the appropriate RPC for your managed device's OS under the **Artifacts** section.
### To Delete your workflow run
1. Click the ellipsis ( **...** ) menu for the workflow.
2. Choose the **Delete workflow run** option.
For detailed documentation about RPC and using it to activate a device, see the [docs](https://open-amt-cloud-toolkit.github.io/docs/)
+5
View File
@@ -0,0 +1,5 @@
# Security Policy
Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation.
## Reporting a Vulnerability
Please report any security vulnerabilities in this project utilizing the guidelines [here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html).
+7 -2
View File
@@ -264,7 +264,12 @@ bool act_create_request(std::string commands, std::string dns_suffix, std::strin
// serialize payload
std::string serializedPayload = utility::conversions::to_utf8string(activationPayload.serialize());
std::string encodedPayload = util_encode_base64(serializedPayload);
std::vector<unsigned char> serializedPayloadVector;
for (int i = 0; i < serializedPayload.size(); i++)
{
serializedPayloadVector.push_back(serializedPayload[i]);
}
std::string encodedPayload = util_encode_base64(serializedPayloadVector);
utility::string_t payload = utility::conversions::to_string_t(encodedPayload);
msg[U("payload")] = web::json::value::string(payload);
@@ -274,7 +279,7 @@ bool act_create_request(std::string commands, std::string dns_suffix, std::strin
return true;
}
bool act_create_response(std::string payload, std::string& response)
bool act_create_response(std::vector<unsigned char> payload, std::string& response)
{
web::json::value msg;
+3 -2
View File
@@ -7,8 +7,9 @@
#define __ACTIVATION_H__
#include <string>
#include <vector>
#define PROTOCOL_VERSION "3.0.0"
#define PROTOCOL_VERSION "4.1.0"
#ifdef _WIN32
#define convertstring to_utf16string
@@ -17,6 +18,6 @@
#endif
bool act_create_request(std::string commands, std::string dns_suffix, std::string& request);
bool act_create_response(std::string payload, std::string& response);
bool act_create_response(std::vector<unsigned char> payload, std::string& response);
#endif
+54 -14
View File
@@ -32,9 +32,6 @@ bool cmd_is_admin()
bool cmd_get_version(std::string& version)
{
version = "14.0.0"; // FIXME: REMOVE WHEN HW AVAILABLE
return true; // FIXME: REMOVE WHEN HW AVAILABLE
version.clear();
// initialize HECI interface
@@ -285,8 +282,10 @@ bool cmd_get_certificate_hashes(std::vector<cert_hash_entry>& hash_entries)
for (int i = 0; i < (int) amt_hash_handles.Length; i++)
{
// get each entry
AMT_STATUS status = pthi_GetCertificateHashEntry(amt_hash_handles.Handles[i], &certhash_entry);
AMT_STATUS amt_status = pthi_GetCertificateHashEntry(amt_hash_handles.Handles[i], &certhash_entry);
if (amt_status == 0)
{
int hashSize;
cert_hash_entry tmp;
switch (certhash_entry.HashAlgorithm) {
@@ -332,6 +331,7 @@ bool cmd_get_certificate_hashes(std::vector<cert_hash_entry>& hash_entries)
hash_entries.push_back(tmp);
}
}
}
return true;
}
@@ -380,14 +380,14 @@ bool cmd_get_remote_access_connection_status(int& network_status, int& remote_st
return false;
}
bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settings)
bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settings, bool wired_interface)
{
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get wired interface
LAN_SETTINGS lan_settings;
UINT32 interface_settings = 0; // wired=0, wireless=1
UINT32 interface_settings = (wired_interface) ? 0 : 1; // wired=0, wireless=1
AMT_STATUS amt_status = pthi_GetLanInterfaceSettings(interface_settings, &lan_settings);
if (amt_status == 0)
{
@@ -396,11 +396,13 @@ bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settin
lan_interface_settings.dhcp_enabled = lan_settings.DhcpEnabled;
lan_interface_settings.link_status = lan_settings.LinkStatus;
lan_interface_settings.ip_address.clear();
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 24) & 0xff);
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 16) & 0xff);
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 8) & 0xff);
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address) & 0xff);
lan_interface_settings.mac_address.clear();
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[0]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[1]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[2]);
@@ -416,10 +418,6 @@ bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settin
bool cmd_start_config_host_based(config_host_based_settings& server_cert, config_host_based_settings& amt_cert)
{
amt_cert.algorithm = "MD5"; // FIXME: REMOVE WHEN HW AVAILABLE
amt_cert.hash = "000102030405060708090a0b0c0d0e0f"; // FIXME: REMOVE WHEN HW AVAILABLE
return true; // FIXME: REMOVE WHEN HW AVAILABLE
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
@@ -450,7 +448,8 @@ bool cmd_start_config_host_based(config_host_based_settings& server_cert, config
return false;
}
std::vector<char> cert_bytes;
int hashSize;
std::vector<unsigned char> cert_bytes;
util_hex_string_to_bytes(server_cert.hash, cert_bytes);
std::copy(std::begin(cert_bytes), std::end(cert_bytes), request.ServerCertHash);
@@ -463,22 +462,29 @@ bool cmd_start_config_host_based(config_host_based_settings& server_cert, config
{
case CERT_HASH_ALGORITHM_MD5:
amt_cert.algorithm = "MD5";
hashSize = 16;
break;
case CERT_HASH_ALGORITHM_SHA1:
amt_cert.algorithm = "SHA1";
hashSize = 20;
break;
case CERT_HASH_ALGORITHM_SHA256:
amt_cert.algorithm = "SHA256";
hashSize = 32;
break;
case CERT_HASH_ALGORITHM_SHA512:
amt_cert.algorithm = "SHA512";
hashSize = 64;
break;
default:
break;
case CERT_HASH_ALGORITHM_SHA384:
case CERT_HASH_ALGORITHM_SHA224:
return false;
}
std::vector<char> hash;
std::copy(std::begin(response.AMTCertHash), std::end(response.AMTCertHash), std::begin(hash));
std::vector<unsigned char> hash;
hash.resize(hashSize);
std::copy(response.AMTCertHash, response.AMTCertHash + hashSize, std::begin(hash));
util_bytes_to_hex_string(hash, amt_cert.hash);
return true;
@@ -486,3 +492,37 @@ bool cmd_start_config_host_based(config_host_based_settings& server_cert, config
return false;
}
bool cmd_get_provisioning_state(int& state)
{
state = 0;
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get Control Mode
AMT_PROVISIONING_STATE provisioningState;
AMT_STATUS amt_status = pthi_GetProvisioningState(&provisioningState);
if (amt_status == 0)
{
state = provisioningState;
return true;
}
return false;
}
bool cmd_stop_configuration()
{
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
AMT_STATUS amt_status = pthi_StopConfiguration();
if (amt_status == 0)
{
return true;
}
return false;
}
+3 -1
View File
@@ -55,7 +55,9 @@ bool cmd_get_dns_suffix(std::string& suffix);
bool cmd_get_wired_mac_address(std::vector<unsigned char>& address);
bool cmd_get_certificate_hashes(std::vector<cert_hash_entry>& hash_entries);
bool cmd_get_remote_access_connection_status(int& network_status, int& remote_status, int& remote_trigger, std::string& mps_hostname);
bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settings);
bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settings, bool wired_interface = true);
bool cmd_start_config_host_based(config_host_based_settings& server_cert, config_host_based_settings& amt_cert);
bool cmd_get_provisioning_state(int& state);
bool cmd_stop_configuration();
#endif
+48
View File
@@ -0,0 +1,48 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "heartbeat.h"
#include <cpprest/ws_client.h>
#include <cpprest/json.h>
#include <cpprest/streams.h>
#include <iostream>
#include <string>
#include "activation.h"
#include "version.h"
#include "commands.h"
#include "network.h"
#include "utils.h"
bool heartbeat_create_response(std::string& response)
{
web::json::value msg;
utility::string_t tmp = utility::conversions::convertstring("heartbeat_response");
msg[U("method")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring("");
msg[U("apiKey")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring(PROJECT_VER);
msg[U("appVersion")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring(PROTOCOL_VERSION);
msg[U("protocolVersion")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring("success");
msg[U("status")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring("");
msg[U("message")] = web::json::value::string(tmp);
// set empty payload
tmp = utility::conversions::convertstring("");
msg[U("payload")] = web::json::value::string(tmp);
// serialize the entire message
response = utility::conversions::to_utf8string(msg.serialize());
return true;
}
+13
View File
@@ -0,0 +1,13 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __HEARTBEAT_H__
#define __HEARTBEAT_H__
#include <string>
bool heartbeat_create_response(std::string& response);
#endif
+29 -3
View File
@@ -20,7 +20,7 @@ void out_text(const std::string name, const std::vector<unsigned char> value, co
for (unsigned char tmp : value)
{
(hex) ? std::cout << std::setfill('0') << std::setw(2) << std::hex << (unsigned int)tmp
: std::cout << (unsigned int)tmp;
: std::cout << std::dec << (unsigned int)tmp;
if (char_count++ < value.size())
{
@@ -270,17 +270,43 @@ bool info_get_lan_interface_settings()
tmp.ip_address.clear();
tmp.mac_address.clear();
if (!cmd_get_lan_interface_settings(tmp)) return false;
bool hasWired = cmd_get_lan_interface_settings(tmp);
if (hasWired)
{
out_text("LAN Inteface", "wired");
out_text("DHCP Enabled", (tmp.dhcp_enabled) ? "true" : "false");
out_text("DHCP Mode", (tmp.dhcp_mode == 1) ? "active" : "passive");
out_text("Link Status", (tmp.link_status) ? "up" : "down");
out_text("IP Address", tmp.ip_address, '.', false);
out_text("MAC Address", tmp.mac_address, ':');
}
tmp.is_enabled = false;
tmp.link_status = false;
tmp.dhcp_enabled = false;
tmp.dhcp_mode = 0;
tmp.ip_address.clear();
tmp.mac_address.clear();
bool hasWireless = cmd_get_lan_interface_settings(tmp, false);
if (hasWireless)
{
out_text("LAN Inteface", "wireless");
out_text("DHCP Enabled", (tmp.dhcp_enabled) ? "true" : "false");
out_text("DHCP Mode", (tmp.dhcp_mode == 1) ? "active" : "passive");
out_text("Link Status", (tmp.link_status) ? "up" : "down");
out_text("IP Address", tmp.ip_address, '.', false);
out_text("MAC Address", tmp.mac_address, ':');
}
if (hasWired || hasWireless)
{
return true;
}
return false;
}
bool info_get(const std::string info)
{
if (info.compare("ver") == 0)
+102 -18
View File
@@ -12,6 +12,7 @@
#include "commands.h"
#include "activation.h"
#include "shbc.h"
#include "heartbeat.h"
#include "utils.h"
#include "usage.h"
#include "args.h"
@@ -62,7 +63,7 @@ int main(int argc, char* argv[])
std::string arg_info;
bool arg_verbose = false;
bool arg_nocertcheck = false;
bool secureHostBasedConfig = false;
bool shbc_config = false;
if (argc == 1)
{
@@ -186,7 +187,7 @@ int main(int argc, char* argv[])
memset(&lms_socket, 0, sizeof(SOCKET));
// set receive handler
client.set_message_handler([&client, &mx, &cv, &lms_socket, arg_verbose, &secureHostBasedConfig](web::websockets::client::websocket_incoming_message ret_msg)
client.set_message_handler([&client, &mx, &cv, &lms_socket, arg_verbose, &shbc_config](web::websockets::client::websocket_incoming_message ret_msg)
{
// kick the timer
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
@@ -211,7 +212,7 @@ int main(int argc, char* argv[])
std::string msgStatus = "";
std::string msgMessage = "";
std::string msgPayload = "";
std::string payloadDecoded = "";
std::vector<unsigned char> payloadDecoded;
if ( !parsed.has_field(U("method")) || !parsed.has_field(U("apiKey")) || !parsed.has_field(U("appVersion")) ||
!parsed.has_field(U("protocolVersion")) || !parsed.has_field(U("status")) || !parsed.has_field(U("message")) ||
@@ -248,6 +249,21 @@ int main(int argc, char* argv[])
return;
}
if (msgMethod.compare("heartbeat_request") == 0)
{
// create the response
std::string response;
if (!heartbeat_create_response(response)) return;
// send it
web::websockets::client::websocket_outgoing_message send_websocket_msg;
std::string send_websocket_buffer(response);
send_websocket_msg.set_utf8_message(send_websocket_buffer);
client.send(send_websocket_msg).wait();
return;
}
if (msgMethod.compare("secure_config_request") == 0)
{
std::string certAlgo;
@@ -276,11 +292,37 @@ int main(int argc, char* argv[])
config_host_based_settings amt_cert;
server_cert.algorithm = certAlgo;
server_cert.hash = certHash;
if (cmd_start_config_host_based(server_cert, amt_cert))
bool sbhc_success = cmd_start_config_host_based(server_cert, amt_cert);
// wait for configuration to settle down
std::this_thread::sleep_for(std::chrono::seconds(1));
if (!sbhc_success)
{
int state;
if (cmd_get_provisioning_state(state))
{
switch (state) {
case 0:
std::cout << "Provisioning state already in pre-provisioning." << std::endl;
break;
case 1:
std::cout << "Provisioning state is in-provisioning." << std::endl;
(cmd_stop_configuration()) ? std::cout << "Provisioning state succesfully reset." << std::endl : std::cout << "Provisioning state could not be reset." << std::endl;
break;
case 2:
std::cout << "Provisioning state is post-provisioning." << std::endl;
(cmd_stop_configuration()) ? std::cout << "Provisioning state succesfully reset." << std::endl : std::cout << "Provisioning state could not be reset." << std::endl;
break;
default:
break;
}
}
}
// create the response
std::string response;
if (!shbc_create_response(amt_cert.algorithm, amt_cert.hash, response)) return;
if (!shbc_create_response(amt_cert.algorithm, amt_cert.hash, sbhc_success, response)) return;
// send it
web::websockets::client::websocket_outgoing_message send_websocket_msg;
@@ -289,11 +331,7 @@ int main(int argc, char* argv[])
client.send(send_websocket_msg).wait();
// use secure host post for LMS going forward
secureHostBasedConfig = true;
return;
}
shbc_config = sbhc_success;
return;
}
@@ -349,7 +387,7 @@ int main(int argc, char* argv[])
try
{
// conntect to lms
lms_socket = lms_connect(secureHostBasedConfig);
lms_socket = lms_connect(shbc_config);
}
catch (...)
{
@@ -360,11 +398,34 @@ int main(int argc, char* argv[])
if (arg_verbose)
{
std::cout << std::endl << "vvv -- message to AMT -- vvv" << std::endl;
std::cout << payloadDecoded << std::endl;
if (shbc_config)
{
std::cout << "message size is " << payloadDecoded.size() << " bytes." << std::endl;
for (int i = 0; i < payloadDecoded.size(); i++)
{
printf("%02x ", payloadDecoded[i]);
if ((i > 0) && ((i+1) % 32 == 0))
{
std::cout << std::endl;
}
}
std::cout << std::endl;
}
else
{
for (int i = 0; i < payloadDecoded.size(); i++)
{
printf("%c", payloadDecoded[i]);
}
}
std::cout << std::endl;
}
// send message to LMS
if (send(lms_socket, payloadDecoded.c_str(), (int)payloadDecoded.length(), 0) < 0)
int sendPayloudStatus = send(lms_socket, (const char *) payloadDecoded.data(), payloadDecoded.size(), 0);
if (sendPayloudStatus < 0)
{
throw std::runtime_error("error: socket send");
}
@@ -383,7 +444,8 @@ int main(int argc, char* argv[])
// read until connection is closed by LMS
while (1)
{
std::string superBuffer = "";
std::vector<unsigned char> superBuffer;
superBuffer.clear();
while (1)
{
int res = select(fd, &rset, NULL, NULL, &timeout);
@@ -401,7 +463,9 @@ int main(int argc, char* argv[])
res = recv(lms_socket, recv_buffer, 4096, 0);
if (res > 0)
{
superBuffer += recv_buffer;
for (int i = 0; i < res; i++) {
superBuffer.push_back(recv_buffer[i]);
}
}
else if (res < 0)
{
@@ -417,16 +481,36 @@ int main(int argc, char* argv[])
} // while select()
// if there is some data send it
if (superBuffer.length() > 0)
if (superBuffer.size() > 0)
{
if (arg_verbose)
{
std::cout << std::endl << "^^^ -- message from AMT -- ^^^" << std::endl;
std::cout << superBuffer << std::endl;
if (shbc_config)
{
std::cout << "message size is " << superBuffer.size() << " bytes." << std::endl;
for (int i = 0; i < superBuffer.size(); i++)
{
printf("%02x ", superBuffer[i]);
if ((i > 0) && ((i + 1) % 32 == 0))
{
std::cout << std::endl;
}
}
std::cout << std::endl;
}
else
{
for (int i = 0; i < superBuffer.size(); i++)
{
printf("%c", superBuffer[i]);
}
}
std::cout << std::endl;
}
std::string response;
if (!act_create_response(superBuffer.c_str(), response)) return;
if (!act_create_response(superBuffer, response)) return;
web::websockets::client::websocket_outgoing_message send_websocket_msg;
std::string send_websocket_buffer(response);
+2 -2
View File
@@ -14,7 +14,7 @@ set BASE_DIR=%cd%
set VCPKG_DIR=C:\opt\vcpkg-source
REM build RPC
cd %BASE_DIR%/rpc
if exist "build" rd /q /s "build"
@@ -23,4 +23,4 @@ cd build
echo %VCPKG_DIR%\vcpkg\scripts\buildsystems\vcpkg.cmake
cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_TOOLCHAIN_FILE=%VCPKG_DIR%\vcpkg\scripts\buildsystems\vcpkg.cmake ..
cmake --build . --config Release
dir %BASE_DIR%\rpc\build
dir %BASE_DIR%\build
+3 -3
View File
@@ -5,9 +5,9 @@ set -x
# Jenkins Build script
# - Ubuntu 18.04
#
export BASE_DIR="$PWD"
export CMAKE_CXX_FLAGS="-isystem /usr/lib/gcc/x86_64-linux-gnu/7/include"
cd "$BASE_DIR"/rpc
if [ -d "build" ]; then
rm -rf build
@@ -15,5 +15,5 @@ fi
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE="$BASE_DIR"/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release ..
cmake -DCMAKE_TOOLCHAIN_FILE="$BASE_DIR"/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
+5 -4
View File
@@ -4,14 +4,15 @@
# - Ubuntu 18.04
#
sudo apt install git cmake build-essential curl zip unzip tar pkg-config
apt update
apt install git cmake build-essential curl zip unzip tar pkg-config -y
## current dir - RPC source directory
export BASE_DIR="$PWD"
#export BASE_DIR="$PWD"
cd "$BASE_DIR"/rpc
#cd "$BASE_DIR"/rpc
## build vcpkg
git clone --branch 2020.11-1 https://github.com/microsoft/vcpkg.git
git -C vcpkg pull || git clone --branch 2020.11-1 https://github.com/microsoft/vcpkg.git vcpkg
cd vcpkg
./bootstrap-vcpkg.sh
+21 -5
View File
@@ -33,7 +33,7 @@ bool get_response_payload(std::string cert_algo, std::string cert_hash, web::jso
return true;
}
bool shbc_create_response(std::string cert_algo, std::string cert_hash, std::string& response)
bool shbc_create_response(std::string cert_algo, std::string cert_hash, bool config_status, std::string& response)
{
web::json::value msg;
@@ -49,22 +49,38 @@ bool shbc_create_response(std::string cert_algo, std::string cert_hash, std::str
tmp = utility::conversions::convertstring(PROTOCOL_VERSION);
msg[U("protocolVersion")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring("");
msg[U("status")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring("");
msg[U("message")] = web::json::value::string(tmp);
if (config_status)
{
// get the activation payload
web::json::value responsePayload;
if (!get_response_payload(cert_algo, cert_hash, responsePayload)) return false;
// serialize payload
std::string serializedPayload = utility::conversions::to_utf8string(responsePayload.serialize());
std::string encodedPayload = util_encode_base64(serializedPayload);
std::vector<unsigned char> serializedPayloadVector;
for (int i = 0; i < serializedPayload.size(); i++)
{
serializedPayloadVector.push_back(serializedPayload[i]);
}
std::string encodedPayload = util_encode_base64(serializedPayloadVector);
utility::string_t payload = utility::conversions::to_string_t(encodedPayload);
msg[U("payload")] = web::json::value::string(payload);
tmp = utility::conversions::convertstring("success");
msg[U("status")] = web::json::value::string(tmp);
}
else
{
tmp = utility::conversions::convertstring("");
msg[U("payload")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring("failed");
msg[U("status")] = web::json::value::string(tmp);
}
// serialize the entire message
response = utility::conversions::to_utf8string(msg.serialize());
+1 -1
View File
@@ -14,6 +14,6 @@
#define convertstring to_utf8string
#endif
bool shbc_create_response(std::string cert_algo, std::string cert_hash, std::string& response);
bool shbc_create_response(std::string cert_algo, std::string cert_hash, bool config_status, std::string& response);
#endif
+2 -2
View File
@@ -29,7 +29,7 @@ TEST(testUtils, isPrintableTestInvalid)
EXPECT_EQ(false, util_is_printable(s));
}
/*
// Test encode of base64 string
TEST(testUtils, encodebase64)
{
@@ -41,7 +41,7 @@ TEST(testUtils, decodebase64)
{
EXPECT_EQ(plainText, util_decode_base64(encodedText));
}
*/
// Test return value of util_format_uuid
TEST(testUtils, formatUUIDSuccess)
{
+3 -3
View File
@@ -49,15 +49,15 @@ void usage_show_help()
std::cout << "Examples:" << std::endl;
std::cout << " # Activate platform using profile1" << std::endl;
std::cout << " " << PROJECT_NAME << \
" --url wss://localhost:8080 --cmd \"-t activate --profile profile1\"" << std::endl;
" --url wss://192.168.86.100/activate --cmd \"-t activate --profile profile1\"" << std::endl;
std::cout << std::endl;
std::cout << " # Activate platform using profile1 and override DNS detection" << std::endl;
std::cout << " " << PROJECT_NAME << \
" --url wss://localhost:8080 --cmd \"-t activate --profile profile1\" --dns corp.com" << std::endl;
" --url wss://mycloud.com/activate --cmd \"-t activate --profile profile1\" --dns corp.com" << std::endl;
std::cout << std::endl;
std::cout << " # Deactivate platform and connect through a proxy" << std::endl;
std::cout << " " << PROJECT_NAME << \
" -u wss://localhost:8080 -c \"-t deactivate --password P@ssw0rd\" -p http://proxy.com:1000" << std::endl;
" -u wss://mycloud.com/activate -c \"-t deactivate --password P@ssw0rd\" -p http://proxy.com:1000" << std::endl;
std::cout << std::endl;
std::cout << " # Show all informational items" << std::endl;
std::cout << " " << PROJECT_NAME << " --amtinfo all" << std::endl;
+9 -7
View File
@@ -8,7 +8,7 @@
#include <string>
#include <cpprest/streams.h>
std::string util_encode_base64(std::string str)
std::string util_encode_base64(std::vector<unsigned char> str)
{
std::vector<unsigned char> strVector(str.begin(), str.end());
utility::string_t base64 = utility::conversions::to_base64(strVector);
@@ -17,11 +17,11 @@ std::string util_encode_base64(std::string str)
return encodedString;
}
std::string util_decode_base64(std::string str)
std::vector<unsigned char> util_decode_base64(std::string str)
{
utility::string_t serializedData = utility::conversions::to_string_t(str);
std::vector<unsigned char> strVector = utility::conversions::from_base64(serializedData);
std::string decodedString(strVector.begin(), strVector.end());
std::vector<unsigned char> decodedString(strVector.begin(), strVector.end());
return decodedString;
}
@@ -57,25 +57,27 @@ bool util_format_uuid(std::vector<unsigned char> uuid_bytes, std::string& uuid_s
return true;
}
bool util_hex_string_to_bytes(std::string hex_string, std::vector<char>& hex_bytes)
bool util_hex_string_to_bytes(std::string hex_string, std::vector<unsigned char>& hex_bytes)
{
hex_bytes.clear();
for (int i = 0; i < hex_string.length(); i += 2)
{
std::string byte_string = hex_string.substr(i, 2);
char value = (char)strtol(byte_string.c_str(), NULL, 16);
byte_string[0] = tolower(byte_string[0]);
byte_string[1] = tolower(byte_string[1]);
unsigned char value = (char)strtol(byte_string.c_str(), NULL, 16);
hex_bytes.push_back(value);
}
return true;
}
bool util_bytes_to_hex_string(std::vector<char> hex_bytes, std::string& hex_string)
bool util_bytes_to_hex_string(std::vector<unsigned char> hex_bytes, std::string& hex_string)
{
hex_string.clear();
for (char hex_char : hex_bytes)
for (unsigned char hex_char : hex_bytes)
{
char hex[10];
snprintf(hex, 10, "%02x", hex_char);
+4 -4
View File
@@ -9,11 +9,11 @@
#include <string>
#include <vector>
std::string util_encode_base64(std::string str);
std::string util_decode_base64(std::string str);
std::string util_encode_base64(std::vector<unsigned char> str);
std::vector<unsigned char> util_decode_base64(std::string str);
bool util_is_printable(std::string str);
bool util_format_uuid(std::vector<unsigned char> uuid_bytes, std::string& uuid_string);
bool util_hex_string_to_bytes(std::string hex_string, std::vector<char>& hex_bytes);
bool util_bytes_to_hex_string(std::vector<char> hex_bytes, std::string& hex_string);
bool util_hex_string_to_bytes(std::string hex_string, std::vector<unsigned char>& hex_bytes);
bool util_bytes_to_hex_string(std::vector<unsigned char> hex_bytes, std::string& hex_string);
#endif