coar 99/04/08 15:17:56
Modified: src CHANGES src/support htpasswd.1 htpasswd.c Log: Allow (though discouraged) htpasswd to get the password from the command line. People who wanted this in the past probably just modified htpasswd.c to do it; that's a lot more difficult in the Win32 environment. Revision Changes Path 1.1302 +5 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.1301 retrieving revision 1.1302 diff -u -r1.1301 -r1.1302 --- CHANGES 1999/04/08 21:04:41 1.1301 +++ CHANGES 1999/04/08 22:17:45 1.1302 @@ -1,4 +1,9 @@ Changes with Apache 1.3.7 + *) support/htpasswd now permits the password to be specified on the + command line with the '-b' switch. This is useful when passwords + need to be maintained by scripts -- particularly in the Win32 + environment. [Ken Coar] + *) Win32: Win32 multiple services patch. Added capability to install and run multiple copies of apache as individual services. 1.9 +42 -3 apache-1.3/src/support/htpasswd.1 Index: htpasswd.1 =================================================================== RCS file: /home/cvs/apache-1.3/src/support/htpasswd.1,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- htpasswd.1 1999/01/25 22:55:40 1.8 +++ htpasswd.1 1999/04/08 22:17:51 1.9 @@ -59,12 +59,33 @@ [ .B \-c ] +[ +.B \-m +] .I passwdfile .I username +.br +.B htpasswd +.B \-b +[ +.B \-c +] +[ +.B \-m +] +.I passwdfile +.I username +.I password .SH DESCRIPTION .B htpasswd is used to create and update the flat-files used to store usernames and password for basic authentication of HTTP users. +If +.B htpasswd +cannot access a file, such as not being able to write to the output +file or not being able to read the file in order to update it, +it returns an error status and makes no changes. +.PP Resources available from the .B httpd Apache web server can be restricted to just the users listed @@ -82,20 +103,38 @@ the Apache manual, which is part of the Apache distribution or can be found at http://www.apache.org/. .SH OPTIONS +.IP \-b +Use batch mode; \fIi.e.\fP, get the password from the command line +rather than prompting for it. \fBThis option should be used with +extreme care, since the password is clearly visible on the command +line.\fP .IP \-c Create the \fIpasswdfile\fP. If \fIpasswdfile\fP already exists, it -is deleted first. +is rewritten and truncated. .IP \-m Use MD5 encryption for passwords. On Windows, this is the only format supported. .IP \fB\fIpasswdfile\fP Name of the file to contain the user name and password. If \-c is given, this file is created if it does not already exist, -or deleted and recreated if it does exist. +or rewritten and truncated if it does exist. .IP \fB\fIusername\fP The username to create or update in \fBpasswdfile\fP. If -\fIusername\fP does not exist is this file, an entry is added. If it +\fIusername\fP does not exist in this file, an entry is added. If it does exist, the password is changed. +.IP \fB\fIpassword\fP +The plaintext password to be encrypted and stored in the file. Only used +with the \fI-b\fP flag. +.SH EXIT STATUS +.B htpasswd +returns a zero status ("true") if the username and password have +been successfully added or updated in the \fIpasswdfile\fP. +.B htpasswd +returns 1 if it encounters some problem accessing files, 2 if there +was a syntax problem with the command line, 3 if the password was +entered interactively and the verification entry didn't match, 4 if +its operation was interrupted, and 5 if a value is too long (username, +filename, password, or final computed record). .SH SEE ALSO .BR httpd(8) . 1.26 +44 -13 apache-1.3/src/support/htpasswd.c Index: htpasswd.c =================================================================== RCS file: /home/cvs/apache-1.3/src/support/htpasswd.c,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- htpasswd.c 1999/04/08 20:56:44 1.25 +++ htpasswd.c 1999/04/08 22:17:53 1.26 @@ -230,17 +230,23 @@ * indicates success; failure means that the output buffer contains an * error message instead. */ -static int mkrecord(char *user, char *record, size_t rlen, int alg) +static int mkrecord(char *user, char *record, size_t rlen, char *passwd, + int alg) { char *pw; char cpw[120]; char salt[9]; - pw = strd((char *) getpass("New password: ")); - if (strcmp(pw, (char *) getpass("Re-type new password: "))) { - ap_cpystrn(record, "password verification error", (rlen - 1)); - return ERR_PWMISMATCH; + if (passwd != NULL) { + pw = passwd; } + else { + pw = strd((char *) getpass("New password: ")); + if (strcmp(pw, (char *) getpass("Re-type new password: "))) { + ap_cpystrn(record, "password verification error", (rlen - 1)); + return ERR_PWMISMATCH; + } + } (void) srand((int) time((time_t *) NULL)); to64(&salt[0], rand(), 8); salt[8] = '\0'; @@ -254,11 +260,14 @@ ap_cpystrn(cpw, (char *)crypt(pw, salt), sizeof(cpw) - 1); break; } + fprintf(stderr, "Yow!\n"); /* * Now that we have the smashed password, we don't need the * plaintext one any more. */ - free(pw); + if (passwd == NULL) { + free(pw); + } /* * Check to see if the buffer is large enough to hold the username, * hash, and delimiters. @@ -275,9 +284,13 @@ static int usage(void) { - fprintf(stderr, "Usage: htpasswd [-cm] passwordfile username\n"); - fprintf(stderr, "The -c flag creates a new file.\n"); - fprintf(stderr, "The -m flag forces MD5 encryption of the password.\n"); + fprintf(stderr, "Usage:\n"); + fprintf(stderr, "\thtpasswd [-cm] passwordfile username\n"); + fprintf(stderr, "\thtpasswd -b[cm] passwordfile username password\n\n"); + fprintf(stderr, " -c Create a new file.\n"); + fprintf(stderr, " -m Force MD5 encryption of the password.\n"); + fprintf(stderr, " -b Use the password from the command line rather "); + fprintf(stderr, "than prompting for it.\n"); fprintf(stderr, "On Windows systems the -m flag is used by default.\n"); return ERR_SYNTAX; } @@ -365,6 +378,7 @@ FILE *ftemp = NULL; FILE *fpw = NULL; char user[MAX_STRING_LEN]; + char password[MAX_STRING_LEN]; char record[MAX_STRING_LEN]; char line[MAX_STRING_LEN]; char pwfilename[MAX_STRING_LEN]; @@ -372,7 +386,9 @@ int found = 0; int alg = ALG_CRYPT; int newfile = 0; + int noninteractive = 0; int i; + int args_left = 2; tempfilename = NULL; signal(SIGINT, (void (*)(int)) interrupted); @@ -402,6 +418,10 @@ else if (*arg == 'm') { alg = ALG_APMD5; } + else if (*arg == 'b') { + noninteractive++; + args_left++; + } else { return usage(); } @@ -409,10 +429,11 @@ } /* - * Make sure we still have exactly two arguments left (the filename - * and the username). + * Make sure we still have exactly the right number of arguments left + # (the filename, the username, and possibly the password if -b was + # specified). */ - if ((argc - i) != 2) { + if ((argc - i) != args_left) { return usage(); } if (strlen(argv[i]) > (sizeof(pwfilename) - 1)) { @@ -425,6 +446,13 @@ return ERR_OVERFLOW; } strcpy(user, argv[i + 1]); + if (noninteractive) { + if (strlen(argv[i + 2]) > (sizeof(password) - 1)) { + fprintf(stderr, "%s: password too long\n", argv[0]); + return ERR_OVERFLOW; + } + strcpy(password, argv[i + 2]); + } #ifdef WIN32 if (alg == ALG_CRYPT) { @@ -481,7 +509,10 @@ * Any error message text is returned in the record buffer, since * the mkrecord() routine doesn't have access to argv[]. */ - if ((i = mkrecord(user, record, sizeof(record) - 1, alg)) != 0) { + i = mkrecord(user, record, sizeof(record) - 1, + noninteractive ? password : NULL, + alg); + if (i != 0) { fprintf(stderr, "%s: %s\n", argv[0], record); exit(i); }