本文主要是介绍libcurl:Protocol smtps not supported or disabled in libcurl,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
libcurl:Protocol “smtps” not supported or disabled in libcurl
在使用libcurl来作为MUA时,开启DEBUG模式,使用smtps协议,在运行时报错:
libcurl:Protocol “smtps” not supported or disabled in libcurl
原因在于,安装libcurl时没有带着openssl。
安装包:curl-7.56.1.tar.gz
错误安装:
[jiang@localhost curl-7.56.1]$ ./configure --prefix=$HOME/libcurl
checking whether to enable maintainer-specific portions of Makefiles... no
……
configure: WARNING: SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.
configure: WARNING: Use --with-ssl, --with-gnutls, --with-polarssl, --with-cyassl, --with-nss, --with-axtls, --with-winssl, or --with-darwinssl to address this.
……
configure: Configured to build curl/libcurl:curl version: 7.56.1Host setup: x86_64-pc-linux-gnuInstall prefix: /home/jiang/libcurlCompiler: gccSSL support: no (--with-{ssl,gnutls,nss,polarssl,mbedtls,cyassl,axtls,winssl,darwinssl} )SSH support: no (--with-libssh2)zlib support: no (--with-zlib)GSS-API support: no (--with-gssapi)TLS-SRP support: no (--enable-tls-srp)resolver: POSIX threadedIPv6 support: enabledUnix sockets support: enabledIDN support: no (--with-{libidn2,winidn})Build libcurl: Shared=yes, Static=yesBuilt-in manual: enabled--libcurl option: enabled (--disable-libcurl-option)Verbose errors: enabled (--disable-verbose)SSPI support: no (--enable-sspi)ca cert bundle: /etc/pki/tls/certs/ca-bundle.crtca cert path: noca fallback: noLDAP support: no (--enable-ldap / --with-ldap-lib / --with-lber-lib)LDAPS support: no (--enable-ldaps)RTSP support: enabledRTMP support: no (--with-librtmp)metalink support: no (--with-libmetalink)PSL support: no (libpsl not found)HTTP2 support: disabled (--with-nghttp2)Protocols: DICT FILE FTP GOPHER HTTP IMAP POP3 RTSP SMTP TELNET TFTP
通常在./configure生成makefile这一步,我都基本不看,能生成makefile即可,然后直接编译安装。
ATTENTION:实际应该仔细确认summary这一部分,可能存在一些潜在的运行时问题。
继续进行编译安装:
[jiang@localhost curl-7.56.1]$ make && make install
OK,到此libcurl就安装完毕。
Code:
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>#define FROM_ADDR "<1158801411@qq.com>"
#define TO_ADDR "<jiangjinwang@ebupt.com>"#define FROM_MAIL "1158801411@qq.com" FROM_ADDR
#define TO_MAIL "jiangjinwang@ebupt.com" TO_ADDRstatic const char *payload_text[] = {"To: " TO_MAIL "\r\n","From: " FROM_MAIL "\r\n","Subject: SMTP example message\r\n","\r\n", /* empty line to divide headers from body, see RFC5322 */"The body of the message starts here.\r\n","\r\n","It could be a lot of lines, could be MIME encoded, whatever.\r\n","Check RFC5322.\r\n",NULL
};struct upload_status {int lines_read;
};static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
{struct upload_status *upload_ctx = (struct upload_status *)userp;const char *data;if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {return 0;}data = payload_text[upload_ctx->lines_read];if(data) {size_t len = strlen(data);memcpy(ptr, data, len);upload_ctx->lines_read++;return len;}return 0;
}int main(void)
{CURL *curl;CURLcode res = CURLE_OK;struct curl_slist *recipients = NULL;struct upload_status upload_ctx;upload_ctx.lines_read = 0;curl = curl_easy_init();if(curl) {curl_easy_setopt(curl, CURLOPT_URL, "smtps://smtp.qq.com:465");curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM_ADDR);recipients = curl_slist_append(recipients, TO_ADDR);curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);curl_easy_setopt(curl, CURLOPT_USERNAME, "1158801411@qq.com");curl_easy_setopt(curl, CURLOPT_PASSWORD, "xxxxxxxxxxxxxxxx");curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);/* DEBUG */curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);/* Send the message */res = curl_easy_perform(curl);/* Check for errors */if(res != CURLE_OK)fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res));curl_slist_free_all(recipients);curl_easy_cleanup(curl);}return (int)res;
}
编译 && 执行:
[jiang@localhost ~]$ gcc -o ssl ssl.c -I/home/jiang/libcurl/include -L /home/jiang/libcurl/lib -lcurl
[jiang@localhost ~]$ ./ssl
* Protocol smtps not supported or disabled in libcurl
* Unsupported protocol
curl_easy_perform() failed: Unsupported protocol
仔细回头看看,想想。
libcurl如果使用smtps,即使用TLS/SSL,那必然涉及到加解密算法,谁来做这个工作呢?
刚刚似乎安装libcurl时没有带着openssl?
实际可能由于openssl版本和libcurl要求的openssl版本不一致或其他原因,导致./configure在生成libcurl的makefile时,并没有(发现)已存在的openssl库。
解决办法:
重新安装/升级openssl:
[root@localhost ~]# yum install openssl-devel -y
重新安装libcurl:
[jiang@localhost curl-7.56.1]$ ./configure --prefix=$HOME/libcurl
……
configure: Configured to build curl/libcurl:curl version: 7.56.1Host setup: x86_64-pc-linux-gnuInstall prefix: /home/jiang/libcurlCompiler: gccSSL support: enabled (OpenSSL)SSH support: no (--with-libssh2)zlib support: enabledGSS-API support: no (--with-gssapi)TLS-SRP support: no (--enable-tls-srp)resolver: POSIX threadedIPv6 support: enabledUnix sockets support: enabledIDN support: no (--with-{libidn2,winidn})Build libcurl: Shared=yes, Static=yesBuilt-in manual: enabled--libcurl option: enabled (--disable-libcurl-option)Verbose errors: enabled (--disable-verbose)SSPI support: no (--enable-sspi)ca cert bundle: /etc/pki/tls/certs/ca-bundle.crtca cert path: noca fallback: noLDAP support: no (--enable-ldap / --with-ldap-lib / --with-lber-lib)LDAPS support: no (--enable-ldaps)RTSP support: enabledRTMP support: no (--with-librtmp)metalink support: no (--with-libmetalink)PSL support: no (libpsl not found)HTTP2 support: disabled (--with-nghttp2)Protocols: DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS POP3 POP3S RTSP SMB SMBS SMTP SMTPS TELNET TFTP[jiang@localhost curl-7.56.1]$ make && make install
仔细对比两次./configure生成输出的summary:
Protocols: DICT FILE FTP GOPHER HTTP IMAP POP3 RTSP SMTP TELNET TFTPProtocols: DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS POP3 POP3S RTSP SMB SMBS SMTP
即,通过安装/升级openssl,使得在安装libcurl生成makefile时,让其发现openssl的存在,带着openssl编译安装,以支持所有需要TLS/SSL的协议(HTTPS、SMTPS等)。
代码编译&&执行如下:
[jiang@localhost ~]$ gcc -o ssl ssl.c -I/home/jiang/libcurl/include -L /home/jiang/libcurl/lib -lcurl
[jiang@localhost ~]$ ./ssl
* Rebuilt URL to: smtps://smtp.qq.com:465/
* Trying 14.17.57.241...
* TCP_NODELAY set
* Connected to smtp.qq.com (14.17.57.241) port 465 (#0)
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crtCApath: none
* SSL connection using TLSv1.2 / AES128-SHA256
* Server certificate:
* subject: C=CN; ST=Guangdong; L=Shenzhen; O=Shenzhen Tencent Computer Systems Company Limited; OU=R&D; CN=pop.qq.com
* start date: Sep 7 00:00:00 2016 GMT
* expire date: Dec 7 23:59:59 2018 GMT
* issuer: C=US; O=GeoTrust Inc.; CN=GeoTrust SSL CA - G3
* SSL certificate verify ok.
< 220 smtp.qq.com Esmtp QQ Mail Server
> EHLO localhost
< 250-smtp.qq.com
< 250-PIPELINING
< 250-SIZE 73400320
< 250-AUTH LOGIN PLAIN
< 250-AUTH=LOGIN
< 250-MAILCOMPRESS
< 250 8BITMIME
> AUTH LOGIN
< 334 VXNlcm5hbWU6
> MTE1ODgwMTQxMUBxcS5jb20=
< 334 UGFzc3dvcmQ6
> YmJ1eXVwZnphdmFoaGhpYw==
< 235 Authentication successful
> MAIL FROM:<1158801411@qq.com>
< 250 Ok
> RCPT TO:<jiangjinwang@ebupt.com>
< 250 Ok
> DATA
< 354 End data with <CR><LF>.<CR><LF>
< 250 Ok: queued as
* Connection #0 to host smtp.qq.com left intact
OK,发送成功(TLS/SSL)。
还有一种可能,也会导致上面的错误信息:
可执行文件链接的动态库不是新版的,支持SMTPS的动态库,而是旧版本的libcurl动态库。
[jiang@localhost ~]$ ldd ./ssllinux-vdso.so.1 => (0x00007ffc6cbeb000)libcurl.so.4 => /usr/lib64/libcurl.so.4 (0x000000312ec00000)……
[jiang@localhost ~]$ ./ssl
* Protocol smtps not supported or disabled in libcurl
* Unsupported protocol
curl_easy_perform() failed: Unsupported protocol
通过设置LD_LIBRARY_PATH,使其找到正确的libcurl动态库(当然,也存在很多其他方法啦):
[jiang@localhost ~]$ export LD_LIBRARY_PATH=$HOME/libcurl/lib:$LD_LIBRARY_PATH
[jiang@localhost ~]$ ./ssl
* Rebuilt URL to: smtps://smtp.qq.com:465/
* Trying 14.17.57.241...
* TCP_NODELAY set
* Connected to smtp.qq.com (14.17.57.241) port 465 (#0)
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
……
总结:
有两种原因导致:
Protocol “smtps” not supported or disabled in libcurl
1.在./configure生成libcurl的makefile时,可能由于openssl库安装不正确、版本等问题导致configure找不到openssl库
2.执行可执行文件时,动态链接器ld找到的不是正确的,支持TLS/SSL的libcurl,而是其他版本、不支持TLS/SSL的libcurl
同理,可能存在:
Protocol “https” not supported or disabled in libcurl
当运行时发现这个问题,可以先检查下libcurl是否支持openssl?安装libcurl时是否是带着openssl进行编译的?
这篇关于libcurl:Protocol smtps not supported or disabled in libcurl的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!