Initial commit.

This commit is contained in:
Ulf Frisk
2025-02-02 00:58:44 +01:00
commit 355ec190ce
37 changed files with 4692 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.vs/
x64/
build/
Debug/
Release/

610
LICENSE.txt Normal file
View File

@@ -0,0 +1,610 @@
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 [yyyy] [name of copyright owner]
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.
-----------------------------------------------------------
BSD 3-Clause License
Copyright 2016, Google Inc.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

104
Readme.md Normal file
View File

@@ -0,0 +1,104 @@
libleechgrpc
============
libleechgrpc is a wrapper around gRPC to allow PCILeech/LeechCore/MemProcFS to access remote LeechAgent instances in a platform independent way.
libleechgrpc supports two authentication modes:
* unauthenticated with no transport encryption - i.e. insecure mode.
* mutually authenticated mTLS connection - i.e. secure mode.
libleechgrpc is by default statically linked and shouldn't require additional libraries.
Building (Windows):
===================
```
#
# Install grpc-static via vcpkg
# This will take a decent while since it's compiling etc.
#
git clone https://github.com/microsoft/vcpkg.git C:\src\vcpkg
cd C:\src\vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg integrate install
.\vcpkg install grpc:x64-windows-static protobuf:x64-windows-static
#
# Generate gRPC stubs using the installed packages.
#
cd C:\src\leechgrpc\leechgrpc\
C:\src\vcpkg\installed\x64-windows-static\tools\protobuf\protoc.exe --proto_path=proto --cpp_out=generated --grpc_out=generated --plugin=protoc-gen-grpc="C:\src\vcpkg\installed\x64-windows\tools\grpc\grpc_cpp_plugin.exe" leechgrpc.proto
#
# Build leechgrpc in Visual Studio or by using the Visual Studio 2022 command prompt:
#
cd C:\src\leechgrpc\
MSBuild libleechgrpc.sln /t:Rebuild /property:Configuration=Release /property:Platform=x64"
```
Building (Linux):
===================
```bash
# export local bin directory to path
export MY_INSTALL_DIR=$HOME/.local
export PATH="$MY_INSTALL_DIR/bin:$PATH"
# install build tools
sudo apt update
sudo apt install git build-essential autoconf libtool pkg-config
# clone gRPC from github
mkdir -p $HOME/.local
mkdir -p $HOME/.local/build
cd $HOME/.local/build
git clone --recurse-submodules -b v1.66.0 https://github.com/grpc/grpc.git
cd grpc
git submodule update --init --recursive
mkdir -p cmake/build
cd cmake/build
# get cmake (since linux cmake may be too old)
wget -q -O cmake-linux.sh https://github.com/Kitware/CMake/releases/download/v3.30.3/cmake-3.30.3-linux-x86_64.sh
sh cmake-linux.sh -- --skip-license --prefix=$MY_INSTALL_DIR
rm cmake-linux.sh
export PATH="$HOME/.local/bin:$PATH"
cmake --version
# build gRPC as a static library and install locally
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \
-DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR \
-DBUILD_SHARED_LIBS=OFF \
-DgRPC_INSTALL=ON \
-DgRPC_BUILD_TESTS=OFF \
-DgRPC_BUILD_GRPC_CSHARP_PLUGIN=OFF \
-DgRPC_BUILD_GRPC_NODE_PLUGIN=OFF \
-DgRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN=OFF \
-DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF \
-DgRPC_BUILD_GRPC_PYTHON_PLUGIN=OFF \
-DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF \
../..
make -j 4
make install
# clone libleechgrpc from github
mkdir -p ~/Github/
cd ~/Github/
git clone https://github.com/ufrisk/libleechgrpc
mkdir -p ~/Github/libleechgrpc/libleechgrpc/build
cd ~/Github/libleechgrpc/libleechgrpc/build
# build libleechgrpc.so
cmake \
-DCMAKE_PREFIX_PATH="$MY_INSTALL_DIR" \
-DCMAKE_CXX_FLAGS="-DLINUX -fPIC -O2 -ffunction-sections -fdata-sections -flto" \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_EXE_LINKER_FLAGS="-flto -Wl,--gc-sections" \
..
make -j 4
# libleechgrpc.so should now have been built if everything was successful!
```

19
cert/client-tls.cer Normal file
View File

@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDCTCCAfGgAwIBAgIULquEzhPTDxOYReDVDTwZdg6EaMUwDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI1MDEyNzE2MDkwMloXDTI2MDEy
NzE2MDkwMlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAnL8Nqmwv/XK+UB+jE49vRYI3ZY7by6GeKaSd57z+ukiN
nDVRlivmIrRGQsjoEpM0w9ZNlDdGcT2jT1JfAitFRGEXN0mmYGgX8KcCZ/AUouWZ
oEqApqrvqSh7Wx+I+OHQpiIhybV8CvYPQxacWrpr484jSfEmaMcxxOv1rK3qTfUP
VI4nLVfOdlTvRpJymxFoJItVWZtUo1AK/kWGrCG0ESvz9/XWZYBmui891P1aunIX
Yq3LDA3ClYr6sa7Perdvj+MWKR85PkJuwE0dz5IKm8m48C9pmmWmChxY2krNtyOJ
IO6I6nZOufIbdyNmg+kchkaBzhf4ilUfGdaXctYCgQIDAQABo1MwUTAdBgNVHQ4E
FgQUN2iRFkdh9cPtBE4fQK7UYaaXBxYwHwYDVR0jBBgwFoAUN2iRFkdh9cPtBE4f
QK7UYaaXBxYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAipsu
E1gQAtrMoWm3wPngsvxX/bi8M6ND9RnLi2O4C/0lnbNkRvIXqnuw8gvaRuXcdIJx
ftJO202df4JaPnZrdmpmwto4Bi3z2pnZYh4BPTMBuQNKdGtieF/WEfYtrXoD/D0U
IYnraCKKRUZ3OOjegS3gqAg2eqRmHd9YmsT3ROGdI1OD8Zw88xlQGE9CoW9hvjCx
lxGrgP1eSFyiQK5yY8RB0dgknm1Yz3XEeu2b7mO7pXpJcmDyNqhjRmUSNWtfl/24
BIHOkPqDRIQyeqRw4VkbLLTTh1RhogSckOnRnYiYPDwFnHuOoK14iw1K2XxxdJfL
SUEGXxqzige7f4LEVQ==
-----END CERTIFICATE-----

28
cert/client-tls.key Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCcvw2qbC/9cr5Q
H6MTj29FgjdljtvLoZ4ppJ3nvP66SI2cNVGWK+YitEZCyOgSkzTD1k2UN0ZxPaNP
Ul8CK0VEYRc3SaZgaBfwpwJn8BSi5ZmgSoCmqu+pKHtbH4j44dCmIiHJtXwK9g9D
FpxaumvjziNJ8SZoxzHE6/WsrepN9Q9UjictV852VO9GknKbEWgki1VZm1SjUAr+
RYasIbQRK/P39dZlgGa6Lz3U/Vq6chdircsMDcKVivqxrs96t2+P4xYpHzk+Qm7A
TR3PkgqbybjwL2maZaYKHFjaSs23I4kg7ojqdk658ht3I2aD6RyGRoHOF/iKVR8Z
1pdy1gKBAgMBAAECggEAALamqvX8O6/LFZmoRA93BOKqaoMdhWI0YmmEObzgrrPD
98AfIYMshG/MQlNwaX27q7DI+H3OK3epq7Oy+KM+aOjVeogieo28vqje9B7J1EI9
6lauelu8tKkZUyVMCgB6ovf0rgquQG1FbWNv5aKTuUUr4FM5fth5xbUCgLVHs9BB
/PHGqH/YgG7DjCImxR7ZxkrxLuRdGtgGN/Tv9FOvF/iAtOW4KGGdPyDlmr+DL491
yZoSRsj3vXiXwTVKJsA+Hr+OB/2PPN7LnFWTIWERmxVQJi+nUyP69VaSPlvz6JQ+
hiNarYQK82LWTSWPNHXB/NOJrvvLCk7hmQIBVdvtsQKBgQDQeC20ezGFsEnINgJm
yKX/LI54Ascz2fOMMmus522MdUYweyasVD3Qk/zKU0FCxgGapDTacfQFfeSutzOy
0LGZFhz2h/260Ws2Joz23yzDcMrlqMaIe4d2gJ1xiTTATmMkZtpYVdRYBePg+4hW
62bKbe+2IIfyOhqg/KLl/jvMUQKBgQDAe+3Lp5SA2fuCHi0eahpnZcDr2w1ptogn
fqTGSWKk3/wjXYzFQSMnZir09u8oQELrtyNjnIThPcQ+9H1FSN+ZcmIRpTyLaVN0
xm4sqfZ7HfpjgRNgMpyqhF/+R1EkmxdNEUlkjqaa4zjQkUlXV7/+B8wxuiIbJOe1
E/EozXa3MQKBgCPwM+DjQ/xKEc4kEXHqsUM2STFDOVglAKlwn8Nk+iu2o+0Drf0T
YLyuZmvywlNikzA3kqz97BVuSJgeGRmAhL1hZIjTlNg59gOVzcNZYfwnW7MPz3oD
4ax6K6pA/wkP+mNyH74OvdaW3VwRwMVLO6M2JJb/MLB/d8u9AdAobeKhAoGBAJz7
9gMk178HCVMj3VRy4Ln3iRJTA2t2TTE43pZBf8xMSU1mnMq7xzn434wOYRsI3gt0
v84b91vkjktyB0EcoBB783PEuc5Rxpj0xSJ0M+xRlMbWnMDWRmPjto6iB5G9U5Gt
SZhTp5mnO80O0SwFCzbZkTX1Qp+0x60taIAIoovhAoGBAM5xOExRJwIvCo0kJF3f
EWgcEQmlxk7wACzRo/afrzze79uYN1HrNjqgOcu9XVKLw8nunp971jHuWMldrPfx
dgu3sDaVWB7+sjyr5q9/Lu5Pq/yHvMLfL5FPhXJNnnvltmK5LuIVGc6pUzGVpUgF
tNfWTpKxshYnZ20YsiBqmBtJ
-----END PRIVATE KEY-----

BIN
cert/client-tls.p12 Normal file

Binary file not shown.

5
cert/password.txt Normal file
View File

@@ -0,0 +1,5 @@
test
openssl req -x509 -newkey rsa:2048 -keyout client-tls.key -out client-tls.crt -days 365 -nodes -subj "/CN=localhost"
openssl pkcs12 -export -out client-tls.p12 -inkey client-tls.key -in client-tls.crt -password pass:test

9
cert/readme.txt Normal file
View File

@@ -0,0 +1,9 @@
These certificates are only for use in testing mTLS connections with the leechgrpc_test_server & leechgrpc_test_client projects.
Do not under any circumstances use these certificates / keys in any production environment!
Password to the .pfx files: test
Generated with commands:
openssl req -x509 -newkey rsa:2048 -keyout client-tls.key -out client-tls.crt -days 365 -nodes -subj "/CN=localhost"
openssl pkcs12 -export -out client-tls.p12 -inkey client-tls.key -in client-tls.crt -password pass:test

19
cert/server-tls.cer Normal file
View File

@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDCTCCAfGgAwIBAgIUa7SPVgJaTd5awjxOGkvu9CcPFPcwDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI1MDEyNzE2MDgzNFoXDTI2MDEy
NzE2MDgzNFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAtIaZ/3JlzIM+NmUsdSX/01Sw0yiy/tXnaDdI1CdUVgWx
83iKPjSYBNntR4UMafiealWn2pr059K4dbLIor2i8Qx2v5riM9k7gyw3bZkdJOdj
mg7wtQFqvd/Z4kJiTf5ORJO7rRoeK0fxQJkxYm2f54v2gRmiiBoJjA5k7bY8R2dz
ZLqJc+bF2zZH8+JUKmkfNbPyPx5LrMTGu/78l+nkdi6OHp9Axd4RFQMMVQ1Sbzkc
DfZxEiWT3bNPqJh5de5/C8EwcxVdjIcAzGqMm1vh7fMAEHllhghJ6npmT7Dc5mVT
eRKiHPitIlA+CQ+R6jUTLEYjXl8THELDXuV2BVL8oQIDAQABo1MwUTAdBgNVHQ4E
FgQUDi7jUZuPjEbcflXQqALNO52cdw0wHwYDVR0jBBgwFoAUDi7jUZuPjEbcflXQ
qALNO52cdw0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEABzPJ
5KTVhT9UteUzAvgjGWQ/6GmsL8oT9XL/au6n/OWLCS1L4h47QPqjaOjZ9SDl+iyF
Myz8NdSUwSNxHDywOKswwFtUWRibRiOjKwWSHLjLtU1BlUTorh3ZCrRz74apdlFC
KQtngMe7cC08DtGtamSxGQ2wpvQ/nISEF3t6VGu5z9pkK6uqkKKxZZoJcVAW/Bsg
+CukowSkNberKPMoKlm1gjFCy8z94nSNTuIIsjMjWtnh5TivHEZfxU5qjo6vLPVG
9EGdNXPChG7Imo4a8rSue40aDgVOnA2P5KVoT5ArVIuS8XCCID8cB4hbT0uv2yjc
tEYT2+hYmdkpJWBfiA==
-----END CERTIFICATE-----

28
cert/server-tls.key Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0hpn/cmXMgz42
ZSx1Jf/TVLDTKLL+1edoN0jUJ1RWBbHzeIo+NJgE2e1HhQxp+J5qVafamvTn0rh1
ssiivaLxDHa/muIz2TuDLDdtmR0k52OaDvC1AWq939niQmJN/k5Ek7utGh4rR/FA
mTFibZ/ni/aBGaKIGgmMDmTttjxHZ3Nkuolz5sXbNkfz4lQqaR81s/I/HkusxMa7
/vyX6eR2Lo4en0DF3hEVAwxVDVJvORwN9nESJZPds0+omHl17n8LwTBzFV2MhwDM
aoybW+Ht8wAQeWWGCEnqemZPsNzmZVN5EqIc+K0iUD4JD5HqNRMsRiNeXxMcQsNe
5XYFUvyhAgMBAAECggEAA8v06dobvqe1TkA7JXeYICIJhKy4HwNGq6Vwra2UvikT
1ggJ+Ebzj4k5zqWYs5MxWbvVcj6MugzE07eKirRW/J+De9d5EcLBgqpnvAawBeUB
Q5iJgspggVUiPaT3G6bROetVfiLXfEI2FmK3wYHcDsBIfeyZGNMGB7ZhybIUeyKZ
G61Qq8WtuCp3odXbaM53SfMeqjtMJTodbc7xphR7h+9YLVvrmUubbk0GzCbUHc1o
0G4OHRPMIDs6G1lRYID6ChwZFLwg+u5htQ2jodSw5Mp8WhaD+NiKiMabsIzM2a2F
nhvv6zeyQJ3hB2mKwQWNSCQj+MxRlVPp2uFSP7bNcQKBgQDrqNyop3D7NPeVfxwp
MxtLBqpgjE6OFCILvear5QzGmM8nONoMuCjZJvgs2VGRjIQeS0W9czJN4Oy0YWFw
FiqeMWSmn9xdWb6WrJttYZe79oUNU6Pw9Y6368ENI0BlFmo5xsZJZxVoiAwMTScP
Oh1wYsi6pIioRhC0DZp8DL3FlQKBgQDEG4Bz0ee9TjxCGCCDANyDzwALaUTOJxr2
cN6nTpsxOiNEGNQR1sFHrBWwZfLN1N19cyjUt+qxJjC4ZJsC2D0+8N8Sfh5eyVgN
XQlAoccb+Ki8lUwwRZd24ZmAdRfck2zWSFQEq0+GK2wRjGD1HhzHrkttIgp5oxbJ
Boi9OvD/3QKBgC400981xY9b2Ve0rp7daHKTggCgQh7Vj79hosL9jD28ZJG6Mfbg
fRHm9C5HBhlVxenytF/rIGfovEC5/1Ls5bpS0PtiyOB84kPE4EzYH9o5AemVBsYO
P8eMMDQVP2ESvg1KDkMCNU5jrokS75+qs27/z3/ZFvp3knrbV/kOvn7pAoGAO4tK
LmCOp6konLzsqjpJum/QyKY28Q1on2lYAZ7ZelH3wUZ0pdH6L8PtdfkOhzbZ5axg
um35gb5hzqslcfCsb/79DIVkvU0PQkd8drZoWXLf8Rq33nRS8BLB5AIps5zD0DB3
6k8Fv2xRzOY9zk9NV8fxOPq8CYDeez1TqXlLEbUCgYEAuSfPfHYCT388zfceAWNO
VtN8c4uFNLZEC++7K+H3rEY6ADfW7Vgk54bn0IQNqkL3wFs+64HjU2HfBiHPFegW
ZEPhBiO5+EsmlAHexuNwUV6A74CZYgPnbcQC1x8nK69uNJHrTDCd55qfmCYkDDXw
BDXN+at1hbwGUqm+qDb5TCo=
-----END PRIVATE KEY-----

BIN
cert/server-tls.p12 Normal file

Binary file not shown.

View File

@@ -0,0 +1,79 @@
#include <Windows.h>
#include <stdio.h>
#include "../libleechgrpc/leechgrpc.h"
#pragma comment(lib, "libleechgrpc.lib")
int main_insecure()
{
LPCSTR szHOST = "localhost";
DWORD dwPORT = 28474;
HANDLE hGRPC;
PBYTE pbIn = NULL, pbOut = NULL;
SIZE_T cbIn = 0, cbOut = 0;
BOOL fResult;
hGRPC = leechgrpc_client_create_insecure(szHOST, dwPORT);
if(hGRPC == NULL) {
printf("[Client] Error creating gRPC client.\n");
return 1;
}
pbIn = (PBYTE)"MESSAGE FROM TEST CLIENT!";
cbIn = strlen((char *)pbIn);
fResult = leechgrpc_client_submit_command(hGRPC, pbIn, cbIn, &pbOut, &cbOut);
if(!fResult) {
printf("[Client] Error submitting command.\n");
leechgrpc_client_free(hGRPC);
return 1;
}
printf("[Client] Server responded with: %s\n", pbOut);
leechgrpc_client_free(hGRPC);
return 0;
}
int main_secure_tls()
{
LPCSTR szHOST = "127.0.0.1";
DWORD dwPORT = 28474;
HANDLE hGRPC;
PBYTE pbIn = NULL, pbOut = NULL;
SIZE_T cbIn = 0, cbOut = 0;
BOOL fResult;
hGRPC = leechgrpc_client_create_secure_p12(szHOST, dwPORT, "localhost", "..\\..\\cert\\server-tls.cer", "..\\..\\cert\\client-tls.p12", "test");
if(hGRPC == NULL) {
printf("[Client] Error creating gRPC client.\n");
return 1;
}
pbIn = (PBYTE)"MESSAGE FROM TEST CLIENT!";
cbIn = strlen((char *)pbIn);
fResult = leechgrpc_client_submit_command(hGRPC, pbIn, cbIn, &pbOut, &cbOut);
if(!fResult) {
printf("[Client] Error submitting command.\n");
leechgrpc_client_free(hGRPC);
return 1;
}
printf("[Client] Server responded with: %s\n", pbOut);
leechgrpc_client_free(hGRPC);
return 0;
}
int main()
{
//main_insecure();
main_secure_tls();
}

