opkg: initial implementation of package list signature verification
authorticktock35 <ticktock35@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358>
Mon, 15 Dec 2008 04:20:10 +0000 (04:20 +0000)
committerticktock35 <ticktock35@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358>
Mon, 15 Dec 2008 04:20:10 +0000 (04:20 +0000)
git-svn-id: http://opkg.googlecode.com/svn/trunk@21 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358

opkg_cmd.c
opkg_download.c
opkg_download.h

index f32aa47..20d3872 100644 (file)
@@ -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);
index 8195e51..6370250 100644 (file)
@@ -18,6 +18,7 @@
 */
 
 #include <curl/curl.h>
+#include <gpgme.h>
 
 #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;
+}
index 24d4da2..d3f419d 100644 (file)
@@ -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