2001-11-22 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / gpgme / engine.c
1 /* engine.c 
2  *      Copyright (C) 2000 Werner Koch (dd9jn)
3  *      Copyright (C) 2001 g10 Code GmbH
4  *
5  * This file is part of GPGME.
6  *
7  * GPGME is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GPGME is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "gpgme.h"
27 #include "util.h"
28
29 #include "engine.h"
30 #include "rungpg.h"
31 #include "engine-gpgsm.h"
32
33 struct engine_object_s
34   {
35     GpgmeProtocol protocol;
36
37     const char *path;
38     const char *version;
39
40     union
41       {
42         GpgObject gpg;
43         GpgsmObject gpgsm;
44       } engine;
45 };
46
47 /* Get the path of the engine for PROTOCOL.  */
48 const char *
49 _gpgme_engine_get_path (GpgmeProtocol proto)
50 {
51   switch (proto)
52     {
53     case GPGME_PROTOCOL_OpenPGP:
54       return _gpgme_get_gpg_path ();
55     case GPGME_PROTOCOL_CMS:
56       return _gpgme_get_gpgsm_path ();
57     default:
58       return NULL;
59     }
60 }
61
62 /* Get the version number of the engine for PROTOCOL.  */
63 const char *
64 _gpgme_engine_get_version (GpgmeProtocol proto)
65 {
66   switch (proto)
67     {
68     case GPGME_PROTOCOL_OpenPGP:
69       return _gpgme_gpg_get_version ();
70     case GPGME_PROTOCOL_CMS:
71       return _gpgme_gpgsm_get_version ();
72     default:
73       return NULL;
74     }
75 }
76
77 GpgmeError
78 gpgme_engine_check_version (GpgmeProtocol proto)
79 {
80   switch (proto)
81     {
82     case GPGME_PROTOCOL_OpenPGP:
83       return _gpgme_gpg_check_version ();
84     case GPGME_PROTOCOL_CMS:
85       return _gpgme_gpgsm_check_version ();
86     default:
87       return mk_error (Invalid_Value);
88     }
89 }
90
91 GpgmeError
92 _gpgme_engine_new (GpgmeProtocol proto, EngineObject *r_engine)
93 {
94   EngineObject engine;
95   GpgmeError err = 0;
96
97   engine = xtrycalloc (1, sizeof *engine);
98   if (!engine)
99     {
100       err = mk_error (Out_Of_Core);
101       goto leave;
102     }
103
104   engine->protocol = proto;
105   switch (proto)
106     {
107     case GPGME_PROTOCOL_OpenPGP:
108       err =_gpgme_gpg_new (&engine->engine.gpg);
109       break;
110     case GPGME_PROTOCOL_CMS:
111       err = _gpgme_gpgsm_new (&engine->engine.gpgsm);
112       if (err)
113         goto leave;
114       break;
115     default:
116       err = mk_error (Invalid_Value);
117     }
118   if (err)
119     goto leave;
120
121   engine->path = _gpgme_engine_get_path (proto);
122   engine->version = _gpgme_engine_get_version (proto);
123
124   if (!engine->path || !engine->version)
125     {
126       err = mk_error (Invalid_Engine);
127       goto leave;
128     }
129
130  leave:
131   if (err)
132     _gpgme_engine_release (engine);
133   else
134     *r_engine = engine;
135   
136   return err;
137 }
138
139 void
140 _gpgme_engine_release (EngineObject engine)
141 {
142   if (!engine)
143     return;
144
145   switch (engine->protocol)
146     {
147     case GPGME_PROTOCOL_OpenPGP:
148       _gpgme_gpg_release (engine->engine.gpg);
149       break;
150     case GPGME_PROTOCOL_CMS:
151       _gpgme_gpgsm_release (engine->engine.gpgsm);
152       break;
153     default:
154       break;
155     }
156   xfree (engine);
157 }
158
159 void
160 _gpgme_engine_set_verbosity (EngineObject engine, int verbosity)
161 {
162   if (!engine)
163     return;
164
165   switch (engine->protocol)
166     {
167     case GPGME_PROTOCOL_OpenPGP:
168       while (verbosity-- > 0)
169         _gpgme_gpg_add_arg (engine->engine.gpg, "--verbose");
170       break;
171     case GPGME_PROTOCOL_CMS:
172       /* FIXME */
173       break;
174     default:
175       break;
176     }
177 }
178
179 void
180 _gpgme_engine_set_status_handler (EngineObject engine,
181                                   GpgStatusHandler fnc, void *fnc_value)
182 {
183   if (!engine)
184     return;
185
186   switch (engine->protocol)
187     {
188     case GPGME_PROTOCOL_OpenPGP:
189       _gpgme_gpg_set_status_handler (engine->engine.gpg, fnc, fnc_value);
190       break;
191     case GPGME_PROTOCOL_CMS:
192       _gpgme_gpgsm_set_status_handler (engine->engine.gpgsm, fnc, fnc_value);
193       break;
194     default:
195       break;
196     }
197 }
198
199 GpgmeError
200 _gpgme_engine_set_command_handler (EngineObject engine,
201                                   GpgCommandHandler fnc, void *fnc_value)
202 {
203   if (!engine)
204     return mk_error (Invalid_Value);
205
206   switch (engine->protocol)
207     {
208     case GPGME_PROTOCOL_OpenPGP:
209       return _gpgme_gpg_set_command_handler (engine->engine.gpg, fnc, fnc_value);
210     case GPGME_PROTOCOL_CMS:
211       /* FIXME */
212       break;
213     default:
214       break;
215     }
216   return 0;
217 }
218
219 GpgmeError _gpgme_engine_set_colon_line_handler (EngineObject engine,
220                                                  GpgColonLineHandler fnc,
221                                                  void *fnc_value)
222 {
223   if (!engine)
224     return mk_error (Invalid_Value);
225
226   switch (engine->protocol)
227     {
228     case GPGME_PROTOCOL_OpenPGP:
229       return _gpgme_gpg_set_colon_line_handler (engine->engine.gpg, fnc,
230                                                 fnc_value);
231     case GPGME_PROTOCOL_CMS:
232       /* FIXME */
233       break;
234     default:
235       break;
236     }
237   return 0;
238 }
239
240 GpgmeError
241 _gpgme_engine_op_decrypt (EngineObject engine, GpgmeData ciph, GpgmeData plain)
242 {
243   if (!engine)
244     return mk_error (Invalid_Value);
245
246   switch (engine->protocol)
247     {
248     case GPGME_PROTOCOL_OpenPGP:
249       return _gpgme_gpg_op_decrypt (engine->engine.gpg, ciph, plain);
250     case GPGME_PROTOCOL_CMS:
251       return _gpgme_gpgsm_op_decrypt (engine->engine.gpgsm, ciph, plain);
252     default:
253       break;
254     }
255   return 0;
256 }
257
258 GpgmeError
259 _gpgme_engine_op_delete (EngineObject engine, GpgmeKey key, int allow_secret)
260 {
261   if (!engine)
262     return mk_error (Invalid_Value);
263
264   switch (engine->protocol)
265     {
266     case GPGME_PROTOCOL_OpenPGP:
267       return _gpgme_gpg_op_delete (engine->engine.gpg, key, allow_secret);
268     case GPGME_PROTOCOL_CMS:
269       return _gpgme_gpgsm_op_delete (engine->engine.gpgsm, key, allow_secret);
270     default:
271       break;
272     }
273   return 0;
274 }
275
276 GpgmeError
277 _gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp,
278                           GpgmeData plain, GpgmeData ciph, int use_armor)
279 {
280   if (!engine)
281     return mk_error (Invalid_Value);
282
283   switch (engine->protocol)
284     {
285     case GPGME_PROTOCOL_OpenPGP:
286       return _gpgme_gpg_op_encrypt (engine->engine.gpg, recp, plain, ciph,
287                                     use_armor);
288     case GPGME_PROTOCOL_CMS:
289       return _gpgme_gpgsm_op_encrypt (engine->engine.gpgsm, recp, plain, ciph,
290                                       use_armor);
291     default:
292       break;
293     }
294   return 0;
295 }
296
297 GpgmeError
298 _gpgme_engine_op_export (EngineObject engine, GpgmeRecipients recp,
299                          GpgmeData keydata, int use_armor)
300 {
301   if (!engine)
302     return mk_error (Invalid_Value);
303
304   switch (engine->protocol)
305     {
306     case GPGME_PROTOCOL_OpenPGP:
307       return _gpgme_gpg_op_export (engine->engine.gpg, recp, keydata,
308                                    use_armor);
309     case GPGME_PROTOCOL_CMS:
310       return _gpgme_gpgsm_op_export (engine->engine.gpgsm, recp, keydata,
311                                      use_armor);
312     default:
313       break;
314     }
315   return 0;
316 }
317
318 GpgmeError
319 _gpgme_engine_op_genkey (EngineObject engine, GpgmeData help_data, int use_armor)
320 {
321   if (!engine)
322     return mk_error (Invalid_Value);
323
324   switch (engine->protocol)
325     {
326     case GPGME_PROTOCOL_OpenPGP:
327       return _gpgme_gpg_op_genkey (engine->engine.gpg, help_data, use_armor);
328     case GPGME_PROTOCOL_CMS:
329       return _gpgme_gpgsm_op_genkey (engine->engine.gpgsm, help_data, use_armor);
330     default:
331       break;
332     }
333   return 0;
334 }
335
336 GpgmeError
337 _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata)
338 {
339   if (!engine)
340     return mk_error (Invalid_Value);
341
342   switch (engine->protocol)
343     {
344     case GPGME_PROTOCOL_OpenPGP:
345       return _gpgme_gpg_op_import (engine->engine.gpg, keydata);
346     case GPGME_PROTOCOL_CMS:
347       return _gpgme_gpgsm_op_import (engine->engine.gpgsm, keydata);
348     default:
349       break;
350     }
351   return 0;
352 }
353
354 GpgmeError
355 _gpgme_engine_op_keylist (EngineObject engine, const char *pattern, int secret_only,
356                           int keylist_mode)
357 {
358   if (!engine)
359     return mk_error (Invalid_Value);
360
361   switch (engine->protocol)
362     {
363     case GPGME_PROTOCOL_OpenPGP:
364       return _gpgme_gpg_op_keylist (engine->engine.gpg, pattern, secret_only,
365                                     keylist_mode);
366     case GPGME_PROTOCOL_CMS:
367       return _gpgme_gpgsm_op_keylist (engine->engine.gpgsm, pattern, secret_only,
368                                       keylist_mode);
369     default:
370       break;
371     }
372   return 0;
373 }
374
375 GpgmeError
376 _gpgme_engine_op_sign (EngineObject engine, GpgmeData in, GpgmeData out,
377                     GpgmeSigMode mode, int use_armor,
378                     int use_textmode, GpgmeCtx ctx /* FIXME */)
379 {
380   if (!engine)
381     return mk_error (Invalid_Value);
382
383   switch (engine->protocol)
384     {
385     case GPGME_PROTOCOL_OpenPGP:
386       return _gpgme_gpg_op_sign (engine->engine.gpg, in, out, mode, use_armor,
387                                  use_textmode, ctx);
388     case GPGME_PROTOCOL_CMS:
389       return _gpgme_gpgsm_op_sign (engine->engine.gpgsm, in, out, mode,
390                                    use_armor, use_textmode, ctx);
391       break;
392     default:
393       break;
394     }
395   return 0;
396 }
397
398 GpgmeError
399 _gpgme_engine_op_trustlist (EngineObject engine, const char *pattern)
400 {
401   if (!engine)
402     return mk_error (Invalid_Value);
403
404   switch (engine->protocol)
405     {
406     case GPGME_PROTOCOL_OpenPGP:
407       return _gpgme_gpg_op_trustlist (engine->engine.gpg, pattern);
408     case GPGME_PROTOCOL_CMS:
409       return _gpgme_gpgsm_op_trustlist (engine->engine.gpgsm, pattern);
410     default:
411       break;
412     }
413   return 0;
414 }
415
416 GpgmeError
417 _gpgme_engine_op_verify (EngineObject engine, GpgmeData sig, GpgmeData text)
418 {
419   if (!engine)
420     return mk_error (Invalid_Value);
421
422   switch (engine->protocol)
423     {
424     case GPGME_PROTOCOL_OpenPGP:
425       return _gpgme_gpg_op_verify (engine->engine.gpg, sig, text);
426     case GPGME_PROTOCOL_CMS:
427       return _gpgme_gpgsm_op_verify (engine->engine.gpgsm, sig, text);
428     default:
429       break;
430     }
431   return 0;
432 }
433
434 GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque)
435 {
436   if (!engine)
437     return mk_error (Invalid_Value);
438
439   switch (engine->protocol)
440     {
441     case GPGME_PROTOCOL_OpenPGP:
442       return _gpgme_gpg_spawn (engine->engine.gpg, opaque);
443     case GPGME_PROTOCOL_CMS:
444       return _gpgme_gpgsm_start (engine->engine.gpgsm, opaque);
445     default:
446       break;
447     }
448   return 0;
449 }