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     std::string asString() const
00055     {
00056       return "[" + id() + "-" + str::hexstring(created(),8).substr(2) + "] [" + name() + "] [" + fingerprint() + "]";
00057     }
00058 
00059     std::string armoredData() const
00060     { return _data; }
00061 
00062     std::string id() const
00063     { return _id; }
00064 
00065     std::string name() const
00066     { return _name; }
00067 
00068     std::string fingerprint() const
00069     { return _fingerprint; }
00070 
00071     Date created() const
00072     { return _created; }
00073 
00074     Date expires() const
00075     { return _expires; }
00076 
00077     Pathname path() const
00078     {
00079       return _data_file.path();
00080       //return _data_file;
00081     }
00082 
00083     protected:
00084 
00085      void readFromFile( const Pathname &keyfile)
00086      {
00087 
00088        PathInfo info(keyfile);
00089        MIL << "Reading pubkey from " << keyfile << " of size " << info.size() << " and sha1 " << filesystem::checksum(keyfile, "sha1")<< endl;
00090        if ( !info.isExist() )
00091          ZYPP_THROW(Exception("Can't read public key from " + keyfile.asString() + ", file not found"));
00092 
00093        if ( copy( keyfile, _data_file.path() ) != 0 )
00094          ZYPP_THROW(Exception("Can't copy public key data from " + keyfile.asString() + " to " +  _data_file.path().asString() ));
00095 
00096         filesystem::TmpDir dir;
00097         const char* argv[] =
00098         {
00099           "gpg",
00100           "-v",
00101           "--no-default-keyring",
00102           "--fixed-list-mode",
00103           "--with-fingerprint",
00104           "--with-colons",
00105           "--homedir",
00106           dir.path().asString().c_str(),
00107           "--quiet",
00108           "--no-tty",
00109           "--no-greeting",
00110           "--batch",
00111           "--status-fd",
00112           "1",
00113           _data_file.path().asString().c_str(),
00114           NULL
00115         };
00116 
00117         ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
00118 
00119         std::string line;
00120         bool sawpub = false;
00121         bool sawsig = false;
00122 
00123         // pub:-:1024:17:A84EDAE89C800ACA:971961473:1214043198::-:SuSE Package Signing Key <build@suse.de>:
00124         // fpr:::::::::79C179B2E1C820C1890F9994A84EDAE89C800ACA:
00125         // sig:::17:A84EDAE89C800ACA:1087899198:::::[selfsig]::13x:
00126         // sig:::17:9E40E310000AABA4:980442706::::[User ID not found]:10x:
00127         // sig:::1:77B2E6003D25D3D9:980443247::::[User ID not found]:10x:
00128         // sub:-:2048:16:197448E88495160C:971961490:1214043258::: [expires: 2008-06-21]
00129         // sig:::17:A84EDAE89C800ACA:1087899258:::::[keybind]::18x:
00130 
00131         for ( line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
00132         {
00133           // trim trailing NL.
00134           if ( line.empty() )
00135             continue;
00136           if ( line[line.size()-1] == '\n' )
00137             line.erase( line.size()-1 );
00138 
00139           // split at ':'
00140           std::vector<std::string> words;
00141           str::splitFields( line, std::back_inserter(words), ":" );
00142           if( words.empty() )
00143             continue;
00144 
00145           if ( words[0] == "pub" )
00146           {
00147             if ( sawpub )
00148               continue;
00149             sawpub = true;
00150             // take default from pub
00151             _id      = words[4];
00152             _name    = words[9];
00153             _created = Date(str::strtonum<Date::ValueType>(words[5]));
00154             _expires = Date(str::strtonum<Date::ValueType>(words[6]));
00155 
00156           }
00157           else if ( words[0] == "sig" )
00158           {
00159             if ( sawsig || words[words.size()-2] != "13x"  )
00160               continue;
00161             sawsig = true;
00162             // update creation and expire dates from 1st signature type "13x"
00163             if ( ! words[5].empty() )
00164               _created = Date(str::strtonum<Date::ValueType>(words[5]));
00165             if ( ! words[6].empty() )
00166               _expires = Date(str::strtonum<Date::ValueType>(words[6]));
00167           }
00168           else if ( words[0] == "fpr" )
00169           {
00170             _fingerprint = words[9];
00171           }
00172           else if ( words[0] == "uid" )
00173           {
00174             if ( ! words[9].empty() )
00175               _name = words[9];
00176           }
00177         }
00178         prog.close();
00179 
00180         if ( _id.size() == 0 )
00181           ZYPP_THROW( BadKeyException( "File " + keyfile.asString() + " doesn't contain public key data" , keyfile ) );
00182 
00183         //replace all escaped semicolon with real ':'
00184         str::replace_all( _name, "\\x3a", ":" );
00185      }
00186 
00187   private:
00188     std::string _id;
00189     std::string _name;
00190     std::string _fingerprint;
00191     std::string _data;
00192     filesystem::TmpFile _data_file;
00193     Date _created;
00194     Date _expires;
00195     //Pathname _data_file;
00196   private:
00197     friend Impl * rwcowClone<Impl>( const Impl * rhs );
00199     Impl * clone() const
00200     { return new Impl( *this ); }
00201   };
00203 
00205   //
00206   //    METHOD NAME : PublicKey::PublicKey
00207   //    METHOD TYPE : Ctor
00208   //
00209   PublicKey::PublicKey()
00210   : _pimpl( Impl::nullimpl() )
00211   {}
00212 
00213   PublicKey::PublicKey( const Pathname &file )
00214   : _pimpl( new Impl(file) )
00215   {
00216     MIL << *this << endl;
00217   }
00219   //
00220   //    METHOD NAME : PublicKey::~PublicKey
00221   //    METHOD TYPE : Dtor
00222   //
00223   PublicKey::~PublicKey()
00224   {}
00225 
00227   //
00228   // Forward to implementation:
00229   //
00231 
00232   std::string PublicKey::asString() const
00233   {
00234     return _pimpl->asString();
00235   }
00236 
00237   std::string PublicKey::armoredData() const
00238   { return _pimpl->armoredData(); }
00239 
00240   std::string PublicKey::id() const
00241   { return _pimpl->id(); }
00242 
00243   std::string PublicKey::name() const
00244   { return _pimpl->name(); }
00245 
00246   std::string PublicKey::fingerprint() const
00247   { return _pimpl->fingerprint(); }
00248 
00249   Date PublicKey::created() const
00250   { return _pimpl->created(); }
00251 
00252   Date PublicKey::expires() const
00253   { return _pimpl->expires(); }
00254 
00255   Pathname PublicKey::path() const
00256   { return _pimpl->path(); }
00257 
00258   bool PublicKey::operator==( PublicKey b ) const
00259   {
00260      return(   b.id() == id()
00261             && b.fingerprint() == fingerprint()
00262             && b.created() == created() );
00263   }
00264 
00265   bool PublicKey::operator==( std::string sid ) const
00266   {
00267     return sid == id();
00268   }
00269 
00270   std::ostream & dumpOn( std::ostream & str, const PublicKey & obj )
00271   {
00272     str << "[" << obj.name() << "]" << endl;
00273     str << "  fpr " << obj.fingerprint() << endl;
00274     str << "   id " << obj.id() << endl;
00275     str << "  cre " << obj.created() << endl;
00276     str << "  exp " << obj.expires() << endl;
00277     str << "]";
00278     return str;
00279   }
00280 
00282 } // namespace zypp

Generated on Sat Sep 5 12:05:11 2009 for zypp by  doxygen 1.4.6