diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/asshelp.c | 54 | ||||
-rw-r--r-- | common/asshelp.h | 10 | ||||
-rw-r--r-- | common/asshelp2.c | 2 | ||||
-rw-r--r-- | common/status.c | 41 | ||||
-rw-r--r-- | common/status.h | 4 |
5 files changed, 110 insertions, 1 deletions
diff --git a/common/asshelp.c b/common/asshelp.c index fe49aa83a..0d903fd5f 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -696,3 +696,57 @@ get_assuan_server_version (assuan_context_t ctx, int mode, char **r_version) } return err; } + + +/* Print a warning if the server's version number is less than our + * version number. Returns an error code on a connection problem. + * CTX is the Assuan context, SERVERNAME is the name of teh server, + * STATUS_FUNC and STATUS_FUNC_DATA is a callback to emit status + * messages. If PRINT_HINTS is set additional hints are printed. For + * MODE see get_assuan_server_version. */ +gpg_error_t +warn_server_version_mismatch (assuan_context_t ctx, + const char *servername, int mode, + gpg_error_t (*status_func)(ctrl_t ctrl, + int status_no, + ...), + void *status_func_ctrl, + int print_hints) +{ + gpg_error_t err; + char *serverversion; + const char *myversion = gpgrt_strusage (13); + + err = get_assuan_server_version (ctx, mode, &serverversion); + if (err) + log_log (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED? + GPGRT_LOGLVL_INFO : GPGRT_LOGLVL_ERROR, + _("error getting version from '%s': %s\n"), + servername, gpg_strerror (err)); + else if (compare_version_strings (serverversion, myversion) < 0) + { + 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); + if (print_hints) + { + log_info (_("Note: Outdated servers may lack important" + " security fixes.\n")); + log_info (_("Note: Use the command \"%s\" to restart them.\n"), + "gpgconf --kill all"); + } + if (status_func) + status_func (status_func_ctrl, STATUS_WARNING, + "server_version_mismatch 0", warn, NULL); + xfree (warn); + } + } + xfree (serverversion); + return err; +} diff --git a/common/asshelp.h b/common/asshelp.h index b2f4e538f..e7e43bd1b 100644 --- a/common/asshelp.h +++ b/common/asshelp.h @@ -89,6 +89,16 @@ start_new_dirmngr (assuan_context_t *r_ctx, gpg_error_t get_assuan_server_version (assuan_context_t ctx, int mode, char **r_version); +/* Print a server version mismatch warning. */ +gpg_error_t warn_server_version_mismatch (assuan_context_t ctx, + const char *servername, int mode, + gpg_error_t (*status_fnc) + (ctrl_t ctrl, + int status_id, + ...), + void *status_func_ctrl, + int print_hints); + /*-- asshelp2.c --*/ diff --git a/common/asshelp2.c b/common/asshelp2.c index a62189df9..4aad8a242 100644 --- a/common/asshelp2.c +++ b/common/asshelp2.c @@ -173,7 +173,7 @@ status_printf (ctrl_t ctrl, const char *keyword, const char *format, ...) } -/* Same as sytus_printf but takes a status number instead of a +/* Same as status_printf but takes a status number instead of a * keyword. */ gpg_error_t status_no_printf (ctrl_t ctrl, int no, const char *format, ...) diff --git a/common/status.c b/common/status.c index 269ffea5d..b752c12c6 100644 --- a/common/status.c +++ b/common/status.c @@ -105,6 +105,47 @@ gnupg_status_printf (int no, const char *format, ...) } +/* Write a status line with code NO followed by the remaining + * arguments which must be a list of strings terminated by a NULL. + * Embedded CR and LFs in the strings are C-style escaped. All + * strings are printed with a space as delimiter. */ +gpg_error_t +gnupg_status_strings (ctrl_t dummy, int no, ...) +{ + va_list arg_ptr; + const char *s; + + (void)dummy; + + if (!statusfp) + return 0; /* Not enabled. */ + + va_start (arg_ptr, no); + + es_fputs ("[GNUPG:] ", statusfp); + es_fputs (get_status_string (no), statusfp); + while ((s = va_arg (arg_ptr, const char*))) + { + if (*s) + es_putc (' ', statusfp); + for (; *s; s++) + { + if (*s == '\n') + es_fputs ("\\n", statusfp); + else if (*s == '\r') + es_fputs ("\\r", statusfp); + else + es_fputc (*(const byte *)s, statusfp); + } + } + es_putc ('\n', statusfp); + es_fflush (statusfp); + + va_end (arg_ptr); + return 0; +} + + const char * get_inv_recpsgnr_code (gpg_error_t err) { diff --git a/common/status.h b/common/status.h index aeab54202..477b29eaa 100644 --- a/common/status.h +++ b/common/status.h @@ -30,6 +30,8 @@ #ifndef GNUPG_COMMON_STATUS_H #define GNUPG_COMMON_STATUS_H +#include "../common/fwddecl.h" + enum { STATUS_ENTER, @@ -166,6 +168,8 @@ const char *get_status_string (int code); void gnupg_set_status_fd (int fd); void gnupg_status_printf (int no, const char *format, ...) GPGRT_ATTR_PRINTF(2,3); +gpg_error_t gnupg_status_strings (ctrl_t dummy, int no, + ...) GPGRT_ATTR_SENTINEL(0); const char *get_inv_recpsgnr_code (gpg_error_t err); |