View File

@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{6126530e-8882-4aaf-97e0-177c0ddb7ede}</ProjectGuid>
<RootNamespace>leechgrpctestclient</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)$(Platform)\$(Configuration)\;</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(SolutionDir)$(Platform)\$(Configuration)\;</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(SolutionDir)$(Platform)\$(Configuration)\;</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)$(Platform)\$(Configuration)\;</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="leechgrpc_test_client.cc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="leechgrpc_test_client.cc">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,63 @@
#include <Windows.h>
#include <stdio.h>
#include "../libleechgrpc/leechgrpc.h"
#pragma comment(lib, "libleechgrpc.lib")
VOID TestServerCB(_In_ PVOID ctx, _In_ PBYTE pbIn, _In_ SIZE_T cbIn, _Out_ PBYTE *ppbOut, _Out_ SIZE_T *pcbOut)
{
printf("[Server] Received message: %s\n", pbIn);
*pcbOut = strlen("MESSAGE FROM TEST SERVER!") + 1;
*ppbOut = (PBYTE)LocalAlloc(LMEM_FIXED, *pcbOut);
memcpy(*ppbOut, "MESSAGE FROM TEST SERVER!", *pcbOut);
}
int main_insecure()
{
DWORD dwPORT = 28474;
HANDLE hGRPC;
hGRPC = leechgrpc_server_create_insecure("0.0.0.0", dwPORT, NULL, TestServerCB);
if(!hGRPC) {
printf("[Server] Error creating gRPC server.\n");
return 1;
}
printf("[Server] server created!\n");
printf("[Server] start wait.\n");
leechgrpc_server_wait(hGRPC);
printf("[Server] wait completed - shutting down!\n");
leechgrpc_server_shutdown(hGRPC);
return 0;
}
int main_secure_tls() {
DWORD dwPORT = 28474;
HANDLE hGRPC;
hGRPC = leechgrpc_server_create_secure_p12("0.0.0.0", dwPORT, NULL, TestServerCB, "..\\..\\cert\\client-tls.cer", "..\\..\\cert\\server-tls.p12", "test");
if(!hGRPC) {
printf("[Server] Error creating gRPC server.\n");
return 1;
}
printf("[Server] server created!\n");
printf("[Server] start wait.\n");
leechgrpc_server_wait(hGRPC);
printf("[Server] wait completed - shutting down!\n");
leechgrpc_server_shutdown(hGRPC);
return 0;
}
int main()
{
main_secure_tls();
}

View File

@@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{2aa97c80-3f98-43df-a640-7d20bc575b4c}</ProjectGuid>
<RootNamespace>leechgrpctestserver</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(SolutionDir)$(Platform)\$(Configuration)\;</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(SolutionDir)$(Platform)\$(Configuration)\;</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)$(Platform)\$(Configuration)\;</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)$(Platform)\$(Configuration)\;</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="leechgrpc_test_server.cc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="leechgrpc_test_server.cc">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

65
libleechgrpc.sln Normal file
View File

@@ -0,0 +1,65 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.12.35707.178
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libleechgrpc", "libleechgrpc\libleechgrpc.vcxproj", "{7F9DE005-851F-4817-8749-0396DA30B3F8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libleechgrpc_test_client", "leechgrpc_test_client\leechgrpc_test_client.vcxproj", "{6126530E-8882-4AAF-97E0-177C0DDB7EDE}"
ProjectSection(ProjectDependencies) = postProject
{7F9DE005-851F-4817-8749-0396DA30B3F8} = {7F9DE005-851F-4817-8749-0396DA30B3F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "leechgrpc_test_server", "leechgrpc_test_server\leechgrpc_test_server.vcxproj", "{2AA97C80-3F98-43DF-A640-7D20BC575B4C}"
ProjectSection(ProjectDependencies) = postProject
{7F9DE005-851F-4817-8749-0396DA30B3F8} = {7F9DE005-851F-4817-8749-0396DA30B3F8}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cert", "cert", "{8B55BAB8-A859-4E01-961F-4C7CF896F07C}"
ProjectSection(SolutionItems) = preProject
cert\client-tls.key = cert\client-tls.key
cert\client-tls.cer = cert\client-tls.cer
cert\client-tls.p12 = cert\client-tls.p12
cert\password.txt = cert\password.txt
cert\server-tls.key = cert\server-tls.key
cert\server-tls.cer = cert\server-tls.cer
cert\server-tls.p12 = cert\server-tls.p12
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7F9DE005-851F-4817-8749-0396DA30B3F8}.Debug|x64.ActiveCfg = Debug|x64
{7F9DE005-851F-4817-8749-0396DA30B3F8}.Debug|x64.Build.0 = Debug|x64
{7F9DE005-851F-4817-8749-0396DA30B3F8}.Debug|x86.ActiveCfg = Debug|Win32
{7F9DE005-851F-4817-8749-0396DA30B3F8}.Debug|x86.Build.0 = Debug|Win32
{7F9DE005-851F-4817-8749-0396DA30B3F8}.Release|x64.ActiveCfg = Release|x64
{7F9DE005-851F-4817-8749-0396DA30B3F8}.Release|x64.Build.0 = Release|x64
{7F9DE005-851F-4817-8749-0396DA30B3F8}.Release|x86.ActiveCfg = Release|Win32
{7F9DE005-851F-4817-8749-0396DA30B3F8}.Release|x86.Build.0 = Release|Win32
{6126530E-8882-4AAF-97E0-177C0DDB7EDE}.Debug|x64.ActiveCfg = Debug|x64
{6126530E-8882-4AAF-97E0-177C0DDB7EDE}.Debug|x64.Build.0 = Debug|x64
{6126530E-8882-4AAF-97E0-177C0DDB7EDE}.Debug|x86.ActiveCfg = Debug|Win32
{6126530E-8882-4AAF-97E0-177C0DDB7EDE}.Debug|x86.Build.0 = Debug|Win32
{6126530E-8882-4AAF-97E0-177C0DDB7EDE}.Release|x64.ActiveCfg = Release|x64
{6126530E-8882-4AAF-97E0-177C0DDB7EDE}.Release|x64.Build.0 = Release|x64
{6126530E-8882-4AAF-97E0-177C0DDB7EDE}.Release|x86.ActiveCfg = Release|Win32
{6126530E-8882-4AAF-97E0-177C0DDB7EDE}.Release|x86.Build.0 = Release|Win32
{2AA97C80-3F98-43DF-A640-7D20BC575B4C}.Debug|x64.ActiveCfg = Debug|x64
{2AA97C80-3F98-43DF-A640-7D20BC575B4C}.Debug|x64.Build.0 = Debug|x64
{2AA97C80-3F98-43DF-A640-7D20BC575B4C}.Debug|x86.ActiveCfg = Debug|Win32
{2AA97C80-3F98-43DF-A640-7D20BC575B4C}.Debug|x86.Build.0 = Debug|Win32
{2AA97C80-3F98-43DF-A640-7D20BC575B4C}.Release|x64.ActiveCfg = Release|x64
{2AA97C80-3F98-43DF-A640-7D20BC575B4C}.Release|x64.Build.0 = Release|x64
{2AA97C80-3F98-43DF-A640-7D20BC575B4C}.Release|x86.ActiveCfg = Release|Win32
{2AA97C80-3F98-43DF-A640-7D20BC575B4C}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,83 @@
# Copyright 2018 gRPC authors.
#
# 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.
#
# cmake build file for C++ helloworld example.
# Assumes protobuf and gRPC have been installed using cmake.
# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build
# that automatically builds all the dependencies before building helloworld.
cmake_minimum_required(VERSION 3.8)
project(leechgrpc C CXX)
include(./common.cmake)
#set(OPENSSL_USE_STATIC_LIBS TRUE)
#find_package(OpenSSL REQUIRED)
# Proto file
get_filename_component(hw_proto "./proto/leechgrpc.proto" ABSOLUTE)
get_filename_component(hw_proto_path "${hw_proto}" PATH)
# Generated sources
set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/leechgrpc.pb.cc")
set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/leechgrpc.pb.h")
set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/leechgrpc.grpc.pb.cc")
set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/leechgrpc.grpc.pb.h")
add_custom_command(
OUTPUT "${hw_proto_srcs}" "${hw_proto_hdrs}" "${hw_grpc_srcs}" "${hw_grpc_hdrs}"
COMMAND ${_PROTOBUF_PROTOC}
ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}"
--cpp_out "${CMAKE_CURRENT_BINARY_DIR}"
-I "${hw_proto_path}"
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
"${hw_proto}"
DEPENDS "${hw_proto}")
# Include generated *.pb.h files
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
# hw_grpc_proto
add_library(hw_grpc_proto
${hw_grpc_srcs}
${hw_grpc_hdrs}
${hw_proto_srcs}
${hw_proto_hdrs})
target_link_libraries(hw_grpc_proto
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})
# --- [ Final shared library ] -----------------------------------------------
# We now create a shared library that pulls in everything statically
# (except for system libs). On Linux, you need position-independent code
# for all objects, which we enabled earlier with CMAKE_POSITION_INDEPENDENT_CODE=TRUE
# when building gRPC and with the default setting for these libraries here.
add_library(leechgrpc SHARED "${CMAKE_CURRENT_SOURCE_DIR}/leechgrpc_client.cc" "${CMAKE_CURRENT_SOURCE_DIR}/leechgrpc_server.cc" "${CMAKE_CURRENT_SOURCE_DIR}/oscompatibility.cc" "${CMAKE_CURRENT_SOURCE_DIR}/util.cc")
# Link the static pieces
target_link_libraries(leechgrpc
PRIVATE
hw_grpc_proto
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF}
# OpenSSL::SSL
# OpenSSL::Crypto
)
# Provide an soname for the library if desired:
set_target_properties(leechgrpc PROPERTIES
OUTPUT_NAME "leechgrpc"
SOVERSION "1"
)

122
libleechgrpc/common.cmake Normal file
View File

@@ -0,0 +1,122 @@
# Copyright 2018 gRPC authors.
#
# 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.
#
# cmake build file for C++ route_guide example.
# Assumes protobuf and gRPC have been installed using cmake.
# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build
# that automatically builds all the dependencies before building route_guide.
cmake_minimum_required(VERSION 3.8)
if(MSVC)
add_definitions(-D_WIN32_WINNT=0x600)
endif()
find_package(Threads REQUIRED)
if(GRPC_AS_SUBMODULE)
# One way to build a projects that uses gRPC is to just include the
# entire gRPC project tree via "add_subdirectory".
# This approach is very simple to use, but the are some potential
# disadvantages:
# * it includes gRPC's CMakeLists.txt directly into your build script
# without and that can make gRPC's internal setting interfere with your
# own build.
# * depending on what's installed on your system, the contents of submodules
# in gRPC's third_party/* might need to be available (and there might be
# additional prerequisites required to build them). Consider using
# the gRPC_*_PROVIDER options to fine-tune the expected behavior.
#
# A more robust approach to add dependency on gRPC is using
# cmake's ExternalProject_Add (see cmake_externalproject/CMakeLists.txt).
# Include the gRPC's cmake build (normally grpc source code would live
# in a git submodule called "third_party/grpc", but this example lives in
# the same repository as gRPC sources, so we just look a few directories up)
add_subdirectory(../../.. ${CMAKE_CURRENT_BINARY_DIR}/grpc EXCLUDE_FROM_ALL)
message(STATUS "Using gRPC via add_subdirectory.")
# After using add_subdirectory, we can now use the grpc targets directly from
# this build.
set(_PROTOBUF_LIBPROTOBUF libprotobuf)
set(_REFLECTION grpc++_reflection)
set(_ORCA_SERVICE grpcpp_orca_service)
if(CMAKE_CROSSCOMPILING)
find_program(_PROTOBUF_PROTOC protoc)
else()
set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
endif()
set(_GRPC_GRPCPP grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
endif()
elseif(GRPC_FETCHCONTENT)
# Another way is to use CMake's FetchContent module to clone gRPC at
# configure time. This makes gRPC's source code available to your project,
# similar to a git submodule.
message(STATUS "Using gRPC via add_subdirectory (FetchContent).")
include(FetchContent)
FetchContent_Declare(
grpc
GIT_REPOSITORY https://github.com/grpc/grpc.git
# when using gRPC, you will actually set this to an existing tag, such as
# v1.25.0, v1.26.0 etc..
# For the purpose of testing, we override the tag used to the commit
# that's currently under test.
GIT_TAG vGRPC_TAG_VERSION_OF_YOUR_CHOICE)
FetchContent_MakeAvailable(grpc)
# Since FetchContent uses add_subdirectory under the hood, we can use
# the grpc targets directly from this build.
set(_PROTOBUF_LIBPROTOBUF libprotobuf)
set(_REFLECTION grpc++_reflection)
set(_PROTOBUF_PROTOC $<TARGET_FILE:protoc>)
set(_GRPC_GRPCPP grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
endif()
else()
# This branch assumes that gRPC and all its dependencies are already installed
# on this system, so they can be located by find_package().
# Find Protobuf installation
# Looks for protobuf-config.cmake file installed by Protobuf's cmake installation.
option(protobuf_MODULE_COMPATIBLE TRUE)
find_package(Protobuf CONFIG REQUIRED)
message(STATUS "Using protobuf ${Protobuf_VERSION}")
set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
set(_REFLECTION gRPC::grpc++_reflection)
if(CMAKE_CROSSCOMPILING)
find_program(_PROTOBUF_PROTOC protoc)
else()
set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
endif()
# Find gRPC installation
# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation.
find_package(gRPC CONFIG REQUIRED)
message(STATUS "Using gRPC ${gRPC_VERSION}")
set(_GRPC_GRPCPP gRPC::grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>)
endif()
endif()

View File

@@ -0,0 +1,86 @@
// Generated by the gRPC C++ plugin.
// If you make any local change, they will be lost.
// source: leechgrpc.proto
#include "leechgrpc.pb.h"
#include "leechgrpc.grpc.pb.h"
#include <functional>
#include <grpcpp/support/async_stream.h>
#include <grpcpp/support/async_unary_call.h>
#include <grpcpp/impl/channel_interface.h>
#include <grpcpp/impl/client_unary_call.h>
#include <grpcpp/support/client_callback.h>
#include <grpcpp/support/message_allocator.h>
#include <grpcpp/support/method_handler.h>
#include <grpcpp/impl/rpc_service_method.h>
#include <grpcpp/support/server_callback.h>
#include <grpcpp/impl/server_callback_handlers.h>
#include <grpcpp/server_context.h>
#include <grpcpp/impl/service_type.h>
#include <grpcpp/support/sync_stream.h>
namespace leechrpc {
static const char* LeechRpc_method_names[] = {
"/leechrpc.LeechRpc/ReservedSubmitCommand",
};
std::unique_ptr< LeechRpc::Stub> LeechRpc::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
(void)options;
std::unique_ptr< LeechRpc::Stub> stub(new LeechRpc::Stub(channel, options));
return stub;
}
LeechRpc::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options)
: channel_(channel), rpcmethod_ReservedSubmitCommand_(LeechRpc_method_names[0], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
{}
::grpc::Status LeechRpc::Stub::ReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::leechrpc::SubmitCommandResponse* response) {
return ::grpc::internal::BlockingUnaryCall< ::leechrpc::SubmitCommandRequest, ::leechrpc::SubmitCommandResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_ReservedSubmitCommand_, context, request, response);
}
void LeechRpc::Stub::async::ReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest* request, ::leechrpc::SubmitCommandResponse* response, std::function<void(::grpc::Status)> f) {
::grpc::internal::CallbackUnaryCall< ::leechrpc::SubmitCommandRequest, ::leechrpc::SubmitCommandResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_ReservedSubmitCommand_, context, request, response, std::move(f));
}
void LeechRpc::Stub::async::ReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest* request, ::leechrpc::SubmitCommandResponse* response, ::grpc::ClientUnaryReactor* reactor) {
::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_ReservedSubmitCommand_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::leechrpc::SubmitCommandResponse>* LeechRpc::Stub::PrepareAsyncReservedSubmitCommandRaw(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::grpc::CompletionQueue* cq) {
return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::leechrpc::SubmitCommandResponse, ::leechrpc::SubmitCommandRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_ReservedSubmitCommand_, context, request);
}
::grpc::ClientAsyncResponseReader< ::leechrpc::SubmitCommandResponse>* LeechRpc::Stub::AsyncReservedSubmitCommandRaw(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::grpc::CompletionQueue* cq) {
auto* result =
this->PrepareAsyncReservedSubmitCommandRaw(context, request, cq);
result->StartCall();
return result;
}
LeechRpc::Service::Service() {
AddMethod(new ::grpc::internal::RpcServiceMethod(
LeechRpc_method_names[0],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< LeechRpc::Service, ::leechrpc::SubmitCommandRequest, ::leechrpc::SubmitCommandResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
[](LeechRpc::Service* service,
::grpc::ServerContext* ctx,
const ::leechrpc::SubmitCommandRequest* req,
::leechrpc::SubmitCommandResponse* resp) {
return service->ReservedSubmitCommand(ctx, req, resp);
}, this)));
}
LeechRpc::Service::~Service() {
}
::grpc::Status LeechRpc::Service::ReservedSubmitCommand(::grpc::ServerContext* context, const ::leechrpc::SubmitCommandRequest* request, ::leechrpc::SubmitCommandResponse* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
} // namespace leechrpc

