@@ -37,6 +37,22 @@ if test "x$want_curl" = "xyes"; then
AC_DEFINE(HAVE_CURL, 1, [Define if you want CURL support])
fi
+# check for libssl-curl
+AC_ARG_ENABLE(ssl-curl,
+ AC_HELP_STRING([--enable-ssl-curl], [Enable certificate authentication with curl
+ [[default=yes]] ]),
+ [want_sslcurl="$enableval"], [want_sslcurl="yes"])
+
+if test "x$want_sslcurl" = "xyes"; then
+ PKG_CHECK_MODULES(OPENSSL, openssl)
+ PKG_CHECK_MODULES(CURL, libcurl)
+ AC_DEFINE(HAVE_CURL, 1, [Define if you want CURL support])
+ AC_DEFINE(HAVE_SSLCURL, 1, [Define if you want certificate authentication with curl])
+ OPENSSL_LIBS="-lssl -lcrypto"
+fi
+AC_SUBST(OPENSSL_LIBS)
+
+
dnl **********
dnl GPGME
@@ -36,7 +36,7 @@ libopkg_la_SOURCES = \
$(opkg_cmd_sources) $(opkg_db_sources) \
$(opkg_util_sources) $(opkg_list_sources)
-libopkg_la_LIBADD = $(top_builddir)/libbb/libbb.la $(CURL_LIBS) $(GPGME_LIBS)
+libopkg_la_LIBADD = $(top_builddir)/libbb/libbb.la $(CURL_LIBS) $(GPGME_LIBS) $(OPENSSL_LIBS)
# make sure we only export symbols that are for public use
libopkg_la_LDFLAGS = -export-symbols-regex "^opkg_.*"
@@ -75,6 +75,17 @@ int opkg_init_options_array(const opkg_conf_t *conf, opkg_option_t **options)
{ "proxy_user", OPKG_OPT_TYPE_STRING, &conf->proxy_user },
{ "query-all", OPKG_OPT_TYPE_BOOL, &conf->query_all },
{ "verbosity", OPKG_OPT_TYPE_BOOL, &conf->verbosity },
+#if defined(HAVE_SSLCURL) && defined(HAVE_CURL)
+ { "ssl_engine", OPKG_OPT_TYPE_STRING, &conf->ssl_engine },
+ { "ssl_cert", OPKG_OPT_TYPE_STRING, &conf->ssl_cert },
+ { "ssl_cert_type", OPKG_OPT_TYPE_STRING, &conf->ssl_cert_type },
+ { "ssl_key", OPKG_OPT_TYPE_STRING, &conf->ssl_key },
+ { "ssl_key_type", OPKG_OPT_TYPE_STRING, &conf->ssl_key_type },
+ { "ssl_key_passwd", OPKG_OPT_TYPE_STRING, &conf->ssl_key_passwd },
+ { "ssl_ca_file", OPKG_OPT_TYPE_STRING, &conf->ssl_ca_file },
+ { "ssl_ca_path", OPKG_OPT_TYPE_STRING, &conf->ssl_ca_path },
+ { "ssl_dont_verify_peer", OPKG_OPT_TYPE_BOOL, &conf->ssl_dont_verify_peer },
+#endif
{ NULL }
};
@@ -75,6 +75,22 @@ struct opkg_conf
int noaction;
char *cache;
+#ifdef HAVE_SSLCURL
+ /* some options could be used by
+ * wget if curl support isn't builtin
+ * If someone want to try...
+ */
+ char *ssl_engine;
+ char *ssl_cert;
+ char *ssl_cert_type;
+ char *ssl_key;
+ char *ssl_key_type;
+ char *ssl_key_passwd;
+ char *ssl_ca_file;
+ char *ssl_ca_path;
+ int ssl_dont_verify_peer;
+#endif
+
/* proxy options */
char *http_proxy;
char *ftp_proxy;
@@ -20,10 +20,15 @@
#ifdef HAVE_CURL
#include <curl/curl.h>
#endif
+
#ifdef HAVE_GPGME
#include <gpgme.h>
#endif
+#ifdef HAVE_SSLCURL
+#include <openssl/conf.h>
+#endif
+
#include "includes.h"
#include "opkg_download.h"
#include "opkg_message.h"
@@ -84,6 +89,11 @@ int opkg_download(opkg_conf_t *conf, const char *src,
CURLcode res;
FILE * file = fopen (tmp_file_location, "w");
+#ifdef HAVE_SSLCURL
+ static char openssl_init = 0;
+#endif
+
+
curl = curl_easy_init ();
if (curl)
{
@@ -105,6 +115,85 @@ int opkg_download(opkg_conf_t *conf, const char *src,
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd);
free (userpwd);
}
+#ifdef HAVE_SSLCURL
+ if (conf->ssl_engine) {
+
+ /* Tels openssl to read it's configuration if not already
+ * done
+ */
+ if(!openssl_init){
+ OPENSSL_config(NULL);
+ openssl_init = 1;
+ }
+
+ /* use crypto engine */
+ if (curl_easy_setopt(curl, CURLOPT_SSLENGINE, conf->ssl_engine) != CURLE_OK){
+ opkg_message(conf, OPKG_ERROR, "can't set crypto engine: '%s'\n",
+ conf->ssl_engine);
+
+ fclose (file);
+ free(tmp_file_location);
+ free(src_basec);
+ curl_easy_cleanup (curl);
+ return -1;
+ }
+ /* set the crypto engine as default */
+ if (curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L) != CURLE_OK){
+ opkg_message(conf, OPKG_ERROR, "can't set crypto engine as default\n");
+
+ fclose (file);
+ free(tmp_file_location);
+ free(src_basec);
+ curl_easy_cleanup (curl);
+ return -1;
+ }
+ }
+
+ /* cert & key can only be in PEM case in the same file */
+ if(conf->ssl_key_passwd){
+ res = curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, conf->ssl_key_passwd);
+ if(res != CURLE_OK){
+ opkg_message(conf,OPKG_DEBUG, "Failed to set key password\n");
+ }
+ }
+
+ /* sets the client certificate */
+ if(conf->ssl_cert_type){
+ res = curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, conf->ssl_cert_type);
+ if(res != CURLE_OK){
+ opkg_message(conf,OPKG_DEBUG, "Failed to set certificate format\n");
+ }
+ }
+ /* SSL cert name isn't mandatory */
+ if(conf->ssl_cert){
+ curl_easy_setopt(curl, CURLOPT_SSLCERT, conf->ssl_cert);
+ }
+ /* sets the client key */
+ if(conf->ssl_key_type){
+ res = curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, conf->ssl_key_type);
+ if(res != CURLE_OK){
+ opkg_message(conf,OPKG_DEBUG, "Failed to set key format\n");
+ }
+ }
+ if(conf->ssl_key){
+ curl_easy_setopt(curl, CURLOPT_SSLKEY, conf->ssl_key);
+ }
+
+ /* Should we verify the peer certificate ? */
+ if(conf->ssl_dont_verify_peer){
+ // CURLOPT_SSL_VERIFYPEER default is nonzero (curl => 7.10)
+ res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+ }
+
+ /* certification authority file and/or path */
+ if(conf->ssl_ca_file){
+ curl_easy_setopt(curl, CURLOPT_CAINFO, conf->ssl_ca_file);
+ }
+ if(conf->ssl_ca_path){
+ curl_easy_setopt(curl, CURLOPT_CAPATH, conf->ssl_ca_path);
+ }
+#endif
+
res = curl_easy_perform (curl);
fclose (file);
if (res)