doc/
[gpgme.git] / gpgme / engine.c
1 /* engine.c - GPGME engine support.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003 g10 Code GmbH
4  
5    This file is part of GPGME.
6  
7    GPGME is free software; you can redistribute it and/or modify it
8    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, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16  
17    You should have received a copy of the GNU General Public License
18    along with GPGME; if not, write to the Free Software Foundation,
19    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "gpgme.h"
28 #include "util.h"
29 #include "sema.h"
30 #include "ops.h"
31
32 #include "engine.h"
33 #include "engine-backend.h"
34
35
36 struct engine_object_s
37 {
38   struct engine_ops *ops;
39   void *engine;
40 };
41
42
43 static struct engine_ops *engine_ops[] =
44   {
45     &_gpgme_engine_ops_gpg,             /* OpenPGP.  */
46 #ifdef ENABLE_GPGSM
47     &_gpgme_engine_ops_gpgsm            /* CMS.  */
48 #else
49     NULL
50 #endif
51   };
52
53
54 /* Get the path of the engine for PROTOCOL.  */
55 const char *
56 _gpgme_engine_get_path (GpgmeProtocol proto)
57 {
58   if (proto > DIM (engine_ops))
59     return NULL;
60
61   if (engine_ops[proto] && engine_ops[proto]->get_path)
62     return (*engine_ops[proto]->get_path) ();
63   else
64     return NULL;
65 }
66
67
68 /* Get the version number of the engine for PROTOCOL.  */
69 const char *
70 _gpgme_engine_get_version (GpgmeProtocol proto)
71 {
72   if (proto > DIM (engine_ops))
73     return NULL;
74
75   if (engine_ops[proto] && engine_ops[proto]->get_version)
76     return (*engine_ops[proto]->get_version) ();
77   else
78     return NULL;
79 }
80
81
82 /* Get the required version number of the engine for PROTOCOL.  */
83 const char *
84 _gpgme_engine_get_req_version (GpgmeProtocol proto)
85 {
86   if (proto > DIM (engine_ops))
87     return NULL;
88
89   if (engine_ops[proto] && engine_ops[proto]->get_req_version)
90     return (*engine_ops[proto]->get_req_version) ();
91   else
92     return NULL;
93 }
94
95
96 /* Verify the version requirement for the engine for PROTOCOL.  */
97 GpgmeError
98 gpgme_engine_check_version (GpgmeProtocol proto)
99 {
100   return _gpgme_compare_versions (_gpgme_engine_get_version (proto),
101                                   _gpgme_engine_get_req_version (proto))
102     ? 0 : GPGME_Invalid_Engine;
103 }
104
105
106 const char *
107 _gpgme_engine_get_info (GpgmeProtocol proto)
108 {
109   static const char fmt[] = " <engine>\n"
110     "  <protocol>%s</protocol>\n"
111     "  <version>%s</version>\n"
112     "  <path>%s</path>\n"
113     " </engine>\n";
114   static const char *const strproto[3] = { "OpenPGP", "CMS", NULL };
115   static const char *engine_info[3];  /* FIXME: MAX_PROTO + 1*/
116   DEFINE_STATIC_LOCK (engine_info_lock);
117
118   if (proto > 2 /* FIXME MAX_PROTO */ || !strproto[proto])
119     return NULL;
120
121   LOCK (engine_info_lock);
122   if (!engine_info[proto])
123     {
124       const char *path = _gpgme_engine_get_path (proto);
125       const char *version = _gpgme_engine_get_version (proto);
126
127       if (path && version)
128         {
129           char *info = malloc (strlen (fmt) + strlen (strproto[proto])
130                                    + strlen (path) + strlen (version) + 1);
131           if (!info)
132             info = " <engine>\n"
133               "  <error>Out of core</error>\n"
134               " </engine>";
135           else
136             sprintf (info, fmt, strproto[proto], version, path);
137           engine_info[proto] = info;
138         }
139     }
140   UNLOCK (engine_info_lock);
141   return engine_info[proto];
142 }
143
144
145 GpgmeError
146 _gpgme_engine_new (GpgmeProtocol proto, EngineObject *r_engine)
147 {
148   EngineObject engine;
149
150   const char *path;
151   const char *version;
152
153   if (proto > DIM (engine_ops))
154     return GPGME_Invalid_Value;
155
156   if (!engine_ops[proto])
157     return GPGME_Invalid_Engine;
158
159   path = _gpgme_engine_get_path (proto);
160   version = _gpgme_engine_get_version (proto);
161   if (!path || !version)
162     return GPGME_Invalid_Engine;
163
164   engine = calloc (1, sizeof *engine);
165   if (!engine)
166     return GPGME_Out_Of_Core;
167
168   engine->ops = engine_ops[proto];
169   if (engine_ops[proto]->new)
170     {
171       GpgmeError err = (*engine_ops[proto]->new) (&engine->engine);
172       if (err)
173         {
174           free (engine);
175           return err;
176         }
177     }
178   else
179     engine->engine = NULL;
180
181   *r_engine = engine;
182   return 0;
183 }
184
185
186 void
187 _gpgme_engine_release (EngineObject engine)
188 {
189   if (!engine)
190     return;
191
192   if (engine->ops->release)
193     (*engine->ops->release) (engine->engine);
194   free (engine);
195 }
196
197
198 void
199 _gpgme_engine_set_verbosity (EngineObject engine, int verbosity)
200 {
201   if (!engine)
202     return;
203
204   if (engine->ops->set_verbosity)
205     (*engine->ops->set_verbosity) (engine->engine, verbosity);
206 }
207
208
209 void
210 _gpgme_engine_set_status_handler (EngineObject engine,
211                                   GpgmeStatusHandler fnc, void *fnc_value)
212 {
213   if (!engine)
214     return;
215
216   if (engine->ops->set_status_handler)
217     (*engine->ops->set_status_handler) (engine->engine, fnc, fnc_value);
218 }
219
220
221 GpgmeError
222 _gpgme_engine_set_command_handler (EngineObject engine,
223                                    GpgmeCommandHandler fnc, void *fnc_value,
224                                    GpgmeData linked_data)
225 {
226   if (!engine)
227     return GPGME_Invalid_Value;
228
229   if (!engine->ops->set_command_handler)
230     return GPGME_Not_Implemented;
231
232   return (*engine->ops->set_command_handler) (engine->engine,
233                                               fnc, fnc_value, linked_data);
234 }
235
236 GpgmeError _gpgme_engine_set_colon_line_handler (EngineObject engine,
237                                                  GpgmeColonLineHandler fnc,
238                                                  void *fnc_value)
239 {
240   if (!engine)
241     return GPGME_Invalid_Value;
242
243   if (!engine->ops->set_colon_line_handler)
244     return GPGME_Not_Implemented;
245
246   return (*engine->ops->set_colon_line_handler) (engine->engine,
247                                                  fnc, fnc_value);
248 }
249
250 GpgmeError
251 _gpgme_engine_op_decrypt (EngineObject engine, GpgmeData ciph, GpgmeData plain)
252 {
253   if (!engine)
254     return GPGME_Invalid_Value;
255
256   if (!engine->ops->decrypt)
257     return GPGME_Not_Implemented;
258
259   return (*engine->ops->decrypt) (engine->engine, ciph, plain);
260 }
261
262 GpgmeError
263 _gpgme_engine_op_delete (EngineObject engine, GpgmeKey key, int allow_secret)
264 {
265   if (!engine)
266     return GPGME_Invalid_Value;
267
268   if (!engine->ops->delete)
269     return GPGME_Not_Implemented;
270
271   return (*engine->ops->delete) (engine->engine, key, allow_secret);
272 }
273
274
275 GpgmeError
276 _gpgme_engine_op_edit (EngineObject engine, GpgmeKey key, GpgmeData out,
277                        GpgmeCtx ctx /* FIXME */)
278 {
279   if (!engine)
280     return GPGME_Invalid_Value;
281
282   if (!engine->ops->edit)
283     return GPGME_Not_Implemented;
284
285   return (*engine->ops->edit) (engine->engine, key, out, ctx);
286 }
287
288
289 GpgmeError
290 _gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp,
291                           GpgmeData plain, GpgmeData ciph, int use_armor)
292 {
293   if (!engine)
294     return GPGME_Invalid_Value;
295
296   if (!engine->ops->encrypt)
297     return GPGME_Not_Implemented;
298
299   return (*engine->ops->encrypt) (engine->engine, recp, plain, ciph,
300                                   use_armor);
301 }
302
303
304 GpgmeError
305 _gpgme_engine_op_encrypt_sign (EngineObject engine, GpgmeRecipients recp,
306                                GpgmeData plain, GpgmeData ciph, int use_armor,
307                                GpgmeCtx ctx /* FIXME */)
308 {
309   if (!engine)
310     return GPGME_Invalid_Value;
311
312   if (!engine->ops->encrypt_sign)
313     return GPGME_Not_Implemented;
314
315   return (*engine->ops->encrypt_sign) (engine->engine, recp, plain, ciph,
316                                        use_armor, ctx);
317 }
318
319
320 GpgmeError
321 _gpgme_engine_op_export (EngineObject engine, GpgmeRecipients recp,
322                          GpgmeData keydata, int use_armor)
323 {
324   if (!engine)
325     return GPGME_Invalid_Value;
326
327   if (!engine->ops->export)
328     return GPGME_Not_Implemented;
329
330   return (*engine->ops->export) (engine->engine, recp, keydata,
331                                  use_armor);
332 }
333
334
335 GpgmeError
336 _gpgme_engine_op_genkey (EngineObject engine, GpgmeData help_data,
337                          int use_armor, GpgmeData pubkey, GpgmeData seckey)
338 {
339   if (!engine)
340     return GPGME_Invalid_Value;
341
342   if (!engine->ops->genkey)
343     return GPGME_Not_Implemented;
344
345   return (*engine->ops->genkey) (engine->engine, help_data, use_armor,
346                                  pubkey, seckey);
347 }
348
349
350 GpgmeError
351 _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata)
352 {
353   if (!engine)
354     return GPGME_Invalid_Value;
355
356   if (!engine->ops->import)
357     return GPGME_Not_Implemented;
358
359   return (*engine->ops->import) (engine->engine, keydata);
360 }
361
362
363 GpgmeError
364 _gpgme_engine_op_keylist (EngineObject engine, const char *pattern,
365                           int secret_only, int keylist_mode)
366 {
367   if (!engine)
368     return GPGME_Invalid_Value;
369
370   if (!engine->ops->keylist)
371     return GPGME_Not_Implemented;
372
373   return (*engine->ops->keylist) (engine->engine, pattern, secret_only,
374                                   keylist_mode);
375 }
376
377
378 GpgmeError
379 _gpgme_engine_op_keylist_ext (EngineObject engine, const char *pattern[],
380                               int secret_only, int reserved, int keylist_mode)
381 {
382   if (!engine)
383     return GPGME_Invalid_Value;
384
385   if (!engine->ops->keylist_ext)
386     return GPGME_Not_Implemented;
387
388   return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
389                                       reserved, keylist_mode);
390 }
391
392
393 GpgmeError
394 _gpgme_engine_op_sign (EngineObject engine, GpgmeData in, GpgmeData out,
395                        GpgmeSigMode mode, int use_armor,
396                        int use_textmode, int include_certs,
397                        GpgmeCtx ctx /* FIXME */)
398 {
399   if (!engine)
400     return GPGME_Invalid_Value;
401
402   if (!engine->ops->sign)
403     return GPGME_Not_Implemented;
404
405   return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor,
406                                use_textmode, include_certs, ctx);
407 }
408
409
410 GpgmeError
411 _gpgme_engine_op_trustlist (EngineObject engine, const char *pattern)
412 {
413   if (!engine)
414     return GPGME_Invalid_Value;
415
416   if (!engine->ops->trustlist)
417     return GPGME_Not_Implemented;
418
419   return (*engine->ops->trustlist) (engine->engine, pattern);
420 }
421
422
423 GpgmeError
424 _gpgme_engine_op_verify (EngineObject engine, GpgmeData sig,
425                          GpgmeData signed_text, GpgmeData plaintext)
426 {
427   if (!engine)
428     return GPGME_Invalid_Value;
429
430   if (!engine->ops->verify)
431     return GPGME_Not_Implemented;
432
433   return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext);
434 }
435
436
437 void
438 _gpgme_engine_set_io_cbs (EngineObject engine,
439                           struct GpgmeIOCbs *io_cbs)
440 {
441   if (!engine)
442     return;
443
444   (*engine->ops->set_io_cbs) (engine->engine, io_cbs);
445 }
446
447
448 void
449 _gpgme_engine_io_event (EngineObject engine,
450                         GpgmeEventIO type, void *type_data)
451 {
452   if (!engine)
453     return;
454
455   (*engine->ops->io_event) (engine->engine, type, type_data);
456 }