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