summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac41
-rw-r--r--libopkg/Makefile.am2
-rw-r--r--libopkg/opkg_conf.c22
-rw-r--r--libopkg/opkg_conf.h16
-rw-r--r--libopkg/opkg_download.c182
5 files changed, 231 insertions, 32 deletions
diff --git a/configure.ac b/configure.ac
index 579a105..95233b5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,6 +15,9 @@ for top_builddir in . .. ../.. $ac_auxdir $ac_auxdir/..; do
test -f $top_builddir/configure && break
done
+# large file support can be useful for gpgme
+AC_SYS_LARGEFILE
+
# Checks for programs
AC_PROG_AWK
@@ -55,8 +58,44 @@ AC_ARG_ENABLE(openssl,
[want_openssl="$enableval"], [want_openssl="no"])
if test "x$want_openssl" = "xyes"; then
- PKG_CHECK_MODULES(OPENSSL, openssl)
AC_DEFINE(HAVE_OPENSSL, 1, [Define if you want OpenSSL support])
+ NEED_SSL_LIBS="yes"
+fi
+
+# check for libssl-curl
+AC_ARG_ENABLE(ssl-curl,
+ AC_HELP_STRING([--enable-ssl-curl], [Enable certificate authentication with curl
+ [[default="$default_sslcurl"]] ]),
+ [want_sslcurl="$enableval"], [want_sslcurl="yes"])
+
+if test "x$want_curl" = "xyes" -a "x$want_sslcurl" = "xyes"; then
+ AC_DEFINE(HAVE_CURL, 1, [Define if you want CURL support])
+ AC_DEFINE(HAVE_SSLCURL, 1, [Define if you want certificate authentication with curl])
+ NEED_SSL_LIBS="yes"
+fi
+
+if test "x$NEED_SSL_LIBS" = "xyes"; then
+ AC_MSG_CHECKING([if openssl is available])
+
+ PKG_CHECK_MODULES(OPENSSL, openssl, [:], [:])
+ if test "x$OPENSSL_LIBS" != "x"; then
+ AC_MSG_RESULT(yes)
+ else
+ OPENSSL_LIBS="-lcrypto -lssl"
+ dnl If pkg-config fails, run compile/link test.
+ AC_TRY_LINK([
+#include <openssl/opensslv.h>
+], [
+return OPENSSL_VERSION_NUMBER; ],
+ [
+ AC_MSG_RESULT(yes)
+
+ ], [
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR(OpenSSL not found)
+ ])
+ fi
+ AC_SUBST(OPENSSL_LIBS)
fi
diff --git a/libopkg/Makefile.am b/libopkg/Makefile.am
index 28fdeb9..555b0e5 100644
--- a/libopkg/Makefile.am
+++ b/libopkg/Makefile.am
@@ -40,7 +40,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_.*"
diff --git a/libopkg/opkg_conf.c b/libopkg/opkg_conf.c
index 2739861..4ea15d6 100644
--- a/libopkg/opkg_conf.c
+++ b/libopkg/opkg_conf.c
@@ -79,6 +79,17 @@ int opkg_init_options_array(const opkg_conf_t *conf, opkg_option_t **options)
{ "signature_ca_file", OPKG_OPT_TYPE_STRING, &conf->signature_ca_file },
{ "signature_ca_path", OPKG_OPT_TYPE_STRING, &conf->signature_ca_path },
#endif
+#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 }
};
@@ -376,6 +387,17 @@ void opkg_conf_deinit(opkg_conf_t *conf)
opkg_conf_free_string(&conf->signature_ca_path);
#endif
+#if defined(HAVE_SSLCURL)
+ opkg_conf_free_string(&conf->ssl_engine);
+ opkg_conf_free_string(&conf->ssl_cert);
+ opkg_conf_free_string(&conf->ssl_cert_type);
+ opkg_conf_free_string(&conf->ssl_key);
+ opkg_conf_free_string(&conf->ssl_key_type);
+ opkg_conf_free_string(&conf->ssl_key_passwd);
+ opkg_conf_free_string(&conf->ssl_ca_file);
+ opkg_conf_free_string(&conf->ssl_ca_path);
+#endif
+
if (conf->verbosity > 1) {
int i;
hash_table_t *hashes[] = {
diff --git a/libopkg/opkg_conf.h b/libopkg/opkg_conf.h
index 4bd50e5..ecfe9ea 100644
--- a/libopkg/opkg_conf.h
+++ b/libopkg/opkg_conf.h
@@ -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;
diff --git a/libopkg/opkg_download.c b/libopkg/opkg_download.c
index ee8dc08..33019d8 100644
--- a/libopkg/opkg_download.c
+++ b/libopkg/opkg_download.c
@@ -17,20 +17,25 @@
General Public License for more details.
*/
#include "config.h"
+
#ifdef HAVE_CURL
#include <curl/curl.h>
#endif
+
+#if defined(HAVE_SSLCURL) || defined(HAVE_OPENSSL)
+#include <openssl/conf.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#endif
+
#if defined(HAVE_GPGME)
#include <gpgme.h>
#elif defined(HAVE_OPENSSL)
#include <openssl/bio.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/hmac.h>
-
#endif
#include "includes.h"
@@ -44,10 +49,22 @@
#include "str_util.h"
#include "opkg_defines.h"
+#if defined(HAVE_OPENSSL) || defined(HAVE_SSLCURL)
+static void openssl_init(void);
+#endif
#ifdef HAVE_OPENSSL
static X509_STORE *setup_verify(opkg_conf_t *conf, char *CAfile, char *CApath);
-static void init_openssl(void);
+#endif
+
+#ifdef HAVE_CURL
+/*
+ * Make curl an instance variable so we don't have to instanciate it
+ * each time
+ */
+static CURL *curl = NULL;
+static void opkg_curl_cleanup(void);
+static CURL *opkg_curl_init(opkg_conf_t *conf, curl_progress_func cb, void *data);
#endif
int opkg_download(opkg_conf_t *conf, const char *src,
@@ -99,27 +116,12 @@ int opkg_download(opkg_conf_t *conf, const char *src,
CURLcode res;
FILE * file = fopen (tmp_file_location, "w");
- curl = curl_easy_init ();
+ curl = opkg_curl_init (conf, cb, data);
if (curl)
{
curl_easy_setopt (curl, CURLOPT_URL, src);
curl_easy_setopt (curl, CURLOPT_WRITEDATA, file);
- curl_easy_setopt (curl, CURLOPT_NOPROGRESS, (cb == NULL));
- if (cb)
- {
- curl_easy_setopt (curl, CURLOPT_PROGRESSDATA, data);
- curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, cb);
- }
- curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt (curl, CURLOPT_FAILONERROR, 1);
- if (conf->http_proxy || conf->ftp_proxy)
- {
- char *userpwd;
- sprintf_alloc (&userpwd, "%s:%s", conf->proxy_user,
- conf->proxy_passwd);
- curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd);
- free (userpwd);
- }
+
res = curl_easy_perform (curl);
fclose (file);
if (res)
@@ -129,10 +131,8 @@ int opkg_download(opkg_conf_t *conf, const char *src,
opkg_message(conf, OPKG_ERROR, "Failed to download %s. \nerror detail: %s\n", src, curl_easy_strerror(res));
free(tmp_file_location);
free(src_basec);
- curl_easy_cleanup (curl);
return res;
}
- curl_easy_cleanup (curl);
}
else
@@ -396,7 +396,7 @@ opkg_verify_file (opkg_conf_t *conf, char *text_file, char *sig_file)
// Sig check failed by default !
int status = -1;
- init_openssl();
+ openssl_init();
// Set-up the key store
if(!(store = setup_verify(conf, conf->signature_ca_file, conf->signature_ca_path))){
@@ -454,6 +454,21 @@ verify_file_end:
}
+#if defined(HAVE_OPENSSL) || defined(HAVE_SSLCURL)
+static void openssl_init(void){
+ static int init = 0;
+
+ if(!init){
+ OPENSSL_config(NULL);
+ OpenSSL_add_all_algorithms();
+ ERR_load_crypto_strings();
+ init = 1;
+ }
+}
+
+#endif
+
+
#if defined HAVE_OPENSSL
static X509_STORE *setup_verify(opkg_conf_t *conf, char *CAfile, char *CApath){
X509_STORE *store = NULL;
@@ -509,13 +524,120 @@ end:
}
-static void init_openssl(void){
- static int init = 0;
+#endif
+
+#ifdef HAVE_CURL
+static void opkg_curl_cleanup(void){
+ if(curl != NULL){
+ curl_easy_cleanup (curl);
+ curl = NULL;
+ }
+}
+
+static CURL *opkg_curl_init(opkg_conf_t *conf, curl_progress_func cb, void *data){
+
+ if(curl == NULL){
+ curl = curl_easy_init();
+
+#ifdef HAVE_SSLCURL
+ openssl_init();
+
+ if (conf->ssl_engine) {
+
+ /* 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);
+
+ opkg_curl_cleanup();
+ return NULL;
+ }
+ /* 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");
+
+ opkg_curl_cleanup();
+ return NULL;
+ }
+ }
+
+ /* cert & key can only be in PEM case in the same file */
+ if(conf->ssl_key_passwd){
+ if (curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, conf->ssl_key_passwd) != CURLE_OK)
+ {
+ opkg_message(conf, OPKG_DEBUG, "Failed to set key password\n");
+ }
+ }
+
+ /* sets the client certificate and its type */
+ if(conf->ssl_cert_type){
+ if (curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, conf->ssl_cert_type) != 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 and its type */
+ if(conf->ssl_key_type){
+ if (curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, conf->ssl_key_type) != CURLE_OK)
+ {
+ opkg_message(conf, OPKG_DEBUG, "Failed to set key format\n");
+ }
+ }
+ if(conf->ssl_key){
+ if (curl_easy_setopt(curl, CURLOPT_SSLKEY, conf->ssl_key) != CURLE_OK)
+ {
+ opkg_message(conf, OPKG_DEBUG, "Failed to set key\n");
+ }
+ }
+
+ /* Should we verify the peer certificate ? */
+ if(conf->ssl_dont_verify_peer){
+ /*
+ * CURLOPT_SSL_VERIFYPEER default is nonzero (curl => 7.10)
+ */
+ 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
+
+ curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1);
+ curl_easy_setopt (curl, CURLOPT_FAILONERROR, 1);
+ if (conf->http_proxy || conf->ftp_proxy)
+ {
+ char *userpwd;
+ sprintf_alloc (&userpwd, "%s:%s", conf->proxy_user,
+ conf->proxy_passwd);
+ curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd);
+ free (userpwd);
+ }
+
+ /* add curl cleanup callback */
+ if(!atexit(opkg_curl_cleanup)){
+ opkg_message(conf,OPKG_DEBUG, "Failed to register atexit curl cleanup function\n");
+ }
- if(!init){
- OpenSSL_add_all_algorithms();
- ERR_load_crypto_strings();
- init = 1;
}
+
+ curl_easy_setopt (curl, CURLOPT_NOPROGRESS, (cb == NULL));
+ if (cb)
+ {
+ curl_easy_setopt (curl, CURLOPT_PROGRESSDATA, data);
+ curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, cb);
+ }
+
+ return curl;
+
}
#endif