]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Optionally read passwords from stdin
authorStefan Fritsch <sf@apache.org>
Sun, 7 Oct 2012 09:10:14 +0000 (09:10 +0000)
committerStefan Fritsch <sf@apache.org>
Sun, 7 Oct 2012 09:10:14 +0000 (09:10 +0000)
PR: 40243
Submitted by: Adomas Paltanavicius <adomas paltanavicius gmail com>, sf

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1395256 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
support/htdbm.c
support/htpasswd.c
support/passwd_common.c
support/passwd_common.h

diff --git a/CHANGES b/CHANGES
index 0460e1e4c015486b313bb092ab767467ea56d9f8..86bb45cf07bf9097941b9c653c3c50cc580e651e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) htpasswd, htdbm: Optionally read passwords from stdin, as more
+     secure alternative to -b.  PR 40243. [Adomas Paltanavicius <adomas
+     paltanavicius gmail com>, Stefan Fritsch]
+
   *) htpasswd, htdbm: Add support for bcrypt algorithm (requires
      apr-util 1.5 or higher). PR 49288. [Stefan Fritsch]
 
index c208b8428a872df4d8c35d8b04248cf000e3daa3..1ce57436d8ab5578570eca1c33ea84c438a2bb81 100644 (file)
@@ -276,11 +276,11 @@ static void htdbm_usage(void)
 {
     fprintf(stderr,
         "htdbm -- program for manipulating DBM password databases.\n\n"
-        "Usage: htdbm    [-cmBdpstvx] [-Ccost] [-TDBTYPE] database username\n"
+        "Usage: htdbm   [-cimBdpstvx] [-Ccost] [-TDBTYPE] database username\n"
         "                -b[cmBdptsv] [-Ccost] [-TDBTYPE] database username password\n"
-        "                -n[mBdpst]   [-Ccost] username\n"
+        "                -n[imBdpst]  [-Ccost] username\n"
         "                -nb[mBdpst]  [-Ccost] username password\n"
-        "                -v[mBdps]    [-Ccost] [-TDBTYPE] database username\n"
+        "                -v[imBdps]   [-Ccost] [-TDBTYPE] database username\n"
         "                -vb[mBdps]   [-Ccost] [-TDBTYPE] database username password\n"
         "                -x           [-Ccost] [-TDBTYPE] database username\n"
         "                -l           [-Ccost] [-TDBTYPE] database\n"
@@ -288,6 +288,7 @@ static void htdbm_usage(void)
         "   -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"
+        "   -i   Read password from stdin without verification (for script usage)\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"
index aed716a0fe38dde97253c84a8fbf7403d7c90915..9175a7bc4043bc40556fdd20e81127257db87bfa 100644 (file)
@@ -92,13 +92,14 @@ static int mkrecord(struct passwd_ctx *ctx, char *user)
 static void usage(void)
 {
     apr_file_printf(errfile, "Usage:" NL
-        "\thtpasswd [-cmBdpsD]  [-C cost] passwordfile username" NL
+        "\thtpasswd [-cimBdpsD] [-C cost] passwordfile username" NL
         "\thtpasswd -b[cmBdpsD] [-C cost] passwordfile username password" NL
         NL
-        "\thtpasswd -n[mBdps]  [-C cost] username" NL
+        "\thtpasswd -n[imBdps] [-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
+        " -i  Read password from stdin without verification (for script usage)" 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
index 2a5b2d8695a09f859959799a1f44b8f05dfa63e0..d1b10d194b593db05b7d74251f4da4fa48aa0ac6 100644 (file)
@@ -95,18 +95,41 @@ void putline(apr_file_t *f, const char *l)
 
 int get_password(struct passwd_ctx *ctx)
 {
-    char buf[MAX_STRING_LEN + 1];
-    apr_size_t bufsize = sizeof(buf);
-    if (apr_password_get("New password: ", ctx->out, &ctx->out_len) != 0)
-        goto err_too_long;
-    apr_password_get("Re-type new password: ", buf, &bufsize);
-    if (strcmp(ctx->out, buf) != 0) {
-        ctx->errstr = "password verification error";
-        memset(ctx->out, '\0', ctx->out_len);
+    if (ctx->passwd_src == PW_STDIN) {
+        char *buf = ctx->out;
+        apr_file_t *file_stdin;
+        apr_size_t nread;
+        if (apr_file_open_stdin(&file_stdin, ctx->pool) != APR_SUCCESS) {
+            ctx->errstr = "Unable to read from stdin.";
+            return ERR_GENERAL;
+        }
+        if (apr_file_read_full(file_stdin, buf, ctx->out_len - 1,
+                               &nread) != APR_EOF
+            || nread == ctx->out_len - 1) {
+            goto err_too_long;
+        }
+        buf[nread] = '\0';
+        if (nread >= 1 && buf[nread-1] == '\n') {
+            buf[nread-1] = '\0';
+            if (nread >= 2 && buf[nread-2] == '\r')
+                buf[nread-2] = '\0';
+        }
+        apr_file_close(file_stdin);
+    }
+    else {
+        char buf[MAX_STRING_LEN + 1];
+        apr_size_t bufsize = sizeof(buf);
+        if (apr_password_get("New password: ", ctx->out, &ctx->out_len) != 0)
+            goto err_too_long;
+        apr_password_get("Re-type new password: ", buf, &bufsize);
+        if (strcmp(ctx->out, buf) != 0) {
+            ctx->errstr = "password verification error";
+            memset(ctx->out, '\0', ctx->out_len);
+            memset(buf, '\0', sizeof(buf));
+            return ERR_PWMISMATCH;
+        }
         memset(buf, '\0', sizeof(buf));
-        return ERR_PWMISMATCH;
     }
-    memset(buf, '\0', sizeof(buf));
     return 0;
 
 err_too_long:
@@ -234,6 +257,9 @@ int parse_common_options(struct passwd_ctx *ctx, char opt,
     case 'b':
         ctx->passwd_src = PW_ARG;
         break;
+    case 'i':
+        ctx->passwd_src = PW_STDIN;
+        break;
     case 'm':
         ctx->alg = ALG_APMD5;
         break;
index 6fc5b712cd45586c7dd281585ef631f452cad61f..67b66da161417b7abe14b72ba17b27f18b98fc08 100644 (file)
@@ -79,7 +79,8 @@ struct passwd_ctx {
     int             cost;
     enum {
         PW_PROMPT = 0,
-        PW_ARG
+        PW_ARG,
+        PW_STDIN
     } passwd_src;
 };