+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
/*
* AUTHOR: Arjan de Vet <Arjan.deVet@adv.iae.nl>
*
* - extra fields in the password file are ignored; this makes it
* possible to use a Unix password file but I do not recommend that.
*
+ * MD5 without salt and magic strings - Added by Ramon de Carvalho and Rodrigo Rubira Branco
*/
-#include "config.h"
+#include "squid.h"
#include "crypt_md5.h"
#include "hash.h"
#include "helpers/defines.h"
#include "rfc1738.h"
#include "util.h"
-#if HAVE_STDIO_H
-#include <stdio.h>
-#endif
+#include <cerrno>
+#include <cstring>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
-#if HAVE_STRING_H
-#include <string.h>
-#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
read_passwd_file(const char *passwdfile)
{
FILE *f;
- char buf[8192];
+ char buf[HELPER_INPUT_BUFFER];
user_data *u;
char *user;
char *passwd;
fprintf(stderr, "FATAL: %s: %s\n", passwdfile, xstrerror());
exit(1);
}
- while (fgets(buf, 8192, f) != NULL) {
+ unsigned int lineCount = 0;
+ buf[HELPER_INPUT_BUFFER-1] = '\0';
+ while (fgets(buf, sizeof(buf)-1, f) != NULL) {
+ ++lineCount;
if ((buf[0] == '#') || (buf[0] == ' ') || (buf[0] == '\t') ||
(buf[0] == '\n'))
continue;
user = strtok(buf, ":\n\r");
+ if (user == NULL) {
+ fprintf(stderr, "ERROR: Missing user name at %s line %d\n", passwdfile, lineCount);
+ continue;
+ }
passwd = strtok(NULL, ":\n\r");
if ((strlen(user) > 0) && passwd) {
u = static_cast<user_data*>(xmalloc(sizeof(*u)));
}
while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != NULL) {
if ((p = strchr(buf, '\n')) != NULL)
- *p = '\0'; /* strip \n */
+ *p = '\0'; /* strip \n */
if (stat(argv[1], &sb) == 0) {
if (sb.st_mtime != change_time) {
read_passwd_file(argv[1]);
u = (user_data *) hash_lookup(hash, user);
if (u == NULL) {
SEND_ERR("No such user");
+ continue;
+ }
+ char *crypted = NULL;
#if HAVE_CRYPT
- } else if (strcmp(u->passwd, (char *) crypt(passwd, u->passwd)) == 0) {
+ size_t passwordLength = strlen(passwd);
+ // Bug 3831: given algorithms more secure than DES crypt() does not truncate, so we can ignore the bug 3107 length checks below
+ // '$1$' = MD5, '$2a$' = Blowfish, '$5$' = SHA256 (Linux), '$6$' = SHA256 (BSD) and SHA512
+ if (passwordLength > 1 && u->passwd[0] == '$' &&
+ (crypted = crypt(passwd, u->passwd)) && strcmp(u->passwd, crypted) == 0) {
SEND_OK("");
+ continue;
+ }
+ // 'other' prefixes indicate DES algorithm.
+ if (passwordLength <= 8 && (crypted = crypt(passwd, u->passwd)) && (strcmp(u->passwd, crypted) == 0)) {
+ SEND_OK("");
+ continue;
+ }
+ if (passwordLength > 8 && (crypted = crypt(passwd, u->passwd)) && (strcmp(u->passwd, crypted) == 0)) {
+ // Bug 3107: crypt() DES functionality silently truncates long passwords.
+ SEND_ERR("Password too long. Only 8 characters accepted.");
+ continue;
+ }
+
#endif
- } else if (strcmp(u->passwd, (char *) crypt_md5(passwd, u->passwd)) == 0) {
+ if ( (crypted = crypt_md5(passwd, u->passwd)) && strcmp(u->passwd, crypted) == 0) {
SEND_OK("");
- } else if (strcmp(u->passwd, (char *) md5sum(passwd)) == 0) { /* md5 without salt and magic strings - Added by Ramon de Carvalho and Rodrigo Rubira Branco */
+ continue;
+ }
+ if ( (crypted = md5sum(passwd)) && strcmp(u->passwd, crypted) == 0) {
SEND_OK("");
- } else {
- SEND_ERR("Wrong password");
+ continue;
}
+ SEND_ERR("Wrong password");
}
if (hash != NULL) {
hashFreeItems(hash, my_free);
}
exit(0);
}
+