Copy link to clipboard
Copied
Hi all,
I am trying connect "HTTPS" server using Boost dlls. But when I send a request to the server it always returns "handshake: An existing connection was forcibly closed by the remote host" error. Please help me if anybody tried this. my code snippet is as below -
bool BscDlgDialogController::verify_certificate(bool preverified, boost::asio::ssl::verify_context& ctx)
{
CAlert::InformationAlert("verify_certificate");
char subject_name[256];
X509_STORE_CTX *cts = ctx.native_handle();
int32_t length = 0;
X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
int32_t depth = X509_STORE_CTX_get_error_depth(cts);
switch (cts->error)
{
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
//Debug(PRIORITY_ERROR, "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT");
break;
case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
//Debug(PRIORITY_ERROR, "Certificate not yet valid!!");
break;
case X509_V_ERR_CERT_HAS_EXPIRED:
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
//Debug(PRIORITY_ERROR, "Certificate expired..");
break;
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
//Debug(PRIORITY_WARN, "Self signed certificate in chain!!!\n");
preverified = true;
break;
default:
break;
}
const int32_t name_length = 256;
X509_NAME_oneline(X509_get_subject_name(cert), subject_name, name_length);
//CAlert::InformationAlert(subject_name);
return preverified;
}
std::string BscDlgDialogController::SendRequestToServer(const std::string& sRequestHdr,const std::string& sRequestBody,
std::ofstream& outFile)
{
std::string retstring("");
try {
std::string hostName = "d1.mediawide.com";
boost::system::error_code error = boost::asio::error::host_not_found;
boost::asio::io_service io_service;
// Create a context that uses the default paths for
// finding CA certificates.
ssl::context ctx(ssl::context::sslv23);
ctx.set_default_verify_paths();
// Get a list of endpoints corresponding to the server name.
tcp::resolver resolver(io_service);
tcp::resolver::query query(hostName, "https");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
// Try each endpoint until we successfully establish a connection.
ssl_socket socket(io_service, ctx);
boost::asio::connect(socket.lowest_layer(), endpoint_iterator);
socket.lowest_layer().set_option(tcp::no_delay(true));
// Perform SSL handshake and verify the remote host's
// certificate.
socket.set_verify_mode(boost::asio::ssl::verify_peer | ssl::verify_fail_if_no_peer_cert);
socket.set_verify_callback(boost::bind(&BscDlgDialogController::verify_certificate, this, _1, _2));
socket.handshake(ssl_socket::client);
//Create request
std::string reqHeader;
reqHeader.append("GET /api/User/Login?UserName=admin&Password=password HTTP/1.1\r\n");
reqHeader.append("Host: hostname.com\r\n");
reqHeader.append("Accept: */*\r\n");
reqHeader.append("Content-Type: application/json\r\n");
reqHeader.append("Connection: close\r\n\r\n");
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << reqHeader;
// Send the request.
boost::asio::write(socket, request);
// Read the response status line.
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
// Check that response is OK.
std::istream response_stream(&response);
std::string http_version;
response_stream >> http_version;
if (!response_stream || http_version.substr(0, 5) != "HTTP/") {
retstring.clear();
retstring.append("Error:Invalid response.");
return retstring;
}
unsigned int status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (status_code != 200)
{
if(status_code != 202)
{
retstring.clear();
retstring.append("Error:");
retstring.append(status_message);
return retstring;
}
}
// Read the response headers, which are terminated by a blank line.
boost::asio::read_until(socket, response, "\r\n\r\n");
// Process the response headers.
std::string header, resHeader;
while(std::getline(response_stream, header) && header != "\r")
resHeader += header;
// Write whatever content we already have to output.
if (response.size() > 0) {
outFile << &response;
}
// Read until EOF, writing data to output as we go.
while (true) {
size_t n = boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error);
if (!error)
{
if(n)
outFile << &response;
}
if (error == boost::asio::error::eof)
break;
if (error)
throw boost::system::system_error(error);
}
}
catch (std::exception& e)
{
retstring.clear();
retstring.append("Exp: ");
retstring.append(e.what());
}
return retstring;
}
Copy link to clipboard
Copied
I have not used Boost Library to make HTTPS calls, but used i think openssl in a CS5 plugin and it did work just fine. Looking at the error that you get it seems something that the server logs might help. Maybe the version of SSL protocol/ cipher mismatch be the culprit. Looking at the server is the first thing i would do if i have access to it, or else try with another server.
-Manan
Copy link to clipboard
Copied
Hi Manan,
I was able to fixed above issue with the openssl libs. But now, after upgrading server with latest configuration I'm again facing same handshake issue while log-in. Before it was working with the SSL protocol, but now it doesn't work with the TLS protocol. Do I need to handle/change the code for TLS protocol?
Please let me know if you require any information from side.