|
3 | 3 | #include <string>
|
4 | 4 |
|
5 | 5 | #include <fcntl.h>
|
| 6 | +#include <unistd.h> |
6 | 7 |
|
7 | 8 | #include <rpm/header.h>
|
8 | 9 | #include <rpm/rpmbase64.h>
|
@@ -148,6 +149,94 @@ rpmRC keystore_fs::import_key(rpmtxn txn, rpmPubkey key, int replace, rpmFlags f
|
148 | 149 | return rc;
|
149 | 150 | }
|
150 | 151 |
|
| 152 | +/*****************************************************************************/ |
| 153 | + |
| 154 | +static rpmRC acquire_write_lock(rpmtxn txn) |
| 155 | +{ |
| 156 | + char * keyringpath = rpmGenPath(rpmtxnRootDir(txn), "%{_keyringpath}/", NULL); |
| 157 | + char * lockpath = rpmGenPath(rpmtxnRootDir(txn), "%{_keyringpath}/", "writelock"); |
| 158 | + FILE* fp = NULL; |
| 159 | + rpmRC rc = RPMRC_FAIL; |
| 160 | + |
| 161 | + if (rpmMkdirs(NULL, keyringpath)) { |
| 162 | + rpmlog(RPMLOG_ERR, _("failed to create keyring directory %s: %s\n"), |
| 163 | + keyringpath, strerror(errno)); |
| 164 | + goto exit; |
| 165 | + } |
| 166 | + |
| 167 | + fp = std::fopen(lockpath, "wx"); |
| 168 | + |
| 169 | + if (!fp) { |
| 170 | + rpmlog(RPMLOG_ERR, _("Can't acquire writelock for keyring at %s\n"), keyringpath); |
| 171 | + } else { |
| 172 | + rc = RPMRC_OK; |
| 173 | + std::fclose(fp); |
| 174 | + } |
| 175 | + |
| 176 | + exit: |
| 177 | + free(keyringpath); |
| 178 | + free(lockpath); |
| 179 | + return rc; |
| 180 | +} |
| 181 | + |
| 182 | +static void free_write_lock(rpmtxn txn) |
| 183 | +{ |
| 184 | + char * path = rpmGenPath(rpmtxnRootDir(txn), "%{_keyringpath}/", "writelock"); |
| 185 | + unlink(path); |
| 186 | + free(path); |
| 187 | +} |
| 188 | + |
| 189 | +rpmRC keystore_openpgp_cert_d::load_keys(rpmtxn txn, rpmKeyring keyring) |
| 190 | +{ |
| 191 | + return load_keys_from_glob(txn, keyring, "%{_keyringpath}/*/*"); |
| 192 | +} |
| 193 | + |
| 194 | +rpmRC keystore_openpgp_cert_d::delete_key(rpmtxn txn, rpmPubkey key) |
| 195 | +{ |
| 196 | + rpmRC rc = RPMRC_NOTFOUND; |
| 197 | + |
| 198 | + if (acquire_write_lock(txn) != RPMRC_OK) |
| 199 | + return RPMRC_FAIL; |
| 200 | + |
| 201 | + string fp = rpmPubkeyFingerprintAsHex(key); |
| 202 | + string dir = fp.substr(0, 2); |
| 203 | + string filename = fp.substr(2); |
| 204 | + char * filepath = rpmGetPath(rpmtxnRootDir(txn), "%{_keyringpath}/", dir.c_str(), "/", filename.c_str(), NULL); |
| 205 | + char * dirpath = rpmGetPath(rpmtxnRootDir(txn), "%{_keyringpath}/", dir.c_str(), NULL); |
| 206 | + |
| 207 | + if (!access(filepath, F_OK)) |
| 208 | + rc = unlink(filepath) ? RPMRC_FAIL : RPMRC_OK; |
| 209 | + /* delete directory if empty */ |
| 210 | + rmdir(dirpath); |
| 211 | + |
| 212 | + free(filepath); |
| 213 | + free(dirpath); |
| 214 | + free_write_lock(txn); |
| 215 | + return rc; |
| 216 | +} |
| 217 | + |
| 218 | +rpmRC keystore_openpgp_cert_d::import_key(rpmtxn txn, rpmPubkey key, int replace, rpmFlags flags) |
| 219 | +{ |
| 220 | + rpmRC rc = RPMRC_NOTFOUND; |
| 221 | + |
| 222 | + if ((rc = acquire_write_lock(txn)) == RPMRC_OK) { |
| 223 | + string fp = rpmPubkeyFingerprintAsHex(key); |
| 224 | + string dir = fp.substr(0, 2); |
| 225 | + string filename = fp.substr(2); |
| 226 | + char *dirpath = rpmGetPath(rpmtxnRootDir(txn), "%{_keyringpath}/", dir.c_str(), NULL); |
| 227 | + string dirstr = dirpath; |
| 228 | + |
| 229 | + rc = write_key_to_disk(key, dirstr, filename, replace, flags); |
| 230 | + |
| 231 | + free_write_lock(txn); |
| 232 | + free(dirpath); |
| 233 | + } |
| 234 | + |
| 235 | + return rc; |
| 236 | +} |
| 237 | + |
| 238 | +/*****************************************************************************/ |
| 239 | + |
151 | 240 | rpmRC keystore_rpmdb::load_keys(rpmtxn txn, rpmKeyring keyring)
|
152 | 241 | {
|
153 | 242 | Header h;
|
|
0 commit comments