aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrdotx <klassiker@gmx.de>2023-04-07 17:44:34 +0200
committermrdotx <klassiker@gmx.de>2023-04-07 17:44:34 +0200
commit51c595a1e11cee49b192c8b170d7c5b094d77298 (patch)
treee380c1cbce654d1c1cb8c9fc3ecdeb29358f2b0c
parent91992dd494bb276c2c8b9cf21537d119691a743b (diff)
pinentry updated to version 1.2.1
-rw-r--r--pinentry/AUTHORS6
-rw-r--r--pinentry/pinentry.c338
-rw-r--r--pinentry/pinentry.h58
-rw-r--r--pinentry/secmem.c49
-rw-r--r--pinentry/util.h17
5 files changed, 236 insertions, 232 deletions
diff --git a/pinentry/AUTHORS b/pinentry/AUTHORS
index 2482e1f..36bf40b 100644
--- a/pinentry/AUTHORS
+++ b/pinentry/AUTHORS
@@ -15,14 +15,14 @@ List of Copyright holders
=========================
Copyright (C) 1999 Robert Bihlmeyer <robbe@orcus.priv.at>
-Copyright (C) 2001-2004, 2007-2008, 2010, 2015-2017 g10 Code GmbH
+Copyright (C) 2001-2004, 2007-2008, 2010, 2015-2017, 2021 g10 Code GmbH
Copyright (C) 2002, 2008 Klarälvdalens Datakonsult AB (KDAB)
Copyright (C) 2004 by Albrecht Dreß <albrecht.dress@arcor.de>
-Copyright 2007 Ingo Klöcker
+Copyright (C) 2007 Ingo Klöcker
Copyright (C) 2014 Serge Voilokov
Copyright (C) 2015 Daiki Ueno
Copyright (C) 2015 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
-Copyright 2016 Intevation GmbH
+Copyright (C) 2016 Intevation GmbH
Copyright (C) 2016 Anatoly madRat L. Berenblit
diff --git a/pinentry/pinentry.c b/pinentry/pinentry.c
index ef81f12..ea11b67 100644
--- a/pinentry/pinentry.c
+++ b/pinentry/pinentry.c
@@ -1,5 +1,5 @@
/* pinentry.c - The PIN entry support library
- * Copyright (C) 2002, 2003, 2007, 2008, 2010, 2015, 2016 g10 Code GmbH
+ * Copyright (C) 2002, 2003, 2007, 2008, 2010, 2015, 2016, 2021 g10 Code GmbH
*
* This file is part of PINENTRY.
*
@@ -37,20 +37,11 @@
#ifndef HAVE_W32CE_SYSTEM
# include <locale.h>
#endif
-#ifdef HAVE_LANGINFO_H
-#include <langinfo.h>
-#endif
#include <limits.h>
#ifdef HAVE_W32CE_SYSTEM
# include <windows.h>
#endif
-#undef WITH_UTF8_CONVERSION
-#if defined FALLBACK_CURSES || defined PINENTRY_CURSES || defined PINENTRY_GTK
-# include <iconv.h>
-# define WITH_UTF8_CONVERSION 1
-#endif
-
#include <assuan.h>
#include "memory.h"
@@ -81,17 +72,11 @@ static const char *flavor_flag;
/* Because gtk_init removes the --display arg from the command lines
* and our command line parser is called after gtk_init (so that it
* does not see gtk specific options) we don't have a way to get hold
- * of the --display option. Our solution is to remember --disable in
+ * of the --display option. Our solution is to remember --display in
* the call to pinentry_have_display and set it then in our
* parser. */
static char *remember_display;
-/* Flag to remember whether a warning has been printed. */
-#ifdef WITH_UTF8_CONVERSION
-static int lc_ctype_unknown_warning;
-#endif
-
-
static void
pinentry_reset (int use_defaults)
{
@@ -111,10 +96,15 @@ pinentry_reset (int use_defaults)
char *default_cf_visi = pinentry.default_cf_visi;
char *default_tt_visi = pinentry.default_tt_visi;
char *default_tt_hide = pinentry.default_tt_hide;
+ char *default_capshint = pinentry.default_capshint;
char *touch_file = pinentry.touch_file;
unsigned long owner_pid = pinentry.owner_pid;
int owner_uid = pinentry.owner_uid;
char *owner_host = pinentry.owner_host;
+ int constraints_enforce = pinentry.constraints_enforce;
+ char *constraints_hint_short = pinentry.constraints_hint_short;
+ char *constraints_hint_long = pinentry.constraints_hint_long;
+ char *constraints_error_title = pinentry.constraints_error_title;
/* These options are set from the command line. Don't reset
them. */
@@ -148,9 +138,13 @@ pinentry_reset (int use_defaults)
free (pinentry.default_cf_visi);
free (pinentry.default_tt_visi);
free (pinentry.default_tt_hide);
+ free (pinentry.default_capshint);
free (pinentry.touch_file);
free (pinentry.owner_host);
free (pinentry.display);
+ free (pinentry.constraints_hint_short);
+ free (pinentry.constraints_hint_long);
+ free (pinentry.constraints_error_title);
}
free (pinentry.title);
@@ -165,6 +159,7 @@ pinentry_reset (int use_defaults)
free (pinentry.repeat_error_string);
free (pinentry.quality_bar);
free (pinentry.quality_bar_tt);
+ free (pinentry.formatted_passphrase_hint);
free (pinentry.keyinfo);
free (pinentry.specific_err_info);
@@ -208,10 +203,15 @@ pinentry_reset (int use_defaults)
pinentry.default_cf_visi = default_cf_visi;
pinentry.default_tt_visi = default_tt_visi;
pinentry.default_tt_hide = default_tt_hide;
+ pinentry.default_capshint = default_capshint;
pinentry.touch_file = touch_file;
pinentry.owner_pid = owner_pid;
pinentry.owner_uid = owner_uid;
pinentry.owner_host = owner_host;
+ pinentry.constraints_enforce = constraints_enforce;
+ pinentry.constraints_hint_short = constraints_hint_short;
+ pinentry.constraints_hint_long = constraints_hint_long;
+ pinentry.constraints_error_title = constraints_error_title;
pinentry.debug = debug;
pinentry.display = display;
@@ -240,150 +240,6 @@ pinentry_assuan_reset_handler (assuan_context_t ctx, char *line)
-#ifdef WITH_UTF8_CONVERSION
-char *
-pinentry_utf8_to_local (const char *lc_ctype, const char *text)
-{
- iconv_t cd;
- const char *input = text;
- size_t input_len = strlen (text) + 1;
- char *output;
- size_t output_len;
- char *output_buf;
- size_t processed;
- char *old_ctype;
- char *target_encoding;
-
- /* If no locale setting could be determined, simply copy the
- string. */
- if (!lc_ctype)
- {
- if (! lc_ctype_unknown_warning)
- {
- fprintf (stderr, "%s: no LC_CTYPE known - assuming UTF-8\n",
- this_pgmname);
- lc_ctype_unknown_warning = 1;
- }
- return strdup (text);
- }
-
- old_ctype = strdup (setlocale (LC_CTYPE, NULL));
- if (!old_ctype)
- return NULL;
- setlocale (LC_CTYPE, lc_ctype);
- target_encoding = nl_langinfo (CODESET);
- if (!target_encoding)
- target_encoding = "?";
- setlocale (LC_CTYPE, old_ctype);
- free (old_ctype);
-
- /* This is overkill, but simplifies the iconv invocation greatly. */
- output_len = input_len * MB_LEN_MAX;
- output_buf = output = malloc (output_len);
- if (!output)
- return NULL;
-
- cd = iconv_open (target_encoding, "UTF-8");
- if (cd == (iconv_t) -1)
- {
- fprintf (stderr, "%s: can't convert from UTF-8 to %s: %s\n",
- this_pgmname, target_encoding, strerror (errno));
- free (output_buf);
- return NULL;
- }
- processed = iconv (cd, (ICONV_CONST char **)&input, &input_len,
- &output, &output_len);
- iconv_close (cd);
- if (processed == (size_t) -1 || input_len)
- {
- fprintf (stderr, "%s: error converting from UTF-8 to %s: %s\n",
- this_pgmname, target_encoding, strerror (errno));
- free (output_buf);
- return NULL;
- }
- return output_buf;
-}
-#endif /*WITH_UTF8_CONVERSION*/
-
-
-/* Convert TEXT which is encoded according to LC_CTYPE to UTF-8. With
- SECURE set to true, use secure memory for the returned buffer.
- Return NULL on error. */
-#ifdef WITH_UTF8_CONVERSION
-char *
-pinentry_local_to_utf8 (char *lc_ctype, char *text, int secure)
-{
- char *old_ctype;
- char *source_encoding;
- iconv_t cd;
- const char *input = text;
- size_t input_len = strlen (text) + 1;
- char *output;
- size_t output_len;
- char *output_buf;
- size_t processed;
-
- /* If no locale setting could be determined, simply copy the
- string. */
- if (!lc_ctype)
- {
- if (! lc_ctype_unknown_warning)
- {
- fprintf (stderr, "%s: no LC_CTYPE known - assuming UTF-8\n",
- this_pgmname);
- lc_ctype_unknown_warning = 1;
- }
- output_buf = secure? secmem_malloc (input_len) : malloc (input_len);
- if (output_buf)
- strcpy (output_buf, input);
- return output_buf;
- }
-
- old_ctype = strdup (setlocale (LC_CTYPE, NULL));
- if (!old_ctype)
- return NULL;
- setlocale (LC_CTYPE, lc_ctype);
- source_encoding = nl_langinfo (CODESET);
- setlocale (LC_CTYPE, old_ctype);
- free (old_ctype);
-
- /* This is overkill, but simplifies the iconv invocation greatly. */
- output_len = input_len * MB_LEN_MAX;
- output_buf = output = secure? secmem_malloc (output_len):malloc (output_len);
- if (!output)
- return NULL;
-
- cd = iconv_open ("UTF-8", source_encoding);
- if (cd == (iconv_t) -1)
- {
- fprintf (stderr, "%s: can't convert from %s to UTF-8: %s\n",
- this_pgmname, source_encoding? source_encoding : "?",
- strerror (errno));
- if (secure)
- secmem_free (output_buf);
- else
- free (output_buf);
- return NULL;
- }
- processed = iconv (cd, (ICONV_CONST char **)&input, &input_len,
- &output, &output_len);
- iconv_close (cd);
- if (processed == (size_t) -1 || input_len)
- {
- fprintf (stderr, "%s: error converting from %s to UTF-8: %s\n",
- this_pgmname, source_encoding? source_encoding : "?",
- strerror (errno));
- if (secure)
- secmem_free (output_buf);
- else
- free (output_buf);
- return NULL;
- }
- return output_buf;
-}
-#endif /*WITH_UTF8_CONVERSION*/
-
-
/* Copy TEXT or TEXTLEN to BUFFER and escape as required. Return a
pointer to the end of the new buffer. Note that BUFFER must be
large enough to keep the entire text; allocataing it 3 times of
@@ -411,6 +267,32 @@ copy_and_escape (char *buffer, const void *text, size_t textlen)
}
+/* Perform percent unescaping in STRING and return the new valid length
+ of the string. A terminating Nul character is inserted at the end of
+ the unescaped string.
+ */
+static size_t
+do_unescape_inplace (char *s)
+{
+ unsigned char *p, *p0;
+
+ p = p0 = s;
+ while (*s)
+ {
+ if (*s == '%' && s[1] && s[2])
+ {
+ s++;
+ *p++ = xtoi_2 (s);
+ s += 2;
+ }
+ else
+ *p++ = *s++;
+ }
+ *p = 0;
+
+ return (p - p0);
+}
+
/* Return a malloced copy of the commandline for PID. If this is not
* possible NULL is returned. */
@@ -423,7 +305,6 @@ get_cmdline (unsigned long pid)
size_t i, n;
snprintf (buffer, sizeof buffer, "/proc/%lu/cmdline", pid);
- buffer[sizeof buffer - 1] = 0;
fp = fopen (buffer, "rb");
if (!fp)
@@ -469,7 +350,6 @@ get_pid_name_for_uid (unsigned long pid, int uid)
char *uidstr;
snprintf (buffer, sizeof buffer, "/proc/%lu/status", pid);
- buffer[sizeof buffer - 1] = 0;
fp = fopen (buffer, "rb");
if (!fp)
@@ -484,6 +364,7 @@ get_pid_name_for_uid (unsigned long pid, int uid)
fclose (fp);
if (n == 0)
return NULL;
+ buffer[n] = 0;
/* Fixme: Is it specified that "Name" is always the first line? For
* robustness I would prefer to have a real parser here. -wk */
if (strncmp (buffer, "Name:\t", 6))
@@ -503,6 +384,13 @@ get_pid_name_for_uid (unsigned long pid, int uid)
#endif /*!HAVE_W32_SYSTEM*/
+const char *
+pinentry_get_pgmname (void)
+{
+ return this_pgmname;
+}
+
+
/* Return a malloced string with the title. The caller mus free the
* string. If no title is available or the title string has an error
* NULL is returned. */
@@ -522,7 +410,7 @@ pinentry_get_title (pinentry_t pe)
char *cmdline = NULL;
if (pe->owner_host &&
- !uname (&utsbuf) && utsbuf.nodename &&
+ !uname (&utsbuf) &&
!strcmp (utsbuf.nodename, pe->owner_host))
{
pidname = get_pid_name_for_uid (pe->owner_pid, pe->owner_uid);
@@ -539,7 +427,6 @@ pinentry_get_title (pinentry_t pe)
else
snprintf (buf, sizeof buf, "[%lu] <unknown host>",
pe->owner_pid);
- buf[sizeof buf - 1] = 0;
free (pidname);
free (cmdline);
title = strdup (buf);
@@ -626,6 +513,71 @@ pinentry_inq_quality (pinentry_t pin, const char *passphrase, size_t length)
return value;
}
+
+/* Run a checkpin inquiry */
+char *
+pinentry_inq_checkpin (pinentry_t pin, const char *passphrase, size_t length)
+{
+ assuan_context_t ctx = pin->ctx_assuan;
+ const char prefix[] = "INQUIRE CHECKPIN ";
+ char *command;
+ char *line;
+ size_t linelen;
+ int gotvalue = 0;
+ char *value = NULL;
+ int rc;
+
+ if (!ctx)
+ return 0; /* Can't run the callback. */
+
+ if (length > 300)
+ length = 300; /* Limit so that it definitely fits into an Assuan
+ line. */
+
+ command = secmem_malloc (strlen (prefix) + 3*length + 1);
+ if (!command)
+ return 0;
+ strcpy (command, prefix);
+ copy_and_escape (command + strlen(command), passphrase, length);
+ rc = assuan_write_line (ctx, command);
+ secmem_free (command);
+ if (rc)
+ {
+ fprintf (stderr, "ASSUAN WRITE LINE failed: rc=%d\n", rc);
+ return 0;
+ }
+
+ for (;;)
+ {
+ do
+ {
+ rc = assuan_read_line (ctx, &line, &linelen);
+ if (rc)
+ {
+ fprintf (stderr, "ASSUAN READ LINE failed: rc=%d\n", rc);
+ return 0;
+ }
+ }
+ while (*line == '#' || !linelen);
+ if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
+ && (!line[3] || line[3] == ' '))
+ break; /* END command received*/
+ if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N'
+ && (!line[3] || line[3] == ' '))
+ break; /* CAN command received*/
+ if (line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
+ && (!line[3] || line[3] == ' '))
+ break; /* ERR command received*/
+ if (line[0] != 'D' || line[1] != ' ' || linelen < 3 || gotvalue)
+ continue;
+ gotvalue = 1;
+ value = strdup (line + 2);
+ }
+
+ return value;
+}
+
+
/* Run a genpin inquiry */
char *
pinentry_inq_genpin (pinentry_t pin)
@@ -656,6 +608,7 @@ pinentry_inq_genpin (pinentry_t pin)
if (rc)
{
fprintf (stderr, "ASSUAN READ LINE failed: rc=%d\n", rc);
+ free (value);
return 0;
}
}
@@ -871,7 +824,6 @@ my_strusage( int level )
{
snprintf (str, n, "Usage: %s [options] (-h for help)",
this_pgmname);
- str[n-1] = 0;
}
}
p = str;
@@ -1247,6 +1199,12 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
if (!pinentry.default_tt_hide)
return gpg_error_from_syserror ();
}
+ else if (!strcmp (key, "default-capshint"))
+ {
+ pinentry.default_capshint = strdup (value);
+ if (!pinentry.default_capshint)
+ return gpg_error_from_syserror ();
+ }
else if (!strcmp (key, "allow-external-password-cache") && !*value)
{
pinentry.allow_external_password_cache = 1;
@@ -1266,6 +1224,48 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
if (!pinentry.invisible_char)
return gpg_error_from_syserror ();
}
+ else if (!strcmp (key, "formatted-passphrase") && !*value)
+ {
+ pinentry.formatted_passphrase = 1;
+ }
+ else if (!strcmp (key, "formatted-passphrase-hint"))
+ {
+ if (pinentry.formatted_passphrase_hint)
+ free (pinentry.formatted_passphrase_hint);
+ pinentry.formatted_passphrase_hint = strdup (value);
+ if (!pinentry.formatted_passphrase_hint)
+ return gpg_error_from_syserror ();
+ do_unescape_inplace(pinentry.formatted_passphrase_hint);
+ }
+ else if (!strcmp (key, "constraints-enforce") && !*value)
+ pinentry.constraints_enforce = 1;
+ else if (!strcmp (key, "constraints-hint-short"))
+ {
+ if (pinentry.constraints_hint_short)
+ free (pinentry.constraints_hint_short);
+ pinentry.constraints_hint_short = strdup (value);
+ if (!pinentry.constraints_hint_short)
+ return gpg_error_from_syserror ();
+ do_unescape_inplace(pinentry.constraints_hint_short);
+ }
+ else if (!strcmp (key, "constraints-hint-long"))
+ {
+ if (pinentry.constraints_hint_long)
+ free (pinentry.constraints_hint_long);
+ pinentry.constraints_hint_long = strdup (value);
+ if (!pinentry.constraints_hint_long)
+ return gpg_error_from_syserror ();
+ do_unescape_inplace(pinentry.constraints_hint_long);
+ }
+ else if (!strcmp (key, "constraints-error-title"))
+ {
+ if (pinentry.constraints_error_title)
+ free (pinentry.constraints_error_title);
+ pinentry.constraints_error_title = strdup (value);
+ if (!pinentry.constraints_error_title)
+ return gpg_error_from_syserror ();
+ do_unescape_inplace(pinentry.constraints_error_title);
+ }
else
return gpg_error (GPG_ERR_UNKNOWN_OPTION);
return 0;
@@ -1309,7 +1309,6 @@ write_status_error (assuan_context_t ctx, pinentry_t pe)
pe->specific_err_loc? pe->specific_err_loc : "?",
pe->specific_err,
pe->specific_err_info? pe->specific_err_info : "");
- buf[sizeof buf -1] = 0;
assuan_write_status (ctx, "ERROR", buf);
}
@@ -1728,9 +1727,11 @@ cmd_getpin (assuan_context_t ctx, char *line)
{
if (pinentry.repeat_okay)
assuan_write_status (ctx, "PIN_REPEATED", "");
+ assuan_begin_confidential (ctx);
result = assuan_send_data (ctx, pinentry.pin, strlen(pinentry.pin));
if (!result)
result = assuan_send_data (ctx, NULL, 0);
+ assuan_end_confidential (ctx);
if (/* GPG Agent says it's okay. */
pinentry.allow_external_password_cache && pinentry.keyinfo
@@ -1866,7 +1867,6 @@ cmd_getinfo (assuan_context_t ctx, char *line)
{
snprintf (buffer, sizeof buffer, "%lu", (unsigned long)getpid ());
- buffer[sizeof buffer -1] = 0;
rc = assuan_send_data (ctx, buffer, strlen (buffer));
}
else if (!strcmp (line, "flavor"))
@@ -1880,7 +1880,6 @@ cmd_getinfo (assuan_context_t ctx, char *line)
s,
flavor_flag? ":":"",
flavor_flag? flavor_flag : "");
- buffer[sizeof buffer -1] = 0;
rc = assuan_send_data (ctx, buffer, strlen (buffer));
/* if (!rc) */
/* rc = assuan_write_status (ctx, "FEATURES", "tabbing foo bar"); */
@@ -1906,7 +1905,6 @@ cmd_getinfo (assuan_context_t ctx, char *line)
#endif
emacs_status
);
- buffer[sizeof buffer -1] = 0;
rc = assuan_send_data (ctx, buffer, strlen (buffer));
}
else
diff --git a/pinentry/pinentry.h b/pinentry/pinentry.h
index 4b51ddc..b97f069 100644
--- a/pinentry/pinentry.h
+++ b/pinentry/pinentry.h
@@ -1,5 +1,5 @@
/* pinentry.h - The interface for the PIN entry support library.
- * Copyright (C) 2002, 2003, 2010, 2015 g10 Code GmbH
+ * Copyright (C) 2002, 2003, 2010, 2015, 2021 g10 Code GmbH
*
* This file is part of PINENTRY.
*
@@ -170,20 +170,29 @@ struct pinentry
"SETQUALITYBAR LABEL".) */
char *quality_bar;
- /* The tooltip to be show for the qualitybar. Malloced or NULL.
+ /* The tooltip to be shown for the qualitybar. Malloced or NULL.
(Assuan: "SETQUALITYBAR_TT TOOLTIP".) */
char *quality_bar_tt;
/* If this is not NULL, a generate action should be shown.
There will be an inquiry back to the caller to get such a
PIN. generate action. Malloced or NULL.
- (Assuan: "GENPIN LABEL .) */
+ (Assuan: "SETGENPIN LABEL" .) */
char *genpin_label;
- /* The tooltip to be show for the generate action. Malloced or NULL.
- (Assuan: "GENPIN TOOLTIP".) */
+ /* The tooltip to be shown for the generate action. Malloced or NULL.
+ (Assuan: "SETGENPIN_TT TOOLTIP".) */
char *genpin_tt;
+ /* Specifies whether passphrase formatting should be enabled.
+ (Assuan: "OPTION formatted-passphrase") */
+ int formatted_passphrase;
+
+ /* A hint to be shown near the passphrase input field if passphrase
+ formatting is enabled. Malloced or NULL.
+ (Assuan: "OPTION formatted-passphrase-hint=HINT".) */
+ char *formatted_passphrase_hint;
+
/* For the curses pinentry, the color of error messages. */
pinentry_color_t color_fg;
int color_fg_bright;
@@ -212,6 +221,9 @@ struct pinentry
/* (Assuan: "OPTION default-tt-hide
Hide passphrase"). */
char *default_tt_hide;
+ /* (Assuan: "OPTION default-capshint
+ Caps Lock is on"). */
+ char *default_capshint;
/* Whether we are allowed to read the password from an external
cache. (Assuan: "OPTION allow-external-password-cache") */
@@ -239,6 +251,26 @@ struct pinentry
used. */
char *invisible_char;
+ /* Whether the passphrase constraints are enforced by gpg-agent.
+ (Assuan: "OPTION constraints-enforce") */
+ int constraints_enforce;
+
+ /* A short translated hint for the user with the constraints for new
+ passphrases to be displayed near the passphrase input field.
+ Malloced or NULL.
+ (Assuan: "OPTION constraints-hint-short=At least 8 characters".) */
+ char *constraints_hint_short;
+
+ /* A longer translated hint for the user with the constraints for new
+ passphrases to be displayed for example as tooltip. Malloced or NULL.
+ (Assuan: "OPTION constraints-hint-long=The passphrase must ...".) */
+ char *constraints_hint_long;
+
+ /* A short translated title for an error dialog informing the user about
+ unsatisfied passphrase constraints. Malloced or NULL.
+ (Assuan: "OPTION constraints-error-title=Passphrase Not Allowed".) */
+ char *constraints_error_title;
+
};
typedef struct pinentry *pinentry_t;
@@ -263,15 +295,7 @@ int pinentry_loop (void);
*/
int pinentry_loop2 (int infd, int outfd);
-
-/* Convert the UTF-8 encoded string TEXT to the encoding given in
- LC_CTYPE. Return NULL on error. */
-char *pinentry_utf8_to_local (const char *lc_ctype, const char *text);
-
-/* Convert TEXT which is encoded according to LC_CTYPE to UTF-8. With
- SECURE set to true, use secure memory for the returned buffer.
- Return NULL on error. */
-char *pinentry_local_to_utf8 (char *lc_ctype, char *text, int secure);
+const char *pinentry_get_pgmname (void);
char *pinentry_get_title (pinentry_t pe);
@@ -279,6 +303,12 @@ char *pinentry_get_title (pinentry_t pe);
int pinentry_inq_quality (pinentry_t pin,
const char *passphrase, size_t length);
+/* Run a checkpin inquiry for PASSPHRASE of LENGTH. Returns NULL, if the
+ passphrase satisfies the constraints. Otherwise, returns a malloced error
+ string. */
+char *pinentry_inq_checkpin (pinentry_t pin,
+ const char *passphrase, size_t length);
+
/* Run a genpin iquriry. Returns a malloced string or NULL */
char *pinentry_inq_genpin (pinentry_t pin);
diff --git a/pinentry/secmem.c b/pinentry/secmem.c
index 29c7ef9..2b03030 100644
--- a/pinentry/secmem.c
+++ b/pinentry/secmem.c
@@ -19,6 +19,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+/* #include <config.h> */
#include <stdio.h>
#include <stdlib.h>
#ifndef HAVE_W32CE_SYSTEM
@@ -30,9 +31,6 @@
# include <sys/mman.h>
# include <sys/types.h>
# include <fcntl.h>
-# ifdef USE_CAPABILITIES
-# include <sys/capability.h>
-# endif
#endif
#include <string.h>
@@ -50,7 +48,7 @@ typedef union {
short b;
char c[1];
long d;
-#ifdef HAVE_U64_TYPEDEF
+#ifdef HAVE_U64_TYPE
u64 e;
#endif
float f;
@@ -102,7 +100,9 @@ struct memblock_struct {
static void *pool;
static volatile int pool_okay; /* may be checked in an atexit function */
+#if HAVE_MMAP
static int pool_is_mmapped;
+#endif
static size_t poolsize; /* allocated length */
static size_t poollen; /* used length */
static MEMBLOCK *unused_blocks;
@@ -127,26 +127,7 @@ print_warn(void)
static void
lock_pool( void *p, size_t n )
{
-#if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
- int err;
-
- cap_set_proc( cap_from_text("cap_ipc_lock+ep") );
- err = mlock( p, n );
- if( err && errno )
- err = errno;
- cap_set_proc( cap_from_text("cap_ipc_lock+p") );
-
- if( err ) {
- if( errno != EPERM
- #ifdef EAGAIN /* OpenBSD returns this */
- && errno != EAGAIN
- #endif
- )
- log_error("can't lock memory: %s\n", strerror(err));
- show_warning = 1;
- }
-
-#elif defined(HAVE_MLOCK)
+#if defined(HAVE_MLOCK)
uid_t uid;
int err;
@@ -155,17 +136,13 @@ lock_pool( void *p, size_t n )
#ifdef HAVE_BROKEN_MLOCK
if( uid ) {
errno = EPERM;
- err = errno;
+ err = -1;
}
else {
err = mlock( p, n );
- if( err && errno )
- err = errno;
}
#else
err = mlock( p, n );
- if( err && errno )
- err = errno;
#endif
if( uid && !geteuid() ) {
@@ -179,11 +156,13 @@ lock_pool( void *p, size_t n )
&& errno != EAGAIN
#endif
)
- log_error("can't lock memory: %s\n", strerror(err));
+ log_error("can't lock memory: %s\n", strerror(errno));
show_warning = 1;
}
#else
+ (void)p;
+ (void)n;
log_info("Please note that you don't have secure memory on this system\n");
#endif
}
@@ -192,20 +171,22 @@ lock_pool( void *p, size_t n )
static void
init_pool( size_t n)
{
+#if HAVE_MMAP
size_t pgsize;
+#endif
poolsize = n;
if( disable_secmem )
log_bug("secure memory is disabled");
+#if HAVE_MMAP
#ifdef HAVE_GETPAGESIZE
pgsize = getpagesize();
#else
pgsize = 4096;
#endif
-#if HAVE_MMAP
poolsize = (poolsize + pgsize -1 ) & ~(pgsize-1);
# ifdef MAP_ANONYMOUS
pool = mmap( 0, poolsize, PROT_READ|PROT_WRITE,
@@ -283,11 +264,7 @@ void
secmem_init( size_t n )
{
if( !n ) {
-#ifdef USE_CAPABILITIES
- /* drop all capabilities */
- cap_set_proc( cap_from_text("all-eip") );
-
-#elif !defined(HAVE_DOSISH_SYSTEM)
+#if !defined(HAVE_DOSISH_SYSTEM)
uid_t uid;
disable_secmem=1;
diff --git a/pinentry/util.h b/pinentry/util.h
index 233ab13..3c8ffb8 100644
--- a/pinentry/util.h
+++ b/pinentry/util.h
@@ -22,21 +22,20 @@
#include <sys/types.h>
-#ifndef HAVE_BYTE_TYPEDEF
+#ifndef HAVE_TYPE_BYTE
# undef byte
-# ifdef __riscos__
- /* Norcroft treats char == unsigned char but char* != unsigned char* */
- typedef char byte;
-# else
- typedef unsigned char byte;
+# if !(defined(_WIN32) && defined(cbNDRContext))
+ /* Windows typedefs byte in the rpc headers. Avoid warning about
+ double definition. */
+ typedef unsigned char byte;
# endif
-# define HAVE_BYTE_TYPEDEF
+# define HAVE_TYPE_BYTE
#endif
-#ifndef HAVE_ULONG_TYPEDEF
+#ifndef HAVE_TYPE_ULONG
# undef ulong
typedef unsigned long ulong;
-# define HAVE_ULONG_TYPEDEF
+# define HAVE_TYPE_ULONG
#endif