From 04c02d72227f9fddc95741a0a936ed0f7ac33c39 Mon Sep 17 00:00:00 2001 From: ticktock35 Date: Mon, 15 Dec 2008 05:20:28 +0000 Subject: [PATCH] opkg: improve opkg_install error reporting and include a check to verify repository signature during install git-svn-id: http://opkg.googlecode.com/svn/trunk@123 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358 --- libopkg/opkg.c | 38 ++++++++++++++++++++++------------ libopkg/opkg.h | 6 ++++-- libopkg/opkg_install.c | 47 ++++++++++++++++++++++++++++++------------ libopkg/opkg_install.h | 15 ++++++++++++++ tests/libopkg_test.c | 15 +++++++++----- 5 files changed, 88 insertions(+), 33 deletions(-) diff --git a/libopkg/opkg.c b/libopkg/opkg.c index ec524f9..6cd0423 100644 --- a/libopkg/opkg.c +++ b/libopkg/opkg.c @@ -407,7 +407,7 @@ opkg_install_package (opkg_t *opkg, const char *package_name, opkg_progress_call { /* XXX: Error: Could not satisfy dependencies */ pkg_vec_free (deps); - return OPKG_DEPENDANCIES_FAILED; + return OPKG_DEPENDENCIES_FAILED; } /* insert the package we are installing so that we download it */ @@ -487,7 +487,17 @@ opkg_install_package (opkg_t *opkg, const char *package_name, opkg_progress_call if (err) { opkg_package_free (pdata.package); - return OPKG_UNKNOWN_ERROR; + switch (err) + { + case PKG_INSTALL_ERR_NOT_TRUSTED: return OPKG_GPG_ERROR; + case PKG_INSTALL_ERR_DOWNLOAD: return OPKG_DOWNLOAD_FAILED; + case PKG_INSTALL_ERR_DEPENDENCIES: + case PKG_INSTALL_ERR_CONFLICTS: return OPKG_DEPENDENCIES_FAILED; + case PKG_INSTALL_ERR_ALREADY_INSTALLED: return OPKG_PACKAGE_ALREADY_INSTALLED; + case PKG_INSTALL_ERR_SIGNATURE: return OPKG_GPG_ERROR; + case PKG_INSTALL_ERR_MD5: return OPKG_MD5_ERROR; + default: return OPKG_UNKNOWN_ERROR; + } } progress (pdata, 75); @@ -675,7 +685,6 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb pkg_src_t *src; int sources_list_count, sources_done; opkg_progress_data_t pdata; - char *tmp_file_name = NULL; opkg_assert (opkg != NULL); @@ -716,7 +725,7 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb return 1; } - /* cout the number of sources so we can give some progress updates */ + /* count the number of sources so we can give some progress updates */ sources_list_count = 0; sources_done = 0; iter = opkg->conf->pkg_src_list.head; @@ -728,7 +737,7 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb for (iter = opkg->conf->pkg_src_list.head; iter; iter = iter->next) { - char *url, *list_file_name; + char *url, *list_file_name = NULL, *sig_file_name = NULL; src = iter->data; @@ -743,6 +752,7 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb { FILE *in, *out; struct _curl_cb_data cb_data; + char *tmp_file_name = NULL; sprintf_alloc (&tmp_file_name, "%s/%s.gz", tmp, src->name); @@ -772,10 +782,10 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb fclose (out); unlink (tmp_file_name); } + free (tmp_file_name); } else err = opkg_download (opkg->conf, url, list_file_name, NULL, NULL); - free (tmp_file_name); if (err) { @@ -793,10 +803,13 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb else sprintf_alloc (&url, "%s/%s", src->value, "Packages.sig"); - /* create temporary file for it */ - sprintf_alloc (&tmp_file_name, "%s/%s", tmp, "Packages.sig"); + /* create filename for signature */ + sprintf_alloc (&sig_file_name, "%s/%s.sig", lists_dir, src->name); - err = opkg_download (opkg->conf, url, tmp_file_name, NULL, NULL); + /* make sure there is no existing signature file */ + unlink (sig_file_name); + + err = opkg_download (opkg->conf, url, sig_file_name, NULL, NULL); if (err) { /* XXX: Warning: Download failed */ @@ -804,7 +817,7 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb else { int err; - err = opkg_verify_file (opkg->conf, list_file_name, tmp_file_name); + err = opkg_verify_file (opkg->conf, list_file_name, sig_file_name); if (err == 0) { /* XXX: Notice: Signature check passed */ @@ -814,15 +827,14 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb /* XXX: Warning: Signature check failed */ } } - unlink (tmp_file_name); - free (tmp_file_name); + free (sig_file_name); + free (list_file_name); free (url); #else /* XXX: Note: Signiture check for %s skipped because GPG support was not * enabled in this build */ #endif - free (list_file_name); sources_done++; progress (pdata, 100 * sources_done / sources_list_count); diff --git a/libopkg/opkg.h b/libopkg/opkg.h index d2a5bd0..36da8cf 100644 --- a/libopkg/opkg.h +++ b/libopkg/opkg.h @@ -37,11 +37,13 @@ enum _opkg_error_code_t OPKG_NO_ERROR, OPKG_UNKNOWN_ERROR, OPKG_DOWNLOAD_FAILED, - OPKG_DEPENDANCIES_FAILED, + OPKG_DEPENDENCIES_FAILED, OPKG_PACKAGE_ALREADY_INSTALLED, OPKG_PACKAGE_NOT_AVAILABLE, OPKG_PACKAGE_NOT_FOUND, - OPKG_PACKAGE_NOT_INSTALLED + OPKG_PACKAGE_NOT_INSTALLED, + OPKG_GPG_ERROR, + OPKG_MD5_ERROR }; struct _opkg_package_t diff --git a/libopkg/opkg_install.c b/libopkg/opkg_install.c index f6666b2..1c73b5c 100644 --- a/libopkg/opkg_install.c +++ b/libopkg/opkg_install.c @@ -755,7 +755,6 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) int old_state_flag; char* file_md5; char *pkgid; - if ( from_upgrade ) message = 1; /* Coming from an upgrade, and should change the output message */ @@ -763,7 +762,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) if (!pkg) { opkg_message(conf, OPKG_ERROR, "INTERNAL ERROR: null pkg passed to opkg_install_pkg\n"); - return -EINVAL; + return PKG_INSTALL_ERR_INTERNAL; } opkg_message(conf, OPKG_DEBUG2, "Function: %s calling pkg_arch_supported %s \n", __FUNCTION__, __FUNCTION__); @@ -771,11 +770,11 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) if (!pkg_arch_supported(conf, pkg)) { opkg_message(conf, OPKG_ERROR, "INTERNAL ERROR: architecture %s for pkg %s is unsupported.\n", pkg->architecture, pkg->name); - return -EINVAL; + return PKG_INSTALL_ERR_INTERNAL; } if (pkg->state_status == SS_INSTALLED && conf->force_reinstall == 0 && conf->nodeps == 0) { err = satisfy_dependencies_for(conf, pkg); - if (err) { return err; } + if (err) { return PKG_INSTALL_ERR_DEPENDENCIES; } opkg_message(conf, OPKG_NOTICE, "Package %s is already installed in %s.\n", @@ -790,7 +789,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) old_pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name); err = opkg_install_check_downgrade(conf, pkg, old_pkg, message); - if (err) { return err; } + if (err) { return PKG_INSTALL_ERR_NO_DOWNGRADE; } pkg->state_want = SW_INSTALL; if (old_pkg){ @@ -800,7 +799,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) /* Abhaya: conflicts check */ err = check_conflicts_for(conf, pkg); - if (err) { return err; } + if (err) { return PKG_INSTALL_ERR_CONFLICTS; } /* this setup is to remove the upgrade scenario in the end when installing pkg A, A deps B & B deps on A. So both B and A are @@ -810,7 +809,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) && conf->force_reinstall == 0) return 0; err = verify_pkg_installable(conf, pkg); - if (err) { return err; } + if (err) { return PKG_INSTALL_ERR_NO_SPACE; } if (pkg->local_filename == NULL) { err = opkg_download_pkg(conf, pkg, conf->tmp_dir); @@ -818,11 +817,33 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) opkg_message(conf, OPKG_ERROR, "Failed to download %s. Perhaps you need to run 'opkg update'?\n", pkg->name); - return err; + return PKG_INSTALL_ERR_DOWNLOAD; } } -/* Check for md5 values */ + /* check that the repository is valid */ + #if HAVE_GPGME + char *list_file_name, *sig_file_name, *lists_dir; + + sprintf_alloc (&lists_dir, "%s", + (conf->restrict_to_default_dest) + ? conf->default_dest->lists_dir + : conf->lists_dir); + sprintf_alloc (&list_file_name, "%s/%s", lists_dir, pkg->src->name); + sprintf_alloc (&sig_file_name, "%s/%s.sig", lists_dir, pkg->src->name); + + if (file_exists (sig_file_name)) + { + if (opkg_verify_file (conf, list_file_name, sig_file_name)) + return PKG_INSTALL_ERR_SIGNATURE; + } + + free (lists_dir); + free (list_file_name); + free (sig_file_name); + #endif + + /* Check for md5 values */ if (pkg->md5sum) { file_md5 = file_md5sum_alloc(pkg->local_filename); @@ -832,7 +853,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) "Package %s md5sum mismatch. Either the opkg or the package index are corrupt. Try 'opkg update'.\n", pkg->name); free(file_md5); - return err; + return PKG_INSTALL_ERR_MD5; } free(file_md5); } @@ -845,11 +866,11 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) /* Pigi: check if it will pass from here when replacing. It seems to fail */ /* That's rather strange that files don't change owner. Investigate !!!!!!*/ err = update_file_ownership(conf, pkg, old_pkg); - if (err) { return err; } + if (err) { return PKG_INSTALL_ERR_UNKNOWN; } if (conf->nodeps == 0) { err = satisfy_dependencies_for(conf, pkg); - if (err) { return err; } + if (err) { return PKG_INSTALL_ERR_DEPENDENCIES; } } replacees = pkg_vec_alloc(); @@ -998,7 +1019,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) sigprocmask(SIG_UNBLOCK, &newset, &oldset); pkg_vec_free (replacees); - return err; + return PKG_INSTALL_ERR_UNKNOWN; } opkg_set_current_state (conf, OPKG_STATE_NONE, NULL); } diff --git a/libopkg/opkg_install.h b/libopkg/opkg_install.h index 4bed953..0c01cc0 100644 --- a/libopkg/opkg_install.h +++ b/libopkg/opkg_install.h @@ -22,6 +22,21 @@ #include "opkg_conf.h" #include "opkg_error.h" +enum { + PKG_INSTALL_ERR_NONE, + PKG_INSTALL_ERR_NOT_TRUSTED, + PKG_INSTALL_ERR_DOWNLOAD, + PKG_INSTALL_ERR_CONFLICTS, + PKG_INSTALL_ERR_ALREADY_INSTALLED, + PKG_INSTALL_ERR_DEPENDENCIES, + PKG_INSTALL_ERR_NO_DOWNGRADE, + PKG_INSTALL_ERR_NO_SPACE, + PKG_INSTALL_ERR_SIGNATURE, + PKG_INSTALL_ERR_MD5, + PKG_INSTALL_ERR_INTERNAL, + PKG_INSTALL_ERR_UNKNOWN +}; + opkg_error_t opkg_install_by_name(opkg_conf_t *conf, const char *pkg_name); opkg_error_t opkg_install_multi_by_name(opkg_conf_t *conf, const char *pkg_name); int opkg_install_from_file(opkg_conf_t *conf, const char *filename); diff --git a/tests/libopkg_test.c b/tests/libopkg_test.c index 7033ced..d9bd0ef 100644 --- a/tests/libopkg_test.c +++ b/tests/libopkg_test.c @@ -4,7 +4,7 @@ opkg_package_t *find_pkg = NULL; -char *errors[8] = { +char *errors[10] = { "No Error", "Unknown Eror", "Download failed", @@ -12,9 +12,14 @@ char *errors[8] = { "Package already installed", "Package not available", "Package not found", - "Package not installed" + "Package not installed", + "Signature check failed", + "MD5 sum failed" }; + +#define TEST_PACKAGE "aspell" + void progress_callback (opkg_t *opkg, const opkg_progress_data_t *progress, void *data) { @@ -112,13 +117,13 @@ main (int argc, char **argv) else printf ("No package available to test find_package.\n"); - err = opkg_install_package (opkg, "aspell", progress_callback, "Installing..."); + err = opkg_install_package (opkg, TEST_PACKAGE, progress_callback, "Installing..."); printf ("\nopkg_install_package returned %d (%s)\n", err, errors[err]); - err = opkg_upgrade_package (opkg, "aspell", progress_callback, "Upgrading..."); + err = opkg_upgrade_package (opkg, TEST_PACKAGE, progress_callback, "Upgrading..."); printf ("\nopkg_upgrade_package returned %d (%s)\n", err, errors[err]); - err = opkg_remove_package (opkg, "aspell", progress_callback, "Removing..."); + err = opkg_remove_package (opkg, TEST_PACKAGE, progress_callback, "Removing..."); printf ("\nopkg_remove_package returned %d (%s)\n", err, errors[err]); printf ("Listing upgradable packages...\n"); -- 2.25.1