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
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 \f
54 /* Get the file name of the engine for PROTOCOL.  */
55 static const char *
56 engine_get_file_name (gpgme_protocol_t proto)
57 {
58   if (proto > DIM (engine_ops))
59     return NULL;
60
61   if (engine_ops[proto] && engine_ops[proto]->get_file_name)
62     return (*engine_ops[proto]->get_file_name) ();
63   else
64     return NULL;
65 }
66
67
68 /* Get the version number of the engine for PROTOCOL.  */
69 static const char *
70 engine_get_version (gpgme_protocol_t 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 static const char *
84 engine_get_req_version (gpgme_protocol_t 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 gpgme_error_t
98 gpgme_engine_check_version (gpgme_protocol_t proto)
99 {
100   return _gpgme_compare_versions (engine_get_version (proto),
101                                   engine_get_req_version (proto))
102     ? 0 : GPGME_Invalid_Engine;
103 }
104
105
106 /* Get the information about the configured and installed engines.  A
107    pointer to the first engine in the statically allocated linked list
108    is returned in *INFO.  If an error occurs, it is returned.  */
109 gpgme_error_t
110 gpgme_get_engine_info (gpgme_engine_info_t *info)
111 {
112   static gpgme_engine_info_t engine_info;
113   DEFINE_STATIC_LOCK (engine_info_lock);
114
115   LOCK (engine_info_lock);
116   if (!engine_info)
117     {
118       gpgme_engine_info_t *lastp = &engine_info;
119       gpgme_protocol_t proto_list[] = { GPGME_PROTOCOL_OpenPGP,
120                                      GPGME_PROTOCOL_CMS };
121       int proto;
122
123       for (proto = 0; proto < DIM (proto_list); proto++)
124         {
125           const char *file_name = engine_get_file_name (proto_list[proto]);
126
127           if (!file_name)
128             continue;
129
130           *lastp = malloc (sizeof (*engine_info));
131           if (!*lastp)
132             {
133               while (engine_info)
134                 {
135                   gpgme_engine_info_t next_info = engine_info->next;
136                   free (engine_info);
137                   engine_info = next_info;
138                 }
139               UNLOCK (engine_info_lock);
140               return GPGME_Out_Of_Core;
141             }
142
143           (*lastp)->protocol = proto_list[proto];
144           (*lastp)->file_name = file_name;
145           (*lastp)->version = engine_get_version (proto_list[proto]);
146           (*lastp)->req_version = engine_get_req_version (proto_list[proto]);
147           lastp = &(*lastp)->next;
148         }
149     }
150   UNLOCK (engine_info_lock);
151   *info = engine_info;
152   return 0;
153 }
154
155 \f
156 gpgme_error_t
157 _gpgme_engine_new (gpgme_protocol_t proto, engine_t *r_engine)
158 {
159   engine_t engine;
160
161   const char *file_name;
162   const char *version;
163
164   if (proto > DIM (engine_ops))
165     return GPGME_Invalid_Value;
166
167   if (!engine_ops[proto])
168     return GPGME_Invalid_Engine;
169
170   file_name = engine_get_file_name (proto);
171   version = engine_get_version (proto);
172   if (!file_name || !version)
173     return GPGME_Invalid_Engine;
174
175   engine = calloc (1, sizeof *engine);
176   if (!engine)
177     return GPGME_Out_Of_Core;
178
179   engine->ops = engine_ops[proto];
180   if (engine_ops[proto]->new)
181     {
182       gpgme_error_t err = (*engine_ops[proto]->new) (&engine->engine);
183       if (err)
184         {
185           free (engine);
186           return err;
187         }
188     }
189   else
190     engine->engine = NULL;
191
192   *r_engine = engine;
193   return 0;
194 }
195
196
197 void
198 _gpgme_engine_release (engine_t engine)
199 {
200   if (!engine)
201     return;
202
203   if (engine->ops->release)
204     (*engine->ops->release) (engine->engine);
205   free (engine);
206 }
207
208
209 void
210 _gpgme_engine_set_status_handler (engine_t engine,
211                                   engine_status_handler_t 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 gpgme_error_t
222 _gpgme_engine_set_command_handler (engine_t engine,
223                                    engine_command_handler_t fnc,
224                                    void *fnc_value,
225                                    gpgme_data_t linked_data)
226 {
227   if (!engine)
228     return GPGME_Invalid_Value;
229
230   if (!engine->ops->set_command_handler)
231     return GPGME_Not_Implemented;
232
233   return (*engine->ops->set_command_handler) (engine->engine,
234                                               fnc, fnc_value, linked_data);
235 }
236
237 gpgme_error_t
238 _gpgme_engine_set_colon_line_handler (engine_t engine,
239                                       engine_colon_line_handler_t fnc,
240                                       void *fnc_value)
241 {
242   if (!engine)
243     return GPGME_Invalid_Value;
244
245   if (!engine->ops->set_colon_line_handler)
246     return GPGME_Not_Implemented;
247
248   return (*engine->ops->set_colon_line_handler) (engine->engine,
249                                                  fnc, fnc_value);
250 }
251
252 gpgme_error_t
253 _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
254                           gpgme_data_t plain)
255 {
256   if (!engine)
257     return GPGME_Invalid_Value;
258
259   if (!engine->ops->decrypt)
260     return GPGME_Not_Implemented;
261
262   return (*engine->ops->decrypt) (engine->engine, ciph, plain);
263 }
264
265 gpgme_error_t
266 _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
267                          int allow_secret)
268 {
269   if (!engine)
270     return GPGME_Invalid_Value;
271
272   if (!engine->ops->delete)
273     return GPGME_Not_Implemented;
274
275   return (*engine->ops->delete) (engine->engine, key, allow_secret);
276 }
277
278
279 gpgme_error_t
280 _gpgme_engine_op_edit (engine_t engine, gpgme_key_t key, gpgme_data_t out,
281                        gpgme_ctx_t ctx /* FIXME */)
282 {
283   if (!engine)
284     return GPGME_Invalid_Value;
285
286   if (!engine->ops->edit)
287     return GPGME_Not_Implemented;
288
289   return (*engine->ops->edit) (engine->engine, key, out, ctx);
290 }
291
292
293 gpgme_error_t
294 _gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
295                           gpgme_encrypt_flags_t flags,
296                           gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
297 {
298   if (!engine)
299     return GPGME_Invalid_Value;
300
301   if (!engine->ops->encrypt)
302     return GPGME_Not_Implemented;
303
304   return (*engine->ops->encrypt) (engine->engine, recp, flags, plain, ciph,
305                                   use_armor);
306 }
307
308
309 gpgme_error_t
310 _gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
311                                gpgme_encrypt_flags_t flags,
312                                gpgme_data_t plain, gpgme_data_t ciph,
313                                int use_armor, gpgme_ctx_t ctx /* FIXME */)
314 {
315   if (!engine)
316     return GPGME_Invalid_Value;
317
318   if (!engine->ops->encrypt_sign)
319     return GPGME_Not_Implemented;
320
321   return (*engine->ops->encrypt_sign) (engine->engine, recp, flags,
322                                        plain, ciph, use_armor, ctx);
323 }
324
325
326 gpgme_error_t
327 _gpgme_engine_op_export (engine_t engine, const char *pattern,
328                          unsigned int reserved, gpgme_data_t keydata,
329                          int use_armor)
330 {
331   if (!engine)
332     return GPGME_Invalid_Value;
333
334   if (!engine->ops->export)
335     return GPGME_Not_Implemented;
336
337   return (*engine->ops->export) (engine->engine, pattern, reserved,
338                                  keydata, use_armor);
339 }
340
341
342 gpgme_error_t
343 _gpgme_engine_op_export_ext (engine_t engine, const char *pattern[],
344                              unsigned int reserved, gpgme_data_t keydata,
345                              int use_armor)
346 {
347   if (!engine)
348     return GPGME_Invalid_Value;
349
350   if (!engine->ops->export_ext)
351     return GPGME_Not_Implemented;
352
353   return (*engine->ops->export_ext) (engine->engine, pattern, reserved,
354                                      keydata, use_armor);
355 }
356
357
358 gpgme_error_t
359 _gpgme_engine_op_genkey (engine_t engine, gpgme_data_t help_data,
360                          int use_armor, gpgme_data_t pubkey,
361                          gpgme_data_t seckey)
362 {
363   if (!engine)
364     return GPGME_Invalid_Value;
365
366   if (!engine->ops->genkey)
367     return GPGME_Not_Implemented;
368
369   return (*engine->ops->genkey) (engine->engine, help_data, use_armor,
370                                  pubkey, seckey);
371 }
372
373
374 gpgme_error_t
375 _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata)
376 {
377   if (!engine)
378     return GPGME_Invalid_Value;
379
380   if (!engine->ops->import)
381     return GPGME_Not_Implemented;
382
383   return (*engine->ops->import) (engine->engine, keydata);
384 }
385
386
387 gpgme_error_t
388 _gpgme_engine_op_keylist (engine_t engine, const char *pattern,
389                           int secret_only, gpgme_keylist_mode_t mode)
390 {
391   if (!engine)
392     return GPGME_Invalid_Value;
393
394   if (!engine->ops->keylist)
395     return GPGME_Not_Implemented;
396
397   return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode);
398 }
399
400
401 gpgme_error_t
402 _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
403                               int secret_only, int reserved,
404                               gpgme_keylist_mode_t mode)
405 {
406   if (!engine)
407     return GPGME_Invalid_Value;
408
409   if (!engine->ops->keylist_ext)
410     return GPGME_Not_Implemented;
411
412   return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
413                                       reserved, mode);
414 }
415
416
417 gpgme_error_t
418 _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out,
419                        gpgme_sig_mode_t mode, int use_armor,
420                        int use_textmode, int include_certs,
421                        gpgme_ctx_t ctx /* FIXME */)
422 {
423   if (!engine)
424     return GPGME_Invalid_Value;
425
426   if (!engine->ops->sign)
427     return GPGME_Not_Implemented;
428
429   return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor,
430                                use_textmode, include_certs, ctx);
431 }
432
433
434 gpgme_error_t
435 _gpgme_engine_op_trustlist (engine_t engine, const char *pattern)
436 {
437   if (!engine)
438     return GPGME_Invalid_Value;
439
440   if (!engine->ops->trustlist)
441     return GPGME_Not_Implemented;
442
443   return (*engine->ops->trustlist) (engine->engine, pattern);
444 }
445
446
447 gpgme_error_t
448 _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
449                          gpgme_data_t signed_text, gpgme_data_t plaintext)
450 {
451   if (!engine)
452     return GPGME_Invalid_Value;
453
454   if (!engine->ops->verify)
455     return GPGME_Not_Implemented;
456
457   return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext);
458 }
459
460
461 void
462 _gpgme_engine_set_io_cbs (engine_t engine, gpgme_io_cbs_t io_cbs)
463 {
464   if (!engine)
465     return;
466
467   (*engine->ops->set_io_cbs) (engine->engine, io_cbs);
468 }
469
470
471 void
472 _gpgme_engine_io_event (engine_t engine,
473                         gpgme_event_io_t type, void *type_data)
474 {
475   if (!engine)
476     return;
477
478   (*engine->ops->io_event) (engine->engine, type, type_data);
479 }