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