Secured SSL connection Error: unknown protocol | bad hostname lookup - c++

Iam downloading RSS feed file (eg. https://tools.ietf.org/dailydose/dailydose_atom.xml) from server via HTTP.
First, i have to connect to the remote server via OpenSSL, as described here.
Unsecured version works just fine and i can connect and receive HTTP answer with feeds:
bio = BIO_new_connect("www.tools.ietf.org:80");
if(bio == NULL)
{
/* Handle the failure */
}
if(BIO_do_connect(bio) <= 0)
{
/* Handle failed connection */
}
Secured version:
BIO * m_bio;
SSL_CTX * m_ctx;
SSL * m_ssl;
SSL_library_init();
m_ctx = SSL_CTX_new(SSLv23_client_method());
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
SSL_CTX_set_default_verify_paths(m_ctx);
m_bio = BIO_new_ssl_connect(m_ctx);
BIO_get_ssl(m_bio, &m_ssl);
SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY);
BIO_set_conn_hostname(m_bio, "www.tools.ietf.org:80");
if (BIO_do_connect(m_bio) <= 0)
{
printf("Error: %s\n", ERR_reason_error_string(ERR_get_error()));
throw std::runtime_error("FEEDREADER: Connection failed.");
}
if(SSL_get_verify_result(m_ssl) != X509_V_OK)
{
throw std::runtime_error("FEEDREADER: Verification failed.");
}
Where do_connect fails with following error:
Error: unknown protocol
when i replace www.tools.ietf.org with http(s)://www.tools.ietf.org
another error appears:
Error: bad hostname lookup
But hostname & dns works well for unsecured version, so may somebody help me with this one ?

80 is the default HTTP port. 443 is the default HTTPS port.
bio = BIO_new_connect("www.tools.ietf.org:443");
BIO_set_conn_hostname(m_bio, "www.tools.ietf.org:443");

Related

Using CURLOPT_CONNECT_TO with an IPv6 address

I am attempting to use curl's CURLOPT_CONNECT_TO option to connect to a specific address (rather than the result of the DNS lookup of the host part of the url):
CURL * r_curl = NULL;
struct curl_slist * r_connect = NULL;
char connectStr[128];
if (af == AF_INET) {
sprintf(connectStr, "::%s:", ipAddrString);
} else if (af == AF_INET6) {
/* in [] per https://curl.haxx.se/libcurl/c/CURLOPT_CONNECT_TO.html */
sprintf(connectStr, "::[%s]:", ipAddrString);
}
fprintf(stderr, "DEBUG: connect '%s', url %s\n", connectStr, url);
r_curl = curl_easy_init();
...
r_connect = curl_slist_append(r_connect, connectStr);
curl_easy_setopt(r_curl, CURLOPT_CONNECT_TO, r_connect);
curl_easy_setopt(r_curl, CURLOPT_URL, url);
curl_easy_perform(r_curl);
When af is AF_INET and ipAddrSring is an IPv4 address this works perfectly. When af is AF_INET6 and ipAddrSring is an IPv6 address, curl looks like it is trying to do a DNS host lookup on the IPv6 address:
DEBUG: connect '::129.186.23.166:', url http://www.iastate.edu/
* Connecting to hostname: 129.186.23.166
* Trying 129.186.23.166...
* TCP_NODELAY set
* Connected to 129.186.23.166 (129.186.23.166) port 80 (#0)
vs
DEBUG: connect '::[2610:130:101:104::2]:', url http://www.iastate.edu/
* Connecting to hostname: 2610:130:101:104::2
* Could not resolve host: 2610:130:101:104::2
What I am doing wrong here?
(Curl is version 7.56.1)
There was a bug in libcurl (before 7.58.0) which made it take IPv6 addresses and attempt to use them for CURLOPT_CONNECT_TO, even if it was built without support for IPv6!
This was addressed in curl 7.58.0 and from then on it makes libcurl return an error if this is attempted!
Answer: Curl Library was built w/o IPv6 support.
I'm thinking that maybe that should result in a more meaningful error message.

How to enable ActiveMQ SSL authentication using C client

I am trying to connect a C client with activeMQ using ssl.For this I created certificates using the following link.
Also I confiugured activeMQ with transport connectors as:
<transportConnector name="ssl" uri="mqtt+ssl://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
The portion of C client uisng SSL is as follows:
MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
ssl_opts.enableServerCertAuth = 0;
conn_opts.ssl = &ssl_opts;
conn_opts.ssl->keyStore = "/home/user/certs/client-chain.pem";
conn_opts.ssl->privateKeyPassword = "password";
conn_opts.ssl->enabledCipherSuites = "DEFAULT";
MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered);
if ((rc = MQTTClient_connect(client, &conn_opts))!=MQTTCLIENT_SUCCESS)
{
printf("%d",rc);
}
But when I connect a C client to activeMQ I get connect failed return code -1 error...Kindly help me to fix this issue

