importing my current diff
[platform/upstream/libzypp.git] / zypp / PublicKey.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/PublicKey.cc
10  *
11 */
12 #include <iostream>
13 //#include "zypp/base/Logger.h"
14
15 #include "zypp/base/String.h"
16 #include "zypp/base/Regex.h"
17 #include "zypp/PublicKey.h"
18 #include "zypp/ExternalProgram.h"
19 #include "zypp/TmpPath.h"
20 #include "zypp/PathInfo.h"
21 #include "zypp/base/Exception.h"
22 #include "zypp/base/Logger.h"
23
24 using std::endl;
25
26 ///////////////////////////////////////////////////////////////////
27 namespace zypp
28 { /////////////////////////////////////////////////////////////////    
29   //
30   //    CLASS NAME : PublicKey::Impl
31   //
32   /** PublicKey implementation. */
33   struct PublicKey::Impl
34   {
35     Impl()
36     {}
37
38     Impl(const Pathname &file)
39     {
40       readFromFile(file);
41       MIL << "Done reading key" << std::endl;
42     }
43     
44     public:
45       /** Offer default Impl. */
46       static shared_ptr<Impl> nullimpl()
47       {
48         static shared_ptr<Impl> _nullimpl( new Impl );
49         return _nullimpl;
50       }
51
52      
53     std::string asString() const
54     {
55       return "[" + id() + "] [" + name() + "] [" + fingerprint() + "]";
56     }
57     
58     std::string armoredData() const
59     { return _data; }
60     
61     std::string id() const
62     { return _id; }
63     
64     std::string name() const
65     { return _name; }
66     
67     std::string fingerprint() const
68     { return _fingerprint; }
69     
70     Pathname path() const
71     { 
72       return _data_file.path();
73       //return _data_file;
74     }
75     
76     protected:
77       
78      void readFromFile( const Pathname &keyfile)
79      {
80        static str::regex rxColons("^([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):\n$");
81        
82        PathInfo info(keyfile);
83        MIL << "Reading pubkey from " << keyfile << " of size " << info.size() << " and sha1 " << filesystem::checksum(keyfile, "sha1")<< endl; 
84        if ( !info.isExist() )
85          ZYPP_THROW(Exception("Can't read public key from " + keyfile.asString() + ", file not found"));
86          
87        if ( copy( keyfile, _data_file.path() ) != 0 )
88          ZYPP_THROW(Exception("Can't copy public key data from " + keyfile.asString() + " to " +  _data_file.path().asString() ));
89
90        
91        filesystem::TmpDir dir;
92   
93         const char* argv[] =
94         {
95           "gpg",
96           "--no-default-keyring",
97           "--homedir",
98           dir.path().asString().c_str(),
99           "--with-fingerprint",
100           "--with-colons",
101           "--quiet",
102           "--no-tty",
103           "--no-greeting",
104           "--batch",
105           "--status-fd",
106           "1",
107           _data_file.path().asString().c_str(),
108           NULL
109         };
110   
111         ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
112   
113         std::string line;
114         int count = 0;
115   
116       // pub:-:1024:17:A84EDAE89C800ACA:2000-10-19:2008-06-21::-:SuSE Package Signing Key <build@suse.de>:
117   
118         for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
119         {
120         //MIL << "[" << line << "]" << std::endl;
121           str::smatch what;
122           if(str::regex_match(line, what, rxColons))
123           {
124             if ( what[1] == "pub" )
125             {
126               _id = what[5];
127               _name = what[10];
128             //return key;
129             }
130             else if ( what[1] == "fpr" )
131             {
132                 _fingerprint = what[10];
133             }
134           //dumpRegexpResults(what);
135           }
136         }
137         prog.close();
138         
139         if (_id.size() == 0 )
140           ZYPP_THROW(BadKeyException("File " + keyfile.asString() + " doesn't contain public key data" , keyfile));
141      }
142     
143   private:
144     std::string _id;
145     std::string _name;
146     std::string _fingerprint;
147     std::string _data;
148     filesystem::TmpFile _data_file;
149     //Pathname _data_file;
150   private:
151     friend Impl * rwcowClone<Impl>( const Impl * rhs );
152     /** clone for RWCOW_pointer */
153     Impl * clone() const
154     { return new Impl( *this ); }
155   };
156   ///////////////////////////////////////////////////////////////////
157
158   ///////////////////////////////////////////////////////////////////
159   //
160   //    METHOD NAME : PublicKey::PublicKey
161   //    METHOD TYPE : Ctor
162   //
163   PublicKey::PublicKey()
164   : _pimpl( Impl::nullimpl() )
165   {}
166
167   PublicKey::PublicKey( const Pathname &file )
168   : _pimpl( new Impl(file) )
169   {}
170   ///////////////////////////////////////////////////////////////////
171   //
172   //    METHOD NAME : PublicKey::~PublicKey
173   //    METHOD TYPE : Dtor
174   //
175   PublicKey::~PublicKey()
176   {}
177
178   ///////////////////////////////////////////////////////////////////
179   //
180   // Forward to implementation:
181   //
182   ///////////////////////////////////////////////////////////////////
183
184   std::string PublicKey::asString() const
185   {
186     return _pimpl->asString();
187   }
188   
189   std::string PublicKey::armoredData() const
190   { return _pimpl->armoredData(); }
191     
192   std::string PublicKey::id() const
193   { return _pimpl->id(); }
194     
195   std::string PublicKey::name() const
196   { return _pimpl->name(); }
197     
198   std::string PublicKey::fingerprint() const
199   { return _pimpl->fingerprint(); }
200   
201   Pathname PublicKey::path() const
202   { return _pimpl->path(); }
203
204   bool PublicKey::operator==( PublicKey b ) const
205   {
206     return (b.id() == id()) && (b.fingerprint() == fingerprint() );
207   }
208     
209   bool PublicKey::operator==( std::string sid ) const
210   {
211     return sid == id();
212   }
213   
214   /////////////////////////////////////////////////////////////////
215 } // namespace zypp
216 ///////////////////////////////////////////////////////////////////