Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xbps-install: add --verify-sig option. #384

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions bin/xbps-install/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ usage(bool fail)
" --reproducible Enable reproducible mode in pkgdb\n"
" -S, --sync Sync remote repository index\n"
" -u, --update Update target package(s)\n"
" --verify-sigs Verify package signatures even for local repositories\n"
" -v, --verbose Verbose messages\n"
" -y, --yes Assume yes to all questions\n"
" -V, --version Show XBPS version\n");
Expand Down Expand Up @@ -118,6 +119,7 @@ main(int argc, char **argv)
{ "version", no_argument, NULL, 'V' },
{ "yes", no_argument, NULL, 'y' },
{ "reproducible", no_argument, NULL, 1 },
{ "verify-sig", no_argument, NULL, 2 },
{ NULL, 0, NULL, 0 }
};
struct xbps_handle xh;
Expand All @@ -138,6 +140,9 @@ main(int argc, char **argv)
case 1:
flags |= XBPS_FLAG_INSTALL_REPRO;
break;
case 2:
flags |= XBPS_FLAG_VERIFY_LOCAL_REPO;
break;
case 'A':
flags |= XBPS_FLAG_INSTALL_AUTO;
break;
Expand Down
7 changes: 7 additions & 0 deletions include/xbps.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,13 @@
*/
#define XBPS_FLAG_KEEP_CONFIG 0x00010000

/**
* @def XBPS_FLAG_VERIFY_LOCAL_REPO
* Verify package signatures even for local repositories.
* Must be set through the xbps_handle::flags member.
*/
#define XBPS_FLAG_VERIFY_LOCAL_REPO 0x00020000

/**
* @def XBPS_FETCH_CACHECONN
* Default (global) limit of cached connections used in libfetch.
Expand Down
56 changes: 34 additions & 22 deletions lib/transaction_fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,44 +47,56 @@ verify_binpkg(struct xbps_handle *xhp, xbps_dictionary_t pkgd)
return ENOMEM;
}
/*
* For pkgs in local repos check the sha256 hash.
* For pkgs in remote repos check the RSA signature.
* For all pkgs, check the sha256 hash.
* For pkgs in local repos, check the RSA sig if requested.
* For pkgs in remote repos, always check the RSA signature.
*/
if ((repo = xbps_rpool_get_repo(repoloc)) == NULL) {
rv = errno;
xbps_dbg_printf(xhp, "%s: failed to get repository "
"%s: %s\n", pkgver, repoloc, strerror(errno));
goto out;
}
if (repo->is_remote) {
/* remote repo */

/* check sha256 */
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY, 0, pkgver,
"%s: verifying SHA256 hash...", pkgver);
xbps_dictionary_get_cstring_nocopy(pkgd, "filename-sha256", &sha256);
if ((rv = xbps_file_sha256_check(binfile, sha256)) != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY_FAIL, rv, pkgver,
"%s: SHA256 hash is not valid: %s", pkgver, strerror(rv));
goto out;
}

if (repo->is_remote || xhp->flags & XBPS_FLAG_VERIFY_LOCAL_REPO) {
/* check RSA sig */
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY, 0, pkgver,
"%s: verifying RSA signature...", pkgver);

if (!xbps_verify_file_signature(repo, binfile)) {
char *sigfile;
rv = EPERM;
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY_FAIL, rv, pkgver,
"%s: the RSA signature is not valid!", pkgver);
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY_FAIL, rv, pkgver,
"%s: removed pkg archive and its signature.", pkgver);
(void)remove(binfile);
sigfile = xbps_xasprintf("%s.sig", binfile);
(void)remove(sigfile);
free(sigfile);
goto out;
}
} else {
/* local repo */
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY, 0, pkgver,
"%s: verifying SHA256 hash...", pkgver);
xbps_dictionary_get_cstring_nocopy(pkgd, "filename-sha256", &sha256);
if ((rv = xbps_file_sha256_check(binfile, sha256)) != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY_FAIL, rv, pkgver,
"%s: SHA256 hash is not valid: %s", pkgver, strerror(rv));
if (repo->is_remote) {
/*
* Don't remove files from local repositories, since we might
* not be the "owner"; with the XBPS cache, we are the owners.
*/
char *sigfile;
const char *errmsg;
sigfile = xbps_xasprintf("%s.sig", binfile);
assert(sigfile);
ericonr marked this conversation as resolved.
Show resolved Hide resolved
if (remove(binfile) == 0 && remove(sigfile) == 0) {
errmsg = "removed pkg archive and its signature";
} else {
errmsg = "there was an error removing pkg archive and its signature";
}
free(sigfile);
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY_FAIL, rv, pkgver,
"%s: %s.", pkgver, errmsg);
}
goto out;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This goto is, and was, excessive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to keep it so people didn't forget to add it back if it became necessary to add more stuff to do after the conditionals are done. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine, let it stay.

}

}
out:
free(binfile);
Expand Down