boost::asio send get request after ssl connection - c++

I'm using boost::asio and I've been looking at the example code on how to connect to an ssl host. But I want to send a get request after I've connected to the server through ssl, how is this possible? Do I send a get request as the http example do exactly?

After the handshake is done (handle_handshake in the example) and there was no errors, you should be able to use the connection just as any other Boost ASIO connection.

Related

Establish http connection through seperate tcp stream

I am working on Client Server application. Client side uses Windows Networking API's to establish connection with server. There are many HTTP requests I am requesting,which can use persistent connection. However for one HTTP Request I have to send it through seperate TCP stream,how can I achieve this? Currently my HTTP request is using the already used TCP stream which is causing issue. I have control on client code,so is there any header I can include to make sure http request does not share the connection
WinHttpSetOption(handle, WINHTTP_OPTION_MAX_CONNS_PER_SERVER, &maxConnections,
sizeof(maxConnections));

SSL tunnel with Boost::Beast

I want to connect to a proxy server that only allows HTTP connections, to speak with the target server by HTTPS.
The proxy server documentation states that the only way to do that is by means of the HTTP Connect verb (they are planning to add direct HTTPS connections to the proxy server itself, but for the moment only HTTP connections are allowed).
In my C++ program, I successfully connected and worked with the target server using ssl_stream's during a couple of months, using boost::asio without boost::beast, but I want now to use a proxy using boost::beast to make things easier; so, I now how to work with boost::asio but I'm a boost::beast newbie (and I don't fully understand how SSL works either).
The think is that, in my understanding, when you use a ssl_stream, you encript the whole communication, however, what I need now is to insert the encrypted message within the CONNECT HTTP body, and I don't know how to do that.
I've readed that this has something to do with the lowest_layer/next_layer thing but I'm not sure.
Could anybody provide an example of a full read/write connection with a proxy-server? or at least further clarifications?
Declare a variable for the connection (ioc is the io_context)
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> stream{ioc};
Build a CONNECT HTTP request message (req) using Beast
Send the request to the proxy in plain-text (note next_layer())
boost::beast::http::write(stream.next_layer(), req);
Read the HTTP response from the proxy
If the response has OK status, the tunnel is established
Now perform the SSL handshake:
stream.handshake(boost::asio::ssl::stream_base::client);
At this point you can write HTTP requests to stream and read HTTP responses from stream using Beast as normal (do not use next_layer() again).

how is the http CONNECT request behaviour?

Recently i started to write a proxy(web debugging) software.
and handled the GET request well.
sometimes i get CONNECT messages from the client, so i connect to the target server and reply the client by "200 Connection Established".
is that it all??
because after it i don't get any messages
from the server or the client.
so i got confused.
I want to know all the steps of https CONNECT message request and responses until an https site(like https://google.com) gets loaded.
Thank you.
The CONNECT request is used to set up a connection tunnel. This is used mainly to allow access to https sites through an http proxy.
The web proxy is expected to set up a proxy connection to the indicated host, and then proxy the traffic between the two connections, until one or the other terminates.
After establishing the connection, you expect to see either the client or the server start sending something to the other. Your proxy code should be prepared, at any time, to receive more data from either the client or the server, to be forwarded to the other party. If not, your proxy is not doing something correctly. It is not your proxy's job to handle https negotiation. Once the connection is established, your proxy must transparently proxy all the data, and it is the client's and the server's task to talk https with each other.

OpenSSL: HTTPS proxy

So far, my proxy only deals HTTP connections on port 80: I'd like to improve it and make it manage HTTPS requests. Here's how it works:
the proxy is listening on a given port; Chrome can "see" the proxy thanks to SwitchyOmega plugin and connect the traffic on that given port.
The proxy reads the packet's header, gets the request (I parse only GET requests until now), e.g. GET http://www.google.it HTTP/1.1, gets the hostname parsing www.google.it, finds the IP address by resolving the hostname with gethostbyname and assumes the server port is number 80.
Now the proxy send to the server what it received from client by opening a socket: this socket is opened, binded, and then connected to the IP address I resolved before from the hostname.
I read here how to turn a socket into an SSL socket: after socket, bind, listen and accept syscalls, set what you need and pass the socket's file descriptor to SSL_set_fd so I can read and write data through the new SSL file descriptor.
What (most above all) bothers me is the creation of SSL context: if SSLv23_server_method is for servers and SSLv23_client_method is for clients, what should I use for my proxy?
I found no particular proxies configuration in OpenSSL documentation.
Thanks in advance for your help.
Edit: more detailed info about how the proxy works.
SSL/TLS has no concept of proxies, only point-to-point connections. Your proxy has a connection to the client, and a separate connection to the target server, and it is simply passing data between the two connections as needed. So the proxy has to secure (or not) those connections independently of each other, and how it must do that depends on how the client is asking the proxy to relay HTTP.
If the client sends a GET/POST/etc request to your proxy requesting an absolute HTTP URL, your proxy needs to connect to the target server without using SSL/TLS, and then relay the client's HTTP request and server's response back and forth. The client may or may not connect to your proxy using SSL/TLS. If it does, that session is only between the client and your proxy, and the data read from, and sent to, the client is encrypted/decrypted accordingly.
If the client sends a GET/POST/etc request to your proxy requesting an absolute HTTPS URL, your proxy needs to connect to the target server and establish its own SSL/TLS session with the server, and then relay the client's HTTP request and server's response back and forth. The proxy is acting as a client to the server, so use a client-based method (sslv23_client_method(), etc). The real client may or may not connect to your proxy using SSL/TLS. If it does, that session is only between the client and your proxy, and the data read from, and sent to, the client is encrypted/decrypted accordingly, separate from the encryption used on the server connection.
If the client sends a CONNECT request to your proxy, the proxy needs to connect to the requested host/port and then pass raw data back and forth as-is. No SSL/TLS is involved on the proxy's part. If the proxy handled the client's or server's SSL/TLS data, it would be acting as a MITM attacker, something SSL/TLS is designed to prevent. If the connection to the server is successful, the client and server (not the proxy) would secure their respective endpoints with SSL/TLS so they are talking to each other directly (needed for exchanging certificates and keys, and validating identities). The SSL/TLS handshake, and subsequent encrypted HTTP request/response data, would pass through the proxy as-is. The proxy would only be able to see the raw encrypted data, not the HTTP data, since only the client and server have the keys needed to decrypt the data.

Https server with cpp-netlib

How can one use cpp-netlib to implement a HTTPS-server?
cpp-netlib can be used as a HTTP server (see service selector, handler and main in my example code).
With boost::asio setting up a SSL connection is not too hard (see my attempt at SSL).
cpp-netlib accepts a boost::asio::io_service via the options provided to the constructor (cpp-netlib reference)
The following questions stop me from combining asio SSL and cpp-netlib:
Both SSL via asio and cpp-netlib use an asio acceptor that listens to a port (e.g. 80 or 443) and then a separate session for the actual connection.
I assume that for HTTPS:
You use the asio ssl acceptor
Which instantiates a connection
Then perform the SSL handshake over this connection, and finally
Have cpp-netlib serve HTTP over this connection
But how can I separate cpp-netlib's HTTP connection handler from the acceptor is uses?
Or does one pass a io_service from the asio SSL connection? If so, which one? Or are they all the same?
Or is there a completely different route to take?
A long shot, but have you tried the following:
#define BOOST_NETWORK_ENABLE_HTTPS
before including the boost network http client.
Make sure OpenSSL is in the compiler path.
The most recent release of cpp-netlib contains a working example. You'll find it in cpp-netlib-0.11.1RC2/libs/network/example/http/ssl. The github files are there:
https://github.com/cpp-netlib/cpp-netlib/tree/0.11-devel/libs/network/example/http/ssl
You have to use an async_server.