Client/Server communication using TCP/IP under TLS 1.3 - c

I want to write a client and server in C preferably, simple C++ if necessary.
The server will run on some flavor of Linux, the client is for testing the server.
I want to ensure messages are received and error free; therefore I will use TCP.
I want them to communicate securely; thus I will use the latest version of TLS (v1.3).
I intend to use the GnuTLS library for reasons:
Actively updated by reputable open source project
License permits selling product
Given the above, if implemented and tested, I could claim that the client/server communication is secure, reliable (a.k.a. assured), and error-checked. Yes?
Am I missing something? Is anything patently false?
Edit: certificates... i think i'm missing something about certificates to protect against man in the middle attacks...

TLS is a complex topic. Depending on your specific code the TLS connection might succeed even if you fail to properly validate the certificate. Thus, just based on what you state so far in your question it cannot be assured that the data are transferred with proper end-to-end protection and that no man in the middle can manipulate the data.

Related

Migrating particular TCP Connection using CRIU tools

Is it possible to migrate a single and particular TCP connection inside a running process in one machine to another machine using CRIU tools in Linux?
What I want is to dump a particular TCP Connection information in a memory and transfer this information to a peer machine. Inside this machine, I will use the dumped information to recreate the the migrated TCP connection. Does anyone have an example or tutorial in c language?
I am aware about different solutions like SockMi which provides Kernel Module + User Space APIs to migrate a certain TCP Socket. However, I want to use CRIU tools since it is part of Linux Mainline.
Right now we only have the TCP migration functionality integrated into CRIU tool. It sits in the sk-tcp.c file, the whole TCP-repair code is there, though it's bound to the rest of CRIU.
On the other hand, we've been asked for TCP-only migration for quite a while, it's possible to pull this code into smth like libcriutcp.so, but it will require patching. You're welcome to participate to the https://github.com/xemul/criu/issues/72

Any HTTP library in C that allows direct communication with the server?

Do you know of any HTTP client library in C (with SSL support) that also allows direct communication with the remote server?
I have a client-server application where the client uses HTTP to start a session in the server and then tells the server to switch the connection from HTTP to a different protocol. All communication is encapsulated in SSL. It is written in Perl and works well, but I'm looking into implementing the client in C.
I know libcurl gives you access to the underlaying socket but it's not enough because of the SSL requirement.
Notice that libcurl doesn't do the SSL part by itself, it uses OpenSSL. So, if you can get the socket handle from libcurl after the first HTTP interactions, AND the session key it uses (some spelunking required) you can go on directly with OpenSSL from that point.
I think that you must be looking for this otherwise you must have to write it yourself, like this
Sounds like you want Web Sockets. Don't know if there's a C library available though. I would assume there is, if you dig.

Custom Application Encryption

I am currently looking to add encryption to a server application (programmed in C) that passes raw data, unencrypted data over TCP to clients (a large number of different applications programmed in many different languages).
What is the best way to do this? Public-key cryptography? If so, how would the process go?
Thanks!
If you have to ask, you're probably not qualified to be doing cryptographic work. It is far to easy to make a subtle mistake in crypto processing that breaks your entire system's security, and unlike most other bugs, it is not at all obvious until someone else breaks your system.
Just use SSL (aka TLS). The folks that designed the SSL/TLS specs and libraries have already done all the hard work for you.
SSL: secure socket layers, which initiates and transmits encrypted data.
TLS: transport layer security, which asks to starttls and the answer to that is a list of capabilities, then the transmission can continue using the best mutually accepted encryption.
Note: the capabilities may include cleartext.
I suggest reading upon how to extend your existing protocol to support TLS, by looking at an example, say, the smtp starttls( rfc 2487 ). your time invested will be rewarded.
OpenSSL suits my needs! A quick view at the documentation and tutorials pointed me in the right direction.

Why is separate getaddrinfo-like() + connect() not refactored into a (theoretical) connect_by_name()?

