#include "ops.h"
#include "wait.h"
#include "io.h"
+#include "key.h"
#include "engine-gpgsm.h"
_gpgme_io_close (gpgsm->message_fd);
assuan_pipe_disconnect (gpgsm->assuan_ctx);
+
+ xfree (gpgsm->command);
xfree (gpgsm);
}
-#define COMMANDLINELEN 40
static AssuanError
-gpgsm_set_fd (ASSUAN_CONTEXT ctx, const char *which, int fd)
+gpgsm_assuan_simple_command (ASSUAN_CONTEXT ctx, char *line)
{
AssuanError err;
- char line[COMMANDLINELEN];
- snprintf (line, COMMANDLINELEN, "%s FD=%i", which, fd);
err = _assuan_write_line (ctx, line);
if (err)
return err;
return ASSUAN_General_Error;
}
+#define COMMANDLINELEN 40
+static AssuanError
+gpgsm_set_fd (ASSUAN_CONTEXT ctx, const char *which, int fd)
+{
+ char line[COMMANDLINELEN];
+
+ snprintf (line, COMMANDLINELEN, "%s FD=%i", which, fd);
+ return gpgsm_assuan_simple_command (ctx, line);
+}
+
GpgmeError
_gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, GpgmeData plain)
{
if (!gpgsm)
return mk_error (Invalid_Value);
+ gpgsm->command = xtrystrdup ("DECRYPT");
+ if (!gpgsm->command)
+ return mk_error (Out_Of_Core);
+
gpgsm->input_data = ciph;
err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server);
if (err)
_gpgme_io_close (gpgsm->message_fd);
gpgsm->message_fd = -1;
- gpgsm->command = "DECRYPT";
return 0;
}
+GpgmeError
+_gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, int allow_secret)
+{
+ /* FIXME */
+ return mk_error (Not_Implemented);
+}
+
+static AssuanError
+gpgsm_set_recipients (ASSUAN_CONTEXT ctx, GpgmeRecipients recp)
+{
+ AssuanError err;
+ char *line;
+ int linelen;
+ struct user_id_s *r;
+
+ linelen = 10 + 40 + 1; /* "RECIPIENT " + guess + '\0'. */
+ line = xtrymalloc (10 + 40 + 1);
+ if (!line)
+ return ASSUAN_Out_Of_Core;
+ strcpy (line, "RECIPIENT ");
+ for (r = recp->list; r; r = r->next)
+ {
+ int newlen = 11 + strlen (r->name);
+ if (linelen < newlen)
+ {
+ char *newline = xtryrealloc (line, newlen);
+ if (! newline)
+ {
+ xfree (line);
+ return ASSUAN_Out_Of_Core;
+ }
+ line = newline;
+ linelen = newlen;
+ }
+ strcpy (&line[10], r->name);
+
+ err = gpgsm_assuan_simple_command (ctx, line);
+ if (err)
+ {
+ xfree (line);
+ return err;
+ }
+ }
+ return 0;
+}
+
+GpgmeError
+_gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp,
+ GpgmeData plain, GpgmeData ciph, int use_armor)
+{
+ AssuanError err;
+
+ if (!gpgsm)
+ return mk_error (Invalid_Value);
+
+ gpgsm->command = xtrystrdup (use_armor ? "ENCRYPT armor" : "ENCRYPT");
+ if (!gpgsm->command)
+ return mk_error (Out_Of_Core);
+
+ gpgsm->input_data = plain;
+ err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server);
+ if (err)
+ return mk_error (General_Error); /* FIXME */
+ gpgsm->output_data = ciph;
+ err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server);
+ if (err)
+ return mk_error (General_Error); /* FIXME */
+ _gpgme_io_close (gpgsm->message_fd);
+ gpgsm->message_fd = -1;
+
+ err = gpgsm_set_recipients (gpgsm->assuan_ctx, recp);
+ if (err)
+ return mk_error (General_Error);
+
+ return 0;
+}
+
+GpgmeError
+_gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp,
+ GpgmeData keydata, int use_armor)
+{
+ /* FIXME */
+ return mk_error (Not_Implemented);
+}
+
+GpgmeError
+_gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data, int use_armor)
+{
+ /* FIXME */
+ return mk_error (Not_Implemented);
+}
+
GpgmeError
_gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata)
{
if (!gpgsm)
return mk_error (Invalid_Value);
+ gpgsm->command = xtrystrdup ("IMPORT");
+ if (!gpgsm->command)
+ return mk_error (Out_Of_Core);
+
gpgsm->input_data = keydata;
err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server);
if (err)
_gpgme_io_close (gpgsm->message_fd);
gpgsm->message_fd = -1;
- gpgsm->command = "DECRYPT";
return 0;
}
+GpgmeError
+_gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,
+ int secret_only, int keylist_mode)
+{
+ char *line;
+
+ line = xtrymalloc (9 + strlen (pattern) + 1); /* "LISTKEYS " + p + '\0'. */
+ if (!line)
+ return mk_error (Out_Of_Core);
+ strcpy (line, "LISTKEYS ");
+ strcpy (&line[9], pattern);
+
+ _gpgme_io_close (gpgsm->input_fd);
+ gpgsm->input_fd = -1;
+ _gpgme_io_close (gpgsm->output_fd);
+ gpgsm->output_fd = -1;
+ _gpgme_io_close (gpgsm->message_fd);
+ gpgsm->message_fd = -1;
+
+ gpgsm->command = line;
+ return 0;
+}
+
+GpgmeError
+_gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out,
+ GpgmeSigMode mode, int use_armor,
+ int use_textmode, GpgmeCtx ctx /* FIXME */)
+{
+ /* FIXME */
+ return mk_error (Not_Implemented);
+}
+
+GpgmeError
+_gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern)
+{
+ /* FIXME */
+ return mk_error (Not_Implemented);
+}
+
GpgmeError
_gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text)
{
if (!gpgsm)
return mk_error (Invalid_Value);
+ gpgsm->command = xtrystrdup ("VERIFY");
+ if (!gpgsm->command)
+ return mk_error (Out_Of_Core);
+
gpgsm->input_data = sig;
err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server);
if (err)
_gpgme_io_close (gpgsm->output_fd);
gpgsm->output_fd = -1;
- gpgsm->command = "VERIFY";
return 0;
}
if (actx->inbound.line[0] == '#' || !actx->inbound.linelen)
return 0; /* FIXME */
- if (actx->inbound.linelen >= 2
- && actx->inbound.line[0] == 'O' && actx->inbound.line[1] == 'K'
- && (actx->inbound.line[2] == '\0' || actx->inbound.line[2] == ' '))
+ if ((actx->inbound.linelen >= 2
+ && actx->inbound.line[0] == 'O' && actx->inbound.line[1] == 'K'
+ && (actx->inbound.line[2] == '\0' || actx->inbound.line[2] == ' '))
+ || (actx->inbound.linelen >= 3
+ && actx->inbound.line[0] == 'E' && actx->inbound.line[1] == 'R'
+ && actx->inbound.line[2] == 'R'
+ && (actx->inbound.line[3] == '\0' || actx->inbound.line[3] == ' ')))
{
+ /* FIXME Save error somewhere. */
if (gpgsm->status.fnc)
gpgsm->status.fnc (gpgsm->status.fnc_value, STATUS_EOF, "");
return 1;
return mk_error (Invalid_Engine);
}
+GpgmeError
+_gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, int allow_secret)
+{
+ return mk_error (Invalid_Engine);
+}
+
+GpgmeError
+_gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp,
+ GpgmeData plain, GpgmeData ciph, int use_armor)
+{
+ return mk_error (Invalid_Engine);
+}
+
+GpgmeError
+_gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp,
+ GpgmeData keydata, int use_armor)
+{
+ return mk_error (Invalid_Engine);
+}
+
+GpgmeError
+_gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data, int use_armor)
+{
+ return mk_error (Invalid_Engine);
+}
+
GpgmeError
_gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata)
{
return mk_error (Invalid_Engine);
}
+GpgmeError
+_gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,
+ int secret_only, int keylist_mode)
+{
+ return mk_error (Invalid_Engine);
+}
+
+GpgmeError
+_gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out,
+ GpgmeSigMode mode, int use_armor,
+ int use_textmode, GpgmeCtx ctx /* FIXME */)
+{
+ return mk_error (Invalid_Engine);
+}
+
+GpgmeError
+_gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern)
+{
+ return mk_error (Invalid_Engine);
+}
+
GpgmeError
_gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text)
{
void _gpgme_gpgsm_set_status_handler (GpgsmObject gpgsm,
GpgStatusHandler fnc, void *fnc_value);
GpgmeError _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph,
- GpgmeData plain);
-GpgmeError _gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, int allow_secret);
+ GpgmeData plain);
+GpgmeError _gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key,
+ int allow_secret);
GpgmeError _gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp,
- GpgmeData plain, GpgmeData ciph,
- int use_armor);
+ GpgmeData plain, GpgmeData ciph,
+ int use_armor);
GpgmeError _gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp,
- GpgmeData keydata, int use_armor);
+ GpgmeData keydata, int use_armor);
GpgmeError _gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data,
- int use_armor);
+ int use_armor);
GpgmeError _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata);
GpgmeError _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,
- int secret_only, int keylist_mode);
-GpgmeError _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out,
- GpgmeSigMode mode, int use_armor,
- int use_textmode, GpgmeCtx ctx /* FIXME */);
+ int secret_only, int keylist_mode);
+GpgmeError _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in,
+ GpgmeData out,
+ GpgmeSigMode mode, int use_armor,
+ int use_textmode, GpgmeCtx ctx /* FIXME */);
GpgmeError _gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern);
-GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text);
+GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig,
+ GpgmeData text);
GpgmeError _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque);
#endif /* ENGINE_GPGSM_H */
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_decrypt (engine->engine.gpg, ciph, plain);
case GPGME_PROTOCOL_CMS:
- /* FIXME */
- break;
+ return _gpgme_gpgsm_op_decrypt (engine->engine.gpgsm, ciph, plain);
default:
break;
}
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_delete (engine->engine.gpg, key, allow_secret);
case GPGME_PROTOCOL_CMS:
- /* FIXME */
- break;
+ return _gpgme_gpgsm_op_delete (engine->engine.gpgsm, key, allow_secret);
default:
break;
}
return _gpgme_gpg_op_encrypt (engine->engine.gpg, recp, plain, ciph,
use_armor);
case GPGME_PROTOCOL_CMS:
- /* FIXME */
- break;
+ return _gpgme_gpgsm_op_encrypt (engine->engine.gpgsm, recp, plain, ciph,
+ use_armor);
default:
break;
}
return _gpgme_gpg_op_export (engine->engine.gpg, recp, keydata,
use_armor);
case GPGME_PROTOCOL_CMS:
- /* FIXME */
- break;
+ return _gpgme_gpgsm_op_export (engine->engine.gpgsm, recp, keydata,
+ use_armor);
default:
break;
}
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_genkey (engine->engine.gpg, help_data, use_armor);
case GPGME_PROTOCOL_CMS:
- /* FIXME */
- break;
+ return _gpgme_gpgsm_op_genkey (engine->engine.gpgsm, help_data, use_armor);
default:
break;
}
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_import (engine->engine.gpg, keydata);
case GPGME_PROTOCOL_CMS:
- /* FIXME */
- break;
+ return _gpgme_gpgsm_op_import (engine->engine.gpgsm, keydata);
default:
break;
}
return _gpgme_gpg_op_keylist (engine->engine.gpg, pattern, secret_only,
keylist_mode);
case GPGME_PROTOCOL_CMS:
- /* FIXME */
- break;
+ return _gpgme_gpgsm_op_keylist (engine->engine.gpgsm, pattern, secret_only,
+ keylist_mode);
default:
break;
}
return _gpgme_gpg_op_sign (engine->engine.gpg, in, out, mode, use_armor,
use_textmode, ctx);
case GPGME_PROTOCOL_CMS:
- /* FIXME */
+ return _gpgme_gpgsm_op_sign (engine->engine.gpgsm, in, out, mode,
+ use_armor, use_textmode, ctx);
break;
default:
break;
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_trustlist (engine->engine.gpg, pattern);
case GPGME_PROTOCOL_CMS:
- /* FIXME */
- break;
+ return _gpgme_gpgsm_op_trustlist (engine->engine.gpgsm, pattern);
default:
break;
}