View File

@@ -0,0 +1,243 @@
// Generated by the gRPC C++ plugin.
// If you make any local change, they will be lost.
// source: leechgrpc.proto
#ifndef GRPC_leechgrpc_2eproto__INCLUDED
#define GRPC_leechgrpc_2eproto__INCLUDED
#include "leechgrpc.pb.h"
#include <functional>
#include <grpcpp/generic/async_generic_service.h>
#include <grpcpp/support/async_stream.h>
#include <grpcpp/support/async_unary_call.h>
#include <grpcpp/support/client_callback.h>
#include <grpcpp/client_context.h>
#include <grpcpp/completion_queue.h>
#include <grpcpp/support/message_allocator.h>
#include <grpcpp/support/method_handler.h>
#include <grpcpp/impl/proto_utils.h>
#include <grpcpp/impl/rpc_method.h>
#include <grpcpp/support/server_callback.h>
#include <grpcpp/impl/server_callback_handlers.h>
#include <grpcpp/server_context.h>
#include <grpcpp/impl/service_type.h>
#include <grpcpp/support/status.h>
#include <grpcpp/support/stub_options.h>
#include <grpcpp/support/sync_stream.h>
namespace leechrpc {
class LeechRpc final {
public:
static constexpr char const* service_full_name() {
return "leechrpc.LeechRpc";
}
class StubInterface {
public:
virtual ~StubInterface() {}
// Mirrors the MSRPC call: LeechRpc_ReservedSubmitCommand
virtual ::grpc::Status ReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::leechrpc::SubmitCommandResponse* response) = 0;
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::leechrpc::SubmitCommandResponse>> AsyncReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::grpc::CompletionQueue* cq) {
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::leechrpc::SubmitCommandResponse>>(AsyncReservedSubmitCommandRaw(context, request, cq));
}
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::leechrpc::SubmitCommandResponse>> PrepareAsyncReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::grpc::CompletionQueue* cq) {
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::leechrpc::SubmitCommandResponse>>(PrepareAsyncReservedSubmitCommandRaw(context, request, cq));
}
class async_interface {
public:
virtual ~async_interface() {}
// Mirrors the MSRPC call: LeechRpc_ReservedSubmitCommand
virtual void ReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest* request, ::leechrpc::SubmitCommandResponse* response, std::function<void(::grpc::Status)>) = 0;
virtual void ReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest* request, ::leechrpc::SubmitCommandResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
};
typedef class async_interface experimental_async_interface;
virtual class async_interface* async() { return nullptr; }
class async_interface* experimental_async() { return async(); }
private:
virtual ::grpc::ClientAsyncResponseReaderInterface< ::leechrpc::SubmitCommandResponse>* AsyncReservedSubmitCommandRaw(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::grpc::CompletionQueue* cq) = 0;
virtual ::grpc::ClientAsyncResponseReaderInterface< ::leechrpc::SubmitCommandResponse>* PrepareAsyncReservedSubmitCommandRaw(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::grpc::CompletionQueue* cq) = 0;
};
class Stub final : public StubInterface {
public:
Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
::grpc::Status ReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::leechrpc::SubmitCommandResponse* response) override;
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::leechrpc::SubmitCommandResponse>> AsyncReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::grpc::CompletionQueue* cq) {
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::leechrpc::SubmitCommandResponse>>(AsyncReservedSubmitCommandRaw(context, request, cq));
}
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::leechrpc::SubmitCommandResponse>> PrepareAsyncReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::grpc::CompletionQueue* cq) {
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::leechrpc::SubmitCommandResponse>>(PrepareAsyncReservedSubmitCommandRaw(context, request, cq));
}
class async final :
public StubInterface::async_interface {
public:
void ReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest* request, ::leechrpc::SubmitCommandResponse* response, std::function<void(::grpc::Status)>) override;
void ReservedSubmitCommand(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest* request, ::leechrpc::SubmitCommandResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
private:
friend class Stub;
explicit async(Stub* stub): stub_(stub) { }
Stub* stub() { return stub_; }
Stub* stub_;
};
class async* async() override { return &async_stub_; }
private:
std::shared_ptr< ::grpc::ChannelInterface> channel_;
class async async_stub_{this};
::grpc::ClientAsyncResponseReader< ::leechrpc::SubmitCommandResponse>* AsyncReservedSubmitCommandRaw(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::grpc::CompletionQueue* cq) override;
::grpc::ClientAsyncResponseReader< ::leechrpc::SubmitCommandResponse>* PrepareAsyncReservedSubmitCommandRaw(::grpc::ClientContext* context, const ::leechrpc::SubmitCommandRequest& request, ::grpc::CompletionQueue* cq) override;
const ::grpc::internal::RpcMethod rpcmethod_ReservedSubmitCommand_;
};
static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
class Service : public ::grpc::Service {
public:
Service();
virtual ~Service();
// Mirrors the MSRPC call: LeechRpc_ReservedSubmitCommand
virtual ::grpc::Status ReservedSubmitCommand(::grpc::ServerContext* context, const ::leechrpc::SubmitCommandRequest* request, ::leechrpc::SubmitCommandResponse* response);
};
template <class BaseClass>
class WithAsyncMethod_ReservedSubmitCommand : public BaseClass {
private:
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
public:
WithAsyncMethod_ReservedSubmitCommand() {
::grpc::Service::MarkMethodAsync(0);
}
~WithAsyncMethod_ReservedSubmitCommand() override {
BaseClassMustBeDerivedFromService(this);
}
// disable synchronous version of this method
::grpc::Status ReservedSubmitCommand(::grpc::ServerContext* /*context*/, const ::leechrpc::SubmitCommandRequest* /*request*/, ::leechrpc::SubmitCommandResponse* /*response*/) override {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
void RequestReservedSubmitCommand(::grpc::ServerContext* context, ::leechrpc::SubmitCommandRequest* request, ::grpc::ServerAsyncResponseWriter< ::leechrpc::SubmitCommandResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
}
};
typedef WithAsyncMethod_ReservedSubmitCommand<Service > AsyncService;
template <class BaseClass>
class WithCallbackMethod_ReservedSubmitCommand : public BaseClass {
private:
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
public:
WithCallbackMethod_ReservedSubmitCommand() {
::grpc::Service::MarkMethodCallback(0,
new ::grpc::internal::CallbackUnaryHandler< ::leechrpc::SubmitCommandRequest, ::leechrpc::SubmitCommandResponse>(
[this](
::grpc::CallbackServerContext* context, const ::leechrpc::SubmitCommandRequest* request, ::leechrpc::SubmitCommandResponse* response) { return this->ReservedSubmitCommand(context, request, response); }));}
void SetMessageAllocatorFor_ReservedSubmitCommand(
::grpc::MessageAllocator< ::leechrpc::SubmitCommandRequest, ::leechrpc::SubmitCommandResponse>* allocator) {
::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(0);
static_cast<::grpc::internal::CallbackUnaryHandler< ::leechrpc::SubmitCommandRequest, ::leechrpc::SubmitCommandResponse>*>(handler)
->SetMessageAllocator(allocator);
}
~WithCallbackMethod_ReservedSubmitCommand() override {
BaseClassMustBeDerivedFromService(this);
}
// disable synchronous version of this method
::grpc::Status ReservedSubmitCommand(::grpc::ServerContext* /*context*/, const ::leechrpc::SubmitCommandRequest* /*request*/, ::leechrpc::SubmitCommandResponse* /*response*/) override {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
virtual ::grpc::ServerUnaryReactor* ReservedSubmitCommand(
::grpc::CallbackServerContext* /*context*/, const ::leechrpc::SubmitCommandRequest* /*request*/, ::leechrpc::SubmitCommandResponse* /*response*/) { return nullptr; }
};
typedef WithCallbackMethod_ReservedSubmitCommand<Service > CallbackService;
typedef CallbackService ExperimentalCallbackService;
template <class BaseClass>
class WithGenericMethod_ReservedSubmitCommand : public BaseClass {
private:
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
public:
WithGenericMethod_ReservedSubmitCommand() {
::grpc::Service::MarkMethodGeneric(0);
}
~WithGenericMethod_ReservedSubmitCommand() override {
BaseClassMustBeDerivedFromService(this);
}
// disable synchronous version of this method
::grpc::Status ReservedSubmitCommand(::grpc::ServerContext* /*context*/, const ::leechrpc::SubmitCommandRequest* /*request*/, ::leechrpc::SubmitCommandResponse* /*response*/) override {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
};
template <class BaseClass>
class WithRawMethod_ReservedSubmitCommand : public BaseClass {
private:
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
public:
WithRawMethod_ReservedSubmitCommand() {
::grpc::Service::MarkMethodRaw(0);
}
~WithRawMethod_ReservedSubmitCommand() override {
BaseClassMustBeDerivedFromService(this);
}
// disable synchronous version of this method
::grpc::Status ReservedSubmitCommand(::grpc::ServerContext* /*context*/, const ::leechrpc::SubmitCommandRequest* /*request*/, ::leechrpc::SubmitCommandResponse* /*response*/) override {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
void RequestReservedSubmitCommand(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
}
};
template <class BaseClass>
class WithRawCallbackMethod_ReservedSubmitCommand : public BaseClass {
private:
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
public:
WithRawCallbackMethod_ReservedSubmitCommand() {
::grpc::Service::MarkMethodRawCallback(0,
new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
[this](
::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ReservedSubmitCommand(context, request, response); }));
}
~WithRawCallbackMethod_ReservedSubmitCommand() override {
BaseClassMustBeDerivedFromService(this);
}
// disable synchronous version of this method
::grpc::Status ReservedSubmitCommand(::grpc::ServerContext* /*context*/, const ::leechrpc::SubmitCommandRequest* /*request*/, ::leechrpc::SubmitCommandResponse* /*response*/) override {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
virtual ::grpc::ServerUnaryReactor* ReservedSubmitCommand(
::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; }
};
template <class BaseClass>
class WithStreamedUnaryMethod_ReservedSubmitCommand : public BaseClass {
private:
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
public:
WithStreamedUnaryMethod_ReservedSubmitCommand() {
::grpc::Service::MarkMethodStreamed(0,
new ::grpc::internal::StreamedUnaryHandler<
::leechrpc::SubmitCommandRequest, ::leechrpc::SubmitCommandResponse>(
[this](::grpc::ServerContext* context,
::grpc::ServerUnaryStreamer<
::leechrpc::SubmitCommandRequest, ::leechrpc::SubmitCommandResponse>* streamer) {
return this->StreamedReservedSubmitCommand(context,
streamer);
}));
}
~WithStreamedUnaryMethod_ReservedSubmitCommand() override {
BaseClassMustBeDerivedFromService(this);
}
// disable regular version of this method
::grpc::Status ReservedSubmitCommand(::grpc::ServerContext* /*context*/, const ::leechrpc::SubmitCommandRequest* /*request*/, ::leechrpc::SubmitCommandResponse* /*response*/) override {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
// replace default version of method with streamed unary
virtual ::grpc::Status StreamedReservedSubmitCommand(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::leechrpc::SubmitCommandRequest,::leechrpc::SubmitCommandResponse>* server_unary_streamer) = 0;
};
typedef WithStreamedUnaryMethod_ReservedSubmitCommand<Service > StreamedUnaryService;
typedef Service SplitStreamedService;
typedef WithStreamedUnaryMethod_ReservedSubmitCommand<Service > StreamedService;
};
} // namespace leechrpc
#endif // GRPC_leechgrpc_2eproto__INCLUDED

View File

@@ -0,0 +1,609 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: leechgrpc.proto
// Protobuf C++ Version: 5.29.2
#include "leechgrpc.pb.h"
#include <algorithm>
#include <type_traits>
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/generated_message_tctable_impl.h"
#include "google/protobuf/extension_set.h"
#include "google/protobuf/generated_message_util.h"
#include "google/protobuf/wire_format_lite.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/generated_message_reflection.h"
#include "google/protobuf/reflection_ops.h"
#include "google/protobuf/wire_format.h"
// @@protoc_insertion_point(includes)
// Must be included last.
#include "google/protobuf/port_def.inc"
PROTOBUF_PRAGMA_INIT_SEG
namespace _pb = ::google::protobuf;
namespace _pbi = ::google::protobuf::internal;
namespace _fl = ::google::protobuf::internal::field_layout;
namespace leechrpc {
inline constexpr SubmitCommandResponse::Impl_::Impl_(
::_pbi::ConstantInitialized) noexcept
: pbout_(
&::google::protobuf::internal::fixed_address_empty_string,
::_pbi::ConstantInitialized()),
_cached_size_{0} {}
template <typename>
PROTOBUF_CONSTEXPR SubmitCommandResponse::SubmitCommandResponse(::_pbi::ConstantInitialized)
#if defined(PROTOBUF_CUSTOM_VTABLE)
: ::google::protobuf::Message(_class_data_.base()),
#else // PROTOBUF_CUSTOM_VTABLE
: ::google::protobuf::Message(),
#endif // PROTOBUF_CUSTOM_VTABLE
_impl_(::_pbi::ConstantInitialized()) {
}
struct SubmitCommandResponseDefaultTypeInternal {
PROTOBUF_CONSTEXPR SubmitCommandResponseDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
~SubmitCommandResponseDefaultTypeInternal() {}
union {
SubmitCommandResponse _instance;
};
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 SubmitCommandResponseDefaultTypeInternal _SubmitCommandResponse_default_instance_;
inline constexpr SubmitCommandRequest::Impl_::Impl_(
::_pbi::ConstantInitialized) noexcept
: pbin_(
&::google::protobuf::internal::fixed_address_empty_string,
::_pbi::ConstantInitialized()),
_cached_size_{0} {}
template <typename>
PROTOBUF_CONSTEXPR SubmitCommandRequest::SubmitCommandRequest(::_pbi::ConstantInitialized)
#if defined(PROTOBUF_CUSTOM_VTABLE)
: ::google::protobuf::Message(_class_data_.base()),
#else // PROTOBUF_CUSTOM_VTABLE
: ::google::protobuf::Message(),
#endif // PROTOBUF_CUSTOM_VTABLE
_impl_(::_pbi::ConstantInitialized()) {
}
struct SubmitCommandRequestDefaultTypeInternal {
PROTOBUF_CONSTEXPR SubmitCommandRequestDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
~SubmitCommandRequestDefaultTypeInternal() {}
union {
SubmitCommandRequest _instance;
};
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 SubmitCommandRequestDefaultTypeInternal _SubmitCommandRequest_default_instance_;
} // namespace leechrpc
static constexpr const ::_pb::EnumDescriptor**
file_level_enum_descriptors_leechgrpc_2eproto = nullptr;
static constexpr const ::_pb::ServiceDescriptor**
file_level_service_descriptors_leechgrpc_2eproto = nullptr;
const ::uint32_t
TableStruct_leechgrpc_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
protodesc_cold) = {
~0u, // no _has_bits_
PROTOBUF_FIELD_OFFSET(::leechrpc::SubmitCommandRequest, _internal_metadata_),
~0u, // no _extensions_
~0u, // no _oneof_case_
~0u, // no _weak_field_map_
~0u, // no _inlined_string_donated_
~0u, // no _split_
~0u, // no sizeof(Split)
PROTOBUF_FIELD_OFFSET(::leechrpc::SubmitCommandRequest, _impl_.pbin_),
~0u, // no _has_bits_
PROTOBUF_FIELD_OFFSET(::leechrpc::SubmitCommandResponse, _internal_metadata_),
~0u, // no _extensions_
~0u, // no _oneof_case_
~0u, // no _weak_field_map_
~0u, // no _inlined_string_donated_
~0u, // no _split_
~0u, // no sizeof(Split)
PROTOBUF_FIELD_OFFSET(::leechrpc::SubmitCommandResponse, _impl_.pbout_),
};
static const ::_pbi::MigrationSchema
schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
{0, -1, -1, sizeof(::leechrpc::SubmitCommandRequest)},
{9, -1, -1, sizeof(::leechrpc::SubmitCommandResponse)},
};
static const ::_pb::Message* const file_default_instances[] = {
&::leechrpc::_SubmitCommandRequest_default_instance_._instance,
&::leechrpc::_SubmitCommandResponse_default_instance_._instance,
};
const char descriptor_table_protodef_leechgrpc_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
protodesc_cold) = {
"\n\017leechgrpc.proto\022\010leechrpc\"$\n\024SubmitCom"
"mandRequest\022\014\n\004pbIn\030\001 \001(\014\"&\n\025SubmitComma"
"ndResponse\022\r\n\005pbOut\030\001 \001(\0142d\n\010LeechRpc\022X\n"
"\025ReservedSubmitCommand\022\036.leechrpc.Submit"
"CommandRequest\032\037.leechrpc.SubmitCommandR"
"esponseb\006proto3"
};
static ::absl::once_flag descriptor_table_leechgrpc_2eproto_once;
PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_leechgrpc_2eproto = {
false,
false,
215,
descriptor_table_protodef_leechgrpc_2eproto,
"leechgrpc.proto",
&descriptor_table_leechgrpc_2eproto_once,
nullptr,
0,
2,
schemas,
file_default_instances,
TableStruct_leechgrpc_2eproto::offsets,
file_level_enum_descriptors_leechgrpc_2eproto,
file_level_service_descriptors_leechgrpc_2eproto,
};
namespace leechrpc {
// ===================================================================
class SubmitCommandRequest::_Internal {
public:
};
SubmitCommandRequest::SubmitCommandRequest(::google::protobuf::Arena* arena)
#if defined(PROTOBUF_CUSTOM_VTABLE)
: ::google::protobuf::Message(arena, _class_data_.base()) {
#else // PROTOBUF_CUSTOM_VTABLE
: ::google::protobuf::Message(arena) {
#endif // PROTOBUF_CUSTOM_VTABLE
SharedCtor(arena);
// @@protoc_insertion_point(arena_constructor:leechrpc.SubmitCommandRequest)
}
inline PROTOBUF_NDEBUG_INLINE SubmitCommandRequest::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena,
const Impl_& from, const ::leechrpc::SubmitCommandRequest& from_msg)
: pbin_(arena, from.pbin_),
_cached_size_{0} {}
SubmitCommandRequest::SubmitCommandRequest(
::google::protobuf::Arena* arena,
const SubmitCommandRequest& from)
#if defined(PROTOBUF_CUSTOM_VTABLE)
: ::google::protobuf::Message(arena, _class_data_.base()) {
#else // PROTOBUF_CUSTOM_VTABLE
: ::google::protobuf::Message(arena) {
#endif // PROTOBUF_CUSTOM_VTABLE
SubmitCommandRequest* const _this = this;
(void)_this;
_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
from._internal_metadata_);
new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
// @@protoc_insertion_point(copy_constructor:leechrpc.SubmitCommandRequest)
}
inline PROTOBUF_NDEBUG_INLINE SubmitCommandRequest::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility,
::google::protobuf::Arena* arena)
: pbin_(arena),
_cached_size_{0} {}
inline void SubmitCommandRequest::SharedCtor(::_pb::Arena* arena) {
new (&_impl_) Impl_(internal_visibility(), arena);
}
SubmitCommandRequest::~SubmitCommandRequest() {
// @@protoc_insertion_point(destructor:leechrpc.SubmitCommandRequest)
SharedDtor(*this);
}
inline void SubmitCommandRequest::SharedDtor(MessageLite& self) {
SubmitCommandRequest& this_ = static_cast<SubmitCommandRequest&>(self);
this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
ABSL_DCHECK(this_.GetArena() == nullptr);
this_._impl_.pbin_.Destroy();
this_._impl_.~Impl_();
}
inline void* SubmitCommandRequest::PlacementNew_(const void*, void* mem,
::google::protobuf::Arena* arena) {
return ::new (mem) SubmitCommandRequest(arena);
}
constexpr auto SubmitCommandRequest::InternalNewImpl_() {
return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(SubmitCommandRequest),
alignof(SubmitCommandRequest));
}
PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::internal::ClassDataFull SubmitCommandRequest::_class_data_ = {
::google::protobuf::internal::ClassData{
&_SubmitCommandRequest_default_instance_._instance,
&_table_.header,
nullptr, // OnDemandRegisterArenaDtor
nullptr, // IsInitialized
&SubmitCommandRequest::MergeImpl,
::google::protobuf::Message::GetNewImpl<SubmitCommandRequest>(),
#if defined(PROTOBUF_CUSTOM_VTABLE)
&SubmitCommandRequest::SharedDtor,
::google::protobuf::Message::GetClearImpl<SubmitCommandRequest>(), &SubmitCommandRequest::ByteSizeLong,
&SubmitCommandRequest::_InternalSerialize,
#endif // PROTOBUF_CUSTOM_VTABLE
PROTOBUF_FIELD_OFFSET(SubmitCommandRequest, _impl_._cached_size_),
false,
},
&SubmitCommandRequest::kDescriptorMethods,
&descriptor_table_leechgrpc_2eproto,
nullptr, // tracker
};
const ::google::protobuf::internal::ClassData* SubmitCommandRequest::GetClassData() const {
::google::protobuf::internal::PrefetchToLocalCache(&_class_data_);
::google::protobuf::internal::PrefetchToLocalCache(_class_data_.tc_table);
return _class_data_.base();
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<0, 1, 0, 0, 2> SubmitCommandRequest::_table_ = {
{
0, // no _has_bits_
0, // no _extensions_
1, 0, // max_field_number, fast_idx_mask
offsetof(decltype(_table_), field_lookup_table),
4294967294, // skipmap
offsetof(decltype(_table_), field_entries),
1, // num_field_entries
0, // num_aux_entries
offsetof(decltype(_table_), field_names), // no aux_entries
_class_data_.base(),
nullptr, // post_loop_handler
::_pbi::TcParser::GenericFallback, // fallback
#ifdef PROTOBUF_PREFETCH_PARSE_TABLE
::_pbi::TcParser::GetTable<::leechrpc::SubmitCommandRequest>(), // to_prefetch
#endif // PROTOBUF_PREFETCH_PARSE_TABLE
}, {{
// bytes pbIn = 1;
{::_pbi::TcParser::FastBS1,
{10, 63, 0, PROTOBUF_FIELD_OFFSET(SubmitCommandRequest, _impl_.pbin_)}},
}}, {{
65535, 65535
}}, {{
// bytes pbIn = 1;
{PROTOBUF_FIELD_OFFSET(SubmitCommandRequest, _impl_.pbin_), 0, 0,
(0 | ::_fl::kFcSingular | ::_fl::kBytes | ::_fl::kRepAString)},
}},
// no aux_entries
{{
}},
};
PROTOBUF_NOINLINE void SubmitCommandRequest::Clear() {
// @@protoc_insertion_point(message_clear_start:leechrpc.SubmitCommandRequest)
::google::protobuf::internal::TSanWrite(&_impl_);
::uint32_t cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
_impl_.pbin_.ClearToEmpty();
_internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}
#if defined(PROTOBUF_CUSTOM_VTABLE)
::uint8_t* SubmitCommandRequest::_InternalSerialize(
const MessageLite& base, ::uint8_t* target,
::google::protobuf::io::EpsCopyOutputStream* stream) {
const SubmitCommandRequest& this_ = static_cast<const SubmitCommandRequest&>(base);
#else // PROTOBUF_CUSTOM_VTABLE
::uint8_t* SubmitCommandRequest::_InternalSerialize(
::uint8_t* target,
::google::protobuf::io::EpsCopyOutputStream* stream) const {
const SubmitCommandRequest& this_ = *this;
#endif // PROTOBUF_CUSTOM_VTABLE
// @@protoc_insertion_point(serialize_to_array_start:leechrpc.SubmitCommandRequest)
::uint32_t cached_has_bits = 0;
(void)cached_has_bits;
// bytes pbIn = 1;
if (!this_._internal_pbin().empty()) {
const std::string& _s = this_._internal_pbin();
target = stream->WriteBytesMaybeAliased(1, _s, target);
}
if (PROTOBUF_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) {
target =
::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
this_._internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
}
// @@protoc_insertion_point(serialize_to_array_end:leechrpc.SubmitCommandRequest)
return target;
}
#if defined(PROTOBUF_CUSTOM_VTABLE)
::size_t SubmitCommandRequest::ByteSizeLong(const MessageLite& base) {
const SubmitCommandRequest& this_ = static_cast<const SubmitCommandRequest&>(base);
#else // PROTOBUF_CUSTOM_VTABLE
::size_t SubmitCommandRequest::ByteSizeLong() const {
const SubmitCommandRequest& this_ = *this;
#endif // PROTOBUF_CUSTOM_VTABLE
// @@protoc_insertion_point(message_byte_size_start:leechrpc.SubmitCommandRequest)
::size_t total_size = 0;
::uint32_t cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void)cached_has_bits;
{
// bytes pbIn = 1;
if (!this_._internal_pbin().empty()) {
total_size += 1 + ::google::protobuf::internal::WireFormatLite::BytesSize(
this_._internal_pbin());
}
}
return this_.MaybeComputeUnknownFieldsSize(total_size,
&this_._impl_._cached_size_);
}
void SubmitCommandRequest::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) {
auto* const _this = static_cast<SubmitCommandRequest*>(&to_msg);
auto& from = static_cast<const SubmitCommandRequest&>(from_msg);
// @@protoc_insertion_point(class_specific_merge_from_start:leechrpc.SubmitCommandRequest)
ABSL_DCHECK_NE(&from, _this);
::uint32_t cached_has_bits = 0;
(void) cached_has_bits;
if (!from._internal_pbin().empty()) {
_this->_internal_set_pbin(from._internal_pbin());
}
_this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);
}
void SubmitCommandRequest::CopyFrom(const SubmitCommandRequest& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:leechrpc.SubmitCommandRequest)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void SubmitCommandRequest::InternalSwap(SubmitCommandRequest* PROTOBUF_RESTRICT other) {
using std::swap;
auto* arena = GetArena();
ABSL_DCHECK_EQ(arena, other->GetArena());
_internal_metadata_.InternalSwap(&other->_internal_metadata_);
::_pbi::ArenaStringPtr::InternalSwap(&_impl_.pbin_, &other->_impl_.pbin_, arena);
}
::google::protobuf::Metadata SubmitCommandRequest::GetMetadata() const {
return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full());
}
// ===================================================================
class SubmitCommandResponse::_Internal {
public:
};
SubmitCommandResponse::SubmitCommandResponse(::google::protobuf::Arena* arena)
#if defined(PROTOBUF_CUSTOM_VTABLE)
: ::google::protobuf::Message(arena, _class_data_.base()) {
#else // PROTOBUF_CUSTOM_VTABLE
: ::google::protobuf::Message(arena) {
#endif // PROTOBUF_CUSTOM_VTABLE
SharedCtor(arena);
// @@protoc_insertion_point(arena_constructor:leechrpc.SubmitCommandResponse)
}
inline PROTOBUF_NDEBUG_INLINE SubmitCommandResponse::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena,
const Impl_& from, const ::leechrpc::SubmitCommandResponse& from_msg)
: pbout_(arena, from.pbout_),
_cached_size_{0} {}
SubmitCommandResponse::SubmitCommandResponse(
::google::protobuf::Arena* arena,
const SubmitCommandResponse& from)
#if defined(PROTOBUF_CUSTOM_VTABLE)
: ::google::protobuf::Message(arena, _class_data_.base()) {
#else // PROTOBUF_CUSTOM_VTABLE
: ::google::protobuf::Message(arena) {
#endif // PROTOBUF_CUSTOM_VTABLE
SubmitCommandResponse* const _this = this;
(void)_this;
_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
from._internal_metadata_);
new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
// @@protoc_insertion_point(copy_constructor:leechrpc.SubmitCommandResponse)
}
inline PROTOBUF_NDEBUG_INLINE SubmitCommandResponse::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility,
::google::protobuf::Arena* arena)
: pbout_(arena),
_cached_size_{0} {}
inline void SubmitCommandResponse::SharedCtor(::_pb::Arena* arena) {
new (&_impl_) Impl_(internal_visibility(), arena);
}
SubmitCommandResponse::~SubmitCommandResponse() {
// @@protoc_insertion_point(destructor:leechrpc.SubmitCommandResponse)
SharedDtor(*this);
}
inline void SubmitCommandResponse::SharedDtor(MessageLite& self) {
SubmitCommandResponse& this_ = static_cast<SubmitCommandResponse&>(self);
this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
ABSL_DCHECK(this_.GetArena() == nullptr);
this_._impl_.pbout_.Destroy();
this_._impl_.~Impl_();
}
inline void* SubmitCommandResponse::PlacementNew_(const void*, void* mem,
::google::protobuf::Arena* arena) {
return ::new (mem) SubmitCommandResponse(arena);
}
constexpr auto SubmitCommandResponse::InternalNewImpl_() {
return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(SubmitCommandResponse),
alignof(SubmitCommandResponse));
}
PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::internal::ClassDataFull SubmitCommandResponse::_class_data_ = {
::google::protobuf::internal::ClassData{
&_SubmitCommandResponse_default_instance_._instance,
&_table_.header,
nullptr, // OnDemandRegisterArenaDtor
nullptr, // IsInitialized
&SubmitCommandResponse::MergeImpl,
::google::protobuf::Message::GetNewImpl<SubmitCommandResponse>(),
#if defined(PROTOBUF_CUSTOM_VTABLE)
&SubmitCommandResponse::SharedDtor,
::google::protobuf::Message::GetClearImpl<SubmitCommandResponse>(), &SubmitCommandResponse::ByteSizeLong,
&SubmitCommandResponse::_InternalSerialize,
#endif // PROTOBUF_CUSTOM_VTABLE
PROTOBUF_FIELD_OFFSET(SubmitCommandResponse, _impl_._cached_size_),
false,
},
&SubmitCommandResponse::kDescriptorMethods,
&descriptor_table_leechgrpc_2eproto,
nullptr, // tracker
};
const ::google::protobuf::internal::ClassData* SubmitCommandResponse::GetClassData() const {
::google::protobuf::internal::PrefetchToLocalCache(&_class_data_);
::google::protobuf::internal::PrefetchToLocalCache(_class_data_.tc_table);
return _class_data_.base();
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<0, 1, 0, 0, 2> SubmitCommandResponse::_table_ = {
{
0, // no _has_bits_
0, // no _extensions_
1, 0, // max_field_number, fast_idx_mask
offsetof(decltype(_table_), field_lookup_table),
4294967294, // skipmap
offsetof(decltype(_table_), field_entries),
1, // num_field_entries
0, // num_aux_entries
offsetof(decltype(_table_), field_names), // no aux_entries
_class_data_.base(),
nullptr, // post_loop_handler
::_pbi::TcParser::GenericFallback, // fallback
#ifdef PROTOBUF_PREFETCH_PARSE_TABLE
::_pbi::TcParser::GetTable<::leechrpc::SubmitCommandResponse>(), // to_prefetch
#endif // PROTOBUF_PREFETCH_PARSE_TABLE
}, {{
// bytes pbOut = 1;
{::_pbi::TcParser::FastBS1,
{10, 63, 0, PROTOBUF_FIELD_OFFSET(SubmitCommandResponse, _impl_.pbout_)}},
}}, {{
65535, 65535
}}, {{
// bytes pbOut = 1;
{PROTOBUF_FIELD_OFFSET(SubmitCommandResponse, _impl_.pbout_), 0, 0,
(0 | ::_fl::kFcSingular | ::_fl::kBytes | ::_fl::kRepAString)},
}},
// no aux_entries
{{
}},
};
PROTOBUF_NOINLINE void SubmitCommandResponse::Clear() {
// @@protoc_insertion_point(message_clear_start:leechrpc.SubmitCommandResponse)
::google::protobuf::internal::TSanWrite(&_impl_);
::uint32_t cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
_impl_.pbout_.ClearToEmpty();
_internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}
#if defined(PROTOBUF_CUSTOM_VTABLE)
::uint8_t* SubmitCommandResponse::_InternalSerialize(
const MessageLite& base, ::uint8_t* target,
::google::protobuf::io::EpsCopyOutputStream* stream) {
const SubmitCommandResponse& this_ = static_cast<const SubmitCommandResponse&>(base);
#else // PROTOBUF_CUSTOM_VTABLE
::uint8_t* SubmitCommandResponse::_InternalSerialize(
::uint8_t* target,
::google::protobuf::io::EpsCopyOutputStream* stream) const {
const SubmitCommandResponse& this_ = *this;
#endif // PROTOBUF_CUSTOM_VTABLE
// @@protoc_insertion_point(serialize_to_array_start:leechrpc.SubmitCommandResponse)
::uint32_t cached_has_bits = 0;
(void)cached_has_bits;
// bytes pbOut = 1;
if (!this_._internal_pbout().empty()) {
const std::string& _s = this_._internal_pbout();
target = stream->WriteBytesMaybeAliased(1, _s, target);
}
if (PROTOBUF_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) {
target =
::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
this_._internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
}
// @@protoc_insertion_point(serialize_to_array_end:leechrpc.SubmitCommandResponse)
return target;
}
#if defined(PROTOBUF_CUSTOM_VTABLE)
::size_t SubmitCommandResponse::ByteSizeLong(const MessageLite& base) {
const SubmitCommandResponse& this_ = static_cast<const SubmitCommandResponse&>(base);
#else // PROTOBUF_CUSTOM_VTABLE
::size_t SubmitCommandResponse::ByteSizeLong() const {
const SubmitCommandResponse& this_ = *this;
#endif // PROTOBUF_CUSTOM_VTABLE
// @@protoc_insertion_point(message_byte_size_start:leechrpc.SubmitCommandResponse)
::size_t total_size = 0;
::uint32_t cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void)cached_has_bits;
{
// bytes pbOut = 1;
if (!this_._internal_pbout().empty()) {
total_size += 1 + ::google::protobuf::internal::WireFormatLite::BytesSize(
this_._internal_pbout());
}
}
return this_.MaybeComputeUnknownFieldsSize(total_size,
&this_._impl_._cached_size_);
}
void SubmitCommandResponse::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) {
auto* const _this = static_cast<SubmitCommandResponse*>(&to_msg);
auto& from = static_cast<const SubmitCommandResponse&>(from_msg);
// @@protoc_insertion_point(class_specific_merge_from_start:leechrpc.SubmitCommandResponse)
ABSL_DCHECK_NE(&from, _this);
::uint32_t cached_has_bits = 0;
(void) cached_has_bits;
if (!from._internal_pbout().empty()) {
_this->_internal_set_pbout(from._internal_pbout());
}
_this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);
}
void SubmitCommandResponse::CopyFrom(const SubmitCommandResponse& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:leechrpc.SubmitCommandResponse)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void SubmitCommandResponse::InternalSwap(SubmitCommandResponse* PROTOBUF_RESTRICT other) {
using std::swap;
auto* arena = GetArena();
ABSL_DCHECK_EQ(arena, other->GetArena());
_internal_metadata_.InternalSwap(&other->_internal_metadata_);
::_pbi::ArenaStringPtr::InternalSwap(&_impl_.pbout_, &other->_impl_.pbout_, arena);
}
::google::protobuf::Metadata SubmitCommandResponse::GetMetadata() const {
return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full());
}
// @@protoc_insertion_point(namespace_scope)
} // namespace leechrpc
namespace google {
namespace protobuf {
} // namespace protobuf
} // namespace google
// @@protoc_insertion_point(global_scope)
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::std::false_type
_static_init2_ PROTOBUF_UNUSED =
(::_pbi::AddDescriptors(&descriptor_table_leechgrpc_2eproto),
::std::false_type{});
#include "google/protobuf/port_undef.inc"

