summaryrefslogtreecommitdiff
path: root/lib/libalpm
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-09-19 20:40:32 -0500
committerDan McGee <dan@archlinux.org>2011-09-20 10:23:11 -0500
commitafdbfc05f771f2c684ee195b46d26b3d08a67085 (patch)
treeb4906677251278e46545e1354676c0ab0f9fe614 /lib/libalpm
parent7eb2f0cd151998d36746e2eb14cad2a3f8fb708b (diff)
Extract an _alpm_pkg_validate_internal() method
_alpm_pkg_load_internal() was becoming a monster. Extract the top bit of the method that dealt with checksum and signature validation into a separate method that should be called before one loads a package to ensure it is valid. Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'lib/libalpm')
-rw-r--r--lib/libalpm/be_package.c89
-rw-r--r--lib/libalpm/package.h6
-rw-r--r--lib/libalpm/sync.c10
3 files changed, 68 insertions, 37 deletions
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index ff820b80..b6cb8c4e 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -273,42 +273,26 @@ static alpm_file_t *files_msort(alpm_file_t *files, size_t n)
}
/**
- * Load a package and create the corresponding alpm_pkg_t struct.
+ * Validate a package.
* @param handle the context handle
* @param pkgfile path to the package file
* @param syncpkg package object to load verification data from (md5sum,
* sha256sum, and/or base64 signature)
- * @param full whether to stop the load after metadata is read or continue
- * through the full archive
* @param level the required level of signature verification
- * @return An information filled alpm_pkg_t struct
+ * @return 0 if package is fully valid, -1 and pm_errno otherwise
*/
-alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
- alpm_pkg_t *syncpkg, int full, alpm_siglevel_t level)
+int _alpm_pkg_validate_internal(alpm_handle_t *handle,
+ const char *pkgfile, alpm_pkg_t *syncpkg, alpm_siglevel_t level)
{
- int ret, has_sig, config = 0;
- struct archive *archive;
- struct archive_entry *entry;
- alpm_pkg_t *newpkg = NULL;
- struct stat st;
- size_t files_count = 0, files_size = 0;
- alpm_file_t *files = NULL;
+ int has_sig;
if(pkgfile == NULL || strlen(pkgfile) == 0) {
- RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL);
+ RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
}
- /* attempt to stat the package file, ensure it exists */
- if(stat(pkgfile, &st) == 0) {
- newpkg = _alpm_pkg_new();
- if(newpkg == NULL) {
- RET_ERR(handle, ALPM_ERR_MEMORY, NULL);
- }
- newpkg->filename = strdup(pkgfile);
- newpkg->size = st.st_size;
- } else {
- /* couldn't stat the pkgfile, return an error */
- RET_ERR(handle, ALPM_ERR_PKG_NOT_FOUND, NULL);
+ /* attempt to access the package file, ensure it exists */
+ if(access(pkgfile, R_OK) != 0) {
+ RET_ERR(handle, ALPM_ERR_PKG_NOT_FOUND, -1);
}
/* can we get away with skipping checksums? */
@@ -330,8 +314,7 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
_alpm_log(handle, ALPM_LOG_DEBUG, "md5sum: %s\n", syncpkg->md5sum);
_alpm_log(handle, ALPM_LOG_DEBUG, "checking md5sum for %s\n", pkgfile);
if(_alpm_test_checksum(pkgfile, syncpkg->md5sum, ALPM_CSUM_MD5) != 0) {
- alpm_pkg_free(newpkg);
- RET_ERR(handle, ALPM_ERR_PKG_INVALID_CHECKSUM, NULL);
+ RET_ERR(handle, ALPM_ERR_PKG_INVALID_CHECKSUM, -1);
}
}
@@ -339,8 +322,7 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
_alpm_log(handle, ALPM_LOG_DEBUG, "sha256sum: %s\n", syncpkg->sha256sum);
_alpm_log(handle, ALPM_LOG_DEBUG, "checking sha256sum for %s\n", pkgfile);
if(_alpm_test_checksum(pkgfile, syncpkg->sha256sum, ALPM_CSUM_SHA256) != 0) {
- alpm_pkg_free(newpkg);
- RET_ERR(handle, ALPM_ERR_PKG_INVALID_CHECKSUM, NULL);
+ RET_ERR(handle, ALPM_ERR_PKG_INVALID_CHECKSUM, -1);
}
}
}
@@ -353,12 +335,49 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
level & ALPM_SIG_PACKAGE_OPTIONAL, level & ALPM_SIG_PACKAGE_MARGINAL_OK,
level & ALPM_SIG_PACKAGE_UNKNOWN_OK)) {
handle->pm_errno = ALPM_ERR_PKG_INVALID_SIG;
- _alpm_pkg_free(newpkg);
- return NULL;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Load a package and create the corresponding alpm_pkg_t struct.
+ * @param handle the context handle
+ * @param pkgfile path to the package file
+ * @param full whether to stop the load after metadata is read or continue
+ * through the full archive
+ */
+alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
+ const char *pkgfile, int full)
+{
+ int ret, config = 0;
+ struct archive *archive;
+ struct archive_entry *entry;
+ alpm_pkg_t *newpkg = NULL;
+ struct stat st;
+ size_t files_count = 0, files_size = 0;
+ alpm_file_t *files = NULL;
+
+ if(pkgfile == NULL || strlen(pkgfile) == 0) {
+ RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL);
+ }
+
+ /* attempt to stat the package file, ensure it exists */
+ if(stat(pkgfile, &st) == 0) {
+ newpkg = _alpm_pkg_new();
+ if(newpkg == NULL) {
+ RET_ERR(handle, ALPM_ERR_MEMORY, NULL);
}
+ newpkg->filename = strdup(pkgfile);
+ newpkg->size = st.st_size;
+ } else {
+ /* couldn't stat the pkgfile, return an error */
+ RET_ERR(handle, ALPM_ERR_PKG_NOT_FOUND, NULL);
}
- /* next- try to create an archive object to read in the package */
+ /* try to create an archive object to read in the package */
if((archive = archive_read_new()) == NULL) {
alpm_pkg_free(newpkg);
RET_ERR(handle, ALPM_ERR_LIBARCHIVE, NULL);
@@ -490,7 +509,11 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful
CHECK_HANDLE(handle, return -1);
ASSERT(pkg != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
- *pkg = _alpm_pkg_load_internal(handle, filename, NULL, full, level);
+ if(_alpm_pkg_validate_internal(handle, filename, NULL, level) == -1) {
+ /* pm_errno is set by pkg_validate */
+ return -1;
+ }
+ *pkg = _alpm_pkg_load_internal(handle, filename, full);
if(*pkg == NULL) {
/* pm_errno is set by pkg_load */
return -1;
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index c19625c1..fbae766c 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -135,8 +135,10 @@ void _alpm_pkg_free(alpm_pkg_t *pkg);
void _alpm_pkg_free_trans(alpm_pkg_t *pkg);
-alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
- alpm_pkg_t *syncpkg, int full, alpm_siglevel_t level);
+int _alpm_pkg_validate_internal(alpm_handle_t *handle,
+ const char *pkgfile, alpm_pkg_t *syncpkg, alpm_siglevel_t level);
+alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
+ const char *pkgfile, int full);
int _alpm_pkg_cmp(const void *p1, const void *p2);
int _alpm_pkg_compare_versions(alpm_pkg_t *local_pkg, alpm_pkg_t *pkg);
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 732e786f..a5281078 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -971,14 +971,20 @@ int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
_alpm_log(handle, ALPM_LOG_DEBUG,
"replacing pkgcache entry with package file for target %s\n",
spkg->name);
- alpm_pkg_t *pkgfile =_alpm_pkg_load_internal(handle, filepath, spkg, 1, level);
- if(!pkgfile) {
+ if(_alpm_pkg_validate_internal(handle, filepath, spkg, level) == -1) {
prompt_to_delete(handle, filepath, handle->pm_errno);
errors++;
*data = alpm_list_add(*data, strdup(spkg->filename));
FREE(filepath);
continue;
}
+ alpm_pkg_t *pkgfile =_alpm_pkg_load_internal(handle, filepath, 1);
+ if(!pkgfile) {
+ errors++;
+ *data = alpm_list_add(*data, strdup(spkg->filename));
+ FREE(filepath);
+ continue;
+ }
FREE(filepath);
pkgfile->reason = spkg->reason; /* copy over install reason */
i->data = pkgfile;