16 #include <boost/thread/once.hpp> 17 #include <boost/interprocess/smart_ptr/scoped_ptr.hpp> 22 #undef ZYPP_BASE_LOGGER_LOGGROUP 23 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::gpg" 33 typedef boost::interprocess::scoped_ptr<gpgme_data, boost::function<void (gpgme_data_t)>>
GpgmeDataPtr;
34 typedef boost::interprocess::scoped_ptr<_gpgme_key, boost::function<void (gpgme_key_t)>>
GpgmeKeyPtr;
35 typedef boost::interprocess::scoped_ptr<FILE, boost::function<int (FILE *)>>
FILEPtr;
39 GpgmeErr( gpgme_error_t err_r = GPG_ERR_NO_ERROR )
42 operator gpgme_error_t()
const {
return _err; }
47 {
return str <<
"<" << gpgme_strsource(obj) <<
"> " << gpgme_strerror(obj); }
51 const char *version = gpgme_check_version(NULL);
54 MIL <<
"Initialized libgpgme version: " << version << endl;
58 MIL <<
"Initialized libgpgme with unknown version" << endl;
111 if (!
PathInfo( signature_r ).isExist())
112 return std::list<std::string>();
116 return std::list<std::string>();
119 GpgmeErr err = gpgme_data_new_from_stream (&fileData.get(), dataFile.get());
122 return std::list<std::string>();
125 FILEPtr sigFile(fopen(signature_r.
c_str(),
"rb"), fclose);
127 ERR <<
"Unable to open signature file '" << signature_r <<
"'" <<endl;
128 return std::list<std::string>();
132 err = gpgme_data_new_from_stream (&sigData.get(), sigFile.get());
135 return std::list<std::string>();
138 err = gpgme_op_verify(
_ctx, sigData.get(), fileData.get(), NULL);
139 if (err != GPG_ERR_NO_ERROR) {
141 return std::list<std::string>();
144 gpgme_verify_result_t res = gpgme_op_verify_result(
_ctx);
145 if (!res || !res->signatures) {
146 ERR <<
"Unable to read signature fingerprints" <<endl;
147 return std::list<std::string>();
150 bool foundBadSignature =
false;
151 std::list<std::string> signatures;
152 for ( gpgme_signature_t sig = res->signatures; sig; sig = sig->next ) {
160 std::string id( sig->fpr );
161 if (
id.size() > 16 )
162 id =
id.substr(
id.size()-16 );
163 signatures.push_back( std::move(
id) );
166 if ( sig->status != GPG_ERR_NO_ERROR )
168 if ( gpgme_err_code(sig->status) != GPG_ERR_KEY_EXPIRED )
170 if ( !foundBadSignature )
171 foundBadSignature =
true;
173 WAR <<
"Failed signature check: " << file_r <<
" " <<
GpgmeErr(sig->status) << endl;
178 WAR <<
"Legacy: Ignore expired key: " << file_r <<
" " <<
GpgmeErr(sig->status) << endl;
184 *verify_r = (!foundBadSignature);
200 if (err != GPG_ERR_NO_ERROR) {
202 return shared_ptr<KeyManagerCtx>();
206 err = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP);
207 if (err != GPG_ERR_NO_ERROR) {
210 return shared_ptr<KeyManagerCtx>();
214 me->_pimpl->_ctx = ctx;
222 gpgme_engine_info_t enginfo = gpgme_ctx_get_engine_info(
_pimpl->
_ctx);
226 GpgmeErr err = gpgme_ctx_set_engine_info(
228 GPGME_PROTOCOL_OpenPGP,
232 if (err != GPG_ERR_NO_ERROR) {
233 ERR <<
"Unable to set homedir " << err << endl;
242 gpgme_engine_info_t enginfo = gpgme_ctx_get_engine_info(
_pimpl->
_ctx);
251 std::list<PublicKeyData> keys;
255 gpgme_keylist_mode_t mode = GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_SIGS;
257 gpgme_op_keylist_start (
_pimpl->
_ctx, NULL, 0);
259 while (!(err = gpgme_op_keylist_next(
_pimpl->
_ctx, &key))) {
262 keys.push_back(data);
264 gpgme_key_release(key);
279 return std::list<PublicKeyData>();
283 return std::list<PublicKeyData>();
286 std::list<PublicKeyData> keys =
listKeys();
307 gpgme_op_keylist_start(
_pimpl->
_ctx, NULL, 0);
308 while (!(err = gpgme_op_keylist_next(
_pimpl->
_ctx, &key))) {
309 if (key->subkeys &&
id ==
str::asString(key->subkeys->keyid)) {
310 GpgmeKeyPtr(key, gpgme_key_release).swap(foundKey);
313 gpgme_key_release(key);
318 WAR <<
"Key " <<
id <<
"not found" << endl;
323 gpgme_key_t keyarray[2];
324 keyarray[0] = foundKey.get();
328 err = gpgme_data_new (&out.get());
336 err = gpgme_op_export_keys (
_pimpl->
_ctx, keyarray, 0, out.get());
338 int ret = gpgme_data_seek (out.get(), 0, SEEK_SET);
340 ERR <<
"Unable to seek in exported key data" << endl;
344 const int bufsize = 512;
345 char buf[bufsize + 1];
346 while ((ret = gpgme_data_read(out.get(), buf, bufsize)) > 0) {
347 stream.write(buf, ret);
352 ERR <<
"Unable to read exported key data" << endl;
356 ERR <<
"Error exporting key: "<< err << endl;
366 if ( !
PathInfo( keyfile ).isExist() ) {
367 ERR <<
"Keyfile '" << keyfile <<
"' does not exist.";
374 err = gpgme_data_new_from_file(&data.get(), keyfile.
c_str(), 1);
376 ERR <<
"Error importing key: "<< err << endl;
380 err = gpgme_op_import(
_pimpl->
_ctx, data.get());
382 ERR <<
"Error importing key: "<< err << endl;
384 return (err == GPG_ERR_NO_ERROR);
392 gpgme_op_keylist_start(
_pimpl->
_ctx, NULL, 0);
394 while (!(err = gpgme_op_keylist_next(
_pimpl->
_ctx, &key))) {
395 if (key->subkeys &&
id ==
str::asString(key->subkeys->keyid)) {
398 gpgme_key_release(key);
402 ERR <<
"Error deleting key: "<< err << endl;
407 gpgme_key_release(key);
411 WAR <<
"Key: '"<<
id <<
"' not found." << endl;
static Ptr createForOpenPGP()
Creates a new KeyManagerCtx for PGP.
std::list< PublicKeyData > readKeyFromFile(const Pathname &file)
Returns a list of all.
GpgmeErr(gpgme_error_t err_r=GPG_ERR_NO_ERROR)
std::list< std::string > readSignaturesFprs(const Pathname &signature_r)
Return all fingerprints found in signature_r.
Class representing one GPG Public Keys data.
const char * c_str() const
String representation.
String related utilities and Regular expression matching.
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
bool verify(const Pathname &file, const Pathname &signature)
Tries to verify file using signature, returns true on success.
boost::interprocess::scoped_ptr< FILE, boost::function< int(FILE *)> > FILEPtr
bool exportKey(const std::string &id, std::ostream &stream)
Exports the key with id into the given stream, returns true on success.
RW_pointer< Impl > _pimpl
Pointer to implementation.
boost::interprocess::scoped_ptr< gpgme_data, boost::function< void(gpgme_data_t)> > GpgmeDataPtr
bool importKey(const Pathname &keyfile)
Tries to import a key from keyfile, returns true on success.
Provide a new empty temporary directory and recursively delete it when no longer needed.
bool verifySignaturesFprs(const Pathname &file_r, const Pathname &signature_r)
Tries to verify the file_r using signature_r.
std::ostream & operator<<(std::ostream &str, const Arch::CompatEntry &obj)
bool deleteKey(const std::string &id)
Tries to delete a key specified by id, returns true on success.
std::list< PublicKeyData > listKeys()
Returns a list of all public keys found in the current keyring.
bool setHomedir(const Pathname &keyring_r)
Changes the keyring directory.
boost::interprocess::scoped_ptr< _gpgme_key, boost::function< void(gpgme_key_t)> > GpgmeKeyPtr
shared_ptr< KeyManagerCtx > Ptr
Wrapper class for ::stat/::lstat.
std::list< std::string > readSignatureFingerprints(const Pathname &signature)
Reads all fingerprints from the signature file , returns a list of all found fingerprints.
std::list< std::string > readSignaturesFprsOptVerify(const Pathname &signature_r, const Pathname &file_r="/dev/null", bool *verify_r=nullptr)
Return all fingerprints found in signature_r and optionally verify the file_r on the fly...
static PublicKeyData fromGpgmeKey(_gpgme_key *data)
Easy-to use interface to the ZYPP dependency resolver.
boost::once_flag gpgme_init_once