View File

@@ -0,0 +1,593 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: leechgrpc.proto
// Protobuf C++ Version: 5.29.2
#ifndef leechgrpc_2eproto_2epb_2eh
#define leechgrpc_2eproto_2epb_2eh
#include <limits>
#include <string>
#include <type_traits>
#include <utility>
#include "google/protobuf/runtime_version.h"
#if PROTOBUF_VERSION != 5029002
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
#endif
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/arena.h"
#include "google/protobuf/arenastring.h"
#include "google/protobuf/generated_message_tctable_decl.h"
#include "google/protobuf/generated_message_util.h"
#include "google/protobuf/metadata_lite.h"
#include "google/protobuf/generated_message_reflection.h"
#include "google/protobuf/message.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/repeated_field.h" // IWYU pragma: export
#include "google/protobuf/extension_set.h" // IWYU pragma: export
#include "google/protobuf/unknown_field_set.h"
// @@protoc_insertion_point(includes)
// Must be included last.
#include "google/protobuf/port_def.inc"
#define PROTOBUF_INTERNAL_EXPORT_leechgrpc_2eproto
namespace google {
namespace protobuf {
namespace internal {
template <typename T>
::absl::string_view GetAnyMessageName();
} // namespace internal
} // namespace protobuf
} // namespace google
// Internal implementation detail -- do not use these members.
struct TableStruct_leechgrpc_2eproto {
static const ::uint32_t offsets[];
};
extern const ::google::protobuf::internal::DescriptorTable
descriptor_table_leechgrpc_2eproto;
namespace leechrpc {
class SubmitCommandRequest;
struct SubmitCommandRequestDefaultTypeInternal;
extern SubmitCommandRequestDefaultTypeInternal _SubmitCommandRequest_default_instance_;
class SubmitCommandResponse;
struct SubmitCommandResponseDefaultTypeInternal;
extern SubmitCommandResponseDefaultTypeInternal _SubmitCommandResponse_default_instance_;
} // namespace leechrpc
namespace google {
namespace protobuf {
} // namespace protobuf
} // namespace google
namespace leechrpc {
// ===================================================================
// -------------------------------------------------------------------
class SubmitCommandResponse final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:leechrpc.SubmitCommandResponse) */ {
public:
inline SubmitCommandResponse() : SubmitCommandResponse(nullptr) {}
~SubmitCommandResponse() PROTOBUF_FINAL;
#if defined(PROTOBUF_CUSTOM_VTABLE)
void operator delete(SubmitCommandResponse* msg, std::destroying_delete_t) {
SharedDtor(*msg);
::google::protobuf::internal::SizedDelete(msg, sizeof(SubmitCommandResponse));
}
#endif
template <typename = void>
explicit PROTOBUF_CONSTEXPR SubmitCommandResponse(
::google::protobuf::internal::ConstantInitialized);
inline SubmitCommandResponse(const SubmitCommandResponse& from) : SubmitCommandResponse(nullptr, from) {}
inline SubmitCommandResponse(SubmitCommandResponse&& from) noexcept
: SubmitCommandResponse(nullptr, std::move(from)) {}
inline SubmitCommandResponse& operator=(const SubmitCommandResponse& from) {
CopyFrom(from);
return *this;
}
inline SubmitCommandResponse& operator=(SubmitCommandResponse&& from) noexcept {
if (this == &from) return *this;
if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const
ABSL_ATTRIBUTE_LIFETIME_BOUND {
return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance);
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields()
ABSL_ATTRIBUTE_LIFETIME_BOUND {
return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
}
static const ::google::protobuf::Descriptor* descriptor() {
return GetDescriptor();
}
static const ::google::protobuf::Descriptor* GetDescriptor() {
return default_instance().GetMetadata().descriptor;
}
static const ::google::protobuf::Reflection* GetReflection() {
return default_instance().GetMetadata().reflection;
}
static const SubmitCommandResponse& default_instance() {
return *internal_default_instance();
}
static inline const SubmitCommandResponse* internal_default_instance() {
return reinterpret_cast<const SubmitCommandResponse*>(
&_SubmitCommandResponse_default_instance_);
}
static constexpr int kIndexInFileMessages = 1;
friend void swap(SubmitCommandResponse& a, SubmitCommandResponse& b) { a.Swap(&b); }
inline void Swap(SubmitCommandResponse* other) {
if (other == this) return;
if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
InternalSwap(other);
} else {
::google::protobuf::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(SubmitCommandResponse* other) {
if (other == this) return;
ABSL_DCHECK(GetArena() == other->GetArena());
InternalSwap(other);
}
// implements Message ----------------------------------------------
SubmitCommandResponse* New(::google::protobuf::Arena* arena = nullptr) const {
return ::google::protobuf::Message::DefaultConstruct<SubmitCommandResponse>(arena);
}
using ::google::protobuf::Message::CopyFrom;
void CopyFrom(const SubmitCommandResponse& from);
using ::google::protobuf::Message::MergeFrom;
void MergeFrom(const SubmitCommandResponse& from) { SubmitCommandResponse::MergeImpl(*this, from); }
private:
static void MergeImpl(
::google::protobuf::MessageLite& to_msg,
const ::google::protobuf::MessageLite& from_msg);
public:
bool IsInitialized() const {
return true;
}
ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
#if defined(PROTOBUF_CUSTOM_VTABLE)
private:
static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
static ::uint8_t* _InternalSerialize(
const MessageLite& msg, ::uint8_t* target,
::google::protobuf::io::EpsCopyOutputStream* stream);
public:
::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
::uint8_t* _InternalSerialize(
::uint8_t* target,
::google::protobuf::io::EpsCopyOutputStream* stream) const {
return _InternalSerialize(*this, target, stream);
}
#else // PROTOBUF_CUSTOM_VTABLE
::size_t ByteSizeLong() const final;
::uint8_t* _InternalSerialize(
::uint8_t* target,
::google::protobuf::io::EpsCopyOutputStream* stream) const final;
#endif // PROTOBUF_CUSTOM_VTABLE
int GetCachedSize() const { return _impl_._cached_size_.Get(); }
private:
void SharedCtor(::google::protobuf::Arena* arena);
static void SharedDtor(MessageLite& self);
void InternalSwap(SubmitCommandResponse* other);
private:
template <typename T>
friend ::absl::string_view(
::google::protobuf::internal::GetAnyMessageName)();
static ::absl::string_view FullMessageName() { return "leechrpc.SubmitCommandResponse"; }
protected:
explicit SubmitCommandResponse(::google::protobuf::Arena* arena);
SubmitCommandResponse(::google::protobuf::Arena* arena, const SubmitCommandResponse& from);
SubmitCommandResponse(::google::protobuf::Arena* arena, SubmitCommandResponse&& from) noexcept
: SubmitCommandResponse(arena) {
*this = ::std::move(from);
}
const ::google::protobuf::internal::ClassData* GetClassData() const PROTOBUF_FINAL;
static void* PlacementNew_(const void*, void* mem,
::google::protobuf::Arena* arena);
static constexpr auto InternalNewImpl_();
static const ::google::protobuf::internal::ClassDataFull _class_data_;
public:
::google::protobuf::Metadata GetMetadata() const;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
enum : int {
kPbOutFieldNumber = 1,
};
// bytes pbOut = 1;
void clear_pbout() ;
const std::string& pbout() const;
template <typename Arg_ = const std::string&, typename... Args_>
void set_pbout(Arg_&& arg, Args_... args);
std::string* mutable_pbout();
PROTOBUF_NODISCARD std::string* release_pbout();
void set_allocated_pbout(std::string* value);
private:
const std::string& _internal_pbout() const;
inline PROTOBUF_ALWAYS_INLINE void _internal_set_pbout(
const std::string& value);
std::string* _internal_mutable_pbout();
public:
// @@protoc_insertion_point(class_scope:leechrpc.SubmitCommandResponse)
private:
class _Internal;
friend class ::google::protobuf::internal::TcParser;
static const ::google::protobuf::internal::TcParseTable<
0, 1, 0,
0, 2>
_table_;
friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena;
template <typename T>
friend class ::google::protobuf::Arena::InternalHelper;
using InternalArenaConstructable_ = void;
using DestructorSkippable_ = void;
struct Impl_ {
inline explicit constexpr Impl_(
::google::protobuf::internal::ConstantInitialized) noexcept;
inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
::google::protobuf::Arena* arena);
inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
::google::protobuf::Arena* arena, const Impl_& from,
const SubmitCommandResponse& from_msg);
::google::protobuf::internal::ArenaStringPtr pbout_;
::google::protobuf::internal::CachedSize _cached_size_;
PROTOBUF_TSAN_DECLARE_MEMBER
};
union { Impl_ _impl_; };
friend struct ::TableStruct_leechgrpc_2eproto;
};
// -------------------------------------------------------------------
class SubmitCommandRequest final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:leechrpc.SubmitCommandRequest) */ {
public:
inline SubmitCommandRequest() : SubmitCommandRequest(nullptr) {}
~SubmitCommandRequest() PROTOBUF_FINAL;
#if defined(PROTOBUF_CUSTOM_VTABLE)
void operator delete(SubmitCommandRequest* msg, std::destroying_delete_t) {
SharedDtor(*msg);
::google::protobuf::internal::SizedDelete(msg, sizeof(SubmitCommandRequest));
}
#endif
template <typename = void>
explicit PROTOBUF_CONSTEXPR SubmitCommandRequest(
::google::protobuf::internal::ConstantInitialized);
inline SubmitCommandRequest(const SubmitCommandRequest& from) : SubmitCommandRequest(nullptr, from) {}
inline SubmitCommandRequest(SubmitCommandRequest&& from) noexcept
: SubmitCommandRequest(nullptr, std::move(from)) {}
inline SubmitCommandRequest& operator=(const SubmitCommandRequest& from) {
CopyFrom(from);
return *this;
}
inline SubmitCommandRequest& operator=(SubmitCommandRequest&& from) noexcept {
if (this == &from) return *this;
if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const
ABSL_ATTRIBUTE_LIFETIME_BOUND {
return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance);
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields()
ABSL_ATTRIBUTE_LIFETIME_BOUND {
return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
}
static const ::google::protobuf::Descriptor* descriptor() {
return GetDescriptor();
}
static const ::google::protobuf::Descriptor* GetDescriptor() {
return default_instance().GetMetadata().descriptor;
}
static const ::google::protobuf::Reflection* GetReflection() {
return default_instance().GetMetadata().reflection;
}
static const SubmitCommandRequest& default_instance() {
return *internal_default_instance();
}
static inline const SubmitCommandRequest* internal_default_instance() {
return reinterpret_cast<const SubmitCommandRequest*>(
&_SubmitCommandRequest_default_instance_);
}
static constexpr int kIndexInFileMessages = 0;
friend void swap(SubmitCommandRequest& a, SubmitCommandRequest& b) { a.Swap(&b); }
inline void Swap(SubmitCommandRequest* other) {
if (other == this) return;
if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
InternalSwap(other);
} else {
::google::protobuf::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(SubmitCommandRequest* other) {
if (other == this) return;
ABSL_DCHECK(GetArena() == other->GetArena());
InternalSwap(other);
}
// implements Message ----------------------------------------------
SubmitCommandRequest* New(::google::protobuf::Arena* arena = nullptr) const {
return ::google::protobuf::Message::DefaultConstruct<SubmitCommandRequest>(arena);
}
using ::google::protobuf::Message::CopyFrom;
void CopyFrom(const SubmitCommandRequest& from);
using ::google::protobuf::Message::MergeFrom;
void MergeFrom(const SubmitCommandRequest& from) { SubmitCommandRequest::MergeImpl(*this, from); }
private:
static void MergeImpl(
::google::protobuf::MessageLite& to_msg,
const ::google::protobuf::MessageLite& from_msg);
public:
bool IsInitialized() const {
return true;
}
ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
#if defined(PROTOBUF_CUSTOM_VTABLE)
private:
static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
static ::uint8_t* _InternalSerialize(
const MessageLite& msg, ::uint8_t* target,
::google::protobuf::io::EpsCopyOutputStream* stream);
public:
::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
::uint8_t* _InternalSerialize(
::uint8_t* target,
::google::protobuf::io::EpsCopyOutputStream* stream) const {
return _InternalSerialize(*this, target, stream);
}
#else // PROTOBUF_CUSTOM_VTABLE
::size_t ByteSizeLong() const final;
::uint8_t* _InternalSerialize(
::uint8_t* target,
::google::protobuf::io::EpsCopyOutputStream* stream) const final;
#endif // PROTOBUF_CUSTOM_VTABLE
int GetCachedSize() const { return _impl_._cached_size_.Get(); }
private:
void SharedCtor(::google::protobuf::Arena* arena);
static void SharedDtor(MessageLite& self);
void InternalSwap(SubmitCommandRequest* other);
private:
template <typename T>
friend ::absl::string_view(
::google::protobuf::internal::GetAnyMessageName)();
static ::absl::string_view FullMessageName() { return "leechrpc.SubmitCommandRequest"; }
protected:
explicit SubmitCommandRequest(::google::protobuf::Arena* arena);
SubmitCommandRequest(::google::protobuf::Arena* arena, const SubmitCommandRequest& from);
SubmitCommandRequest(::google::protobuf::Arena* arena, SubmitCommandRequest&& from) noexcept
: SubmitCommandRequest(arena) {
*this = ::std::move(from);
}
const ::google::protobuf::internal::ClassData* GetClassData() const PROTOBUF_FINAL;
static void* PlacementNew_(const void*, void* mem,
::google::protobuf::Arena* arena);
static constexpr auto InternalNewImpl_();
static const ::google::protobuf::internal::ClassDataFull _class_data_;
public:
::google::protobuf::Metadata GetMetadata() const;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
enum : int {
kPbInFieldNumber = 1,
};
// bytes pbIn = 1;
void clear_pbin() ;
const std::string& pbin() const;
template <typename Arg_ = const std::string&, typename... Args_>
void set_pbin(Arg_&& arg, Args_... args);
std::string* mutable_pbin();
PROTOBUF_NODISCARD std::string* release_pbin();
void set_allocated_pbin(std::string* value);
private:
const std::string& _internal_pbin() const;
inline PROTOBUF_ALWAYS_INLINE void _internal_set_pbin(
const std::string& value);
std::string* _internal_mutable_pbin();
public:
// @@protoc_insertion_point(class_scope:leechrpc.SubmitCommandRequest)
private:
class _Internal;
friend class ::google::protobuf::internal::TcParser;
static const ::google::protobuf::internal::TcParseTable<
0, 1, 0,
0, 2>
_table_;
friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena;
template <typename T>
friend class ::google::protobuf::Arena::InternalHelper;
using InternalArenaConstructable_ = void;
using DestructorSkippable_ = void;
struct Impl_ {
inline explicit constexpr Impl_(
::google::protobuf::internal::ConstantInitialized) noexcept;
inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
::google::protobuf::Arena* arena);
inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
::google::protobuf::Arena* arena, const Impl_& from,
const SubmitCommandRequest& from_msg);
::google::protobuf::internal::ArenaStringPtr pbin_;
::google::protobuf::internal::CachedSize _cached_size_;
PROTOBUF_TSAN_DECLARE_MEMBER
};
union { Impl_ _impl_; };
friend struct ::TableStruct_leechgrpc_2eproto;
};
// ===================================================================
// ===================================================================
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif // __GNUC__
// -------------------------------------------------------------------
// SubmitCommandRequest
// bytes pbIn = 1;
inline void SubmitCommandRequest::clear_pbin() {
::google::protobuf::internal::TSanWrite(&_impl_);
_impl_.pbin_.ClearToEmpty();
}
inline const std::string& SubmitCommandRequest::pbin() const
ABSL_ATTRIBUTE_LIFETIME_BOUND {
// @@protoc_insertion_point(field_get:leechrpc.SubmitCommandRequest.pbIn)
return _internal_pbin();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void SubmitCommandRequest::set_pbin(Arg_&& arg,
Args_... args) {
::google::protobuf::internal::TSanWrite(&_impl_);
_impl_.pbin_.SetBytes(static_cast<Arg_&&>(arg), args..., GetArena());
// @@protoc_insertion_point(field_set:leechrpc.SubmitCommandRequest.pbIn)
}
inline std::string* SubmitCommandRequest::mutable_pbin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
std::string* _s = _internal_mutable_pbin();
// @@protoc_insertion_point(field_mutable:leechrpc.SubmitCommandRequest.pbIn)
return _s;
}
inline const std::string& SubmitCommandRequest::_internal_pbin() const {
::google::protobuf::internal::TSanRead(&_impl_);
return _impl_.pbin_.Get();
}
inline void SubmitCommandRequest::_internal_set_pbin(const std::string& value) {
::google::protobuf::internal::TSanWrite(&_impl_);
_impl_.pbin_.Set(value, GetArena());
}
inline std::string* SubmitCommandRequest::_internal_mutable_pbin() {
::google::protobuf::internal::TSanWrite(&_impl_);
return _impl_.pbin_.Mutable( GetArena());
}
inline std::string* SubmitCommandRequest::release_pbin() {
::google::protobuf::internal::TSanWrite(&_impl_);
// @@protoc_insertion_point(field_release:leechrpc.SubmitCommandRequest.pbIn)
return _impl_.pbin_.Release();
}
inline void SubmitCommandRequest::set_allocated_pbin(std::string* value) {
::google::protobuf::internal::TSanWrite(&_impl_);
_impl_.pbin_.SetAllocated(value, GetArena());
if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.pbin_.IsDefault()) {
_impl_.pbin_.Set("", GetArena());
}
// @@protoc_insertion_point(field_set_allocated:leechrpc.SubmitCommandRequest.pbIn)
}
// -------------------------------------------------------------------
// SubmitCommandResponse
// bytes pbOut = 1;
inline void SubmitCommandResponse::clear_pbout() {
::google::protobuf::internal::TSanWrite(&_impl_);
_impl_.pbout_.ClearToEmpty();
}
inline const std::string& SubmitCommandResponse::pbout() const
ABSL_ATTRIBUTE_LIFETIME_BOUND {
// @@protoc_insertion_point(field_get:leechrpc.SubmitCommandResponse.pbOut)
return _internal_pbout();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void SubmitCommandResponse::set_pbout(Arg_&& arg,
Args_... args) {
::google::protobuf::internal::TSanWrite(&_impl_);
_impl_.pbout_.SetBytes(static_cast<Arg_&&>(arg), args..., GetArena());
// @@protoc_insertion_point(field_set:leechrpc.SubmitCommandResponse.pbOut)
}
inline std::string* SubmitCommandResponse::mutable_pbout() ABSL_ATTRIBUTE_LIFETIME_BOUND {
std::string* _s = _internal_mutable_pbout();
// @@protoc_insertion_point(field_mutable:leechrpc.SubmitCommandResponse.pbOut)
return _s;
}
inline const std::string& SubmitCommandResponse::_internal_pbout() const {
::google::protobuf::internal::TSanRead(&_impl_);
return _impl_.pbout_.Get();
}
inline void SubmitCommandResponse::_internal_set_pbout(const std::string& value) {
::google::protobuf::internal::TSanWrite(&_impl_);
_impl_.pbout_.Set(value, GetArena());
}
inline std::string* SubmitCommandResponse::_internal_mutable_pbout() {
::google::protobuf::internal::TSanWrite(&_impl_);
return _impl_.pbout_.Mutable( GetArena());
}
inline std::string* SubmitCommandResponse::release_pbout() {
::google::protobuf::internal::TSanWrite(&_impl_);
// @@protoc_insertion_point(field_release:leechrpc.SubmitCommandResponse.pbOut)
return _impl_.pbout_.Release();
}
inline void SubmitCommandResponse::set_allocated_pbout(std::string* value) {
::google::protobuf::internal::TSanWrite(&_impl_);
_impl_.pbout_.SetAllocated(value, GetArena());
if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.pbout_.IsDefault()) {
_impl_.pbout_.Set("", GetArena());
}
// @@protoc_insertion_point(field_set_allocated:leechrpc.SubmitCommandResponse.pbOut)
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif // __GNUC__
// @@protoc_insertion_point(namespace_scope)
} // namespace leechrpc
// @@protoc_insertion_point(global_scope)
#include "google/protobuf/port_undef.inc"
#endif // leechgrpc_2eproto_2epb_2eh