gSOAP SSL - converting existing code to ssl

The earlier Version of this question got no Response, so I'm updating the entire Thing:
I have a test gSOAP Client and server on my machine. The client does an MTOM upload of various files to the server.
When attempting to convert the code to ssl I get the following error:
The server reports:
"SSL_ERROR_SSL
error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher"
The client reports:
An SSL error occured
SOAP 1.2 fault SOAP-ENV:Receiver [no subcode]
"SSL_ERROR_SSL
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure"
Detail: SSL_connect error in tcp_connect()
it runs without the "SSL" option. Can someone advise me as to what I'm doing wrong?
Applicable client code -
if(fSSL)
soap_ssl_init();
. . .
soap_init1(&my_soap, SOAP_ENC_MTOM); /* Enable MTOM */
. . .
if(fSSL)
{
if (soap_ssl_client_context(&my_soap,
SOAP_SSL_NO_AUTHENTICATION + SOAP_TLSv1_2,
NULL, // client keyfile
NULL, // passphrase for keyfile
NULL, // certified authority certificate
NULL, // directory for trusted certificates
NULL))// random data for seed
{
soap_print_fault(&my_soap, stderr);
...
}
}
...
long gsoap_status = soap_call___ns1__upload(&my_soap, endpoint.c_str(), NULL, &upload_parms, &upload_response);
Applicable server code -
if(fSSL)
soap_ssl_init();
. . .
soap_init1(&my_soap, SOAP_ENC_MTOM); /* Enable MTOM */
. . .
if(fSSL)
{
if (soap_ssl_server_context(&my_soap,
SOAP_SSL_NO_AUTHENTICATION + SOAP_TLSv1_2, // per EMAIL - option 1
NULL, // Keyfile - required for authentication
NULL, // passphrase
NULL, // password to read Keyfile
NULL, // optional cacert file
NULL, // DH Filename or DH key len bits
NULL, // Randfile
NULL)) // optional server identification (enable SSL session cache)
{
soap_print_fault(&my_soap, stderr);
exit(0);
}
}
. . .
my_soap.connect_timeout = 20;
my_soap.send_timeout = 60;
my_soap.recv_timeout = 60;
if(!soap_valid_socket(soap_bind(&my_soap, NULL, port, 100)))
{
soap_print_fault(&my_soap, stderr);
exit(1);
}
fprintf(stderr, "Bind to port %d successful\n", port);
// server loop starts
for (;;)
printf("server loop sta\n");
int t_socket = soap_accept(&my_soap);
struct soap* t_soap = 0;
t_soap = soap_copy(&my_soap);
if(fSSL)
{
if(soap_ssl_accept(&my_soap)) <------ FAILS HERE
{
printf("NOT Accepting (ssl) socket=%d connection from IP: %d.%d.%d.%d ...", t_socket,
(int)my_soap.ip>>24&0xFF,
(int)my_soap.ip>>16&0xFF,
(int)my_soap.ip>>8&0xFF,
(int)my_soap.ip&0xFF);
soap_print_fault(&my_soap, stderr);
soap_destroy(&my_soap);
soap_end(&my_soap);
continue;
}
}
. . .
if(soap_serve(&my_soap))
...
Server Console output:
Bind to port 8080 successful
server loop sta
NOT Accepting (ssl) socket=364 connection from IP: 127.0.0.1 ...Error 30 fault is internal [no subcode]
"SSL_ERROR_SSL
error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher"
Detail: SSL_accept() failed in soap_ssl_accept()
I'm working on this now. I think the errors that you are seeing are because most/all distributions of openSSL do not support anonymous authentication any longer due to man in the middle attacks. A self-signed certificate on the server-side may be the only way to make these examples work.

InternetConnect fails to connect to FTP server via ftp proxy

