108 Commits

Author SHA1 Message Date
Mike
c9a2ab44dd fix(spelling): lan inteface -> lan interface in amtinfo 2021-08-24 16:03:21 -07:00
Mike
fb29227f9d Merge pull request #61 from open-amt-cloud-toolkit/feat_message_formatting
feat: format json status messages
2021-08-18 08:51:44 -07:00
Mudit Vats
26629a1a68 feat: format json status messages 2021-08-17 13:41:07 -07:00
Mike
db924a9b2e build: bump version to v1.3.0 2021-08-02 10:13:39 -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
trleasher-intel
da9c26bc26 Merge pull request #30 from open-amt-cloud-toolkit/feature_test_framework
feat: add unit test framework
2021-02-16 08:37:47 -07:00
Mudit Vats
bb4e144684 feat: add unit test framework 2021-02-12 16:49:02 -07:00
trleasher-intel
86cf9657ad Merge pull request #29 from open-amt-cloud-toolkit/feature_hostname
feat: add hostname to activation info
2021-02-12 15:54:23 -07:00
Mudit Vats
025152f359 feat: add hostname to activation info 2021-02-12 14:42:43 -07:00
mpvats-intel
9b0d7fe649 Merge pull request #26 from open-amt-cloud-toolkit/changelog
docs: changelog
2021-02-11 13:05:49 -07:00
Mike
b2a54c47a3 Merge branch 'master' into changelog 2021-02-11 12:11:55 -07:00
Mike
a859cf5648 docs: add changelog 2021-02-11 12:11:34 -07:00
mpvats-intel
5a9597fc2b Merge pull request #27 from open-amt-cloud-toolkit/fix_kw_defect
fix: free fqdn buffer
2021-02-11 11:16:47 -07:00
Mudit Vats
b1f7b32baa fix: free fqdn buffer 2021-02-11 10:28:16 -07:00
mpvats-intel
2fb64ac3f8 Merge pull request #24 from open-amt-cloud-toolkit/feature_version_tick
feat: version update
2021-02-09 14:59:29 -07:00
Mudit Vats
b03e2988a5 feat: version update 2021-02-09 13:49:09 -07:00
mpvats-intel
acf428537f Merge pull request #23 from open-amt-cloud-toolkit/jenkins_scripts
build(jenkins): jenkins build scripts for Windows and Ubuntu
2021-02-09 08:53:45 -07:00
trleasher-intel
6cd660a7af build(jenkins): jenkins build scripts for Windows and Ubuntu 2021-02-09 08:02:21 -07:00
mpvats-intel
c4de327e7e Merge pull request #21 from rsdmike/master
ci: add support for debug/release builds
2021-02-02 10:17:41 -07:00
Mike
fc600d61a1 Merge branch 'master' of https://github.com/rsdmike/rpc 2021-02-02 09:49:41 -07:00
Mike
41a1be5249 ci: update build 2021-02-02 09:49:24 -07:00
Mike
4e5dccce89 ci: update build 2021-01-29 13:42:56 -07:00
Mike
0679235cba Merge branch 'master' of https://github.com/rsdmike/rpc 2021-01-29 10:12:21 -07:00
Mike
95a422478b Merge pull request #22 from open-amt-cloud-toolkit/semantic
ci: add types for conventional commits
2021-01-28 20:55:08 -07:00
Mike
f9f70d23f9 Merge branch 'master' into semantic 2021-01-28 16:29:34 -07:00
mpvats-intel
f1b32ef953 Merge pull request #20 from open-amt-cloud-toolkit/feature_nocertcheck
feat: cli skip cert checking
2021-01-28 15:45:09 -07:00
Mudit Vats
d23b1c4be5 Add newline. 2021-01-28 15:22:57 -07:00
Mudit Vats
b54025168c Add --nocertcheck, -n args to skip websocket server certificate verification for all builds. 2021-01-28 14:57:56 -07:00
Mike
6433a553a0 Merge pull request #11 from rsdmike/releaseOption
ci: add support for release or debug
2021-01-28 14:43:19 -07:00
Mike
b13c070598 Merge pull request #10 from rsdmike/releaseOption
ci: add support for release or debug
2021-01-28 13:44:09 -07:00
Mike
ecc31a25f7 ci: add support for release or debug
Signed-off-by: Mike <michael.johanson@intel.com>
2021-01-28 13:41:34 -07:00
Mike
01316bcfa2 Merge pull request #19 from open-amt-cloud-toolkit/github_actions
ci: add ci for status checks
2021-01-27 13:02:20 -07:00
Mike
c1fbf6aa39 ci: add types for conventional commits
Signed-off-by: Mike <michael.johanson@intel.com>
2021-01-24 16:36:12 -07:00
Mike
fd5817461e ci: add ci for status checks
Signed-off-by: Mike <michael.johanson@intel.com>
2021-01-19 17:00:40 -07:00
mpvats-intel
a889f91cdc Merge pull request #18 from open-amt-cloud-toolkit/feature_linux_vcpkg
Feature Linux vcpkg, CentOS support.
2021-01-15 10:54:57 -07:00
trleasher-intel
a32e109913 Updates for using Vcpkg for both Linux and Windows 2021-01-15 09:23:37 -07:00
Mike
9efc9476a4 Merge pull request #17 from rsdmike/disclaimer
docs: add release disclaimer
2021-01-14 09:20:36 -07:00
Mike
aa7d888fab docs: add release disclaimer
Signed-off-by: Mike <michael.johanson@intel.com>
2021-01-14 09:09:32 -07:00
Mudit Vats
aa68d7cfdb Use latest vcpkg release 2021-01-12 14:05:27 -07:00
Mudit Vats
434c9a1cc2 Use latest vcpkg release 2021-01-12 14:03:32 -07:00
Mudit Vats
8b4f3b00bb Update dependencies 2021-01-07 15:49:48 -07:00
Mudit Vats
53bc0c42da Fix vcpkg boostrap command. Add CentOS8 build notes. 2021-01-06 13:58:23 -07:00
Mudit Vats
dbb825c49e Build Git instead 2021-01-05 13:44:43 -07:00
Mudit Vats
385ea2b9c3 Build Git instead 2021-01-05 13:43:48 -07:00
Mudit Vats
0ecd6c9911 Use -DNO_SELECT=ON to work around select behavior on older distros 2021-01-04 14:38:40 -07:00
Mudit Vats
ca85fa4d14 Build Linux with VCPKG instead; previously explicitly cloning CPPRESTSDK and manually building. Now, VCPKG and CPPRESTSDK must be built before building RPC. See Build.md for build notes. 2020-12-18 09:11:34 -07:00
mpvats-intel
711d9ef58d Merge pull request #16 from open-amt-cloud-toolkit/fqdn
Add/update DNS Suffix (OS), Hostname (OS), fqdn [AMT] and DNS Suffix …
2020-12-18 06:49:00 -07:00
Mudit Vats
458d6ba2e2 Remove unused code 2020-12-17 15:05:39 -07:00
Mudit Vats
d2633af0c5 Add/update DNS Suffix (OS), Hostname (OS), fqdn [AMT] and DNS Suffix [AMT] info returned by --amtinfo. 2020-12-17 11:08:13 -07:00
mpvats-intel
3bfb88aeb6 Merge pull request #14 from open-amt-cloud-toolkit/link_status_fix
Fix link status not being set.
2020-12-17 10:56:43 -07:00
bwendlandt-intel
d22f00ec0b Merge pull request #15 from bwendlandt-intel/docs_link_update
update to new docs location
2020-12-07 11:34:04 -07:00
bwendlandt-intel
cd4046c741 update to new docs location 2020-12-07 10:46:22 -07:00
Mudit Vats
584a8e4f34 Set link status 2020-12-07 10:41:21 -07:00
Mike
1fc6816153 Merge pull request #13 from open-amt-cloud-toolkit/rsdmike-patch-1
Create LICENSE
2020-11-20 15:30:33 -07:00
Mike
a5788382d7 Create LICENSE 2020-11-20 15:29:37 -07:00
Mike
f5aa168acb Merge pull request #12 from open-amt-cloud-toolkit/ActivEdge
1.0 release
2020-11-20 15:13:41 -07:00
bwendlandt-intel
a2c396bae1 Add readme edits for release of doc site (#11)
* Update README for 1.0

* Fix gif link

* gif sizing and punctuation matching

Co-authored-by: bwendlandt-intel <bryan-wendlandt@intel.com>
2020-11-20 14:31:36 -07:00
Mike
bbf9ea967b Merge pull request #10 from rsdmike/github_automation
build: Add Github Actions Support
2020-11-19 09:02:39 -07:00
Mike
722a97958f build: Add Github Actions Support
Signed-off-by: Mike <michael.johanson@intel.com>
2020-11-13 14:49:10 -07:00
Mudit Vats
6d2e37e7fc Update amtinfo, usage and admin check. General code cleanup and bug fixes. 2020-10-30 09:51:18 -07:00
Mudit Vats
eb42f1e89d Update license. 2020-09-08 13:40:45 -07:00
Mudit Vats
23fe0e1663 Developer Experience Release. Added LMS and code refactor. 2020-09-01 16:04:04 -07:00
Mudit Vats
958096a375 Add CMake requirements. 2020-07-17 14:17:23 -07:00
78 changed files with 22446 additions and 1069 deletions

42
.chglog/CHANGELOG.tpl.md Normal file
View File

@@ -0,0 +1,42 @@
{{ if .Versions -}}
<a name="unreleased"></a>
## [Unreleased]
{{ if .Unreleased.CommitGroups -}}
{{ range .Unreleased.CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
{{ end }}
{{ end -}}
{{ end -}}
{{ end -}}
{{ range .Versions }}
<a name="{{ .Tag.Name }}"></a>
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }}
{{ range .CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
{{ end }}
{{ end -}}
{{- if .NoteGroups -}}
{{ range .NoteGroups -}}
### {{ .Title }}
{{ range .Notes }}
{{ .Body }}
{{ end }}
{{ end -}}
{{ end -}}
{{ end -}}
{{- if .Versions }}
[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD
{{ range .Versions -}}
{{ if .Tag.Previous -}}
[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}
{{ end -}}
{{ end -}}
{{ end -}}

28
.chglog/config.yml Normal file
View File

@@ -0,0 +1,28 @@
style: github
template: CHANGELOG.tpl.md
info:
title: CHANGELOG
repository_url: https://github.com/open-amt-cloud-toolkit/rpc
options:
commits:
# filters:
# Type:
# - feat
# - fix
# - perf
# - refactor
commit_groups:
# title_maps:
# feat: Features
# fix: Bug Fixes
# perf: Performance Improvements
# refactor: Code Refactoring
header:
pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$"
pattern_maps:
- Type
- Scope
- Subject
notes:
keywords:
- BREAKING CHANGE

14
.github/semantic.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
allowMergeCommits: true
# Always validate the PR title AND all the commits
titleAndCommits: true
types:
- feat
- fix
- docs
- style
- refactor
- perf
- test
- build
- ci
- revert

101
.github/workflows/build_all.yml vendored Normal file
View File

@@ -0,0 +1,101 @@
#*********************************************************************
# Copyright (c) Intel Corporation 2020
# SPDX-License-Identifier: Apache-2.0
#*********************************************************************/
name: Build RPC (Native) Debug/Release
on:
workflow_dispatch:
inputs:
build_type:
description: 'Build Type can be "debug" or "release".'
required: true
default: "release"
env:
BUILD_TYPE: ${{github.event.inputs.build_type}}
jobs:
build-windows:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2
- name: Create Build Dir
run: mkdir build
- name: Clone
run: git clone --branch 2020.11-1 https://github.com/microsoft/vcpkg.git
- name: Build VCPKG
run: cd vcpkg && bootstrap-vcpkg.bat
shell: cmd
- name: dir
run: ls
- name: dir
run: cd vcpkg && ls
- name: Install C++ REST SDK
run: ${{ runner.workspace }}\rpc\vcpkg\vcpkg.exe install cpprestsdk[websockets]:x64-windows-static
shell: cmd
- name: dir
run: ls && cd vcpkg && ls
shell: bash
- name: Prepare for build
run: cd build && cmake .. -DCMAKE_PREFIX_PATH=D:/a/rpc/rpc/vcpkg/installed/x64-windows-static -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_TOOLCHAIN_FILE=D:/a/rpc/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Build RPC (Debug)
if: ${{ github.event.inputs.build_type }} == "debug"
run: cd build && cmake --build . --config Debug
- name: Build RPC (Release)
if: ${{ github.event.inputs.build_type }} == "release"
run: cd build && cmake --build . --config Release
- name: GitHub Upload Release Artifacts
if: ${{ github.event.inputs.build_type }} == "release"
uses: actions/upload-artifact@v2
with:
name: RPC_Windows_release.exe
path: ${{ runner.workspace }}\rpc\build\Release\rpc.exe
- name: GitHub Upload Release Artifacts
if: ${{ github.event.inputs.build_type }} == "debug"
uses: actions/upload-artifact@v2
with:
name: RPC_Windows_debug.exe
path: ${{ runner.workspace }}\rpc\build\Debug\rpc.exe
build-linux:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, ubuntu-20.04]
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: sudo apt install git cmake build-essential curl zip unzip tar pkg-config
- name: Create Build Dir
run: mkdir build
- name: Clone
run: git clone --branch 2020.11-1 https://github.com/microsoft/vcpkg.git
- name: Build VCPKG
run: cd vcpkg && ./bootstrap-vcpkg.sh
shell: bash
- name: dir
run: ls
- name: dir
run: cd vcpkg && ls
- name: Install C++ REST SDK
run: ${{ runner.workspace }}/rpc/vcpkg/vcpkg install cpprestsdk[websockets]
shell: bash
- name: dir
run: ls && cd vcpkg && ls
shell: bash
- name: Prepare for build
if: ${{ github.event.inputs.build_type }} == "debug"
run: cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=${{ runner.workspace }}/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Prepare for build
if: ${{ github.event.inputs.build_type }} == "release"
run: cd build && cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${{ runner.workspace }}/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Build RPC
run: cd build && cmake --build .
- name: GitHub Upload Release Artifacts
uses: actions/upload-artifact@v2
with:
name: RPC_Linux_${{ matrix.os }}_${{github.event.inputs.build_type}}
path: |
build/rpc

20
.github/workflows/changelog.yml vendored Normal file
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

74
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,74 @@
#*********************************************************************
# Copyright (c) Intel Corporation 2020
# SPDX-License-Identifier: Apache-2.0
#*********************************************************************/
name: Build RPC (Native)
on:
pull_request:
branches: [ master ]
env:
BUILD_TYPE: Release
jobs:
build-windows:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2
- name: Create Build Dir
run: mkdir build
- name: Clone
run: git clone --branch 2020.11-1 https://github.com/microsoft/vcpkg.git
- name: Build VCPKG
run: cd vcpkg && bootstrap-vcpkg.bat
shell: cmd
- name: dir
run: ls
- name: dir
run: cd vcpkg && ls
- name: Install C++ REST SDK
run: ${{ runner.workspace }}\rpc\vcpkg\vcpkg.exe install cpprestsdk[websockets]:x64-windows-static
shell: cmd
- name: dir
run: ls && cd vcpkg && ls
shell: bash
- name: Prepare for build
run: cd build && cmake .. -DCMAKE_PREFIX_PATH=D:/a/rpc/rpc/vcpkg/installed/x64-windows-static -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_TOOLCHAIN_FILE=D:/a/rpc/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Build RPC (Release)
run: cd build && cmake --build . --config Release
- name: Build RPC (Debug)
run: cd build && cmake --build . --config Debug
build-linux:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, ubuntu-20.04]
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: sudo apt install git cmake build-essential curl zip unzip tar pkg-config
- name: Create Build Dir
run: mkdir build
- name: Clone
run: git clone --branch 2020.11-1 https://github.com/microsoft/vcpkg.git
- name: Build VCPKG
run: cd vcpkg && ./bootstrap-vcpkg.sh
shell: bash
- name: dir
run: ls
- name: dir
run: cd vcpkg && ls
- name: Install C++ REST SDK
run: ${{ runner.workspace }}/rpc/vcpkg/vcpkg install cpprestsdk[websockets]
shell: bash
- name: dir
run: ls && cd vcpkg && ls
shell: bash
- name: Prepare for build
run: cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=${{ runner.workspace }}/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Build RPC
run: cd build && cmake --build .

29
.github/workflows/docker-ci.yml vendored Normal file
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

4
.gitignore vendored
View File

@@ -8,4 +8,6 @@ install_manifest.txt
compile_commands.json
CTestTestfile.cmake
build/
.vscode/*
.vscode/*
.vs
*.exe

View File

@@ -1,76 +0,0 @@
/* SPDX-License-Identifier: Apache-2.0 */
/*
* Copyright (C) 2010-2019 Intel Corporation
*/
/*++
@file: GetControlModeCommand.h
--*/
#ifndef __GET_CONTROL_MODE_COMMAND_H__
#define __GET_CONTROL_MODE_COMMAND_H__
#include "AMTHICommand.h"
#include "MEIparser.h"
namespace Intel
{
namespace MEI_Client
{
namespace AMTHI_Client
{
struct GET_CONTROL_MODE_RESPONSE
{
uint32_t ControlMode;
void parse (std::vector<uint8_t>::const_iterator& itr, const std::vector<uint8_t>::const_iterator end)
{
Intel::MEI_Client::parseData(*this, itr, end);
}
};
class GetControlModeRequest;
class GetControlModeCommand : public AMTHICommand
{
public:
GetControlModeCommand();
virtual ~GetControlModeCommand() {}
virtual void reTransact();
GET_CONTROL_MODE_RESPONSE getResponse();
private:
virtual void parseResponse(const std::vector<uint8_t>& buffer);
std::shared_ptr<AMTHICommandResponse<GET_CONTROL_MODE_RESPONSE>> m_response;
static const uint32_t RESPONSE_COMMAND_NUMBER = 0x0480006B;
};
class GetControlModeRequest : public AMTHICommandRequest
{
public:
GetControlModeRequest() {}
virtual ~GetControlModeRequest() {}
private:
static const uint32_t REQUEST_COMMAND_NUMBER = 0x0400006B;
virtual unsigned int requestHeaderCommandNumber()
{
//this is the command number (taken from the AMTHI document)
return REQUEST_COMMAND_NUMBER;
}
virtual uint32_t requestDataSize()
{
return 0;
}
virtual std::vector<uint8_t> SerializeData();
};
} // namespace AMTHI_Client
} // namespace MEI_Client
} // namespace Intel
#endif //__GET_CONTROL_MODE_COMMAND_H__

View File

@@ -1,51 +0,0 @@
/* SPDX-License-Identifier: Apache-2.0 */
/*
* Copyright (C) 2010-2019 Intel Corporation
*/
/*++
@file: GetControlModeCommand.cpp
--*/
#include "GetControlModeCommand.h"
#include "StatusCodeDefinitions.h"
#include <string.h>
using namespace std;
using namespace Intel::MEI_Client::AMTHI_Client;
GetControlModeCommand::GetControlModeCommand()
{
shared_ptr<MEICommandRequest> tmp(new GetControlModeRequest());
m_request = tmp;
Transact();
}
void GetControlModeCommand::reTransact()
{
shared_ptr<MEICommandRequest> tmp(new GetControlModeRequest());
m_request = tmp;
Transact();
}
GET_CONTROL_MODE_RESPONSE GetControlModeCommand::getResponse()
{
return m_response->getResponse();
}
void
GetControlModeCommand::parseResponse(const vector<uint8_t>& buffer)
{
shared_ptr<AMTHICommandResponse<GET_CONTROL_MODE_RESPONSE>> tmp(
new AMTHICommandResponse<GET_CONTROL_MODE_RESPONSE>(buffer, RESPONSE_COMMAND_NUMBER));
m_response = tmp;
}
std::vector<uint8_t>
GetControlModeRequest::SerializeData()
{
vector<uint8_t> output;
return output;
}

101
Build.md Normal file
View File

@@ -0,0 +1,101 @@
# Remote Provisioning Client (RPC)
RPC is an application which enables remote capabilities for AMT, such as as device activation. To accomplish this, RPC communicates with the RPS (Remote Provisioning Server).
The steps below assume the following directory structure where **rpc** is the clone of this repository, **vcpkg** is a clone of the VCPKG tool source and **build** is the RPC build directory. Both vcpkg and build directories will be created in later steps.
```
\rpc
|__vcpkg
|__build
```
# Linux
Steps below are for Ubuntu 18.04 and 20.04.
## Dependencies
```
sudo apt install git cmake build-essential curl zip unzip tar pkg-config
```
## Build C++ REST SDK
Open a Terminal window.
```
git clone -b 2020.11-1 https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg install cpprestsdk[websockets]
```
## Build RPC
Open a Terminal window.
```
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
```
To build debug:
```
cmake -DCMAKE_TOOLCHAIN_FILE=/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .
```
## Run RPC
Open a Terminal window.
```
cd build
sudo ./rpc --url wss://localhost:8080 --cmd "-t activate --profile profile1"
```
Use --help for more options.
# Windows
Steps below are for Windows 10 and Visual Studio 2019 Professional.
## Build C++ REST SDK
Open an x64 Native Tools Command Prompt for Visual Studio 2019.
```
git clone -b 2020.11-1 https://github.com/microsoft/vcpkg.git
cd vcpkg
bootstrap-vcpkg.bat
vcpkg install cpprestsdk[websockets]:x64-windows-static
```
## Build RPC
Open an x64 Native Tools Command Prompt for Visual Studio 2019.
```
mkdir build
cd build
cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_TOOLCHAIN_FILE=/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake ..
cmake --build . --config Release
```
To build debug:
```
cmake --build . --config Debug
```
## Run RPC
Open a Command Prompt as Administrator.
```
cd build\Release
rpc.exe --url wss://localhost:8080 --cmd "-t activate --profile profile1"
```
Use --help for more options.

65
CHANGELOG.md Normal file
View File

@@ -0,0 +1,65 @@
<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
### Build
- **jenkins:** jenkins build scripts for Windows and Ubuntu
- add support for centos7 and 8
- Use `-DNO_SELECT=ON` to work around select behavior on older distros
- Use vcpkg for both linux and windows
### Ci
- update build
- update build
- add support for release or debug
- add types for conventional commits
- add ci for status checks
### Docs
- add release disclaimer
### Fix
- link status not reported correctly
- free fqdn buffer
### Feat
- version update
- Add `--nocertcheck`, `-n` args to skip websocket server certificate verification for all builds.
- Add/update DNS Suffix (OS), Hostname (OS), fqdn [AMT] and DNS Suffix info returned by --amtinfo.
<a name="v1.0.0"></a>
## [v1.0.0] - 2020-11-20
### Build
- Add Github Actions Support

View File

@@ -1,18 +1,14 @@
cmake_minimum_required (VERSION 3.1)
project (rpc VERSION 1.0.0)
project (rpc VERSION 1.3.0)
set (CMAKE_CXX_STANDARD 11)
# RPC version info
configure_file(version.h.in
version.h)
configure_file(version.h.in version.h)
include_directories(${PROJECT_BINARY_DIR})
# TODO: figure out how to read the LMS version from repo like the main lms CMakeLists.txt
set (LMS_VERSION_STRING 1932.0.0.0)
# Compiler settings [Obtained from CmakeLists.txt for lms]
# Common compiler settings
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -DDEBUG -D_DEBUG")
string(APPEND CMAKE_C_FLAGS_DEBUG " -DDEBUG -D_DEBUG")
@@ -27,11 +23,10 @@ if (UNIX)
#Secure library usage and secure compile flags
add_definitions (-fstack-protector-strong -D_FORTIFY_SOURCE=2 -O2 -Wformat -Wformat-security)
add_definitions (-fno-strict-overflow -fno-delete-null-pointer-checks -fwrapv)
add_definitions (-fno-strict-overflow -fno-delete-null-pointer-checks -fwrapv -fpermissive)
else (UNIX)
add_definitions (/GS /sdl)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NXCompat /DynamicBase")
#add_definitions (/D UNICODE /D _UNICODE)
add_definitions (/D UNICODE /D _UNICODE /D_NO_ASYNCRTIMP /D_ASYNCRT_EXPORT /D_NO_PPLXIMP /DWIN32 /DMBCS /D_USRDLL /DCPPREST_EXCLUDE_COMPRESSION /D_WINSOCK_DEPRECATED_NO_WARNINGS)
add_compile_options ($<$<CONFIG:Release>:/O2>)
add_compile_options (/MT$<$<CONFIG:Debug>:d>)
@@ -39,93 +34,112 @@ else (UNIX)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
endif (UNIX)
# Download and unpack lms at configure time
configure_file(lms.cmake.in
lms-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/lms-download )
execute_process(COMMAND ${CMAKE_COMMAND} --build .
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/lms-download )
# Add MEIClient directly to our build. This adds
# the following targets: LmsMEIClient and LIBMETEE
add_subdirectory(${CMAKE_BINARY_DIR}/lms-src/MEIClient
${CMAKE_BINARY_DIR}/lms-build/MEIClient)
add_dependencies(LmsMEIClient libmetee)
if (UNIX)
# Find threads [unix it pthreads]
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
# Find Boost
find_package(Boost COMPONENTS system REQUIRED)
# Find OpenSSL
find_package(OpenSSL)
# Download and build CppRestSDK, If GIT_TAG is changed then need to delete cpprestsdk-prefix because UPDATE_COMMAND is set to ""
include(ExternalProject)
ExternalProject_Add(cpprestsdk
GIT_REPOSITORY https://github.com/Microsoft/cpprestsdk.git
GIT_TAG v2.10.14
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=0 -DBUILD_SAMPLES=OFF -DBUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=<SOURCE_DIR>/../../install
TEST_COMMAND ""
UPDATE_COMMAND ""
)
ExternalProject_Get_Property(cpprestsdk SOURCE_DIR)
set(CPPRESTSDK_LIBARIES ${SOURCE_DIR}/../../install/lib/)
set(CPPRESTSDK_INCLUDE_DIR ${SOURCE_DIR}/../../install/include/)
add_library(cpprest INTERFACE)
target_link_libraries(cpprest INTERFACE ${CPPRESTSDK_LIBARIES}/libcpprest.a OpenSSL::SSL OpenSSL::Crypto ${Boost_LIBRARIES} Threads::Threads)
target_include_directories(cpprest INTERFACE ${CPPRESTSDK_INCLUDE_DIR})
else (UNIX)
# Add MicroLMS directly to our build. This adds
# the following targets: MicroLMS
add_subdirectory(MicroLMS)
# CppRestSDK
find_package(cpprestsdk CONFIG REQUIRED)
endif (UNIX)
# GoogleTest
# Download and unpack googletest at configure time
configure_file(googletest.cmake.in googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
# Prevent overriding the parent project's compiler/linker
# settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL)
# add the test executable
add_executable(rpctest
test.cpp
utils.cpp
)
target_link_libraries(rpctest
gtest_main
cpprestsdk::cpprest
cpprestsdk::cpprestsdk_zlib_internal
cpprestsdk::cpprestsdk_boost_internal
cpprestsdk::cpprestsdk_openssl_internal
)
# ccu-poc
add_executable (rpc
AMTHIClient/Include/GetControlModeCommand.h
AMTHIClient/Src/GetControlModeCommand.cpp
info.h
info.cpp
args.h
args.cpp
usage.h
usage.cpp
port.h
utils.h
utils.cpp
network.h
network.cpp
commands.h
commands.cpp
activation.h
activation.cpp
heartbeat.h
heartbeat.cpp
lms.h
lms.cpp
main.cpp
)
target_include_directories(rpc PUBLIC
"AMTHIClient/Include/"
"MicroLMS/heci"
)
add_dependencies(rpc MicroLMS)
if (UNIX)
add_dependencies(rpc cpprestsdk)
target_link_libraries (rpc PRIVATE
LmsMEIClient
cpprest
MicroLMS
cpprestsdk::cpprest
cpprestsdk::cpprestsdk_zlib_internal
cpprestsdk::cpprestsdk_boost_internal
cpprestsdk::cpprestsdk_openssl_internal
)
else (UNIX)
target_link_libraries (rpc PRIVATE
LmsMEIClient
iphlpapi
MicroLMS
cpprestsdk::cpprest
cpprestsdk::cpprestsdk_zlib_internal
cpprestsdk::cpprestsdk_boost_internal
cpprestsdk::cpprestsdk_brotli_internal
${Boost_LIBRARIES}
DbgHelp.lib
Iphlpapi.lib
Setupapi.lib
ws2_32.lib
Psapi.lib
Crypt32.lib
Wintrust.lib
Version.lib
Wtsapi32.lib
Gdiplus.lib
Userenv.lib
)
endif (UNIX)

85
CentOS7.md Normal file
View File

@@ -0,0 +1,85 @@
# Remote Provisioning Client (RPC)
RPC is an application which enables remote capabilities for AMT, such as as device activation. To accomplish this, RPC communicates with the RPS (Remote Provisioning Server).
The steps below assume the following directory structure where **rpc** is the clone of this repository, **vcpkg** is a clone of the VCPKG tool source and **build** is the RPC build directory. Both vcpkg and build directories will be created in later steps.
```
\rpc
|__vcpkg
|__build
```
# Linux
Steps below are for CentOS7.
**The "export PATH=..." (for CMake and Git), and "scl enable devtoolset-7 bash" (for GCC) must be executed in in the Terminal you are building from; i.e. these are temporary changes which only affect the current Terminal session.**
## Dependencies
### CMake
Download cmake-3.10.2-Linux-x86_64.sh from https://github.com/Kitware/CMake/releases/tag/v3.10.2.
```
./cmake-3.10.2-Linux-x86_64.sh
export PATH=/home/user/Downloads/cmake-3.10.2-Linux-x86_64/bin:$PATH
```
### GCC
Update GCC toolchain.
```
sudo yum install centos-release-scl
sudo yum install devtoolset-7
scl enable devtoolset-7 bash
```
### Git
Build Git source control system.
```
sudo yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-CPAN perl-devel
git clone https://github.com/git/git.git
make configure
make
export PATH=/home/user/Downloads/git:$PATH
```
## Build C++ REST SDK
Using a Terminal window with the PATH and devtoolset enabled per the Dependencies.
```
git clone -b 2020.11-1 https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg install cpprestsdk[websockets]
```
## Build RPC
Using a Terminal window with the PATH and devtoolset enabled per the Dependencies.
```
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DNO_SELECT=ON ..
cmake --build .
```
To build debug:
```
cmake -DCMAKE_TOOLCHAIN_FILE=/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Debug -DNO_SELECT=ON ..
cmake --build .
```
## Run RPC
Open a Terminal window.
```
cd build
sudo ./rpc --url wss://localhost:8080 --cmd "-t activate --profile profile1"
```
Use --help for more options.

63
CentOS8.md Normal file
View File

@@ -0,0 +1,63 @@
# Remote Provisioning Client (RPC)
RPC is an application which enables remote capabilities for AMT, such as as device activation. To accomplish this, RPC communicates with the RPS (Remote Provisioning Server).
The steps below assume the following directory structure where **rpc** is the clone of this repository, **vcpkg** is a clone of the VCPKG tool source and **build** is the RPC build directory. Both vcpkg and build directories will be created in later steps.
```
\rpc
|__vcpkg
|__build
```
# Linux
Steps below are for CentOS8.
## Dependencies
### CMake
Install CMake.
```
sudo yum install cmake
```
## Build C++ REST SDK
Using a Terminal window with the PATH and devtoolset enabled per the Dependencies.
```
git clone -b 2020.11-1 https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg install cpprestsdk[websockets]
```
## Build RPC
Using a Terminal window with the PATH and devtoolset enabled per the Dependencies.
```
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
```
To build debug:
```
cmake -DCMAKE_TOOLCHAIN_FILE=/rpc/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .
```
## Run RPC
Open a Terminal window.
```
cd build
sudo ./rpc --url wss://localhost:8080 --cmd "-t activate --profile profile1"
```
Use --help for more options.

37
Dockerfile Normal file
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"]

154
Jenkinsfile vendored Normal file
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()
}
}
}
}

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2019 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

191
MicroLMS/CMakeLists.txt Normal file
View File

@@ -0,0 +1,191 @@
cmake_minimum_required (VERSION 3.4)
###########################################################
# Set project options
#
# set the project name
project(MicroLMS)
set (CMAKE_CXX_STANDARD 11)
set (CMAKE_POSITION_INDEPENDENT_CODE ON)
# set to ON to build library, OFF to build executable
set (BUILD_LIBRARY ON)
include_directories(
${PROJECT_BINARY_DIR}
MicroLMS
core
heci)
###########################################################
# Compiler / linker options
#
if (UNIX)
#
# Linux Compiler and Linker Options
# Find threads [unix it pthreads]
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
if (${BUILD_LIBRARY})
add_definitions(-D BUILD_LIBRARY)
endif (${BUILD_LIBRARY})
if (${NO_SELECT})
add_definitions(-D NO_SELECT)
endif (${NO_SELECT})
add_definitions( -D_POSIX )
else (UNIX)
# Windows Compiler and Linker Options
if (${BUILD_LIBRARY})
add_definitions(/D BUILD_LIBRARY)
endif (${BUILD_LIBRARY})
add_definitions (/GS /GL /W3 /Gy /Zc:wchar_t /Zi /Zc:inline /fp:precise /WX- /Zc:forScope /Gd /Oi /FC /EHsc /nologo )
add_definitions (/D WIN32 /D WIN64 /D NDEBUG /D _CONSOLE /D MICROSTACK_NO_STDAFX /D WINSOCK2 /D MICROSTACK_NOTLS /D _UNICODE /D UNICODE)
add_definitions (/errorReport:prompt /diagnostics:column)
add_compile_options ($<$<CONFIG:Release>:/O1>)
add_compile_options (/MT$<$<CONFIG:Debug>:d>)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /Gm-")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd /Gm /Od /D _DEBUG /D MEMORY_CHECK /D __STDC__ /D _CRT_SECURE_NO_WARNINGS /D ILibWebServer_SESSION_TRACKING /Gd /MDd")
set (CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS}
/MANIFEST
/LTCG:incremental
/NXCOMPAT
/DynamicBase
/MACHINE:X64
/OPT:REF
/INCREMENTAL:NO
/SUBSYSTEM:CONSOLE
/MANIFESTUAC:\"level='asInvoker' uiAccess='false'\"
/OPT:ICF
/ERRORREPORT:PROMPT
/NOLOGO
/TLBID:1"
)
endif (UNIX)
###########################################################
# Create the binary
#
if (UNIX)
#
# Linux Library and Executable Build
#
if (BUILD_LIBRARY)
# Create a library
add_library (
MicroLMS
STATIC
MicroLMS/main.c
core/utils.c
heci/HECILinux.c
heci/LMEConnection.c
heci/PTHICommand.c
microstack/ILibAsyncServerSocket.c
microstack/ILibAsyncSocket.c
microstack/ILibLMS.c
microstack/ILibParsers.c
)
target_link_libraries (
MicroLMS )
else (BUILD_LIBRARY)
# Create an executable
add_executable (
MicroLMS
MicroLMS/main.c
core/utils.c
heci/HECILinux.c
heci/LMEConnection.c
heci/PTHICommand.c
microstack/ILibAsyncServerSocket.c
microstack/ILibAsyncSocket.c
microstack/ILibLMS.c
microstack/ILibParsers.c
)
target_link_libraries (
MicroLMS
PRIVATE
pthread
)
endif (BUILD_LIBRARY)
else (UNIX)
#
# Windows Library and Executable Build
#
if (BUILD_LIBRARY)
# Create a library
add_library (
MicroLMS
STATIC
MicroLMS/main.c
MicroLMS/stdafx.cpp
core/utils.c
heci/HECIWin.c
heci/LMEConnection.c
heci/PTHICommand.c
microstack/ILibAsyncServerSocket.c
microstack/ILibAsyncSocket.c
microstack/ILibLMS.c
microstack/ILibParsers.c
)
target_link_libraries (
MicroLMS )
else (BUILD_LIBRARY)
# Create an executable
add_executable (
MicroLMS
MicroLMS/main.c
MicroLMS/stdafx.cpp
core/utils.c
heci/HECIWin.c
heci/LMEConnection.c
heci/PTHICommand.c
microstack/ILibAsyncServerSocket.c
microstack/ILibAsyncSocket.c
microstack/ILibLMS.c
microstack/ILibParsers.c
)
target_link_libraries (
MicroLMS
PRIVATE
DbgHelp.lib
Iphlpapi.lib
Setupapi.lib
ws2_32.lib
Psapi.lib
Crypt32.lib
Wintrust.lib
Version.lib
Wtsapi32.lib
Gdiplus.lib
Userenv.lib
)
endif (BUILD_LIBRARY)
endif (UNIX)

137
MicroLMS/MicroLMS/main.c Normal file
View File

@@ -0,0 +1,137 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2006 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#if defined(WIN32) || defined (_WIN32_WCE)
#ifndef MICROSTACK_NO_STDAFX
#include "stdafx.h"
#endif
#else
#define UNREFERENCED_PARAMETER(P) (P)
#endif
#if defined(WIN32)
#define _CRTDBG_MAP_ALLOC
#ifdef _DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif
#endif
#if defined(WINSOCK2)
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(WINSOCK1)
#include <winsock.h>
#include <wininet.h>
#endif
#include <signal.h>
#include "../microstack/ILibParsers.h"
#include "../microstack/ILibLMS.h"
#if defined(WIN32) & !defined(_CONSOLE)
#include "resource.h"
#endif
#if defined(WIN32) && defined (_DEBUG)
#include <crtdbg.h>
#endif
// The following macros set and clear, respectively, given bits
// of the C runtime library debug flag, as specified by a bitmask.
#ifdef _DEBUG
#define SET_CRT_DEBUG_FIELD(a) \
_CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
#define CLEAR_CRT_DEBUG_FIELD(a) \
_CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
#else
#define SET_CRT_DEBUG_FIELD(a) ((void) 0)
#define CLEAR_CRT_DEBUG_FIELD(a) ((void) 0)
#endif
#ifdef MEMORY_CHECK
#ifdef WIN32
// This routine place comments at the head of a section of debug output
void OutputHeading( const char * explanation )
{
_RPT1( _CRT_WARN, "\n\n%s:\n**************************************************************************\n", explanation );
}
#endif
#endif
void *Chain = NULL;
struct ILibLMS_StateModule *MicroLMS = NULL;
extern void ctrl_SendSubscriptionEvent(char *data, int datalen);
void BreakSink(int s)
{
UNREFERENCED_PARAMETER( s );
signal(SIGINT, SIG_IGN); // To ignore any more ctrl-c interrupts
ILibStopChain(Chain);
}
#if defined(_POSIX) || defined (_CONSOLE)
#if defined (BUILD_LIBRARY)
int main_micro_lms()
#else
int main(int argc, char **argv)
#endif
#else
DWORD WINAPI GPMain(LPVOID lpParameter)
#endif
{
// Shutdown on Ctrl + C
signal(SIGINT, BreakSink);
#ifdef _POSIX
signal(SIGPIPE, SIG_IGN);
#ifdef _DEBUG
//mtrace();
#endif
#endif
#ifdef MEMORY_CHECK
#ifdef WIN32
//SET_CRT_DEBUG_FIELD( _CRTDBG_DELAY_FREE_MEM_DF );
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF);
#endif
#endif
Chain = ILibCreateChain();
MicroLMS = ILibLMS_Create(Chain);
if (MicroLMS != NULL)
{
printf("Starting MicroLMS.\r\n");
ILibStartChain(Chain);
printf("Stopping MicroLMS.\r\n");
}
else
{
printf("Unable to launch MicroLMS. Check that Intel ME is present, MEI driver installed and run this executable as administrator.\r\n");
}
#ifdef MEMORY_CHECK
#ifdef WIN32
OutputHeading("Generating the final memory leak report\r\n");
_CrtCheckMemory();
_CrtDumpMemoryLeaks();
#endif
#endif
#ifdef _POSIX
#ifdef _DEBUG
//muntrace();
#endif
#endif
#ifdef _POSIX
exit(EXIT_SUCCESS);
#else
return 0;
#endif
}

View File

@@ -0,0 +1,15 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by MeshMessenger.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// TinyMesh.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@@ -0,0 +1,15 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here

View File

@@ -0,0 +1,13 @@
#pragma once
// The following macros define the minimum required platform. The minimum required platform
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
// your application. The macros work by enabling all features available on platform versions up to and
// including the version specified.
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
#endif

88
MicroLMS/core/utils.c Normal file
View File

@@ -0,0 +1,88 @@
/*
Copyright 2011 - 2020 Intel Corporation.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#if defined(WIN32) && !defined(_MINCORE)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#if defined(WINSOCK2)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <shlobj.h>
#elif defined(WINSOCK1)
#include <winsock.h>
#include <wininet.h>
#include <windows.h>
#include <shlobj.h>
#endif
#include "utils.h"
#if defined(_MESHAGENT)
#include "meshcore.h"
#include "meshinfo.h"
#else
#define PB_SESSIONKEY 9
#define PB_AESCRYPTO 8
#endif
#include <stdio.h>
#include <string.h>
char* __fastcall util_tohex_lower(char* data, int len, char* out)
{
char utils_HexTable2[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
int i;
char *p = out;
if (data == NULL || len == 0) { *p = 0; return NULL; }
for (i = 0; i < len; i++)
{
*(p++) = utils_HexTable2[((unsigned char)data[i]) >> 4];
*(p++) = utils_HexTable2[((unsigned char)data[i]) & 0x0F];
}
*p = 0;
return out;
}
#ifdef WIN32
BOOL GetWindowsDllPath(const char* dllName, wchar_t* out)
{
char buf[MAX_PATH];
#if _WIN64
if (SHGetSpecialFolderPathA(NULL, buf, CSIDL_SYSTEM, FALSE) == FALSE) return FALSE;
#else
if (SHGetSpecialFolderPathA(NULL, buf, CSIDL_SYSTEMX86, FALSE) == FALSE) return FALSE;
#endif
if(strcat_s(buf, MAX_PATH, dllName)!= 0) return FALSE;
int str_len = MultiByteToWideChar(CP_UTF8, 0, buf, -1, out, 0);
if(MultiByteToWideChar(CP_UTF8, 0, buf, -1, out, MAX_PATH) == 0) return FALSE;
return TRUE;
}
#endif
// These are all missing MINCORE function that are re-implemented here.
#ifdef WIN32
BOOL util_MoveFile(_In_ LPCSTR lpExistingFileName, _In_ LPCSTR lpNewFileName) { return MoveFileA(lpExistingFileName, lpNewFileName); }
BOOL util_CopyFile(_In_ LPCSTR lpExistingFileName, _In_ LPCSTR lpNewFileName, _In_ BOOL bFailIfExists) { return CopyFileA(lpExistingFileName, lpNewFileName, bFailIfExists); }
#endif

53
MicroLMS/core/utils.h Normal file
View File

@@ -0,0 +1,53 @@
/*
Copyright 2011 - 2020 Intel Corporation.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#if !defined(__MeshUtils__)
#define __MeshUtils__
#include "../microstack/ILibParsers.h"
#if !defined(WIN32)
#define __fastcall
#endif
// Debugging features
#if defined(_DEBUG)
// Display & log
//char spareDebugMemory[4000];
//int spareDebugLen;
//#define MSG(x) printf("%s",x);//mdb_addevent(x, (int)strlen(x));
//#define MSG(...) spareDebugLen = snprintf(spareDebugMemory, 4000, __VA_ARGS__);printf("%s",spareDebugMemory);//mdb_addevent(spareDebugMemory, spareDebugLen);
// Display only
#define MSG(...) printf(__VA_ARGS__); fflush(NULL)
#define DEBUGSTATEMENT(x) x
#else
#ifndef MSG
#define MSG(...)
#endif
#define DEBUGSTATEMENT(x)
#endif
char* __fastcall util_tohex_lower(char* data, int len, char* out);
#ifdef WIN32
int __fastcall util_crc(unsigned char *buffer, int len, int initial_value);
BOOL util_MoveFile(_In_ LPCSTR lpExistingFileName, _In_ LPCSTR lpNewFileName);
BOOL util_CopyFile(_In_ LPCSTR lpExistingFileName, _In_ LPCSTR lpNewFileName, _In_ BOOL bFailIfExists);
BOOL GetWindowsDllPath(const char* dllName, wchar_t* out);
#endif
#endif

379
MicroLMS/heci/HECILinux.c Normal file
View File

@@ -0,0 +1,379 @@
/*********************************************************************
* Intel Management Engine Interface (Intel MEI) Linux driver
* Intel MEI Interface Header
*
* Copyright (c) Intel Corporation 2003 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#include <stdbool.h>
#include "HECILinux.h"
#include "../core/utils.h"
/*****************************************************************************
* Intel Management Engine Interface
*****************************************************************************/
#ifdef _HECIDEBUG
#define mei_msg(_me, fmt, ARGS...) do { printf(fmt, ##ARGS); } while (0)
#define mei_err(_me, fmt, ARGS...) do { printf(fmt, ##ARGS); } while (0)
#else
#define mei_msg(_me, fmt, ARGS...)
#define mei_err(_me, fmt, ARGS...)
#endif
static void mei_deinit(struct mei *cl)
{
// mei_err(cl, "mei_deinit()\n");
if (cl->initialized == false) return;
cl->initialized = false;
if (cl->fd != -1) close(cl->fd);
cl->fd = -1;
cl->buf_size = 0;
cl->prot_ver = 0;
sem_destroy(&(cl->Lock));
}
static bool mei_init(struct mei *me, const uuid_le *guid, unsigned char req_protocol_version, bool verbose)
{
int result;
struct mei_client *cl;
struct mei_connect_client_data data;
mei_deinit(me);
me->verbose = verbose;
// open me
me->fd = open("/dev/mei0", O_RDWR);
if (me->fd == -1) {
// mei_err(me, "Cannot establish a handle to the Intel MEI driver\n");
goto err;
}
memcpy(&me->guid, guid, sizeof(*guid));
memset(&data, 0, sizeof(data));
me->initialized = true;
memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid));
result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data);
if (result) {
mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d,%d\n", result, errno);
goto err;
}
cl = &data.out_client_properties;
//mei_msg(me, "max_message_length %d\n", cl->max_msg_length);
//mei_msg(me, "protocol_version %d\n", cl->protocol_version);
if ((req_protocol_version > 0) && (cl->protocol_version != req_protocol_version)) {
mei_err(me, "Intel MEI protocol version not supported\n");
goto err;
}
me->buf_size = cl->max_msg_length;
me->prot_ver = cl->protocol_version;
sem_init(&(me->Lock), 0, 1);
mei_msg(me, "mei init succ");
return true;
err:
mei_deinit(me);
return false;
}
static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer, ssize_t len, unsigned long timeout)
{
ssize_t rc;
mei_msg(me, "call read length = %zd\n", len);
rc = read(me->fd, buffer, len);
if (rc < 0) {
mei_err(me, "read failed with status %zd %s\n", rc, strerror(errno));
mei_deinit(me);
} else {
mei_msg(me, "read succeeded with result %zd\n", rc);
}
return rc;
}
static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer, ssize_t len, unsigned long timeout)
{
#ifndef NO_SELECT
struct timeval tv;
#endif
ssize_t written;
ssize_t rc;
fd_set set;
#ifndef NO_SELECT
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000000;
#endif
mei_msg(me, "call write length = %zd, cmd=%d\n", len, (int)buffer[0]);
sem_wait(&(me->Lock));
written = write(me->fd, buffer, len);
if (written < 0) {
rc = -errno;
mei_err(me, "write failed with status %zd %s\n", written, strerror(errno));
goto out;
}
#ifndef NO_SELECT
FD_ZERO(&set);
FD_SET(me->fd, &set);
rc = select(me->fd + 1 , NULL, &set, NULL, &tv);
if (rc > 0 && FD_ISSET(me->fd, &set)) {
mei_msg(me, "write success\n");
} else if (rc == 0) {
mei_err(me, "write failed on timeout with status 0, timeout = %ld, written=%ld, cmd=%d\n", timeout, written, (int)buffer[0]);
goto out;
} else { // rc < 0
mei_err(me, "write failed on select with status %zd\n", rc);
goto out;
}
#endif
rc = written;
out:
sem_post(&(me->Lock));
mei_msg(me, "call write written = %zd\n", written);
if (rc < 0) mei_deinit(me);
return rc;
}
/***************************************************************************
* Intel Advanced Management Technology Host Interface
***************************************************************************/
struct amt_host_if_msg_header {
struct amt_version version;
uint16_t _reserved;
uint32_t command;
uint32_t length;
} __attribute__((packed));
struct amt_host_if_resp_header {
struct amt_host_if_msg_header header;
uint32_t status;
unsigned char data[0];
} __attribute__((packed));
const uuid_le MEI_IAMTHIF = {.b={0x28, 0x00, 0xf8, 0x12, 0xb7, 0xb4, 0x2d, 0x4b, 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c}};
const uuid_le MEI_LMEIF = {.b={0xdb, 0xa4, 0x33, 0x67, 0x76, 0x04, 0x7b, 0x4e, 0xb3, 0xaf, 0xbc, 0xfc, 0x29, 0xbe, 0xe7, 0xa7}};
#define AMT_HOST_IF_CODE_VERSIONS_REQUEST 0x0400001A
#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A
const struct amt_host_if_msg_header CODE_VERSION_REQ = {
.version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION},
._reserved = 0,
.command = AMT_HOST_IF_CODE_VERSIONS_REQUEST,
.length = 0
};
static bool amt_host_if_init(struct amt_host_if *acmd, unsigned long send_timeout, bool verbose, int client)
{
acmd->send_timeout = (send_timeout) ? send_timeout : 20000;
if (client == 0) { acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose); }
else if (client == 1) { acmd->initialized = mei_init(&acmd->mei_cl, &MEI_LMEIF, 0, verbose); }
return acmd->initialized;
}
static void amt_host_if_deinit(struct amt_host_if *acmd)
{
mei_deinit(&acmd->mei_cl);
acmd->initialized = false;
}
static uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp)
{
uint32_t status = AMT_STATUS_SUCCESS;
struct amt_code_versions *code_ver;
size_t code_ver_len;
uint32_t ver_type_cnt;
uint32_t len;
uint32_t i;
code_ver = (struct amt_code_versions *)resp->data;
/* length - sizeof(status) */
code_ver_len = resp->header.length - sizeof(uint32_t);
ver_type_cnt = code_ver_len -
sizeof(code_ver->bios) -
sizeof(code_ver->count);
if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) {
status = AMT_STATUS_INTERNAL_ERROR;
goto out;
}
for (i = 0; i < code_ver->count; i++) {
len = code_ver->versions[i].description.length;
if (len > AMT_UNICODE_STRING_LEN) {
status = AMT_STATUS_INTERNAL_ERROR;
goto out;
}
len = code_ver->versions[i].version.length;
if (code_ver->versions[i].version.string[len] != '\0' ||
len != strlen(code_ver->versions[i].version.string)) {
status = AMT_STATUS_INTERNAL_ERROR;
goto out;
}
}
out:
return status;
}
static uint32_t amt_verify_response_header(uint32_t command, const struct amt_host_if_msg_header *resp_hdr, uint32_t response_size)
{
if (response_size < sizeof(struct amt_host_if_resp_header)) {
return AMT_STATUS_INTERNAL_ERROR;
} else if (response_size != (resp_hdr->length +
sizeof(struct amt_host_if_msg_header))) {
return AMT_STATUS_INTERNAL_ERROR;
} else if (resp_hdr->command != command) {
return AMT_STATUS_INTERNAL_ERROR;
} else if (resp_hdr->_reserved != 0) {
return AMT_STATUS_INTERNAL_ERROR;
} else if (resp_hdr->version.major != AMT_MAJOR_VERSION ||
resp_hdr->version.minor < AMT_MINOR_VERSION) {
return AMT_STATUS_INTERNAL_ERROR;
}
return AMT_STATUS_SUCCESS;
}
static uint32_t amt_host_if_call(struct amt_host_if *acmd, const unsigned char *command, ssize_t command_sz, uint8_t **read_buf, uint32_t rcmd, unsigned int expected_sz)
{
uint32_t in_buf_sz;
uint32_t out_buf_sz;
ssize_t written;
uint32_t status;
struct amt_host_if_resp_header *msg_hdr;
in_buf_sz = acmd->mei_cl.buf_size;
*read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz);
if (*read_buf == NULL) return AMT_STATUS_SDK_RESOURCES;
memset(*read_buf, 0, in_buf_sz);
msg_hdr = (struct amt_host_if_resp_header *)*read_buf;
written = mei_send_msg(&acmd->mei_cl, command, command_sz, acmd->send_timeout);
if (written != command_sz)
return AMT_STATUS_INTERNAL_ERROR;
out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000);
if (out_buf_sz <= 0)
return AMT_STATUS_HOST_IF_EMPTY_RESPONSE;
status = msg_hdr->status;
if (status != AMT_STATUS_SUCCESS)
return status;
status = amt_verify_response_header(rcmd, &msg_hdr->header, out_buf_sz);
if (status != AMT_STATUS_SUCCESS)
return status;
if (expected_sz && expected_sz != out_buf_sz)
return AMT_STATUS_INTERNAL_ERROR;
return AMT_STATUS_SUCCESS;
}
static uint32_t amt_get_code_versions(struct amt_host_if *cmd, struct amt_code_versions *versions)
{
struct amt_host_if_resp_header *response = NULL;
uint32_t status;
status = amt_host_if_call(cmd,
(const unsigned char *)&CODE_VERSION_REQ,
sizeof(CODE_VERSION_REQ),
(uint8_t **)&response,
AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0);
if (status != AMT_STATUS_SUCCESS)
goto out;
status = amt_verify_code_versions(response);
if (status != AMT_STATUS_SUCCESS)
goto out;
memcpy(versions, response->data, sizeof(struct amt_code_versions));
out:
if (response != NULL)
free(response);
return status;
}
/************************** end of amt_host_if_command ***********************/
int MEI_globalSetup = 0;
struct MEImodule MEI_global;
bool heci_Init(struct MEImodule* module, int client)
{
if (module == NULL && client != 0) return false;
if (module == NULL) { module = &MEI_global; if (MEI_globalSetup == 1) return true; }
memset(module, 0 , sizeof(struct MEImodule));
if (!amt_host_if_init(&(module->acmd), 5000, module->verbose, client)) return false;
if (module == &MEI_global) MEI_globalSetup = 1;
module->inited = true;
if (client == 0) module->status = amt_get_code_versions(&(module->acmd), &(module->ver));
return true;
}
void heci_Deinit(struct MEImodule* module)
{
if (module == NULL) { module = &MEI_global; MEI_globalSetup = 0; }
amt_host_if_deinit(&(module->acmd));
memset(module, 0, sizeof(struct MEImodule));
}
int heci_ReceiveMessage(struct MEImodule* module, unsigned char *buffer, int len, unsigned long timeout) // Timeout default is 2000
{
if (module == NULL) module = &MEI_global;
return mei_recv_msg(&(module->acmd.mei_cl), buffer, len, timeout);
}
int heci_SendMessage(struct MEImodule* module, const unsigned char *buffer, int len, unsigned long timeout) // Timeout default is 2000
{
if (module == NULL) module = &MEI_global;
return mei_send_msg(&(module->acmd.mei_cl), buffer, len, timeout);
}
unsigned int heci_GetBufferSize(struct MEImodule* module)
{
if (module == NULL) module = &MEI_global;
if (module->inited) return module->acmd.mei_cl.buf_size;
return -1;
}
unsigned char heci_GetProtocolVersion(struct MEImodule* module)
{
if (module == NULL) module = &MEI_global;
if (module->inited) return module->acmd.mei_cl.prot_ver;
return 0;
}
// Get the version of MEI from the last MEI init.
bool heci_GetHeciVersion(struct MEImodule* module, HECI_VERSION *version)
{
version->major = AMT_MAJOR_VERSION;
version->minor = AMT_MINOR_VERSION;
return true;
}
bool heci_IsInitialized(struct MEImodule* module)
{
return module->inited;
}

103
MicroLMS/heci/HECILinux.h Normal file
View File

@@ -0,0 +1,103 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2004 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __HECI_LINUX_H__
#define __HECI_LINUX_H__
#include "HECI_if.h"
#include "mei.h"
#include <semaphore.h>
#include <stdint.h>
#ifndef bool
#define bool int
#endif
/***************************************************************************
* Intel Advanced Management Technology ME Client
***************************************************************************/
#define AMT_MAJOR_VERSION 1
#define AMT_MINOR_VERSION 1
#define AMT_STATUS_SUCCESS 0x0
#define AMT_STATUS_INTERNAL_ERROR 0x1
#define AMT_STATUS_NOT_READY 0x2
#define AMT_STATUS_INVALID_AMT_MODE 0x3
#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4
#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE 0x4000
#define AMT_STATUS_SDK_RESOURCES 0x1004
#define AMT_BIOS_VERSION_LEN 65
#define AMT_VERSIONS_NUMBER 50
#define AMT_UNICODE_STRING_LEN 20
typedef enum
{
PTHI_CLIENT,
LMS_CLIENT,
MKHI_CLIENT
} HECI_CLIENTS;
struct amt_unicode_string {
uint16_t length;
char string[AMT_UNICODE_STRING_LEN];
} __attribute__((packed));
struct amt_version_type {
struct amt_unicode_string description;
struct amt_unicode_string version;
} __attribute__((packed));
struct amt_version {
uint8_t major;
uint8_t minor;
} __attribute__((packed));
struct amt_code_versions {
uint8_t bios[AMT_BIOS_VERSION_LEN];
uint32_t count;
struct amt_version_type versions[AMT_VERSIONS_NUMBER];
} __attribute__((packed));
struct mei {
uuid_le guid;
bool initialized;
bool verbose;
unsigned int buf_size;
unsigned char prot_ver;
int fd;
sem_t Lock;
};
struct amt_host_if {
struct mei mei_cl;
unsigned long send_timeout;
bool initialized;
};
struct MEImodule
{
struct amt_code_versions ver;
struct amt_host_if acmd;
unsigned int i;
unsigned int status;
bool verbose;
bool inited;
};
bool heci_Init(struct MEImodule* module, int client);
void heci_Deinit(struct MEImodule* module);
int heci_ReceiveMessage(struct MEImodule* module, unsigned char *buffer, int len, unsigned long timeout); // Timeout default is 2000
int heci_SendMessage(struct MEImodule* module, const unsigned char *buffer, int len, unsigned long timeout); // Timeout default is 2000
unsigned int heci_GetBufferSize(struct MEImodule* module);
unsigned char heci_GetProtocolVersion(struct MEImodule* module);
bool heci_GetHeciVersion(struct MEImodule* module, HECI_VERSION *version);
bool heci_IsInitialized(struct MEImodule* module);
#endif // __HECI_LINUX_H__

376
MicroLMS/heci/HECIWin.c Normal file
View File

@@ -0,0 +1,376 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef _MINCORE
#include <windows.h>
#include <setupapi.h>
#include <initguid.h>
#include <winioctl.h>
#include "HECIWin.h"
#include "heci_if.h"
#define false 0
#define true 1
#define HECI_MAX_LINE_LEN 300
DEFINE_GUID(GUID_DEVINTERFACE_HECI, 0xE2D1FF34, 0x3458, 0x49A9, 0x88, 0xDA, 0x8E, 0x69, 0x15, 0xCE, 0x9B, 0xE5);
DEFINE_GUID(HECI_PTHI_GUID , 0x12F80028, 0xB4B7, 0x4b2d, 0xAC, 0xA8, 0x46, 0xE0, 0xFF, 0x65, 0x81, 0x4c);
DEFINE_GUID(LMS_GUID , 0x6733a4db, 0x0476, 0x4e7b, 0xb3, 0xaf, 0xbc, 0xfc, 0x29, 0xbe, 0xe7, 0xa7);
DEFINE_GUID(MKHI_GUID , 0x8E6A6715, 0x9ABC, 0x4043, 0x88, 0xEF, 0x9E, 0x39, 0xC6, 0xF6, 0x3E, 0x0F);
//VOID _displayHECIError(UINT32 errorCode,DWORD lastError);
//VOID _displayHECIData(UINT32 messageId);
int heci_doIoctl(struct MEImodule* module, DWORD code, void *inbuf, int inlen, void *outbuf, int outlen);
struct MEImodule MEI_global;
/***************************** public functions *****************************/
unsigned int heci_GetBufferSize(struct MEImodule* module) { if (module != NULL) return module->_bufSize; else return MEI_global._bufSize; }
unsigned char heci_GetProtocolVersion(struct MEImodule* module) { if (module != NULL) return module->_protocolVersion; else return MEI_global._protocolVersion; }
bool heci_IsInitialized(struct MEImodule* module) { if (module != NULL) return module->_initialized; else return MEI_global._initialized; }
bool heci_GetHeciVersion(struct MEImodule* module, HECI_VERSION *version)
{
if (module == NULL) module = &MEI_global;
if (module->m_haveHeciVersion)
{
memcpy_s(version, sizeof(HECI_VERSION), &(module->m_heciVersion), sizeof(HECI_VERSION));
return true;
}
return false;
}
bool heci_Init(struct MEImodule* module, HECI_CLIENTS client)
{
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetail = NULL;
HDEVINFO hDeviceInfo;
DWORD bufferSize;
SP_DEVICE_INTERFACE_DATA interfaceData;
LONG ii = 0;
int result;
HECI_CLIENT properties;
GUID guid;
if (client == PTHI_CLIENT) guid = HECI_PTHI_GUID;
if (client == LMS_CLIENT) guid = LMS_GUID;
if (client == MKHI_CLIENT) guid = MKHI_GUID;
if (module == NULL) module = &MEI_global;
module->_verbose = false;
if (module->_initialized) {
heci_Deinit(module);
}
// Find all devices that have our interface
hDeviceInfo = SetupDiGetClassDevs((LPGUID)&GUID_DEVINTERFACE_HECI, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDeviceInfo == INVALID_HANDLE_VALUE) {
if (module->_verbose) {
//_displayHECIError(GET_CLASS_DEVS,GetLastError());
}
return false; //GET_CLASS_DEVS;
}
// Setup the interface data struct
interfaceData.cbSize = sizeof(interfaceData);
for (ii = 0;
SetupDiEnumDeviceInterfaces(hDeviceInfo, NULL, (LPGUID)&GUID_DEVINTERFACE_HECI, ii, &interfaceData);
++ii) {
// Found our device instance
if (!SetupDiGetDeviceInterfaceDetail(hDeviceInfo, &interfaceData, NULL, 0, &bufferSize, NULL)) {
DWORD err = GetLastError();
if (err != ERROR_INSUFFICIENT_BUFFER) {
if (module->_verbose) {
//_displayHECIError(GET_INTERFACE_DETAIL,err);
}
continue;
}
}
// Allocate a big enough buffer to get detail data
deviceDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(bufferSize);
if (deviceDetail == NULL) {
if (module->_verbose) {
//_displayHECIError(ALLOCATE_MEMORY_ERROR,0);
}
continue;
}
// Setup the device interface struct
deviceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
// Try again to get the device interface detail info
if (!SetupDiGetDeviceInterfaceDetail(hDeviceInfo, &interfaceData, deviceDetail, bufferSize, NULL, NULL))
{
/*
if (_verbose)
{
DWORD err = GetLastError();
_displayHECIError(GET_INTERFACE_DETAIL,err);
}
*/
free(deviceDetail);
deviceDetail = NULL;
continue;
}
break;
}
SetupDiDestroyDeviceInfoList(hDeviceInfo);
if (deviceDetail == NULL) {
if (module->_verbose) {
//_displayHECIError(FIND_HECI_FAILURE,0);
}
return false; //FIND_HECI_FAILURE;
}
module->_handle = CreateFile(deviceDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
free(deviceDetail);
if (module->_handle == INVALID_HANDLE_VALUE) {
if (module->_verbose) {
//_displayHECIError(CREATE_HECI_FILE_FAILURE,GetLastError());
}
return false; //CREATE_HECI_FILE_FAILURE;
}
module->_initialized = true;
result = heci_doIoctl(module, (DWORD)IOCTL_HECI_GET_VERSION, NULL, 0, &(module->m_heciVersion), sizeof(HECI_VERSION));
if (result != sizeof(HECI_VERSION)) {
if (module->_verbose) {
//_displayHECIError(GET_HECI_DRIVER_VERSION_FAILURE,0);
}
heci_Deinit(module);
return false; //GET_HECI_DRIVER_VERSION_FAILURE;
}
module->m_haveHeciVersion = true;
if (module->_verbose) {
//_displayHECIData(HECI_DRIVER_VERSION);
//_ftprintf(stdout,_T("%d.%d.%d.%d\n"), (m_heciVersion).major, (m_heciVersion).minor, (m_heciVersion).hotfix, (m_heciVersion).build);
}
memset(&properties, 0, sizeof(properties));
result = heci_doIoctl(module, (DWORD)IOCTL_HECI_CONNECT_CLIENT, (void*)(&guid), sizeof(GUID), &properties, sizeof(properties));
if (result != sizeof(properties))
{
if (module->_verbose) {
//_displayHECIError(HECI_CONNECT_TO_PTHI_CLIENT_FAILURE,0);
}
//Deinit();
return false; //HECI_CONNECT_TO_PTHI_CLIENT_FAILURE;
}
module->_bufSize = properties.MaxMessageLength;
return true;
}
void heci_Deinit(struct MEImodule* module)
{
if (module == NULL) module = &MEI_global;
if (module->_initialized == false) return;
module->_initialized = false;
module->_bufSize = 0;
if (module->_handle != INVALID_HANDLE_VALUE)
{
CloseHandle(module->_handle);
module->_handle = INVALID_HANDLE_VALUE;
}
}
int heci_ReceiveMessage(struct MEImodule* module, unsigned char *buffer, int len, unsigned long timeout) // Timeout default is 2000
{
DWORD bytesRead = 0;
int res;
HANDLE h_event = NULL;
OVERLAPPED overlapped;
DWORD error;
DWORD eventRes;
if (module == NULL) module = &MEI_global;
if ((h_event = CreateEvent(NULL, FALSE, FALSE, NULL)) == 0) goto out;
overlapped.hEvent = h_event;
overlapped.Offset = 0;
overlapped.OffsetHigh = 0;
res = ReadFile(module->_handle, buffer, len, &bytesRead, &overlapped);
error = GetLastError();
if ((0 == res) && (ERROR_IO_PENDING != error)) {
if (module->_verbose) {
//_displayHECIError(READ_FILE,GetLastError());
}
bytesRead = (DWORD)-1;
goto out;
}
eventRes = WaitForSingleObject(h_event, timeout);
if (eventRes == WAIT_TIMEOUT) {
bytesRead = 0;
goto out;
}
res = GetOverlappedResult(module->_handle, &overlapped, &bytesRead, true);
if (res == 0) {
if (module->_verbose) {
//_displayHECIError(READ_FILE,GetLastError());
}
bytesRead = (DWORD)-1;
goto out;
}
out:
if (h_event != NULL) CloseHandle(h_event);
if (bytesRead <= 0) heci_Deinit(module);
return bytesRead;
}
int heci_SendMessage(struct MEImodule* module, const unsigned char *buffer, int len, unsigned long timeout) // Timeout default is 2000
{
DWORD bytesWritten = 0;
int res;
HANDLE h_event = NULL;
OVERLAPPED overlapped;
DWORD lastError;
DWORD eventRes;
if (module == NULL) module = &MEI_global;
if ((h_event = CreateEvent(NULL, FALSE, FALSE, NULL)) == 0) goto out;
overlapped.hEvent = h_event;
overlapped.Offset = 0;
overlapped.OffsetHigh = 0;
res = WriteFile(module->_handle, buffer, len, &bytesWritten, &overlapped);
lastError = GetLastError();
if ((0 == res) && (ERROR_IO_PENDING !=lastError )) {
if (module->_verbose) {
//_displayHECIError(WRITE_FILE,GetLastError());
}
bytesWritten = (DWORD)-1;
goto out;
}
eventRes = WaitForSingleObject(h_event, timeout);
if (eventRes == WAIT_TIMEOUT) {
if (module->_verbose) {
//_displayHECIError(WRITE_FILE_TIME_OUT,0);
}
bytesWritten = 0;
goto out;
}
res = GetOverlappedResult(module->_handle, &overlapped, &bytesWritten, false);
if (res == 0) {
if (module->_verbose) {
//_displayHECIError(WRITE_FILE,GetLastError());
}
bytesWritten = (DWORD)-1;
goto out;
}
out:
if (h_event != NULL) CloseHandle(h_event);
if (bytesWritten <= 0) heci_Deinit(module);
return bytesWritten;
}
int heci_doIoctl(struct MEImodule* module, DWORD code, void *inbuf, int inlen, void *outbuf, int outlen)
{
int res;
DWORD bytesRead = 0;
HANDLE h_event = NULL;
OVERLAPPED overlapped;
if (module == NULL) module = &MEI_global;
if (!module->_initialized) return -1;
if ((h_event = CreateEvent(NULL, FALSE, FALSE, NULL)) == 0) goto out;
overlapped.hEvent = h_event;
overlapped.Offset = 0;
overlapped.OffsetHigh = 0;
res = DeviceIoControl(module->_handle, code, inbuf, inlen, outbuf, outlen, &bytesRead, &overlapped);
if ((0 == res) && (ERROR_IO_PENDING != GetLastError())) {
if (module->_verbose) {
//_displayHECIError(IOCTL_COMMAND,GetLastError());
}
bytesRead = (DWORD)-1;
goto out;
}
WaitForSingleObject(h_event, INFINITE);
res = GetOverlappedResult(module->_handle, &overlapped, &bytesRead, true);
if (res == 0) {
if (module->_verbose) {
//_displayHECIError(IOCTL_COMMAND,GetLastError());
}
bytesRead = (DWORD)-1;
goto out;
}
out:
if (h_event != NULL) CloseHandle(h_event);
if (bytesRead == (DWORD)-1) heci_Deinit(module);
return bytesRead;
}
TCHAR *_getErrMsg(DWORD err)
{
static TCHAR buffer[1024];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
err,
0,
buffer,
sizeof(buffer) - 1,
0);
return buffer;
}
/*
// Display a HECI error message
void _displayHECIError(UINT32 errorCode, DWORD lastError)
{
TCHAR str[HECI_MAX_LINE_LEN];
TCHAR *msg;
LoadString(GetModuleHandle(NULL), HECI_ERROR_MESSAGE, str, sizeof(str)/sizeof(TCHAR));
_ftprintf(stderr, _T("%s"), str);
_ftprintf(stderr, _T("%s"), L" ");
LoadString(GetModuleHandle(NULL), errorCode , str, sizeof(str)/sizeof(TCHAR));
if(0!= lastError)
{
msg = _getErrMsg(lastError);
_ftprintf(stderr, _T("%s (%d): %s\n"),str, lastError, msg);
}
else
{
_ftprintf(stderr, _T("%s\n"),str);
}
}
// Display a HECI data message
void _displayHECIData(UINT32 messageId)
{
TCHAR str[HECI_MAX_LINE_LEN];
LoadString(GetModuleHandle(NULL), messageId , str, sizeof(str)/sizeof(TCHAR));
_ftprintf(stdout,_T("%s"),str);
_ftprintf(stdout,_T("%s"),L" ");
}
*/
#endif

48
MicroLMS/heci/HECIWin.h Normal file
View File

@@ -0,0 +1,48 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef _MINCORE
#ifndef __HECI_WIN_H__
#define __HECI_WIN_H__
#include "HECI_if.h"
#include <stdio.h>
#include <windows.h>
#define bool int
typedef enum
{
PTHI_CLIENT,
LMS_CLIENT,
MKHI_CLIENT
} HECI_CLIENTS;
struct MEImodule
{
bool _initialized;
bool _verbose;
unsigned int _bufSize;
unsigned char _protocolVersion;
int _fd;
bool m_haveHeciVersion;
HECI_VERSION m_heciVersion;
HANDLE _handle;
OVERLAPPED overlapped;
};
bool heci_Init(struct MEImodule* module, HECI_CLIENTS client);
void heci_Deinit(struct MEImodule* module);
int heci_ReceiveMessage(struct MEImodule* module, unsigned char *buffer, int len, unsigned long timeout); // Timeout default is 2000
int heci_SendMessage(struct MEImodule* module, const unsigned char *buffer, int len, unsigned long timeout); // Timeout default is 2000
unsigned int heci_GetBufferSize(struct MEImodule* module);
unsigned char heci_GetProtocolVersion(struct MEImodule* module);
bool heci_GetHeciVersion(struct MEImodule* module, HECI_VERSION *version);
bool heci_IsInitialized(struct MEImodule* module);
#endif // __HECI_WIN_H__
#endif

198
MicroLMS/heci/HECI_if.h Normal file
View File

@@ -0,0 +1,198 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef _MINCORE
#ifndef __HECI_INTRFACE_H__
#define __HECI_INTRFACE_H__
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef char CHAR;
typedef unsigned long ULONG;
typedef UINT32 AMT_STATUS;
typedef UINT32 AMT_BOOLEAN;
typedef enum _HECI_STATUS {
HECI_STATUS_OK = 0x0,
HECI_STATUS_GENERAL_ERROR = 0x2000,
HECI_STATUS_LOCATE_DEVICE_ERROR,
HECI_STATUS_MEMORY_ACCESS_ERROR,
HECI_STATUS_WRITE_REGISTER_ERROR,
HECI_STATUS_MEMORY_ALLOCATION_ERROR,
HECI_STATUS_BUFFER_OVEREFLOW_ERROR,
HECI_STATUS_NOT_ENOUGH_MEMORY,
HECI_STATUS_MSG_TRANSMISSION_ERROR,
HECI_STATUS_VERSION_MISMATCH,
HECI_STATUS_UNEXPECTED_INTERRUPT_REASON,
HECI_STATUS_TIMEOUT_ERROR,
HECI_STATUS_UNEXPECTED_RESPONSE,
HECI_STATUS_UNKNOWN_MESSAGE,
HECI_STATUS_CANNOT_FOUND_HOST_CLIENT,
HECI_STATUS_CANNOT_FOUND_ME_CLIENT,
HECI_STATUS_CLIENT_ALREADY_CONNECTED,
HECI_STATUS_NO_FREE_CONNECTION,
HECI_STATUS_ILLEGAL_PARAMETER,
HECI_STATUS_FLOW_CONTROL_ERROR,
HECI_STATUS_NO_MESSAGE,
HECI_STATUS_BUFFER_TOO_LARGE,
HECI_STATUS_BUFFER_TOO_SMALL,
HECI_STATUS_BUFFER_NOT_EMPTY,
NUM_OF_HECI_STATUSES
} HECI_STATUS;
#ifdef WIN32
// Win32 code
#define AMT_LOCAL_AGENT_STATUS_SUCCESS 0
#define USAGE 1
#define ERROR_MESSAGE 2
#define VERSION_MESSAGE 3
#define HECI_ERROR_MESSAGE 4
#define UNKNOWN 5
#define HECI_CONNECT_TO_FWU_CLIENT_FAILURE 6
#define WRITE_FILE_TIME_OUT 7
#define ME_FW_INFO 8
#define ME_MODE 9
#define IOCTL_COMMAND 10
#define WRITE_FILE 11
#define READ_FILE 12
#define GET_CLASS_DEVS 13
#define GET_INTERFACE_DETAIL 14
#define ICH_VERSION 15
#define FIND_HECI_FAILURE 16
#define CREATE_HECI_FILE 17
#define CREATE_HECI_FILE_FAILURE 17
#define GET_HECI_DRIVER_VERSION_FAILURE 18
#define LA_STATUS_INTERNAL_ERROR 19
#define HECI_CONNECT_TO_PTHI_CLIENT_FAILURE 20
#define LA_HECI_ERROR 21
#define ALLOCATE_MEMORY_ERROR 22
#define LA_HECI_NOT_INSTALLED_ERROR 23
#define FW_BUFFER_IS_TO_SMALL 24
#define SEND_DATA_TO_FW_FAILURE 25
#define RECEIVE_DATA_FROM_FW_FAILURE 26
#define GET_INFO_FROM_HECI_FAILURE 27
#define MCH_VERSION 28
#define OEM_VENDOR 29
#define HECI_DRIVER_VERSION 30
#define CODE_MAJOR_VERSION 31
#define CODE_MINOR_VERSION 32
#define CODE_HOTFIX_VERSION 33
#define CODE_BUID_VERSION 34
#define BIOS_VERSION 35
#define AMT_CODE_VERSION 36
#define AMT_MODE 37
#define AMT_MODE_1 38
#define IDS_STRING39 39
#define AMT_MODE_2 39
#define PROVISIONING_STATE 40
#define STATE_PRE 41
#define STATE_IN 42
#define STATE_POST 43
#define IDS_STRING44 44
#define PARSE_KEYWORD_DISCOVERY_TEST 44
#define DISCOVERY_PASS 45
#define IDS_STRING46 46
#define DISCOVERY_FAILED 46
#define IDS_STRING47 47
#define PARSE_KEYWORD_ACTIVATE 47
#define PARSE_KEYWORD_OTP 48
#define PARSE_KEYWORD_DNS 49
#define PARSE_KEYWORD_VERBOSE 50
#define INVALID_PARAM_INPUT 51
#define USAGE_LOCAL_AGENT 52
#define USAGE_OPTIONS 53
#define USAGE_OPTIONS_OTP 54
#define USAGE_OPTIONS_DNS 55
#define USAGE_OPTIONS_DISCOVERY 56
#define USAGE_OPTIONS_ACTIVATE 57
#define USAGE_OPTIONS_VERBOSE 58
#define WORD_ZTC 59
#define WORD_ENABLED 60
#define WORD_DISABLED 61
#define WORD_PROVISIONING_TLS_MODE 62
#define WORD_PKI 63
#define WORD_PSK 64
#define WORD_RNG_SEED_STATUS 65
#define WORD_EXIST 66
#define WORD_IN_PROGRESS 67
#define WORD_NOT_EXIST 68
#define WORD_AMT_CONFIG_ACTIVATE 69
#define WORD_SUCCESS 70
#define IDS_STRING71 71
#define WORD_FAILURE 71
#define WORD_NOT_READY 72
#define IDS_STRING73 73
#define HASH_ENTRY 73
#define HECI_CONNECT_TO_WD_CLIENT_FAILURE 74
#define CHANGE_TO_AMT_FAILURE 75
#define IDS_STRING76 76
#define WORD_CHANGE_TO_AMT 76
#define FOUND 77
#define CERT_HASHES_IN_FW 78
#define NO_HANDLES_FOUND 79
#define CERT_HASH 80
#define FRIENDLY_NAME 81
#define FILE_DEVICE_HECI 0x8000
#define HECI_IOCTL(index) CTL_CODE(FILE_DEVICE_HECI, index, METHOD_BUFFERED, FILE_READ_DATA)
#define IOCTL_HECI_GET_VERSION CTL_CODE(FILE_DEVICE_HECI, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS)
#define IOCTL_HECI_CONNECT_CLIENT CTL_CODE(FILE_DEVICE_HECI, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS)
#define IOCTL_HECI_WD CTL_CODE(FILE_DEVICE_HECI, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS)
#endif
#pragma pack(1)
typedef struct _HECI_VERSION {
UINT8 major;
UINT8 minor;
UINT8 hotfix;
UINT16 build;
} HECI_VERSION;
typedef struct _HECI_CLIENT {
UINT32 MaxMessageLength;
UINT8 ProtocolVersion;
} HECI_CLIENT;
typedef union _MEFWCAPS_SKU
{
UINT32 Data;
struct {
UINT32 Reserved :1; //Legacy
UINT32 Qst :1; //QST
UINT32 Asf :1; //ASF2
UINT32 Amt :1; //AMT Professional
UINT32 AmtFund :1; //AMT Fundamental
UINT32 Tpm :1; //TPM
UINT32 Dt :1;
UINT32 Fps :1; //Fingerprint Sensor
UINT32 HomeIT :1; //Home IT
UINT32 Mctp :1; //MCTP
UINT32 WoX :1;
UINT32 PmcPatch :1; //PMC Patch
UINT32 Ve :1; //VE
UINT32 Tdt :1; //Theft Deterrent Technology
UINT32 Corp :1; //Corporate
UINT32 Reserved2 :17;
} Fields;
} MEFWCAPS_SKU;
typedef enum _MEFWCAPS_MANAGEABILITY_SUPP
{
MEFWCAPS_MANAGEABILITY_SUPP_NONE = 0,
MEFWCAPS_MANAGEABILITY_SUPP_AMT,
MEFWCAPS_MANAGEABILITY_SUPP_ASF,
MEFWCAPS_MANAGEABILITY_SUPP_CP
} MEFWCAPS_MANAGEABILITY_SUPP;
#pragma pack()
#endif // __HECI_INTRFACE_H__
#endif

View File

@@ -0,0 +1,553 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef _MINCORE
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "LMEConnection.h"
#include "LMS_if.h"
#include "../microstack/ILibParsers.h"
#ifdef _POSIX
#define UNREFERENCED_PARAMETER(P) (P)
#endif
#define MEI_IO_TIMEOUT 1000
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
const unsigned int LME_RX_WINDOW_SIZE = 4096;
int LME_sendMessage(struct LMEConnection* module, unsigned char *buffer, int len);
void LME_doRX(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead);
void LME_apfGlobalRequest(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead, int *status);
void LME_Deinit(struct LMEConnection* module);
bool LME_IsInitialized(struct LMEConnection* module)
{
// Lock il(_initLock);
bool ret = (bool)(module->initState == INIT_STATE_CONNECTED);
return ret;
}
#ifdef WIN32
DWORD WINAPI LME_Thread(void* obj)
#else
void LME_Thread(void* obj)
#endif
{
#ifdef WIN32
HECI_VERSION version;
#endif
int len = 0;
int bufsize = 0;
unsigned char* data = NULL;
struct LMEConnection* module = (struct LMEConnection*)obj;
//printf("LMS THREAD START\r\n");
do {
bufsize = heci_GetBufferSize(&(module->mei));
if ((data = (unsigned char*)malloc(bufsize)) == NULL) ILIBCRITICALEXIT(254);
do {
len = heci_ReceiveMessage(&(module->mei), data, bufsize, 0xFFFFFFFF);
//printf("LMS THREAD READ LEN=%d\r\n", len);
if (len > 0 && data != NULL) LME_doRX(module, data, len);
} while (len >= 0);
module->cb(module, module->cbParam, NULL, 0);
module->initState = INIT_STATE_DISCONNECTED;
free(data);
// printf("LMS TRYING RECONNECT\r\n");
while (module->exit == 0 && module->initState == INIT_STATE_DISCONNECTED)
{
// Setup the MEI interface with the LME GUID
#ifdef WIN32
if (heci_Init(&(module->mei), LMS_CLIENT) == TRUE && heci_GetHeciVersion(&(module->mei), &version) == TRUE && version.major >= LMS_PROTOCOL_VERSION) { module->initState = INIT_STATE_CONNECTED; }
#else
if (heci_Init(&(module->mei), 1) == TRUE && heci_GetProtocolVersion(&(module->mei)) >= LMS_PROTOCOL_VERSION) { module->initState = INIT_STATE_CONNECTED; }
#endif
if (module->exit == 0 && module->initState == INIT_STATE_DISCONNECTED)
{
// printf("LMS THREAD SLEEP\r\n");
#ifdef WIN32
Sleep(2000);
#else
sleep(2);
#endif
}
//if (module->initState == INIT_STATE_CONNECTED) printf("LMS THREAD RECONNECT\r\n");
}
}
while (module->exit == 0);
// printf("LMS THREAD QUIT\r\n");
module->exit = 2;
#ifdef WIN32
return 0;
#endif
}
// Setup the LME connection
bool LME_Init(struct LMEConnection* module, MEICallback cb, void *param)
{
#ifdef WIN32
HECI_VERSION version;
#endif
// Setup the state object
memset(module, 0, sizeof(struct LMEConnection));
module->initState = INIT_STATE_DISCONNECTED;
module->cb = cb;
module->cbParam = param;
// Setup the MEI interface with the LME GUID
#ifdef WIN32
if (heci_Init(&(module->mei), LMS_CLIENT) == FALSE || heci_GetHeciVersion(&(module->mei), &version) == FALSE || version.major < LMS_PROTOCOL_VERSION) { module->initState = INIT_STATE_DISCONNECTED; return FALSE; }
#else
if (heci_Init(&(module->mei), 1) == FALSE || heci_GetProtocolVersion(&(module->mei)) < LMS_PROTOCOL_VERSION) { module->initState = INIT_STATE_DISCONNECTED; return FALSE; }
#endif
module->initState = INIT_STATE_CONNECTED;
if ((module->txBuffer = (unsigned char*)malloc(LME_GetMeiBufferSize(module))) == NULL) ILIBCRITICALEXIT(254);
// Create the thread that will read the MEI/LME stream
ILibSpawnNormalThread((voidfp)(&LME_Thread), module);
return TRUE;
}
// Disconnect the LME connection
void LME_Deinit(struct LMEConnection* module)
{
//printf("LME_Deinit()\r\n");
if (module == NULL) return;
if (module->initState == INIT_STATE_CONNECTED) { heci_Deinit(&(module->mei)); }
module->initState = INIT_STATE_DISCONNECTED;
}
// Exit LME
void LME_Exit(struct LMEConnection* module)
{
int l = 0;
//printf("LME_Exit()\r\n");
if (module == NULL) return;
if (module->exit == 0) module->exit = 1;
LME_Deinit(module);
#ifdef WIN32
while (module->exit != 2 && l < 40) { Sleep(100); l++; }
#else
/*
while (module->exit != 2 && l < 4)
{
printf("LME_Holding %d\r\n", l);
Sleep(1);
l++;
}
*/
#endif
if (module->txBuffer != NULL && l < 40) { free(module->txBuffer); module->txBuffer = NULL; }
}
// Send the APF disconnect message to the MEI
bool LME_Disconnect(struct LMEConnection* module, APF_DISCONNECT_REASON_CODE reasonCode)
{
unsigned char buf[sizeof(APF_DISCONNECT_MESSAGE)];
APF_DISCONNECT_MESSAGE *disconnectMessage = (APF_DISCONNECT_MESSAGE *)buf;
memset(disconnectMessage, 0, sizeof(buf));
disconnectMessage->MessageType = APF_DISCONNECT;
disconnectMessage->ReasonCode = htonl(reasonCode);
return (LME_sendMessage(module, buf, sizeof(buf)) == sizeof(buf));
}
// Send the AFP service accept message to the MEI
bool LME_ServiceAccept(struct LMEConnection* module, char* serviceName)
{
int len;
int res;
int servicenamelen = (int)strnlen_s(serviceName, _MAX_PATH);
unsigned char *buf;
unsigned char *pCurrent;
if (!LME_IsInitialized(module)) return FALSE;
if ((buf = (unsigned char*)malloc(sizeof(APF_SERVICE_ACCEPT_MESSAGE) + servicenamelen)) == NULL) ILIBCRITICALEXIT(254);
pCurrent = buf;
*pCurrent = APF_SERVICE_ACCEPT;
++pCurrent;
*((unsigned int *)pCurrent) = htonl(servicenamelen);
pCurrent += 4;
memcpy_s(pCurrent, sizeof(APF_SERVICE_ACCEPT_MESSAGE) + servicenamelen, serviceName, servicenamelen);
pCurrent += servicenamelen;
len = (int)(pCurrent - buf);
res = LME_sendMessage(module, buf, len);
free(buf);
return (res == len);
}
bool LME_ProtocolVersion(struct LMEConnection* module, unsigned int majorversion, unsigned int minorversion, unsigned int triggerreason)
{
APF_PROTOCOL_VERSION_MESSAGE protVersion;
memset(&protVersion, 0, sizeof(protVersion));
protVersion.MessageType = APF_PROTOCOLVERSION;
protVersion.MajorVersion = htonl(majorversion);
protVersion.MinorVersion = htonl(minorversion);
protVersion.TriggerReason = htonl(triggerreason);
return (LME_sendMessage(module, (unsigned char *)&protVersion, sizeof(protVersion)) == sizeof(protVersion));
}
bool LME_TcpForwardReplySuccess(struct LMEConnection* module, unsigned int port)
{
APF_TCP_FORWARD_REPLY_MESSAGE message;
memset(&message, 0, sizeof(message));
message.MessageType = APF_REQUEST_SUCCESS;
message.PortBound = htonl(port);
return (LME_sendMessage(module, (unsigned char *)&message, sizeof(message)) == sizeof(message));
}
bool LME_SendShortMessage(struct LMEConnection* module, unsigned char buf)
{
return (LME_sendMessage(module, &buf, sizeof(buf)) == sizeof(buf));
}
#define pCurrentOffset ((int)(pCurrent - buf))
bool LME_ChannelOpenForwardedRequest(struct LMEConnection* module, unsigned int senderChannel, char* connectedIP, unsigned int connectedPort, char* originatorIP, unsigned int originatorPort)
{
int res;
int connectedIPlen = (int)strnlen_s(connectedIP, _MAX_PATH);
int originatorIPlen = (int)strnlen_s(originatorIP, _MAX_PATH);
unsigned char *buf;
unsigned char *pCurrent;
int mallocSize = 5 + APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED) + 16 + connectedIPlen + 8 + originatorIPlen + 4;
if (!LME_IsInitialized(module)) return FALSE;
if ((buf = (unsigned char*)malloc(mallocSize)) == NULL) ILIBCRITICALEXIT(254);
pCurrent = buf;
if (strnlen_s(originatorIP, _MAX_PATH) > 63) { free(buf); return FALSE; }
*pCurrent = APF_CHANNEL_OPEN;
++pCurrent;
*((unsigned int *)pCurrent) = htonl(APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED));
pCurrent += sizeof(unsigned int);
memcpy_s(pCurrent, mallocSize - pCurrentOffset, APF_OPEN_CHANNEL_REQUEST_FORWARDED, APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED));
pCurrent += APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED);
*((unsigned int *)pCurrent) = htonl(senderChannel);
pCurrent += sizeof(unsigned int);
*((unsigned int *)pCurrent) = htonl(LME_RX_WINDOW_SIZE);
pCurrent += sizeof(unsigned int);
*((unsigned int *)pCurrent) = 0xFFFFFFFF;
pCurrent += sizeof(unsigned int);
*((unsigned int *)pCurrent) = htonl(connectedIPlen);
pCurrent += sizeof(unsigned int);
memcpy_s(pCurrent, mallocSize - pCurrentOffset, connectedIP, connectedIPlen);
pCurrent += connectedIPlen;
*((unsigned int *)pCurrent) = htonl(connectedPort);
pCurrent += sizeof(unsigned int);
*((unsigned int *)pCurrent) = htonl((unsigned int)originatorIPlen);
pCurrent += sizeof(unsigned int);
memcpy_s(pCurrent, mallocSize - pCurrentOffset, originatorIP, originatorIPlen);
pCurrent += originatorIPlen;
*((unsigned int *)pCurrent) = htonl(originatorPort);
pCurrent += sizeof(unsigned int);
res = LME_sendMessage(module, buf, (int)(pCurrent - buf));
free(buf);
return (res == pCurrent - buf);
}
bool LME_ChannelOpenReplySuccess(struct LMEConnection* module, unsigned int recipientChannel, unsigned int senderChannel)
{
APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE message;
message.MessageType = APF_CHANNEL_OPEN_CONFIRMATION;
message.RecipientChannel = htonl(recipientChannel);
message.SenderChannel = htonl(senderChannel);
message.InitialWindowSize = htonl(LME_RX_WINDOW_SIZE);
message.Reserved = 0xFFFFFFFF;
return (LME_sendMessage(module, (unsigned char*)&message, sizeof(message)) == sizeof(message));
}
bool LME_ChannelOpenReplyFailure(struct LMEConnection* module, unsigned int recipientChannel, unsigned int reason)
{
APF_CHANNEL_OPEN_FAILURE_MESSAGE message;
message.MessageType = APF_CHANNEL_OPEN_FAILURE;
message.RecipientChannel = htonl(recipientChannel);
message.ReasonCode = htonl(reason);
message.Reserved = 0x00000000;
message.Reserved2 = 0x00000000;
return (LME_sendMessage(module, (unsigned char*)&message, sizeof(message)) == sizeof(message));
}
bool LME_ChannelClose(struct LMEConnection* module, unsigned int recipientChannel, unsigned int senderChannel )
{
APF_CHANNEL_CLOSE_MESSAGE message;
UNREFERENCED_PARAMETER( senderChannel );
message.MessageType = APF_CHANNEL_CLOSE;
message.RecipientChannel = htonl(recipientChannel);
return (LME_sendMessage(module, (unsigned char*)&message, sizeof(message)) == sizeof(message));
}
int LME_ChannelData(struct LMEConnection* module, unsigned int recipientChannel, unsigned int len, unsigned char *buffer)
{
APF_CHANNEL_DATA_MESSAGE *message;
if (len > (LME_GetMeiBufferSize(module) - sizeof(APF_CHANNEL_DATA_MESSAGE)) || module->txBuffer == NULL) return -1;
message = (APF_CHANNEL_DATA_MESSAGE*)module->txBuffer;
message->MessageType = APF_CHANNEL_DATA;
message->RecipientChannel = htonl(recipientChannel);
message->DataLength = htonl(len);
memcpy_s(module->txBuffer + sizeof(APF_CHANNEL_DATA_MESSAGE), LME_GetMeiBufferSize(module) - sizeof(APF_CHANNEL_DATA_MESSAGE), buffer, len);
return LME_sendMessage(module, (unsigned char *)message, sizeof(APF_CHANNEL_DATA_MESSAGE) + len) - sizeof(APF_CHANNEL_DATA_MESSAGE);
}
bool LME_ChannelWindowAdjust(struct LMEConnection* module, unsigned int recipientChannel, unsigned int len)
{
APF_WINDOW_ADJUST_MESSAGE message;
message.MessageType = APF_CHANNEL_WINDOW_ADJUST;
message.RecipientChannel = htonl(recipientChannel);
message.BytesToAdd = htonl(len);
return (LME_sendMessage(module, (unsigned char *)&message, sizeof(message)) == sizeof(message));
}
int LME_sendMessage(struct LMEConnection* module, unsigned char *buffer, int len)
{
int result;
if (!LME_IsInitialized(module)) { return -1; }
result = heci_SendMessage(&(module->mei), buffer, len, MEI_IO_TIMEOUT);
if (result < 0) LME_Deinit(module);
return result;
}
bool LME_checkMinMsgSize(unsigned char *buf, unsigned int bytesRead)
{
switch (buf[0]) {
case APF_DISCONNECT:
if (bytesRead < sizeof(APF_DISCONNECT_MESSAGE)) { return FALSE; }
break;
case APF_SERVICE_REQUEST:
if (bytesRead < sizeof(APF_SERVICE_REQUEST_MESSAGE)) { return FALSE; }
if (bytesRead < (sizeof(APF_SERVICE_REQUEST_MESSAGE) + ntohl(((APF_SERVICE_REQUEST_MESSAGE *)buf)->ServiceNameLength))) { return FALSE; }
break;
case APF_USERAUTH_REQUEST:
if (bytesRead < (3 * sizeof(unsigned int))) { return FALSE; }
break;
case APF_GLOBAL_REQUEST:
if (bytesRead < (sizeof(APF_GENERIC_HEADER) + sizeof(UINT8))) { return FALSE; }
if (bytesRead < (sizeof(APF_GENERIC_HEADER) + sizeof(UINT8) + ntohl(((APF_GENERIC_HEADER *)buf)->StringLength))) { return FALSE; }
break;
case APF_CHANNEL_OPEN:
if (bytesRead < sizeof(APF_GENERIC_HEADER)) { return FALSE; }
if (bytesRead < (sizeof(APF_GENERIC_HEADER) + ntohl(((APF_GENERIC_HEADER *)buf)->StringLength))) { return FALSE; }
break;
case APF_CHANNEL_OPEN_CONFIRMATION:
if (bytesRead < sizeof(APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE)) { return FALSE; }
break;
case APF_CHANNEL_OPEN_FAILURE:
if (bytesRead < sizeof(APF_CHANNEL_OPEN_FAILURE_MESSAGE)) { return FALSE; }
break;
case APF_CHANNEL_CLOSE:
if (bytesRead < sizeof(APF_CHANNEL_CLOSE_MESSAGE)) { return FALSE; }
break;
case APF_CHANNEL_DATA:
if (bytesRead < sizeof(APF_CHANNEL_DATA_MESSAGE)) { return FALSE; }
if (bytesRead < (sizeof(APF_CHANNEL_DATA_MESSAGE) + ntohl(((APF_CHANNEL_DATA_MESSAGE *)buf)->DataLength))) { return FALSE; }
break;
case APF_CHANNEL_WINDOW_ADJUST:
if (bytesRead < sizeof(APF_WINDOW_ADJUST_MESSAGE)) { return FALSE; }
break;
case APF_PROTOCOLVERSION:
if (bytesRead < sizeof(APF_PROTOCOL_VERSION_MESSAGE)) { return FALSE; }
break;
default:
return FALSE;
}
return TRUE;
}
void LME_doRX(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead)
{
if (bytesRead == 0) return;
if (!LME_checkMinMsgSize(rxBuffer, bytesRead)) { LME_Deinit(module); return; }
module->cb(module, module->cbParam, rxBuffer, bytesRead);
}
/*
void LME_apfChannelOpen(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead, int *status)
{
APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer;
if (_strnicmp((char *)pHeader->String, APF_OPEN_CHANNEL_REQUEST_DIRECT, APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_DIRECT)) == 0)
{
unsigned int senderChannel = 0;
LME_apfChannelOpenDirect(module, rxBuffer, bytesRead, &senderChannel, status);
if (LME_IsInitialized(module) && (*status == 1)) {
if (plugin.retry(rxBuffer, bytesRead) != LMS_DROPPED) { LME_apfChannelOpenDirect(module, rxBuffer, bytesRead, NULL, status); }
}
if (LME_IsInitialized(module) && (*status == 1)) {
LME_ChannelOpenReplyFailure(module, senderChannel, OPEN_FAILURE_REASON_CONNECT_FAILED);
}
}
}
void LME_apfChannelOpenDirect(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead, unsigned int *senderChannel, int *status)
{
unsigned char *pCurrent;
APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer;
if (bytesRead < sizeof(APF_GENERIC_HEADER) +
ntohl(pHeader->StringLength) +
7 + (5 * sizeof(unsigned int))) {
ILIBMESSAGE("apfChannelOpenDirect: Error receiving data from MEI\n");
LME_Deinit(module);
return;
}
pCurrent = rxBuffer + sizeof(APF_GENERIC_HEADER) +
APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_DIRECT);
LMEChannelOpenRequestMessage channelOpenRequest;
channelOpenRequest.ChannelType = APF_CHANNEL_DIRECT;
channelOpenRequest.SenderChannel = ntohl(*((unsigned int *)pCurrent));
if (senderChannel) {
*senderChannel = channelOpenRequest.SenderChannel;
}
pCurrent += sizeof(unsigned int);
channelOpenRequest.InitialWindow = ntohl(*((unsigned int *)pCurrent));
pCurrent += 2 * sizeof(unsigned int);
unsigned int len = ntohl(*((unsigned int *)pCurrent));
pCurrent += sizeof(unsigned int);
channelOpenRequest.Address.append((char *)pCurrent, len);
pCurrent += len;
channelOpenRequest.Port = ntohl(*((unsigned int *)pCurrent));
pCurrent += sizeof(unsigned int);
module->_cb(module, module->_cbParam, &channelOpenRequest, sizeof(channelOpenRequest), status);
}
*/
/*
void LME_apfUserAuthRequest(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead, int *status)
{
unsigned char *pCurrent = rxBuffer;
++pCurrent;
LMEUserAuthRequestMessage userAuthRequest;
unsigned int len = ntohl(*((unsigned int *)pCurrent));
pCurrent += sizeof(unsigned int);
if ((bytesRead - (pCurrent - rxBuffer)) < len) {
ILIBMESSAGE("_apfUserAuthRequest1: Error receiving data from MEI\n");
LME_Deinit(module);
return;
}
userAuthRequest.Username.append((char *)pCurrent, len);
pCurrent += len;
if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(unsigned int)) {
ILIBMESSAGE("_apfUserAuthRequest2: Error receiving data from MEI\n");
LME_Deinit(module);
return;
}
len = ntohl(*((unsigned int *)pCurrent));
pCurrent += sizeof(unsigned int);
if ((bytesRead - (pCurrent - rxBuffer)) < len) {
ILIBMESSAGE("_apfUserAuthRequest3: Error receiving data from MEI\n");
LME_Deinit(module);
return;
}
userAuthRequest.ServiceName.append((char *)pCurrent, len);
pCurrent += len;
if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(unsigned int)) {
ILIBMESSAGE("_apfUserAuthRequest4: Error receiving data from MEI\n");
LME_Deinit(module);
return;
}
len = ntohl(*((unsigned int *)pCurrent));
pCurrent += sizeof(unsigned int);
if ((bytesRead - (pCurrent - rxBuffer)) < len) {
ILIBMESSAGE("_apfUserAuthRequest5: Error receiving data from MEI\n");
LME_Deinit(module);
return;
}
userAuthRequest.MethodName.append((char *)pCurrent, len);
pCurrent += len;
if (_strnicmp(userAuthRequest.MethodName.c_str(), APF_AUTH_PASSWORD,
userAuthRequest.MethodName.size()) == 0) {
if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(unsigned int) + 1) {
ILIBMESSAGE("_apfUserAuthRequest6: Error receiving data from MEI\n");
LME_Deinit(module);
return;
}
++pCurrent;
len = ntohl(*((unsigned int *)pCurrent));
pCurrent += sizeof(unsigned int);
if ((bytesRead - (pCurrent - rxBuffer)) < len) {
ILIBMESSAGE("_apfUserAuthRequest7: Error receiving data from MEI\n");
LME_Deinit(module);
return;
}
AuthPasswordData authData;
authData.Password.append((char *)pCurrent, len);
pCurrent += len;
userAuthRequest.MethodData = &authData;
}
module->_cb(module, module->_cbParam, &userAuthRequest, sizeof(userAuthRequest), status);
}
*/
unsigned int LME_GetMeiBufferSize(struct LMEConnection* module)
{
return heci_GetBufferSize(&(module->mei));
}
#endif

View File

@@ -0,0 +1,183 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef _MINCORE
#ifndef __LME_CONNECTION_H__
#define __LME_CONNECTION_H__
#ifdef WIN32
#include "HECIWin.h"
#else
#include "HECILinux.h"
#endif
#include "LMS_if.h"
enum INIT_STATES {
INIT_STATE_DISCONNECTED = 0,
INIT_STATE_CONNECTING,
INIT_STATE_CONNECTED
};
struct LMEConnection;
typedef void (*MEICallback)(struct LMEConnection* module, void *param, void *buffer, unsigned int len);
struct LMEConnection
{
unsigned char reqID;
unsigned char *txBuffer;
MEICallback cb;
void* cbParam;
enum INIT_STATES initState;
unsigned char protocolVer;
struct MEImodule mei;
unsigned char exit;
};
struct LMEDisconnectMessage
{
APF_MESSAGE_TYPE MessageType;
APF_DISCONNECT_REASON_CODE ReasonCode;
};
struct LMEServiceRequestMessage
{
APF_MESSAGE_TYPE MessageType;
char* ServiceName;
};
typedef enum APF_REQUEST_ENUM {
TCP_FORWARD_REQUEST,
TCP_FORWARD_CANCEL_REQUEST,
UDP_SEND_TO
} APF_REQUEST_TYPE;
struct LMEGlobalRequestMessage
{
APF_MESSAGE_TYPE MessageType;
APF_REQUEST_TYPE RequestType;
};
struct LMEProtocolVersionMessage
{
APF_MESSAGE_TYPE MessageType;
unsigned int MajorVersion;
unsigned int MinorVersion;
APF_TRIGGER_REASON TriggerReason;
};
struct LMEUserAuthRequestMessage
{
APF_MESSAGE_TYPE MessageType;
char* Username;
char* ServiceName;
char* MethodName;
char* MethodData;
};
struct LMETcpForwardRequestMessage
{
APF_MESSAGE_TYPE MessageType;
APF_REQUEST_TYPE RequestType;
char* Address;
unsigned int Port;
};
struct LMETcpForwardCancelRequestMessage {
APF_MESSAGE_TYPE MessageType;
APF_REQUEST_TYPE RequestType;
char* Address;
unsigned int Port;
};
struct LMEUdpSendToMessage
{
APF_MESSAGE_TYPE MessageType;
APF_REQUEST_TYPE RequestType;
char* Address;
unsigned int Port;
unsigned int DataLength;
unsigned char *Data;
};
typedef enum APF_CHANNEL_ENUM {
APF_CHANNEL_FORWARDED,
APF_CHANNEL_DIRECT
} APF_CHANNEL_TYPE;
struct LMEChannelOpenRequestMessage
{
APF_MESSAGE_TYPE MessageType;
APF_CHANNEL_TYPE ChannelType;
unsigned int SenderChannel;
unsigned int InitialWindow;
char* Address;
unsigned int Port;
};
struct LMEChannelOpenReplySuccessMessage
{
APF_MESSAGE_TYPE MessageType;
unsigned int RecipientChannel;
unsigned int SenderChannel;
unsigned int InitialWindow;
};
struct LMEChannelOpenReplyFailureMessage
{
APF_MESSAGE_TYPE MessageType;
unsigned int RecipientChannel;
OPEN_FAILURE_REASON ReasonCode;
};
struct LMEChannelCloseMessage
{
APF_MESSAGE_TYPE MessageType;
unsigned int RecipientChannel;
};
struct LMEChannelDataMessage
{
APF_MESSAGE_TYPE MessageType;
unsigned int RecipientChannel;
unsigned int DataLength;
unsigned char *Data;
};
struct LMEChannelWindowAdjustMessage
{
APF_MESSAGE_TYPE MessageType;
unsigned int RecipientChannel;
unsigned int BytesToAdd;
};
bool LME_Init(struct LMEConnection* module, MEICallback cb, void *param);
void LME_Deinit(struct LMEConnection* module);
bool LME_IsInitialized(struct LMEConnection* module);
bool LME_Disconnect(struct LMEConnection* module, APF_DISCONNECT_REASON_CODE reasonCode);
bool LME_ServiceAccept(struct LMEConnection* module, char* serviceName);
bool LME_ProtocolVersion(struct LMEConnection* module, unsigned int majorversion, unsigned int minorversion, unsigned int triggerreason);
bool LME_TcpForwardReplySuccess(struct LMEConnection* module, unsigned int port);
bool LME_SendShortMessage(struct LMEConnection* module, unsigned char buf);
bool LME_ChannelOpenForwardedRequest(struct LMEConnection* module, unsigned int sender, char* connectedIP, unsigned int connectedPort, char* originatorIP, unsigned int originatorPort);
bool LME_ChannelOpenReplySuccess(struct LMEConnection* module, unsigned int recipient, unsigned int sender);
bool LME_ChannelOpenReplyFailure(struct LMEConnection* module, unsigned int recipient, unsigned int reason);
bool LME_ChannelClose(struct LMEConnection* module, unsigned int recipient, unsigned int sender);
int LME_ChannelData(struct LMEConnection* module, unsigned int recipient, unsigned int len, unsigned char *buffer);
bool LME_ChannelWindowAdjust(struct LMEConnection* module, unsigned int recipient, unsigned int len);
void LME_Deinit(struct LMEConnection* module);
void LME_Exit(struct LMEConnection* module);
unsigned int LME_GetMeiBufferSize(struct LMEConnection* module);
#define LME_UserAuthSuccess(module) LME_SendShortMessage(module, APF_USERAUTH_SUCCESS)
#define LME_TcpForwardReplyFailure(module) LME_SendShortMessage(module, APF_REQUEST_FAILURE)
#define LME_TcpForwardCancelReplySuccess(module) LME_SendShortMessage(module, APF_REQUEST_SUCCESS)
#define LME_TcpForwardCancelReplyFailure(module) LME_SendShortMessage(module, APF_REQUEST_FAILURE)
#endif
#endif

172
MicroLMS/heci/LMS_if.h Normal file
View File

@@ -0,0 +1,172 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef _MINCORE
#ifndef _LMS_IF_H_
#define _LMS_IF_H_
#include "LMS_if_constants.h"
#pragma pack(1)
typedef struct {
unsigned char MessageType;
} APF_MESSAGE_HEADER;
/**
* APF_GENERIC_HEADER - generic request header (note that its not complete header per protocol (missing WantReply)
*
* @MessageType:
* @RequestStringLength: length of the string identifies the request
* @RequestString: the string that identifies the request
**/
typedef struct {
unsigned char MessageType;
unsigned int StringLength;
unsigned char String[0];
} APF_GENERIC_HEADER;
/**
* TCP forward reply message
* @MessageType - Protocol's Major version
* @PortBound - the TCP port was bound on the server
**/
typedef struct {
unsigned char MessageType;
unsigned int PortBound;
} APF_TCP_FORWARD_REPLY_MESSAGE;
/**
* response to ChannelOpen when channel open succeed
* @MessageType - APF_CHANNEL_OPEN_CONFIRMATION
* @RecipientChannel - channel number given in the open request
* @SenderChannel - channel number assigned by the sender
* @InitialWindowSize - Number of bytes in the window
* @Reserved - Reserved
**/
typedef struct {
unsigned char MessageType;
unsigned int RecipientChannel;
unsigned int SenderChannel;
unsigned int InitialWindowSize;
unsigned int Reserved;
} APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE;
/**
* response to ChannelOpen when a channel open failed
* @MessageType - APF_CHANNEL_OPEN_FAILURE
* @RecipientChannel - channel number given in the open request
* @ReasonCode - code for the reason channel could not be open
* @Reserved - Reserved
**/
typedef struct {
unsigned char MessageType;
unsigned int RecipientChannel;
unsigned int ReasonCode;
unsigned int Reserved;
unsigned int Reserved2;
} APF_CHANNEL_OPEN_FAILURE_MESSAGE;
/**
* close channel message
* @MessageType - APF_CHANNEL_CLOSE
* @RecipientChannel - channel number given in the open request
**/
typedef struct {
unsigned char MessageType;
unsigned int RecipientChannel;
} APF_CHANNEL_CLOSE_MESSAGE;
/**
* used to send/receive data.
* @MessageType - APF_CHANNEL_DATA
* @RecipientChannel - channel number given in the open request
* @Length - Length of the data in the message
* @Data - The data in the message
**/
typedef struct {
unsigned char MessageType;
unsigned int RecipientChannel;
unsigned int DataLength;
// unsigned char Data[0];
} APF_CHANNEL_DATA_MESSAGE;
/**
* used to adjust receive window size.
* @MessageType - APF_WINDOW_ADJUST
* @RecipientChannel - channel number given in the open request
* @BytesToAdd - number of bytes to add to current window size value
**/
typedef struct {
unsigned char MessageType;
unsigned int RecipientChannel;
unsigned int BytesToAdd;
} APF_WINDOW_ADJUST_MESSAGE;
/**
* This message causes immediate termination of the connection with AMT.
* @ReasonCode - A Reason code for the disconnection event
* @Reserved - Reserved must be set to 0
**/
typedef struct {
unsigned char MessageType;
unsigned int ReasonCode;
unsigned short Reserved;
} APF_DISCONNECT_MESSAGE;
/**
* Used to request a service identified by name
* @ServiceNameLength - The length of the service name string.
* @ServiceName - The name of the service being requested.
**/
typedef struct {
unsigned char MessageType;
unsigned int ServiceNameLength;
unsigned char ServiceName[0];
} APF_SERVICE_REQUEST_MESSAGE;
/**
* Used to send a service accept identified by name
* @ServiceNameLength - The length of the service name string.
* @ServiceName - The name of the service being requested.
**/
typedef struct {
unsigned char MessageType;
unsigned int ServiceNameLength;
unsigned char ServiceName[0];
} APF_SERVICE_ACCEPT_MESSAGE;
/**
* holds the protocl major and minor version implemented by AMT.
* @MajorVersion - Protocol's Major version
* @MinorVersion - Protocol's Minor version
* @Trigger - The open session reason
* @UUID - System Id
**/
typedef struct {
unsigned char MessageType;
unsigned int MajorVersion;
unsigned int MinorVersion;
unsigned int TriggerReason;
unsigned char UUID[16];
unsigned char Reserved[64];
} APF_PROTOCOL_VERSION_MESSAGE;
/**
* holds the user authentication request success reponse.
**/
typedef struct {
unsigned char MessageType;
} APF_USERAUTH_SUCCESS_MESSAGE;
#pragma pack()
#endif
#endif

View File

@@ -0,0 +1,91 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef _MINCORE
#ifndef _LMS_IF_CONSTANTS_H_
#define _LMS_IF_CONSTANTS_H_
#define LMS_PROTOCOL_VERSION 4
//
// messages opcodes
//
typedef enum {
APF_DISCONNECT = 1,
APF_SERVICE_REQUEST = 5,
APF_SERVICE_ACCEPT = 6,
APF_USERAUTH_REQUEST = 50,
APF_USERAUTH_FAILURE = 51,
APF_USERAUTH_SUCCESS = 52,
APF_GLOBAL_REQUEST = 80,
APF_REQUEST_SUCCESS = 81,
APF_REQUEST_FAILURE = 82,
APF_CHANNEL_OPEN = 90,
APF_CHANNEL_OPEN_CONFIRMATION = 91,
APF_CHANNEL_OPEN_FAILURE = 92,
APF_CHANNEL_WINDOW_ADJUST = 93,
APF_CHANNEL_DATA = 94,
APF_CHANNEL_CLOSE = 97,
APF_PROTOCOLVERSION = 192
} APF_MESSAGE_TYPE;
typedef enum {
APF_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1,
APF_DISCONNECT_PROTOCOL_ERROR = 2,
APF_DISCONNECT_KEY_EXCHANGE_FAILED = 3,
APF_DISCONNECT_RESERVED = 4,
APF_DISCONNECT_MAC_ERROR = 5,
APF_DISCONNECT_COMPRESSION_ERROR = 6,
APF_DISCONNECT_SERVICE_NOT_AVAILABLE = 7,
APF_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED = 8,
APF_DISCONNECT_HOST_KEY_NOT_VERIFIABLE = 9,
APF_DISCONNECT_CONNECTION_LOST = 10,
APF_DISCONNECT_BY_APPLICATION = 11,
APF_DISCONNECT_TOO_MANY_CONNECTIONS = 12,
APF_DISCONNECT_AUTH_CANCELLED_BY_USER = 13,
APF_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 14,
APF_DISCONNECT_ILLEGAL_USER_NAME = 15
} APF_DISCONNECT_REASON_CODE;
//
//strings used in global messages
//
#define APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST "tcpip-forward"
#define APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST "cancel-tcpip-forward"
#define APF_GLOBAL_REQUEST_STR_UDP_SEND_TO "udp-send-to@amt.intel.com"
#define APF_OPEN_CHANNEL_REQUEST_FORWARDED "forwarded-tcpip"
#define APF_OPEN_CHANNEL_REQUEST_DIRECT "direct-tcpip"
// APF service names
#define APF_SERVICE_PFWD "pfwd@amt.intel.com"
#define APF_SERVICE_AUTH "auth@amt.intel.com"
// APF Authentication method
#define APF_AUTH_NONE "none"
#define APF_AUTH_PASSWORD "password"
//calculate string length without the NULL terminator
#define APF_STR_SIZE_OF(s) (sizeof(s)-1)
// Trigger reason code
typedef enum {
USER_INITIATED_REQUEST = 1,
ALERT_REQUEST = 2,
HIT_PROVISIONING_REQUEST = 3,
PERIODIC_REQUEST = 4,
LME_REQUEST = 254
} APF_TRIGGER_REASON;
typedef enum {
OPEN_FAILURE_REASON_ADMINISTRATIVELY_PROHIBITED = 1,
OPEN_FAILURE_REASON_CONNECT_FAILED = 2,
OPEN_FAILURE_REASON_UNKNOWN_CHANNEL_TYPE = 3,
OPEN_FAILURE_REASON_RESOURCE_SHORTAGE = 4
} OPEN_FAILURE_REASON;
#endif
#endif

1505
MicroLMS/heci/PTHICommand.c Normal file

File diff suppressed because it is too large Load Diff

836
MicroLMS/heci/PTHICommand.h Normal file
View File

@@ -0,0 +1,836 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef _MINCORE
//----------------------------------------------------------------------------
//
// File: PTHICommand.h
//
// Contents: header file of PTHICommand class
//
//----------------------------------------------------------------------------
#ifndef __PTHI_COMMAND_H__
#define __PTHI_COMMAND_H__
#include "StatusCodeDefinitions.h"
#ifdef WIN32
#include <windows.h>
#include "HECIwin.h"
#endif
#ifdef _POSIX
#include "HECILinux.h"
#endif
#define CERT_HASH_MAX_LENGTH 64
#define CERT_HASH_MAX_NUMBER 23
#define NET_TLS_CERT_PKI_MAX_SERIAL_NUMS 3
#define NET_TLS_CERT_PKI_MAX_SERIAL_NUM_LENGTH 16
#define MPS_HOSTNAME_LENGTH 256
#define CFG_MAX_ACL_USER_LENGTH 33
#define CFG_MAX_ACL_PWD_LENGTH 33
#pragma pack(1)
typedef struct _LOCAL_SYSTEM_ACCOUNT
{
// contain null terminated string
char username[CFG_MAX_ACL_USER_LENGTH];
// contain null terminated string
char password[CFG_MAX_ACL_PWD_LENGTH];
}LOCAL_SYSTEM_ACCOUNT;
#pragma pack()
/*
* Constants
*/
/*
static #define IDER_LOG_ENTRIES = 16;
const UINT8 MAJOR_VERSION = 1;
const UINT8 MINOR_VERSION = 1;
const UINT8 AMT_MAJOR_VERSION = 1;
const UINT8 AMT_MINOR_VERSION = 1;
*/
#define IDER_LOG_ENTRIES 16
#define MAJOR_VERSION 1
#define MINOR_VERSION 1
#define AMT_MAJOR_VERSION 1
#define AMT_MINOR_VERSION 1
typedef enum _CFG_PROVISIONING_MODE
{
CFG_PROVISIONING_MODE_NONE = 0,
CFG_PROVISIONING_MODE_ENTERPRISE,
CFG_PROVISIONING_MODE_SMALL_BUSINESS,
CFG_PROVISIONING_MODE_REMOTE_ASSISTANCE
} CFG_PROVISIONING_MODE;
typedef enum _AMT_PROVISIONING_STATE
{
PROVISIONING_STATE_PRE = 0,
PROVISIONING_STATE_IN = 1,
PROVISIONING_STATE_POST = 2
} AMT_PROVISIONING_STATE;
typedef enum _AMT_EHBC_STATE
{
EHBC_STATE_DISABLED = 0,
EHBC_STATE_ENABLED = 1
} AMT_EHBC_STATE;
typedef enum _AMT_FEATURE_STATE_REQUEST
{
REDIRECTION_SESSION = 0,
SYSTEM_DEFENSE = 1,
WEB_UI = 2
} AMT_FEATURE_STATE_REQUEST;
typedef enum _AMT_LAST_HOST_RESET_REASON
{
RemoteControl = 0,
Other = 1
} AMT_LAST_HOST_RESET_REASON;
typedef enum _AMT_INTERFACE_INDEX
{
WIRED = 0,
WIRELESS = 1
} AMT_INTERFACE_INDEX;
typedef enum _AMT_DHCP_IP_ADDRESS
{
ACTIVE = 1,
PASSIVE = 2
} AMT_DHCP_IP_MODE;
//typedef UINT32 CFG_IPv4_ADDRESS
#define CFG_IPv4_ADDRESS UINT32
/*
static #define BIOS_VERSION_LEN = 65;
static #define VERSIONS_NUMBER = 50;
static #define UNICODE_STRING_LEN = 20;
*/
#define BIOS_VERSION_LEN 65
#define VERSIONS_NUMBER 50
#define UNICODE_STRING_LEN 20
typedef enum _AMT_PROVISIONING_TLS_MODE
{
NOT_READY = 0,
PSK = 1,
PKI = 2
} AMT_PROVISIONING_TLS_MODE;
typedef enum _AMT_RNG_STATUS
{
RNG_STATUS_EXIST = 0,
RNG_STATUS_IN_PROGRESS = 1,
RNG_STATUS_NOT_EXIST = 2
} AMT_RNG_STATUS;
#pragma pack(1)
typedef struct _AMT_UNICODE_STRING
{
UINT16 Length;
UINT8 String[UNICODE_STRING_LEN];
} AMT_UNICODE_STRING;
typedef struct _AMT_VERSION_TYPE
{
AMT_UNICODE_STRING Description;
AMT_UNICODE_STRING Version;
} AMT_VERSION_TYPE;
typedef struct _PTHI_VERSION
{
UINT8 MajorNumber;
UINT8 MinorNumber;
} PTHI_VERSION;
typedef struct _CODE_VERSIONS
{
UINT8 BiosVersion[BIOS_VERSION_LEN];
UINT32 VersionsCount;
AMT_VERSION_TYPE Versions[VERSIONS_NUMBER];
} CODE_VERSIONS;
typedef struct _COMMAND_FMT
{
union
{
UINT32 val;
struct
{
UINT32 Operation : 23;
UINT32 IsResponse : 1;
UINT32 Class : 8;
} fields;
} cmd;
} COMMAND_FMT;
typedef struct _AMT_ANSI_STRING
{
UINT16 Length;
CHAR *Buffer;
} AMT_ANSI_STRING;
typedef struct _PTHI_MESSAGE_HEADER
{
PTHI_VERSION Version;
UINT16 Reserved;
COMMAND_FMT Command;
UINT32 Length;
} PTHI_MESSAGE_HEADER;
typedef struct _PTHI_RESPONSE_MESSAGE_HEADER
{
PTHI_MESSAGE_HEADER Header;
AMT_STATUS Status;
} PTHI_RESPONSE_MESSAGE_HEADER;
typedef struct _CFG_GET_CODE_VERSIONS_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
CODE_VERSIONS CodeVersions;
} CFG_GET_CODE_VERSIONS_RESPONSE;
typedef struct _CFG_GET_PROVISIONING_MODE_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
CFG_PROVISIONING_MODE ProvisioningMode;
AMT_BOOLEAN LegacyMode;
} CFG_GET_PROVISIONING_MODE_RESPONSE;
typedef struct _CFG_GET_PROVISIONING_STATE_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_PROVISIONING_STATE ProvisioningState;
} CFG_GET_PROVISIONING_STATE_RESPONSE;
typedef struct _CFG_GET_MAC_ADDRESSES_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
UINT8 DedicatedMac[6];
UINT8 HostMac[6];
} CFG_GET_MAC_ADDRESSES_RESPONSE;
typedef struct _CFG_GET_FEATURES_STATE_REQUEST
{
PTHI_MESSAGE_HEADER Header;
UINT32 RequestID;
} CFG_GET_FEATURES_STATE_REQUEST;
typedef struct _GET_FEATURES_REDIRECTION_SESSION_STATUS
{
AMT_BOOLEAN IderOpen;
AMT_BOOLEAN SolOpen;
AMT_BOOLEAN Reserved;
} GET_FEATURES_REDIRECTION_SESSION_STATUS;
typedef struct _GET_FEATURES_SYSTEM_DEFENSE_STATE_RESPONSE
{
AMT_BOOLEAN SystemDefenseActivated;
} GET_FEATURES_SYSTEM_DEFENSE_STATUS_RESPONSE;
typedef struct _GET_FEATURES_WEB_UI_STATE_RESPONSE
{
AMT_BOOLEAN WebUiEnabled;
} GET_FEATURES_WEB_UI_STATUS_RESPONSE;
typedef union _FEATURES_STATUS_DATA
{
GET_FEATURES_REDIRECTION_SESSION_STATUS rs;
GET_FEATURES_SYSTEM_DEFENSE_STATUS_RESPONSE sd;
GET_FEATURES_WEB_UI_STATUS_RESPONSE webUI;
} FEATURES_STATUS_DATA;
typedef struct _CFG_GET_FEATURES_STATE_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
UINT32 RequestID;
FEATURES_STATUS_DATA Data;
} CFG_GET_FEATURES_STATE_RESPONSE;
typedef struct _CFG_GET_CURRENT_POWER_POLICY_REQUEST
{
PTHI_MESSAGE_HEADER Header;
} CFG_GET_CURRENT_POWER_POLICY_REQUEST;
typedef struct _CFG_GET_CURRENT_POWER_POLICY_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_ANSI_STRING PolicyName;
} CFG_GET_CURRENT_POWER_POLICY_RESPONSE;
typedef struct _CFG_GET_LAST_HOST_RESET_REASON_REQUEST
{
PTHI_MESSAGE_HEADER Header;
} CFG_GET_LAST_HOST_RESET_REASON_REQUEST;
typedef struct _CFG_GET_LAST_HOST_RESET_REASON_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
UINT32 Reason;
UINT32 RemoteControlTimeStamp;
} CFG_GET_LAST_HOST_RESET_REASON_RESPONSE;
typedef struct _LAN_SETTINGS
{
AMT_BOOLEAN Enabled;
CFG_IPv4_ADDRESS Ipv4Address;
AMT_BOOLEAN DhcpEnabled;
UINT8 DhcpIpMode;
UINT8 LinkStatus;
UINT8 MacAddress[6];
} LAN_SETTINGS;
typedef struct _CFG_GET_LAN_INTERFACE_SETTINGS_REQUEST
{
PTHI_MESSAGE_HEADER Header;
UINT32 InterfaceIndex;
} CFG_GET_LAN_INTERFACE_SETTINGS_REQUEST;
typedef struct _CFG_GET_LAN_INTERFACE_SETTINGS_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_BOOLEAN Enabled;
CFG_IPv4_ADDRESS Ipv4Address;
AMT_BOOLEAN DhcpEnabled;
UINT8 DhcpIpMode;
UINT8 LinkStatus;
UINT8 MacAddress[6];
} CFG_GET_LAN_INTERFACE_SETTINGS_RESPONSE;
typedef struct _CFG_GET_SECURITY_PARAMETERS_REQUEST
{
PTHI_MESSAGE_HEADER Header;
} CFG_GET_SECURITY_PARAMETERS_REQUEST;
typedef struct _CFG_GET_SECURITY_PARAMETERS_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_BOOLEAN EnterpriseMode;
AMT_BOOLEAN TLSEnabled;
AMT_BOOLEAN HWCryptoEnabled;
AMT_PROVISIONING_STATE ProvisioningState;
AMT_BOOLEAN NetworkInterfaceEnabled;
AMT_BOOLEAN SOLEnabled;
AMT_BOOLEAN IDEREnabled;
AMT_BOOLEAN FWUpdateEnabled;
AMT_BOOLEAN LinkIsUp;
AMT_BOOLEAN Reserved[8];
} CFG_GET_SECURITY_PARAMETERS_RESPONSE;
typedef struct _CFG_GET_DNS_SUFFIX_LIST_REQUEST
{
PTHI_MESSAGE_HEADER Header;
} CFG_GET_DNS_SUFFIX_LIST_REQUEST;
typedef struct _CFG_GET_DNS_SUFFIX_LIST_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
UINT16 DataLength;
UINT8 Data[0];
} CFG_GET_DNS_SUFFIX_LIST_RESPONSE;
/**
* CFG_SET_ENTERPRISE_ACCESS_REQUEST
*
* Flags Bit 0 - If this bit is set then HostIPAddress is IPv6, otherwise HostIPAddress is IPv4 address.
* Bits 1..7 - Reserved, should be zero.
* HostIPAddress IPv4 / IPv6 address
* EnterpriseAccess 1 if LMS has access to enterprise network, otherwise 0.
*/
typedef struct _CFG_SET_ENTERPRISE_ACCESS_REQUEST
{
PTHI_MESSAGE_HEADER Header;
UINT8 Flags;
UINT8 HostIPAddress[16];
UINT8 EnterpriseAccess;
} CFG_SET_ENTERPRISE_ACCESS_REQUEST;
typedef struct _CFG_SET_ENTERPRISE_ACCESS_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
} CFG_SET_ENTERPRISE_ACCESS_RESPONSE;
typedef struct _CFG_OPEN_USER_INITIATED_CONNECTION_REQUEST
{
PTHI_MESSAGE_HEADER Header;
} CFG_OPEN_USER_INITIATED_CONNECTION_REQUEST;
typedef struct _CFG_OPEN_USER_INITIATED_CONNECTION_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
} CFG_OPEN_USER_INITIATED_CONNECTION_RESPONSE;
typedef struct _CFG_CLOSE_USER_INITIATED_CONNECTION_REQUEST
{
PTHI_MESSAGE_HEADER Header;
} CFG_CLOSE_USER_INITIATED_CONNECTION_REQUEST;
typedef struct _CFG_CLOSE_USER_INITIATED_CONNECTION_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
} CFG_CLOSE_USER_INITIATED_CONNECTION_RESPONSE;
typedef enum
{
AMT_NETWORK_CONNECTION_DIRECT = 0,
AMT_NETWORK_CONNECTION_VPN,
AMT_NETWORK_CONNECTION_OUTSIDE_ENTERPRISE
} AMT_NETWORK_CONNECTION_STATUS;
typedef enum
{
REMOTE_ACCESS_CONNECTION_STATUS_NOT_CONNECTED = 0,
REMOTE_ACCESS_CONNECTION_STATUS_CONNECTING,
REMOTE_ACCESS_CONNECTION_STATUS_CONNECTED
} REMOTE_ACCESS_CONNECTION_STATUS;
typedef enum
{
REMOTE_ACCESS_CONNECTION_TRIGGER_USER_INITIATED = 0,
REMOTE_ACCESS_CONNECTION_TRIGGER_ALERT,
REMOTE_ACCESS_CONNECTION_TRIGGER_PROVISIONING,
REMOTE_ACCESS_CONNECTION_TRIGGER_PERIODIC
} REMOTE_ACCESS_CONNECTION_TRIGGER;
typedef struct _CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_REQUEST
{
PTHI_MESSAGE_HEADER Header;
} CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_REQUEST;
typedef struct _CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_NETWORK_CONNECTION_STATUS AmtNetworkConnectionStatus;
REMOTE_ACCESS_CONNECTION_STATUS RemoteAccessConnectionStatus;
REMOTE_ACCESS_CONNECTION_TRIGGER RemoteAccessConnectionTrigger;
AMT_ANSI_STRING MpsHostname;
} CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE;
typedef struct _REMOTE_ACCESS_STATUS
{
AMT_NETWORK_CONNECTION_STATUS AmtNetworkConnectionStatus;
REMOTE_ACCESS_CONNECTION_STATUS RemoteAccessConnectionStatus;
REMOTE_ACCESS_CONNECTION_TRIGGER RemoteAccessConnectionTrigger;
AMT_ANSI_STRING MpsHostname;
} REMOTE_ACCESS_STATUS;
typedef UINT8 AMT_UUID[16];
//const AMT_UUID AMT_UUID_LINK_STATE;
typedef struct _STATE_DATA
{
UINT8 LinkStatus; // (0 - down; 1 - up)
UINT8 HardSKU;
UINT8 CryptoFuse; // (0 - disabled; 1 - enabled)
UINT8 FlashProtaction; // (0 - disabled; 1 - enabled)
UINT8 LastMEResetReason;
} STATE_DATA;
typedef struct _STATE_GET_AMT_STATE_REQUEST
{
PTHI_MESSAGE_HEADER Header;
AMT_UUID StateVariableIdentifier;
} STATE_GET_AMT_STATE_REQUEST;
typedef struct _STATE_GET_AMT_STATE_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_UUID StateDataIdentifier;
UINT32 ByteCount;
STATE_DATA StateData;
} STATE_GET_AMT_STATE_RESPONSE;
typedef struct _AMT_HASH_HANDLES
{
UINT32 Length;
UINT32 Handles[CERT_HASH_MAX_NUMBER];
} AMT_HASH_HANDLES;
typedef struct _CERTHASH_ENTRY
{
AMT_BOOLEAN IsDefault;
AMT_BOOLEAN IsActive;
UINT8 CertificateHash[CERT_HASH_MAX_LENGTH];
UINT8 HashAlgorithm;
AMT_ANSI_STRING Name;
} CERTHASH_ENTRY;
typedef enum
{
CERT_HASH_ALGORITHM_MD5 = 0, // 16 bytes
CERT_HASH_ALGORITHM_SHA1, // 20 bytes
CERT_HASH_ALGORITHM_SHA256, // 32 bytes
CERT_HASH_ALGORITHM_SHA512, // 64 bytes
} CERT_HASH_ALGORITHM;
typedef struct
{
UINT16 Year;
UINT16 Month;
UINT16 DayOfWeek;
UINT16 Day;
UINT16 Hour;
UINT16 Minute;
UINT16 Second;
} TIME_DATE;
typedef struct _AMT_PROV_AUDIT_RECORD
{
UINT8 ProvisioningTLSMode;
AMT_BOOLEAN SecureDNS;
AMT_BOOLEAN HostInitiated;
CERT_HASH_ALGORITHM SelectedHashType;
UINT8 SelectedHashData[CERT_HASH_MAX_LENGTH];
UINT8 CaCertificateSerials[NET_TLS_CERT_PKI_MAX_SERIAL_NUMS*NET_TLS_CERT_PKI_MAX_SERIAL_NUM_LENGTH];
AMT_BOOLEAN AdditionalCaSerialNums;
AMT_BOOLEAN IsOemDefault;
AMT_BOOLEAN IsTimeValid;
UINT32 ProvServerIP;
TIME_DATE TlsStartTime;
AMT_ANSI_STRING ProvServerFQDN;
} AMT_PROV_AUDIT_RECORD;
typedef struct
{
PTHI_MESSAGE_HEADER Header;
AMT_STATUS Status;
AMT_BOOLEAN SharedFQDN;
AMT_BOOLEAN DDNSUpdateEnabled;
UINT32 DDNSPeriodicUpdateInterval;
UINT32 DDNSTTL;
UINT32 HostNameLength;
AMT_ANSI_STRING FQDN;
} CFG_GET_FQDN_RESPONSE;
typedef struct _CFG_GENERATE_RNG_SEED_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
} CFG_GENERATE_RNG_SEED_RESPONSE;
typedef struct _CFG_GET_RNG_SEED_STATUS_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_RNG_STATUS RngStatus;
} CFG_GET_RNG_SEED_STATUS_RESPONSE;
typedef struct _CFG_GET_ZERO_TOUCH_ENABLED_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_BOOLEAN ZeroTouchEnabled;
} CFG_GET_ZERO_TOUCH_ENABLED_RESPONSE;
typedef struct _CFG_GET_PROVISIONING_TLS_MODE_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_PROVISIONING_TLS_MODE ProvisioningTlsMode;
} CFG_GET_PROVISIONING_TLS_MODE_RESPONSE;
typedef struct _CFG_START_CONFIGURATION_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
} CFG_START_CONFIGURATION_RESPONSE;
typedef struct _CFG_STOP_CONFIGURATION_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
} CFG_STOP_CONFIGURATION_RESPONSE;
typedef struct _CFG_SET_PROVISIONING_SERVER_OTP_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
} CFG_SET_PROVISIONING_SERVER_OTP_RESPONSE;
typedef struct _CFG_SET_DNS_SUFFIX_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
} CFG_SET_DNS_SUFFIX_RESPONSE;
typedef struct _CFG_GET_HASH_HANDLES_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_HASH_HANDLES HashHandles;
} CFG_GET_HASH_HANDLES_RESPONSE;
typedef struct _CFG_GET_CERTHASH_ENTRY_REQUEST
{
PTHI_MESSAGE_HEADER Header;
UINT32 HashHandle;
} CFG_GET_CERTHASH_ENTRY_REQUEST;
typedef struct _CFG_GET_CERTHASH_ENTRY_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
CERTHASH_ENTRY Hash;
} CFG_GET_CERTHASH_ENTRY_RESPONSE;
typedef struct _CFG_GET_PKI_FQDN_SUFFIX_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_ANSI_STRING Suffix;
} CFG_GET_PKI_FQDN_SUFFIX_RESPONSE;
typedef struct CFG_SET_HOST_FQDN_REQUEST
{
PTHI_MESSAGE_HEADER Header;
UINT16 FQDNL;
char FQDN[256];
}CFG_SET_HOST_FQDN_REQUEST;
typedef struct CFG_GET_HOST_FQDN_REQUEST
{
PTHI_MESSAGE_HEADER Header;
} CFG_GET_HOST_FQDN_REQUEST;
typedef struct _CFG_SET_HOST_FQDN_RESPONSE
{
PTHI_MESSAGE_HEADER Header;
AMT_STATUS Status;
} CFG_SET_HOST_FQDN_RESPONSE;
typedef struct _CFG_GET_LOCAL_SYSTEM_ACCOUNT_RESPONSE
{
PTHI_MESSAGE_HEADER Header;
AMT_STATUS Status;
LOCAL_SYSTEM_ACCOUNT Account;
} CFG_GET_LOCAL_SYSTEM_ACCOUNT_RESPONSE;
typedef struct _CFG_GET_LOCAL_SYSTEM_ACCOUNT_REQUEST
{
PTHI_MESSAGE_HEADER Header;
UINT8 Reserved[40];
} CFG_GET_LOCAL_SYSTEM_ACCOUNT_REQUEST;
typedef struct _CFG_UNPROVISION_RESPONSE
{
PTHI_MESSAGE_HEADER Header;
AMT_STATUS Status;
} CFG_UNPROVISION_RESPONSE;
typedef struct _CFG_UNPROVISION_REQUEST
{
PTHI_MESSAGE_HEADER Header;
UINT32 Mode;
} CFG_UNPROVISION_REQUEST;
typedef struct _CFG_GETEHBPSTATE_REQUEST
{
PTHI_MESSAGE_HEADER Header;
} CFG_GETEHBPSTATE_REQUEST;
typedef struct _CFG_GETEHBPSTATE_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_EHBC_STATE EHBCState;
} CFG_GETEHBPSTATE_RESPONSE;
typedef struct _CFG_GET_CONTROL_MODE_REQUEST
{
PTHI_MESSAGE_HEADER Header;
} CFG_GET_CONTROL_MODE_REQUEST;
typedef struct _CFG_GET_CONTROL_MODE_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
int state;
} CFG_GET_CONTROL_MODE_RESPONSE;
typedef struct _CFG_GET_UUID_REQUEST
{
PTHI_MESSAGE_HEADER Header;
} CFG_GET_UUID_REQUEST;
typedef struct _CFG_GET_UUID_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
AMT_UUID UUID;
} CFG_GET_UUID_RESPONSE;
#pragma pack()
AMT_STATUS pthi_GetCodeVersions(CODE_VERSIONS *codeVersions);
AMT_STATUS pthi_GetProvisioningMode(CFG_PROVISIONING_MODE *provisioningMode, AMT_BOOLEAN *legacy);
AMT_STATUS pthi_GetProvisioningState(AMT_PROVISIONING_STATE *state);
AMT_STATUS pthi_GetMacAddresses(UINT8 DedicatedMac[6], UINT8 HostMac[6]);
AMT_STATUS pthi_GetFeaturesState(UINT32 requestID, AMT_BOOLEAN (*requestStatus)[2]);
AMT_STATUS pthi_GetLastHostResetReason(UINT32 *Reason, UINT32 *RemoteControlTimeStamp);
AMT_STATUS pthi_GetCurrentPowerPolicy(AMT_ANSI_STRING *policyName);
AMT_STATUS pthi_GetLanInterfaceSettings(UINT32 interfaceSettings, LAN_SETTINGS *lanSettings);
AMT_STATUS pthi_GetHeciVersion(HECI_VERSION *hecVersion);
AMT_STATUS pthi_GetTLSEnabled(AMT_BOOLEAN *tlsEnabled);
//AMT_STATUS pthi_GetDNSSuffixList(std::list<std::string> *dnsSuffixList);
AMT_STATUS pthi_SetEnterpriseAccess(UINT8 Flags, UINT8 HostIPAddress[16], UINT8 EnterpriseAccess);
AMT_STATUS pthi_GetFWResetReason(UINT8 *MEResetReason);
AMT_STATUS pthi_OpenUserInitiatedConnection();
AMT_STATUS pthi_CloseUserInitiatedConnection();
AMT_STATUS pthi_GetRemoteAccessConnectionStatus(REMOTE_ACCESS_STATUS *remoteAccessStatus);
AMT_STATUS pthi_GenerateRngKey();
AMT_STATUS pthi_GetRngSeedStatus(AMT_RNG_STATUS *rngStatus);
AMT_STATUS pthi_GetZeroTouchEnabled(AMT_BOOLEAN *zeroTouchEnabled);
AMT_STATUS pthi_GetProvisioningTlsMode(AMT_PROVISIONING_TLS_MODE *provisioningTlsMode);
AMT_STATUS pthi_StartConfiguration();
AMT_STATUS pthi_StopConfiguration();
AMT_STATUS pthi_SetProvisioningServerOTP(AMT_ANSI_STRING passwordOTP);
AMT_STATUS pthi_SetDnsSuffix(AMT_ANSI_STRING dnsSuffix);
AMT_STATUS pthi_EnumerateHashHandles(AMT_HASH_HANDLES *hashHandles);
AMT_STATUS pthi_GetCertificateHashEntry(UINT32 hashHandle, CERTHASH_ENTRY *hashEntry);
AMT_STATUS pthi_GetDnsSuffix(AMT_ANSI_STRING *dnsSuffix);
AMT_STATUS pthi_SetHostFQDN(char* str);
AMT_STATUS pthi_GetHostFQDN(CFG_GET_FQDN_RESPONSE* fqdn);
AMT_STATUS pthi_GetLocalSystemAccount(LOCAL_SYSTEM_ACCOUNT *localAccount);
AMT_STATUS pthi_Unprovision(CFG_PROVISIONING_MODE provisionMode);
AMT_STATUS pthi_GetStateEHBC(AMT_EHBC_STATE *state);
AMT_STATUS pthi_GetControlMode(int *state);
AMT_STATUS pthi_GetUUID(AMT_UUID *uuid);
#define PROVISIONING_MODE_REQUEST 0x04000008
#define PROVISIONING_MODE_RESPONSE 0x04800008
const PTHI_MESSAGE_HEADER GET_PROVISIONING_MODE_HEADER;
#define UNPROVISION_REQUEST 0x04000010
#define UNPROVISION_RESPONSE 0x04800010
const PTHI_MESSAGE_HEADER UNPROVISION_HEADER;
#define PROVISIONING_STATE_REQUEST 0x04000011
#define PROVISIONING_STATE_RESPONSE 0x04800011
const PTHI_MESSAGE_HEADER GET_PROVISIONING_STATE_HEADER;
#define CODE_VERSIONS_REQUEST 0x0400001A
#define CODE_VERSIONS_RESPONSE 0x0480001A
const PTHI_MESSAGE_HEADER GET_CODE_VERSION_HEADER;
#define GET_SECURITY_PARAMETERS_REQUEST 0x0400001B
#define GET_SECURITY_PARAMETERS_RESPONSE 0x0480001B
//const PTHI_MESSAGE_HEADER GET_SECURITY_PARAMETERS_HEADER;
#define GET_MAC_ADDRESSES_REQUEST 0x04000025
#define GET_MAC_ADDRESSES_RESPONSE 0x04800025
const PTHI_MESSAGE_HEADER GET_MAC_ADDRESSES_HEADER;
#define GENERATE_RNG_SEED_REQUEST 0x04000028
#define GENERATE_RNG_SEED_RESPONSE 0x04800028
//const PTHI_MESSAGE_HEADER GENERATE_RNG_SEED_HEADER;
#define SET_PROVISIONING_SERVER_OTP_REQUEST 0x0400002A
#define SET_PROVISIONING_SERVER_OTP_RESPONSE 0x0480002A
#define SET_DNS_SUFFIX_REQUEST 0x0400002F
#define SET_DNS_SUFFIX_RESPONSE 0x0480002F
#define ENUMERATE_HASH_HANDLES_REQUEST 0x0400002C
#define ENUMERATE_HASH_HANDLES_RESPONSE 0x0480002C
//const PTHI_MESSAGE_HEADER ENUMERATE_HASH_HANDLES_HEADER;
#define GET_RNG_SEED_STATUS_REQUEST 0x0400002E
#define GET_RNG_SEED_STATUS_RESPONSE 0x0480002E
//const PTHI_MESSAGE_HEADER GET_RNG_SEED_STATUS_HEADER;
#define GET_DNS_SUFFIX_LIST_REQUEST 0x0400003E
#define GET_DNS_SUFFIX_LIST_RESPONSE 0x0480003E
//const PTHI_MESSAGE_HEADER GET_DNS_SUFFIX_LIST_HEADER;
#define SET_ENTERPRISE_ACCESS_REQUEST 0x0400003F
#define SET_ENTERPRISE_ACCESS_RESPONSE 0x0480003F
//const PTHI_MESSAGE_HEADER SET_ENTERPRISE_ACCESS_HEADER;
#define OPEN_USER_INITIATED_CONNECTION_REQUEST 0x04000044
#define OPEN_USER_INITIATED_CONNECTION_RESPONSE 0x04800044
//const PTHI_MESSAGE_HEADER OPEN_USER_INITIATED_CONNECTION_HEADER;
#define CLOSE_USER_INITIATED_CONNECTION_REQUEST 0x04000045
#define CLOSE_USER_INITIATED_CONNECTION_RESPONSE 0x04800045
//const PTHI_MESSAGE_HEADER CLOSE_USER_INITIATED_CONNECTION_HEADER;
#define GET_REMOTE_ACCESS_CONNECTION_STATUS_REQUEST 0x04000046
#define GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE 0x04800046
//const PTHI_MESSAGE_HEADER GET_REMOTE_ACCESS_CONNECTION_STATUS_HEADER;
#define GET_CURRENT_POWER_POLICY_REQUEST 0x04000047
#define GET_CURRENT_POWER_POLICY_RESPONSE 0x04800047
const PTHI_MESSAGE_HEADER GET_CURRENT_POWER_POLICY_HEADER;
#define GET_LAN_INTERFACE_SETTINGS_REQUEST 0x04000048
#define GET_LAN_INTERFACE_SETTINGS_RESPONSE 0x04800048
//const PTHI_MESSAGE_HEADER GET_LAN_INTERFACE_SETTINGS_HEADER;
#define GET_FEATURES_STATE_REQUEST 0x04000049
#define GET_FEATURES_STATE_RESPONSE 0x04800049
const PTHI_MESSAGE_HEADER GET_FEATURES_STATE_HEADER;
#define GET_LAST_HOST_RESET_REASON_REQUEST 0x0400004A
#define GET_LAST_HOST_RESET_REASON_RESPONSE 0x0480004A
//const PTHI_MESSAGE_HEADER GET_LAST_HOST_RESET_REASON_HEADER;
#define GET_AMT_STATE_REQUEST 0x01000001
#define GET_AMT_STATE_RESPONSE 0x01800001
//const PTHI_MESSAGE_HEADER GET_AMT_STATE_HEADER;
#define GET_ZERO_TOUCH_ENABLED_REQUEST 0x04000030
#define GET_ZERO_TOUCH_ENABLED_RESPONSE 0x04800030
//const PTHI_MESSAGE_HEADER GET_ZERO_TOUCH_ENABLED_HEADER;
#define GET_PROVISIONING_TLS_MODE_REQUEST 0x0400002B
#define GET_PROVISIONING_TLS_MODE_RESPONSE 0x0480002B
//const PTHI_MESSAGE_HEADER GET_PROVISIONING_TLS_MODE_HEADER;
#define START_CONFIGURATION_REQUEST 0x04000029
#define START_CONFIGURATION_RESPONSE 0x04800029
//const PTHI_MESSAGE_HEADER START_CONFIGURATION_HEADER;
#define GET_CERTHASH_ENTRY_REQUEST 0x0400002D
#define GET_CERTHASH_ENTRY_RESPONSE 0x0480002D
//const PTHI_MESSAGE_HEADER GET_CERTHASH_ENTRY_HEADER;
#define GET_PKI_FQDN_SUFFIX_REQUEST 0x04000036
#define GET_PKI_FQDN_SUFFIX_RESPONSE 0x04800036
//
#define SET_HOST_FQDN_REQUEST 0x0400005b
#define SET_HOST_FQDN_RESPONSE 0x0480005b
//const PTHI_MESSAGE_HEADER GET_PKI_FQDN_SUFFIX_HEADER;
#define GET_FQDN_REQUEST 0x4000056
#define GET_FQDN_RESPONSE 0x4800056
#define GET_LOCAL_SYSTEM_ACCOUNT_REQUEST 0x04000067
#define GET_LOCAL_SYSTEM_ACCOUNT_RESPONSE 0x04800067
//const PTHI_MESSAGE_HEADER GET_LOCAL_SYSTEM_ACCOUNT_HEADER;
#define GET_EHBC_STATE_REQUEST 0x4000084
#define GET_EHBC_STATE_RESPONSE 0x4800084
const PTHI_MESSAGE_HEADER GET_EHBC_STATE_HEADER;
#define GET_CONTROL_MODE_REQUEST 0x400006b
#define GET_CONTROL_MODE_RESPONSE 0x480006b
const PTHI_MESSAGE_HEADER GET_CONTROL_MODE_HEADER;
#define STOP_CONFIGURATION_REQUEST 0x400005e
#define STOP_CONFIGURATION_RESPONSE 0x480005e
#define GET_UUID_REQUEST 0x400005c
#define GET_UUID_RESPONSE 0x480005c
#endif
#endif

View File

@@ -0,0 +1,402 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef _MINCORE
//----------------------------------------------------------------------------
//
// File: StatusCodeDefinitions.h
//
// Notes: This file contains the definitions of the status codes
// as defined in the Intel<65> AMT Network Design Guide.
//
//----------------------------------------------------------------------------
#ifndef STATUS_CODE_DEFINITIONS_H
#define STATUS_CODE_DEFINITIONS_H
typedef unsigned int PT_STATUS;
//typedef unsigned int AMT_STATUS;
//Request succeeded
#define PT_STATUS_SUCCESS 0x0
#define AMT_STATUS_SUCCESS 0x0
//An internal error in the Intel<65> AMT device has occurred
#define PT_STATUS_INTERNAL_ERROR 0x1
#define AMT_STATUS_INTERNAL_ERROR 0x1
//Intel<65> AMT device has not progressed far enough in its
//initialization to process the command.
#define PT_STATUS_NOT_READY 0x2
#define AMT_STATUS_NOT_READY 0x2
//Command is not permitted in current operating mode.
#define PT_STATUS_INVALID_PT_MODE 0x3
#define AMT_STATUS_INVALID_PT_MODE 0x3
//Length field of header is invalid.
#define PT_STATUS_INVALID_MESSAGE_LENGTH 0x4
#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4
//The requested hardware asset inventory table
//checksum is not available.
#define PT_STATUS_TABLE_FINGERPRINT_NOT_AVAILABLE 0x5
#define AMT_STATUS_TABLE_FINGERPRINT_NOT_AVAILABLE 0x5
//The Integrity Check Value field of the request
//message sent by Intel<65> AMT enabled device is invalid.
#define PT_STATUS_INTEGRITY_CHECK_FAILED 0x6
#define AMT_STATUS_INTEGRITY_CHECK_FAILED 0x6
//The specified ISV version is not supported
#define PT_STATUS_UNSUPPORTED_ISVS_VERSION 0x7
#define AMT_STATUS_UNSUPPORTED_ISVS_VERSION 0x7
//The specified queried application is not registered.
#define PT_STATUS_APPLICATION_NOT_REGISTERED 0x8
#define AMT_STATUS_APPLICATION_NOT_REGISTERED 0x8
//Either an invalid name or a not previously registered
//<2F>Enterprise<73> name was specified
#define PT_STATUS_INVALID_REGISTRATION_DATA 0x9
#define AMT_STATUS_INVALID_REGISTRATION_DATA 0x9
//The application handle provided in the request
//message has never been allocated.
#define PT_STATUS_APPLICATION_DOES_NOT_EXIST 0xA
#define AMT_STATUS_APPLICATION_DOES_NOT_EXIST 0xA
//The requested number of bytes cannot be allocated in ISV storage.
#define PT_STATUS_NOT_ENOUGH_STORAGE 0xB
#define AMT_STATUS_NOT_ENOUGH_STORAGE 0xB
//The specified name is invalid.
#define PT_STATUS_INVALID_NAME 0xC
#define AMT_STATUS_INVALID_NAME 0xC
//The specified block does not exist.
#define PT_STATUS_BLOCK_DOES_NOT_EXIST 0xD
#define AMT_STATUS_BLOCK_DOES_NOT_EXIST 0xD
//The specified byte offset is invalid.
#define PT_STATUS_INVALID_BYTE_OFFSET 0xE
#define AMT_STATUS_INVALID_BYTE_OFFSET 0xE
//The specified byte count is invalid.
#define PT_STATUS_INVALID_BYTE_COUNT 0xF
#define AMT_STATUS_INVALID_BYTE_COUNT 0xF
//The requesting application is not
//permitted to request execution of the specified operation.
#define PT_STATUS_NOT_PERMITTED 0x10
#define AMT_STATUS_NOT_PERMITTED 0x10
//The requesting application is not the owner of the block
//as required for the requested operation.
#define PT_STATUS_NOT_OWNER 0x11
#define AMT_STATUS_NOT_OWNER 0x11
//The specified block is locked by another application.
#define PT_STATUS_BLOCK_LOCKED_BY_OTHER 0x12
#define AMT_STATUS_BLOCK_LOCKED_BY_OTHER 0x12
//The specified block is not locked.
#define PT_STATUS_BLOCK_NOT_LOCKED 0x13
#define AMT_STATUS_BLOCK_NOT_LOCKED 0x13
//The specified group permission bits are invalid.
#define PT_STATUS_INVALID_GROUP_PERMISSIONS 0x14
#define AMT_STATUS_INVALID_GROUP_PERMISSIONS 0x14
//The specified group does not exist.
#define PT_STATUS_GROUP_DOES_NOT_EXIST 0x15
#define AMT_STATUS_GROUP_DOES_NOT_EXIST 0x15
//The specified member count is invalid.
#define PT_STATUS_INVALID_MEMBER_COUNT 0x16
#define AMT_STATUS_INVALID_MEMBER_COUNT 0x16
//The request cannot be satisfied because a maximum
//limit associated with the request has been reached.
#define PT_STATUS_MAX_LIMIT_REACHED 0x17
#define AMT_STATUS_MAX_LIMIT_REACHED 0x17
//specified key algorithm is invalid.
#define PT_STATUS_INVALID_AUTH_TYPE 0x18
#define AMT_STATUS_INVALID_AUTH_TYPE 0x18
//Not Used
#define PT_STATUS_AUTHENTICATION_FAILED 0x19
#define AMT_STATUS_AUTHENTICATION_FAILED 0x19
//The specified DHCP mode is invalid.
#define PT_STATUS_INVALID_DHCP_MODE 0x1A
#define AMT_STATUS_INVALID_DHCP_MODE 0x1A
//The specified IP address is not a valid IP unicast address.
#define PT_STATUS_INVALID_IP_ADDRESS 0x1B
#define AMT_STATUS_INVALID_IP_ADDRESS 0x1B
//The specified domain name is not a valid domain name.
#define PT_STATUS_INVALID_DOMAIN_NAME 0x1C
#define AMT_STATUS_INVALID_DOMAIN_NAME 0x1C
//Not Used
#define PT_STATUS_UNSUPPORTED_VERSION 0x1D
#define AMT_STATUS_UNSUPPORTED_VERSION 0x1D
//The requested operation cannot be performed because a
//prerequisite request message has not been received.
#define PT_STATUS_REQUEST_UNEXPECTED 0x1E
#define AMT_STATUS_REQUEST_UNEXPECTED 0x1E
//Not Used
#define PT_STATUS_INVALID_TABLE_TYPE 0x1F
#define AMT_STATUS_INVALID_TABLE_TYPE 0x1F
//The specified provisioning mode code is undefined.
#define PT_STATUS_INVALID_PROVISIONING_STATE 0x20
#define AMT_STATUS_INVALID_PROVISIONING_STATE 0x20
//Not Used
#define PT_STATUS_UNSUPPORTED_OBJECT 0x21
#define AMT_STATUS_UNSUPPORTED_OBJECT 0x21
//The specified time was not accepted by the Intel<65> AMT device
//since it is earlier than the baseline time set for the device.
#define PT_STATUS_INVALID_TIME 0x22
#define AMT_STATUS_INVALID_TIME 0x22
//StartingIndex is invalid.
#define PT_STATUS_INVALID_INDEX 0x23
#define AMT_STATUS_INVALID_INDEX 0x23
//A parameter is invalid.
#define PT_STATUS_INVALID_PARAMETER 0x24
#define AMT_STATUS_INVALID_PARAMETER 0x24
//An invalid netmask was supplied
//(a valid netmask is an IP address in which all <20>1<EFBFBD>s are before
//the <20>0<EFBFBD> <20> e.g. FFFC0000h is valid, FF0C0000h is invalid).
#define PT_STATUS_INVALID_NETMASK 0x25
#define AMT_STATUS_INVALID_NETMASK 0x25
//The operation failed because the Flash wear-out
//protection mechanism prevented a write to an NVRAM sector.
#define PT_STATUS_FLASH_WRITE_LIMIT_EXCEEDED 0x26
#define AMT_STATUS_FLASH_WRITE_LIMIT_EXCEEDED 0x26
//ME FW did not receive the entire image file.
#define PT_STATUS_INVALID_IMAGE_LENGTH 0x27
#define AMT_STATUS_INVALID_IMAGE_LENGTH 0x27
//ME FW received an image file with an invalid signature.
#define PT_STATUS_INVALID_IMAGE_SIGNATURE 0x28
#define AMT_STATUS_INVALID_IMAGE_SIGNATURE 0x28
//LME can not support the requested version.
#define PT_STATUS_PROPOSE_ANOTHER_VERSION 0x29
#define AMT_STATUS_PROPOSE_ANOTHER_VERSION 0x29
//The PID must be a 64 bit quantity made up of ASCII codes
//of some combination of 8 characters <20>
//capital alphabets (A<>Z), and numbers (0<>9).
#define PT_STATUS_INVALID_PID_FORMAT 0x2A
#define AMT_STATUS_INVALID_PID_FORMAT 0x2A
//The PPS must be a 256 bit quantity made up of ASCII codes
//of some combination of 32 characters <20>
//capital alphabets (A<>Z), and numbers (0<>9).
#define PT_STATUS_INVALID_PPS_FORMAT 0x2B
#define AMT_STATUS_INVALID_PPS_FORMAT 0x2B
//Full BIST test has been blocked
#define PT_STATUS_BIST_COMMAND_BLOCKED 0x2C
#define AMT_STATUS_BIST_COMMAND_BLOCKED 0x2C
//A TCP/IP connection could not be opened on with the selected port.
#define PT_STATUS_CONNECTION_FAILED 0x2D
#define AMT_STATUS_CONNECTION_FAILED 0x2D
//Max number of connection reached.
//LME can not open the requested connection.
#define PT_STATUS_CONNECTION_TOO_MANY 0x2E
#define AMT_STATUS_CONNECTION_TOO_MANY 0x2E
//Random key generation is in progress.
#define PT_STATUS_RNG_GENERATION_IN_PROGRESS 0x2F
#define AMT_STATUS_RNG_GENERATION_IN_PROGRESS 0x2F
//A randomly generated key does not exist.
#define PT_STATUS_RNG_NOT_READY 0x30
#define AMT_STATUS_RNG_NOT_READY 0x30
//Self-generated AMT certificate does not exist.
#define PT_STATUS_CERTIFICATE_NOT_READY 0x31
#define AMT_STATUS_CERTIFICATE_NOT_READY 0x31
//This code establishes a dividing line between
//status codes which are common to host interface and
//network interface and status codes which are used by
//network interface only.
#define PT_STATUS_NETWORK_IF_ERROR_BASE 0x800
#define AMT_STATUS_NETWORK_IF_ERROR_BASE 0x800
//The OEM number specified in the remote control
//command is not supported by the Intel<65> AMT device
#define PT_STATUS_UNSUPPORTED_OEM_NUMBER 0x801
#define AMT_STATUS_UNSUPPORTED_OEM_NUMBER 0x801
//The boot option specified in the remote control command
//is not supported by the Intel<65> AMT device
#define PT_STATUS_UNSUPPORTED_BOOT_OPTION 0x802
#define AMT_STATUS_UNSUPPORTED_BOOT_OPTION 0x802
//The command specified in the remote control command
//is not supported by the Intel<65> AMT device
#define PT_STATUS_INVALID_COMMAND 0x803
#define AMT_STATUS_INVALID_COMMAND 0x803
//The special command specified in the remote control command
//is not supported by the Intel<65> AMT device
#define PT_STATUS_INVALID_SPECIAL_COMMAND 0x804
#define AMT_STATUS_INVALID_SPECIAL_COMMAND 0x804
//The handle specified in the command is invalid
#define PT_STATUS_INVALID_HANDLE 0x805
#define AMT_STATUS_INVALID_HANDLE 0x805
//The password specified in the User ACL is invalid
#define PT_STATUS_INVALID_PASSWORD 0x806
#define AMT_STATUS_INVALID_PASSWORD 0x806
//The realm specified in the User ACL is invalid
#define PT_STATUS_INVALID_REALM 0x807
#define AMT_STATUS_INVALID_REALM 0x807
//The FPACL or EACL entry is used by an active
//registration and cannot be removed or modified.
#define PT_STATUS_STORAGE_ACL_ENTRY_IN_USE 0x808
#define AMT_STATUS_STORAGE_ACL_ENTRY_IN_USE 0x808
//Essential data is missing on CommitChanges command.
#define PT_STATUS_DATA_MISSING 0x809
#define AMT_STATUS_DATA_MISSING 0x809
//The parameter specified is a duplicate of an existing value.
//Returned for a case where duplicate entries are added to FPACL
//(Factory Partner Allocation Control List) or EACL
//(Enterprise Access Control List) lists.
#define PT_STATUS_DUPLICATE 0x80A
#define AMT_STATUS_DUPLICATE 0x80A
//Event Log operation failed due to the current freeze status of the log.
#define PT_STATUS_EVENTLOG_FROZEN 0x80B
#define AMT_STATUS_EVENTLOG_FROZEN 0x80B
//The device is missing private key material.
#define PT_STATUS_PKI_MISSING_KEYS 0x80C
#define AMT_STATUS_PKI_MISSING_KEYS 0x80C
//The device is currently generating a keypair.
//Caller may try repeating this operation at a later time.
#define PT_STATUS_PKI_GENERATING_KEYS 0x80D
#define AMT_STATUS_PKI_GENERATING_KEYS 0x80D
//An invalid Key was entered.
#define PT_STATUS_INVALID_KEY 0x80E
#define AMT_STATUS_INVALID_KEY 0x80E
//An invalid X.509 certificate was entered.
#define PT_STATUS_INVALID_CERT 0x80F
#define AMT_STATUS_INVALID_CERT 0x80F
//Certificate Chain and Private Key do not match.
#define PT_STATUS_CERT_KEY_NOT_MATCH 0x810
#define AMT_STATUS_CERT_KEY_NOT_MATCH 0x810
//The request cannot be satisfied because the maximum
//number of allowed Kerberos domains has been reached.
//(The domain is determined by the first 24 Bytes of the SID.)
#define PT_STATUS_MAX_KERB_DOMAIN_REACHED 0x811
#define AMT_STATUS_MAX_KERB_DOMAIN_REACHED 0x811
// The requested configuration is unsupported
#define PT_STATUS_UNSUPPORTED 0x812
#define AMT_STATUS_UNSUPPORTED 0x812
// A profile with the requested priority already exists
#define PT_STATUS_INVALID_PRIORITY 0x813
#define AMT_STATUS_INVALID_PRIORITY 0x813
// Unable to find specified element
#define PT_STATUS_NOT_FOUND 0x814
#define AMT_STATUS_NOT_FOUND 0x814
// Invalid User credentials
#define PT_STATUS_INVALID_CREDENTIALS 0x815
#define AMT_STATUS_INVALID_CREDENTIALS 0x815
// Passphrase is invalid
#define PT_STATUS_INVALID_PASSPHRASE 0x816
#define AMT_STATUS_INVALID_PASSPHRASE 0x816
// A certificate handle must be chosen before the
// operation can be completed.
#define PT_STATUS_NO_ASSOCIATION 0x818
#define AMT_STATUS_NO_ASSOCIATION 0x818
// The command is defined as Audit Log event and can not be
// logged.
#define PT_STATUS_AUDIT_FAIL 0x81B
#define AMT_STATUS_AUDIT_FAIL 0x81B
// One of the ME components is not ready for unprovisioning.
#define PT_STATUS_BLOCKING_COMPONENT 0x81C
#define AMT_STATUS_BLOCKING_COMPONENT 0x81C
//The application has identified an internal error
#define PTSDK_STATUS_INTERNAL_ERROR 0x1000
//An ISV operation was called while the library is not
//initialized
#define PTSDK_STATUS_NOT_INITIALIZED 0x1001
//The requested library I/F is not supported by the current library
//implementation.
#define PTSDK_STATUS_LIB_VERSION_UNSUPPORTED 0x1002
//One of the parameters is invalid (usually indicates a
//NULL pointer or an invalid session handle is specified)
#define PTSDK_STATUS_INVALID_PARAM 0x1003
//The SDK could not allocate sufficient resources to complete the operation.
#define PTSDK_STATUS_RESOURCES 0x1004
//The Library has identified a HW Internal error.
#define PTSDK_STATUS_HARDWARE_ACCESS_ERROR 0x1005
//The application that sent the request message is not registered.
//Usually indicates the registration timeout has elapsed.
//The caller should reregister with the Intel AMT enabled device.
#define PTSDK_STATUS_REQUESTOR_NOT_REGISTERED 0x1006
//A network error has occurred while processing the call.
#define PTSDK_STATUS_NETWORK_ERROR 0x1007
//Specified container can not hold the requested string
#define PTSDK_STATUS_PARAM_BUFFER_TOO_SHORT 0x1008
//For Windows only.
//ISVS_InitializeCOMinThread was not called by the current thread.
#define PTSDK_STATUS_COM_NOT_INITIALIZED_IN_THREAD 0x1009
//The URL parameter was not optional in current configuration.
#define PTSDK_STATUS_URL_REQUIRED 0x100A
#endif
#endif

57
MicroLMS/heci/mei.h Normal file
View File

@@ -0,0 +1,57 @@
/****************************************************************************
****************************************************************************
***
*** This header was automatically generated from a Linux kernel header
*** of the same name, to make information necessary for userspace to
*** call into the kernel available to libc. It contains only constants,
*** structures, and macros generated from the original header, and thus,
*** contains no copyrightable information.
***
*** To edit the content of this header, modify the corresponding
*** source file (e.g. under external/kernel-headers/original/) then
*** run bionic/libc/kernel/tools/update_all.py
***
*** Any manual change here will be lost the next time this script will
*** be run. You've been warned!
***
****************************************************************************
****************************************************************************/
#ifndef _LINUX_MEI_H
#define _LINUX_MEI_H
// #include <linux/types.h>
// #include <linux/string.h>
typedef struct {
unsigned char b[16];
} uuid_le;
#define IOCTL_MEI_CONNECT_CLIENT _IOWR('H' , 0x01, struct mei_connect_client_data)
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
struct mei_client {
unsigned int max_msg_length;
unsigned char protocol_version;
unsigned char reserved[3];
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
};
struct mei_connect_client_data {
union {
uuid_le in_client_uuid;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
struct mei_client out_client_properties;
};
};
#define IOCTL_MEI_SETUP_DMA_BUF _IOWR('H' , 0x02, struct mei_client_dma_data)
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IOCTL_MEI_UNSET_DMA_BUF _IOW('H' , 0x03, struct mei_client_dma_handle)
struct mei_client_dma_data {
union {
unsigned long userptr;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
};
unsigned int length;
unsigned int handle;
};
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
struct mei_client_dma_handle {
unsigned int handle;
};
#endif
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */

View File

@@ -0,0 +1,613 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#if defined(WIN32) && !defined(_MINCORE)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define SOCKET_ERROR (-1)
#define UNREFERENCED_PARAMETER(P) (P)
#endif
#if defined(WINSOCK2)
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(WINSOCK1)
#include <winsock.h>
#include <wininet.h>
#endif
#include "ILibParsers.h"
#include "ILibAsyncServerSocket.h"
#include "ILibAsyncSocket.h"
#define DEBUGSTATEMENT(x)
#define INET_SOCKADDR_LENGTH(x) ((x==AF_INET6?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)))
typedef struct ILibAsyncServerSocketModule
{
ILibChain_Link ChainLink;
int MaxConnection;
void **AsyncSockets;
ILibServerScope scope;
SOCKET ListenSocket;
unsigned short portNumber, initialPortNumber;
int listening;
int loopbackFlag;
ILibAsyncServerSocket_OnReceive OnReceive;
ILibAsyncServerSocket_OnConnect OnConnect;
ILibAsyncServerSocket_OnDisconnect OnDisconnect;
ILibAsyncServerSocket_OnInterrupt OnInterrupt;
ILibAsyncServerSocket_OnSendOK OnSendOK;
void *Tag;
int Tag2;
}ILibAsyncServerSocketModule;
struct ILibAsyncServerSocket_Data
{
struct ILibAsyncServerSocketModule *module;
ILibAsyncServerSocket_BufferReAllocated Callback;
void *user;
};
const int ILibMemory_ASYNCSERVERSOCKET_CONTAINERSIZE = (const int)sizeof(ILibAsyncServerSocketModule);
/*! \fn ILibAsyncServerSocket_GetTag(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule)
\brief Returns the user Tag associated with the AsyncServer
\param ILibAsyncSocketModule The ILibAsyncServerSocket to query
\returns The user Tag
*/
void *ILibAsyncServerSocket_GetTag(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule)
{
return (((struct ILibAsyncServerSocketModule*)ILibAsyncSocketModule)->Tag);
}
/*! \fn ILibAsyncServerSocket_SetTag(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule, void *tag)
\brief Sets the user Tag associated with the AsyncServer
\param ILibAsyncSocketModule The ILibAsyncServerSocket to save the tag to
\param tag The value to save
*/
void ILibAsyncServerSocket_SetTag(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule, void *tag)
{
((struct ILibAsyncServerSocketModule*)ILibAsyncSocketModule)->Tag = tag;
}
/*! \fn ILibAsyncServerSocket_GetTag(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule)
\brief Returns the user Tag associated with the AsyncServer
\param ILibAsyncSocketModule The ILibAsyncServerSocket to query
\returns The user Tag
*/
int ILibAsyncServerSocket_GetTag2(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule)
{
return(((struct ILibAsyncServerSocketModule*)ILibAsyncSocketModule)->Tag2);
}
/*! \fn ILibAsyncServerSocket_SetTag(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule, void *tag)
\brief Sets the user Tag associated with the AsyncServer
\param ILibAsyncSocketModule The ILibAsyncServerSocket to save the tag to
\param tag The value to save
*/
void ILibAsyncServerSocket_SetTag2(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule, int tag)
{
((struct ILibAsyncServerSocketModule*)ILibAsyncSocketModule)->Tag2 = tag;
}
//
// Internal method called by ILibAsyncSocket, to signal an interrupt condition
//
// <param name="socketModule">The ILibAsyncServerSocket that was interrupted</param>
// <param name="user">The associated user tag</param>
void ILibAsyncServerSocket_OnInterruptSink(ILibAsyncSocket_SocketModule socketModule, void *user)
{
struct ILibAsyncServerSocket_Data *data = (struct ILibAsyncServerSocket_Data*)user;
if (data == NULL) return;
if (data->module->OnInterrupt != NULL) data->module->OnInterrupt(data->module, socketModule, data->user);
free(user);
}
//
// Chain PreSelect handler
//
// <param name="socketModule"></param>
// <param name="readset"></param>
// <param name="writeset"></param>
// <param name="errorset"></param>
// <param name="blocktime"></param>
void ILibAsyncServerSocket_PreSelect(void* socketModule, fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime)
{
struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule;
int flags,i;
UNREFERENCED_PARAMETER( writeset );
UNREFERENCED_PARAMETER( errorset );
UNREFERENCED_PARAMETER( blocktime );
//
// The socket isn't put in listening mode, until the chain is started.
// If this variable == 0, that means we need to do that.
//
if (module->listening == 0)
{
//
// Set the socket to non-block mode, so we can play nice and share the thread
//
#ifdef WIN32
flags = 1;
if(ioctlsocket(module->ListenSocket, FIONBIO, (u_long *)(&flags)) == SOCKET_ERROR) ILIBCRITICALEXIT2(246, WSAGetLastError());
#elif _POSIX
flags = fcntl(module->ListenSocket, F_GETFL,0);
fcntl(module->ListenSocket, F_SETFL, O_NONBLOCK | flags);
#endif
//
// Put the socket in Listen, and add it to the fdset for the Select loop
//
module->listening = 1;
listen(module->ListenSocket, 4);
#if defined(WIN32)
#pragma warning( push, 3 ) // warning C4127: conditional expression is constant
#endif
FD_SET(module->ListenSocket, readset);
#if defined(WIN32)
#pragma warning( pop )
#endif
}
else if (module->ListenSocket != ~0)
{
// Only put the ListenSocket in the readset, if we are able to handle a new socket
for(i = 0; i < module->MaxConnection; ++i)
{
if (ILibAsyncSocket_IsFree(module->AsyncSockets[i]) != 0)
{
#if defined(WIN32)
#pragma warning( push, 3 ) // warning C4127: conditional expression is constant
#endif
FD_SET(module->ListenSocket, readset);
#if defined(WIN32)
#pragma warning( pop )
#endif
break;
}
}
}
}
/*! \fn ILibAsyncServerSocket_SetReAllocateNotificationCallback(ILibAsyncServerSocket_ServerModule AsyncServerSocketToken, ILibAsyncServerSocket_ConnectionToken ConnectionToken, ILibAsyncServerSocket_BufferReAllocated Callback)
\brief Set the callback handler for when the internal data buffer has been resized
\param AsyncServerSocketToken The ILibAsyncServerSocket to query
\param ConnectionToken The specific connection to set the callback with
\param Callback The callback handler to set
*/
void ILibAsyncServerSocket_SetReAllocateNotificationCallback(ILibAsyncServerSocket_ServerModule AsyncServerSocketToken, ILibAsyncServerSocket_ConnectionToken ConnectionToken, ILibAsyncServerSocket_BufferReAllocated Callback)
{
struct ILibAsyncServerSocket_Data *data = (struct ILibAsyncServerSocket_Data*)ILibAsyncSocket_GetUser(ConnectionToken);
UNREFERENCED_PARAMETER( AsyncServerSocketToken );
if (data != NULL) data->Callback = Callback;
}
//
// Chain PostSelect handler
//
// <param name="socketModule"></param>
// <param name="slct"></param>
// <param name="readset"></param>
// <param name="writeset"></param>
// <param name="errorset"></param>
void ILibAsyncServerSocket_PostSelect(void* socketModule, int slct, fd_set *readset, fd_set *writeset, fd_set *errorset)
{
struct ILibAsyncServerSocket_Data *data;
struct sockaddr_in6 addr;
#ifdef _POSIX
socklen_t addrlen;
#else
int addrlen;
#endif
struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule;
int i,flags;
#ifdef WIN32
SOCKET NewSocket;
#elif defined( _POSIX)
int NewSocket;
#endif
UNREFERENCED_PARAMETER( slct );
UNREFERENCED_PARAMETER( writeset );
UNREFERENCED_PARAMETER( errorset );
if (FD_ISSET(module->ListenSocket, readset) != 0)
{
//
// There are pending TCP connection requests
//
for(i = 0; i < module->MaxConnection; ++i)
{
//
// Check to see if we have available resources to handle this connection request
//
if (ILibAsyncSocket_IsFree(module->AsyncSockets[i]) != 0)
{
addrlen = sizeof(addr);
NewSocket = accept(module->ListenSocket, (struct sockaddr*)&addr, &addrlen); // Klocwork claims we could lose the resource acquired fom the declaration, but that is not possible in this case
if (NewSocket != ~0)
{
//printf("Accepting new connection, socket = %d\r\n", NewSocket);
//
// Set this new socket to non-blocking mode, so we can play nice and share thread
//
#ifdef WIN32
flags = 1;
if (ioctlsocket(NewSocket, FIONBIO, (u_long *)(&flags)) == SOCKET_ERROR) ILIBCRITICALEXIT2(246, WSAGetLastError());
#elif _POSIX
flags = fcntl(NewSocket, F_GETFL,0);
fcntl(NewSocket, F_SETFL, O_NONBLOCK|flags);
#endif
//
// Instantiate a module to contain all the data about this connection
//
if ((data = (struct ILibAsyncServerSocket_Data*)malloc(sizeof(struct ILibAsyncServerSocket_Data))) == NULL) ILIBCRITICALEXIT(254);
memset(data, 0, sizeof(struct ILibAsyncServerSocket_Data));
data->module = (struct ILibAsyncServerSocketModule*)socketModule;
ILibAsyncSocket_UseThisSocket(module->AsyncSockets[i], NewSocket, &ILibAsyncServerSocket_OnInterruptSink, data);
ILibAsyncSocket_SetRemoteAddress(module->AsyncSockets[i], (struct sockaddr*)&addr);
if (module->OnConnect != NULL)
{
// Notify the user about this new connection
module->OnConnect(module, module->AsyncSockets[i], &(data->user));
}
}
else {break;}
}
}
}
} // Klocwork claims that we could lose the resource acquired in the declaration, but that is not possible in this case
//
// Chain Destroy handler
//
// <param name="socketModule"></param>
void ILibAsyncServerSocket_Destroy(void *socketModule)
{
struct ILibAsyncServerSocketModule *module =(struct ILibAsyncServerSocketModule*)socketModule;
free(module->AsyncSockets);
if (module->ListenSocket != (SOCKET)~0)
{
#ifdef WIN32
closesocket(module->ListenSocket);
#elif _POSIX
close(module->ListenSocket);
#endif
module->ListenSocket = (SOCKET)~0;
}
}
//
// Internal method dispatched by the OnData event of the underlying ILibAsyncSocket
//
// <param name="socketModule"></param>
// <param name="buffer"></param>
// <param name="p_beginPointer"></param>
// <param name="endPointer"></param>
// <param name="OnInterrupt"></param>
// <param name="user"></param>
// <param name="PAUSE"></param>
void ILibAsyncServerSocket_OnData(ILibAsyncSocket_SocketModule socketModule,char* buffer,int *p_beginPointer, int endPointer,void (**OnInterrupt)(void *AsyncSocketMoudle, void *user),void **user, int *PAUSE)
{
struct ILibAsyncServerSocket_Data *data = (struct ILibAsyncServerSocket_Data*)(*user);
int bpointer = *p_beginPointer;
UNREFERENCED_PARAMETER( OnInterrupt );
// Pass the received data up
if (data != NULL && data->module->OnReceive != NULL)
{
data->module->OnReceive(data->module, socketModule, buffer, &bpointer, endPointer, &(data->module->OnInterrupt), &(data->user), PAUSE);
if (ILibAsyncSocket_IsFree(socketModule))
{
*p_beginPointer = endPointer;
}
else
{
*p_beginPointer = bpointer;
}
}
}
//
// Internal method dispatched by the OnConnect event of the underlying ILibAsyncSocket. In this case, it will only occur when TLS connection is established.
//
// <param name="socketModule"></param>
// <param name="user"></param>
void ILibAsyncServerSocket_OnConnectSink(ILibAsyncSocket_SocketModule socketModule, int Connected, void *user)
{
struct ILibAsyncServerSocket_Data *data = (struct ILibAsyncServerSocket_Data*)user;
if (data == NULL) return;
if (Connected == 0)
{
// Connection Failed, clean up
free(data);
return;
}
if (data->module->OnConnect != NULL) data->module->OnConnect(data->module, socketModule, &(data->user));
}
//
// Internal method dispatched by the OnDisconnect event of the underlying ILibAsyncSocket
//
// <param name="socketModule"></param>
// <param name="user"></param>
void ILibAsyncServerSocket_OnDisconnectSink(ILibAsyncSocket_SocketModule socketModule, void *user)
{
struct ILibAsyncServerSocket_Data *data = (struct ILibAsyncServerSocket_Data*)user;
// Pass this Disconnect event up
if (data == NULL) return;
if (data->module->OnDisconnect != NULL) data->module->OnDisconnect(data->module, socketModule, data->user);
// If the chain is shutting down, we need to free some resources
if (ILibIsChainBeingDestroyed(data->module->ChainLink.ParentChain) == 0) free(data);
}
//
// Internal method dispatched by the OnSendOK event of the underlying ILibAsyncSocket
//
// <param name="socketModule"></param>
// <param name="user"></param>
void ILibAsyncServerSocket_OnSendOKSink(ILibAsyncSocket_SocketModule socketModule, void *user)
{
struct ILibAsyncServerSocket_Data *data = (struct ILibAsyncServerSocket_Data*)user;
// Pass the OnSendOK event up
if (data != NULL && data->module->OnSendOK != NULL) data->module->OnSendOK(data->module, socketModule, data->user);
}
//
// Internal method dispatched by ILibAsyncSocket, to signal that the buffers have been reallocated
//
// <param name="ConnectionToken">The ILibAsyncSocket sender</param>
// <param name="user">The ILibAsyncServerSocket_Data object</param>
// <param name="offSet">The offset to the new buffer location</param>
void ILibAsyncServerSocket_OnBufferReAllocated(ILibAsyncSocket_SocketModule ConnectionToken, void *user, ptrdiff_t offSet)
{
struct ILibAsyncServerSocket_Data *data = (struct ILibAsyncServerSocket_Data*)user;
if (data!=NULL && data->Callback!=NULL)
{
//
// If someone above us, has registered for this callback, we need to fire it,
// with the correct user object
//
data->Callback(data->module,ConnectionToken,data->user,offSet);
}
}
void ILibAsyncServerSocket_ResumeListeningSink(void *chain, void* user)
{
ILibAsyncServerSocketModule *m = (ILibAsyncServerSocketModule*)user;
int ra = 1;
int off = 0;
int receivingAddressLength = sizeof(struct sockaddr_in6);
struct sockaddr_in6 localif;
struct sockaddr_in6 localAddress;
UNREFERENCED_PARAMETER(chain);
memset(&localif, 0, sizeof(struct sockaddr_in6));
if (m->loopbackFlag != 2 && ILibDetectIPv6Support())
{
// Setup the IPv6 any or loopback address, this socket will also work for IPv4 traffic on IPv6 stack
localif.sin6_family = AF_INET6;
localif.sin6_addr = (m->loopbackFlag != 0 ? in6addr_loopback : in6addr_any);
localif.sin6_port = htons(m->initialPortNumber);
}
else
{
// IPv4-only detected
localif.sin6_family = AF_INET;
#ifdef WINSOCK2
((struct sockaddr_in*)&localif)->sin_addr.S_un.S_addr = htonl((m->loopbackFlag != 0 ? INADDR_LOOPBACK : INADDR_ANY));
#else
((struct sockaddr_in*)&localif)->sin_addr.s_addr = htonl((m->loopbackFlag != 0 ? INADDR_LOOPBACK : INADDR_ANY));
#endif
((struct sockaddr_in*)&localif)->sin_port = htons(m->initialPortNumber);
}
// Get our listening socket
if ((m->ListenSocket = socket(localif.sin6_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { m->ListenSocket = (SOCKET)~0; return; }
// Setup the IPv6 & IPv4 support on same socket
if (localif.sin6_family == AF_INET6) if (setsockopt(m->ListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&off, sizeof(off)) != 0) ILIBCRITICALERREXIT(253);
#ifdef SO_NOSIGPIPE
setsockopt(m->ListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&ra, sizeof(int)); // Turn off SIGPIPE if writing to disconnected socket
#endif
#if defined(WIN32)
// On Windows. Lets make sure no one else can bind to this addr/port. This stops socket hijacking (not a problem on Linux).
if (setsockopt(m->ListenSocket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&ra, sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
#else
// On Linux. Setting the re-use on a TCP socket allows reuse of the socket even in timeout state. Allows for fast stop/start (Not a problem on Windows).
if (setsockopt(m->ListenSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&ra, sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
#endif
// Bind the socket
#if defined(WIN32)
if (bind(m->ListenSocket, (struct sockaddr*)&localif, INET_SOCKADDR_LENGTH(localif.sin6_family)) != 0) { closesocket(m->ListenSocket); m->ListenSocket = (SOCKET)~0; return; }
#else
if (bind(m->ListenSocket, (struct sockaddr*)&localif, INET_SOCKADDR_LENGTH(localif.sin6_family)) != 0) { close(m->ListenSocket); m->ListenSocket = (SOCKET)~0; return; }
#endif
// Fetch the local port number
#if defined(WINSOCK2)
getsockname(m->ListenSocket, (struct sockaddr*)&localAddress, (int*)&receivingAddressLength);
#else
getsockname(m->ListenSocket, (struct sockaddr*)&localAddress, (socklen_t*)&receivingAddressLength);
#endif
if (localAddress.sin6_family == AF_INET6) m->portNumber = ntohs(localAddress.sin6_port); else m->portNumber = ntohs(((struct sockaddr_in*)&localAddress)->sin_port);
m->listening = 0;
}
void ILibAsyncServerSocket_StopListeningSink(void *chain, void* user)
{
ILibAsyncServerSocketModule *m = (ILibAsyncServerSocketModule*)user;
UNREFERENCED_PARAMETER(chain);
if (m->ListenSocket != (SOCKET)~0)
{
#ifdef WIN32
closesocket(m->ListenSocket);
#else
close(m->ListenSocket);
#endif
m->ListenSocket = (SOCKET)~0;
}
}
//! Take the server socket out of listening mode, rejecting new incoming connection requests
/*!
\param module ILibAsyncServerSocket_ServerModule Server Listening Module
*/
void ILibAsyncServerSocket_StopListening(ILibAsyncServerSocket_ServerModule module)
{
ILibAsyncServerSocketModule *m = (ILibAsyncServerSocketModule*)module;
ILibChain_RunOnMicrostackThread(m->ChainLink.ParentChain, ILibAsyncServerSocket_StopListeningSink, m);
}
//! Put the server socket back in listening mode, to allow new incoming connection requests
/*!
\param module ILibAsyncServerSocket_ServerModule Server Listening Module
*/
void ILibAsyncServerSocket_ResumeListening(ILibAsyncServerSocket_ServerModule module)
{
ILibAsyncServerSocketModule *m = (ILibAsyncServerSocketModule*)module;
ILibChain_RunOnMicrostackThread(m->ChainLink.ParentChain, ILibAsyncServerSocket_ResumeListeningSink, m);
}
/*! \fn ILibCreateAsyncServerSocketModule(void *Chain, int MaxConnections, int PortNumber, int initialBufferSize, ILibAsyncServerSocket_OnConnect OnConnect,ILibAsyncServerSocket_OnDisconnect OnDisconnect,ILibAsyncServerSocket_OnReceive OnReceive,ILibAsyncServerSocket_OnInterrupt OnInterrupt, ILibAsyncServerSocket_OnSendOK OnSendOK)
\brief Instantiates a new ILibAsyncServerSocket
\param Chain The chain to add this module to. (Chain must <B>not</B> be running)
\param MaxConnections The max number of simultaneous connections that will be allowed
\param PortNumber The port number to bind to. 0 will select a random port
\param initialBufferSize The initial size of the receive buffer
\param loopbackFlag 0 to bind to ANY, 1 to bind to IPv6 loopback first, 2 to bind to IPv4 loopback first.
\param OnConnect Function Pointer that triggers when a connection is established
\param OnDisconnect Function Pointer that triggers when a connection is closed
\param OnReceive Function Pointer that triggers when data is received
\param OnInterrupt Function Pointer that triggers when connection interrupted
\param OnSendOK Function Pointer that triggers when pending sends are complete
\param ServerAutoFreeMemorySize Size of AutoFreeMemory on Server to co-allocate
\param SessionAutoFreeMemorySize Size of AutoFreeMemory on Session to co-allocate
\returns An ILibAsyncServerSocket module
*/
ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemory(void *Chain, int MaxConnections, unsigned short PortNumber, int initialBufferSize, int loopbackFlag, ILibAsyncServerSocket_OnConnect OnConnect, ILibAsyncServerSocket_OnDisconnect OnDisconnect, ILibAsyncServerSocket_OnReceive OnReceive, ILibAsyncServerSocket_OnInterrupt OnInterrupt, ILibAsyncServerSocket_OnSendOK OnSendOK, int ServerUserMappedMemorySize, int SessionUserMappedMemorySize)
{
int i;
int ra = 1;
int off = 0;
int receivingAddressLength = sizeof(struct sockaddr_in6);
struct sockaddr_in6 localif;
struct sockaddr_in6 localAddress;
struct ILibAsyncServerSocketModule *RetVal;
memset(&localif, 0, sizeof(struct sockaddr_in6));
if (loopbackFlag != 2 && ILibDetectIPv6Support())
{
// Setup the IPv6 any or loopback address, this socket will also work for IPv4 traffic on IPv6 stack
localif.sin6_family = AF_INET6;
localif.sin6_addr = (loopbackFlag != 0?in6addr_loopback:in6addr_any);
localif.sin6_port = htons(PortNumber);
}
else
{
// IPv4-only detected
localif.sin6_family = AF_INET;
#ifdef WINSOCK2
((struct sockaddr_in*)&localif)->sin_addr.S_un.S_addr = htonl((loopbackFlag != 0?INADDR_LOOPBACK:INADDR_ANY));
#else
((struct sockaddr_in*)&localif)->sin_addr.s_addr = htonl((loopbackFlag != 0?INADDR_LOOPBACK:INADDR_ANY));
#endif
((struct sockaddr_in*)&localif)->sin_port = htons(PortNumber);
}
// Instantiate a new AsyncServer module
RetVal = (struct ILibAsyncServerSocketModule*)ILibChain_Link_Allocate(sizeof(struct ILibAsyncServerSocketModule), ServerUserMappedMemorySize);
RetVal->ChainLink.PreSelectHandler = &ILibAsyncServerSocket_PreSelect;
RetVal->ChainLink.PostSelectHandler = &ILibAsyncServerSocket_PostSelect;
RetVal->ChainLink.DestroyHandler = &ILibAsyncServerSocket_Destroy;
RetVal->ChainLink.ParentChain = Chain;
RetVal->OnConnect = OnConnect;
RetVal->OnDisconnect = OnDisconnect;
RetVal->OnInterrupt = OnInterrupt;
RetVal->OnSendOK = OnSendOK;
RetVal->OnReceive = OnReceive;
RetVal->MaxConnection = MaxConnections;
RetVal->AsyncSockets = (void**)malloc(MaxConnections * sizeof(void*));
if (RetVal->AsyncSockets == NULL) { free(RetVal); ILIBMARKPOSITION(253); return NULL; }
RetVal->portNumber = (unsigned short)PortNumber;
RetVal->loopbackFlag = loopbackFlag;
RetVal->initialPortNumber = PortNumber;
// Get our listening socket
if ((RetVal->ListenSocket = socket(localif.sin6_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { free(RetVal->AsyncSockets); free(RetVal); return 0; }
// Setup the IPv6 & IPv4 support on same socket
if (localif.sin6_family == AF_INET6) if (setsockopt(RetVal->ListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&off, sizeof(off)) != 0) ILIBCRITICALERREXIT(253);
#ifdef SO_NOSIGPIPE
setsockopt(RetVal->ListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&ra, sizeof(int)); // Turn off SIGPIPE if writing to disconnected socket
#endif
#if defined(WIN32)
// On Windows. Lets make sure no one else can bind to this addr/port. This stops socket hijacking (not a problem on Linux).
if (setsockopt(RetVal->ListenSocket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&ra, sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
#else
// On Linux. Setting the re-use on a TCP socket allows reuse of the socket even in timeout state. Allows for fast stop/start (Not a problem on Windows).
if (setsockopt(RetVal->ListenSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&ra, sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
#endif
// Bind the socket
#if defined(WIN32)
if (bind(RetVal->ListenSocket, (struct sockaddr*)&localif, INET_SOCKADDR_LENGTH(localif.sin6_family)) != 0) { closesocket(RetVal->ListenSocket); free(RetVal->AsyncSockets); free(RetVal); return 0; }
#else
if (bind(RetVal->ListenSocket, (struct sockaddr*)&localif, INET_SOCKADDR_LENGTH(localif.sin6_family)) != 0) { close(RetVal->ListenSocket); free(RetVal->AsyncSockets); free(RetVal); return 0; }
#endif
// Fetch the local port number
#if defined(WINSOCK2)
getsockname(RetVal->ListenSocket, (struct sockaddr*)&localAddress, (int*)&receivingAddressLength);
#else
getsockname(RetVal->ListenSocket, (struct sockaddr*)&localAddress, (socklen_t*)&receivingAddressLength);
#endif
if (localAddress.sin6_family == AF_INET6) RetVal->portNumber = ntohs(localAddress.sin6_port); else RetVal->portNumber = ntohs(((struct sockaddr_in*)&localAddress)->sin_port);
// Create our socket pool
for(i = 0; i < MaxConnections; ++i)
{
RetVal->AsyncSockets[i] = ILibCreateAsyncSocketModuleWithMemory(Chain, initialBufferSize, &ILibAsyncServerSocket_OnData, &ILibAsyncServerSocket_OnConnectSink, &ILibAsyncServerSocket_OnDisconnectSink, &ILibAsyncServerSocket_OnSendOKSink, SessionUserMappedMemorySize);
//
// We want to know about any buffer reallocations, because anything above us may want to know
//
ILibAsyncSocket_SetReAllocateNotificationCallback(RetVal->AsyncSockets[i], &ILibAsyncServerSocket_OnBufferReAllocated);
}
ILibAddToChain(Chain, RetVal);
return(RetVal);
}
/*! \fn ILibAsyncServerSocket_GetPortNumber(ILibAsyncServerSocket_ServerModule ServerSocketModule)
\brief Returns the port number the server is bound to
\param ServerSocketModule The ILibAsyncServer to query
\returns The listening port number
*/
unsigned short ILibAsyncServerSocket_GetPortNumber(ILibAsyncServerSocket_ServerModule ServerSocketModule)
{
return(((struct ILibAsyncServerSocketModule*)ServerSocketModule)->portNumber);
}

View File

@@ -0,0 +1,154 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef ___ILibAsyncServerSocket___
#define ___ILibAsyncServerSocket___
/*! \file ILibAsyncServerSocket.h
\brief MicroStack APIs for TCP Server Functionality
*/
/*! \defgroup ILibAsyncServerSocket ILibAsyncServerSocket Module
\{
*/
#if defined(WIN32)
#include <STDDEF.H>
#elif defined(_POSIX)
#include <malloc.h>
#endif
#include "ILibAsyncSocket.h"
#ifdef __cplusplus
extern "C" {
#endif
/*! \typedef ILibAsyncServerSocket_ServerModule
\brief The handle for an ILibAsyncServerSocket module
*/
typedef void* ILibAsyncServerSocket_ServerModule;
/*! \typedef ILibAsyncServerSocket_ConnectionToken
\brief Connection state, for a connected session
*/
typedef ILibAsyncSocket_SocketModule ILibAsyncServerSocket_ConnectionToken;
/*! \typedef ILibAsyncServerSocket_BufferReAllocated
\brief BufferReAllocation Handler
\param AsyncServerSocketToken The ILibAsyncServerSocket token
\param ConnectionToken The ILibAsyncServerSocket_Connection token
\param user The User object
\param newOffset The buffer has shifted by this offset
*/
typedef void (*ILibAsyncServerSocket_BufferReAllocated)(ILibAsyncServerSocket_ServerModule AsyncServerSocketToken, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user, ptrdiff_t newOffset);
void ILibAsyncServerSocket_SetReAllocateNotificationCallback(ILibAsyncServerSocket_ServerModule AsyncServerSocketToken, ILibAsyncServerSocket_ConnectionToken ConnectionToken, ILibAsyncServerSocket_BufferReAllocated Callback);
/*! \typedef ILibAsyncServerSocket_OnInterrupt
\brief Handler for when a session was interrupted by a call to ILibStopChain
\param AsyncServerSocketModule The parent ILibAsyncServerSocket_ServerModule
\param ConnectionToken The connection state for this session
\param user
*/
typedef void (*ILibAsyncServerSocket_OnInterrupt)(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user);
/*! \typedef ILibAsyncServerSocket_OnReceive
\brief Handler for when data is received
\par
<B>Note on memory handling:</B>
When you process the received buffer, you must advance \a p_beginPointer the number of bytes that you
have processed. If \a p_beginPointer does not equal \a endPointer when this method completes,
the system will continue to reclaim any memory that has already been processed, and call this method again
until no more memory has been processed. If no memory has been processed, and more data has been received
on the network, the buffer will be automatically grown (according to a specific alogrythm), to accomodate any new data.
\param AsyncServerSocketModule The parent ILibAsyncServerSocket_ServerModule
\param ConnectionToken The connection state for this session
\param buffer The data that was received
\param[in,out] p_beginPointer The start index of the data that was received
\param endPointer The end index of the data that was received
\param[in,out] OnInterrupt Set this pointer to receive notification if this session is interrupted
\param[in,out] user Set a custom user object
\param[out] PAUSE Flag to indicate if the system should continue reading data off the network
*/
typedef void (*ILibAsyncServerSocket_OnReceive)(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, char* buffer, int *p_beginPointer, int endPointer, ILibAsyncServerSocket_OnInterrupt *OnInterrupt, void **user, int *PAUSE);
/*! \typedef ILibAsyncServerSocket_OnConnect
\brief Handler for when a connection is made
\param AsyncServerSocketModule The parent ILibAsyncServerSocket_ServerModule
\param ConnectionToken The connection state for this session
\param[in,out] user Set a user object to associate with this connection
*/
typedef void (*ILibAsyncServerSocket_OnConnect)(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void **user);
/*! \typedef ILibAsyncServerSocket_OnDisconnect
\brief Handler for when a connection is terminated normally
\param AsyncServerSocketModule The parent ILibAsyncServerSocket_ServerModule
\param ConnectionToken The connection state for this session
\param user User object that was associated with this connection
*/
typedef void (*ILibAsyncServerSocket_OnDisconnect)(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user);
/*! \typedef ILibAsyncServerSocket_OnSendOK
\brief Handler for when pending send operations have completed
\par
This handler will only be called if a call to \a ILibAsyncServerSocket_Send returned a value greater
than 0, which indicates that not all of the data could be sent.
\param AsyncServerSocketModule The parent ILibAsyncServerSocket_ServerModule
\param ConnectionToken The connection state for this session
\param user User object that was associated with this connection
*/
typedef void (*ILibAsyncServerSocket_OnSendOK)(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user);
extern const int ILibMemory_ASYNCSERVERSOCKET_CONTAINERSIZE;
#define ILibCreateAsyncServerSocketModule(Chain, MaxConnections, PortNumber, initialBufferSize, loopbackFlag, OnConnect, OnDisconnect, OnReceive, OnInterrupt, OnSendOK) ILibCreateAsyncServerSocketModuleWithMemory(Chain, MaxConnections, PortNumber, initialBufferSize, loopbackFlag, OnConnect, OnDisconnect, OnReceive, OnInterrupt, OnSendOK, 0, 0)
ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemory(void *Chain, int MaxConnections, unsigned short PortNumber, int initialBufferSize, int loopbackFlag, ILibAsyncServerSocket_OnConnect OnConnect, ILibAsyncServerSocket_OnDisconnect OnDisconnect, ILibAsyncServerSocket_OnReceive OnReceive, ILibAsyncServerSocket_OnInterrupt OnInterrupt, ILibAsyncServerSocket_OnSendOK OnSendOK, int ServerUserMappedMemorySize, int SessionUserMappedMemorySize);
void *ILibAsyncServerSocket_GetTag(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule);
void ILibAsyncServerSocket_SetTag(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule, void *user);
int ILibAsyncServerSocket_GetTag2(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule);
void ILibAsyncServerSocket_SetTag2(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule, int user);
void ILibAsyncServerSocket_StopListening(ILibAsyncServerSocket_ServerModule module);
void ILibAsyncServerSocket_ResumeListening(ILibAsyncServerSocket_ServerModule module);
unsigned short ILibAsyncServerSocket_GetPortNumber(ILibAsyncServerSocket_ServerModule ServerSocketModule);
/*! \def ILibAsyncServerSocket_Send
\brief Sends data onto the TCP stream
\param ServerSocketModule The parent ILibAsyncServerSocket_ServerModule
\param ConnectionToken The connection state for this session
\param buffer The data to be sent
\param bufferLength The length of \a buffer
\param UserFreeBuffer The \a ILibAsyncSocket_MemoryOwnership enumeration, that identifies how the memory pointer to by \a buffer is to be handled
\returns \a ILibAsyncSocket_SendStatus indicating the send status
*/
#define ILibAsyncServerSocket_Send(ServerSocketModule, ConnectionToken, buffer, bufferLength, UserFreeBuffer) ILibAsyncSocket_Send(ConnectionToken, buffer, bufferLength, UserFreeBuffer)
/*! \def ILibAsyncServerSocket_Disconnect
\brief Disconnects a TCP stream
\param ServerSocketModule The parent ILibAsyncServerSocket_ServerModule
\param ConnectionToken The connection state for this session
*/
#define ILibAsyncServerSocket_Disconnect(ServerSocketModule, ConnectionToken) ILibAsyncSocket_Disconnect(ConnectionToken)
/*! \def ILibAsyncServerSocket_GetPendingBytesToSend
\brief Gets the outstanding number of bytes to be sent
*/
#define ILibAsyncServerSocket_GetPendingBytesToSend(ServerSocketModule, ConnectionToken) ILibAsyncSocket_GetPendingBytesToSend(ConnectionToken)
/*! \def ILibAsyncServerSocket_GetTotalBytesSent
\brief Gets the total number of bytes that have been sent
\param ServerSocketModule The parent ILibAsyncServerSocket_ServerModule
\param ConnectionToken The connection state for this session
*/
#define ILibAsyncServerSocket_GetTotalBytesSent(ServerSocketModule, ConnectionToken) ILibAsyncSocket_GetTotalBytesSent(ConnectionToken)
/*! \def ILibAsyncServerSocket_ResetTotalBytesSent
\brief Resets the total bytes sent counter
\param ServerSocketModule The parent ILibAsyncServerSocket_ServerModule
\param ConnectionToken The connection state for this session
*/
#define ILibAsyncServerSocket_ResetTotalBytesSent(ServerSocketModule, ConnectionToken) ILibAsyncSocket_ResetTotalBytesSent(ConnectionToken)
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,194 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef ___ILibAsyncSocket___
#define ___ILibAsyncSocket___
/*! \file ILibAsyncSocket.h
\brief MicroStack APIs for TCP Client Functionality
*/
/*! \defgroup ILibAsyncSocket ILibAsyncSocket Module
\{
*/
#if defined(WIN32)
#include <STDDEF.H>
#elif defined(_POSIX)
#include <malloc.h>
#endif
//#include "ssl.h"
#ifdef __cplusplus
extern "C" {
#endif
/*! \def MEMORYCHUNKSIZE
\brief Incrementally grow the buffer by this amount of bytes
*/
#define MEMORYCHUNKSIZE 4096
#define ILibTransports_AsyncSocket 0x40
typedef enum ILibAsyncSocket_SendStatus
{
ILibAsyncSocket_ALL_DATA_SENT = 1, /*!< All of the data has already been sent */
ILibAsyncSocket_NOT_ALL_DATA_SENT_YET = 0, /*!< Not all of the data could be sent, but is queued to be sent as soon as possible */
ILibAsyncSocket_SEND_ON_CLOSED_SOCKET_ERROR = -4 /*!< A send operation was attmepted on a closed socket */
}ILibAsyncSocket_SendStatus;
/*! \enum ILibAsyncSocket_MemoryOwnership
\brief Enumeration values for Memory Ownership of variables
*/
typedef enum ILibAsyncSocket_MemoryOwnership
{
ILibAsyncSocket_MemoryOwnership_CHAIN = 0, /*!< The Microstack will own this memory, and free it when it is done with it */
ILibAsyncSocket_MemoryOwnership_STATIC = 1, /*!< This memory is static, so the Microstack will not free it, and assume it will not go away, so it won't copy it either */
ILibAsyncSocket_MemoryOwnership_USER = 2 /*!< The Microstack doesn't own this memory, so if necessary the memory will be copied */
}ILibAsyncSocket_MemoryOwnership;
/*! \typedef ILibAsyncSocket_SocketModule
\brief The handle for an ILibAsyncSocket module
*/
typedef void* ILibAsyncSocket_SocketModule;
/*! \typedef ILibAsyncSocket_OnInterrupt
\brief Handler for when a session was interrupted by a call to ILibStopChain
\param socketModule The \a ILibAsyncSocket_SocketModule that was interrupted
\param user The user object that was associated with this connection
*/
//typedef void(*ILibAsyncSocket_OnReplaceSocket)(ILibAsyncSocket_SocketModule socketModule, void *user);
typedef void(*ILibAsyncSocket_OnBufferSizeExceeded)(ILibAsyncSocket_SocketModule socketModule, void *user);
typedef void(*ILibAsyncSocket_OnInterrupt)(ILibAsyncSocket_SocketModule socketModule, void *user);
/*! \typedef ILibAsyncSocket_OnData
\brief Handler for when data is received
\par
<B>Note on memory handling:</B>
When you process the received buffer, you must advance \a p_beginPointer the number of bytes that you
have processed. If \a p_beginPointer does not equal \a endPointer when this method completes,
the system will continue to reclaim any memory that has already been processed, and call this method again
until no more memory has been processed. If no memory has been processed, and more data has been received
on the network, the buffer will be automatically grown (according to a specific alogrythm), to accomodate any new data.
\param socketModule The \a ILibAsyncSocket_SocketModule that received data
\param buffer The data that was received
\param[in,out] p_beginPointer The start index of the data that was received
\param endPointer The end index of the data that was received
\param[in,out] OnInterrupt Set this pointer to receive notification if this session is interrupted
\param[in,out] user Set a custom user object
\param[out] PAUSE Flag to indicate if the system should continue reading data off the network
*/
typedef void(*ILibAsyncSocket_OnData)(ILibAsyncSocket_SocketModule socketModule, char* buffer, int *p_beginPointer, int endPointer,ILibAsyncSocket_OnInterrupt* OnInterrupt, void **user, int *PAUSE);
/*! \typedef ILibAsyncSocket_OnConnect
\brief Handler for when a connection is made
\param socketModule The \a ILibAsyncSocket_SocketModule that was connected
\param user The user object that was associated with this object
*/
typedef void(*ILibAsyncSocket_OnConnect)(ILibAsyncSocket_SocketModule socketModule, int Connected, void *user);
/*! \typedef ILibAsyncSocket_OnDisconnect
\brief Handler for when a connection is terminated normally
\param socketModule The \a ILibAsyncSocket_SocketModule that was disconnected
\param user User object that was associated with this connection
*/
typedef void(*ILibAsyncSocket_OnDisconnect)(ILibAsyncSocket_SocketModule socketModule, void *user);
/*! \typedef ILibAsyncSocket_OnSendOK
\brief Handler for when pending send operations have completed
\par
This handler will only be called if a call to \a ILibAsyncSocket_Send returned a value greater
than 0, which indicates that not all of the data could be sent.
\param socketModule The \a ILibAsyncSocket_SocketModule whos pending sends have completed
\param user User object that was associated with this connection
*/
typedef void(*ILibAsyncSocket_OnSendOK)(ILibAsyncSocket_SocketModule socketModule, void *user);
/*! \typedef ILibAsyncSocket_OnBufferReAllocated
\brief Handler for when the internal data buffer has been resized.
\par
<B>Note:</B> This is only useful if you are storing pointer values into the buffer supplied in \a ILibAsyncSocket_OnData.
\param AsyncSocketToken The \a ILibAsyncSocket_SocketModule whos buffer was resized
\param user The user object that was associated with this connection
\param newOffset The new offset differential. Simply add this value to your existing pointers, to obtain the correct pointer into the resized buffer.
*/
typedef void(*ILibAsyncSocket_OnBufferReAllocated)(ILibAsyncSocket_SocketModule AsyncSocketToken, void *user, ptrdiff_t newOffset);
/*! \defgroup TLSGroup TLS Related Methods
* @{
*/
/*! @} */
extern const int ILibMemory_ASYNCSOCKET_CONTAINERSIZE;
void ILibAsyncSocket_SetReAllocateNotificationCallback(ILibAsyncSocket_SocketModule AsyncSocketToken, ILibAsyncSocket_OnBufferReAllocated Callback);
void *ILibAsyncSocket_GetUser(ILibAsyncSocket_SocketModule socketModule);
void ILibAsyncSocket_SetUser(ILibAsyncSocket_SocketModule socketModule, void* user);
void *ILibAsyncSocket_GetUser2(ILibAsyncSocket_SocketModule socketModule);
void ILibAsyncSocket_SetUser2(ILibAsyncSocket_SocketModule socketModule, void* user);
int ILibAsyncSocket_GetUser3(ILibAsyncSocket_SocketModule socketModule);
void ILibAsyncSocket_SetUser3(ILibAsyncSocket_SocketModule socketModule, int user);
void ILibAsyncSocket_UpdateOnData(ILibAsyncSocket_SocketModule module, ILibAsyncSocket_OnData OnData);
#define ILibCreateAsyncSocketModule(Chain, initialBufferSize, OnData, OnConnect, OnDisconnect, OnSendOK) ILibCreateAsyncSocketModuleWithMemory(Chain, initialBufferSize, OnData, OnConnect, OnDisconnect, OnSendOK, 0)
ILibAsyncSocket_SocketModule ILibCreateAsyncSocketModuleWithMemory(void *Chain, int initialBufferSize, ILibAsyncSocket_OnData OnData, ILibAsyncSocket_OnConnect OnConnect, ILibAsyncSocket_OnDisconnect OnDisconnect, ILibAsyncSocket_OnSendOK OnSendOK, int UserMappedMemorySize);
void *ILibAsyncSocket_GetSocket(ILibAsyncSocket_SocketModule module);
void ILibAsyncSocket_Shutdown(ILibAsyncSocket_SocketModule module);
unsigned int ILibAsyncSocket_GetPendingBytesToSend(ILibAsyncSocket_SocketModule socketModule);
unsigned int ILibAsyncSocket_GetTotalBytesSent(ILibAsyncSocket_SocketModule socketModule);
void ILibAsyncSocket_ResetTotalBytesSent(ILibAsyncSocket_SocketModule socketModule);
void ILibAsyncSocket_ConnectTo(void* socketModule, struct sockaddr *localInterface, struct sockaddr *remoteAddress, ILibAsyncSocket_OnInterrupt InterruptPtr, void *user);
#ifdef MICROSTACK_PROXY
void ILibAsyncSocket_ConnectToProxy(void* socketModule, struct sockaddr *localInterface, struct sockaddr *remoteAddress, struct sockaddr *proxyAddress, char* proxyUser, char* proxyPass, ILibAsyncSocket_OnInterrupt InterruptPtr, void *user);
#endif
enum ILibAsyncSocket_SendStatus ILibAsyncSocket_SendTo(ILibAsyncSocket_SocketModule socketModule, char* buffer, int length, struct sockaddr *remoteAddress, enum ILibAsyncSocket_MemoryOwnership UserFree);
/*! \def ILibAsyncSocket_Send
\brief Sends data onto the TCP stream
\param socketModule The \a ILibAsyncSocket_SocketModule to send data on
\param buffer The data to be sent
\param length The length of \a buffer
\param UserFree The \a ILibAsyncSocket_MemoryOwnership enumeration, that identifies how the memory pointer to by \a buffer is to be handled
\returns \a ILibAsyncSocket_SendStatus indicating the send status
*/
#define ILibAsyncSocket_Send(socketModule, buffer, length, UserFree) ILibAsyncSocket_SendTo(socketModule, buffer, length, NULL, UserFree)
void ILibAsyncSocket_Disconnect(ILibAsyncSocket_SocketModule socketModule);
void ILibAsyncSocket_GetBuffer(ILibAsyncSocket_SocketModule socketModule, char **buffer, int *BeginPointer, int *EndPointer);
#if defined(WIN32)
void ILibAsyncSocket_UseThisSocket(ILibAsyncSocket_SocketModule socketModule, SOCKET UseThisSocket, ILibAsyncSocket_OnInterrupt InterruptPtr, void *user);
#elif defined(_POSIX)
void ILibAsyncSocket_UseThisSocket(ILibAsyncSocket_SocketModule socketModule, int UseThisSocket, ILibAsyncSocket_OnInterrupt InterruptPtr, void *user);
#endif
void ILibAsyncSocket_SetRemoteAddress(ILibAsyncSocket_SocketModule socketModule, struct sockaddr *remoteAddress);
void ILibAsyncSocket_SetLocalInterface(ILibAsyncSocket_SocketModule module, struct sockaddr *localAddress);
int ILibAsyncSocket_IsFree(ILibAsyncSocket_SocketModule socketModule);
int ILibAsyncSocket_IsConnected(ILibAsyncSocket_SocketModule socketModule);
int ILibAsyncSocket_GetLocalInterface(ILibAsyncSocket_SocketModule socketModule, struct sockaddr *localAddress);
int ILibAsyncSocket_GetRemoteInterface(ILibAsyncSocket_SocketModule socketModule, struct sockaddr *remoteAddress);
unsigned short ILibAsyncSocket_GetLocalPort(ILibAsyncSocket_SocketModule socketModule);
void ILibAsyncSocket_Resume(ILibAsyncSocket_SocketModule socketModule);
void ILibAsyncSocket_Pause(ILibAsyncSocket_SocketModule socketModule);
int ILibAsyncSocket_WasClosedBecauseBufferSizeExceeded(ILibAsyncSocket_SocketModule socketModule);
void ILibAsyncSocket_SetMaximumBufferSize(ILibAsyncSocket_SocketModule module, int maxSize, ILibAsyncSocket_OnBufferSizeExceeded OnBufferSizeExceededCallback, void *user);
void ILibAsyncSocket_SetSendOK(ILibAsyncSocket_SocketModule module, ILibAsyncSocket_OnSendOK OnSendOK);
int ILibAsyncSocket_IsIPv6LinkLocal(struct sockaddr *LocalAddress);
int ILibAsyncSocket_IsModuleIPv6LinkLocal(ILibAsyncSocket_SocketModule module);
typedef void(*ILibAsyncSocket_TimeoutHandler)(ILibAsyncSocket_SocketModule module, void *user);
void ILibAsyncSocket_SetTimeout(ILibAsyncSocket_SocketModule module, int timeoutSeconds, ILibAsyncSocket_TimeoutHandler timeoutHandler);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,833 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
/*
Real LMS code can be found here: http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers
*/
#if !defined(_NOHECI)
#if defined(WIN32) && !defined(_MINCORE)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#if defined(WINSOCK2)
#include <winsock2.h>
#include <ws2ipdef.h>
#elif defined(WINSOCK1)
#include <winsock.h>
#include <wininet.h>
#endif
#include "ILibParsers.h"
#include "ILibAsyncSocket.h"
#include "ILibAsyncServerSocket.h"
#ifdef WIN32
#include "../heci/heciwin.h"
#include "WinBase.h"
#endif
#ifdef _POSIX
#include "../heci/HECILinux.h"
#define UNREFERENCED_PARAMETER(P) (P)
#endif
#include "../heci/PTHICommand.h"
#include "../heci/LMEConnection.h"
#define INET_SOCKADDR_LENGTH(x) ((x==AF_INET6?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)))
#define LMS_MAX_CONNECTIONS 16 // Maximum is 32
#define LMS_MAX_SESSIONS 32
// #define _DEBUGLMS
#ifdef _DEBUGLMS
#define LMSDEBUG(...) printf(__VA_ARGS__);
#else
#define LMSDEBUG(...)
#endif
char * g_SelfLMSDir=NULL;
int LastId = 2;
struct ILibLMS_StateModule* IlibExternLMS = NULL; // Glocal pointer to the LMS module. Since we can only have one of these modules running, a global pointer is sometimes useful.
void ILibLMS_SetupConnection(struct ILibLMS_StateModule* module, int i);
void ILibLMS_LaunchHoldingSessions(struct ILibLMS_StateModule* module);
// Each LMS session can be in one of these states.
enum LME_CHANNEL_STATUS {
LME_CS_FREE = 0, // The session slot is free, can be used at any time.
LME_CS_PENDING_CONNECT = 1, // A connection as been made to LMS and a notice has been send to Intel AMT asking for a CHANNEL OPEN.
LME_CS_CONNECTED = 2, // Intel AMT confirmed the connection and data can flow in both directions.
LME_CS_PENDING_LMS_DISCONNECT = 3, // The connection to LMS was disconnected, Intel AMT has been notified and we are waitting for Intel AMT confirmation.
LME_CS_PENDING_AMT_DISCONNECT = 4, // Intel AMT decided to close the connection. We are disconnecting the LMS TCP connection.
LME_CS_HOLDING = 5, // We got too much data from the LMS TCP connection, more than Intel AMT can handle. We are holding the connection until AMT can handle more.
LME_CS_CONNECTION_WAIT = 6 // A TCP connection to LMS was made, but there all LMS connections are currently busy. Waitting for one to free up.
};
// This is the structure for a session
struct LMEChannel
{
int ourid; // The iddentifier of this channel on our side, this is the same as the index in the "Channel Sessions[LMS_MAX_SESSIONS];" array below.
int amtid; // The Intel AMT identifier for this channel.
enum LME_CHANNEL_STATUS status; // Current status of the channel.
int sockettype; // Type of connected socket: 0 = TCP, 1 = WebSocket
void* socketmodule; // The microstack associated with the LMS connection.
int txwindow; // Transmit window.
int rxwindow; // Receive window.
unsigned short localport; // The Intel AMT connection port.
int errorcount; // Open channel error count.
char* pending; // Buffer pointing to pending data that needs to be sent to Intel AMT, used for websocket only.
int pendingcount; // Buffer pointing to pending data size that needs to be sent to Intel AMT, used for websocket only.
int pendingptr; // Pointer to start of the pending buffer.
};
enum LME_VERSION_HANDSHAKING {
LME_NOT_INITIATED,
LME_INITIATED,
LME_AGREED
};
enum LME_SERVICE_STATUS {
LME_NOT_STARTED,
LME_STARTED
};
// This is the Intel AMT LMS chain module structure
struct ILibLMS_StateModule
{
ILibChain_Link ChainLink;
void *Server1; // Microstack TCP server for port 16992
void *Server2; // Microstack TCP server for port 16993
void *ControlSocket; // Pointer to the LMS control web socket, NULL if not connected.
struct LMEConnection MeConnection; // The MEI connection structure
struct LMEChannel Sessions[LMS_MAX_SESSIONS]; // List of sessions
//ILibWebServer_ServerToken WebServer; // LMS Web Server
enum LME_VERSION_HANDSHAKING handshakingStatus;
enum LME_SERVICE_STATUS pfwdService;
unsigned int AmtProtVersionMajor; // Intel AMT MEI major version
unsigned int AmtProtVersionMinor; // Intel AMT MEI minor version
sem_t Lock; // Global lock, this is needed because MEI listener is a different thread from the microstack thread
};
/*
// Convert a block of data to HEX
// The "out" must have (len*2)+1 free space.
char utils_HexTable[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
char* __fastcall util_tohex(char* data, int len, char* out)
{
int i;
char *p = out;
if (data == NULL || len == 0) { *p = 0; return NULL; }
for (i = 0; i < len; i++)
{
*(p++) = utils_HexTable[((unsigned char)data[i]) >> 4];
*(p++) = utils_HexTable[((unsigned char)data[i]) & 0x0F];
}
*p = 0;
return out;
}
*/
int GetFreeSlot(struct ILibLMS_StateModule* module){
int i;
int cur = LastId;
// Look for an empty session
for (i = 0; i < LMS_MAX_SESSIONS-3; i++) {
cur++;
if (cur >= LMS_MAX_SESSIONS){
cur = 3;
}
if (module->Sessions[cur].status == LME_CS_FREE) {
LastId = cur;
return cur;
}
}
return -1;
}
//int GetFreeSlot(struct ILibLMS_StateModule* module){
// int i;
// for (i = 0; i < LMS_MAX_SESSIONS - 3; i++) {
// if (cur >= LMS_MAX_SESSIONS){
// cur = 3;
// }
// if (module->Sessions[cur].status == LME_CS_FREE) {
// LastId = cur;
// return cur;
// }
// }
// return -1;
//}
// This function is called each time a MEI message is received from Intel AMT
void ILibLMS_MEICallback(struct LMEConnection* lmemodule, void *param, void *rxBuffer, unsigned int len)
{
struct ILibLMS_StateModule* module = (struct ILibLMS_StateModule*)param;
int disconnects = 0; // This is a counter of how many sessions are freed up. We use this at the end to place HOLDING sessions into free slots.
//ILibAsyncServerSocket_ServerModule newModule;
//ILibLinkedList list;
//void* node;
//ILibTransport* curModule;
// Happens when the chain is being destroyed, don't call anything chain related.
if (rxBuffer == NULL) return;
sem_wait(&(module->Lock));
LMSDEBUG("ILibLMS_MEICallback %d\r\n", ((unsigned char*)rxBuffer)[0]);
switch (((unsigned char*)rxBuffer)[0])
{
case APF_GLOBAL_REQUEST: // 80
{
int request = 0;
unsigned char *pCurrent;
APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer;
pHeader->StringLength = ntohl(pHeader->StringLength);
if (pHeader->StringLength == APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST) && memcmp(pHeader->String, APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST, APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST)) == 0) { request = 1; }
else if (pHeader->StringLength == APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST) && memcmp(pHeader->String, APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST, APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST)) == 0) { request = 2; }
else if (pHeader->StringLength == APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_UDP_SEND_TO) && memcmp(pHeader->String, APF_GLOBAL_REQUEST_STR_UDP_SEND_TO, APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_UDP_SEND_TO)) == 0) { request = 3; }
if (request == 1 || request == 2)
{
int port = 0;
unsigned int len2;
unsigned int bytesRead = len;
unsigned int hsize=0;
if (request==1)
hsize = sizeof(APF_GENERIC_HEADER) + APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST) + sizeof(UINT8);
else if (request==2)
hsize = sizeof(APF_GENERIC_HEADER) + APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST) + sizeof(UINT8);
pCurrent = (unsigned char*)rxBuffer + hsize;
bytesRead -= hsize;
if (bytesRead < sizeof(unsigned int)) {
LME_Deinit(lmemodule);
sem_post(&(module->Lock));
return;
}
len2 = ntohl(*((unsigned int *)pCurrent));
pCurrent += sizeof(unsigned int);
if (bytesRead < (sizeof(unsigned int) + len2 + sizeof(unsigned int))) {
LME_Deinit(lmemodule);
sem_post(&(module->Lock));
return;
}
// addr = (char*)pCurrent;
pCurrent += len2;
port = ntohl(*((unsigned int *)pCurrent));
if (request == 1)
{
//newModule = ILibCreateAsyncServerSocketModule(module->Chain, LMS_MAX_CONNECTIONS, port, 4096, 0, &ILibLMS_OnConnect, &ILibLMS_OnDisconnect, &ILibLMS_OnReceive, NULL, &ILibLMS_OnSendOK);
//if (newModule){
// ILibAsyncServerSocket_SetTag(newModule, module);
// LME_TcpForwardReplySuccess(lmemodule, port);
//}
//else{
// LME_TcpForwardReplyFailure(lmemodule);
//}
// New forwarding request
if (port == 16992 || port == 16993)
LME_TcpForwardReplySuccess(lmemodule, port);
else
LME_TcpForwardReplyFailure(lmemodule);
}
else
{
// Cancel a forwarding request
//list = ILibGetModuleList(module->Chain);
//node = ILibLinkedList_GetNode_Head(list);
//while (node != NULL){
// curModule = (ILibTransport*)ILibLinkedList_GetDataFromNode(node);
// if (curModule->IdentifierFlags == ILibTransports_ILibAsyncServerSocket){
// if (ILibAsyncServerSocket_GetPortNumber(curModule)){
// ILibAsyncServerSocket_Close(curModule);
// }
// }
// node = ILibLinkedList_GetNextNode(node);
//}
LME_TcpForwardCancelReplySuccess(lmemodule);
}
}
else if (request == 3)
{
// Send a UDP packet
// TODO: Send UDP
}
else{
// do nothing
}
}
break;
case APF_CHANNEL_OPEN: // (90) Sent by Intel AMT when a channel needs to be open from Intel AMT. This is not common, but WSMAN events are a good example of channel coming from AMT.
{
APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer;
if (pHeader->StringLength == APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_DIRECT) && memcmp((char*)pHeader->String, APF_OPEN_CHANNEL_REQUEST_DIRECT, APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_DIRECT)) == 0)
{
unsigned int len2;
unsigned char *pCurrent;
struct LMEChannelOpenRequestMessage channelOpenRequest;
if (len < sizeof(APF_GENERIC_HEADER) + ntohl(pHeader->StringLength) + 7 + (5 * sizeof(UINT32))) { LME_Deinit(lmemodule); sem_post(&(module->Lock)); return; }
pCurrent = (unsigned char*)rxBuffer + sizeof(APF_GENERIC_HEADER) + APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_DIRECT);
channelOpenRequest.ChannelType = APF_CHANNEL_DIRECT;
channelOpenRequest.SenderChannel = ntohl(*((UINT32 *)pCurrent));
pCurrent += sizeof(UINT32);
channelOpenRequest.InitialWindow = ntohl(*((UINT32 *)pCurrent));
pCurrent += 2 * sizeof(UINT32);
len2 = ntohl(*((UINT32 *)pCurrent));
pCurrent += sizeof(UINT32);
channelOpenRequest.Address = (char*)pCurrent;
pCurrent += len2;
channelOpenRequest.Port = ntohl(*((UINT32 *)pCurrent));
pCurrent += sizeof(UINT32);
LME_ChannelOpenReplyFailure(lmemodule, channelOpenRequest.SenderChannel, OPEN_FAILURE_REASON_CONNECT_FAILED);
}
}
break;
case APF_DISCONNECT: // (1) Intel AMT wants to completely disconnect. Not sure when this happens.
{
// First, we decode the message.
struct LMEDisconnectMessage disconnectMessage;
disconnectMessage.MessageType = APF_DISCONNECT;
disconnectMessage.ReasonCode = ((APF_DISCONNECT_REASON_CODE)ntohl(((APF_DISCONNECT_MESSAGE *)rxBuffer)->ReasonCode));
LMSDEBUG("LME requested to disconnect with reason code 0x%08x\r\n", disconnectMessage.ReasonCode);
LME_Deinit(lmemodule);
}
break;
case APF_SERVICE_REQUEST: // (5)
{
int service = 0;
APF_SERVICE_REQUEST_MESSAGE *pMessage = (APF_SERVICE_REQUEST_MESSAGE *)rxBuffer;
pMessage->ServiceNameLength = ntohl(pMessage->ServiceNameLength);
if (pMessage->ServiceNameLength == 18) {
if (memcmp(pMessage->ServiceName, "pfwd@amt.intel.com", 18) == 0) service = 1;
else if (memcmp(pMessage->ServiceName, "auth@amt.intel.com", 18) == 0) service = 2;
}
if (service > 0)
{
if (service == 1)
{
LME_ServiceAccept(lmemodule, "pfwd@amt.intel.com");
module->pfwdService = LME_STARTED;
}
else if (service == 2)
{
LME_ServiceAccept(lmemodule, "auth@amt.intel.com");
}
} else {
LMSDEBUG("APF_SERVICE_REQUEST - APF_DISCONNECT_SERVICE_NOT_AVAILABLE\r\n");
LME_Disconnect(lmemodule, APF_DISCONNECT_SERVICE_NOT_AVAILABLE);
LME_Deinit(lmemodule);
sem_post(&(module->Lock));
return;
}
}
break;
case APF_CHANNEL_OPEN_CONFIRMATION: // (91) Intel AMT confirmation to an APF_CHANNEL_OPEN request.
{
// First, we decode the message.
struct LMEChannel* channel;
APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE *pMessage = (APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE *)rxBuffer;
struct LMEChannelOpenReplySuccessMessage channelOpenReply;
channelOpenReply.RecipientChannel = ntohl(pMessage->RecipientChannel); // This is the identifier on our side.
channelOpenReply.SenderChannel = ntohl(pMessage->SenderChannel); // This is the identifier on the Intel AMT side.
channelOpenReply.InitialWindow = ntohl(pMessage->InitialWindowSize); // This is the starting window size for flow control.
channel = &(module->Sessions[channelOpenReply.RecipientChannel]); // Get the current session for this message.
if (channel == NULL)
break; // This should never happen.
LMSDEBUG("MEI OPEN OK OUR:%d AMT:%d\r\n", channelOpenReply.RecipientChannel, channelOpenReply.SenderChannel);
if (channel->status == LME_CS_PENDING_CONNECT) // If the channel is in PENDING_CONNECT mode, move the session to connected state.
{
channel->amtid = channelOpenReply.SenderChannel; // We have to set the Intel AMT identifier for this session.
channel->txwindow = channelOpenReply.InitialWindow; // Set the session txwindow.
channel->status = LME_CS_CONNECTED; // Now set the session as CONNECTED.
LMSDEBUG("Channel %d now CONNECTED by AMT %d\r\n", channel->ourid, channel->socketmodule);
if (channel->sockettype == 0) // If the current socket is PAUSED, lets resume it so data can start flowing again.
{
ILibAsyncSocket_Resume(channel->socketmodule); // TCP socket resume
}
}
else if (channel->status == LME_CS_PENDING_LMS_DISCONNECT) // If the channel is in PENDING_DISCONNECT, we have to disconnect the session now. Happens when we disconnect while connection is pending. We don't want to stop a channel during connection, that is bad.
{
channel->amtid = channelOpenReply.SenderChannel; // We have to set the Intel AMT identifier for this session.
LME_ChannelClose(&(module->MeConnection), channel->amtid, channel->ourid); // Send the Intel AMT close. We keep the channel in LME_CS_PENDING_LMS_DISCONNECT state until the close is confirmed.
LMSDEBUG("Channel %d now CONNECTED by AMT %d, but CLOSING it now\r\n", channel->ourid, channel->socketmodule);
}
else
{
// Here, we get an APF_CHANNEL_OPEN in an unexpected state, this should never happen.
LMSDEBUG("Channel %d, unexpected CONNECTED by AMT %d\r\n", channel->ourid, channel->socketmodule);
}
}
break;
case APF_CHANNEL_OPEN_FAILURE: // (92) Intel AMT rejected our connection attempt.
{
// First, we decode the message.
struct LMEChannel* channel;
APF_CHANNEL_OPEN_FAILURE_MESSAGE *pMessage = (APF_CHANNEL_OPEN_FAILURE_MESSAGE *)rxBuffer;
struct LMEChannelOpenReplyFailureMessage channelOpenReply;
channelOpenReply.RecipientChannel = ntohl(pMessage->RecipientChannel); // This is the identifier on our side.
channelOpenReply.ReasonCode = (OPEN_FAILURE_REASON)(ntohl(pMessage->ReasonCode)); // Get the error reason code.
channel = &(module->Sessions[channelOpenReply.RecipientChannel]); // Get the current session for this message.
if (channel == NULL) break; // This should never happen.
LMSDEBUG("**OPEN FAIL OUR:%d ERR:%d\r\n", channelOpenReply.RecipientChannel, channelOpenReply.ReasonCode);
if (channel->errorcount++ >= 0 || channel->status == LME_CS_PENDING_LMS_DISCONNECT)
{
// Fail connection
channel->status = LME_CS_FREE;
LMSDEBUG("Channel %d now FREE by AMT\r\n", channel->ourid);
sem_post(&(module->Lock));
ILibAsyncSocket_Disconnect(channel->socketmodule);
//ILibLMS_LaunchHoldingSessions(module);
return;
}
else
{
// Try again
//ILibLMS_SetupConnection(module, channel->ourid);
}
}
break;
case APF_CHANNEL_CLOSE: // (97) Intel AMT is closing this channel, we need to disconnect the LMS TCP connection
{
// First, we decode the message.
struct LMEChannel* channel;
APF_CHANNEL_CLOSE_MESSAGE *pMessage = (APF_CHANNEL_CLOSE_MESSAGE *)rxBuffer;
struct LMEChannelCloseMessage channelClose;
channelClose.RecipientChannel = ntohl(pMessage->RecipientChannel); // This is the identifier on our side.
channel = &(module->Sessions[channelClose.RecipientChannel]); // Get the current session for this message.
if (channel == NULL) break; // This should never happen.
//LMSDEBUG("CLOSE OUR:%d\r\n", channelClose.RecipientChannel);
if (channel->status == LME_CS_CONNECTED)
{
if (ILibAsyncSocket_IsConnected(channel->socketmodule))
{
channel->status = LME_CS_PENDING_AMT_DISCONNECT;
LMSDEBUG("Channel %d now PENDING_AMT_DISCONNECT by AMT, calling microstack disconnect %d\r\n", channel->ourid, channel->socketmodule);
LME_ChannelClose(lmemodule, channel->amtid, channel->ourid);
sem_post(&(module->Lock));
if (channel->sockettype == 0) // If the current socket is PAUSED, lets resume it so data can start flowing again.
{
ILibAsyncSocket_Disconnect(channel->socketmodule); // TCP socket close
}
sem_wait(&(module->Lock));
channel->status = LME_CS_FREE;
disconnects++;
LMSDEBUG("Channel %d now FREE by AMT\r\n", channel->ourid);
}
else
{
channel->status = LME_CS_FREE;
disconnects++;
LMSDEBUG("Channel %d now FREE by AMT\r\n", channel->ourid);
}
}
else if (channel->status == LME_CS_PENDING_LMS_DISCONNECT)
{
channel->status = LME_CS_FREE;
disconnects++;
LMSDEBUG("Channel %d now FREE by AMT\r\n", channel->ourid);
}
else
{
LMSDEBUG("Channel %d CLOSE, UNEXPECTED STATE %d\r\n", channel->ourid, channel->status);
}
}
break;
case APF_CHANNEL_DATA: // (94) Intel AMT is sending data that we must relay into an LMS TCP connection.
{
//sem_wait(&(module->Lock));
struct LMEChannel* channel;
APF_CHANNEL_DATA_MESSAGE *pMessage = (APF_CHANNEL_DATA_MESSAGE *)rxBuffer;
struct LMEChannelDataMessage channelData;
enum ILibAsyncSocket_SendStatus r;
channelData.MessageType = APF_CHANNEL_DATA;
channelData.RecipientChannel = ntohl(pMessage->RecipientChannel);
channelData.DataLength = ntohl(pMessage->DataLength);
channelData.Data = (unsigned char*)rxBuffer + sizeof(APF_CHANNEL_DATA_MESSAGE);
channel = &(module->Sessions[channelData.RecipientChannel]);
if (channel == NULL || channel->socketmodule == NULL){
sem_post(&(module->Lock));
break;
}
if (channel->sockettype == 0)
{
r = ILibAsyncSocket_Send(channel->socketmodule, (char*)(channelData.Data), channelData.DataLength, ILibAsyncSocket_MemoryOwnership_USER); // TCP socket
}
channel->rxwindow += channelData.DataLength;
if (r == ILibAsyncSocket_ALL_DATA_SENT && channel->rxwindow > 1024) {
LME_ChannelWindowAdjust(lmemodule, channel->amtid, channel->rxwindow); channel->rxwindow = 0;
}
//sem_post(&(module->Lock));
}
break;
case APF_CHANNEL_WINDOW_ADJUST: // 93
{
//sem_wait(&(module->Lock));
struct LMEChannel* channel;
APF_WINDOW_ADJUST_MESSAGE *pMessage = (APF_WINDOW_ADJUST_MESSAGE *)rxBuffer;
struct LMEChannelWindowAdjustMessage channelWindowAdjust;
channelWindowAdjust.MessageType = APF_CHANNEL_WINDOW_ADJUST;
channelWindowAdjust.RecipientChannel = ntohl(pMessage->RecipientChannel);
channelWindowAdjust.BytesToAdd = ntohl(pMessage->BytesToAdd);
channel = &(module->Sessions[channelWindowAdjust.RecipientChannel]);
if (channel == NULL || channel->status == LME_CS_FREE){
sem_post(&(module->Lock));
break;
}
channel->txwindow += channelWindowAdjust.BytesToAdd;
if (channel->sockettype == 0)
{
ILibAsyncSocket_Resume(channel->socketmodule); // TCP socket
}
//sem_post(&(module->Lock));
}
break;
case APF_PROTOCOLVERSION: // 192
{
APF_PROTOCOL_VERSION_MESSAGE *pMessage = (APF_PROTOCOL_VERSION_MESSAGE *)rxBuffer;
struct LMEProtocolVersionMessage protVersion;
protVersion.MajorVersion = ntohl(pMessage->MajorVersion);
protVersion.MinorVersion = ntohl(pMessage->MinorVersion);
protVersion.TriggerReason = (APF_TRIGGER_REASON)ntohl(pMessage->TriggerReason);
switch (module->handshakingStatus)
{
case LME_AGREED:
case LME_NOT_INITIATED:
{
LME_ProtocolVersion(lmemodule, 1, 0, protVersion.TriggerReason);
}
case LME_INITIATED:
if (protVersion.MajorVersion != 1 || protVersion.MinorVersion != 0)
{
LMSDEBUG("LME Version %d.%d is not supported.\r\n", protVersion.MajorVersion, protVersion.MinorVersion);
LME_Disconnect(lmemodule, APF_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED);
LME_Deinit(lmemodule);
sem_post(&(module->Lock));
return;
}
module->AmtProtVersionMajor = protVersion.MajorVersion;
module->AmtProtVersionMinor = protVersion.MinorVersion;
module->handshakingStatus = LME_AGREED;
break;
default:
LME_Disconnect(lmemodule, APF_DISCONNECT_BY_APPLICATION);
LME_Deinit(lmemodule);
break;
}
}
break;
case APF_USERAUTH_REQUEST: // 50
{
// _lme.UserAuthSuccess();
}
break;
default:
// Unknown request.
LMSDEBUG("**Unknown LME command: %d\r\n", ((unsigned char*)rxBuffer)[0]);
LME_Disconnect(lmemodule, APF_DISCONNECT_PROTOCOL_ERROR);
LME_Deinit(lmemodule);
break;
}
sem_post(&(module->Lock));
//if (disconnects > 0) ILibLMS_LaunchHoldingSessions(module); // If disconnects is set to anything, we have free session slots we can fill up.
}
void ILibLMS_OnReceive(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, char* buffer, int *p_beginPointer, int endPointer, ILibAsyncServerSocket_OnInterrupt *OnInterrupt, void **user, int *PAUSE)
{
int r, maxread = endPointer;
struct ILibLMS_StateModule* module = (struct ILibLMS_StateModule*)ILibAsyncServerSocket_GetTag(AsyncServerSocketModule);
struct LMEChannel* channel = (struct LMEChannel*)*user;
UNREFERENCED_PARAMETER( AsyncServerSocketModule );
UNREFERENCED_PARAMETER( ConnectionToken );
UNREFERENCED_PARAMETER( OnInterrupt );
UNREFERENCED_PARAMETER( PAUSE );
if (channel == NULL) return;
sem_wait(&(module->Lock));
if (channel->socketmodule != ConnectionToken) { sem_post(&(module->Lock)); ILibAsyncSocket_Disconnect(ConnectionToken); return; }
if (channel->txwindow < endPointer) maxread = channel->txwindow;
if (channel->status != LME_CS_CONNECTED || maxread == 0) { *PAUSE = 1; sem_post(&(module->Lock)); return; }
//printf("%.*s", maxread, buffer);
r = LME_ChannelData(&(module->MeConnection), channel->amtid, maxread, (unsigned char*)buffer);
//LMSDEBUG("ILibLMS_OnReceive, status = %d, txwindow = %d, endPointer = %d, r = %d\r\n", channel->status, channel->txwindow, endPointer, r);
if (r != maxread)
{
//LMSDEBUG("ILibLMS_OnReceive, DISCONNECT %d\r\n", channel->ourid);
sem_post(&(module->Lock));
ILibAsyncSocket_Disconnect(ConnectionToken); // Drop the connection
return;
}
channel->txwindow -= maxread;
*p_beginPointer = maxread;
sem_post(&(module->Lock));
}
void ILibLMS_SetupConnection(struct ILibLMS_StateModule* module, int i)
{
int rport = 0;
char* laddr = NULL;
struct sockaddr_in6 remoteAddress;
if (module->Sessions[i].sockettype == 0)
{
// Fetch the socket remote TCP address
ILibAsyncSocket_GetRemoteInterface(module->Sessions[i].socketmodule, (struct sockaddr*)&remoteAddress);
if (remoteAddress.sin6_family == AF_INET6)
{
laddr = "::1"; // TODO: decode this properly into a string
rport = ntohs(remoteAddress.sin6_port);
}
else
{
laddr = "127.0.0.1"; // TODO: decode this properly into a string
rport = ntohs(((struct sockaddr_in*)(&remoteAddress))->sin_port);
}
}
else
{
// Fetch the socket remote web socket address
laddr = "127.0.0.1"; // TODO: decode this properly into a string
rport = 123; // TODO: decode the remote port
}
// Setup a new LME session
LME_ChannelOpenForwardedRequest(&(module->MeConnection), (unsigned int)i, laddr, module->Sessions[i].localport, laddr, rport);
//LMSDEBUG("ILibLMS_OnReceive, CONNECT %d\r\n", i);
}
int OnConnect = 0;
void ILibLMS_OnConnect(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void **user)
{
OnConnect++;
LMSDEBUG("OnCOnnect:%d", OnConnect);
int i, sessionid = -1, activecount = 0;
struct ILibLMS_StateModule* module = (struct ILibLMS_StateModule*)ILibAsyncServerSocket_GetTag(AsyncServerSocketModule);
sem_wait(&(module->Lock));
// Count the number of active sessions
activecount = LMS_MAX_SESSIONS;
for (i = 0; i < LMS_MAX_SESSIONS; i++) {
if (module->Sessions[i].status == LME_CS_FREE || module->Sessions[i].status == LME_CS_CONNECTION_WAIT) {
activecount--;
}
}
sessionid=GetFreeSlot(module);
// Look for an empty session
//for (i = 1; i < LMS_MAX_SESSIONS; i++) {
// if (module->Sessions[i].status == LME_CS_FREE) {
// sessionid = i;
// break;
// }
//}
if (sessionid == -1)
{
sem_post(&(module->Lock));
LMSDEBUG("ILibLMS_OnConnect NO SESSION SLOTS AVAILABLE\r\n");
ILibAsyncSocket_Disconnect(ConnectionToken); // Drop the connection
return;
}
i = sessionid;
// LMSDEBUG("USING SLOT OUR:%d\r\n", i);
module->Sessions[i].amtid = -1;
module->Sessions[i].ourid = i;
module->Sessions[i].sockettype = 0; // TCP Type
module->Sessions[i].socketmodule = ConnectionToken;
module->Sessions[i].rxwindow = 0;
module->Sessions[i].txwindow = 0;
module->Sessions[i].localport = ILibAsyncServerSocket_GetPortNumber(AsyncServerSocketModule);
module->Sessions[i].errorcount = 0;
*user = &(module->Sessions[i]);
/*
if (activecount >= LMS_MAX_CONNECTIONS)
{
module->Sessions[i].status = LME_CS_CONNECTION_WAIT;
LMSDEBUG("ILibLMS_OnConnect %d (HOLDING)\r\n", i);
}
else
*/
{
module->Sessions[i].status = LME_CS_PENDING_CONNECT;
LMSDEBUG("ILibLMS_OnConnect %d\r\n", i);
ILibLMS_SetupConnection(module, i);
}
sem_post(&(module->Lock));
}
void ILibLMS_OnDisconnect(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user)
{
int disconnects = 0;
struct ILibLMS_StateModule* module = (struct ILibLMS_StateModule*)ILibAsyncServerSocket_GetTag(AsyncServerSocketModule);
struct LMEChannel* channel = (struct LMEChannel*)user;
UNREFERENCED_PARAMETER( ConnectionToken );
sem_wait(&(module->Lock));
if (channel == NULL || channel->socketmodule != ConnectionToken)
{
LMSDEBUG("****ILibLMS_OnDisconnect EXIT\r\n");
sem_post(&(module->Lock));
return;
}
LMSDEBUG("ILibLMS_OnDisconnect, Channel %d, %d\r\n", channel->ourid, ConnectionToken);
if (channel->status == LME_CS_CONNECTED)
{
channel->status = LME_CS_PENDING_LMS_DISCONNECT;
if (channel->amtid!=-1 && !LME_ChannelClose(&(module->MeConnection), channel->amtid, channel->ourid))
{
channel->status = LME_CS_FREE;
disconnects++;
LMSDEBUG("Channel %d now FREE by LMS because of failed close\r\n", channel->ourid);
}
else
{
LMSDEBUG("Channel %d now PENDING_LMS_DISCONNECT by LMS\r\n", channel->ourid);
//LMSDEBUG("LME_ChannelClose OK\r\n");
}
}
else if (channel->status == LME_CS_PENDING_CONNECT)
{
channel->status = LME_CS_PENDING_LMS_DISCONNECT;
LMSDEBUG("Channel %d now PENDING_DISCONNECT by LMS\r\n", channel->ourid);
}
else if (channel->status == LME_CS_CONNECTION_WAIT)
{
channel->status = LME_CS_FREE;
disconnects++;
LMSDEBUG("Channel %d now FREE by LMS\r\n", channel->ourid);
}
//LMSDEBUG("ILibLMS_OnDisconnect, DISCONNECT %d, status = %d\r\n", channel->ourid, channel->status);
sem_post(&(module->Lock));
//if (disconnects > 0) ILibLMS_LaunchHoldingSessions(module);
}
void ILibLMS_OnSendOK(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user)
{
struct ILibLMS_StateModule* module = (struct ILibLMS_StateModule*)ILibAsyncServerSocket_GetTag(AsyncServerSocketModule);
struct LMEChannel* channel = (struct LMEChannel*)user;
UNREFERENCED_PARAMETER( ConnectionToken );
// Ok to send more on this socket, adjust the window
sem_wait(&(module->Lock));
if (channel->rxwindow != 0)
{
//LMSDEBUG("LME_ChannelWindowAdjust id=%d, rxwindow=%d\r\n", channel->amtid, channel->rxwindow);
LME_ChannelWindowAdjust(&(module->MeConnection), channel->amtid, channel->rxwindow);
channel->rxwindow = 0;
}
sem_post(&(module->Lock));
}
// Private method called when the chain is destroyed, we want to do our cleanup here
void ILibLMS_Destroy(void *object)
{
struct ILibLMS_StateModule* module = (struct ILibLMS_StateModule*)object;
UNREFERENCED_PARAMETER( object );
sem_wait(&(module->Lock));
LME_Disconnect(&(module->MeConnection), APF_DISCONNECT_BY_APPLICATION);
LME_Exit(&(module->MeConnection));
sem_destroy(&(module->Lock));
if (IlibExternLMS == module) { IlibExternLMS = NULL; } // Clear the global reference to the the LMS module.
}
// Create a new Reflector module.
struct ILibLMS_StateModule *ILibLMS_Create(void *Chain)
{
struct ILibLMS_StateModule *module;
// Allocate the new module
module = (struct ILibLMS_StateModule*)malloc(sizeof(struct ILibLMS_StateModule));
if (module == NULL) { ILIBCRITICALEXIT(254); }
memset(module, 0, sizeof(struct ILibLMS_StateModule));
// Setup MEI with LMS interface, if we can't return null
if (LME_Init(&(module->MeConnection), &ILibLMS_MEICallback, module) == 0) {
free(module);
return NULL;
}
// Setup the module
module->ChainLink.DestroyHandler = &ILibLMS_Destroy;
module->ChainLink.ParentChain = Chain;
sem_init(&(module->Lock), 0, 1);
// TCP servers
module->Server1 = ILibCreateAsyncServerSocketModule(Chain, LMS_MAX_CONNECTIONS, 16992, 4096, 0, &ILibLMS_OnConnect, &ILibLMS_OnDisconnect, &ILibLMS_OnReceive, NULL, &ILibLMS_OnSendOK);
if (module->Server1 == NULL) { sem_destroy(&(module->Lock)); free(module); return NULL; }
ILibAsyncServerSocket_SetTag(module->Server1, module);
module->Server2 = ILibCreateAsyncServerSocketModule(Chain, LMS_MAX_CONNECTIONS, 16993, 4096, 0, &ILibLMS_OnConnect, &ILibLMS_OnDisconnect, &ILibLMS_OnReceive, NULL, &ILibLMS_OnSendOK);
if (module->Server2 == NULL) { sem_destroy(&(module->Lock)); free(module->Server1); free(module); return NULL; }
ILibAsyncServerSocket_SetTag(module->Server2, module);
// TODO: US6986 - The meshcommander site should not be served on localhost:16994.
// This code should be commented out - in the future(late 2018) IMC could be put there instead.
// Web Server
//module->WebServer = ILibWebServer_CreateEx(Chain, 8, 16994, 2, &ILibLMS_WebServer_OnSession, module);
IlibExternLMS = module; // Set the global reference to the LMS module.
ILibAddToChain(Chain, module); // Add this module to the chain.
return module;
}
#endif

View File

@@ -0,0 +1,25 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#if !defined(_NOHECI)
#ifndef __ILibLMS__
#define __ILibLMS__
#include "ILibAsyncServerSocket.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ILibLMS_StateModule *ILibLMS_Create(void *Chain);
#ifdef __cplusplus
}
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,94 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2011 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __ILIBREMOTELOGGING__
#define __ILIBREMOTELOGGING__
#include "ILibParsers.h"
/*! \defgroup ILibRemoteLogging ILibRemoteLogging Module
@{
*/
//! Module Types
typedef enum ILibRemoteLogging_Modules
{
ILibRemoteLogging_Modules_UNKNOWN = 0x00, //!< UNKNOWN Module
ILibRemoteLogging_Modules_Logger = 0x01, //!< RESERVED: Logger
ILibRemoteLogging_Modules_WebRTC_STUN_ICE = 0x02, //!< WebRTC: STUN/ICE
ILibRemoteLogging_Modules_WebRTC_DTLS = 0x04, //!< WebRTC: DTLS
ILibRemoteLogging_Modules_WebRTC_SCTP = 0x08, //!< WebRTC: SCTP
ILibRemoteLogging_Modules_Agent_GuardPost = 0x10, //!< Mesh Agent: Guard Post
ILibRemoteLogging_Modules_Agent_P2P = 0x20, //!< Mesh Agent: Peer to Peer
ILibRemoteLogging_Modules_Agent_KVM = 0x200, //!< Mesh AGent: KVM
ILibRemoteLogging_Modules_Microstack_AsyncSocket = 0x40, //!< Microstack: AsyncSocket, AsyncServerSocket, AsyncUDPSocket
ILibRemoteLogging_Modules_Microstack_Web = 0x80, //!< Microstack: WebServer, WebSocket, WebClient
ILibRemoteLogging_Modules_Microstack_Pipe = 0x400,//!< Microstack: Pipe
ILibRemoteLogging_Modules_Microstack_Generic = 0x100,//!< Microstack: Generic
ILibRemoteLogging_Modules_ConsolePrint = 0x4000
}ILibRemoteLogging_Modules;
//! Logging Flags
typedef enum ILibRemoteLogging_Flags
{
ILibRemoteLogging_Flags_NONE = 0x00, //!< NONE
ILibRemoteLogging_Flags_DisableLogging = 0x01, //!< DISABLED
ILibRemoteLogging_Flags_VerbosityLevel_1 = 0x02, //!< Verbosity Level 1
ILibRemoteLogging_Flags_VerbosityLevel_2 = 0x04, //!< Verbosity Level 2
ILibRemoteLogging_Flags_VerbosityLevel_3 = 0x08, //!< Verbosity Level 3
ILibRemoteLogging_Flags_VerbosityLevel_4 = 0x10, //!< Verbosity Level 4
ILibRemoteLogging_Flags_VerbosityLevel_5 = 0x20, //!< Verbosity Level 5
}ILibRemoteLogging_Flags;
typedef enum ILibRemoteLogging_Command_Logger_Flags
{
ILibRemoteLogging_Command_Logger_Flags_ENABLE = 0x100, //!< Enables/Disables File Logging
ILibRemoteLogging_Command_Logger_Flags_RESET_FILE = 0x200, //!< Erases the log file
ILibRemoteLogging_Command_Logger_Flags_READ_FILE = 0x400, //!< Reads the log file
ILibRemoteLogging_Command_Logger_Flags_RESET_FLAGS = 0x800, //!< Sets the Module/Flags to log to file
}ILibRemoteLogging_Command_Logger_Flags;
#define ILibTransports_RemoteLogging_FileTransport 0x70
typedef void* ILibRemoteLogging;
typedef void (*ILibRemoteLogging_OnWrite)(ILibRemoteLogging module, char* data, int dataLen, void *userContext);
typedef void (*ILibRemoteLogging_OnCommand)(ILibRemoteLogging sender, ILibRemoteLogging_Modules module, unsigned short flags, char* data, int dataLen, void *userContext);
typedef void(*ILibRemoteLogging_OnRawForward)(ILibRemoteLogging sender, ILibRemoteLogging_Modules module, ILibRemoteLogging_Flags flags, char *buffer, int bufferLen);
#ifdef _REMOTELOGGING
char* ILibRemoteLogging_ConvertAddress(struct sockaddr* addr);
char* ILibRemoteLogging_ConvertToHex(char* inVal, int inValLength);
void ILibRemoteLogging_printf(ILibRemoteLogging loggingModule, ILibRemoteLogging_Modules module, ILibRemoteLogging_Flags flags, char* format, ...);
ILibRemoteLogging ILibRemoteLogging_Create(ILibRemoteLogging_OnWrite onOutput);
ILibTransport* ILibRemoteLogging_CreateFileTransport(ILibRemoteLogging loggingModule, ILibRemoteLogging_Modules modules, ILibRemoteLogging_Flags flags, char* path, int pathLen);
void ILibRemoteLogging_Destroy(ILibRemoteLogging logger);
void ILibRemoteLogging_SetRawForward(ILibRemoteLogging logger, int bufferOffset, ILibRemoteLogging_OnRawForward onRawForward);
void ILibRemoteLogging_DeleteUserContext(ILibRemoteLogging logger, void *userContext);
void ILibRemoteLogging_RegisterCommandSink(ILibRemoteLogging logger, ILibRemoteLogging_Modules module, ILibRemoteLogging_OnCommand sink);
int ILibRemoteLogging_Dispatch(ILibRemoteLogging loggingModule, char* data, int dataLen, void *userContext);
#define ILibRemoteLogging_ReadModuleType(data) ((ILibRemoteLogging_Modules)ntohs(((unsigned short*)data)[0]))
#define ILibRemoteLogging_ReadFlags(data) ((ILibRemoteLogging_Flags)ntohs(((unsigned short*)data)[1]))
int ILibRemoteLogging_IsModuleSet(ILibRemoteLogging loggingModule, ILibRemoteLogging_Modules module);
void ILibRemoteLogging_Forward(ILibRemoteLogging loggingModule, char* data, int dataLen);
#else
#define ILibRemoteLogging_ConvertAddress(...) ;
#define ILibRemoteLogging_ConvertToHex(...) ;
#define ILibRemoteLogging_printf(...) ;
#define ILibRemoteLogging_Create(...) NULL;
#define ILibRemoteLogging_SetRawForward(...) ;
#define ILibRemoteLogging_CreateFileTransport(...) NULL;
#define ILibRemoteLogging_Destroy(...) ;
#define ILibRemoteLogging_DeleteUserContext(...) ;
#define ILibRemoteLogging_RegisterCommandSink(...) ;
#define ILibRemoteLogging_Dispatch(...) ;
#define ILibRemoteLogging_ReadModuleType(data) ILibRemoteLogging_Modules_UNKNOWN
#define ILibRemoteLogging_ReadFlags(data) ILibRemoteLogging_Flags_NONE
#define ILibRemoteLogging_IsModuleSet(...) 0
#define ILibRemoteLogging_Forward(...) ;
#endif
/*! @} */
#endif

View File

@@ -1,66 +1,46 @@
# Remote Provisioning Client (RPC)
# Remote Provisioning Client
RPC is an application which enables remote capabilities for AMT, such as as device activation. To accomplish this, RPC communicates with the RPS (Remote Provisioning Server).
> Disclaimer: Production viable releases are tagged and listed under 'Releases'. All other check-ins should be considered 'in-development' and should not be used in production
As a prerequisite, a Local Management Service (LMS) must be installed and running on the operating system.
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.
## Linux
<br><br>
Steps below are for Ubuntu 18.04.
**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/).
### Dependencies
<br>
- sudo apt install git cmake build-essential libboost-system-dev libboost-thread-dev libboost-random-dev libboost-regex-dev libboost-filesystem-dev libssl-dev zlib1g-dev
## Prerequisites
### Build
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.)
- mkdir build
- cd build
- cmake -DCMAKE_BUILD_TYPE=Release ..
- Build debug: cmake -DCMAKE_BUILD_TYPE=Debug ..
- cmake --build .
### Run
<p align="center">
<img src="assets/animations/forkandbuild.gif" width="650" />
</p>
- See ./rpc --help for details.
- Example
- sudo ./rpc --url wss://localhost:8080 --profile profile1
## Build the Remote Provisioning Client (RPC)
## Windows
1. <a href="https://github.com/open-amt-cloud-toolkit/rpc/fork" target="_blank">Create a fork of rpc on GitHub.</a>
Steps below are for Windows 10 and Visual Studio 2019 Professional.
2. Click on the **Actions** tab at the top and select **Build RPC (Native) Debug/Release**.
### Build VCPKG
3. Click the **Run Workflow** dropdown.
Open an x64 native command prompt for Visual Studio 2019 as Administrator.
4. Select the **Branch: master**, or a preferred version, from the **Use workflow from** dropdown.
- git clone --branch 2020.01 https://github.com/microsoft/vcpkg.git
- cd vcpkg
- bootstrap-vcpkg.bat
- vcpkg integrate install
5. By default, the Build Type should be **release**.
### Build C++ REST SDK
6. Click the **Run Workflow** button. Grab a coffee and take a break! The build time ranges from 15 to 20 minutes.
Open an x64 native tools command prompt for Visual Studio 2019.
8. Once the download is complete, click the completed job which will feature a green checkmark.
- cd vcpkg
- vcpkg install cpprestsdk:x64-windows-static
9. Download the appropriate RPC for your managed device's OS under the **Artifacts** section.
### Build
### To Delete your workflow run
Open an x64 native tools command prompt for Visual Studio 2019.
1. Click the ellipsis ( **...** ) menu for the workflow.
- mkdir build
- cd build
- cmake .. -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake
- cmake --build . --config Release
- Build debug: cmake --build . --config Debug
2. Choose the **Delete workflow run** option.
### Run
Open a command prompt as Administrator.
- See rpc.exe --help for details.
- Example
- cd build\Release
- rpc.exe --url wss://localhost:8080 --profile profile1
For detailed documentation about RPC and using it to activate a device, see the [docs](https://open-amt-cloud-toolkit.github.io/docs/)

5
SECURITY.md Normal file
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).

306
activation.cpp Normal file
View File

@@ -0,0 +1,306 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "activation.h"
#include <cpprest/ws_client.h>
#include <cpprest/json.h>
#include <cpprest/streams.h>
#include <iostream>
#include <string>
#include "version.h"
#include "commands.h"
#include "network.h"
#include "utils.h"
bool get_certificate_hashes(web::json::value& hashes)
{
std::vector<web::json::value> hashValues;
std::vector<cert_hash_entry> certHashes;
if (!cmd_get_certificate_hashes(certHashes))
{
return false;
}
for (cert_hash_entry hashString : certHashes)
{
hashValues.push_back(web::json::value::string(utility::conversions::convertstring(hashString.hash)));
}
hashes = web::json::value::array(hashValues);
return true;
}
bool get_uuid(web::json::value& value)
{
int i = 0;
std::vector<web::json::value> uuidValue;
std::vector<unsigned char> uuid;
if (!cmd_get_uuid(uuid)) return false;
for (unsigned char value : uuid)
{
uuidValue.push_back(web::json::value(uuid[i++]));
}
value = web::json::value::array(uuidValue);
return true;
}
std::string get_dns_info()
{
std::string dnsSuffix;
// get DNS according to AMT
cmd_get_dns_suffix(dnsSuffix);
if (!dnsSuffix.length())
{
// get DNS from OS
dnsSuffix = net_get_dns();
}
return dnsSuffix;
}
web::json::value get_dns()
{
utility::string_t tmp;
std::string dnsSuffix = get_dns_info();
tmp = utility::conversions::convertstring(dnsSuffix);
return web::json::value::string(tmp);
}
web::json::value get_hostname()
{
utility::string_t tmp;
std::string hostName = net_get_hostname();
tmp = utility::conversions::convertstring(hostName);
return web::json::value::string(tmp);
}
bool getVersion(web::json::value& value)
{
std::string version;
utility::string_t tmp;
if (!cmd_get_version(version)) return false;
tmp = utility::conversions::convertstring(version);
value = web::json::value::string(tmp);
return true;
}
bool get_sku(web::json::value& value)
{
std::string version;
utility::string_t tmp;
if (!cmd_get_sku(version)) return false;
tmp = utility::conversions::convertstring(version);
value = web::json::value::string(tmp);
return true;
}
bool get_build_number(web::json::value& value)
{
std::string version;
utility::string_t tmp;
if (!cmd_get_build_number(version)) return false;
tmp = utility::conversions::convertstring(version);
value = web::json::value::string(tmp);
return true;
}
bool get_local_system_account_username(web::json::value& value)
{
std::string username;
std::string password;
utility::string_t tmp;
if (!cmd_get_local_system_account(username, password)) return false;
tmp = utility::conversions::convertstring(username);
value = web::json::value::string(tmp);
return true;
}
bool get_local_system_account_password(web::json::value& value)
{
std::string username;
std::string password;
utility::string_t tmp;
if (!cmd_get_local_system_account(username, password)) return false;
tmp = utility::conversions::convertstring(password);
value = web::json::value::string(tmp);
return true;
}
bool get_control_mode(web::json::value& value)
{
int controlMode;
utility::string_t tmp;
if (!cmd_get_control_mode(controlMode)) return false;
value = web::json::value::number(controlMode);
return true;
}
bool get_client_string(web::json::value& value)
{
int controlMode;
utility::string_t tmp;
tmp = utility::conversions::convertstring("PPC");
value = web::json::value::string(tmp);
return true;
}
bool get_activation_payload(web::json::value& payload)
{
web::json::value value;
utility::string_t tmp;
web::json::value activationParams;
// get code version
if (!getVersion(value)) return false;
activationParams[U("ver")] = value;
if (!get_build_number(value)) return false;
activationParams[U("build")] = value;
if (!get_sku(value)) return false;
activationParams[U("sku")] = value;
// get UUID
if (!get_uuid(value)) return false;
activationParams[U("uuid")] = value;
// get local system account
if (!get_local_system_account_username(value)) return false;
activationParams[U("username")] = value;
if (!get_local_system_account_password(value)) return false;
activationParams[U("password")] = value;
// get Control Mode
if (!get_control_mode(value)) return false;
activationParams[U("currentMode")] = value;
// get DNS Info
activationParams[U("fqdn")] = get_dns();
// get hostname
activationParams[U("hostname")] = get_hostname();
// get client string
if (!get_client_string(value)) return false;
activationParams[U("client")] = value;
// get certificate hashes
if (!get_certificate_hashes(value)) return false;
activationParams[U("certHashes")] = value;
payload = activationParams;
return true;
}
bool act_create_request(std::string commands, std::string dns_suffix, std::string& request)
{
web::json::value msg;
// get the activation info
utility::string_t tmp = utility::conversions::convertstring(commands);
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("");
msg[U("status")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring("");
msg[U("message")] = web::json::value::string(tmp);
// get the activation payload
web::json::value activationPayload;
if (!get_activation_payload(activationPayload)) return false;
// override dns value if passed in
if (!dns_suffix.empty())
{
utility::string_t tmp = utility::conversions::convertstring(dns_suffix);
activationPayload[U("fqdn")] = web::json::value::string(tmp);
}
// serialize payload
std::string serializedPayload = utility::conversions::to_utf8string(activationPayload.serialize());
std::string encodedPayload = util_encode_base64(serializedPayload);
utility::string_t payload = utility::conversions::to_string_t(encodedPayload);
msg[U("payload")] = web::json::value::string(payload);
// serialize the entire message
request = utility::conversions::to_utf8string(msg.serialize());
return true;
}
bool act_create_response(std::string payload, std::string& response)
{
web::json::value msg;
utility::string_t tmp = utility::conversions::convertstring("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("");
msg[U("status")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring("");
msg[U("message")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring(util_encode_base64(payload));
msg[U("payload")] = web::json::value::string(tmp);
response = utility::conversions::to_utf8string(msg.serialize());
return true;
}

22
activation.h Normal file
View File

@@ -0,0 +1,22 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __ACTIVATION_H__
#define __ACTIVATION_H__
#include <string>
#define PROTOCOL_VERSION "4.0.0"
#ifdef _WIN32
#define convertstring to_utf16string
#else
#define convertstring to_utf8string
#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);
#endif

134
args.cpp Normal file
View File

@@ -0,0 +1,134 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "args.h"
#include <string>
#include "port.h"
#include "utils.h"
bool get_arg_exists(int argc, char* argv[], const char* long_opt, const char* short_opt)
{
for (int i = 1; i < argc; i++)
{
if ((strcasecmp(argv[i], long_opt) == 0) || (strcasecmp(argv[i], short_opt) == 0))
{
return true;
}
}
return false;
}
bool get_arg_exists(int argc, char* argv[], const char* opt)
{
for (int i = 1; i < argc; i++)
{
if ((strcasecmp(argv[i], opt) == 0))
{
return true;
}
}
return false;
}
bool get_arg_string(int argc, char* argv[], const char* long_opt, const char* short_opt, std::string& value)
{
value = "";
for (int i = 1; i < argc; i++)
{
if ((strcasecmp(argv[i], long_opt) == 0) || (strcasecmp(argv[i], short_opt) == 0))
{
if (i + 1 < argc)
{
std::string tmp = argv[++i];
if (!util_is_printable(tmp))
{
return false;
}
value = tmp;
return true;
}
}
}
return false;
}
bool get_arg_string(int argc, char* argv[], const char* opt, std::string& value)
{
value = "";
for (int i = 1; i < argc; i++)
{
if ((strcasecmp(argv[i], opt) == 0))
{
if (i + 1 < argc)
{
std::string tmp = argv[++i];
if (!util_is_printable(tmp))
{
return false;
}
value = tmp;
return true;
}
}
}
return false;
}
bool args_get_help(int argc, char* argv[])
{
return get_arg_exists(argc, argv, "--help");
}
bool args_get_version(int argc, char* argv[])
{
return get_arg_exists(argc, argv, "--version");
}
bool args_get_url(int argc, char* argv[], std::string& url)
{
return get_arg_string(argc, argv, "--url", "-u", url);
}
bool args_get_proxy(int argc, char* argv[], std::string& proxy)
{
return get_arg_string(argc, argv, "--proxy", "-p", proxy);
}
bool args_get_cmd(int argc, char* argv[], std::string& cmd)
{
return get_arg_string(argc, argv, "--cmd", "-c", cmd);
}
bool args_get_dns(int argc, char* argv[], std::string& dns)
{
return get_arg_string(argc, argv, "--dns", "-d", dns);
}
bool args_get_info(int argc, char* argv[], std::string& info)
{
return get_arg_string(argc, argv, "--amtinfo", info);
}
bool args_get_verbose(int argc, char* argv[])
{
return get_arg_exists(argc, argv, "--verbose", "-v");
}
bool args_get_nocertcheck(int argc, char* argv[])
{
return get_arg_exists(argc, argv, "--nocertcheck", "-n");
}

21
args.h Normal file
View File

@@ -0,0 +1,21 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __ARGS_H__
#define __ARGS_H__
#include <string>
bool args_get_help(int argc, char* argv[]);
bool args_get_version(int argc, char* argv[]);
bool args_get_url(int argc, char* argv[], std::string& url);
bool args_get_proxy(int argc, char* argv[], std::string& proxy);
bool args_get_cmd(int argc, char* argv[], std::string& cmd);
bool args_get_dns(int argc, char* argv[], std::string& dns);
bool args_get_info(int argc, char* argv[], std::string& info);
bool args_get_verbose(int argc, char* argv[]);
bool args_get_nocertcheck(int argc, char* argv[]);
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

View File

@@ -1,509 +1,417 @@
/*
Copyright 2019 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "commands.h"
#ifdef _WIN32
#include <boost/asio.hpp>
#include <winsock2.h>
#include <iphlpapi.h>
#endif
#include "AMTHICommand.h"
#include "MEIClientException.h"
#include "GetUUIDCommand.h"
#include "GetLocalSystemAccountCommand.h"
#include "GetCodeVersionCommand.h"
#include "GetControlModeCommand.h"
#include "GetProvisioningStateCommand.h"
#include "GetDNSSuffixCommand.h"
#include "GetLanInterfaceSettingsCommand.h"
#include "GetCertificateHashEntryCommand.h"
#include "EnumerateHashHandlesCommand.h"
#include "MEIparser.h"
#include "version.h"
#include <boost/algorithm/string.hpp>
#include <cpprest/ws_client.h>
#include <cpprest/json.h>
#include <cpprest/streams.h>
#include <sstream>
#include <iostream>
#include <string>
#include "lms.h"
#include "port.h"
#include "utils.h"
using namespace std;
using namespace Intel::MEI_Client::AMTHI_Client;
using namespace web::websockets::client;
using namespace web;
#define WORKING_BUFFER_SIZE 15000
#define MAX_TRIES 3
#ifdef _WIN32
std::string getDNSFromMAC(char *macAddress)
{
std::string dnsSuffix = "";
char dns[256];
memset(dns, 0, 256);
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
ULONG outBufLen = 0;
ULONG Iterations = 0;
outBufLen = WORKING_BUFFER_SIZE;
// get info for all adapters
do {
pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
if (pAddresses == NULL) {
cout << "dns memory error" << std::endl;
return dnsSuffix;
}
dwRetVal = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW)
{
free(pAddresses);
pAddresses = NULL;
}
else
{
break;
}
Iterations++;
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES));
// get DNS from MAC
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
pCurrAddresses = pAddresses;
while (pCurrAddresses)
{
if (pCurrAddresses->PhysicalAddressLength != 0)
{
if (memcmp(macAddress, (char *) pCurrAddresses->PhysicalAddress, 6) == 0)
{
if (wcslen(pCurrAddresses->DnsSuffix) > 0)
{
snprintf(dns, 256, "%ws", pCurrAddresses->DnsSuffix );
break;
}
}
}
pCurrAddresses = pCurrAddresses->Next;
}
dnsSuffix = dns;
return dnsSuffix;
}
#else
std::string getDNSFromMAC(char *macAddress)
{
std::string dnsSuffix = "";
// get socket
SOCKET s = 0;
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0)
{
cout << "couldn't get socket" << endl;
return dnsSuffix;
}
// get info for all adapters
struct ifconf ifc;
memset(&ifc, 0, sizeof(ifconf));
char buffer[8192];
memset(buffer, 0, sizeof(buffer));
ifc.ifc_buf = buffer;
ifc.ifc_len = sizeof(buffer);
if(ioctl(s, SIOCGIFCONF, &ifc) < 0)
{
cout << "ioctl SIOCGIFCONF failed" << endl;
return dnsSuffix;
}
// get DNS from IP associated with MAC
struct ifreq *ifr = ifc.ifc_req;
int interfaceCount = ifc.ifc_len / sizeof(struct ifreq);
char ip[INET6_ADDRSTRLEN] = {0};
struct ifreq *item;
struct sockaddr *addr;
for(int i = 0; i < interfaceCount; i++)
{
item = &ifr[i];
addr = &(item->ifr_addr);
// get IP address
if(ioctl(s, SIOCGIFADDR, item) < 0)
{
cout << "ioctl SIOCGIFADDR failed" << endl;
continue;
}
if (inet_ntop(AF_INET, &( ((struct sockaddr_in *)addr)->sin_addr ),
ip, sizeof(ip) ) == NULL)
{
cout << "inet_ntop" << endl;
continue;
}
// get MAC address
if(ioctl(s, SIOCGIFHWADDR, item) < 0)
{
cout << "ioctl SIOCGIFHWADDR failed" << endl;
continue;
}
if (memcmp(macAddress, (char *) item->ifr_hwaddr.sa_data, 6) == 0)
{
// Get host by using the IP address which AMT device is using
struct in_addr addr = {0};
struct hostent *host;
addr.s_addr = inet_addr(ip);
host = gethostbyaddr((char *)&addr, 4, AF_INET);
if (host == NULL)
{
cout << "gethostbyaddr() failed";
return dnsSuffix;
}
// strip off the hostname to get actual domain name
int domainNameSize = 256;
char domainName[domainNameSize];
memset(domainName, 0, domainNameSize);
char *dn = strchr(host->h_name, '.');
if (dn != NULL)
{
if (domainNameSize >= strlen(dn + 1))
{
snprintf(domainName, domainNameSize, "%s", ++dn);
dnsSuffix = domainName;
}
}
}
}
return dnsSuffix;
}
#ifndef _WIN32
#include <string.h>
#endif
extern "C" {
#ifndef _WIN32
#include "HECILinux.h"
#endif
#include "PTHICommand.h"
#ifdef bool
#undef bool
#endif
}
#include "version.h"
json::value getCertificateHashes()
bool cmd_is_admin()
{
json::value certHashes;
vector<json::value> hashValues;
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
return true;
}
bool cmd_get_version(std::string& version)
{
version.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get code version
CODE_VERSIONS codeVersion;
AMT_STATUS status = pthi_GetCodeVersions(&codeVersion);
// additional versions
if (status == 0)
{
for (int i = 0; i < (int) codeVersion.VersionsCount; i++)
{
if (strcmp((char*)(codeVersion.Versions[i].Description.String), "AMT") == 0)
{
version = ((char*)codeVersion.Versions[i].Version.String);
return true;
}
}
}
return false;
}
bool cmd_get_build_number(std::string& version)
{
version.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get code version
CODE_VERSIONS codeVersion;
AMT_STATUS status = pthi_GetCodeVersions(&codeVersion);
// additional versions
if (status == 0)
{
for (int i = 0; i < (int) codeVersion.VersionsCount; i++)
{
if (strcmp((char*)(codeVersion.Versions[i].Description.String), "Build Number") == 0)
{
version = ((char*)codeVersion.Versions[i].Version.String);
return true;
}
}
}
return false;
}
bool cmd_get_sku(std::string& version)
{
version.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get code version
CODE_VERSIONS codeVersion;
AMT_STATUS status = pthi_GetCodeVersions(&codeVersion);
// additional versions
if (status == 0)
{
for (int i = 0; i < (int) codeVersion.VersionsCount; i++)
{
if (strcmp((char*)(codeVersion.Versions[i].Description.String), "Sku") == 0)
{
version = ((char*)codeVersion.Versions[i].Version.String);
return true;
}
}
}
return false;
}
bool cmd_get_uuid(std::vector<unsigned char>& uuid)
{
uuid.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get UUID
AMT_UUID amt_uuid;
AMT_STATUS amt_status = pthi_GetUUID(&amt_uuid);
if (amt_status == 0)
{
for (int i = 0; i < 16; i++)
{
uuid.push_back(amt_uuid[i]);
}
return true;
}
return false;
}
bool cmd_get_local_system_account(std::string& username, std::string& password)
{
username.clear();
password.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get Local System Account
LOCAL_SYSTEM_ACCOUNT local_system_account;
AMT_STATUS amt_status = pthi_GetLocalSystemAccount(&local_system_account);
if (amt_status == 0)
{
username = local_system_account.username;
password = local_system_account.password;
return true;
}
return false;
}
bool cmd_get_control_mode(int& mode)
{
mode = 0;
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get Control Mode
int controlMode;
AMT_STATUS amt_status = pthi_GetControlMode(&controlMode);
if (amt_status == 0)
{
mode = controlMode;
return true;
}
return false;
}
bool cmd_get_fqdn(fqdn_settings& fqdn_settings)
{
fqdn_settings.fqdn.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get fqdn
CFG_GET_FQDN_RESPONSE fqdn;
memset(&fqdn, 0, sizeof(CFG_GET_FQDN_RESPONSE));
AMT_STATUS amt_status = pthi_GetHostFQDN(&fqdn);
if (amt_status == 0)
{
fqdn_settings.ddns_ttl = fqdn.DDNSTTL;
fqdn_settings.ddns_update_enabled = fqdn.DDNSUpdateEnabled;
fqdn_settings.ddns_update_interval = fqdn.DDNSPeriodicUpdateInterval;
if (fqdn.FQDN.Length > 0)
{
fqdn_settings.fqdn = std::string(fqdn.FQDN.Buffer, fqdn.FQDN.Length);
free(fqdn.FQDN.Buffer);
}
return true;
}
return false;
}
bool cmd_get_dns_suffix(std::string& suffix)
{
suffix.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get DNS according to AMT
AMT_ANSI_STRING amt_dns_suffix;
AMT_STATUS amt_status = pthi_GetDnsSuffix(&amt_dns_suffix);
if (amt_status == 0)
{
if (amt_dns_suffix.Buffer != NULL)
{
std::string tmp(amt_dns_suffix.Buffer, amt_dns_suffix.Length);
suffix = tmp;
free(amt_dns_suffix.Buffer);
}
return true;
}
return false;
}
bool cmd_get_wired_mac_address(std::vector<unsigned char>& address)
{
address.clear();
// 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
AMT_STATUS amt_status = pthi_GetLanInterfaceSettings(interface_settings, &lan_settings);
if (amt_status == 0)
{
if (!lan_settings.Enabled)
{
return false;
}
for (int i = 0; i < 6; i++)
{
address.push_back(lan_settings.MacAddress[i]);
}
return true;
}
return false;
}
bool cmd_get_certificate_hashes(std::vector<cert_hash_entry>& hash_entries)
{
hash_entries.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get the hash handles
EnumerateHashHandlesCommand command;
ENUMERATE_HASH_HANDLES_RESPONSE response = command.getResponse();
AMT_HASH_HANDLES amt_hash_handles;
CERTHASH_ENTRY certhash_entry;
vector<unsigned int>::iterator itr = response.HashHandles.begin();
vector<unsigned int>::iterator endItr = response.HashHandles.end();
for (; itr != endItr; ++itr)
memset(&amt_hash_handles, 0, sizeof(AMT_HASH_HANDLES));
if (pthi_EnumerateHashHandles(&amt_hash_handles) == 0)
{
// get each entry
GetCertificateHashEntryCommand command(*itr);
GET_CERTIFICATE_HASH_ENTRY_RESPONSE response = command.getResponse();
for (int i = 0; i < (int) amt_hash_handles.Length; i++)
{
// get each entry
AMT_STATUS amt_status = pthi_GetCertificateHashEntry(amt_hash_handles.Handles[i], &certhash_entry);
int hashSize;
switch (response.HashAlgorithm) {
case 0: // MD5
hashSize = 16;
break;
case 1: // SHA1
hashSize = 20;
break;
case 2: // SHA256
hashSize = 32;
break;
case 3: // SHA512
hashSize = 64;
break;
default:
hashSize = 64;
break;
}
if (response.IsActive == 1) {
string hashString;
hashString.clear();
for (int i = 0; i < hashSize; i++)
if (amt_status == 0)
{
char hex[10];
snprintf(hex, 10, "%02x", response.CertificateHash[i]);
hashString += hex;
int hashSize;
cert_hash_entry tmp;
switch (certhash_entry.HashAlgorithm) {
case 0: // MD5
hashSize = 16;
tmp.algorithm = "MD5";
break;
case 1: // SHA1
hashSize = 20;
tmp.algorithm = "SHA1";
break;
case 2: // SHA256
hashSize = 32;
tmp.algorithm = "SHA256";
break;
case 3: // SHA512
hashSize = 64;
tmp.algorithm = "SHA512";
break;
default:
hashSize = 0;
tmp.algorithm = "UNKNOWN";
break;
}
if (certhash_entry.IsActive == 1)
{
std::string cert_name(certhash_entry.Name.Buffer, certhash_entry.Name.Length);
tmp.name = cert_name;
tmp.is_default = certhash_entry.IsDefault;
tmp.is_active = certhash_entry.IsActive;
std::string hashString;
for (int i = 0; i < hashSize; i++)
{
char hex[10];
snprintf(hex, 10, "%02x", certhash_entry.CertificateHash[i]);
hashString += hex;
}
tmp.hash = hashString;
hash_entries.push_back(tmp);
}
}
}
return true;
}
return false;
}
bool cmd_get_remote_access_connection_status(int& network_status, int& remote_status, int& remote_trigger, std::string& mps_hostname)
{
network_status = 0;
remote_status = 0;
remote_trigger = 0;
mps_hostname = "";
const int MPS_SERVER_MAXLENGTH = 256;
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get DNS according to AMT
REMOTE_ACCESS_STATUS remote_access_connection_status;
AMT_STATUS amt_status = pthi_GetRemoteAccessConnectionStatus(&remote_access_connection_status);
if (amt_status == 0)
{
network_status = remote_access_connection_status.AmtNetworkConnectionStatus;
remote_status = remote_access_connection_status.RemoteAccessConnectionStatus;
remote_trigger = remote_access_connection_status.RemoteAccessConnectionTrigger;
if (remote_access_connection_status.MpsHostname.Buffer != NULL)
{
if (remote_access_connection_status.MpsHostname.Length < MPS_SERVER_MAXLENGTH)
{
std::string tmp(remote_access_connection_status.MpsHostname.Buffer, remote_access_connection_status.MpsHostname.Length);
if (util_is_printable(tmp))
{
mps_hostname = tmp;
}
}
hashValues.push_back( json::value::string( utility::conversions::convertstring(hashString) ) );
free(remote_access_connection_status.MpsHostname.Buffer);
}
return true;
}
return json::value::array(hashValues);
return false;
}
std::string getDNSInfo()
bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settings, bool wired_interface)
{
std::string dnsSuffix;
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// Get interface info which AMT is using. We don't worry about wireless since
// only wired used for configuration
GetLanInterfaceSettingsCommand getLanInterfaceSettingsCommandWired(Intel::MEI_Client::AMTHI_Client::WIRED);
LAN_SETTINGS lanSettings = getLanInterfaceSettingsCommandWired.getResponse();
if (!lanSettings.Enabled)
// get wired interface
LAN_SETTINGS lan_settings;
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)
{
cout << "error: no wired AMT interfaces enabled" << endl;
return "";
lan_interface_settings.is_enabled = lan_settings.Enabled;
lan_interface_settings.dhcp_mode = lan_settings.DhcpIpMode;
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]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[3]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[4]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[5]);
return true;
}
// Get DNS according to AMT
GetDNSSuffixCommand getDnsSuffixCommand;
dnsSuffix = getDnsSuffixCommand.getResponse();
// get DNS from OS
if (!dnsSuffix.length())
{
dnsSuffix = getDNSFromMAC((char *)&lanSettings.MacAddress);
}
return dnsSuffix;
return false;
}
string getActivateInfo(string profile, string dnssuffixcmd)
{
utility::string_t tmp;
// Activation parameters
json::value activationParams;
// Get code version
GetCodeVersionCommand codeVersionCommand;
CODE_VERSIONS codeVersion = codeVersionCommand.getResponse();
// Additional versions
// UINT8[16] UUID;
// AMT_VERSION_TYPE Version and Description are std::string.
for (vector<AMT_VERSION_TYPE>::iterator it = codeVersion.Versions.begin(); it != codeVersion.Versions.end(); it++)
{
if (boost::iequals(it->Description, "AMT"))
{
tmp = utility::conversions::convertstring(it->Version);
activationParams[U("ver")] = json::value::string(tmp);
}
else if (boost::iequals(it->Description, "Build Number"))
{
tmp = utility::conversions::convertstring(it->Version);
activationParams[U("build")] = json::value::string(tmp);
}
else if (boost::iequals(it->Description, "Sku"))
{
tmp = utility::conversions::convertstring(it->Version);
activationParams[U("sku")] = json::value::string(tmp);
}
}
// Get UUID
GetUUIDCommand get;
GET_UUID_RESPONSE res = get.getResponse();
std::vector<json::value> UUID;
for (int i = 0; i < 16; i++)
{
UUID.push_back(json::value(res.UUID[i]));
}
activationParams[U("uuid")] = json::value::array(UUID);
// Get local system account
// User name in ASCII char-set. The string is NULL terminated. CFG_MAX_ACL_USER_LENGTH is 33
// Password in ASCII char set. From AMT 6.1 this field is in BASE64 format. The string is NULL terminated.
GetLocalSystemAccountCommand sac;
tmp = utility::conversions::convertstring(sac.getResponse().UserName);
activationParams[U("username")] = json::value::string(tmp);
tmp = utility::conversions::convertstring(sac.getResponse().Password);
activationParams[U("password")] = json::value::string(tmp);
// Get Control Mode
GetControlModeCommand controlModeCommand;
GET_CONTROL_MODE_RESPONSE controlMode = controlModeCommand.getResponse();
activationParams[U("currentMode")] = json::value::number(controlMode.ControlMode);
// Get DNS Info
tmp = utility::conversions::convertstring("");
string dnsSuffix = "";
if (dnssuffixcmd.length() > 0)
{
// use what's passed in
dnsSuffix = dnssuffixcmd;
}
else
{
// get it from AMT or OS
dnsSuffix = getDNSInfo();
}
if (dnsSuffix.length())
{
tmp = utility::conversions::convertstring(dnsSuffix);
}
activationParams[U("fqdn")] = json::value::string(tmp);
tmp = utility::conversions::convertstring("PPC");
activationParams[U("client")] = json::value::string(tmp);
tmp = utility::conversions::convertstring(profile);
activationParams[U("profile")] = json::value::string(tmp);
// Get certificate hashes
activationParams[U("certHashes")] = getCertificateHashes();
// Return serialized parameters in base64
string serializedParams = utility::conversions::to_utf8string(activationParams.serialize());
#ifdef DEBUG
cout << "Activation info payload:" << serializedParams << std::endl;
#endif
return encodeBase64(serializedParams);
}
string encodeBase64(string str)
{
std::vector<unsigned char> strVector(str.begin(), str.end());
utility::string_t base64 = utility::conversions::to_base64(strVector);
string encodedString = utility::conversions::to_utf8string(base64);
return encodedString;
}
string decodeBase64(string str)
{
utility::string_t serializedData = utility::conversions::to_string_t(str);
std::vector<unsigned char> strVector = utility::conversions::from_base64(serializedData);
string decodedString(strVector.begin(), strVector.end());
return decodedString;
}
string createActivationRequest(string profile, string dnssuffixcmd)
{
// Activation parameters
json::value request;
// placeholder stuff; will likely change
utility::string_t tmp = utility::conversions::convertstring("activation");
request[U("method")] = json::value::string(tmp);
tmp = utility::conversions::convertstring("key");
request[U("apiKey")] = json::value::string(tmp);
tmp = utility::conversions::convertstring(PROJECT_VER);
request[U("appVersion")] = json::value::string(tmp);
tmp = utility::conversions::convertstring(PROTOCOL_VERSION);
request[U("protocolVersion")] = json::value::string(tmp);
tmp = utility::conversions::convertstring("ok");
request[U("status")] = json::value::string(tmp);
tmp = utility::conversions::convertstring("all\'s good!");
request[U("message")] = json::value::string(tmp);
// payload
string activationInfo = getActivateInfo(profile, dnssuffixcmd);
utility::string_t payload = utility::conversions::to_string_t(activationInfo);
request[U("payload")] = json::value::string(payload);
return utility::conversions::to_utf8string(request.serialize());
}
string createResponse(string payload)
{
// Activation parameters
json::value response;
// placeholder stuff; will likely change
utility::string_t tmp = utility::conversions::convertstring("response");
response[U("method")] = json::value::string(tmp);
tmp = utility::conversions::convertstring("key");
response[U("apiKey")] = json::value::string(tmp);
tmp = utility::conversions::convertstring(PROJECT_VER);
response[U("appVersion")] = json::value::string(tmp);
tmp = utility::conversions::convertstring(PROTOCOL_VERSION);
response[U("protocolVersion")] = json::value::string(tmp);
tmp = utility::conversions::convertstring("ok");
response[U("status")] = json::value::string(tmp);
tmp = utility::conversions::convertstring("all\'s good!");
response[U("message")] = json::value::string(tmp);
// payload
tmp = utility::conversions::convertstring( encodeBase64(payload) );
response[U("payload")] = json::value::string(tmp);
return utility::conversions::to_utf8string(response.serialize());
}
void dumpMessage(utility::string_t tmp)
{
web::json::value parsed = web::json::value::parse(tmp);
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")) ||
!parsed.has_field(U("payload")) ) {
cout << "error: dumpMessage message is empty" << endl;
return;
}
utility::string_t out = parsed[U("method")].as_string();
cout << "method: " << utility::conversions::to_utf8string(out) << endl;
out = parsed[U("apiKey")].as_string();
cout << "apiKey: " << utility::conversions::to_utf8string(out) << endl;
out = parsed[U("appVersion")].as_string();
cout << "appVersion: " << utility::conversions::to_utf8string(out) << endl;
out = parsed[U("protocolVersion")].as_string();
cout << "protocolVersion: " << utility::conversions::to_utf8string(out) << endl;
out = parsed[U("status")].as_string();
cout << "status: " << utility::conversions::to_utf8string(out) << endl;
out = parsed[U("message")].as_string();
cout << "message: " << utility::conversions::to_utf8string(out) << endl;
out = parsed[U("payload")].as_string();
cout << "payload: " << utility::conversions::to_utf8string(out) << endl;
}

View File

@@ -1,48 +1,54 @@
/*
Copyright 2019 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __COMMANDS_H__
#define __COMMANDS_H__
#include <iostream>
#include <vector>
#include <string>
#include <cpprest/ws_client.h>
#include <cpprest/json.h>
#include <cpprest/streams.h>
struct cert_hash_entry
{
std::string hash;
std::string name;
std::string algorithm;
bool is_active;
bool is_default;
};
using namespace std;
using namespace web::websockets::client;
using namespace web;
struct lan_interface_settings
{
bool is_enabled;
bool link_status;
bool dhcp_enabled;
int dhcp_mode;
std::vector<unsigned char> ip_address;
std::vector<unsigned char> mac_address;
};
#define PROTOCOL_VERSION "2.0.0"
struct fqdn_settings
{
bool shared_fqdn;
bool ddns_update_enabled;
int ddns_update_interval;
int ddns_ttl;
std::string fqdn;
};
#ifdef _WIN32
#define convertstring to_utf16string
#else
#define convertstring to_utf8string
#endif
string getDNSInfo();
string createActivationRequest(string profile, string dnssuffixcmd);
json::value getCertificateHashes();
string createResponse(string payload);
string getActivateInfo(string profile, string dnssuffixcmd);
string encodeBase64(string str);
string decodeBase64(string str);
void dumpMessage(string tmp);
bool cmd_is_admin();
bool cmd_get_version(std::string& version);
bool cmd_get_build_number(std::string& version);
bool cmd_get_sku(std::string& version);
bool cmd_get_uuid(std::vector<unsigned char>& uuid);
bool cmd_get_local_system_account(std::string& username, std::string& password);
bool cmd_get_control_mode(int& mode);
bool cmd_get_fqdn(fqdn_settings& fqdn_settings);
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 wired_interface = true);
#endif

15
googletest.cmake.in Normal file
View File

@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 2.8.12)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.10.0
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

48
heartbeat.cpp Normal file
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
heartbeat.h Normal file
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

371
info.cpp Normal file
View File

@@ -0,0 +1,371 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "info.h"
#include <iostream>
#include <string>
#include <iomanip>
#include "commands.h"
#include "utils.h"
#include "network.h"
const int PADDING = 25;
void out_text(const std::string name, const std::vector<unsigned char> value, const unsigned char delimeter = ' ', const bool hex = true)
{
std::cout << name << std::setfill(' ') << std::setw(PADDING - name.size()) << ": ";
int char_count = 1;
for (unsigned char tmp : value)
{
(hex) ? std::cout << std::setfill('0') << std::setw(2) << std::hex << (unsigned int)tmp
: std::cout << std::dec << (unsigned int)tmp;
if (char_count++ < value.size())
{
std::cout << delimeter;
}
}
std::cout << std::endl;
}
void out_text(const std::string name, const std::string value)
{
std::cout << name << std::setfill(' ') << std::setw(PADDING - name.size()) << ": ";
std::cout << value;
std::cout << std::endl;
}
void out_text(const std::string name, const int value)
{
std::cout << name << std::setfill(' ') << std::setw(PADDING - name.size()) << ": ";
std::cout << value;
std::cout << std::endl;
}
void out_text(const std::string name, const std::vector<std::string> value)
{
std::cout << name << std::setfill(' ') << std::setw(PADDING - name.size()) << ": " << std::endl;
for (std::string tmp : value)
{
std::cout << tmp << std::endl;
}
}
bool info_get_version()
{
std::string tmp;
if (!cmd_get_version(tmp)) return false;
out_text("Version", tmp);
return true;
}
bool info_get_build_number()
{
std::string tmp;
if (!cmd_get_build_number(tmp)) return false;
out_text("Build Number", tmp);
return true;
}
bool info_get_sku()
{
std::string tmp;
if (!cmd_get_sku(tmp)) return false;
out_text("SKU", tmp);
return true;
}
bool info_get_uuid()
{
std::string uuid_string;
std::vector<unsigned char> tmp;
if (!cmd_get_uuid(tmp)) return false;
if (!util_format_uuid(tmp, uuid_string)) return false;
out_text("UUID", uuid_string);
return true;
}
bool info_get_control_mode()
{
int tmp;
if (!cmd_get_control_mode(tmp)) return false;
std::string control_mode;
if (tmp == 0) control_mode = "pre-provisioning state";
else if (tmp == 1) control_mode = "activated in client control mode";
else if (tmp == 2) control_mode = "activated in admin control mode";
out_text("Control Mode", control_mode);
return true;
}
bool info_get_dns_suffix()
{
std::string tmp;
if (!cmd_get_dns_suffix(tmp)) return false;
out_text("DNS Suffix", tmp);
tmp = net_get_dns();
out_text("DNS Suffix (OS)", tmp);
return true;
}
bool info_get_fqdn()
{
fqdn_settings fqdn;
if (cmd_get_fqdn(fqdn))
{
out_text("FQDN", fqdn.fqdn);
}
std::string tmp;
std::string dns;
tmp = net_get_hostname();
out_text("Hostname (OS)", tmp);
return true;
}
bool info_get_certificate_hashes()
{
std::vector<cert_hash_entry> hash_entries;
std::vector<std::string> tmp;
if (!cmd_get_certificate_hashes(hash_entries)) return false;
for (cert_hash_entry entry : hash_entries)
{
std::string name = entry.name;
(entry.is_default) ? name += ", (Default, " : ", (Not Default, ";
(entry.is_active) ? name += "Active)" : "Not Active)";
tmp.push_back(name);
std::string algorithm = " " + entry.algorithm;
algorithm += ": " + entry.hash;
tmp.push_back(algorithm);
}
out_text("Certificate Hashes", tmp);
return true;
}
bool info_get_all()
{
bool status_ver = info_get_version();
bool status_bld = info_get_build_number();
bool status_sku = info_get_sku();
bool status_uuid = info_get_uuid();
bool status_mode = info_get_control_mode();
bool status_dns = info_get_dns_suffix();
bool status_fqdn = info_get_fqdn();
bool status_ras = info_get_remote_access_connection_status();
bool status_lan = info_get_lan_interface_settings();
bool status_cert = info_get_certificate_hashes();
if (status_ver && status_bld && status_sku && status_uuid && status_mode &&
status_dns && status_fqdn && status_ras && status_lan && status_cert)
{
return true;
}
return false;
}
bool info_get_remote_access_connection_status()
{
int network_status;
int remote_status;
int remote_trigger;
std::string mps_hostname;
if (!cmd_get_remote_access_connection_status(network_status, remote_status, remote_trigger, mps_hostname)) return false;
std::string tmp;
switch (network_status)
{
case 0: tmp = "direct";
break;
case 1: tmp = "vpn";
break;
case 2: tmp = "outside enterprise";
break;
case 3:
default: tmp = "unknown";
break;
}
out_text("RAS Network", tmp);
switch (remote_status)
{
case 0: tmp = "not connected";
break;
case 1: tmp = "connecting";
break;
case 2: tmp = "connected";
break;
default: tmp = "unknown";
break;
}
out_text("RAS Remote Status", tmp);
switch (remote_trigger)
{
case 0: tmp = "user initiated";
break;
case 1: tmp = "alert";
break;
case 2: tmp = "periodic";
break;
case 3: tmp = "provisioning";
break;
default: tmp = "unknown";
break;
}
out_text("RAS Trigger", tmp);
out_text("RAS MPS Hostname", mps_hostname);
return true;
}
bool info_get_lan_interface_settings()
{
lan_interface_settings tmp;
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 hasWired = cmd_get_lan_interface_settings(tmp);
if (hasWired)
{
out_text("LAN Interface", "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 Interface", "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)
{
return info_get_version();
}
else if (info.compare("bld") == 0)
{
return info_get_build_number();
}
else if (info.compare("sku") == 0)
{
return info_get_sku();
}
else if (info.compare("uuid") == 0)
{
return info_get_uuid();
}
else if (info.compare("mode") == 0)
{
return info_get_control_mode();
}
else if (info.compare("dns") == 0)
{
return info_get_dns_suffix();
}
else if (info.compare("fqdn") == 0)
{
return info_get_fqdn();
}
else if (info.compare("cert") == 0)
{
return info_get_certificate_hashes();
}
else if (info.compare("ras") == 0)
{
return info_get_remote_access_connection_status();
}
else if (info.compare("lan") == 0)
{
return info_get_lan_interface_settings();
}
else if (info.compare("all") == 0)
{
return info_get_all();
}
return false;
}
bool info_get_verify(const std::string info)
{
if ((info.compare("ver") == 0) || (info.compare("bld") == 0) || (info.compare("sku") == 0) ||
(info.compare("uuid") == 0) || (info.compare("mode") == 0) || (info.compare("fqdn") == 0) ||
(info.compare("dns") == 0) || (info.compare("cert") == 0) || (info.compare("ras") == 0) ||
(info.compare("lan") == 0) || (info.compare("all") == 0))
{
return true;
}
return false;
}

24
info.h Normal file
View File

@@ -0,0 +1,24 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __INFO_H__
#define __INFO_H__
#include <string>
bool info_get(const std::string info);
bool info_get_verify(const std::string info);
bool info_get_version();
bool info_get_build_number();
bool info_get_sku();
bool info_get_uuid();
bool info_get_control_mode();
bool info_get_dns_suffix();
bool info_get_fqdn();
bool info_get_all();
bool info_get_remote_access_connection_status();
bool info_get_lan_interface_settings();
#endif

View File

@@ -1,15 +0,0 @@
cmake_minimum_required(VERSION 3.1)
project(lms-download NONE)
include(ExternalProject)
ExternalProject_Add(lms
GIT_REPOSITORY https://github.com/intel/lms.git
GIT_TAG v1932.0.0.0
SOURCE_DIR "${CMAKE_BINARY_DIR}/lms-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/lms-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

21
lms.cpp
View File

@@ -1,18 +1,7 @@
/*
Copyright 2019 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "lms.h"
#include <string.h>
@@ -26,7 +15,7 @@ limitations under the License.
#include <netdb.h>
#endif
SOCKET lmsConnect()
SOCKET lms_connect()
{
std::string lmsAddress = "localhost";
std::string lmsPort = "16992";

21
lms.h
View File

@@ -1,18 +1,7 @@
/*
Copyright 2019 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __LMS_H__
#define __LMS_H__
@@ -39,6 +28,6 @@ static inline int closesocket(int fd)
#define SD_BOTH SHUT_RDWR
#endif
SOCKET lmsConnect();
SOCKET lms_connect();
#endif

492
main.cpp
View File

@@ -1,67 +1,49 @@
/*
Copyright 2019 Intel Corporation
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <cpprest/ws_client.h>
#include <cpprest/streams.h>
#include <iostream>
#include <string>
#include <thread>
#include <boost/algorithm/string.hpp>
#include <cctype>
#include "commands.h"
#include "lms.h"
#include "version.h"
using namespace std;
using namespace web;
using namespace web::websockets::client;
#include <cpprest/ws_client.h>
#include <cpprest/json.h>
#include <algorithm>
#include "port.h"
#include "lms.h"
#include "commands.h"
#include "activation.h"
#include "heartbeat.h"
#include "utils.h"
#include "usage.h"
#include "args.h"
#include "info.h"
void showUsage();
bool isPrintable(std::string str);
// timer thread globals
long long g_timeout_val = 0;
const int g_timeout_max = 10;
bool g_thread_alive = true;
string websocket_address = "";
string server_profile = "";
string websocket_proxy = "";
string dns_suffix = "";
long long timeoutTimer = 0;
const int MAX_TIMEOUT = 10; // seconds
bool timeoutThreadAlive = true;
void timeoutFunc(std::condition_variable *cv, std::mutex *mx)
// timeout thread function
// used to exit application in case a timeout occurs
void timeout_thread_function(std::condition_variable *cv, std::mutex *mx)
{
while (timeoutThreadAlive)
while (g_thread_alive)
{
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
auto duration = now.time_since_epoch();
long long currTime = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
if (currTime > timeoutTimer)
if (currTime > g_timeout_val)
{
if (currTime - timeoutTimer >= MAX_TIMEOUT)
if (currTime - g_timeout_val >= g_timeout_max)
{
cv->notify_all();
// check if timeoutTimer is not 0 since we explicitly set to zero when an
// activation is successfull. If it's not zero, we are in a time out scenario.
if (timeoutTimer)
if (g_timeout_val)
{
cout << endl << "Timed-out due to inactivity." <<endl;
std::cout << std::endl << "Timed-out due to inactivity." << std::endl;
}
break;
}
@@ -71,192 +53,172 @@ void timeoutFunc(std::condition_variable *cv, std::mutex *mx)
}
}
int main(int argc, char *argv[])
int main(int argc, char* argv[])
{
string activationInfo;
std::string activation_info;
std::string arg_url;
std::string arg_proxy;
std::string arg_cmd;
std::string arg_dns;
std::string arg_info;
bool arg_verbose = false;
bool arg_nocertcheck = false;
bool gotURL = false;
bool gotProfile = false;
bool gotProxy = false;
bool gotDns = false;
if (argc==1)
if (argc == 1)
{
std::cout << "Use -h, --help for help." << std::endl;
std::cout << "Use --help for help." << std::endl;
return 0;
}
for (int i=1; i<argc; i++)
// get for help
if (args_get_help(argc, argv))
{
if ( (boost::equals(argv[i], "--help")) || (boost::equals(argv[i], "-h")) )
{
showUsage();
return 0;
}
usage_show_help();
return 0;
}
for (int i=1; i<argc; i++)
// check for version
if (args_get_version(argc, argv))
{
if ( (boost::equals(argv[i], "--url")) || (boost::equals(argv[i], "-u")) )
{
if (i+1<argc)
{
gotURL = true;
websocket_address = argv[++i];
if (!isPrintable(websocket_address))
{
std::cout << "Input contains invalid characters." << std::endl;
std::cout << "Use -h, --help for help." << std::endl;
return 0;
}
}
}
else if ( (boost::equals(argv[i], "--profile")) || (boost::equals(argv[i], "-p")) )
{
if (i+1<argc)
{
gotProfile = true;
server_profile = argv[++i];
if (!isPrintable(server_profile))
{
std::cout << "Input contains invalid characters." << std::endl;
std::cout << "Use -h, --help for help." << std::endl;
return 0;
}
}
}
else if ( (boost::equals(argv[i], "--proxy")) ||(boost::equals(argv[i], "-x")) )
{
if (i+1<argc)
{
gotProxy = true;
websocket_proxy = argv[++i];
if (!isPrintable(websocket_proxy))
{
std::cout << "Input contains invalid characters." << std::endl;
std::cout << "Use -h, --help for help." << std::endl;
return 0;
}
}
}
else if ( (boost::equals(argv[i], "--dns")) ||(boost::equals(argv[i], "-d")) )
{
if (i+1<argc)
{
gotDns = true;
dns_suffix = argv[++i];
if (!isPrintable(dns_suffix))
{
std::cout << "Input contains invalid characters." << std::endl;
std::cout << "Use -h, --help for help." << std::endl;
return 0;
}
}
}
else
{
std::cout << "Unrecognized command line arguments." << std::endl;
std::cout << "Use -h, --help for help." << std::endl;
return 0;
}
usage_show_version();
return 0;
}
if (!gotURL || !gotProfile)
// Check if running in elevated privileges
if (!cmd_is_admin())
{
std::cout << "Unable to launch application. Please ensure that Intel ME is present, the MEI driver is installed and that this application is run with administrator or root privileges." << std::endl;
return 0;
}
// check for info
if (args_get_info(argc, argv, arg_info))
{
if (!info_get_verify(arg_info))
{
std::cout << "Incorrect or missing arguments." << std::endl;
std::cout << "Use --help for help." << std::endl;
return 0;
}
info_get(arg_info);
return 0;
}
// get required arguments
if (!args_get_url(argc, argv, arg_url) || !args_get_cmd(argc, argv, arg_cmd))
{
std::cout << "Incorrect or missing arguments." << std::endl;
std::cout << "Use -h, --help for help." << std::endl;
std::cout << "Use --help for help." << std::endl;
return 0;
}
// verbose output
if (args_get_verbose(argc, argv))
{
arg_verbose = true;
}
// no websocket server certificate verification
if (args_get_nocertcheck(argc, argv))
{
arg_nocertcheck = true;
}
// Print version info
cout << PROJECT_NAME << " v" PROJECT_VER << endl;
usage_show_version();
try {
// Get activation info
activationInfo = createActivationRequest(server_profile, dns_suffix);
if (args_get_dns(argc, argv, arg_dns))
{
if (!act_create_request(arg_cmd, arg_dns, activation_info)) throw std::runtime_error("unable to get activation info");
}
else
{
if (!act_create_request(arg_cmd, "" , activation_info)) throw std::runtime_error("unable to get activation info");
}
}
catch (...)
{
std::cerr << endl << "Unable to get activation info. Check AMT configuration." << endl;
std::cerr << std::endl << "Unable to get activation info. Try again later or check AMT configuration." << std::endl;
return 1;
}
try
{
// Check if LMS is available
SOCKET s = lmsConnect();
closesocket(s);
// check if LMS is available
SOCKET lms_socket = lms_connect();
closesocket(lms_socket);
}
catch (...)
{
std::cerr << endl << "Unable to connect to Local Management Service (LMS). Please ensure LMS is running." << endl;
return 1;
// start MicroLMS thread
std::thread main_micro_lms_thread(main_micro_lms);
main_micro_lms_thread.detach();
// wait for MicroLMS to startup
for (int i=0; i<5; i++) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
// Show activation info
#ifdef DEBUG
cout << "Activation info: " << endl << activationInfo << endl;
#endif
// WebSocket Interface
websocket_client_config client_config;
if (!websocket_proxy.empty())
// webSocket Interface
web::websockets::client::websocket_client_config client_config;
if (args_get_proxy(argc, argv, arg_proxy))
{
client_config.set_proxy(web::web_proxy(utility::conversions::to_string_t(websocket_proxy)));
client_config.set_proxy(web::web_proxy(utility::conversions::to_string_t(arg_proxy)));
}
#ifdef DEBUG
// skip certificate verification if debug build
cout << "!!! SKIPPING CERTIFICATE VERIFICATION !!!" << endl;
client_config.set_validate_certificates(false);
#endif
websocket_callback_client client(client_config);
// websocket server certificate verification
if (arg_nocertcheck)
{
// skip websocket server certificate verification
std::cout << "Skipping certificate verification." << std::endl;
client_config.set_validate_certificates(false);
}
web::websockets::client::websocket_callback_client client(client_config);
std::condition_variable cv;
std::mutex mx;
SOCKET s;
SOCKET lms_socket;
memset(&lms_socket, 0, sizeof(SOCKET));
// set receive handler
client.set_message_handler([&client, &mx, &cv, &s](websocket_incoming_message ret_msg)
client.set_message_handler([&client, &mx, &cv, &lms_socket, arg_verbose](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();
auto duration = now.time_since_epoch();
timeoutTimer = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
g_timeout_val = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
try
{
// handle message from server...
string rcv_websocket_msg = ret_msg.extract_string().get();
#ifdef DEBUG
cout << endl << "<<<<< Received Message " << endl;
cout << rcv_websocket_msg << endl;
#endif
cout << "." << std::flush; // dot status output
// handle message from server
std::string rcv_websocket_msg = ret_msg.extract_string().get();
std::cout << "." << std::flush; // dot status output
// parse incoming JSON message
utility::string_t tmp = utility::conversions::convertstring(rcv_websocket_msg);
web::json::value parsed = web::json::value::parse(tmp);
utility::string_t out = U("");
string msgMethod = "";
string msgApiKey = "";
string msgAppVersion = "";
string msgProtocolVersion = "";
string msgStatus = "";
string msgMessage = "";
string msgPayload = "";
string payloadDecoded = "";
std::string msgMethod = "";
std::string msgApiKey = "";
std::string msgAppVersion = "";
std::string msgProtocolVersion = "";
std::string msgStatus = "";
std::string msgMessage = "";
std::string msgPayload = "";
std::string 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")) ||
!parsed.has_field(U("payload")) ) {
std::cerr << endl << "Received incorrectly formatted message." << endl;
std::cerr << std::endl << "Received incorrectly formatted message." << std::endl;
cv.notify_all();
timeoutThreadAlive = false;
g_thread_alive = false;
return;
}
@@ -282,35 +244,74 @@ int main(int argc, char *argv[])
}
catch (...)
{
std::cerr << endl << "Received message parse error." << endl;
std::cerr << std::endl << "Received message parse error." << std::endl;
return;
}
if (msgMethod.compare("heartbeat_request") == 0)
{
// create the response
std::string response;
if (!heartbeat_create_response(response)) return;
#ifdef DEBUG
cout << msgMethod << ", " << msgStatus << ", " << msgMessage << endl;
cout << rcv_websocket_msg << endl;
#endif
// 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;
}
// process any messages we can
// - if success, done
// - if error, get out
if (boost::iequals(msgMethod, "success"))
if (msgStatus.compare("success")==0)
{
// cleanup
timeoutTimer = 0;
g_timeout_val = 0;
// exit
cout << endl << msgMessage << endl;
try {
std::cout << std::endl;
utility::string_t tmp = utility::conversions::convertstring(msgMessage);
web::json::value parsed = web::json::value::parse(tmp);
for (const auto& obj : parsed.as_object()) {
std::string key = utility::conversions::to_utf8string(obj.first);
std::string value = utility::conversions::to_utf8string(obj.second.serialize());
value.erase(std::remove(value.begin(), value.end(), '"'), value.end());
std::cout << key << ": " << value << std::endl;
}
}
catch (...)
{
std::cout << std::endl << msgMessage << std::endl;
}
return;
}
else if (boost::iequals(msgMethod, "error"))
else if (msgStatus.compare("failed")==0)
{
// cleanup
timeoutTimer = 0;
g_timeout_val = 0;
// exit
cout << endl << msgMessage << endl;
try {
std::cout << std::endl;
utility::string_t tmp = utility::conversions::convertstring(msgMessage);
web::json::value parsed = web::json::value::parse(tmp);
for (const auto& obj : parsed.as_object()) {
std::string key = utility::conversions::to_utf8string(obj.first);
std::string value = utility::conversions::to_utf8string(obj.second.serialize());
value.erase(std::remove(value.begin(), value.end(), '"'), value.end());
std::cout << key << ": " << value << std::endl;
}
}
catch (...)
{
std::cout << std::endl << msgMessage << std::endl;
}
return;
}
@@ -325,7 +326,7 @@ int main(int argc, char *argv[])
msgPayload = utility::conversions::to_utf8string(out);
// decode payload
payloadDecoded = decodeBase64(msgPayload);
payloadDecoded = util_decode_base64(msgPayload);
}
else
{
@@ -335,37 +336,38 @@ int main(int argc, char *argv[])
}
catch (...)
{
std::cerr << endl << "JSON format error. Unable to parse message." << endl;
std::cerr << std::endl << "JSON format error. Unable to parse message." << std::endl;
return;
}
try
{
// conntect to lms
s = lmsConnect();
lms_socket = lms_connect();
}
catch (...)
{
std::cerr << endl << "Unable to connect to Local Management Service (LMS). Please ensure LMS is running." << endl;
std::cerr << std::endl << "Unable to connect to Local Management Service (LMS). Please ensure LMS is running." << std::endl;
return;
}
#ifdef DEBUG
cout << endl << "vvvvv Sending Message " << endl;
cout << payloadDecoded << endl;
#endif
if (arg_verbose)
{
std::cout << std::endl << "vvv -- message to AMT -- vvv" << std::endl;
std::cout << payloadDecoded << std::endl;
}
// send message to LMS
if (send(s, payloadDecoded.c_str(), (int)payloadDecoded.length(), 0) < 0)
if (send(lms_socket, payloadDecoded.c_str(), (int)payloadDecoded.length(), 0) < 0)
{
throw std::runtime_error("error: socket send");
}
// handle response message from LMS
int fd = ((int) s) + 1;
int fd = ((int)lms_socket) + 1;
fd_set rset;
FD_ZERO(&rset);
FD_SET(s, &rset);
FD_SET(lms_socket, &rset);
timeval timeout;
memset(&timeout, 0, sizeof(timeval));
@@ -375,7 +377,7 @@ int main(int argc, char *argv[])
// read until connection is closed by LMS
while (1)
{
string superBuffer = "";
std::string superBuffer = "";
while (1)
{
int res = select(fd, &rset, NULL, NULL, &timeout);
@@ -390,13 +392,9 @@ int main(int argc, char *argv[])
// read from LMS
char recv_buffer[4096];
memset(recv_buffer, 0, 4096);
res = recv(s, recv_buffer, 4096, 0);
res = recv(lms_socket, recv_buffer, 4096, 0);
if (res > 0)
{
#ifdef DEBUG
cout << endl << "^^^^^ Received Message" << endl;
cout << recv_buffer << endl;
#endif
superBuffer += recv_buffer;
}
else if (res < 0)
@@ -406,9 +404,8 @@ int main(int argc, char *argv[])
}
else
{
// case where res is zero bytes
// discussion below, but select returns 1 with recv returning 0 to indicate close
// https://stackoverflow.com/questions/2992547/waiting-for-data-via-select-not-working
// case where res is zero bytes, select returns 1
// with recv returning 0 to indicate close
break;
}
} // while select()
@@ -416,34 +413,37 @@ int main(int argc, char *argv[])
// if there is some data send it
if (superBuffer.length() > 0)
{
string response = createResponse(superBuffer.c_str());
websocket_outgoing_message send_websocket_msg;
string send_websocket_buffer(response);
if (arg_verbose)
{
std::cout << std::endl << "^^^ -- message from AMT -- ^^^" << std::endl;
std::cout << superBuffer << std::endl;
}
std::string response;
if (!act_create_response(superBuffer.c_str(), response)) return;
web::websockets::client::websocket_outgoing_message send_websocket_msg;
std::string send_websocket_buffer(response);
send_websocket_msg.set_utf8_message(send_websocket_buffer);
#ifdef DEBUG
cout << endl << ">>>>> Sending Message" << endl;
cout << superBuffer << endl;
cout << send_websocket_buffer << endl;
#endif
client.send(send_websocket_msg).wait();
// done
closesocket(s);
closesocket(lms_socket);
return;
}
}
closesocket(s);
closesocket(lms_socket);
}
catch (...)
{
std::cerr << endl << "Communication error in receive handler." << endl;
closesocket(s);
std::cerr << std::endl << "Communication error in receive handler." << std::endl;
closesocket(lms_socket);
}
});
// set close handler
client.set_close_handler([&mx,&cv](websocket_close_status status, const utility::string_t &reason, const std::error_code &code)
client.set_close_handler([&mx,&cv](web::websockets::client::websocket_close_status status, const utility::string_t &reason, const std::error_code &code)
{
// websocket closed by server, notify main thread
cv.notify_all();
@@ -451,37 +451,32 @@ int main(int argc, char *argv[])
try
{
// Connect to web socket server; AMT activation server
client.connect(utility::conversions::to_string_t(websocket_address)).wait();
// connect to web socket server; AMT activation server
client.connect(utility::conversions::to_string_t(arg_url)).wait();
}
catch (...)
{
std::cerr << "Unable to connect to websocket server. Please check url." << endl;
std::cerr << "Unable to connect to websocket server. Please check url." << std::endl;
exit(1);
}
try
{
// Send activationParams to websocket
websocket_outgoing_message out_msg;
out_msg.set_utf8_message(activationInfo);
#ifdef DEBUG
cout << endl << ">>>>> Sending Activiation Info" << endl;
cout << activationInfo << endl;
#endif
// send activationParams to websocket
web::websockets::client::websocket_outgoing_message out_msg;
out_msg.set_utf8_message(activation_info);
client.send(out_msg).wait();
}
catch (...)
{
std::cerr << endl << "Unable to send message to websocket server." << endl;
std::cerr << std::endl << "Unable to send message to websocket server." << std::endl;
exit(1);
}
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
auto duration = now.time_since_epoch();
timeoutTimer = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
std::thread timeoutThread(timeoutFunc, &cv, &mx);
g_timeout_val = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
std::thread timeoutThread(timeout_thread_function, &cv, &mx);
// wait for server to send success/failure command
std::unique_lock<std::mutex> lock(mx);
@@ -494,40 +489,9 @@ int main(int argc, char *argv[])
client.close().wait();
// clean-up socket
if (s) {
shutdown(s, SD_BOTH);
closesocket(s);
}
shutdown(lms_socket, SD_BOTH);
closesocket(lms_socket);
exit(0);
}
bool isPrintable(std::string str)
{
for (char c : str)
{
if (!std::isprint(c))
{
return false;
}
}
return true;
}
void showUsage()
{
cout << "Usage: " << PROJECT_NAME << " --url <url> --profile <name> [--proxy <addr>]" << endl;
cout << "Required:" << endl;
cout << " -u, --url <url> websocket server" << endl;
cout << " -p, --profile <name> server profile" << endl;
cout << "Optional:" << endl;
cout << " -x, --proxy <addr> proxy address and port" << endl;
cout << " -d, --dns <dns> dns suffix" << endl;
cout << endl;
cout << "Examples:" << endl;
cout << " " << PROJECT_NAME << " --url wss://localhost --profile profile1" << endl;
cout << " " << PROJECT_NAME << " -u wss://localhost --profile profile1 --proxy http://proxy.com:1000" << endl;
cout << " " << PROJECT_NAME << " -u wss://localhost -p profile1 -x http://proxy.com:1000" << endl;
cout << endl;
}

240
network.cpp Normal file
View File

@@ -0,0 +1,240 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "network.h"
#include "commands.h"
#include <iostream>
#include <vector>
#ifdef _WIN32
#include <winsock2.h>
#include <iphlpapi.h>
#define WORKING_BUFFER_SIZE 15000
#define MAX_TRIES 3
#else
#include <string.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
typedef int SOCKET;
#endif
#ifdef _WIN32
std::string net_get_dns(char* macAddress)
{
std::string dnsSuffix = "";
char dns[256];
memset(dns, 0, 256);
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
ULONG outBufLen = 0;
ULONG Iterations = 0;
outBufLen = WORKING_BUFFER_SIZE;
// get info for all adapters
do {
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
if (pAddresses == NULL) {
std::cout << "dns memory error" << std::endl;
return dnsSuffix;
}
dwRetVal = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW)
{
free(pAddresses);
pAddresses = NULL;
}
else
{
break;
}
Iterations++;
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES));
// get DNS from MAC
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
pCurrAddresses = pAddresses;
while (pCurrAddresses)
{
if (pCurrAddresses->PhysicalAddressLength != 0)
{
if (memcmp(macAddress, (char*)pCurrAddresses->PhysicalAddress, 6) == 0)
{
if (wcslen(pCurrAddresses->DnsSuffix) > 0)
{
snprintf(dns, 256, "%ws", pCurrAddresses->DnsSuffix);
break;
}
}
}
pCurrAddresses = pCurrAddresses->Next;
}
dnsSuffix = dns;
return dnsSuffix;
}
#else
std::string net_get_dns(char* macAddress)
{
std::string dnsSuffix = "";
// get socket
SOCKET s = 0;
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0)
{
std::cout << "couldn't get socket" << std::endl;
return dnsSuffix;
}
// get info for all adapters
struct ifconf ifc;
memset(&ifc, 0, sizeof(ifconf));
char buffer[8192];
memset(buffer, 0, sizeof(buffer));
ifc.ifc_buf = buffer;
ifc.ifc_len = sizeof(buffer);
if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
{
std::cout << "ioctl SIOCGIFCONF failed" << std::endl;
return dnsSuffix;
}
// get DNS from IP associated with MAC
struct ifreq* ifr = ifc.ifc_req;
int interfaceCount = ifc.ifc_len / sizeof(struct ifreq);
char ip[INET6_ADDRSTRLEN] = { 0 };
struct ifreq* item;
struct sockaddr* addr;
for (int i = 0; i < interfaceCount; i++)
{
item = &ifr[i];
addr = &(item->ifr_addr);
// get IP address
if (ioctl(s, SIOCGIFADDR, item) < 0)
{
std::cout << "ioctl SIOCGIFADDR failed" << std::endl;
continue;
}
if (inet_ntop(AF_INET, &(((struct sockaddr_in*)addr)->sin_addr),
ip, sizeof(ip)) == NULL)
{
std::cout << "inet_ntop" << std::endl;
continue;
}
// get MAC address
if (ioctl(s, SIOCGIFHWADDR, item) < 0)
{
std::cout << "ioctl SIOCGIFHWADDR failed" << std::endl;
continue;
}
if (memcmp(macAddress, (char*)item->ifr_hwaddr.sa_data, 6) == 0)
{
// Get host by using the IP address which AMT device is using
struct in_addr addr = { 0 };
struct hostent* host;
addr.s_addr = inet_addr(ip);
host = gethostbyaddr((char*)&addr, 4, AF_INET);
if (host == NULL)
{
std::cout << "gethostbyaddr() failed";
return dnsSuffix;
}
// strip off the hostname to get actual domain name
int domainNameSize = 256;
char domainName[domainNameSize];
memset(domainName, 0, domainNameSize);
char* dn = strchr(host->h_name, '.');
if (dn != NULL)
{
if (domainNameSize >= strlen(dn + 1))
{
snprintf(domainName, domainNameSize, "%s", ++dn);
dnsSuffix = domainName;
}
}
}
}
return dnsSuffix;
}
#endif
std::string net_get_hostname()
{
char hostname[256];
std::string hostname_string = "";
int result;
#ifdef WIN32
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
throw std::runtime_error("error: network error");
}
#endif
// get hostname
result = gethostname(hostname, sizeof(hostname));
#ifdef WIN32
WSACleanup();
#endif
if (result == 0)
{
hostname_string = hostname;
}
return hostname_string;
}
std::string net_get_dns()
{
std::string dns_suffix;
std::vector<unsigned char> address;
cmd_get_wired_mac_address(address);
if (address.size() == 6)
{
char macAddress[6];
macAddress[0] = address[0];
macAddress[1] = address[1];
macAddress[2] = address[2];
macAddress[3] = address[3];
macAddress[4] = address[4];
macAddress[5] = address[5];
// get DNS from OS
dns_suffix = net_get_dns(macAddress);
}
return dns_suffix;
}

15
network.h Normal file
View File

@@ -0,0 +1,15 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __NETWORK_H__
#define __NETWORK_H__
#include <string>
std::string net_get_dns(char* macAddress);
std::string net_get_hostname();
std::string net_get_dns();
#endif

26
port.h Normal file
View File

@@ -0,0 +1,26 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __PORT_H__
#define __PORT_H__
#include <string.h>
extern "C"
{
// main entry into microlms
extern int main_micro_lms();
}
#ifdef _WIN32
// Windows
#define strncpy strncpy_s
#define strcasecmp _stricmp
#else
// Linux
#endif
#endif

26
scripts/jenkins-build.cmd Executable file
View File

@@ -0,0 +1,26 @@
:: Build script
:: - Windows 10
:: - Visual Studio 2019
:: - Git
::
:: IMPORTANT!!!
:: Open "x64 Native Command Tool Prompt for VS 2019" as Administrator.
::
CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"
REM current dir - RPC source directory
set BASE_DIR=%cd%
set VCPKG_DIR=C:\opt\vcpkg-source
REM build RPC
if exist "build" rd /q /s "build"
mkdir build
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%\build

19
scripts/jenkins-build.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
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"
if [ -d "build" ]; then
rm -rf build
fi
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE="$BASE_DIR"/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .

23
scripts/jenkins-pre-build.cmd Executable file
View File

@@ -0,0 +1,23 @@
:: Build script
:: - Windows 10
:: - Visual Studio 2019
:: - Git
::
:: IMPORTANT!!!
:: Open "x64 Native Command Tool Prompt for VS 2019" as Administrator.
::
CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"
REM current dir - RPC source directory
set VCPKG_DIR=C:\opt\vcpkg-source
cd %VCPKG_DIR%
REM build vcpkg
git clone --branch 2020.11-1 https://github.com/microsoft/vcpkg.git
cd vcpkg
cmd /c bootstrap-vcpkg.bat
REM install CPPRestSDK
cmd /c vcpkg install cpprestsdk[websockets]:x64-windows-static

20
scripts/jenkins-pre-build.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
# Jenkins Pre Build script
# - Ubuntu 18.04
#
apt update
apt install git cmake build-essential curl zip unzip tar pkg-config -y
## current dir - RPC source directory
#export BASE_DIR="$PWD"
#cd "$BASE_DIR"/rpc
## build vcpkg
git -C vcpkg pull || git clone --branch 2020.11-1 https://github.com/microsoft/vcpkg.git vcpkg
cd vcpkg
./bootstrap-vcpkg.sh
## install CPPRestSDK
./vcpkg install cpprestsdk[websockets]

89
test.cpp Normal file
View File

@@ -0,0 +1,89 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "gtest/gtest.h"
#include <string>
#include <thread>
#include <cpprest/ws_client.h>
#include <cpprest/json.h>
#include "port.h"
#include "utils.h"
const std::string plainText = "Ut aliquet ex id enim accumsan bibendum. Nullam nibh ligula, rhoncus vitae nisl eu, fermentum luctus tellus. Sed non semper augue, vitae congue nibh. Suspendisse sed placerat metus. Nunc a sapien vel nisl semper fringilla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam accumsan, nisi vitae efficitur ultricies, velit neque mattis velit, sed sodales tellus est at orci. Duis sed ipsum lorem. In eu enim eu odio fringilla lacinia id id lorem. Vestibulum velit augue, ultricies et neque eget, molestie vehicula urna. Etiam venenatis nibh vel nunc fringilla, vitae feugiat ipsum posuere. Pellentesque ac libero quis nulla pretium iaculis sed at felis. Integer malesuada turpis eget lectus interdum, a commodo nisl tristique. Proin rutrum nisl ut metus aliquam, vel lacinia tortor ullamcorper. Nulla rhoncus ullamcorper accumsan. Fusce eget augue vulputate, porta quam at, laoreet justo.";
const std::string encodedText = "VXQgYWxpcXVldCBleCBpZCBlbmltIGFjY3Vtc2FuIGJpYmVuZHVtLiBOdWxsYW0gbmliaCBsaWd1bGEsIHJob25jdXMgdml0YWUgbmlzbCBldSwgZmVybWVudHVtIGx1Y3R1cyB0ZWxsdXMuIFNlZCBub24gc2VtcGVyIGF1Z3VlLCB2aXRhZSBjb25ndWUgbmliaC4gU3VzcGVuZGlzc2Ugc2VkIHBsYWNlcmF0IG1ldHVzLiBOdW5jIGEgc2FwaWVuIHZlbCBuaXNsIHNlbXBlciBmcmluZ2lsbGEuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBBbGlxdWFtIGFjY3Vtc2FuLCBuaXNpIHZpdGFlIGVmZmljaXR1ciB1bHRyaWNpZXMsIHZlbGl0IG5lcXVlIG1hdHRpcyB2ZWxpdCwgc2VkIHNvZGFsZXMgdGVsbHVzIGVzdCBhdCBvcmNpLiBEdWlzIHNlZCBpcHN1bSBsb3JlbS4gSW4gZXUgZW5pbSBldSBvZGlvIGZyaW5naWxsYSBsYWNpbmlhIGlkIGlkIGxvcmVtLiBWZXN0aWJ1bHVtIHZlbGl0IGF1Z3VlLCB1bHRyaWNpZXMgZXQgbmVxdWUgZWdldCwgbW9sZXN0aWUgdmVoaWN1bGEgdXJuYS4gRXRpYW0gdmVuZW5hdGlzIG5pYmggdmVsIG51bmMgZnJpbmdpbGxhLCB2aXRhZSBmZXVnaWF0IGlwc3VtIHBvc3VlcmUuIFBlbGxlbnRlc3F1ZSBhYyBsaWJlcm8gcXVpcyBudWxsYSBwcmV0aXVtIGlhY3VsaXMgc2VkIGF0IGZlbGlzLiBJbnRlZ2VyIG1hbGVzdWFkYSB0dXJwaXMgZWdldCBsZWN0dXMgaW50ZXJkdW0sIGEgY29tbW9kbyBuaXNsIHRyaXN0aXF1ZS4gUHJvaW4gcnV0cnVtIG5pc2wgdXQgbWV0dXMgYWxpcXVhbSwgdmVsIGxhY2luaWEgdG9ydG9yIHVsbGFtY29ycGVyLiBOdWxsYSByaG9uY3VzIHVsbGFtY29ycGVyIGFjY3Vtc2FuLiBGdXNjZSBlZ2V0IGF1Z3VlIHZ1bHB1dGF0ZSwgcG9ydGEgcXVhbSBhdCwgbGFvcmVldCBqdXN0by4=";
// Test if characters are printable
TEST(testUtils, isPrintableTestValid)
{
std::string s = "The quick brown fox jumps over the lazy dog.";
EXPECT_EQ(true, util_is_printable(s));
}
// Test if characters are printable
TEST(testUtils, isPrintableTestInvalid)
{
std::string s = "The quick brown fox jumps over the lazy dog.";
s[0] = 10; // non-printable character
EXPECT_EQ(false, util_is_printable(s));
}
// Test encode of base64 string
TEST(testUtils, encodebase64)
{
EXPECT_EQ(encodedText, util_encode_base64(plainText));
}
// Test decode of base64 sstring
TEST(testUtils, decodebase64)
{
EXPECT_EQ(plainText, util_decode_base64(encodedText));
}
// Test return value of util_format_uuid
TEST(testUtils, formatUUIDSuccess)
{
std::vector<unsigned char> uuid_bytes;
for (int i=0; i<16; i++)
{
uuid_bytes.push_back(i);
}
std::string uuid_string;
util_format_uuid(uuid_bytes, uuid_string);
EXPECT_EQ(true, util_format_uuid(uuid_bytes, uuid_string));
}
// Test return value of util_format_uuid
TEST(testUtils, formatUUIDFail)
{
std::vector<unsigned char> uuid_bytes;
for (int i=0; i<5; i++) // invalid length
{
uuid_bytes.push_back(i);
}
std::string uuid_string;
util_format_uuid(uuid_bytes, uuid_string);
EXPECT_EQ(false, util_format_uuid(uuid_bytes, uuid_string));
}
// Test value of the uuid format to ensure format is correct
TEST(testUtils, formatUUIDValue)
{
std::string uuid_string;
std::vector<unsigned char> uuid_bytes;
for (int i=0; i<16; i++)
{
uuid_bytes.push_back(i);
}
util_format_uuid(uuid_bytes, uuid_string);
EXPECT_EQ("03020100-0504-0706-0809-0a0b0c0d0e0f", uuid_string);
}

73
usage.cpp Normal file
View File

@@ -0,0 +1,73 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "usage.h"
#include <iostream>
#include "version.h"
#include "activation.h"
void usage_show_help()
{
// 80 chars "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
std::cout << "Usage: " << std::endl;
std::cout << " " << PROJECT_NAME << " <required> [optional]" << std::endl;
std::cout << " " << PROJECT_NAME << " <informational>" << std::endl;
std::cout << std::endl;
std::cout << "Required:" << std::endl;
std::cout << " -u, --url <url> websocket server" << std::endl;
std::cout << " -c, --cmd <command> server command" << std::endl;
std::cout << std::endl;
std::cout << " Since <command> can contain multiple options and arguments, the entire" << std::endl;
std::cout << " <command> must be in quotes. Please see examples below." << std::endl;
std::cout << std::endl;
std::cout << "Optional:" << std::endl;
std::cout << " -p, --proxy <addr> proxy address and port" << std::endl;
std::cout << " -d, --dns <dns> dns suffix override" << std::endl;
std::cout << " -n, --nocertcheck skip websocket server certificate verification" << std::endl;
std::cout << " -v, --verbose verbose output" << std::endl;
std::cout << std::endl;
std::cout << "Informational:" << std::endl;
std::cout << " --help this help text" << std::endl;
std::cout << " --version version" << std::endl;
std::cout << " --amtinfo <item> AMT info on an <item>" << std::endl;
std::cout << std::endl;
std::cout << "Item:" << std::endl;
std::cout << " all all items" << std::endl;
std::cout << " ver BIOS version" << std::endl;
std::cout << " bld build number" << std::endl;
std::cout << " sku product SKU" << std::endl;
std::cout << " uuid unique identifier" << std::endl;
std::cout << " mode current control mode" << std::endl;
std::cout << " dns domain name suffix" << std::endl;
std::cout << " fqdn fully qualified domain name" << std::endl;
std::cout << " cert certificate hashes" << std::endl;
std::cout << " ras remote access status" << std::endl;
std::cout << " lan LAN settings" << std::endl;
std::cout << std::endl;
std::cout << "Examples:" << std::endl;
std::cout << " # Activate platform using profile1" << std::endl;
std::cout << " " << PROJECT_NAME << \
" --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://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://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;
}
void usage_show_version()
{
std::string project_name = PROJECT_NAME;
for (auto& c : project_name) c = toupper(c); // get upper case string
std::cout << project_name << " " << PROJECT_VER << "." << std::endl;
std::cout << "Protocol " << PROTOCOL_VERSION << "." << std::endl;
}

12
usage.h Normal file
View File

@@ -0,0 +1,12 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __USAGE_H__
#define __USAGE_H__
void usage_show_help();
void usage_show_version();
#endif

59
utils.cpp Normal file
View File

@@ -0,0 +1,59 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "utils.h"
#include <vector>
#include <string>
#include <cpprest/streams.h>
std::string util_encode_base64(std::string str)
{
std::vector<unsigned char> strVector(str.begin(), str.end());
utility::string_t base64 = utility::conversions::to_base64(strVector);
std::string encodedString = utility::conversions::to_utf8string(base64);
return encodedString;
}
std::string 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());
return decodedString;
}
bool util_is_printable(std::string str)
{
for (char c : str)
{
if (!std::isprint(c))
{
return false;
}
}
return true;
}
bool util_format_uuid(std::vector<unsigned char> uuid_bytes, std::string& uuid_string)
{
if (uuid_bytes.size() != 16) return false;
char tmp[100];
snprintf(tmp, 100,
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid_bytes[3], uuid_bytes[2], uuid_bytes[1], uuid_bytes[0],
uuid_bytes[5], uuid_bytes[4],
uuid_bytes[7], uuid_bytes[6],
uuid_bytes[8], uuid_bytes[9],
uuid_bytes[10], uuid_bytes[11], uuid_bytes[12], uuid_bytes[13], uuid_bytes[14], uuid_bytes[15]);
uuid_string = tmp;
return true;
}

17
utils.h Normal file
View File

@@ -0,0 +1,17 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __UTILS_H__
#define __UTILS_H__
#include <string>
#include <vector>
std::string util_encode_base64(std::string str);
std::string 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);
#endif