#include <string.h>
#include <sys/types.h>
#include <assert.h>
+#include <unistd.h>
+#include <locale.h>
#include <fcntl.h> /* FIXME */
#include "rungpg.h"
}
+static GpgmeError
+map_assuan_error (AssuanError err)
+{
+ switch (err)
+ {
+ case ASSUAN_No_Error:
+ return mk_error (No_Error);
+ case ASSUAN_General_Error:
+ return mk_error (General_Error);
+ case ASSUAN_Out_Of_Core:
+ return mk_error (Out_Of_Core);
+ case ASSUAN_Invalid_Value:
+ return mk_error (Invalid_Value);
+ case ASSUAN_Read_Error:
+ return mk_error (Read_Error);
+ case ASSUAN_Write_Error:
+ return mk_error (Write_Error);
+
+ case ASSUAN_Timeout:
+ case ASSUAN_Problem_Starting_Server:
+ case ASSUAN_Not_A_Server:
+ case ASSUAN_Not_A_Client:
+ case ASSUAN_Nested_Commands:
+ case ASSUAN_Invalid_Response:
+ case ASSUAN_No_Data_Callback:
+ case ASSUAN_No_Inquire_Callback:
+ case ASSUAN_Connect_Failed:
+ case ASSUAN_Accept_Failed:
+ return mk_error (General_Error);
+
+ /* The following error codes are meant as status codes. */
+ case ASSUAN_Not_Implemented:
+ return mk_error (Not_Implemented);
+ case ASSUAN_Canceled:
+ return mk_error (Canceled);
+ case ASSUAN_Unsupported_Algorithm:
+ return mk_error (Not_Implemented); /* XXX Argh. */
+
+ /* These are errors internal to GPGME. */
+ case ASSUAN_No_Data_Available:
+ case ASSUAN_No_Input:
+ case ASSUAN_No_Output:
+ case ASSUAN_Invalid_Command:
+ case ASSUAN_Unknown_Command:
+ case ASSUAN_Syntax_Error:
+ case ASSUAN_Parameter_Error:
+ case ASSUAN_Parameter_Conflict:
+ case ASSUAN_Line_Too_Long:
+ case ASSUAN_Line_Not_Terminated:
+ case ASSUAN_Invalid_Data:
+ case ASSUAN_Unexpected_Command:
+ case ASSUAN_Too_Much_Data:
+ case ASSUAN_Inquire_Unknown:
+ case ASSUAN_Inquire_Error:
+ case ASSUAN_Invalid_Option:
+ case ASSUAN_Invalid_Index:
+ case ASSUAN_Unexpected_Status:
+ case ASSUAN_Unexpected_Data:
+ case ASSUAN_Invalid_Status:
+ case ASSUAN_Not_Confirmed:
+ return mk_error (General_Error);
+
+ /* These are errors in the server. */
+ case ASSUAN_Server_Fault:
+ case ASSUAN_Server_Resource_Problem:
+ case ASSUAN_Server_IO_Error:
+ case ASSUAN_Server_Bug:
+ case ASSUAN_No_Agent:
+ case ASSUAN_Agent_Error:
+ return mk_error (Invalid_Engine); /* XXX: Need something more useful. */
+
+ case ASSUAN_Bad_Certificate:
+ case ASSUAN_Bad_Certificate_Path:
+ case ASSUAN_Missing_Certificate:
+ case ASSUAN_No_Public_Key:
+ case ASSUAN_No_Secret_Key:
+ case ASSUAN_Invalid_Name:
+ case ASSUAN_Card_Error: /* XXX: Oh well. */
+ case ASSUAN_Invalid_Card: /* XXX: Oh well. */
+ case ASSUAN_No_PKCS15_App: /* XXX: Oh well. */
+ case ASSUAN_Card_Not_Present: /* XXX: Oh well. */
+ case ASSUAN_Invalid_Id: /* XXX: Oh well. */
+ return mk_error (Invalid_Key);
+
+ case ASSUAN_Bad_Signature:
+ return mk_error (Invalid_Key); /* XXX: This is wrong. */
+
+ case ASSUAN_Cert_Revoked:
+ case ASSUAN_No_CRL_For_Cert:
+ case ASSUAN_CRL_Too_Old:
+ case ASSUAN_Not_Trusted:
+ return mk_error (Invalid_Key); /* XXX Some more details would be good. */
+
+ default:
+ return mk_error (General_Error);
+ }
+}
+
+
GpgmeError
_gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
{
GpgmeError err = 0;
GpgsmObject gpgsm;
- char *argv[] = { "gpgsm", "--server", NULL };
+ char *argv[3];
int fds[2];
int child_fds[4];
+ char *dft_display = NULL;
+ char *dft_ttyname = NULL;
+ char *dft_ttytype = NULL;
+ char *old_lc = NULL;
+ char *dft_lc = NULL;
+ char *optstr;
*r_gpgsm = NULL;
gpgsm = xtrycalloc (1, sizeof *gpgsm);
child_fds[1] = gpgsm->output_fd_server;
child_fds[2] = gpgsm->message_fd_server;
child_fds[3] = -1;
+
+ argv[0] = "gpgsm";
+ argv[1] = "--server";
+ argv[2] = NULL;
+
err = assuan_pipe_connect (&gpgsm->assuan_ctx,
_gpgme_get_gpgsm_path (), argv, child_fds);
+ dft_display = getenv ("DISPLAY");
+ if (dft_display)
+ {
+ if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
+ {
+ err = mk_error (Out_Of_Core);
+ goto leave;
+ }
+ err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ free (optstr);
+ if (err)
+ {
+ err = map_assuan_error (err);
+ goto leave;
+ }
+ }
+ dft_ttyname = ttyname (1);
+ if (dft_ttyname)
+ {
+ if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
+ {
+ err = mk_error (Out_Of_Core);
+ goto leave;
+ }
+ err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ free (optstr);
+ if (err)
+ {
+ err = map_assuan_error (err);
+ goto leave;
+ }
+
+ dft_ttytype = getenv ("TERM");
+ if (dft_ttytype)
+ {
+ if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0)
+ {
+ err = mk_error (Out_Of_Core);
+ goto leave;
+ }
+ err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ free (optstr);
+ if (err)
+ {
+ err = map_assuan_error (err);
+ goto leave;
+ }
+ }
+ old_lc = setlocale (LC_CTYPE, NULL);
+ dft_lc = setlocale (LC_CTYPE, "");
+ if (dft_lc)
+ {
+ if (asprintf (&optstr, "OPTION lc-ctype=%s", dft_lc) < 0)
+ err = mk_error (Out_Of_Core);
+ else
+ {
+ err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ free (optstr);
+ if (err)
+ err = map_assuan_error (err);
+ }
+ }
+ if (old_lc)
+ setlocale (LC_CTYPE, old_lc);
+ if (err)
+ goto leave;
+
+ old_lc = setlocale (LC_MESSAGES, NULL);
+ dft_lc = setlocale (LC_MESSAGES, "");
+ if (dft_lc)
+ {
+ if (asprintf (&optstr, "OPTION lc-messages=%s", dft_lc) < 0)
+ err = mk_error (Out_Of_Core);
+ else
+ {
+ err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ free (optstr);
+ if (err)
+ err = map_assuan_error (err);
+ }
+ }
+ if (old_lc)
+ setlocale (LC_MESSAGES, old_lc);
+ if (err)
+ goto leave;
+ }
+
if (!err &&
(_gpgme_io_set_close_notify (gpgsm->input_fd,
close_notify_handler, gpgsm)
}
-static GpgmeError
-map_assuan_error (AssuanError err)
-{
- switch (err)
- {
- case ASSUAN_No_Error:
- return mk_error (No_Error);
- case ASSUAN_General_Error:
- return mk_error (General_Error);
- case ASSUAN_Out_Of_Core:
- return mk_error (Out_Of_Core);
- case ASSUAN_Invalid_Value:
- return mk_error (Invalid_Value);
- case ASSUAN_Read_Error:
- return mk_error (Read_Error);
- case ASSUAN_Write_Error:
- return mk_error (Write_Error);
-
- case ASSUAN_Timeout:
- case ASSUAN_Problem_Starting_Server:
- case ASSUAN_Not_A_Server:
- case ASSUAN_Not_A_Client:
- case ASSUAN_Nested_Commands:
- case ASSUAN_Invalid_Response:
- case ASSUAN_No_Data_Callback:
- case ASSUAN_No_Inquire_Callback:
- case ASSUAN_Connect_Failed:
- case ASSUAN_Accept_Failed:
- return mk_error (General_Error);
-
- /* The following error codes are meant as status codes. */
- case ASSUAN_Not_Implemented:
- return mk_error (Not_Implemented);
- case ASSUAN_Canceled:
- return mk_error (Canceled);
- case ASSUAN_Unsupported_Algorithm:
- return mk_error (Not_Implemented); /* XXX Argh. */
-
- /* These are errors internal to GPGME. */
- case ASSUAN_No_Data_Available:
- case ASSUAN_No_Input:
- case ASSUAN_No_Output:
- case ASSUAN_Invalid_Command:
- case ASSUAN_Unknown_Command:
- case ASSUAN_Syntax_Error:
- case ASSUAN_Parameter_Error:
- case ASSUAN_Parameter_Conflict:
- case ASSUAN_Line_Too_Long:
- case ASSUAN_Line_Not_Terminated:
- case ASSUAN_Invalid_Data:
- case ASSUAN_Unexpected_Command:
- case ASSUAN_Too_Much_Data:
- case ASSUAN_Inquire_Unknown:
- case ASSUAN_Inquire_Error:
- case ASSUAN_Invalid_Option:
- case ASSUAN_Invalid_Index:
- case ASSUAN_Unexpected_Status:
- case ASSUAN_Unexpected_Data:
- case ASSUAN_Invalid_Status:
- case ASSUAN_Not_Confirmed:
- return mk_error (General_Error);
-
- /* These are errors in the server. */
- case ASSUAN_Server_Fault:
- case ASSUAN_Server_Resource_Problem:
- case ASSUAN_Server_IO_Error:
- case ASSUAN_Server_Bug:
- case ASSUAN_No_Agent:
- case ASSUAN_Agent_Error:
- return mk_error (Invalid_Engine); /* XXX: Need something more useful. */
-
- case ASSUAN_Bad_Certificate:
- case ASSUAN_Bad_Certificate_Path:
- case ASSUAN_Missing_Certificate:
- case ASSUAN_No_Public_Key:
- case ASSUAN_No_Secret_Key:
- case ASSUAN_Invalid_Name:
- case ASSUAN_Card_Error: /* XXX: Oh well. */
- case ASSUAN_Invalid_Card: /* XXX: Oh well. */
- case ASSUAN_No_PKCS15_App: /* XXX: Oh well. */
- case ASSUAN_Card_Not_Present: /* XXX: Oh well. */
- case ASSUAN_Invalid_Id: /* XXX: Oh well. */
- return mk_error(Invalid_Key);
-
- case ASSUAN_Bad_Signature:
- return mk_error(Invalid_Key); /* XXX: This is wrong. */
-
- case ASSUAN_Cert_Revoked:
- case ASSUAN_No_CRL_For_Cert:
- case ASSUAN_CRL_Too_Old:
- case ASSUAN_Not_Trusted:
- return mk_error(Invalid_Key); /* XXX Some more details would be good. */
-
- default:
- return mk_error (General_Error);
- }
-}
-
-
static GpgmeError
gpgsm_assuan_simple_command (ASSUAN_CONTEXT ctx, char *cmd)
{
if (! newline)
{
xfree (line);
- return mk_error(Out_Of_Core);
+ return mk_error (Out_Of_Core);
}
line = newline;
linelen = newlen;