Re: svn commit: r1591012 - in /httpd/httpd/trunk: CHANGES docs/log-message-tags/next-number modules/aaa/mod_authnz_ldap.c

2023-11-18 Thread Graham Leggett via dev
On 18 Nov 2023, at 17:14, Yann Ylavic  wrote:

> Oh it seems that the callers want the "filtbuf" to be \0 terminated
> (even in case of error), so this v2 probably..

Looking at this now.

Seems to be some differences between trunk and v2.4, seeing how they can be 
aligned to make this easier.

Regards,
Graham
—



Re: svn commit: r1591012 - in /httpd/httpd/trunk: CHANGES docs/log-message-tags/next-number modules/aaa/mod_authnz_ldap.c

2023-11-18 Thread Yann Ylavic
On Sat, Nov 18, 2023 at 5:59 PM Yann Ylavic  wrote:
>
> All in all, I'd rewrite this function like in the attached patch (not
> even compile tested, just to show what I'm talking about..).

Oh it seems that the callers want the "filtbuf" to be \0 terminated
(even in case of error), so this v2 probably..

>
> Regards;
> Yann.
Index: modules/aaa/mod_authnz_ldap.c
===
--- modules/aaa/mod_authnz_ldap.c	(revision 1913813)
+++ modules/aaa/mod_authnz_ldap.c	(working copy)
@@ -206,7 +206,7 @@ static const char* authn_ldap_xlate_password(reque
  * search filter will be (&(posixid=*)(uid=userj)).
  */
 #define FILTER_LENGTH MAX_STRING_LEN
-static apr_status_t authn_ldap_build_filter(char *filtbuf,
+static apr_status_t authn_ldap_build_filter(char filtbuf[FILTER_LENGTH],
  request_rec *r,
  const char *user,
  const char *filter,
@@ -219,6 +219,7 @@ static const char* authn_ldap_xlate_password(reque
 apr_size_t outbytes;
 char *outbuf;
 int nofilter = 0, len;
+apr_statut rv = APR_SUCCESS;
 
 if (!filter) {
 filter = sec->filter;
@@ -244,7 +245,7 @@ static const char* authn_ldap_xlate_password(reque
  * config-supplied portions.
  */
 
-if ((nofilter = (filter && !strcasecmp(filter, "none" { 
+if ((nofilter = (!filter || !*filter || !strcasecmp(filter, "none" { 
 len = apr_snprintf(filtbuf, FILTER_LENGTH, "(%s=", sec->attribute);
 }
 else { 
@@ -256,12 +257,13 @@ static const char* authn_ldap_xlate_password(reque
  * LDAP filter metachars are escaped.
  */
 filtbuf_end = filtbuf + FILTER_LENGTH - 1;
+for (p = user, q = filtbuf + len; *p; ) {
+if (strchr("*()\\", *p) != NULL) {
 #if APR_HAS_MICROSOFT_LDAPSDK
-for (p = user, q=filtbuf + len;
- *p && q < filtbuf_end; ) {
-if (strchr("*()\\", *p) != NULL) {
-if ( q + 3 >= filtbuf_end)
-  break;  /* Don't write part of escape sequence if we can't write all of it */
+if (q + 3 >= filtbuf_end) { /* accounts for final \0 */
+rv = APR_EGENERAL;
+goto out;
+}
 *q++ = '\\';
 switch ( *p++ )
 {
@@ -281,23 +283,24 @@ static const char* authn_ldap_xlate_password(reque
 *q++ = '5';
 *q++ = 'c';
 break;
-}
-}
-else
-*q++ = *p++;
-}
+}
 #else
-for (p = user, q=filtbuf + len;
- *p && q < filtbuf_end; *q++ = *p++) {
-if (strchr("*()\\", *p) != NULL) {
+if (q + 2 >= filtbuf_end) { /* accounts for final \0 */
+rv = APR_EGENERAL;
+goto out;
+}
 *q++ = '\\';
-if (q >= filtbuf_end) {
-  break;
+*q++ = *p++;
+#endif
+}
+else {
+if (q + 1 >= filtbuf_end) { /* accounts for final \0 */
+rv = APR_EGENERAL;
+goto out;
 }
+*q++ = *p++;
 }
 }
-#endif
-*q = '\0';
 
 /*
  * Append the closing parens of the filter, unless doing so would
@@ -305,23 +308,24 @@ static const char* authn_ldap_xlate_password(reque
  */
 
 if (nofilter) { 
-if (q + 1 <= filtbuf_end) {
-strcat(filtbuf, ")");
+if (q + 1 >= filtbuf_end) { /* accounts for final \0 */
+rv = APR_EGENERAL;
+goto out;
 }
-else {
-return APR_EGENERAL;
-}
+*q++ = ')';
 } 
 else { 
-if (q + 2 <= filtbuf_end) {
-strcat(filtbuf, "))");
+if (q + 2 >= filtbuf_end) { /* accounts for final \0 */
+rv = APR_EGENERAL;
+goto out;
 }
-else {
-return APR_EGENERAL;
-}
+*q++ = ')';
+*q++ = ')';
 }
 
-return APR_SUCCESS;
+out:
+*q = '\0';
+return rv;
 }
 
 static void *create_authnz_ldap_dir_config(apr_pool_t *p, char *d)


Re: svn commit: r1591012 - in /httpd/httpd/trunk: CHANGES docs/log-message-tags/next-number modules/aaa/mod_authnz_ldap.c

2023-11-18 Thread Yann Ylavic
On Tue, Apr 29, 2014 at 6:06 PM  wrote:
>
> Author: minfrin
> Date: Tue Apr 29 16:05:56 2014
> New Revision: 1591012
>
> URL: http://svn.apache.org/r1591012
> Log:
> mod_authnz_ldap: Fail explicitly when the filter is too long. Remove
> unnecessary apr_pstrdup() and strlen().

It seems that the escaping cases don't error out if filtbuf is not
large enough? (see below)

>
> --- httpd/httpd/trunk/modules/aaa/mod_authnz_ldap.c (original)
> +++ httpd/httpd/trunk/modules/aaa/mod_authnz_ldap.c Tue Apr 29 16:05:56 2014
[]
> @@ -205,31 +202,23 @@ static const char* authn_ldap_xlate_pass
>   * search filter will be (&(posixid=*)(uid=userj)).
>   */
>  #define FILTER_LENGTH MAX_STRING_LEN
> -static void authn_ldap_build_filter(char *filtbuf,
> +static apr_status_t authn_ldap_build_filter(char *filtbuf,
>   request_rec *r,
> - const char* sent_user,
> - const char* sent_filter,
> + const char *user,
> + const char *filter,
>   authn_ldap_config_t *sec)
>  {
[]
> @@ -264,7 +253,7 @@ static void authn_ldap_build_filter(char
>   */
>  filtbuf_end = filtbuf + FILTER_LENGTH - 1;
>  #if APR_HAS_MICROSOFT_LDAPSDK
> -for (p = user, q=filtbuf + strlen(filtbuf);
> +for (p = user, q=filtbuf + len;
>   *p && q < filtbuf_end; ) {
>  if (strchr("*()\\", *p) != NULL) {
>  if ( q + 3 >= filtbuf_end)

Here we break the loop and fall through with no error.

> @@ -294,7 +283,7 @@ static void authn_ldap_build_filter(char
>  *q++ = *p++;
>  }
>  #else
> -for (p = user, q=filtbuf + strlen(filtbuf);
> +for (p = user, q=filtbuf + len;
>   *p && q < filtbuf_end; *q++ = *p++) {
>  if (strchr("*()\\", *p) != NULL) {
>  *q++ = '\\';

Next it's:
if (q >= filtbuf_end) {
  break;
}
so same here, plus it's not consistent because for
APR_HAS_MICROSOFT_LDAPSDK in the previous hunk we break out before
'\\' while here it's after.

> @@ -312,14 +301,23 @@ static void authn_ldap_build_filter(char
>   */
>
>  if (nofilter) {
> -if (q + 1 <= filtbuf_end)
> +if (q + 1 <= filtbuf_end) {
>  strcat(filtbuf, ")");
> +}
> +else {
> +return APR_EGENERAL;
> +}
>  }
>  else {
> -if (q + 2 <= filtbuf_end)
> +if (q + 2 <= filtbuf_end) {
>  strcat(filtbuf, "))");

> +}
> +else {
> +return APR_EGENERAL;
> +}
>  }

These final checks do not catch the escaping truncations either
because we might have left some room. Also the strcat()s look
inefficient since "q" points at the end of "filtbuf" already.

>
> +return APR_SUCCESS;
>  }


All in all, I'd rewrite this function like in the attached patch (not
even compile tested, just to show what I'm talking about..).

Regards;
Yann.
Index: modules/aaa/mod_authnz_ldap.c
===
--- modules/aaa/mod_authnz_ldap.c	(revision 1913813)
+++ modules/aaa/mod_authnz_ldap.c	(working copy)
@@ -206,7 +206,7 @@ static const char* authn_ldap_xlate_password(reque
  * search filter will be (&(posixid=*)(uid=userj)).
  */
 #define FILTER_LENGTH MAX_STRING_LEN
-static apr_status_t authn_ldap_build_filter(char *filtbuf,
+static apr_status_t authn_ldap_build_filter(char filtbuf[FILTER_LENGTH],
  request_rec *r,
  const char *user,
  const char *filter,
@@ -244,7 +244,7 @@ static const char* authn_ldap_xlate_password(reque
  * config-supplied portions.
  */
 
-if ((nofilter = (filter && !strcasecmp(filter, "none" { 
+if ((nofilter = (!filter || !*filter || !strcasecmp(filter, "none" { 
 len = apr_snprintf(filtbuf, FILTER_LENGTH, "(%s=", sec->attribute);
 }
 else { 
@@ -256,12 +256,12 @@ static const char* authn_ldap_xlate_password(reque
  * LDAP filter metachars are escaped.
  */
 filtbuf_end = filtbuf + FILTER_LENGTH - 1;
+for (p = user, q = filtbuf + len; *p; ) {
+if (strchr("*()\\", *p) != NULL) {
 #if APR_HAS_MICROSOFT_LDAPSDK
-for (p = user, q=filtbuf + len;
- *p && q < filtbuf_end; ) {
-if (strchr("*()\\", *p) != NULL) {
-if ( q + 3 >= filtbuf_end)
-  break;  /* Don't write part of escape sequence if we can't write all of it */
+if (q + 3 >= filtbuf_end) { /* accounts for final \0 */
+return APR_EGENERAL;
+}
 *q++ = '\\';
 switch ( *p++ )
 {
@@ -281,23 +281,22 @@ static const char* authn_ldap_xlate_password(reque
 *q++ = '5';
 *q++ = 'c';
 break;
-}
-}
-else
-*q++ = *p++;
-}
+