Support key listing, and key importing.
[platform/upstream/libzypp.git] / zypp / KeyRing.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/KeyRing.cc
10  *
11 */
12 #include <iostream>
13 #include <fstream>
14 //#include "zypp/base/Logger.h"
15 #include <sys/file.h>
16 #include <cstdio>
17 #include <unistd.h>
18
19 #include "zypp/ZYppFactory.h"
20 #include "zypp/ZYpp.h"
21
22 #include <boost/regex.hpp>
23
24 #include "zypp/base/String.h"
25 #include "zypp/KeyRing.h"
26 #include "zypp/ExternalProgram.h"
27 #include "zypp/TmpPath.h"
28
29 using std::endl;
30 using namespace boost;
31 using namespace zypp::filesystem;
32 using namespace std;
33
34 ///////////////////////////////////////////////////////////////////
35 namespace zypp
36 { /////////////////////////////////////////////////////////////////
37
38   static void dumpRegexpResults( const boost::smatch &what )
39   {
40     for ( unsigned int k=0; k < what.size(); k++)
41     {
42       XXX << "[match "<< k << "] [" << what[k] << "]" << std::endl;
43     }
44   }
45   
46   ///////////////////////////////////////////////////////////////////
47   //
48   //    CLASS NAME : KeyRing::Impl
49   //
50   /** KeyRing implementation. */
51   struct KeyRing::Impl
52   {
53     Impl()
54     {}
55
56     Impl( const Pathname &general_kr, const Pathname &trusted_kr )
57     {
58       _general_kr = general_kr;
59       _trusted_kr = trusted_kr;
60     }
61
62     PublicKey importKey( const Pathname &keyfile, bool trusted );
63     void deleteKey( const std::string &id, bool trusted );
64     std::list<PublicKey> trustedPublicKeys();
65     std::list<PublicKey> publicKeys();
66   private:
67     //mutable std::map<Locale, std::string> translations;
68     
69     PublicKey importKey( const Pathname &keyfile, const Pathname &keyring);
70     void deleteKey( const std::string &id, const Pathname &keyring );
71     std::list<PublicKey> publicKeys(const Pathname &keyring);
72     
73     Pathname _general_kr;
74     Pathname _trusted_kr;
75   public:
76     /** Offer default Impl. */
77     static shared_ptr<Impl> nullimpl()
78     {
79       static shared_ptr<Impl> _nullimpl( new Impl );
80       return _nullimpl;
81     }
82
83   private:
84     friend Impl * rwcowClone<Impl>( const Impl * rhs );
85     /** clone for RWCOW_pointer */
86     Impl * clone() const
87     { return new Impl( *this ); }
88   };
89   
90   PublicKey KeyRing::Impl::importKey( const Pathname &keyfile, bool trusted)
91   {
92     return importKey( keyfile, trusted ? _trusted_kr : _general_kr );
93   }
94   
95   void KeyRing::Impl::deleteKey( const std::string &id, bool trusted)
96   {
97     deleteKey( id, trusted ? _trusted_kr : _general_kr );
98   }
99   
100   std::list<PublicKey> KeyRing::Impl::publicKeys()
101   {
102     return publicKeys( _general_kr );
103   }
104   
105   std::list<PublicKey> KeyRing::Impl::trustedPublicKeys()
106   {
107     return publicKeys( _trusted_kr );
108   }
109
110   std::list<PublicKey> KeyRing::Impl::publicKeys(const Pathname &keyring)
111   {
112     const char* argv[] =
113     {
114       "gpg",
115       "--quiet",
116       "--list-keys",
117       "--with-colons",
118       "--with-fingerprint",
119       "--homedir",
120       keyring.asString().c_str(),
121       NULL
122     };
123     std::list<PublicKey> keys;
124     
125     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
126     std::string line;
127     int count = 0;
128     
129     boost::regex rxColons("^([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):\n$");
130     
131     for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
132     {
133       MIL << line << std::endl;
134       boost::smatch what;
135       if(boost::regex_match(line, what, rxColons, boost::match_extra))
136       {
137         if ( what[1] == "pub" )
138         {
139           PublicKey key;
140           key.id = what[5];
141           key.name = what[10];
142           keys.push_back(key);
143         }
144         //dumpRegexpResults(what);
145       }
146     }
147     prog.close();
148     return keys;
149   }
150   
151   PublicKey KeyRing::Impl::importKey( const Pathname &keyfile, const Pathname &keyring)
152   {
153     const char* argv[] =
154     {
155       "gpg",
156       "--quiet",
157       "--no-tty",
158       "--no-greeting",
159       "--status-fd",
160       "1",  
161       "--homedir",
162       keyring.asString().c_str(),
163       "--import",
164       keyfile.asString().c_str(),
165       NULL
166     };
167     
168     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
169     
170     boost::regex rxImported("^\\[GNUPG:\\] IMPORTED ([^[:space:]]+) (.+)\n$");
171     std::string line;
172     int count = 0;
173     for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
174     {
175       MIL << line << std::endl;
176        boost::smatch what;
177        if(boost::regex_match(line, what, rxImported, boost::match_extra))
178        {
179          MIL << std::endl;
180          PublicKey key;
181          key.id = what[1];
182          key.name = what[2];
183          return key;
184        }
185     }
186     prog.close();
187     throw Exception("failed to import key");
188     return PublicKey();
189   }
190   
191   void KeyRing::Impl::deleteKey( const std::string &id, const Pathname &keyring )
192   {
193     const char* argv[] =
194     {
195       "gpg",
196       "--batch",
197       "--yes",
198       "--delete-keys",
199       "--homedir",
200       keyring.asString().c_str(),
201       id.c_str(),
202       NULL
203     };
204     
205     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
206     prog.close();
207   }    
208   
209   ///////////////////////////////////////////////////////////////////
210
211   ///////////////////////////////////////////////////////////////////
212   //
213   //    CLASS NAME : KeyRing
214   //
215   ///////////////////////////////////////////////////////////////////
216
217   ///////////////////////////////////////////////////////////////////
218   //
219   //    METHOD NAME : KeyRing::KeyRing
220   //    METHOD TYPE : Ctor
221   //
222   KeyRing::KeyRing()
223   : _pimpl( Impl::nullimpl() )
224   {}
225
226   ///////////////////////////////////////////////////////////////////
227   //
228   //    METHOD NAME : KeyRing::KeyRing
229   //    METHOD TYPE : Ctor
230   //
231   KeyRing::KeyRing( const Pathname &general_kr, const Pathname &trusted_kr )
232   : _pimpl( new Impl(general_kr, trusted_kr) )
233   {}
234
235   ///////////////////////////////////////////////////////////////////
236   //
237   //    METHOD NAME : KeyRing::~KeyRing
238   //    METHOD TYPE : Dtor
239   //
240   KeyRing::~KeyRing()
241   {}
242
243   ///////////////////////////////////////////////////////////////////
244   //
245   // Forward to implementation:
246   //
247   ///////////////////////////////////////////////////////////////////
248
249   PublicKey KeyRing::importKey( const Pathname &keyfile, bool trusted)
250   {
251     return _pimpl->importKey(keyfile, trusted);
252   }
253   
254   void KeyRing::deleteKey( const std::string &id, bool trusted )
255   {
256     _pimpl->deleteKey(id, trusted);
257   }
258   
259   std::list<PublicKey> KeyRing::publicKeys()
260   {
261     return _pimpl->publicKeys();
262   }
263   
264   std::list<PublicKey> KeyRing::trustedPublicKeys()
265   {
266     return _pimpl->trustedPublicKeys();
267   }
268   
269   /////////////////////////////////////////////////////////////////
270 } // namespace zypp
271 ///////////////////////////////////////////////////////////////////