PdCom  5.0
Process data communication client
Loading...
Searching...
No Matches
gnutls_example.cpp

Process implementation for TLS encrypted traffic.

Process implementation for TLS encrypted traffic.

/*****************************************************************************
* vim:tw=78
*
* Copyright (C) 2021 Bjarne von Horn (vh at igh dot de).
*
* This file is part of the PdCom library.
*
* The PdCom library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* The PdCom library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the PdCom library. If not, see <http://www.gnu.org/licenses/>.
*
*****************************************************************************/
/* PdCom example with TLS encryption.
*
* This example shows how to set up a PdCom::Process instance with the help
* of SecureProcess and PosixProcess.
* A running tls-enabled pdserv instance is needed, it should listen to port
* 4523.
* After the client application connects, it will list all available variables
* (signals and parameters) on the server and exit.
*
*/
#include <fstream>
#include <iostream>
#include <poll.h>
class MyProcess : public PdCom::SecureProcess, private PdCom::PosixProcess
{
// pass data between SecureProcess and PosixProcess
int secureRead(char *buf, int count) override
{
return posixRead(buf, count);
}
void secureWrite(const char *buf, size_t count) override
{
posixWriteDirect(buf, count);
}
void listReply(
std::vector<PdCom::Variable> vars /* variables */,
std::vector<std::string> /* directories */) override
{
// we want to enumerate all found variables
for (const auto &v : vars)
std::cout << "Found var " << v.getPath() << "\n";
running_ = false;
}
void connected() override
{
// connection is established, we're now allowed to start interacting
// with the server.
std::cout << "Connected!" << std::endl;
list("");
}
public:
void waitForSocket()
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd_, &fds);
select(fd_ + 1, &fds, NULL, NULL, NULL);
}
MyProcess(const std::string &ca_pem, const char *host = "localhost") :
PdCom::SecureProcess({EncryptionDetails::Default, ca_pem, host}),
PdCom::PosixProcess(host, 4523)
{
// start TLS session
do {
std::cerr << "Handshaking\n";
} while (!handshake());
}
bool running_ = true;
};
int main(int argc, char *argv[])
{
if (argc < 3) {
std::cerr << "Usage: " << argv[0] << " <hostname> <Path to CA.pem>\n";
return -1;
}
// initializing GnuTls
// read CA file
std::ifstream ca_file(argv[2]);
std::string ca;
getline(ca_file, ca, '\0');
// creating Process instance
MyProcess p(ca, argv[1]);
// process incoming data until work is done
while (p.running_) {
// wait until socket is readable
p.waitForSocket();
// ask PdCom to process incoming data
p.asyncData();
}
// close TLS session
p.bye();
return 0;
}
Wrapper around POSIX socket.
Definition: PosixProcess.h:45
void posixWriteDirect(const char *buf, size_t count)
Unbuffered Wrapper for write().
int posixRead(char *buf, int count)
Wrapper for read().
virtual void connected()=0
Protocol initialization completed.
virtual void listReply(std::vector< Variable > variables, std::vector< std::string > dirs)
Reply to list() call.
bool list(const std::string &path="")
List a directory path.
Definition: SecureProcess.h:41
bool handshake()
TLS Handshake.
static void InitLibrary()
GnuTls global initialization.