00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013 #include <vector>
00014
00015 #include "zypp/base/Logger.h"
00016 #include "zypp/base/Exception.h"
00017 #include "zypp/base/String.h"
00018
00019 #include "zypp/ExternalProgram.h"
00020 #include "zypp/PublicKey.h"
00021 #include "zypp/TmpPath.h"
00022 #include "zypp/PathInfo.h"
00023 #include "zypp/Date.h"
00024 #include "zypp/TmpPath.h"
00025
00026 using std::endl;
00027
00029 namespace zypp
00030 {
00031
00032
00033
00035 struct PublicKey::Impl
00036 {
00037 Impl()
00038 {}
00039
00040 Impl(const Pathname &file)
00041 {
00042 readFromFile(file);
00043 MIL << "Done reading key" << std::endl;
00044 }
00045
00046 public:
00048 static shared_ptr<Impl> nullimpl()
00049 {
00050 static shared_ptr<Impl> _nullimpl( new Impl );
00051 return _nullimpl;
00052 }
00053
00054 #warning FIX asString ====================================================================================
00055 std::string asString() const
00056 {
00057 return "[" + id() + "-" + str::hexstring(created(),8).substr(2) + "] [" + name() + "] [" + fingerprint() + "]";
00058 }
00059
00060 std::string armoredData() const
00061 { return _data; }
00062
00063 std::string id() const
00064 { return _id; }
00065
00066 std::string name() const
00067 { return _name; }
00068
00069 std::string fingerprint() const
00070 { return _fingerprint; }
00071
00072 Date created() const
00073 { return _created; }
00074
00075 Date expires() const
00076 { return _expires; }
00077
00078 Pathname path() const
00079 {
00080 return _data_file.path();
00081
00082 }
00083
00084 protected:
00085
00086 void readFromFile( const Pathname &keyfile)
00087 {
00088
00089 PathInfo info(keyfile);
00090 MIL << "Reading pubkey from " << keyfile << " of size " << info.size() << " and sha1 " << filesystem::checksum(keyfile, "sha1")<< endl;
00091 if ( !info.isExist() )
00092 ZYPP_THROW(Exception("Can't read public key from " + keyfile.asString() + ", file not found"));
00093
00094 if ( copy( keyfile, _data_file.path() ) != 0 )
00095 ZYPP_THROW(Exception("Can't copy public key data from " + keyfile.asString() + " to " + _data_file.path().asString() ));
00096
00097 filesystem::TmpDir dir;
00098 const char* argv[] =
00099 {
00100 "gpg",
00101 "-v",
00102 "--no-default-keyring",
00103 "--fixed-list-mode",
00104 "--with-fingerprint",
00105 "--with-colons",
00106 "--homedir",
00107 dir.path().asString().c_str(),
00108 "--quiet",
00109 "--no-tty",
00110 "--no-greeting",
00111 "--batch",
00112 "--status-fd",
00113 "1",
00114 _data_file.path().asString().c_str(),
00115 NULL
00116 };
00117
00118 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
00119
00120 std::string line;
00121 bool sawpub = false;
00122 bool sawsig = false;
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 for ( line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
00133 {
00134
00135 if ( line.empty() )
00136 continue;
00137 if ( line[line.size()-1] == '\n' )
00138 line.erase( line.size()-1 );
00139
00140
00141 std::vector<std::string> words;
00142 str::splitFields( line, std::back_inserter(words), ":" );
00143 if( words.empty() )
00144 continue;
00145
00146 if ( words[0] == "pub" )
00147 {
00148 if ( sawpub )
00149 continue;
00150 sawpub = true;
00151
00152 _id = words[4];
00153 _name = words[9];
00154 _created = Date(str::strtonum<Date::ValueType>(words[5]));
00155 _expires = Date(str::strtonum<Date::ValueType>(words[6]));
00156
00157 }
00158 else if ( words[0] == "sig" )
00159 {
00160 if ( sawsig || words[words.size()-2] != "13x" )
00161 continue;
00162 sawsig = true;
00163
00164 if ( ! words[5].empty() )
00165 _created = Date(str::strtonum<Date::ValueType>(words[5]));
00166 if ( ! words[6].empty() )
00167 _expires = Date(str::strtonum<Date::ValueType>(words[6]));
00168 }
00169 else if ( words[0] == "fpr" )
00170 {
00171 _fingerprint = words[9];
00172 }
00173 else if ( words[0] == "uid" )
00174 {
00175 if ( ! words[9].empty() )
00176 _name = words[9];
00177 }
00178 }
00179 prog.close();
00180
00181 if ( _id.size() == 0 )
00182 ZYPP_THROW( BadKeyException( "File " + keyfile.asString() + " doesn't contain public key data" , keyfile ) );
00183
00184
00185 str::replace_all( _name, "\\x3a", ":" );
00186 }
00187
00188 private:
00189 std::string _id;
00190 std::string _name;
00191 std::string _fingerprint;
00192 std::string _data;
00193 filesystem::TmpFile _data_file;
00194 Date _created;
00195 Date _expires;
00196
00197 private:
00198 friend Impl * rwcowClone<Impl>( const Impl * rhs );
00200 Impl * clone() const
00201 { return new Impl( *this ); }
00202 };
00204
00206
00207
00208
00209
00210 PublicKey::PublicKey()
00211 : _pimpl( Impl::nullimpl() )
00212 {}
00213
00214 PublicKey::PublicKey( const Pathname &file )
00215 : _pimpl( new Impl(file) )
00216 {
00217 MIL << *this << endl;
00218 }
00220
00221
00222
00223
00224 PublicKey::~PublicKey()
00225 {}
00226
00228
00229
00230
00232
00233 std::string PublicKey::asString() const
00234 {
00235 return _pimpl->asString();
00236 }
00237
00238 std::string PublicKey::armoredData() const
00239 { return _pimpl->armoredData(); }
00240
00241 std::string PublicKey::id() const
00242 { return _pimpl->id(); }
00243
00244 std::string PublicKey::name() const
00245 { return _pimpl->name(); }
00246
00247 std::string PublicKey::fingerprint() const
00248 { return _pimpl->fingerprint(); }
00249
00250 Date PublicKey::created() const
00251 { return _pimpl->created(); }
00252
00253 Date PublicKey::expires() const
00254 { return _pimpl->expires(); }
00255
00256 Pathname PublicKey::path() const
00257 { return _pimpl->path(); }
00258
00259 bool PublicKey::operator==( PublicKey b ) const
00260 {
00261 return( b.id() == id()
00262 && b.fingerprint() == fingerprint()
00263 && b.created() == created() );
00264 }
00265
00266 bool PublicKey::operator==( std::string sid ) const
00267 {
00268 return sid == id();
00269 }
00270
00271 std::ostream & dumpOn( std::ostream & str, const PublicKey & obj )
00272 {
00273 str << "[" << obj.name() << "]" << endl;
00274 str << " fpr " << obj.fingerprint() << endl;
00275 str << " id " << obj.id() << endl;
00276 str << " cre " << obj.created() << endl;
00277 str << " exp " << obj.expires() << endl;
00278 str << "]";
00279 return str;
00280 }
00281
00283 }