summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--daemon/ldap.c49
2 files changed, 26 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 0c08cf1..1521b17 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
0.9 ???
- Allow 128 character long NTLM domains.
+ - Parse passwords from LDAP more circumspectly.
0.8 [06-07-2007]
- Support ignoring of HTTP method in digest. Useful for pass-through
diff --git a/daemon/ldap.c b/daemon/ldap.c
index 59e9912..a1aa1a1 100644
--- a/daemon/ldap.c
+++ b/daemon/ldap.c
@@ -206,53 +206,54 @@ static const char* make_password_sha(ha_buffer_t* buf, const char* clearpw)
return ha_bufenc64(buf, digest, SHA1_LEN);
}
-static int parse_ldap_password(const char** password)
+static int parse_ldap_password(const char* input, const char **result)
{
- const char* pw;
const char* scheme;
+ const char* password;
int i;
- ASSERT(password && *password);
-
- pw = *password;
+ ASSERT(input);
+ *result = input;
/* zero length passwords are clear */
- if(strlen(pw) == 0)
+ if(strlen(input) == 0)
return LDAP_PW_CLEAR;
/* passwords without a scheme are clear */
- if(pw[0] != '{')
+ if(input[0] != '{')
return LDAP_PW_CLEAR;
- pw++;
- scheme = pw;
+ password = input;
+ password++;
+ scheme = password;
- while(*pw && (isalpha(*pw) || isdigit(*pw) || *pw == '-'))
- pw++;
+ while(*password && (isalpha(*password) || isdigit(*password) || *password == '-'))
+ password++;
/* scheme should end in a brace */
- if(*pw != '}')
+ if(*password != '}')
return LDAP_PW_CLEAR;
- *password = pw + 1;
-
/* find a scheme in our map */
for(i = 0; i < countof(kLDAPPWTypes); i++)
{
- if(strncasecmp(kLDAPPWTypes[i].name, scheme, pw - scheme) == 0)
+ if(strncasecmp(kLDAPPWTypes[i].name, scheme, password - scheme) == 0) {
+ *result = password;
return kLDAPPWTypes[i].type;
+ }
}
- return LDAP_PW_UNKNOWN;
+ /* This covers a user using two braces in their password */
+ return LDAP_PW_CLEAR;
}
-static const char** find_cleartext_password(ha_buffer_t* buf, const char** pws)
+static const char** find_cleartext_password(ha_buffer_t* buf, const char** pws, const char **password)
{
ASSERT(buf);
for(; pws && *pws; pws++)
{
- if(parse_ldap_password(pws) == LDAP_PW_CLEAR)
+ if(parse_ldap_password(*pws, password) == LDAP_PW_CLEAR)
return pws;
}
@@ -325,8 +326,7 @@ static int validate_ldap_password(const ha_request_t* rq, ldap_context_t* ctx, L
{
for(t = pws ; *t; t++)
{
- pw = *t;
- type = parse_ldap_password(&pw);
+ type = parse_ldap_password(*t, &pw);
if(type != LDAP_PW_UNKNOWN)
foundany = 1;
@@ -643,6 +643,7 @@ static int validate_digest(ha_request_t* rq, const char* user, digest_context_t*
const char** pws = NULL; /* freed in finally */
int ret = HA_FALSE;
const char* dn = NULL;
+ const char* password;
int r;
int foundany = 0;
@@ -714,14 +715,14 @@ static int validate_digest(ha_request_t* rq, const char* user, digest_context_t*
if(pws && *pws)
{
- const char** p = pws;
+ const char** p = pws;
/* Find a cleartext password */
- while((p = find_cleartext_password(rq->buf, p)))
+ while((p = find_cleartext_password(rq->buf, p, &password)))
{
foundany = 1;
- digest_makeha1(dg->ha1, user, rq->context->realm, *p);
+ digest_makeha1(dg->ha1, user, rq->context->realm, password);
/* Run the actual check */
ret = digest_complete_check(dg, rq->context, rq->buf);
@@ -729,7 +730,7 @@ static int validate_digest(ha_request_t* rq, const char* user, digest_context_t*
if(ret != HA_FALSE)
RETURN(ret);
- p++;
+ p++;
}
}