[PATCH 1/2] agent: Defer passphrase quality check to external tool.

Damien Goutte-Gattat dgouttegattat at incenp.org
Sat Dec 30 11:19:24 CET 2017


* agent/call-pinentry.c (estimate_passphrase_quality): Call external
program to evaluate passphrase if requested.
* agent/agent.h (struct opt): New field passphrase_quality_checker.
* agent/gpg-agent.c (oPassphraseChecker): New const.
(opts): New option --passphrase-checker.
(parse_rereadable_options): Handle the new option.
* doc/gpg-agent.texi: Document the new option.
--

GnuPG-bug-id: 2103
Signed-off-by: Damien Goutte-Gattat <dgouttegattat at incenp.org>
---
 agent/agent.h         |  3 +++
 agent/call-pinentry.c | 21 +++++++++++++++++++++
 agent/gpg-agent.c     |  6 ++++++
 doc/gpg-agent.texi    |  7 +++++++
 4 files changed, 37 insertions(+)

diff --git a/agent/agent.h b/agent/agent.h
index 687635dc7..b1c649e1a 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -116,6 +116,9 @@ struct
   /* File name with a patternfile or NULL if not enabled.  */
   const char *check_passphrase_pattern;
 
+  /* Path to a external passphrase checker (NULL to disable). */
+  const char *passphrase_quality_checker;
+
   /* If not 0 the user is asked to change his passphrase after these
      number of days.  */
   unsigned int max_passphrase_days;
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index af4eb06f2..1d971db6f 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -39,6 +39,7 @@
 #include <assuan.h>
 #include "../common/sysutils.h"
 #include "../common/i18n.h"
+#include "../common/exectool.h"
 
 #ifdef _POSIX_OPEN_MAX
 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
@@ -785,6 +786,26 @@ estimate_passphrase_quality (const char *pw)
   int length;
   const char *s;
 
+  if (opt.passphrase_quality_checker)
+    {
+      char *output;
+      long percent;
+
+      if (gnupg_exec_tool (opt.passphrase_quality_checker, NULL,
+                           pw, &output, NULL))
+        return 0;
+
+      percent = strtol (output, NULL, 10);
+      if (percent < 0)
+        percent = 0;
+      if (percent > 100)
+        percent = 100;
+
+      xfree (output);
+
+      return percent;
+    }
+
   if (goodlength < 1)
     return 0;
 
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index a1964ece8..7e9a03310 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -110,6 +110,7 @@ enum cmd_and_opt_values
   oMinPassphraseLen,
   oMinPassphraseNonalpha,
   oCheckPassphrasePattern,
+  oPassphraseChecker,
   oMaxPassphraseDays,
   oEnablePassphraseHistory,
   oEnableExtendedKeyFormat,
@@ -224,6 +225,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oCheckPassphrasePattern,  "check-passphrase-pattern", "@"),
   ARGPARSE_s_u (oMaxPassphraseDays,       "max-passphrase-days", "@"),
   ARGPARSE_s_n (oEnablePassphraseHistory, "enable-passphrase-history", "@"),
+  ARGPARSE_s_s (oPassphraseChecker,       "passphrase-checker", "@"),
 
   ARGPARSE_s_n (oIgnoreCacheForSigning, "ignore-cache-for-signing",
                 /* */    N_("do not use the PIN cache when signing")),
@@ -821,6 +823,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
       opt.min_passphrase_len = MIN_PASSPHRASE_LEN;
       opt.min_passphrase_nonalpha = MIN_PASSPHRASE_NONALPHA;
       opt.check_passphrase_pattern = NULL;
+      opt.passphrase_quality_checker = NULL;
       opt.max_passphrase_days = MAX_PASSPHRASE_DAYS;
       opt.enable_passphrase_history = 0;
       opt.enable_extended_key_format = 0;
@@ -890,6 +893,9 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
     case oCheckPassphrasePattern:
       opt.check_passphrase_pattern = pargs->r.ret_str;
       break;
+    case oPassphraseChecker:
+      opt.passphrase_quality_checker = pargs->r.ret_str;
+      break;
     case oMaxPassphraseDays:
       opt.max_passphrase_days = pargs->r.ret_ulong;
       break;
diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
index 3e8bd894d..1a72836aa 100644
--- a/doc/gpg-agent.texi
+++ b/doc/gpg-agent.texi
@@ -458,6 +458,13 @@ a policy.  A better policy is to educate users on good security
 behavior and optionally to run a passphrase cracker regularly on all
 users passphrases to catch the very simple ones.
 
+ at item --passphrase-checker @var{filename}
+ at opindex passphrase-checker
+Call program @var{filename} to estimate the quality of a new passphrase.
+The program is expected to read the passphrase to check on its standard
+input and should print the estimated quality as an integer value between
+0 and 100. The default is not to call any such program.
+
 @item --max-passphrase-days @var{n}
 @opindex max-passphrase-days
 Ask the user to change the passphrase if @var{n} days have passed since
-- 
2.14.1




More information about the Gnupg-devel mailing list