From 29b3b9d76a8d6b9af6d6465a9f501c2e5066bea0 Mon Sep 17 00:00:00 2001 From: ticktock35 Date: Tue, 27 Oct 2009 12:45:12 +0000 Subject: [PATCH] Add sha256 ckecksums to okpg Thanks to Camille Moncelier http://groups.google.com/group/opkg-devel/browse_thread/thread/78a2eb328da0ef73?utoken=pV1Kli0AAADKDldt5ZXsDDLs9sWCpWZI0mClVcTs45ANzZ7C9NH-1YGBxa5Bow63PTuzFmQCb1c Here is a patch which adds sha256 checksum checking to Opkg. More Opkg patches will follow shortly (x509 and smime signature support, libcurl client/server authentication) I hope these patch will be useful and finds their ways into okpg Camille Moncelier http://devlife.org/ git-svn-id: http://opkg.googlecode.com/svn/trunk@220 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358 --- configure.ac | 11 +++++++++ libopkg/Makefile.am | 4 +++ libopkg/file_util.c | 55 ++++++++++++++++++++++++++++++++++++++++++ libopkg/file_util.h | 1 + libopkg/opkg.c | 2 ++ libopkg/opkg.h | 3 ++- libopkg/opkg_error.h | 1 + libopkg/opkg_install.c | 19 +++++++++++++++ libopkg/pkg.c | 26 +++++++++++++++++++- libopkg/pkg.h | 3 +++ libopkg/pkg_parse.c | 4 +++ 11 files changed, 127 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 4346373..9c108f3 100644 --- a/configure.ac +++ b/configure.ac @@ -37,6 +37,17 @@ if test "x$want_curl" = "xyes"; then AC_DEFINE(HAVE_CURL, 1, [Define if you want CURL support]) fi +# check for sha256 +AC_ARG_ENABLE(sha256, + AC_HELP_STRING([--enable-sha256], [Enable sha256sum check + [[default=yes]] ]), + [want_sha256="$enableval"], [want_sha256="yes"]) + +if test "x$want_sha256" = "xyes"; then + AC_DEFINE(HAVE_SHA256, 1, [Define if you want sha256 support]) +fi +AM_CONDITIONAL(HAVE_SHA256, test "x$want_sha256" = "xyes") + dnl ********** dnl GPGME diff --git a/libopkg/Makefile.am b/libopkg/Makefile.am index 0e9d3a9..28fdeb9 100644 --- a/libopkg/Makefile.am +++ b/libopkg/Makefile.am @@ -30,6 +30,10 @@ opkg_util_sources = file_util.c file_util.h opkg_message.h opkg_message.c md5.c sprintf_alloc.c sprintf_alloc.h str_util.c str_util.h \ xregex.c xregex.h xsystem.c xsystem.h +if HAVE_SHA256 +opkg_util_sources += sha256.c sha256.h +endif + lib_LTLIBRARIES = libopkg.la libopkg_la_SOURCES = \ $(opkg_libcore_sources) \ diff --git a/libopkg/file_util.c b/libopkg/file_util.c index fad4178..4176257 100644 --- a/libopkg/file_util.c +++ b/libopkg/file_util.c @@ -25,6 +25,10 @@ #include "libbb/libbb.h" #undef strlen +#if defined HAVE_SHA256 +#include "sha256.h" +#endif + int file_exists(const char *file_name) { int err; @@ -175,3 +179,54 @@ char *file_md5sum_alloc(const char *file_name) return md5sum_hex; } +#ifdef HAVE_SHA256 +char *file_sha256sum_alloc(const char *file_name) +{ + static const int sha256sum_bin_len = 32; + static const int sha256sum_hex_len = 64; + + static const unsigned char bin2hex[16] = { + '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' + }; + + int i, err; + FILE *file; + char *sha256sum_hex; + unsigned char sha256sum_bin[sha256sum_bin_len]; + + sha256sum_hex = calloc(1, sha256sum_hex_len + 1); + if (sha256sum_hex == NULL) { + fprintf(stderr, "%s: out of memory\n", __FUNCTION__); + return strdup(""); + } + + file = fopen(file_name, "r"); + if (file == NULL) { + fprintf(stderr, "%s: Failed to open file %s: %s\n", + __FUNCTION__, file_name, strerror(errno)); + return strdup(""); + } + + err = sha256_stream(file, sha256sum_bin); + if (err) { + fprintf(stderr, "%s: ERROR computing sha256sum for %s: %s\n", + __FUNCTION__, file_name, strerror(err)); + return strdup(""); + } + + fclose(file); + + for (i=0; i < sha256sum_bin_len; i++) { + sha256sum_hex[i*2] = bin2hex[sha256sum_bin[i] >> 4]; + sha256sum_hex[i*2+1] = bin2hex[sha256sum_bin[i] & 0xf]; + } + + sha256sum_hex[sha256sum_hex_len] = '\0'; + + return sha256sum_hex; +} + +#endif diff --git a/libopkg/file_util.h b/libopkg/file_util.h index bcfb3cb..184e04d 100644 --- a/libopkg/file_util.h +++ b/libopkg/file_util.h @@ -25,5 +25,6 @@ int file_move(const char *src, const char *dest); int file_copy(const char *src, const char *dest); int file_mkdir_hier(const char *path, long mode); char *file_md5sum_alloc(const char *file_name); +char *file_sha256sum_alloc(const char *file_name); #endif diff --git a/libopkg/opkg.c b/libopkg/opkg.c index 4799dc1..a20023e 100644 --- a/libopkg/opkg.c +++ b/libopkg/opkg.c @@ -531,6 +531,7 @@ opkg_install_package (opkg_t *opkg, const char *package_name, opkg_progress_call case OPKG_INSTALL_ERR_ALREADY_INSTALLED: return OPKG_PACKAGE_ALREADY_INSTALLED; case OPKG_INSTALL_ERR_SIGNATURE: return OPKG_GPG_ERROR; case OPKG_INSTALL_ERR_MD5: return OPKG_MD5_ERROR; + case OPKG_INSTALL_ERR_SHA256: return OPKG_SHA256_ERROR; default: return OPKG_UNKNOWN_ERROR; } } @@ -670,6 +671,7 @@ opkg_upgrade_package (opkg_t *opkg, const char *package_name, opkg_progress_call case OPKG_INSTALL_ERR_ALREADY_INSTALLED: return OPKG_PACKAGE_ALREADY_INSTALLED; case OPKG_INSTALL_ERR_SIGNATURE: return OPKG_GPG_ERROR; case OPKG_INSTALL_ERR_MD5: return OPKG_MD5_ERROR; + case OPKG_INSTALL_ERR_SHA256: return OPKG_SHA256_ERROR; default: return OPKG_UNKNOWN_ERROR; } } diff --git a/libopkg/opkg.h b/libopkg/opkg.h index 970590c..4c34c32 100644 --- a/libopkg/opkg.h +++ b/libopkg/opkg.h @@ -43,7 +43,8 @@ enum _opkg_error_code_t OPKG_PACKAGE_NOT_FOUND, OPKG_PACKAGE_NOT_INSTALLED, OPKG_GPG_ERROR, - OPKG_MD5_ERROR + OPKG_MD5_ERROR, + OPKG_SHA256_ERROR }; struct _opkg_package_t diff --git a/libopkg/opkg_error.h b/libopkg/opkg_error.h index a99da37..43a5507 100644 --- a/libopkg/opkg_error.h +++ b/libopkg/opkg_error.h @@ -41,6 +41,7 @@ enum opkg_error { OPKG_INSTALL_ERR_SIGNATURE, OPKG_INSTALL_ERR_MD5, OPKG_INSTALL_ERR_INTERNAL, + OPKG_INSTALL_ERR_SHA256, }; typedef enum opkg_error opkg_error_t; diff --git a/libopkg/opkg_install.c b/libopkg/opkg_install.c index aba0d1e..750ea65 100644 --- a/libopkg/opkg_install.c +++ b/libopkg/opkg_install.c @@ -766,6 +766,9 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) abstract_pkg_t *ab_pkg = NULL; int old_state_flag; char* file_md5; +#ifdef HAVE_SHA256 + char* file_sha256; +#endif char *pkgid; if ( from_upgrade ) @@ -874,6 +877,22 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) free(file_md5); } +#ifdef HAVE_SHA256 + /* Check for sha256 value */ + if(pkg->sha256sum) + { + file_sha256 = file_sha256sum_alloc(pkg->local_filename); + if (strcmp(file_sha256, pkg->sha256sum)) + { + opkg_message(conf, OPKG_ERROR, + "Package %s sha256sum mismatch. Either the opkg or the package index are corrupt. Try 'opkg update'.\n", + pkg->name); + free(file_sha256); + return OPKG_INSTALL_ERR_SHA256; + } + } +#endif + if (pkg->tmp_unpack_dir == NULL) { unpack_pkg_control_files(conf, pkg); } diff --git a/libopkg/pkg.c b/libopkg/pkg.c index 1ab24e1..0c7bb5a 100644 --- a/libopkg/pkg.c +++ b/libopkg/pkg.c @@ -131,6 +131,9 @@ int pkg_init(pkg_t *pkg) pkg->local_filename = NULL; pkg->tmp_unpack_dir = NULL; pkg->md5sum = NULL; +#if defined HAVE_SHA256 + pkg->sha256sum = NULL; +#endif pkg->size = NULL; pkg->installed_size = NULL; pkg->priority = NULL; @@ -255,6 +258,10 @@ void pkg_deinit(pkg_t *pkg) pkg->tmp_unpack_dir = NULL; free(pkg->md5sum); pkg->md5sum = NULL; +#if defined HAVE_SHA256 + free(pkg->sha256sum); + pkg->sha256sum = NULL; +#endif free(pkg->size); pkg->size = NULL; free(pkg->installed_size); @@ -405,6 +412,10 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status) oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir); if (!oldpkg->md5sum) oldpkg->md5sum = str_dup_safe(newpkg->md5sum); +#if defined HAVE_SHA256 + if (!oldpkg->sha256sum) + oldpkg->sha256sum = str_dup_safe(newpkg->sha256sum); +#endif if (!oldpkg->size) oldpkg->size = str_dup_safe(newpkg->size); if (!oldpkg->installed_size) @@ -955,7 +966,7 @@ char * pkg_formatted_field(pkg_t *pkg, const char *field ) break; case 's': case 'S': { - /* Section | Size | Source | Status | Suggests */ + /* Section | SHA256sum | Size | Source | Status | Suggests */ if (strcasecmp(field, "Section") == 0) { /* Section */ if (pkg->section) { @@ -967,6 +978,19 @@ char * pkg_formatted_field(pkg_t *pkg, const char *field ) temp[0]='\0'; snprintf(temp, (strlen(pkg->section)+11), "Section: %s\n", pkg->section); } +#if defined HAVE_SHA256 + } else if (strcasecmp(field, "SHA256sum") == 0) { + /* SHA256sum */ + if (pkg->sha256sum) { + temp = (char *)realloc(temp,strlen(pkg->sha256sum)+13); + if ( temp == NULL ){ + fprintf(stderr, "%s: out of memory\n", __FUNCTION__); + return NULL; + } + temp[0]='\0'; + snprintf(temp, (strlen(pkg->sha256sum)+13), "SHA256sum: %s\n", pkg->sha256sum); + } +#endif } else if (strcasecmp(field, "Size") == 0) { /* Size */ if (pkg->size) { diff --git a/libopkg/pkg.h b/libopkg/pkg.h index a7c98ec..2d9ab40 100644 --- a/libopkg/pkg.h +++ b/libopkg/pkg.h @@ -161,6 +161,9 @@ struct pkg char *url; char *tmp_unpack_dir; char *md5sum; +#if defined HAVE_SHA256 + char *sha256sum; +#endif char *size; char *installed_size; char *priority; diff --git a/libopkg/pkg_parse.c b/libopkg/pkg_parse.c index 76cd648..a588e18 100644 --- a/libopkg/pkg_parse.c +++ b/libopkg/pkg_parse.c @@ -266,6 +266,10 @@ int pkg_parse_raw(pkg_t *pkg, char ***raw, pkg_src_t *src, pkg_dest_t *dest) case 'S': if(isGenericFieldType("Section:", *lines)) pkg->section = parseGenericFieldType("Section", *lines); +#ifdef HAVE_SHA256 + else if(isGenericFieldType("SHA256sum:", *lines)) + pkg->sha256sum = parseGenericFieldType("SHA256sum", *lines); +#endif else if(isGenericFieldType("Size:", *lines)) pkg->size = parseGenericFieldType("Size", *lines); else if(isGenericFieldType("Source:", *lines)) -- 2.25.1