-*- 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]
{
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"
" -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"
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
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:
case 'b':
ctx->passwd_src = PW_ARG;
break;
+ case 'i':
+ ctx->passwd_src = PW_STDIN;
+ break;
case 'm':
ctx->alg = ALG_APMD5;
break;
int cost;
enum {
PW_PROMPT = 0,
- PW_ARG
+ PW_ARG,
+ PW_STDIN
} passwd_src;
};