summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/status.h1
-rw-r--r--doc/DETAILS7
-rw-r--r--g10/call-agent.c46
-rw-r--r--g10/call-dirmngr.c37
-rw-r--r--sm/call-agent.c42
-rw-r--r--sm/call-dirmngr.c38
6 files changed, 164 insertions, 7 deletions
diff --git a/common/status.h b/common/status.h
index 509e04439..e50827fe0 100644
--- a/common/status.h
+++ b/common/status.h
@@ -141,6 +141,7 @@ enum
STATUS_PLAINTEXT_FOLLOWS, /* Used by g13-syshelp */
STATUS_ERROR,
+ STATUS_WARNING,
STATUS_SUCCESS,
STATUS_FAILURE,
diff --git a/doc/DETAILS b/doc/DETAILS
index 7c3e67c61..69c2e5b00 100644
--- a/doc/DETAILS
+++ b/doc/DETAILS
@@ -840,7 +840,12 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
should not contain spaces. The error code is a either a string
commencing with a letter or such a string prefixed with a
numerical error code and an underscore; e.g.: "151011327_EOF".
-
+*** WARNING <location> <error code> [<text>]
+ This is a generic warning status message, it might be followed by
+ error location specific data. <error code> and <location>
+ should not contain spaces. The error code is a either a string
+ commencing with a letter or such a string prefixed with a
+ numerical error code and an underscore; e.g.: "151011327_EOF".
*** SUCCESS [<location>]
Postive confirmation that an operation succeeded. It is used
similar to ISO-C's EXIT_SUCCESS. <location> is optional but if
diff --git a/g10/call-agent.c b/g10/call-agent.c
index 3600579bd..83fabcc32 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -253,6 +253,40 @@ check_hijacking (assuan_context_t ctx)
+/* Print a warning if the server's version number is less than our
+ version number. Returns an error code on a connection problem. */
+static gpg_error_t
+warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
+{
+ gpg_error_t err;
+ char *serverversion;
+ const char *myversion = strusage (13);
+
+ err = get_assuan_server_version (ctx, mode, &serverversion);
+ if (err)
+ log_error (_("error getting version from '%s': %s\n"),
+ servername, gpg_strerror (err));
+ else if (!compare_version_strings (serverversion, myversion))
+ {
+ char *warn;
+
+ warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"),
+ servername, serverversion, myversion);
+ if (!warn)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ log_info (_("WARNING: %s\n"), warn);
+ write_status_strings (STATUS_WARNING, "server_version_mismatch 0",
+ " ", warn, NULL);
+ xfree (warn);
+ }
+ }
+ xfree (serverversion);
+ return err;
+}
+
+
/* Try to connect to the agent via socket or fork it off and work by
pipes. Handle the server's initial greeting */
static int
@@ -286,7 +320,8 @@ start_agent (ctrl_t ctrl, int for_card)
log_info (_("no gpg-agent running in this session\n"));
}
}
- else if (!rc)
+ else if (!rc
+ && !(rc = warn_version_mismatch (agent_ctx, GPG_AGENT_NAME, 0)))
{
/* Tell the agent that we support Pinentry notifications.
No error checking so that it will work also with older
@@ -324,9 +359,12 @@ start_agent (ctrl_t ctrl, int for_card)
struct agent_card_info_s info;
memset (&info, 0, sizeof info);
- rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
- NULL, NULL, NULL, NULL,
- learn_status_cb, &info);
+
+ rc = warn_version_mismatch (agent_ctx, SCDAEMON_NAME, 2);
+ if (!rc)
+ rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
+ NULL, NULL, NULL, NULL,
+ learn_status_cb, &info);
if (rc)
{
switch (gpg_err_code (rc))
diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
index b1c856d77..360e12743 100644
--- a/g10/call-dirmngr.c
+++ b/g10/call-dirmngr.c
@@ -38,6 +38,7 @@
#include "i18n.h"
#include "asshelp.h"
#include "keyserver.h"
+#include "status.h"
#include "call-dirmngr.h"
@@ -132,6 +133,40 @@ gpg_dirmngr_deinit_session_data (ctrl_t ctrl)
}
+/* Print a warning if the server's version number is less than our
+ version number. Returns an error code on a connection problem. */
+static gpg_error_t
+warn_version_mismatch (assuan_context_t ctx, const char *servername)
+{
+ gpg_error_t err;
+ char *serverversion;
+ const char *myversion = strusage (13);
+
+ err = get_assuan_server_version (ctx, 0, &serverversion);
+ if (err)
+ log_error (_("error getting version from '%s': %s\n"),
+ servername, gpg_strerror (err));
+ else if (!compare_version_strings (serverversion, myversion))
+ {
+ char *warn;
+
+ warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"),
+ servername, serverversion, myversion);
+ if (!warn)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ log_info (_("WARNING: %s\n"), warn);
+ write_status_strings (STATUS_WARNING, "server_version_mismatch 0",
+ " ", warn, NULL);
+ xfree (warn);
+ }
+ }
+ xfree (serverversion);
+ return err;
+}
+
+
/* Try to connect to the Dirmngr via a socket or spawn it if possible.
Handle the server's initial greeting and set global options. */
static gpg_error_t
@@ -157,7 +192,7 @@ create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
log_info (_("no dirmngr running in this session\n"));
}
}
- else if (!err)
+ else if (!err && !(err = warn_version_mismatch (ctx, DIRMNGR_NAME)))
{
char *line;
diff --git a/sm/call-agent.c b/sm/call-agent.c
index b881fb8c4..c7d4c5a88 100644
--- a/sm/call-agent.c
+++ b/sm/call-agent.c
@@ -76,6 +76,41 @@ struct import_key_parm_s
+/* Print a warning if the server's version number is less than our
+ version number. Returns an error code on a connection problem. */
+static gpg_error_t
+warn_version_mismatch (ctrl_t ctrl, assuan_context_t ctx,
+ const char *servername, int mode)
+{
+ gpg_error_t err;
+ char *serverversion;
+ const char *myversion = strusage (13);
+
+ err = get_assuan_server_version (ctx, mode, &serverversion);
+ if (err)
+ log_error (_("error getting version from '%s': %s\n"),
+ servername, gpg_strerror (err));
+ else if (!compare_version_strings (serverversion, myversion))
+ {
+ char *warn;
+
+ warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"),
+ servername, serverversion, myversion);
+ if (!warn)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ log_info (_("WARNING: %s\n"), warn);
+ gpgsm_status2 (ctrl, STATUS_WARNING, "server_version_mismatch 0",
+ warn, NULL);
+ xfree (warn);
+ }
+ }
+ xfree (serverversion);
+ return err;
+}
+
+
/* Try to connect to the agent via socket or fork it off and work by
pipes. Handle the server's initial greeting */
static int
@@ -108,7 +143,8 @@ start_agent (ctrl_t ctrl)
log_info (_("no gpg-agent running in this session\n"));
}
}
- else if (!rc)
+ else if (!rc && !(rc = warn_version_mismatch (ctrl, agent_ctx,
+ GPG_AGENT_NAME, 0)))
{
/* Tell the agent that we support Pinentry notifications. No
error checking so that it will work also with older
@@ -919,6 +955,10 @@ gpgsm_agent_learn (ctrl_t ctrl)
if (rc)
return rc;
+ rc = warn_version_mismatch (ctrl, agent_ctx, SCDAEMON_NAME, 2);
+ if (rc)
+ return rc;
+
init_membuf (&data, 4096);
learn_parm.error = 0;
learn_parm.ctrl = ctrl;
diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c
index 379d7e9cc..881c484d5 100644
--- a/sm/call-dirmngr.c
+++ b/sm/call-dirmngr.c
@@ -149,6 +149,41 @@ get_membuf (struct membuf *mb, size_t *len)
}
+/* Print a warning if the server's version number is less than our
+ version number. Returns an error code on a connection problem. */
+static gpg_error_t
+warn_version_mismatch (ctrl_t ctrl, assuan_context_t ctx,
+ const char *servername, int mode)
+{
+ gpg_error_t err;
+ char *serverversion;
+ const char *myversion = strusage (13);
+
+ err = get_assuan_server_version (ctx, mode, &serverversion);
+ if (err)
+ log_error (_("error getting version from '%s': %s\n"),
+ servername, gpg_strerror (err));
+ else if (!compare_version_strings (serverversion, myversion))
+ {
+ char *warn;
+
+ warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"),
+ servername, serverversion, myversion);
+ if (!warn)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ log_info (_("WARNING: %s\n"), warn);
+ gpgsm_status2 (ctrl, STATUS_WARNING, "server_version_mismatch 0",
+ warn, NULL);
+ xfree (warn);
+ }
+ }
+ xfree (serverversion);
+ return err;
+}
+
+
/* This function prepares the dirmngr for a new session. The
audit-events option is used so that other dirmngr clients won't get
disturbed by such events. */
@@ -158,6 +193,9 @@ prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err)
struct keyserver_spec *server;
if (!err)
+ err = warn_version_mismatch (ctrl, ctx, DIRMNGR_NAME, 0);
+
+ if (!err)
{
err = assuan_transact (ctx, "OPTION audit-events=1",
NULL, NULL, NULL, NULL, NULL, NULL);