Skip to content

Commit

Permalink
Refactor s backend into shared helper functions
Browse files Browse the repository at this point in the history
This will be useful for the next commit.

This still is a mess of C and C++ style strings that we want to clean
up later by adding C++ string based path handling and may be using the
filesystem C++ library.

Related: #3341
  • Loading branch information
ffesti committed Nov 11, 2024
1 parent bd907b0 commit 5ee40a5
Showing 1 changed file with 56 additions and 39 deletions.
95 changes: 56 additions & 39 deletions lib/keystore.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ using namespace rpm;

static int makePubkeyHeader(rpmts ts, rpmPubkey key, Header * hdrp);

rpmRC keystore_fs::load_keys(rpmtxn txn, rpmKeyring keyring)
static rpmRC load_keys_from_glob(rpmtxn txn, rpmKeyring keyring, string glob)
{
ARGV_t files = NULL;
/* XXX TODO: deal with chroot path issues */
char *pkpath = rpmGetPath(rpmtxnRootDir(txn), "%{_keyringpath}/*.key", NULL);
char *pkpath = rpmGetPath(rpmtxnRootDir(txn), glob.c_str(), NULL);

rpmlog(RPMLOG_DEBUG, "loading keyring from pubkeys in %s\n", pkpath);
if (rpmGlob(pkpath, NULL, &files)) {
Expand All @@ -55,6 +55,53 @@ rpmRC keystore_fs::load_keys(rpmtxn txn, rpmKeyring keyring)
return RPMRC_OK;
}

static rpmRC write_key_to_disk(rpmPubkey key, string & dir, string & filename, int replace, rpmFlags flags)
{
rpmRC rc = RPMRC_FAIL;
char *keyval = rpmPubkeyArmorWrap(key);
string tmppath = "";
string path = dir + "/" + filename;

if (replace) {
tmppath = dir + "/" + filename + ".new";
unlink(tmppath.c_str());
}

if (rpmMkdirs(NULL, dir.c_str())) {
rpmlog(RPMLOG_ERR, _("failed to create keyring directory %s: %s\n"),
path.c_str(), strerror(errno));
goto exit;
}

if (FD_t fd = Fopen(replace ? tmppath.c_str() : path.c_str(), "wx")) {
size_t keylen = strlen(keyval);
if (Fwrite(keyval, 1, keylen, fd) == keylen)
rc = RPMRC_OK;
Fclose(fd);
}
if (!rc && replace && rename(tmppath.c_str(), path.c_str()) != 0)
rc = RPMRC_FAIL;

if (rc) {
rpmlog(RPMLOG_ERR, _("failed to import key: %s: %s\n"),
replace ? tmppath.c_str() : path.c_str(), strerror(errno));
if (replace)
unlink(tmppath.c_str());
}

exit:
free(keyval);
return rc;
}


/*****************************************************************************/

rpmRC keystore_fs::load_keys(rpmtxn txn, rpmKeyring keyring)
{
return load_keys_from_glob(txn, keyring, "%{_keyringpath}/*.key");
}

rpmRC keystore_fs::delete_key(rpmtxn txn, const string & keyid, const string & newname)
{
rpmRC rc = RPMRC_NOTFOUND;
Expand Down Expand Up @@ -82,52 +129,22 @@ rpmRC keystore_fs::delete_key(rpmtxn txn, rpmPubkey key)
rpmRC keystore_fs::import_key(rpmtxn txn, rpmPubkey key, int replace, rpmFlags flags)
{
rpmRC rc = RPMRC_FAIL;
const char *fp = rpmPubkeyFingerprintAsHex(key);
char *keyfmt = rstrscat(NULL, "gpg-pubkey-", fp, ".key", NULL);
char *keyval = rpmPubkeyArmorWrap(key);
char *path = rpmGenPath(rpmtxnRootDir(txn), "%{_keyringpath}/", keyfmt);
char *tmppath = NULL;

if (replace) {
rasprintf(&tmppath, "%s.new", path);
unlink(tmppath);
}
string fp = rpmPubkeyFingerprintAsHex(key);
string keyfmt = "gpg-pubkey-" + fp + ".key";
char *dir = rpmGenPath(rpmtxnRootDir(txn), "%{_keyringpath}/", NULL);
string dirstr = dir;

if (rpmMkdirs(rpmtxnRootDir(txn), "%{_keyringpath}")) {
rpmlog(RPMLOG_ERR, _("failed to create keyring directory %s: %s\n"),
path, strerror(errno));
goto exit;
}

if (FD_t fd = Fopen(tmppath ? tmppath : path, "wx")) {
size_t keylen = strlen(keyval);
if (Fwrite(keyval, 1, keylen, fd) == keylen)
rc = RPMRC_OK;
Fclose(fd);
}
if (!rc && tmppath && rename(tmppath, path) != 0)
rc = RPMRC_FAIL;

if (rc) {
rpmlog(RPMLOG_ERR, _("failed to import key: %s: %s\n"),
tmppath ? tmppath : path, strerror(errno));
if (tmppath)
unlink(tmppath);
}
rc = write_key_to_disk(key, dirstr, keyfmt, replace, flags);

if (!rc && replace) {
/* find and delete the old pubkey entry */
if (delete_key(txn, fp, keyfmt) == RPMRC_NOTFOUND) {
/* make sure an old, short keyid version gets removed */
delete_key(txn, fp+32, keyfmt);
delete_key(txn, fp.substr(32), keyfmt);
}
}

exit:
free(path);
free(keyval);
free(keyfmt);
free(tmppath);
free(dir);
return rc;
}

Expand Down

0 comments on commit 5ee40a5

Please sign in to comment.