Most of the applications I've seen that use TCP, do roughly the following to connect to remote host:
get the hostname (or address) from the configuration/user input (textual)
either resolve the hostname into address and add the port, or use getaddrinfo()
from the above fill in the sockaddr_* structure with one of the remote addresses
use the connect() to get the socket connected to the remote host.
if fails, possibly go to (3) and retry - or just complain about the error
(2) is blocking in the stock library implementation, and the (4) seems to be most frequently non-blocking, which seems to give a room for a lot of somewhat similar yet different code that serves the purpose to asynchronously connect to a remote host by its hostname.
So the question: what are the good reasons not to have the additional single call like following:
int sockfd = connect_by_name(const char *hostname, const char *servicename)
?
I can come up with three:
historic: because that's what the API is
provide for custom per-application policy mechanism for address selection/connection retry: this seems a bit superficial, since for the common case ("get me a tube to talk to remote host") the underlying OS should know better
provide the visual feedback to the user about the exact step involved ("name resolution" vs "connection attempt"): this seems rather important, lookup+connection attempt may take time
Only the last of them seems to be compelling enough to rewrite the resolve/connect code for every client app (as opposed to at least having and using a widely used library that would implement the connect_by_name() semantics in addition to the existing sockets API), so surely there should be some more reasons that I am missing ?
(one of the reasons behind the question is that this kind of API would appear to help the portability to IPv6, as well as possibly to other stream transport protocols significantly)
Or, maybe such a library exists and my google-fu failed me ?
(edited: corrected the definition to look like it was meant to look, thanks LnxPrgr3)
Implementing such an API with non-blocking characteristics within the constraints of the standard library (which, crucially, isn't supposed to start its own threads or processes to work asynchronously) would be problematic.
Both the name lookup and connecting part of the process require waiting for a remote response. If either of these are not to block, then that requires a way of doing asychronous work and signalling the change in state of the socket to the calling application. connect is able to do this, because the work of the connect call is done in the kernel, and the kernel can mark the socket as readable when the connect is done. However, name lookup is not able to do this, because the work of a name lookup is done in userspace - and without starting a new thread (which is verboten in the standard library), giving that name lookup code a way to be woken up to continue work is a difficult problem.
You could do it by having your proposed call return two file descriptors - one for the socket itself, and another that you are told "Do nothing with this file descriptor except to check regularly if it is readable. If this file descriptor becomes readable, call cbn_do_some_more_work(fd)". That is clearly a fairly uninspiring API!
The usual UNIX approach is to provide a set of simple, flexible tools, working on a small set of object types, that can be combined in order to produce complex effects. That applies to the programming API as much as it does to the standard shell tools.
Because you can build higher level APIs such as the one you propose on top of the native low level APIs.
The socket API is not just for TCP, but can also be used for other protocols that may have different end point conventions (i.e. the Unix-local protocol where you have a name only and no service). Or consider DNS which uses sockets to implement itself. How does the DNS code connect to the server if the connection code relies on DNS?
If you would like a higher level abstraction, one library to check out is ACE.
There are several questions in your question. For instance, why not
standardizing an API with such connect_by_name? That would certainly
be a good idea. It would not fit every purpose (see the DNS example
from R Samuel Klatchko) but for the typical network program, it would
be OK. A paper exploring such APIs is "Simplifying Internet Applications Development
With A Name-Oriented Sockets Interface" by Christian Vogt. Note
that another difficulty for such an API would be "callback"
applications, for instance a SIP client asking to be called back: the
application has no easy way to know its own name and therefore often
prefer to be called back by address, despite the problems it make, for
instance with NAT.
Now, another question is "Is it possible to build such
connect_by_name subroutine today?" Partly yes (with the caveats
mentioned by caf) but, if written in userspace, in an ordinary
library, it would not be completely "name-oriented" since the Unix
kernel still manages the connections using IP addresses. For instance,
I would expect a "real" connect_by_name routine to be able to
survive renumbering (for instance because a mobile host renumbered),
which is quite difficult to do in userspace.
Finally, yes, it already exists a lot of libraries with similar
semantics. For a HTTP client (the most common case for a program whose
network abilities are not the main feature, for instance a XML
processor), you have Neon and libcURL. With libcURL, you can
simply write things like:
#define URL "http://www.velib.paris.fr/service/stationdetails/42"
...
curl_easy_setopt(curl, CURLOPT_URL, URL);
result = curl_easy_perform(curl);
which is even higher-layer than connect_by_name since it uses an
URL, not a domain name.

Runtime information in C daemon

The user, administrators and support staff need detailed runtime and monitoring information from a daemon developed in C.
In my case these information are e.g.
the current system health, like throughput (MB/s), already written data, ...
the current configuration
I would use JMX in the Java world and the procfs (or sysfs) interface for a kernel module. A log file doesn't seem to be the best way.
What is the best way for such a information interface for a C daemon?
I thought about opening a socket and implementing a bare-metal http or xmlrpc server, but that seems to be overkill. What are alternatives?
You can use a signal handler in your daemon that reacts to, say USR1, and dumps information to the screen/log/net. This way, you can just send the process a USR1 signal whenever you need the info.
You could listen on a UNIX-domain socket, and write regularly write the current status (say once a second) to anyone who connects to it. You don't need to implement a protocol like HTTP or XMLRPC - since the communication will be one-way just regularly write a single line of plain text containing the state.
If you are using a relational database anyway, create another table and fill it with the current status as frequent as necessary. If you don't have a relational database, write the status in a file, and implement some rotation scheme to avoid overwriting a file that somebody reads at that very moment.
Write to a file. Use a file locking protocol to force atomic reads and writes. Anything you agree on will work. There's probably a UUCP locking library floating around that you can use. In a previous life I found one for Linux. I've also implemented it from scratch. It's fairly trivial to do that too.
Check out the lockdev(3) library on Linux. It's for devices, but it may work for plain files too.
I like the socket idea best. There's no need to support HTTP or any RPC protocol. You can create a simple application specific protocol that returns requested information. If the server always returns the same info, then handling incoming requests is trivial, though the trivial approach may cause problems down the line if you ever want to expand on the possible queries. The main reason to use a pre-existing protocol is to leverage existing libraries and tools.
Speaking of leveraging, another option is to use SNMP and access the daemon as a managed component. If you need to query/manage the daemon remotely, this option has its advantages, but otherwise can turn out to be greater overkill than an HTTP server.

Resources