You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by sf...@apache.org on 2012/10/07 11:06:10 UTC

svn commit: r1395255 - in /httpd/httpd/trunk: CHANGES support/htdbm.c support/htpasswd.c support/passwd_common.c support/passwd_common.h

Author: sf
Date: Sun Oct  7 09:06:10 2012
New Revision: 1395255

URL: http://svn.apache.org/viewvc?rev=1395255&view=rev
Log:
add support for bcrypt

PR: 49288

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/support/htdbm.c
    httpd/httpd/trunk/support/htpasswd.c
    httpd/httpd/trunk/support/passwd_common.c
    httpd/httpd/trunk/support/passwd_common.h

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1395255&r1=1395254&r2=1395255&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sun Oct  7 09:06:10 2012
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) htpasswd, htdbm: Add support for bcrypt algorithm (requires
+     apr-util 1.5 or higher). PR 49288. [Stefan Fritsch]
+
   *) htpasswd, htdbm: Put full 48bit of entropy into salt, improve
      error handling. Add some of htpasswd's improvements to htdbm,
      e.g. warn if password is truncated by crypt(). [Stefan Fritsch]

Modified: httpd/httpd/trunk/support/htdbm.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/support/htdbm.c?rev=1395255&r1=1395254&r2=1395255&view=diff
==============================================================================
--- httpd/httpd/trunk/support/htdbm.c (original)
+++ httpd/httpd/trunk/support/htdbm.c Sun Oct  7 09:06:10 2012
@@ -276,29 +276,33 @@ static void htdbm_usage(void)
 {
     fprintf(stderr,
         "htdbm -- program for manipulating DBM password databases.\n\n"
-        "Usage: htdbm    [-cmdpstvx] [-TDBTYPE] database username\n"
-        "                -b[cmdptsv] [-TDBTYPE] database username password\n"
-        "                -n[mdpst]   username\n"
-        "                -nb[mdpst]  username password\n"
-        "                -v[mdps]    [-TDBTYPE] database username\n"
-        "                -vb[mdps]   [-TDBTYPE] database username password\n"
-        "                -x          [-TDBTYPE] database username\n"
-        "                -l          [-TDBTYPE] database\n"
+        "Usage: htdbm    [-cmBdpstvx] [-Ccost] [-TDBTYPE] database username\n"
+        "                -b[cmBdptsv] [-Ccost] [-TDBTYPE] database username password\n"
+        "                -n[mBdpst]   [-Ccost] username\n"
+        "                -nb[mBdpst]  [-Ccost] username password\n"
+        "                -v[mBdps]    [-Ccost] [-TDBTYPE] database username\n"
+        "                -vb[mBdps]   [-Ccost] [-TDBTYPE] database username password\n"
+        "                -x           [-Ccost] [-TDBTYPE] database username\n"
+        "                -l           [-Ccost] [-TDBTYPE] database\n"
         "Options:\n"
         "   -b   Use the password from the command line rather than prompting for it.\n"
         "   -c   Create a new database.\n"
         "   -n   Don't update database; display results on stdout.\n"
         "   -m   Force MD5 encryption of the password (default).\n"
+        "   -B   Force BCRYPT encryption of the password (very secure).\n"
         "   -d   Force CRYPT encryption of the password (8 chars max, insecure).\n"
         "   -p   Do not encrypt the password (plaintext).\n"
         "   -s   Force SHA encryption of the password (insecure).\n"
+        "   -C   Set the computing time used for the bcrypt algorithm.\n"
+        "        (higher is more secure but slower, default: %d, valid: 4 to 31)\n"
         "   -T   DBM Type (SDBM|GDBM|DB|default).\n"
         "   -l   Display usernames from database on stdout.\n"
         "   -t   The last param is username comment.\n"
         "   -v   Verify the username/password.\n"
         "   -x   Remove the username record from database.\n"
         "The SHA algorithm does not use a salt and is less secure than the "
-        "MD5 algorithm.\n");
+        "MD5 algorithm.\n",
+        BCRYPT_DEFAULT_COST);
     exit(ERR_SYNTAX);
 }
 