354
libleechgrpc/leechgrpc.h Normal file
View File

@@ -0,0 +1,354 @@
// leechgrpc.h : external header of the libleechgrpc library.
//
// libleechgrpc is a library used by LeechCore to communicate with a LeechAgent
// gRPC server. The library provides functions to create a gRPC client and
// server, submit commands to the server, and handle incoming commands.
//
// libleechgrpc offers a platform-independent way to communicate with remote
// LeechAgent instances, using gRPC as the underlying communication protocol.
// The library supports both insecure and secure connections, with secure
// connections using mTLS.
//
// For more information visit the project page at:
// https://github.com/ufrisk/libleechgrpc
//
// (c) Ulf Frisk, 2025
// Author: Ulf Frisk, pcileech@frizk.net
//
#ifndef __LEECHGRPC_H__
#define __LEECHGRPC_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define LEECHGRPC_MESSAGE_SIZE_MAX (64*1024*1024)
#define LEECHGRPC_CLIENT_TIMEOUT_MS (5000)
#ifdef _WIN32
#include <Windows.h>
#define LEECHGRPC_EXPORTED_FUNCTION __declspec(dllexport)
#endif /* _WIN32 */
#if defined(LINUX) || defined(MACOS)
#include <inttypes.h>
#include <stdlib.h>
#define LEECHGRPC_EXPORTED_FUNCTION __attribute__((visibility("default")))
typedef void VOID, *PVOID, *HANDLE;
typedef size_t SIZE_T;
typedef uint32_t DWORD, BOOL;
typedef uint8_t BYTE, *PBYTE;
typedef char CHAR, *LPSTR;
typedef const char *LPCSTR;
#define _Success_(x)
#define _In_
#define _Out_
#define _In_opt_
#endif /* LINUX || MACOS */
typedef void *LEECHGRPC_CLIENT_HANDLE, *LEECHGRPC_SERVER_HANDLE;
//-----------------------------------------------------------------------------
// LeechgRPC Client API:
//-----------------------------------------------------------------------------
/*
* Submit a command to the gRPC server.
* -- hGRPC: Handle to the gRPC client.
* -- pbIn: Pointer to the input buffer.
* -- cbIn: Size of the input buffer.
* -- ppbOut: Pointer to receive the output buffer. The caller is responsible for freeing this buffer with LocalFree/free.
* -- pcbOut: Pointer to receive the size of the output buffer.
* -- return: TRUE if the command was successfully submitted; otherwise, FALSE.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return)
BOOL leechgrpc_client_submit_command(
_In_ LEECHGRPC_CLIENT_HANDLE hGRPC,
_In_ PBYTE pbIn,
_In_ SIZE_T cbIn,
_Out_ PBYTE *ppbOut,
_Out_ SIZE_T *pcbOut
);
typedef BOOL(*pfn_leechgrpc_client_submit_command)(
_In_ LEECHGRPC_CLIENT_HANDLE hGRPC,
_In_ PBYTE pbIn,
_In_ SIZE_T cbIn,
_Out_ PBYTE *ppbOut,
_Out_ SIZE_T *pcbOut
);
/*
* Free the gRPC client connection.
* -- hGRPC: Handle to the gRPC client.
*/
LEECHGRPC_EXPORTED_FUNCTION
VOID leechgrpc_client_free(
_In_ LEECHGRPC_CLIENT_HANDLE hGRPC
);
typedef VOID(*pfn_leechgrpc_client_free)(
_In_ LEECHGRPC_CLIENT_HANDLE hGRPC
);
/*
* Create an insecure unauthenticated unencrypted gRPC client connection to the gRPC server.
* -- pszAddress: Address of the gRPC server.
* -- dwPort: Port of the gRPC server.
* -- return: Handle to the gRPC client connection, or NULL on failure.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_CLIENT_HANDLE leechgrpc_client_create_insecure(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort
);
typedef LEECHGRPC_CLIENT_HANDLE(*pfn_leechgrpc_client_create_insecure)(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort
);
/*
* Create a gRPC client connection to the gRPC server with mTLS.
* -- pszAddress: Address of the gRPC server.
* -- dwPort: Port of the gRPC server.
* -- szTlsServerHostnameOverride: Optional hostname to verify against the server certificate (if different from address).
* -- szTlsServerCertPath: Server CA certificate to trust for mTLS connections.
* -- szTlsClientP12Path: Path to the client's TLS certificate (incl. chain) & private key (.p12 / .pfx).
* -- szTlsClientP12Password: Password for the client's TLS certificate & private key (.p12 / .pfx).
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_CLIENT_HANDLE leechgrpc_client_create_secure_p12(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ LPCSTR szTlsServerHostnameOverride,
_In_opt_ LPCSTR szTlsServerCertPath,
_In_ LPCSTR szTlsClientP12Path,
_In_ LPCSTR szTlsClientP12Password
);
typedef LEECHGRPC_CLIENT_HANDLE(*pfn_leechgrpc_client_create_secure_p12)(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ LPCSTR szTlsServerHostnameOverride,
_In_opt_ LPCSTR szTlsServerCertPath,
_In_ LPCSTR szTlsClientP12Path,
_In_ LPCSTR szTlsClientP12Password
);
/*
* Create a gRPC client connection to the gRPC server with mTLS.
* -- pszAddress: Address of the gRPC server.
* -- dwPort: Port of the gRPC server.
* -- szTlsServerHostnameOverride: Optional hostname to verify against the server certificate (if different from address).
* -- szTlsServerCert: Server CA certificate to trust for mTLS connections.
* -- szTlsClientCert: Cerver TLS certificate.
* -- szTlsClientCertPrivateKey: Client TLS certificate private key.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_CLIENT_HANDLE leechgrpc_client_create_secure_pemraw(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ LPCSTR szTlsServerHostnameOverride,
_In_opt_ LPCSTR szTlsServerCert,
_In_ LPCSTR szTlsClientCert,
_In_ LPCSTR szTlsClientCertPrivateKey
);
typedef LEECHGRPC_CLIENT_HANDLE(*pfn_leechgrpc_client_create_secure_pemraw)(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ LPCSTR szTlsServerHostnameOverride,
_In_opt_ LPCSTR szTlsServerCert,
_In_ LPCSTR szTlsClientCert,
_In_ LPCSTR szTlsClientCertPrivateKey
);
/*
* Create a gRPC client connection to the gRPC server with mTLS.
* -- pszAddress: Address of the gRPC server.
* -- dwPort: Port of the gRPC server.
* -- szTlsServerHostnameOverride: Optional hostname to verify against the server certificate (if different from address).
* -- szTlsServerCertPath: Server CA certificate to trust for mTLS connections.
* -- szTlsClientCertPath: Cerver TLS certificate.
* -- szTlsClientCertPrivateKeyPath: Client TLS certificate private key.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_CLIENT_HANDLE leechgrpc_client_create_secure_pemfile(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ LPCSTR szTlsServerHostnameOverride,
_In_opt_ LPCSTR szTlsServerCertPath,
_In_ LPCSTR szTlsClientCertPath,
_In_ LPCSTR szTlsClientCertPrivateKeyPath
);
typedef LEECHGRPC_CLIENT_HANDLE(*pfn_leechgrpc_client_create_secure_pemfile)(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ LPCSTR szTlsServerHostnameOverride,
_In_opt_ LPCSTR szTlsServerCertPath,
_In_ LPCSTR szTlsClientCertPath,
_In_ LPCSTR szTlsClientCertPrivateKeyPath
);
//-----------------------------------------------------------------------------
// LeechgRPC Server API:
//-----------------------------------------------------------------------------
/*
* Callback function used to pass on a command received by the gRPC server.
* -- pbIn: Pointer to the input buffer.
* -- cbIn: Size of the input buffer.
* -- ppbOut: Pointer to receive the output buffer allocated by the callback function, freed by the caller.
* -- pcbOut: Pointer to receive the size of the output buffer.
*/
typedef VOID(*PFN_RESERVED_SUBMIT_COMMAND_CB)(_In_opt_ PVOID ctx, _In_ PBYTE pbIn, _In_ SIZE_T cbIn, _Out_ PBYTE *ppbOut, _Out_ SIZE_T *pcbOut);
/*
* Wait for the gRPC server to shutdown.
* -- hGRPC: Handle to the gRPC server.
*/
LEECHGRPC_EXPORTED_FUNCTION
VOID leechgrpc_server_wait(_In_ LEECHGRPC_SERVER_HANDLE hGRPC);
typedef VOID(*pfn_leechgrpc_server_wait)(_In_ LEECHGRPC_SERVER_HANDLE hGRPC);
/*
* Shut down the gRPC server.
* -- hGRPC: Handle to the gRPC server.
*/
LEECHGRPC_EXPORTED_FUNCTION
VOID leechgrpc_server_shutdown(_In_ LEECHGRPC_SERVER_HANDLE hGRPC);
typedef VOID(*pfn_leechgrpc_server_shutdown)(_In_ LEECHGRPC_SERVER_HANDLE hGRPC);
/*
* Create an insecure gRPC server without any authentication / encryption.
* -- szAddress: Address to listen on, e.g., "localhost" or "0.0.0.0".
* -- dwPort: Port to listen on.
* -- pfnReservedSubmitCommandCB: Callback function to handle incoming commands.
* -- return: Handle to the gRPC server, or NULL on failure.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_SERVER_HANDLE leechgrpc_server_create_insecure(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB
);
typedef LEECHGRPC_SERVER_HANDLE(*pfn_leechgrpc_server_create_insecure)(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB
);
/*
* Create a gRPC server with mTLS.
* -- szAddress: Address to listen on, e.g., "localhost" or "
* -- dwPort: Port to listen on.
* -- ctx: Optional context to pass to the callback function.
* -- pfnReservedSubmitCommandCB: Callback function to handle incoming commands.
* -- szTlsClientCertPath: Client CA certificate to trust for mTLS connections.
* -- szTlsServerP12Path: Path to the server's TLS certificate (incl. chain) & private key (.p12 / .pfx).
* -- szTlsServerP12Password: Password for the server's TLS certificate & private key (.p12 / .pfx).
* -- return: Handle to the gRPC server, or NULL on failure.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_SERVER_HANDLE leechgrpc_server_create_secure_p12(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB,
_In_ LPCSTR szTlsClientCertPath,
_In_ LPCSTR szTlsServerP12Path,
_In_ LPCSTR szTlsServerP12Password
);
typedef LEECHGRPC_SERVER_HANDLE(*pfn_leechgrpc_server_create_secure_p12)(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB,
_In_ LPCSTR szTlsClientCertPath,
_In_ LPCSTR szTlsServerP12Path,
_In_ LPCSTR szTlsServerP12Password
);
/*
* Create a gRPC server with mTLS.
* -- szAddress: Address to listen on, e.g., "localhost" or "
* -- dwPort: Port to listen on.
* -- ctx: Optional context to pass to the callback function.
* -- pfnReservedSubmitCommandCB: Callback function to handle incoming commands.
* -- szTlsClientCert: Client CA certificate to trust for mTLS connections.
* -- szTlsServerCert: Server TLS certificate (incl. chain).
* -- szTlsServerCertPrivateKey: Server TLS certificate private key.
* -- return: Handle to the gRPC server, or NULL on failure.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_SERVER_HANDLE leechgrpc_server_create_secure_pemraw(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB,
_In_ LPCSTR szTlsClientCert,
_In_ LPCSTR szTlsServerCert,
_In_ LPCSTR szTlsServerCertPrivateKey
);
typedef LEECHGRPC_SERVER_HANDLE(*pfn_leechgrpc_server_create_secure_pemraw)(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB,
_In_ LPCSTR szTlsClientCert,
_In_ LPCSTR szTlsServerCert,
_In_ LPCSTR szTlsServerCertPrivateKey
);
/*
* Create a gRPC server with mTLS.
* -- szAddress: Address to listen on, e.g., "localhost" or "
* -- dwPort: Port to listen on.
* -- ctx: Optional context to pass to the callback function.
* -- pfnReservedSubmitCommandCB: Callback function to handle incoming commands.
* -- szTlsClientCertPath: Client CA certificate to trust for mTLS connections.
* -- szTlsServerCertPath: Server TLS certificate (incl. chain).
* -- szTlsServerCertPrivateKeyPath: Server TLS certificate private key.
* -- return: Handle to the gRPC server, or NULL on failure.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_SERVER_HANDLE leechgrpc_server_create_secure_pemfile(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB,
_In_ LPCSTR szTlsClientCertPath,
_In_ LPCSTR szTlsServerCertPath,
_In_ LPCSTR szTlsServerCertPrivateKeyPath
);
typedef LEECHGRPC_SERVER_HANDLE(*pfn_leechgrpc_server_create_secure_pemfile)(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB,
_In_ LPCSTR szTlsClientCertPath,
_In_ LPCSTR szTlsServerCertPath,
_In_ LPCSTR szTlsServerCertPrivateKeyPath
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __LEECHGRPC_H__ */

