Sending Email With libcurl fails Over Exchange Server - c++

I am attempting to send a simple email message using libcurl in C++ over a MS Exchange server. The program seems to connect with the server, authenticate correctly, but fails with error 500 - unknown command when attempting to send the package.
I have verified the server address, that libcurl was compiled with SSL support, NTLM is supported authentication type, and all the email addresses are valid.
Checking the CURL version returns:
curl 7.37.1 (armv5tejl-unknown-linux-gnueabi) libcurl/7.37.1 OpenSSL/0.9.8o zlib/1.2.3.4
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: IPv6 Largefile NTLM NTLM_WB SSL libz
And the program reports the following:
* Rebuilt URL to: mail.domain.net:587/
* Hostname was NOT found in DNS cache
* Trying 192.168.0.114...
* Connected to mail.domain.net (192.168.0.114) port 587 (#0)
* Server auth using NTLM with user 'redmine'
> PUT / HTTP/1.1
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
Host: mail.iem.net:587
Accept: */*
Content-Length: 0
220 mail.domain.net Microsoft ESMTP MAIL Service ready at Fri, 22 Aug 2014 15:20:09 -0400
500 5.3.3 Unrecognized command
500 5.3.3 Unrecognized command
500 5.3.3 Unrecognized command
500 5.3.3 Unrecognized command
500 5.3.3 Unrecognized command
421 4.7.0 Too many errors on this connection, closing transmission channel
* Connection #0 to host mail.iem.net left intact
I'm using the following connection settings in the program:
curl_easy_setopt(this->curl,CURLOPT_URL, this->address.c_str());
curl_easy_setopt(this->curl,CURLOPT_USERNAME,this->username.c_str());
curl_easy_setopt(this->curl,CURLOPT_PASSWORD,this->username.c_str());
curl_easy_setopt(this->curl,CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt(this->curl,CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_easy_setopt(this->curl,CURLOPT_USE_SSL, CURLUSESSL_ALL);
curl_easy_setopt(this->curl,CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(this->curl,CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(this->curl,CURLOPT_UPLOAD, 1L);
curl_easy_setopt(this->curl, CURLOPT_VERBOSE, 1L);
Any suggestions would be greatly appreciated!

Related

Libcurl no support for https but curl does

When I run curl -V my output is this
curl 7.82.0-DEV (x86_64-pc-win32) libcurl/7.82.0-DEV OpenSSL/1.1.1m WinIDN
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS HSTS HTTPS-proxy IDN IPv6 Kerberos Largefile NTLM SPNEGO SSL SSPI UnixSockets alt-svc
Https is clearly there. When I use it through c++, by using curl_version_info_data
curl_version_info_data* ver = curl_version_info(CURLVERSION_NOW);
for (int i = 0; i < 14; ++i) {
cout << ver->protocols[i] << endl;
}
The supported protocols listed are
dict
file
ftp
gopher
http
imap
ldap
mqtt
pop3
rtsp
smb
smtp
telnet
tftp
If I try using https, I get the error Unsupported protocol. Anyone get any ideas?
I figured it out, when running I tried fixing by grabbing libcurl.lib and libcurl_imp.lib from a precompiled version of Curl (I had two versions installed). The precompiled version did not have support for https. I read the FAQ here https://curl.se/docs/faq.html and properly linked the static library. Afterwards, it worked fine.

libcurl HTTPS enabled but not usable

For our project we build libcurl from scratch over cmake. The libcurl-configure-out.log tells me it enabled HTTPS (among others), heres the important part about that:
-- Enabled features: SSL IPv6 unixsockets AsynchDNS Largefile alt-svc HSTS NTLM HTTPS-proxy
-- Enabled protocols: DICT FILE FTP FTPS GOPHER GOPHERS HTTP HTTPS IMAP IMAPS LDAP MQTT POP3 POP3S RTSP SCP SFTP SMB SMBS SMTP SMTPS TELNET TFTP
-- Enabled SSL backends: OpenSSL
But when I try to set a TLS version in our code, it says "CURLE_NOT_BUILT_IN"
const CURLcode state = curl_easy_setopt(this->m_curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
// state == 4 aka "CURLE_NOT_BUILT_IN"
I also tried to verify over the curl executable, which kinda gives me the same impression
C:<snip>\build\ex_libcurl-prefix\src\ex_libcurl-build\src\Debug>curl.exe --version
curl 7.80.0 (Windows) libcurl/7.80.0 libssh2/1.10.0
Release-Date: 2021-12-10
Protocols: dict file ftp gopher http imap ldap mqtt pop3 rtsp scp sftp smb smtp telnet tftp
Features: AsynchDNS HSTS IPv6 Largefile NTLM UnixSockets alt-svc
Where did I go wrong?
Edit: Some more parts about SSL beeing enabled:
-- Found OpenSSL: optimized;C:/Program Files/OpenSSL-Win64/lib/VC/libcrypto64MD.lib;debug;C:/Program Files/OpenSSL-Win64/lib/VC/libcrypto64MDd.lib (found version "3.0.0")
-- Looking for openssl/crypto.h
-- Looking for openssl/crypto.h - found
-- Looking for cldap_open in wldap32;winmm;ws2_32;OpenSSL::SSL;OpenSSL::Crypto
-- Looking for cldap_open in wldap32;winmm;ws2_32;OpenSSL::SSL;OpenSSL::Crypto - found

Protocol https not supported or disabled in libcurl in Redhat Linux 8

I have an C++ application which is using curl 7.61.1 version.
while trying to connect to device using ssl I get this error:
"Protocol https not supported or disabled in libcurl"
although the default curl version installed in RHEL8 supports https
curl --version
curl 7.61.1 (x86_64-redhat-linux-gnu) libcurl/7.61.1 OpenSSL/1.1.1 zlib/1.2.11 brotli/1.0.6 libidn2/2.0.5 libpsl/0.20.2 (+libidn2/2.0.5) libssh/0.8.3/openssl/zlib nghttp2/1.33.0
Release-Date: 2018-09-05
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz brotli TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL Metalink
please suggest how to configure/use curl with ssl in Redhat Linux 8

Kubernetes ingress on GKE results in 502 response on http / SSL_ERROR_SYSCALL on https

I've tested my configuration on minikube where it works perfectly, however on GKE I run into an error of HTTP responding with 502 while the HTTPS gets the connection terminated?
I have no idea how to diagnose this issue, which logs could I look at?
Here is a verbose curl log when accessing over https://
* Expire in 0 ms for 1 (transfer 0x1deb470)
* Expire in 0 ms for 1 (transfer 0x1deb470)
* Expire in 0 ms for 1 (transfer 0x1deb470)
* Trying 35.244.154.110...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x1deb470)
* Connected to chrischrisexample.de (35.244.154.110) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to chrischrisexample.de:443
* Closing connection 0
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to chrischrisexample.de:443
To solve it I had to:
Respond with a HTTP 200 on the health check (from the Google load balancer!)
Set a SSL certificate secret in the ingress (even if a self signed one)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Sync 14m (x20 over 157m) loadbalancer-controller Could not find TLS certificates. Continuing setup for the load balancer to serve HTTP. Note: this behavior is deprecated and will be removed in a future version of ingress-gce
Warning Translate 3m56s (x18 over 9m24s) loadbalancer-controller error while evaluating the ingress spec: could not find port "80" in service "default/app"; could not find port "80" in service "default/app"; could not find port "80" in service "default/app"; could not find port "80" in service "default/app"
These errors were shown on the kubectl describe ingress... Still doesn't make sense why it would error on the SSL handshake / connection though.

CURL receive "empty reply from server", but browser receive response. Why?

I set up rest-api server. (Django 1.11 + NGINX + Gunicorn + Postgresql 9.6)
For testing, I developed simple API. Get request URL /test, then respond "success" string. In web browser, it worked well.
But when I request same url with CURL, I receive "curl: (52) Empty reply from server". I tried curl on other remote server, and I tried curl http://127.0.0.1/test on that server. Both didn't not work. I received "curl: (52) Empty reply from server".
Why it work in web browser, and it not work in CURL? Where should I check? NGIMX? Django? I checked firewell.
Sorry for poor english. Thanks!
UPDATE:
I tried the following,
$ curl -vv http://127.0.0.1/test/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /test/ HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.58.0
> Accept: */*
>
* Empty reply from server
* Connection #0 to host 127.0.0.1 left intact
curl: (52) Empty reply from server
First add -vv to the curl command to see what is happening with the connection. If it says server redirection is happening, add -L to solve the problem.