Modified: httpd/httpd/trunk/support/htpasswd.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/support/htpasswd.c?rev=1395255&r1=1395254&r2=1395255&view=diff
==============================================================================
--- httpd/httpd/trunk/support/htpasswd.c (original)
+++ httpd/httpd/trunk/support/htpasswd.c Sun Oct  7 09:06:10 2012
@@ -92,14 +92,17 @@ static int mkrecord(struct passwd_ctx *c
 static void usage(void)
 {
     apr_file_printf(errfile, "Usage:" NL
-        "\thtpasswd [-cmdpsD] passwordfile username" NL
-        "\thtpasswd -b[cmdpsD] passwordfile username password" NL
+        "\thtpasswd [-cmBdpsD]  [-C cost] passwordfile username" NL
+        "\thtpasswd -b[cmBdpsD] [-C cost] passwordfile username password" NL
         NL
-        "\thtpasswd -n[mdps] username" NL
-        "\thtpasswd -nb[mdps] username password" NL
+        "\thtpasswd -n[mBdps]  [-C cost] username" NL
+        "\thtpasswd -nb[mBdps] [-C cost] username password" NL
         " -c  Create a new file." NL
         " -n  Don't update file; display results on stdout." NL
         " -m  Force MD5 encryption of the password (default)." NL
+        " -B  Force bcrypt encryption of the password (very secure)." NL
+        " -C  Set the computing time used for the bcrypt algorithm" NL
+        "     (higher is more secure but slower, default: %d, valid: 4 to 31)" NL
         " -d  Force CRYPT encryption of the password (8 chars max, "
             "insecure)." NL
         " -p  Do not encrypt the password (plaintext, insecure)." NL
@@ -110,7 +113,8 @@ static void usage(void)
         "On other systems than Windows and NetWare the '-p' flag will "
             "probably not work." NL
         "The SHA algorithm does not use a salt and is less secure than the "
-            "MD5 algorithm." NL
+            "MD5 algorithm." NL,
+        BCRYPT_DEFAULT_COST
     );
     exit(ERR_SYNTAX);
 }

Modified: httpd/httpd/trunk/support/passwd_common.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/support/passwd_common.c?rev=1395255&r1=1395254&r2=1395255&view=diff
==============================================================================
--- httpd/httpd/trunk/support/passwd_common.c (original)
+++ httpd/httpd/trunk/support/passwd_common.c Sun Oct  7 09:06:10 2012
@@ -131,6 +131,11 @@ int mkhash(struct passwd_ctx *ctx)
     char *cbuf;
 #endif
 
+    if (ctx->cost != 0 && ctx->alg != ALG_BCRYPT) {
+        apr_file_printf(errfile,
+                        "Warning: Ignoring -C argument for this algorithm." NL);
+    }
+
     if (ctx->passwd != NULL) {
         pw = ctx->passwd;
     }
@@ -189,6 +194,30 @@ int mkhash(struct passwd_ctx *ctx)
         }
         break;
 #endif /* CRYPT_ALGO_SUPPORTED */
+
+#if BCRYPT_ALGO_SUPPORTED
+    case ALG_BCRYPT:
+        rv = apr_generate_random_bytes((unsigned char*)salt, 16);
+        if (rv != APR_SUCCESS) {
+            ctx->errstr = apr_psprintf(ctx->pool, "Unable to generate random "
+                                       "bytes: %pm", &rv);
+            ret = ERR_RANDOM;
+            break;
+        }
+
+        if (ctx->cost == 0)
+            ctx->cost = BCRYPT_DEFAULT_COST;
+        rv = apr_bcrypt_encode(pw, ctx->cost, (unsigned char*)salt, 16,
+                               ctx->out, ctx->out_len);
+        if (rv != APR_SUCCESS) {
+            ctx->errstr = apr_psprintf(ctx->pool, "Unable to encode with "
+                                       "bcrypt: %pm", &rv);
+            ret = ERR_PWMISMATCH;
+            break;
+        }
+        break;
+#endif /* BCRYPT_ALGO_SUPPORTED */
+
     default:
         apr_file_printf(errfile, "%s: BUG: invalid algorithm %d", __func__,
                         ctx->alg);
@@ -232,6 +261,25 @@ int parse_common_options(struct passwd_c
         ctx->alg = ALG_APMD5;
 #endif
         break;
+    case 'B':
+#if BCRYPT_ALGO_SUPPORTED
+        ctx->alg = ALG_BCRYPT;
+#else
+        /* Don't fall back to something less secure */
+        ctx->errstr = "BCRYPT algorithm not supported on this platform";
+        return ERR_ALG_NOT_SUPP;
+#endif
+        break;
+    case 'C': {
+            char *endptr;
+            long num = strtol(opt_arg, &endptr, 10);
+            if (*endptr != '\0' || num <= 0) {
+                ctx->errstr = "argument to -C must be a positive integer";
+                return ERR_SYNTAX;
+            }
+            ctx->cost = num;
+            break;
+        }
     default:
         apr_file_printf(errfile, "%s: BUG: invalid option %c", __func__, opt);
         abort();

Modified: httpd/httpd/trunk/support/passwd_common.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/support/passwd_common.h?rev=1395255&r1=1395254&r2=1395255&view=diff
==============================================================================
--- httpd/httpd/trunk/support/passwd_common.h (original)
+++ httpd/httpd/trunk/support/passwd_common.h Sun Oct  7 09:06:10 2012
@@ -21,6 +21,9 @@
 #include "apr_file_io.h"
 #include "apr_general.h"
 #include "apr_version.h"
+#if !APR_VERSION_AT_LEAST(2,0,0)
+#include "apu_version.h"
+#endif
 
 #define MAX_STRING_LEN 256
 
@@ -28,6 +31,9 @@
 #define ALG_CRYPT 1
 #define ALG_APMD5 2
 #define ALG_APSHA 3
+#define ALG_BCRYPT 4
+
+#define BCRYPT_DEFAULT_COST 5
 
 #define ERR_FILEPERM 1
 #define ERR_SYNTAX 2
@@ -50,6 +56,13 @@
 #define PLAIN_ALGO_SUPPORTED 0
 #endif
 
+#if APR_VERSION_AT_LEAST(2,0,0) || \
+    (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 5)
+#define BCRYPT_ALGO_SUPPORTED 1
+#else
+#define BCRYPT_ALGO_SUPPORTED 0
+#endif
+
 /*
  * Must be initialized with apr_file_open_stderr() before using any of the
  * below functions.
@@ -63,6 +76,7 @@ struct passwd_ctx {
     apr_size_t      out_len;
     char            *passwd;
     int             alg;
+    int             cost;
     enum {
         PW_PROMPT = 0,
         PW_ARG