View File

@@ -0,0 +1,294 @@
#include <grpcpp/grpcpp.h>
#include <iostream>
#include <memory>
#include <string>
// Include the generated headers.
#ifdef _WIN32
#include "generated/leechgrpc.grpc.pb.h"
#include "generated/leechgrpc.pb.h"
#else
#include "leechgrpc.grpc.pb.h"
#include "leechgrpc.pb.h"
#endif /* _WIN32 */
#include "leechgrpc.h"
#include "oscompatibility.h"
#include "util.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using leechrpc::LeechRpc;
using leechrpc::SubmitCommandRequest;
using leechrpc::SubmitCommandResponse;
// A client class that connects to the LeechRpc server
class LeechRpcClient {
public:
// Constructor: create a new Stub connected to the provided channel
explicit LeechRpcClient(std::shared_ptr<Channel> channel) : stub_(LeechRpc::NewStub(channel)) {}
// Calls the ReservedSubmitCommand RPC
std::string ReservedSubmitCommand(const std::string& message)
{
// Container for the request and response
SubmitCommandRequest request;
SubmitCommandResponse response;
// Fill the request with the client data
request.set_pbin(message);
// Context for the client (can set metadata, etc.)
ClientContext context;
// Set a deadline for the RPC
auto deadline = std::chrono::system_clock::now() + std::chrono::milliseconds(LEECHGRPC_CLIENT_TIMEOUT_MS);
context.set_deadline(deadline);
// The actual RPC
Status status = stub_->ReservedSubmitCommand(&context, request, &response);
// Act upon its status
if (!status.ok()) {
//std::cerr << "[Client] RPC failed: " << status.error_message() << std::endl;
return "";
}
// Return the pbOut bytes as a std::string
return response.pbout();
}
private:
// Stub used for making RPC calls
std::unique_ptr<LeechRpc::Stub> stub_;
};
/*
* Submit a command to the gRPC server.
* -- hGRPC: Handle to the gRPC client.
* -- pbIn: Pointer to the input buffer.
* -- cbIn: Size of the input buffer.
* -- ppbOut: Pointer to receive the output buffer. The caller is responsible for freeing this buffer with LocalFree/free.
* -- pcbOut: Pointer to receive the size of the output buffer.
* -- return: TRUE if the command was successfully submitted; otherwise, FALSE.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return)
BOOL leechgrpc_client_submit_command(
_In_ LEECHGRPC_CLIENT_HANDLE hGRPC,
_In_ PBYTE pbIn,
_In_ SIZE_T cbIn,
_Out_ PBYTE *ppbOut,
_Out_ SIZE_T *pcbOut
)
{
try {
// Cast the handle to a client
LeechRpcClient *client = static_cast<LeechRpcClient *>(hGRPC);
// Call the ReservedSubmitCommand RPC
std::string message(reinterpret_cast<char *>(pbIn), cbIn);
std::string reply = client->ReservedSubmitCommand(message);
// Allocate memory for the response
*ppbOut = reinterpret_cast<PBYTE>(LocalAlloc(LMEM_ZEROINIT, reply.size()));
if(*ppbOut == NULL) {
std::cerr << "[Client] Error allocating memory for response" << std::endl;
return FALSE;
}
if(reply.size() == 0) {
std::cerr << "[Client] Error submitting command" << std::endl;
return FALSE;
}
// Copy the response to the output buffer
memcpy(*ppbOut, reply.c_str(), reply.size());
*pcbOut = reply.size();
return TRUE;
} catch(const std::exception &e) {
std::cerr << "[Client] Error submitting command: " << e.what() << std::endl;
return FALSE;
}
}
/*
* Create a gRPC client connection to the gRPC server.
* -- pszAddress: Address of the gRPC server.
* -- dwPort: Port of the gRPC server.
* -- return: Handle to the gRPC client connection, or NULL on failure.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_CLIENT_HANDLE leechgrpc_client_create_insecure(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort
) {
try {
std::string address = std::string(szAddress) + ":" + std::to_string(dwPort);
grpc::ChannelArguments channel_args;
channel_args.SetMaxReceiveMessageSize(LEECHGRPC_MESSAGE_SIZE_MAX);
channel_args.SetMaxSendMessageSize(LEECHGRPC_MESSAGE_SIZE_MAX);
channel_args.SetSslTargetNameOverride("*");
return reinterpret_cast<LEECHGRPC_CLIENT_HANDLE>(new LeechRpcClient(grpc::CreateCustomChannel(address, grpc::InsecureChannelCredentials(), channel_args)));
} catch(const std::exception &e) {
std::cerr << "[Client] Error creating channel: " << e.what() << std::endl;
return NULL;
}
}
_Success_(return != NULL)
LEECHGRPC_CLIENT_HANDLE leechgrpc_client_create_secure_internal(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ LPCSTR szTlsServerHostnameOverride,
_In_ const std::string sTlsServerCert,
_In_ const std::string sTlsClientCert,
_In_ const std::string sTlsClientCertPrivateKey
) {
try {
if(sTlsClientCert.length() < 8 || sTlsClientCertPrivateKey.length() < 8) {
std::cerr << "[Client] Invalid TLS certificate or key provided." << std::endl;
return NULL;
}
// address/port -> string:
CHAR szAddressAndPort[MAX_PATH] = { 0 };
_snprintf_s(szAddressAndPort, MAX_PATH, _TRUNCATE, "%s:%u", szAddress, dwPort);
const std::string server_address(szAddressAndPort);
// mTLS server cert & client cert/key:
grpc::SslCredentialsOptions sslOpts;
if(sTlsServerCert.length() > 8) {
sslOpts.pem_root_certs = sTlsServerCert;
}
sslOpts.pem_private_key = sTlsClientCertPrivateKey;
sslOpts.pem_cert_chain = sTlsClientCert;
// build and configure server:
grpc::ChannelArguments channelArgs;
channelArgs.SetMaxReceiveMessageSize(LEECHGRPC_MESSAGE_SIZE_MAX);
channelArgs.SetMaxSendMessageSize(LEECHGRPC_MESSAGE_SIZE_MAX);
if(szTlsServerHostnameOverride) {
channelArgs.SetSslTargetNameOverride(szTlsServerHostnameOverride);
}
auto creds = grpc::SslCredentials(sslOpts);
auto channel = grpc::CreateCustomChannel(server_address, creds, channelArgs);
if(!channel) {
std::cerr << "[Client] Error creating secure channel to: " << server_address << std::endl;
return NULL;
}
// create and return a new LeechRpcClient object, cast to LEECHGRPC_CLIENT_HANDLE:
// caller is responsible for deleting this pointer.
return reinterpret_cast<LEECHGRPC_CLIENT_HANDLE>(new LeechRpcClient(channel));
} catch(const std::exception &e) {
std::cerr << "[Client] Exception in secure client creation: " << e.what() << std::endl;
return NULL;
} catch(...) {
std::cerr << "[Client] Unknown error in secure client creation." << std::endl;
return NULL;
}
}
/*
* Create a gRPC client connection to the gRPC server with mTLS.
* -- pszAddress: Address of the gRPC server.
* -- dwPort: Port of the gRPC server.
* -- szTlsServerHostnameOverride: Optional hostname to verify against the server certificate (if different from address).
* -- szTlsServerCertPath: Server CA certificate to trust for mTLS connections.
* -- szTlsClientP12Path: Path to the client's TLS certificate (incl. chain) & private key (.p12 / .pfx).
* -- szTlsClientP12Password: Password for the client's TLS certificate & private key (.p12 / .pfx).
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_CLIENT_HANDLE leechgrpc_client_create_secure_p12(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ LPCSTR szTlsServerHostnameOverride,
_In_opt_ LPCSTR szTlsServerCertPath,
_In_ LPCSTR szTlsClientP12Path,
_In_ LPCSTR szTlsClientP12Password
) {
std::string sTlsServerCert("");
std::string sTlsClientCert;
std::string sTlsClientCertPrivateKey;
if(szTlsServerCertPath) {
if(!Util_LoadCaPemFromFile(szTlsServerCertPath, sTlsServerCert)) {
std::cerr << "[Client] Failed to load root CA from file: " << szTlsServerCertPath << std::endl;
return NULL;
}
}
if(!Util_LoadPemFromPkcs12(szTlsClientP12Path, szTlsClientP12Password, sTlsClientCertPrivateKey, sTlsClientCert)) {
std::cerr << "[Client] Failed to load client cert/key from: " << szTlsClientP12Path << std::endl;
return NULL;
}
return leechgrpc_client_create_secure_internal(szAddress, dwPort, szTlsServerHostnameOverride, sTlsServerCert, sTlsClientCert, sTlsClientCertPrivateKey);
}
/*
* Create a gRPC client connection to the gRPC server with mTLS.
* -- pszAddress: Address of the gRPC server.
* -- dwPort: Port of the gRPC server.
* -- szTlsServerHostnameOverride: Optional hostname to verify against the server certificate (if different from address).
* -- szTlsServerCert: Server CA certificate to trust for mTLS connections.
* -- szTlsClientCert: Cerver TLS certificate.
* -- szTlsClientCertPrivateKey: Client TLS certificate private key.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_CLIENT_HANDLE leechgrpc_client_create_secure_pemraw(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ LPCSTR szTlsServerHostnameOverride,
_In_opt_ LPCSTR szTlsServerCert,
_In_ LPCSTR szTlsClientCert,
_In_ LPCSTR szTlsClientCertPrivateKey
) {
const std::string sTlsServerCertNull("");
const std::string sTlsServerCert(szTlsServerCert);
const std::string sTlsClientCert(szTlsClientCert);
const std::string sTlsClientCertPrivateKey(szTlsClientCertPrivateKey);
return leechgrpc_client_create_secure_internal(szAddress, dwPort, szTlsServerHostnameOverride, (szTlsServerCert ? sTlsServerCert : sTlsServerCertNull), sTlsClientCert, sTlsClientCertPrivateKey);
}
/*
* Create a gRPC client connection to the gRPC server with mTLS.
* -- pszAddress: Address of the gRPC server.
* -- dwPort: Port of the gRPC server.
* -- szTlsServerHostnameOverride: Optional hostname to verify against the server certificate (if different from address).
* -- szTlsServerCertPath: Server CA certificate to trust for mTLS connections.
* -- szTlsClientCertPath: Cerver TLS certificate.
* -- szTlsClientCertPrivateKeyPath: Client TLS certificate private key.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_CLIENT_HANDLE leechgrpc_client_create_secure_pemfile(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ LPCSTR szTlsServerHostnameOverride,
_In_opt_ LPCSTR szTlsServerCertPath,
_In_ LPCSTR szTlsClientCertPath,
_In_ LPCSTR szTlsClientCertPrivateKeyPath
) {
std::string sTlsServerCert("");
std::string sTlsClientCert;
std::string sTlsClientCertPrivateKey;
if(szTlsServerCertPath) {
if(!Util_LoadCaPemFromFile(szTlsServerCertPath, sTlsServerCert)) {
std::cerr << "[Client] Failed to load server ca certificate from file: " << szTlsServerCertPath << std::endl;
return NULL;
}
}
if(!Util_LoadCaPemFromFile(szTlsClientCertPath, sTlsClientCert)) {
std::cerr << "[Client] Failed to load client certificate from file: " << szTlsClientCertPath << std::endl;
return NULL;
}
if(!Util_LoadCaPemFromFile(szTlsClientCertPrivateKeyPath, sTlsClientCertPrivateKey)) {
std::cerr << "[Client] Failed to load client certificate private key from file: " << szTlsClientCertPrivateKeyPath << std::endl;
return NULL;
}
return leechgrpc_client_create_secure_internal(szAddress, dwPort, szTlsServerHostnameOverride, sTlsServerCert, sTlsClientCert, sTlsClientCertPrivateKey);
}
/*
* Free the gRPC client connection.
* -- hGRPC: Handle to the gRPC client.
*/
LEECHGRPC_EXPORTED_FUNCTION
VOID leechgrpc_client_free(_In_ LEECHGRPC_CLIENT_HANDLE hGRPC)
{
try {
delete static_cast<LeechRpcClient*>(hGRPC);
} catch(const std::exception &e) {
std::cerr << "[Client] Error free client: " << e.what() << std::endl;
}
}