I am trying to connect to FTP server using WinGate FTP Proxy. The InternetOpen() executes successfully returning appropriate handle in all cases.
In case Proxy Authentication is OFF, InternetConnect() returns proper handle and I can proceed with further ftp operations but in case Proxy Authentication is ON, InternetConnect() returns NULL.
On MSDN they have mentioned for proxies use InternetSetOption() with INTERNET_OPTION_PROXY_USERNAME and INTERNET_OPTION_PROXY_PASSWORD flags to set proxy username and password on handle returned by InternetConnect, but it's returning NULL and on printing GetLastError(), I get the following message:
InternetConnect failed: 12014
220 WinGate Engine FTP Gateway ready
331 send password
530 Auth Failed
if ((hHandle=InternetOpen("Upload", INTERNET_OPEN_TYPE_PROXY, "ftp=ftp://<servername>:<port>", NULL, 0)) == NULL)
{
printf("InternetOpen failed: %d", GetLastError());
printInternetErrorMsg(function);
return false;
}
char buffer[1024];
string proxy_username,proxy_password;
// get ftp proxy username and password
// ..
if ((m_itConnect=InternetConnect(hHandle, ftpserver, INTERNET_DEFAULT_FTP_PORT, ftpusrname, ftppasswd, INTERNET_SERVICE_FTP, NULL, NULL)) == NULL){
printf("InternetConnect failed: %d", GetLastError());
printInternetErrorMsg(function);
//Internet Connect Fails with following error when Proxy Authentication is ON
//InternetConnect failed: 12014
//220 WinGate Engine FTP Gateway ready
//331 send password
//530 Auth Failed
return false;
}
strcpy(buffer,proxy_username.c_str());
if ( !InternetSetOption (m_itConnect, INTERNET_OPTION_PROXY_USERNAME, (LPVOID) buffer, lstrlen (buffer) ))
{
printf("Unable to set proxy authetication settings (username). Error returned: %d", GetLastError() );
return false;
}
strcpy(buffer, proxy_password.c_str());
if ( !InternetSetOption (m_itConnect, INTERNET_OPTION_PROXY_PASSWORD, (LPVOID) buffer, lstrlen (buffer) ))
{
printf("Unable to set proxy authetication settings (password). Error returned: %d", GetLastError() );
return false;
}
}
printf("InternetConnect successful ...");
return true;
Any help is appreciated.
Thanks in Advance.
the problem is you are connecting to an FTP proxy, rather than an HTTP proxy. So you're getting an FTP welcome string back.
When working through a proxy using WinInet, FTP is done over HTTP. The client makes an HTTP request to the HTTP proxy for an FTP URL. the HTTP proxy acts as an FTP client to the FTP server, and translates the response back to HTTP for the client. Strange but true.
So you need to change the proxy port to be the HTTP proxy in WinGate.

How can you force a web service client to use a specific port?

Is it possible to force an web service client to talk from a specific range of port E.g. 4900- 4999 to a web server in port 80?
I understand now that there is client and server port numbers and need to create a client application to send http statuses to a web server but firewall team only opens ports 4900 to 4999 in the client.
Any ideas?
If you are using a web browser to connect to your server then you may be out of luck but as you said in your question that you are creating a client application you can do this with the bind system call in both Windows and Linux (this code is in C):
struct sockaddr_in client;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
memset(&client, 0, sizeof(client));
client.sin_family = AF_INET;
client.sin_addr.s_addr = htonl(INADDR_ANY);
client.sin_port = htons(4901);
Then call bind:
res = bind(sock, (struct sockaddr *)&client, sizeof(client));
If this call is successful (res is 0) you can then connect your socket to the server and you will be connecting from port 4901.
In case someone else needs it, here is the Python code to do that:
#!/usr/bin/env python
from socket import *
import time
HOST = '**.**.**.**' # IP of the server
PORT = 8080
GET = '/hello/There'
BUFSIZ = 1024
ADDR = (HOST, PORT)
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(('',4925))
sock.connect(ADDR)
print 'connected'
request = """GET %s HTTP/1.0\n
Host: %s\n
User-Agent: Python\n
\n""" % (GET, HOST)
sock.send(request)
data = sock.recv(1024)
string = ""
while len(data):
string = string + data
data = sock.recv(1024)
print string
sock.close()
This is working with a wsgi server running on the other side. Pretty straight forward. Thanks for the help.