From 080a13effc327e8d9c2419d425e81aedc37c6c89 Mon Sep 17 00:00:00 2001 From: ticktock35 Date: Mon, 15 Dec 2008 04:20:10 +0000 Subject: [PATCH 1/1] opkg: initial implementation of package list signature verification git-svn-id: http://opkg.googlecode.com/svn/trunk@21 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358 --- opkg_cmd.c | 34 ++++++++++++++++++++++++++++++++++ opkg_download.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ opkg_download.h | 1 + 3 files changed, 83 insertions(+) diff --git a/opkg_cmd.c b/opkg_cmd.c index f32aa47..20d3872 100644 --- a/opkg_cmd.c +++ b/opkg_cmd.c @@ -265,6 +265,40 @@ static int opkg_update_cmd(opkg_conf_t *conf, int argc, char **argv) list_file_name); } free(url); + + /* download detached signitures to verify the package lists */ + /* get the url for the sig file */ + if (src->extra_data) /* debian style? */ + sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data, + "Packages.sig"); + else + sprintf_alloc(&url, "%s/%s", src->value, "Packages.sig"); + + /* create temporary dir for it */ + char *tmp, *tmp_file_name; + tmp = strdup ("/tmp/opkg.XXXXXX"); + if (mkdtemp (tmp) == NULL) { + perror ("mkdtemp"); + failures++; + continue; + } + sprintf_alloc (&tmp_file_name, "%s/%s", tmp, "Packages.sig"); + + err = opkg_download(conf, url, tmp_file_name); + if (err) { + failures++; + } else { + int err; + err = opkg_verify_file (list_file_name, tmp_file_name); + if (err == 0) + opkg_message (conf, OPKG_NOTICE, "Signature check passed\n"); + else + opkg_message (conf, OPKG_NOTICE, "Signature check failed\n"); + } + unlink (tmp_file_name); + free (tmp_file_name); + + free (url); free(list_file_name); } free(lists_dir); diff --git a/opkg_download.c b/opkg_download.c index 8195e51..6370250 100644 --- a/opkg_download.c +++ b/opkg_download.c @@ -18,6 +18,7 @@ */ #include +#include #include "opkg.h" #include "opkg_download.h" @@ -152,6 +153,7 @@ int opkg_download(opkg_conf_t *conf, const char *src, const char *dest_file_name curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 0); curl_easy_setopt (curl, CURLOPT_PROGRESSDATA, src); curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, curl_progress_func); + curl_easy_setopt (curl, CURLOPT_FAILONERROR, 1); if (conf->http_proxy || conf->ftp_proxy) { char *userpwd; @@ -163,6 +165,8 @@ int opkg_download(opkg_conf_t *conf, const char *src, const char *dest_file_name res = curl_easy_perform (curl); curl_easy_cleanup (curl); fclose (file); + if (res) + return res; } else @@ -271,3 +275,47 @@ int opkg_prepare_url_for_install(opkg_conf_t *conf, const char *url, char **name } return 0; } + +int +opkg_verify_file (char *text_file, char *sig_file) +{ + int status = -1; + gpgme_ctx_t ctx; + gpgme_data_t sig, text; + gpgme_error_t err = -1; + gpgme_verify_result_t result; + gpgme_signature_t s; + + err = gpgme_new (&ctx); + + if (err) + return -1; + + err = gpgme_data_new_from_file (&sig, sig_file, 1); + if (err) + return -1; + + err = gpgme_data_new_from_file (&text, text_file, 1); + if (err) + return -1; + + err = gpgme_op_verify (ctx, sig, text, NULL); + + result = gpgme_op_verify_result (ctx); + + /* see if any of the signitures matched */ + s = result->signatures; + while (s) + { + status = gpg_err_code (s->status); + if (status == GPG_ERR_NO_ERROR) + break; + s = s->next; + } + + gpgme_data_release (sig); + gpgme_data_release (text); + gpgme_release (ctx); + + return status; +} diff --git a/opkg_download.h b/opkg_download.h index 24d4da2..d3f419d 100644 --- a/opkg_download.h +++ b/opkg_download.h @@ -27,4 +27,5 @@ int opkg_download_pkg(opkg_conf_t *conf, pkg_t *pkg, const char *dir); */ int opkg_prepare_url_for_install(opkg_conf_t *conf, const char *url, char **namep); +int opkg_verify_file (char *text_file, char *sig_file); #endif -- 2.25.1