View File

@@ -0,0 +1,279 @@
#include <grpcpp/grpcpp.h>
#include <grpcpp/security/server_credentials.h>
#include <openssl/ssl.h>
#include <iostream>
#include <memory>
#include <string>
// Include the generated headers.
#ifdef _WIN32
#include "generated/leechgrpc.grpc.pb.h"
#include "generated/leechgrpc.pb.h"
#else
#include "leechgrpc.grpc.pb.h"
#include "leechgrpc.pb.h"
#endif /* _WIN32 */
#include "leechgrpc.h"
#include "oscompatibility.h"
#include "util.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using leechrpc::LeechRpc;
using leechrpc::SubmitCommandRequest;
using leechrpc::SubmitCommandResponse;
// Implementation of the LeechRpc service.
class LeechRpcServiceImpl final : public LeechRpc::Service {
public:
explicit LeechRpcServiceImpl(PVOID ctx, PFN_RESERVED_SUBMIT_COMMAND_CB pfnCB) : m_ctx(ctx), m_pfnCB(pfnCB)
{
}
// Handle the ReservedSubmitCommand RPC.
Status ReservedSubmitCommand(ServerContext *context, const SubmitCommandRequest *request, SubmitCommandResponse *response) override
{
// Extract the clients message (pbIn)
const std::string client_data = request->pbin();
const PBYTE pbIn = reinterpret_cast<PBYTE>(const_cast<char *>(client_data.data()));
SIZE_T cbIn = client_data.size();
// Call the callback function
PBYTE pbOut = NULL;
SIZE_T cbOut = 0;
m_pfnCB(m_ctx, pbIn, cbIn, &pbOut, &cbOut);
// Set the response message & free it.
response->set_pbout(reinterpret_cast<const char *>(pbOut), cbOut);
LocalFree(pbOut);
return Status::OK;
}
private:
PVOID m_ctx;
PFN_RESERVED_SUBMIT_COMMAND_CB m_pfnCB;
};
/*
* Create a gRPC server.
* -- dwPort: Port to listen on.
* -- pfnReservedSubmitCommandCB: Callback function to handle incoming commands.
* -- return: Handle to the gRPC server, or NULL on failure.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
HANDLE leechgrpc_server_create_insecure(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB
) {
auto *service = new LeechRpcServiceImpl(ctx, pfnReservedSubmitCommandCB);
// Convert the address/port to a string
CHAR szAddressAndPort[MAX_PATH] = { 0 };
_snprintf_s(szAddressAndPort, MAX_PATH, _TRUNCATE, "%s:%d", szAddress, dwPort);
const std::string server_address(szAddressAndPort);
// Build the server
ServerBuilder builder;
builder.SetMaxReceiveMessageSize(LEECHGRPC_MESSAGE_SIZE_MAX);
builder.SetMaxSendMessageSize(LEECHGRPC_MESSAGE_SIZE_MAX);
// Listen on the given address without any authentication mechanism (Insecure)
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register our service
builder.RegisterService(service);
// Assemble the server
std::unique_ptr<Server> server = builder.BuildAndStart();
if(!server) {
return NULL;
}
// Dynamically allocate a unique_ptr<Server> on the heap
std::unique_ptr<std::unique_ptr<Server>> ptrOnHeap(new std::unique_ptr<Server>(std::move(server)));
// Transfer ownership by returning the raw pointer as HANDLE
// The caller will store this handle and cast it back later.
return reinterpret_cast<HANDLE>(ptrOnHeap.release());
}
_Success_(return != NULL)
LEECHGRPC_SERVER_HANDLE leechgrpc_server_create_secure_internal(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB,
_In_ const std::string sTlsClientCert,
_In_ const std::string sTlsServerCert,
_In_ const std::string sTlsServerCertPrivateKey
) {
try {
if(sTlsClientCert.length() < 8 || sTlsServerCert.length() < 8 || sTlsServerCertPrivateKey.length() < 8) {
std::cerr << "[Server] Invalid TLS certificate or key provided." << std::endl;
return NULL;
}
auto *service = new LeechRpcServiceImpl(ctx, pfnReservedSubmitCommandCB);
// address/port -> string:
CHAR szAddressAndPort[MAX_PATH] = { 0 };
_snprintf_s(szAddressAndPort, MAX_PATH, _TRUNCATE, "%s:%u", szAddress, dwPort);
const std::string server_address(szAddressAndPort);
// mTLS client cert & server cert/key:
grpc::SslServerCredentialsOptions::PemKeyCertPair keyCertPair;
keyCertPair.private_key = sTlsServerCertPrivateKey;
keyCertPair.cert_chain = sTlsServerCert;
grpc::SslServerCredentialsOptions sslOpts;
sslOpts.pem_key_cert_pairs.push_back(keyCertPair);
sslOpts.pem_root_certs = sTlsClientCert;
sslOpts.client_certificate_request = GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
// build and configure server:
auto serverCreds = grpc::SslServerCredentials(sslOpts);
grpc::ServerBuilder builder;
builder.SetMaxReceiveMessageSize(LEECHGRPC_MESSAGE_SIZE_MAX);
builder.SetMaxSendMessageSize(LEECHGRPC_MESSAGE_SIZE_MAX);
builder.AddListeningPort(server_address, serverCreds);
builder.RegisterService(service);
// start the server:
std::unique_ptr<grpc::Server> server = builder.BuildAndStart();
if(!server) {
std::cerr << "[Server] Failed to start secure server on: " << server_address << std::endl;
return NULL;
}
// dynamically allocate a unique_ptr<Server> on the heap:
std::unique_ptr<std::unique_ptr<grpc::Server>> ptrOnHeap(new std::unique_ptr<grpc::Server>(std::move(server)));
// return the raw pointer as a LEECHGRPC_SERVER_HANDLE.
// caller is responsible for cleanup.
return reinterpret_cast<LEECHGRPC_SERVER_HANDLE>(ptrOnHeap.release());
} catch(const std::exception &ex) {
std::cerr << "[Server] Exception in secure server creation: " << ex.what() << std::endl;
return NULL;
} catch(...) {
std::cerr << "[Server] Unknown error in secure server creation." << std::endl;
return NULL;
}
}
/*
* Create a gRPC server with mTLS.
* -- szAddress: Address to listen on, e.g., "localhost" or "
* -- dwPort: Port to listen on.
* -- ctx: Optional context to pass to the callback function.
* -- pfnReservedSubmitCommandCB: Callback function to handle incoming commands.
* -- szTlsClientCert: Client CA certificate to trust for mTLS connections.
* -- szTlsServerCert: Server TLS certificate (incl. chain).
* -- szTlsServerCertPrivateKey: Server TLS certificate private key.
* -- return: Handle to the gRPC server, or NULL on failure.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_SERVER_HANDLE leechgrpc_server_create_secure_pemraw(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB,
_In_ LPCSTR szTlsClientCert,
_In_ LPCSTR szTlsServerCert,
_In_ LPCSTR szTlsServerCertPrivateKey
) {
const std::string sTlsClientCert(szTlsClientCert);
const std::string sTlsServerCert(szTlsServerCert);
const std::string sTlsServerCertPrivateKey(szTlsServerCertPrivateKey);
return leechgrpc_server_create_secure_internal(szAddress, dwPort, ctx, pfnReservedSubmitCommandCB, sTlsClientCert, sTlsServerCert, sTlsServerCertPrivateKey);
}
/*
* Create a gRPC server with mTLS.
* -- szAddress: Address to listen on, e.g., "localhost" or "
* -- dwPort: Port to listen on.
* -- ctx: Optional context to pass to the callback function.
* -- pfnReservedSubmitCommandCB: Callback function to handle incoming commands.
* -- szTlsClientCertPath: Client CA certificate to trust for mTLS connections.
* -- szTlsServerP12Path: Path to the server's TLS certificate & private key (.p12 / .pfx).
* -- szTlsServerP12Password: Password for the server's TLS certificate & private key (.p12 / .pfx).
* -- return: Handle to the gRPC server, or NULL on failure.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_SERVER_HANDLE leechgrpc_server_create_secure_p12(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB,
_In_ LPCSTR szTlsClientCertPath,
_In_ LPCSTR szTlsServerP12Path,
_In_ LPCSTR szTlsServerP12Password
) {
// server certificate from .p12 file:
std::string sTlsClientCert;
std::string sTlsServerCert;
std::string sTlsServerCertPrivateKey;
if(!Util_LoadPemFromPkcs12(szTlsServerP12Path, szTlsServerP12Password, sTlsServerCertPrivateKey, sTlsServerCert)) {
std::cerr << "[Server] Failed to load mTLS server cert/key from .p12 file: " << szTlsServerP12Path << std::endl;
return NULL;
}
// client certificate:
if(!Util_LoadCaPemFromFile(szTlsClientCertPath, sTlsClientCert)) {
std::cerr << "[Server] Failed to load mTLS client ca cert from: " << szTlsClientCertPath << std::endl;
return NULL;
}
return leechgrpc_server_create_secure_internal(szAddress, dwPort, ctx, pfnReservedSubmitCommandCB, sTlsClientCert, sTlsServerCert, sTlsServerCertPrivateKey);
}
/*
* Create a gRPC server with mTLS.
* -- szAddress: Address to listen on, e.g., "localhost" or "
* -- dwPort: Port to listen on.
* -- ctx: Optional context to pass to the callback function.
* -- pfnReservedSubmitCommandCB: Callback function to handle incoming commands.
* -- szTlsClientCertPath: Client CA certificate to trust for mTLS connections.
* -- szTlsServerCertPath: Server TLS certificate (incl. chain).
* -- szTlsServerCertPrivateKeyPath: Server TLS certificate private key.
* -- return: Handle to the gRPC server, or NULL on failure.
*/
LEECHGRPC_EXPORTED_FUNCTION _Success_(return != NULL)
LEECHGRPC_SERVER_HANDLE leechgrpc_server_create_secure_pemfile(
_In_ LPCSTR szAddress,
_In_ DWORD dwPort,
_In_opt_ PVOID ctx,
_In_ PFN_RESERVED_SUBMIT_COMMAND_CB pfnReservedSubmitCommandCB,
_In_ LPCSTR szTlsClientCertPath,
_In_ LPCSTR szTlsServerCertPath,
_In_ LPCSTR szTlsServerCertPrivateKeyPath
) {
// Load the server's private key and certificate from the .p12 file
std::string sTlsClientCert;
std::string sTlsServerCert;
std::string sTlsServerCertPrivateKey;
if(!Util_LoadCaPemFromFile(szTlsServerCertPath, sTlsServerCert)) {
std::cerr << "[Server] Failed to load server ca certificate from: " << szTlsServerCertPath << std::endl;
return NULL;
}
if(!Util_LoadCaPemFromFile(szTlsServerCertPrivateKeyPath, sTlsServerCertPrivateKey)) {
std::cerr << "[Server] Failed to load server ca certificate private key from: " << szTlsServerCertPrivateKeyPath << std::endl;
return NULL;
}
if(!Util_LoadCaPemFromFile(szTlsClientCertPath, sTlsClientCert)) {
std::cerr << "[Server] Failed to load client ca certificate from: " << szTlsClientCertPath << std::endl;
return NULL;
}
return leechgrpc_server_create_secure_internal(szAddress, dwPort, ctx, pfnReservedSubmitCommandCB, sTlsClientCert, sTlsServerCert, sTlsServerCertPrivateKey);
}
/*
* Wait for the gRPC server to shutdown.
* -- hGRPC: Handle to the gRPC server.
*/
LEECHGRPC_EXPORTED_FUNCTION
VOID leechgrpc_server_wait(_In_ LEECHGRPC_SERVER_HANDLE hGRPC)
{
auto pServer = reinterpret_cast<std::unique_ptr<Server>*>(hGRPC);
(*pServer)->Wait();
}
/*
* Shut down the gRPC server.
* -- hGRPC: Handle to the gRPC server.
*/
LEECHGRPC_EXPORTED_FUNCTION
VOID leechgrpc_server_shutdown(_In_ LEECHGRPC_SERVER_HANDLE hGRPC)
{
auto pServer = reinterpret_cast<std::unique_ptr<Server>*>(hGRPC);
(*pServer)->Shutdown();
delete pServer;
}

