mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
05.44.2007 bdd7fafc56563eba2413d62794bed388a7a2be69
Update the LDAPFilter code so that the process for decoding filters from
strings will perform more strict checking to ensure that the attribute
description in a simple filter contains only valid characters. This will
catch filters that are invalid but were not properly rejected, like
"((uid=user.0))", "(&&(uid=user.0))", or "!uid=user.0".

OpenDS Issue Numbers: 1565, 1848
3 files modified
142 ■■■■■ changed files
opends/src/server/org/opends/server/messages/ProtocolMessages.java 30 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/ldap/LDAPFilter.java 109 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestLDAPFilter.java 3 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/ProtocolMessages.java
@@ -4609,14 +4609,13 @@
  /**
   * The message ID for the message that will be used if an LDAP search filter
   * is enclosed in apostrophes ("single-quotes").
   * (FIXME -- This error is a workaround for
   * https://opends.dev.java.net/issues/show_bug.cgi?id=1024. A correct fix
   * is to validate the characters used in the attribute type.
   * is enclosed in apostrophes ("single-quotes").  See issue #1024.
   */
  public static final int MSGID_LDAP_FILTER_ENCLOSED_IN_APOSTROPHES =
       CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_MILD_ERROR | 427;
  /**
   * The message ID for the message that will be used as the description of the
   * configuration attribute specifying whether to enable the LDAPS
@@ -4625,6 +4624,19 @@
  public static final int MSGID_JMX_CONNHANDLER_DESCRIPTION_ENABLE =
       CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_INFORMATIONAL | 428;
  /**
   * The message ID for the message that will be used if an LDAP search filter
   * includes an invalid character in an attribute type.  This takes three
   * arguments, which are the attribute type, the illegal character, and the
   * position at which it occurred.
   */
  public static final int MSGID_LDAP_FILTER_INVALID_CHAR_IN_ATTR_TYPE =
       CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_MILD_ERROR | 429;
  /**
   * Associates a set of generic messages with the message IDs defined in this
   * class.
@@ -5410,6 +5422,12 @@
                    "The provided search filter \"%s\" could not be decoded " +
                    "because the NOT filter between positions %d and %d " +
                    "did not contain exactly one filter component");
    registerMessage(MSGID_LDAP_FILTER_ENCLOSED_IN_APOSTROPHES,
                    "An LDAP filter enclosed in apostrophes is invalid:  %s");
    registerMessage(MSGID_LDAP_FILTER_INVALID_CHAR_IN_ATTR_TYPE,
                    "The provided search filter contains an invalid " +
                    "attribute type '%s' with invalid character '%s' at " +
                    "position %d");
    registerMessage(MSGID_LDAP_CLIENT_SEND_RESPONSE_NO_RESULT_CODE,
@@ -6605,10 +6623,6 @@
    registerMessage(MSGID_CANNOT_DECODE_GETEFFECTIVERIGHTS_AUTHZID_DN,
                    "Unable to decode authzid DN string \"%s\" as a valid " +
                    "distinguished name:  %s");
    registerMessage(MSGID_LDAP_FILTER_ENCLOSED_IN_APOSTROPHES,
                    "An LDAP filter enclosed in apostrophes is invalid:  %s");
  }
}
opends/src/server/org/opends/server/protocols/ldap/LDAPFilter.java
@@ -367,10 +367,7 @@
    }
    // If the filter is enclosed in a pair of apostrophes ("single-quotes") it
    // is invalid.
    // (FIXME -- This error is a workaround for
    //  https://opends.dev.java.net/issues/show_bug.cgi?id=1024. A correct fix
    // is to validate the characters used in the attribute type.)
    // is invalid (issue #1024).
    if (1 < filterString.length()
         && filterString.startsWith("'") && filterString.endsWith("'"))
    {
@@ -467,8 +464,110 @@
    // The part of the filter string before the equal sign should be the
    // attribute type.
    // attribute type.  Make sure that the characters it contains are acceptable
    // for attribute types, including those allowed by attribute name
    // exceptions (ASCII letters and digits, the dash, and the underscore).  We
    // also need to allow attribute options, which includes the semicolon and
    // the equal sign.
    String attrType = filterString.substring(startPos, attrEndPos);
    for (int i=0; i < attrType.length(); i++)
    {
      switch (attrType.charAt(i))
      {
        case '-':
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case ';':
        case '=':
        case 'A':
        case 'B':
        case 'C':
        case 'D':
        case 'E':
        case 'F':
        case 'G':
        case 'H':
        case 'I':
        case 'J':
        case 'K':
        case 'L':
        case 'M':
        case 'N':
        case 'O':
        case 'P':
        case 'Q':
        case 'R':
        case 'S':
        case 'T':
        case 'U':
        case 'V':
        case 'W':
        case 'X':
        case 'Y':
        case 'Z':
        case '_':
        case 'a':
        case 'b':
        case 'c':
        case 'd':
        case 'e':
        case 'f':
        case 'g':
        case 'h':
        case 'i':
        case 'j':
        case 'k':
        case 'l':
        case 'm':
        case 'n':
        case 'o':
        case 'p':
        case 'q':
        case 'r':
        case 's':
        case 't':
        case 'u':
        case 'v':
        case 'w':
        case 'x':
        case 'y':
        case 'z':
          // These are all OK.
          break;
        case '.':
        case '/':
        case ':':
        case '<':
        case '>':
        case '?':
        case '@':
        case '[':
        case '\\':
        case ']':
        case '^':
        case '`':
          // These are not allowed, but they are explicitly called out because
          // they are included in the range of values between '-' and 'z', and
          // making sure all possible characters are included can help make the
          // switch statement more efficient.  We'll fall through to the default
          // clause to reject them.
        default:
          int    msgID   = MSGID_LDAP_FILTER_INVALID_CHAR_IN_ATTR_TYPE;
          String message = getMessage(msgID, attrType,
                                      String.valueOf(attrType.charAt(i)), i);
          throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, msgID,
                                  message);
      }
    }
    // Get the attribute value.
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestLDAPFilter.java
@@ -70,6 +70,9 @@
      { "(cn=billy bob", null },
      { "(|(!(title=sweep*)(l=Paris*)))", null },
      { "(|(!))", null },
      { "((uid=user.0))", null },
      { "(&&(uid=user.0))", null },
      { "!uid=user.0", null },
    };
  }