diff options
| -rw-r--r-- | ChangeLog | 1 | ||||
| -rw-r--r-- | daemon/ldap.c | 49 | 
2 files changed, 26 insertions, 24 deletions
@@ -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++;          }      }  | 