View File

@@ -0,0 +1,184 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{7f9de005-851f-4817-8749-0396da30b3f8}</ProjectGuid>
<RootNamespace>leechgrpc</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>libleechgrpc</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgUseStatic>true</VcpkgUseStatic>
<VcpkgTriplet>
</VcpkgTriplet>
<VcpkgUseMD>false</VcpkgUseMD>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgUseStatic>true</VcpkgUseStatic>
<VcpkgTriplet>
</VcpkgTriplet>
<VcpkgUseMD>false</VcpkgUseMD>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgUseStatic>true</VcpkgUseStatic>
<VcpkgTriplet>
</VcpkgTriplet>
<VcpkgUseMD>false</VcpkgUseMD>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgUseStatic>true</VcpkgUseStatic>
<VcpkgTriplet>
</VcpkgTriplet>
<VcpkgUseMD>false</VcpkgUseMD>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="proto\leechgrpc.proto" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="generated\leechgrpc.grpc.pb.h" />
<ClInclude Include="generated\leechgrpc.pb.h" />
<ClInclude Include="leechgrpc.h" />
<ClInclude Include="oscompatibility.h" />
<ClInclude Include="util.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="generated\leechgrpc.grpc.pb.cc" />
<ClCompile Include="generated\leechgrpc.pb.cc" />
<ClCompile Include="leechgrpc_client.cc" />
<ClCompile Include="leechgrpc_server.cc" />
<ClCompile Include="oscompatibility.cc" />
<ClCompile Include="util.cc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="proto">
<UniqueIdentifier>{e08fb88d-9d45-4866-9ec6-273e6ce4b653}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\generated">
<UniqueIdentifier>{4d4ccebb-a242-4d03-b043-48e5d6d6fa10}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\generated">
<UniqueIdentifier>{8cba3da9-b9ff-4e09-9e61-13629ff93cb0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="proto\leechgrpc.proto">
<Filter>proto</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="leechgrpc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="oscompatibility.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="generated\leechgrpc.grpc.pb.h">
<Filter>Header Files\generated</Filter>
</ClInclude>
<ClInclude Include="generated\leechgrpc.pb.h">
<Filter>Header Files\generated</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="generated\leechgrpc.grpc.pb.cc">
<Filter>Source Files\generated</Filter>
</ClCompile>
<ClCompile Include="generated\leechgrpc.pb.cc">
<Filter>Source Files\generated</Filter>
</ClCompile>
<ClCompile Include="leechgrpc_client.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="util.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="leechgrpc_server.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="oscompatibility.cc">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View File

@@ -0,0 +1,29 @@
// oscompatibility.c : LeechCore Windows/Linux compatibility layer.
//
// (c) Ulf Frisk, 2017-2025
// Author: Ulf Frisk, pcileech@frizk.net
//
#if defined(LINUX) || defined(MACOS)
#include "oscompatibility.h"
// ----------------------------------------------------------------------------
// LocalAlloc/LocalFree BELOW:
// ----------------------------------------------------------------------------
HANDLE LocalAlloc(DWORD uFlags, SIZE_T uBytes)
{
HANDLE h = malloc(uBytes);
if(h && (uFlags & LMEM_ZEROINIT)) {
memset(h, 0, uBytes);
}
return h;
}
VOID LocalFree(HANDLE hMem)
{
free(hMem);
}
#endif /* LINUX || MACOS */

View File

@@ -0,0 +1,160 @@
// oscompatibility.h : LeechCore Windows/Linux compatibility layer.
//
// (c) Ulf Frisk, 2017-2025
// Author: Ulf Frisk, pcileech@frizk.net
//
#ifndef __OSCOMPATIBILITY_H__
#define __OSCOMPATIBILITY_H__
#include "leechgrpc.h"
#ifdef _WIN32
#include <Windows.h>
#include <stdio.h>
#endif /* _WIN32 */
#if defined(LINUX) || defined(MACOS)
#define _FILE_OFFSET_BITS 64
#include <ctype.h>
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
typedef void VOID, *PVOID;
typedef void *HANDLE, **PHANDLE, *HMODULE, *FARPROC;
typedef uint32_t BOOL, *PBOOL;
typedef uint8_t BYTE, *PBYTE;
typedef uint8_t UCHAR, *PUCHAR;
typedef char CHAR, *PCHAR, *PSTR, *LPSTR;
typedef const char *LPCSTR;
typedef int32_t LONG;
typedef uint16_t WORD, *PWORD, USHORT, *PUSHORT;
typedef uint16_t WCHAR, *PWCHAR, *LPWSTR;
typedef const uint16_t *LPCWSTR;
typedef uint32_t UINT, DWORD, *PDWORD, ULONG, *PULONG;
typedef long long unsigned int QWORD, *PQWORD, ULONG64, *PULONG64;
typedef uint64_t LARGE_INTEGER, *PLARGE_INTEGER, FILETIME;
typedef size_t SIZE_T, *PSIZE_T;
typedef void *OVERLAPPED, *LPOVERLAPPED;
typedef struct tdEXCEPTION_RECORD32 { CHAR sz[80]; } EXCEPTION_RECORD32;
typedef struct tdEXCEPTION_RECORD64 { CHAR sz[152]; } EXCEPTION_RECORD64;
typedef int(*_CoreCrtNonSecureSearchSortCompareFunction)(void const *, void const *);
#define __forceinline inline __attribute__((always_inline))
#define TRUE 1
#define FALSE 0
#define MAX_PATH 260
#define LMEM_ZEROINIT 0x0040
#define INVALID_HANDLE_VALUE ((HANDLE)-1)
#define STD_INPUT_HANDLE ((DWORD)-10)
#define STD_OUTPUT_HANDLE ((DWORD)-11)
#define GENERIC_WRITE (0x40000000L)
#define GENERIC_READ (0x80000000L)
#define FILE_SHARE_READ (0x00000001L)
#define CREATE_NEW (0x00000001L)
#define OPEN_EXISTING (0x00000003L)
#define FILE_ATTRIBUTE_NORMAL (0x00000080L)
#define STILL_ACTIVE (0x00000103L)
#define CRYPT_STRING_HEX_ANY (0x00000008L)
#define CRYPT_STRING_HEXASCIIADDR (0x00000008L)
#define STILL_ACTIVE (0x00000103L)
#define INVALID_FILE_SIZE (0xffffffffL)
#define _TRUNCATE ((SIZE_T)-1LL)
#define LPTHREAD_START_ROUTINE PVOID
#define WINUSB_INTERFACE_HANDLE libusb_device_handle*
#define PIPE_TRANSFER_TIMEOUT 0x03
#define CONSOLE_SCREEN_BUFFER_INFO PVOID // TODO: remove this dummy
#define SOCKET int
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define WSAEWOULDBLOCK 10035L
#define MAXIMUM_WAIT_OBJECTS 64
#define WAIT_OBJECT_0 (0x00000000UL)
#define WAIT_FAILED (0xFFFFFFFFUL)
#define WAIT_TIMEOUT (258L)
#define INFINITE (0xFFFFFFFFUL)
#define E_FAIL (0x80004005UL)
#define error_status_t DWORD
#define SecureZeroMemory(pb, cb) (ZeroMemory(pb, cb))
#define _itoa_s(n, s, l, b) (snprintf(s, l, "%d", n))
#define _In_
#define _In_z_
#define _Out_
#define _Inout_
#define _Inout_opt_
#define _In_opt_
#define _In_opt_z_
#define _Out_opt_
#define _Check_return_opt_
#define _Frees_ptr_opt_
#define _Post_ptr_invalid_
#define _Printf_format_string_
#define _In_reads_(x)
#define _In_reads_opt_(x)
#define _Out_writes_(x)
#define __bcount(x)
#define _Inout_bytecount_(x)
#define _Inout_updates_opt_(x)
#define _Inout_updates_bytes_(x)
#define _Out_writes_opt_(x)
#define _Success_(x)
#define UNREFERENCED_PARAMETER(x)
#define WINAPI
#define _byteswap_ushort(v) (__builtin_bswap16(v))
#define _byteswap_ulong(v) (__builtin_bswap32(v))
#define _byteswap_uint64(v) (__builtin_bswap64(v))
#ifndef _rotr
#define _rotr(v,c) ((((DWORD)v) >> ((DWORD)c) | (DWORD)((DWORD)v) << (32 - (DWORD)c)))
#endif /* _rotr */
#define _rotr16(v,c) ((((WORD)v) >> ((WORD)c) | (WORD)((WORD)v) << (16 - (WORD)c)))
#define _rotr64(v,c) ((((QWORD)v) >> ((QWORD)c) | (QWORD)((QWORD)v) << (64 - (QWORD)c)))
#define _rotl64(v,c) ((QWORD)(((QWORD)v) << ((QWORD)c)) | (((QWORD)v) >> (64 - (QWORD)c)))
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#define sprintf_s(s, maxcount, ...) (snprintf(s, maxcount, __VA_ARGS__))
#define strnlen_s(s, maxcount) (strnlen(s, maxcount))
#define strcpy_s(dst, len, src) (strncpy(dst, src, len))
#define strncpy_s(dst, len, src, srclen) (strncpy(dst, src, min((QWORD)(max(1, len)) - 1, (QWORD)(srclen))))
#define strncat_s(dst, dstlen, src, srclen) (strncat(dst, src, min((((strlen(dst) + 1 >= (QWORD)(dstlen)) || ((QWORD)(dstlen) == 0)) ? 0 : ((QWORD)(dstlen) - strlen(dst) - 1)), (QWORD)(srclen))))
#define strcat_s(dst, dstlen, src) (strncat_s(dst, dstlen, src, _TRUNCATE))
#define _vsnprintf_s(dst, len, cnt, fmt, a) (vsnprintf(dst, min((QWORD)(len), (QWORD)(cnt)), fmt, a))
#define _stricmp(s1, s2) (strcasecmp(s1, s2))
#define _strnicmp(s1, s2, maxcount) (strncasecmp(s1, s2, maxcount))
#define strtok_s(s, d, c) (strtok_r(s, d, c))
#define _snprintf_s(s,l,c,...) (snprintf(s,l,__VA_ARGS__))
#define sscanf_s(s, f, ...) (sscanf(s, f, __VA_ARGS__))
#define SwitchToThread() (sched_yield())
#define ExitThread(dwExitCode) (pthread_exit(dwExitCode))
#define ExitProcess(c) (exit(c ? EXIT_SUCCESS : EXIT_FAILURE))
#define Sleep(dwMilliseconds) (usleep(1000*dwMilliseconds))
#define fopen_s(ppFile, szFile, szAttr) ((*ppFile = fopen(szFile, szAttr)) ? 0 : 1)
#define GetModuleFileNameA(m, f, l) (readlink("/proc/self/exe", f, l))
#define ZeroMemory(pb, cb) (memset(pb, 0, cb))
#define WinUsb_SetPipePolicy(h, p, t, cb, pb) // TODO: implement this for better USB2 performance.
#define WSAGetLastError() (WSAEWOULDBLOCK) // TODO: remove this dummy when possible.
#define _ftelli64(f) (ftello(f))
#define _fseeki64(f, o, w) (fseeko(f, o, w))
#define _chsize_s(fd, cb) (ftruncate64(fd, cb))
#define _fileno(f) (fileno(f))
#define InterlockedAdd64(p, v) (__sync_add_and_fetch_8(p, v))
#define InterlockedIncrement64(p) (__sync_add_and_fetch_8(p, 1))
#define InterlockedIncrement(p) (__sync_add_and_fetch_4(p, 1))
#define InterlockedDecrement(p) (__sync_sub_and_fetch_4(p, 1))
#define GetCurrentProcess() ((HANDLE)-1)
#define closesocket(s) close(s)
HANDLE LocalAlloc(DWORD uFlags, SIZE_T uBytes);
VOID LocalFree(HANDLE hMem);
#endif /* LINUX || MACOS */
#endif /* __OSCOMPATIBILITY_H__ */

View File

@@ -0,0 +1,16 @@
syntax = "proto3";
package leechrpc;
service LeechRpc {
// Mirrors the MSRPC call: LeechRpc_ReservedSubmitCommand
rpc ReservedSubmitCommand(SubmitCommandRequest) returns (SubmitCommandResponse);
}
message SubmitCommandRequest {
bytes pbIn = 1;
}
message SubmitCommandResponse {
bytes pbOut = 1;
}

126
libleechgrpc/util.cc Normal file
View File

@@ -0,0 +1,126 @@
#include "leechgrpc.h"
#include "oscompatibility.h"
#include "util.h"
#include <string>
#include <fstream>
#include <streambuf>
#include <iostream>
#include <openssl/pkcs12.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/err.h>
_Success_(return)
bool Util_LoadPemFromPkcs12(
_In_ const std::string &pkcs12Path,
_In_ const std::string &password,
_Out_ std::string &outPrivateKeyPem,
_Out_ std::string &outCertPem
) {
// Open PKCS#12 file:
FILE *fp = NULL;
if(fopen_s(&fp, pkcs12Path.c_str(), "rb")) {
fprintf(stderr, "Failed to open P12 file: %s\n", pkcs12Path.c_str());
return false;
}
// Read the file into a PKCS12 structure
PKCS12 *p12 = d2i_PKCS12_fp(fp, nullptr);
fclose(fp);
if(!p12) {
fprintf(stderr, "Failed to d2i_PKCS12_fp\n");
return false;
}
// Parse the PKCS12
EVP_PKEY *pkey = nullptr;
X509 *cert = nullptr;
STACK_OF(X509) *ca = nullptr;
if(!PKCS12_parse(p12, password.c_str(), &pkey, &cert, &ca)) {
fprintf(stderr, "Failed to parse PKCS12\n");
PKCS12_free(p12);
return false;
}
PKCS12_free(p12);
// Convert private key to PEM
{
BIO *bio = BIO_new(BIO_s_mem());
if(!PEM_write_bio_PrivateKey(bio, pkey, nullptr, nullptr, 0, nullptr, nullptr)) {
fprintf(stderr, "Failed to write private key to PEM\n");
EVP_PKEY_free(pkey);
X509_free(cert);
//sk_X509_pop_free(ca, X509_free);
BIO_free(bio);
return false;
}
// Read the PEM data from the BIO into outPrivateKeyPem
char *pemData = nullptr;
long pemLen = BIO_get_mem_data(bio, &pemData);
outPrivateKeyPem.assign(pemData, pemLen);
BIO_free(bio);
}
// Convert cert (and optional chain) to PEM
{
BIO *bio = BIO_new(BIO_s_mem());
// Write the main certificate
if(!PEM_write_bio_X509(bio, cert)) {
fprintf(stderr, "Failed to write certificate to PEM\n");
EVP_PKEY_free(pkey);
X509_free(cert);
//sk_X509_pop_free(ca, X509_free);
BIO_free(bio);
return false;
}
// Optionally write out the chain certs
if(ca) {
int count = sk_X509_num(ca);
for(int i = 0; i < count; i++) {
X509 *chainCert = sk_X509_value(ca, i);
PEM_write_bio_X509(bio, chainCert);
}
}
char *pemData = nullptr;
long pemLen = BIO_get_mem_data(bio, &pemData);
outCertPem.assign(pemData, pemLen);
BIO_free(bio);
}
// Cleanup
EVP_PKEY_free(pkey);
X509_free(cert);
//if(ca) {
// sk_X509_pop_free(ca, X509_free);
//}
return true;
//return false;
}
_Success_(return)
bool Util_LoadCaPemFromFile(
_In_ const std::string &filePath,
_Out_ std::string &outCertPem
) {
// Clear the output parameter just in case
outCertPem.clear();
// Open the file in binary mode
std::ifstream file(filePath, std::ios::in | std::ios::binary);
if(!file.is_open()) {
std::cerr << "[Util_LoadCaPemFromFile] Failed to open CA certificate file: "
<< filePath << std::endl;
return false;
}
// Read entire file into a temporary string
std::string pem(
(std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>()
);
file.close();
// Basic validation: Check if the file content is not empty
if(pem.empty()) {
std::cerr << "[Util_LoadCaPemFromFile] CA certificate file is empty: "
<< filePath << std::endl;
return false;
}
// Assign to output parameter
outCertPem = std::move(pem);
return true;
}

23
libleechgrpc/util.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef __UTIL_H__
#define __UTIL_H__
#include "leechgrpc.h"
#include <iostream>
#include <memory>
#include <string>
_Success_(return)
bool Util_LoadPemFromPkcs12(
_In_ const std::string &pkcs12Path,
_In_ const std::string &password,
_Out_ std::string &outPrivateKeyPem,
_Out_ std::string &outCertPem
);
_Success_(return)
bool Util_LoadCaPemFromFile(
_In_ const std::string &filePath,
_Out_ std::string &outCertPem
);
#endif /* __UTIL_H__ */