00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013
00014
00015 #include "zypp/base/String.h"
00016 #include "zypp/base/Regex.h"
00017 #include "zypp/PublicKey.h"
00018 #include "zypp/ExternalProgram.h"
00019 #include "zypp/TmpPath.h"
00020 #include "zypp/PathInfo.h"
00021 #include "zypp/base/Exception.h"
00022 #include "zypp/base/Logger.h"
00023
00024 using std::endl;
00025
00027 namespace zypp
00028 {
00029
00030
00031
00033 struct PublicKey::Impl
00034 {
00035 Impl()
00036 {}
00037
00038 Impl(const Pathname &file)
00039 {
00040 readFromFile(file);
00041 MIL << "Done reading key" << std::endl;
00042 }
00043
00044 public:
00046 static shared_ptr<Impl> nullimpl()
00047 {
00048 static shared_ptr<Impl> _nullimpl( new Impl );
00049 return _nullimpl;
00050 }
00051
00052
00053 std::string asString() const
00054 {
00055 return "[" + id() + "] [" + name() + "] [" + fingerprint() + "]";
00056 }
00057
00058 std::string armoredData() const
00059 { return _data; }
00060
00061 std::string id() const
00062 { return _id; }
00063
00064 std::string name() const
00065 { return _name; }
00066
00067 std::string fingerprint() const
00068 { return _fingerprint; }
00069
00070 Pathname path() const
00071 {
00072 return _data_file.path();
00073
00074 }
00075
00076 protected:
00077
00078 void readFromFile( const Pathname &keyfile)
00079 {
00080 static str::regex rxColons("^([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):\n$");
00081
00082 PathInfo info(keyfile);
00083 MIL << "Reading pubkey from " << keyfile << " of size " << info.size() << " and sha1 " << filesystem::checksum(keyfile, "sha1")<< endl;
00084 if ( !info.isExist() )
00085 ZYPP_THROW(Exception("Can't read public key from " + keyfile.asString() + ", file not found"));
00086
00087 if ( copy( keyfile, _data_file.path() ) != 0 )
00088 ZYPP_THROW(Exception("Can't copy public key data from " + keyfile.asString() + " to " + _data_file.path().asString() ));
00089
00090
00091 filesystem::TmpDir dir;
00092
00093 const char* argv[] =
00094 {
00095 "gpg",
00096 "--no-default-keyring",
00097 "--homedir",
00098 dir.path().asString().c_str(),
00099 "--with-fingerprint",
00100 "--with-colons",
00101 "--quiet",
00102 "--no-tty",
00103 "--no-greeting",
00104 "--batch",
00105 "--status-fd",
00106 "1",
00107 _data_file.path().asString().c_str(),
00108 NULL
00109 };
00110
00111 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
00112
00113 std::string line;
00114 int count = 0;
00115
00116
00117
00118 for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
00119 {
00120
00121 str::smatch what;
00122 if(str::regex_match(line, what, rxColons))
00123 {
00124 if ( what[1] == "pub" )
00125 {
00126 _id = what[5];
00127 _name = what[10];
00128
00129 }
00130 else if ( what[1] == "fpr" )
00131 {
00132 _fingerprint = what[10];
00133 }
00134
00135 }
00136 }
00137 prog.close();
00138
00139 if (_id.size() == 0 )
00140 ZYPP_THROW(BadKeyException("File " + keyfile.asString() + " doesn't contain public key data" , keyfile));
00141 }
00142
00143 private:
00144 std::string _id;
00145 std::string _name;
00146 std::string _fingerprint;
00147 std::string _data;
00148 filesystem::TmpFile _data_file;
00149
00150 private:
00151 friend Impl * rwcowClone<Impl>( const Impl * rhs );
00153 Impl * clone() const
00154 { return new Impl( *this ); }
00155 };
00157
00159
00160
00161
00162
00163 PublicKey::PublicKey()
00164 : _pimpl( Impl::nullimpl() )
00165 {}
00166
00167 PublicKey::PublicKey( const Pathname &file )
00168 : _pimpl( new Impl(file) )
00169 {}
00171
00172
00173
00174
00175 PublicKey::~PublicKey()
00176 {}
00177
00179
00180
00181
00183
00184 std::string PublicKey::asString() const
00185 {
00186 return _pimpl->asString();
00187 }
00188
00189 std::string PublicKey::armoredData() const
00190 { return _pimpl->armoredData(); }
00191
00192 std::string PublicKey::id() const
00193 { return _pimpl->id(); }
00194
00195 std::string PublicKey::name() const
00196 { return _pimpl->name(); }
00197
00198 std::string PublicKey::fingerprint() const
00199 { return _pimpl->fingerprint(); }
00200
00201 Pathname PublicKey::path() const
00202 { return _pimpl->path(); }
00203
00204 bool PublicKey::operator==( PublicKey b ) const
00205 {
00206 return (b.id() == id()) && (b.fingerprint() == fingerprint() );
00207 }
00208
00209 bool PublicKey::operator==( std::string sid ) const
00210 {
00211 return sid == id();
00212 }
00213
00215 }