Establish http connection through seperate tcp stream - c++

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));

Related

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.

boost::asio send get request after ssl connection

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.

How to ignore certain socket requests

I'm currently working on a TCP socket server in C++; and I'm trying to figure out how I can ignore all browser connections made to my server. Any idea's?
Thanks.
Need more details to give good feedback.
Are you going to be listening on port 80 but want to avoid all HTTP traffic? Or will your protocol be HTTP-based? Do you need to listen on 80 or can you pick any port?
If it's your own custom protocol (HTTP or not) you could just look at the first line sent up and if it's not to your liking just close() the socket.
EDIT:
Since you're going to be listening on a custom port, you probably won't get any browser traffic anyhow. Further, since you're going to be writing your own protocol, just require a handshake which establishes your client speaks your custom protocol and then ignore (close()) everything else.
Bonus points: depending on your goal, send back an HTTP error message which can be displayed to the user.
You can't stop a web-browser initiated tcp-session from connecting to your tcp server. You can (as stated above) close the connection once you've detected the client is trying to talk http to you (or any other unwanted application-layer protocol).
Just look at the differences between valid connection requests and invalid ones (i.e. dump both request types to examine each request), in your specific case, you'll want to look at the HTTP request header to ignore all such requests (assuming that valid requests do not make use of HTTP).