PublicKey.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
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   //    CLASS NAME : PublicKey::Impl
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       //return _data_file;
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         // pub:-:1024:17:A84EDAE89C800ACA:971961473:1214043198::-:SuSE Package Signing Key <build@suse.de>:
00125         // fpr:::::::::79C179B2E1C820C1890F9994A84EDAE89C800ACA:
00126         // sig:::17:A84EDAE89C800ACA:1087899198:::::[selfsig]::13x:
00127         // sig:::17:9E40E310000AABA4:980442706::::[User ID not found]:10x:
00128         // sig:::1:77B2E6003D25D3D9:980443247::::[User ID not found]:10x:
00129         // sub:-:2048:16:197448E88495160C:971961490:1214043258::: [expires: 2008-06-21]
00130         // sig:::17:A84EDAE89C800ACA:1087899258:::::[keybind]::18x:
00131 
00132         for ( line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
00133         {
00134           // trim trailing NL.
00135           if ( line.empty() )
00136             continue;
00137           if ( line[line.size()-1] == '\n' )
00138             line.erase( line.size()-1 );
00139 
00140           // split at ':'
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             // take default from pub
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             // update creation and expire dates from 1st signature type "13x"
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         //replace all escaped semicolon with real ':'
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     //Pathname _data_file;
00197   private:
00198     friend Impl * rwcowClone<Impl>( const Impl * rhs );
00200     Impl * clone() const
00201     { return new Impl( *this ); }
00202   };
00204 
00206   //
00207   //    METHOD NAME : PublicKey::PublicKey
00208   //    METHOD TYPE : Ctor
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   //    METHOD NAME : PublicKey::~PublicKey
00222   //    METHOD TYPE : Dtor
00223   //
00224   PublicKey::~PublicKey()
00225   {}
00226 
00228   //
00229   // Forward to implementation:
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 } // namespace zypp

Generated on Fri Jul 4 16:57:58 2008 for zypp by  doxygen 1.5.0