UnboundID LDAP SDK for Java 4.0.6

We have just released the UnboundID LDAP SDK for Java version 4.0.6, available for download from the releases page of our GitHub repository, from the Files page of our SourceForge project, and from the Maven Central Repository. The most significant changes in this release include:

  • We fixed a number of issues in the way that the LDAP SDK handled characters whose UTF-8 representation requires more than two bytes (and therefore requires two Java chars to represent a single character). Issues related to these characters were found in code for matching rules, DNs and RDNs, and search filters.
  • We fixed an issue in the ldapsearch tool that could cause it to use an incorrect scope when constructing search requests from LDAP URLs that were read from a file.
  • We fixed a bug in schema handling that could arise if an object class definition did not explicitly specify an object class type (STRUCTURAL, AUXILIARY, or ABSTRACT). In some cases, the type could be incorrectly inherited from the superclass rather than assuming the default type of STRUCTURAL.
  • We updated the LDAPConnectionPool and LDAPThreadLocalConnectionPool classes to add new setServerSet and setBindRequest methods. These new methods make it possible to update an existing pool to change the logic that it uses for establishing and authenticating new connections.
  • We added a new LDAPRequest.setReferralConnector method that makes it possible to set a custom referral connector on a per-request basis. We also added a new RetainConnectExceptionReferralConnector class that makes it easier to obtain the exception (if any) that was caught on the last attempt to establish a connection for the purpose of following a referral.
  • Updated the in-memory directory server to better handle any java.lang.Errors that occur while interacting with a client connection. These kinds of errors should not happen under normal circumstances but may be generated by third-party code (for example, an InMemoryOperationInterceptor), and it is possible for the JVM to generate them in extraordinary circumstances like running out of memory. In such cases, the thread responsible for interacting with that client would exit without returning a response for the operation being processed and without closing the operation. The LDAP SDK will now attempt to return an error (if appropriate for the type of operation being processed) and close the connection.
  • Updated the manage-certificates tool to fix an incorrect interpretation of the path length element of a basic constraints extension.
  • Updated manage-certificates to add support for importing PEM-encoded RSA private keys that are not wrapped in a PKCS #8 envelope (that is, from a file whose header contains “BEGIN RSA PRIVATE KEY” instead of “BEGIN PRIVATE KEY”). Previously, it was only possible to import private keys using the PKCS #8 format.
  • Updated manage-certificates to add an --allow-sha-1-signature-for-issuer-certificates argument to the check-certificate-usability subcommand. If this argument is provided, then the tool will continue to call out issuer certificates whose signature is based on the now-considered-weak SHA-1 digest algorithm, but it will no longer cause the tool to exit with an error just because of that issue. This argument has no effect for certificates that use a signature based on the extremely weak MD5 digest, and it also does not have any effect if the certificate at the head of the chain (that is, the server certificate rather than the root certificate) has a SHA-1-based signature.
  • Added client-side support for a new “reload HTTP connection handler certificates” task that may be used in some Ping Identity server products to request that the server dynamically reload the certificate key and trust stores used by all HTTP connection handler instances that provide support for HTTPS.

A Baffling Android Security Update Policy

Google is maddeningly schizophrenic when it comes to security. They were early adopters of two-factor authentication for their online services, and they offer multiple ways for obtaining that second factor (including at least TOTP, SMS, voice call, and U2F). Yet you can’t always require two-factor authentication when logging into a Chromebook, and it doesn’t seem like there’s any two-factor authentication scheme for logging into mobile devices. I’d love the option to require both a passphrase (or at least a reasonably long PIN) and a fingerprint, but enabling the fingerprint reader for any purpose (even if you just want to use a fingerprint as a second factor in an app) automatically makes your phone unlockable with just a fingerprint. That’s insane.

Their lack of decent VPN support for Chromebooks also boggles the mind. Unless you’re willing to jump through some very ugly hoops (like using Crouton to set up a Linux sandbox, diving deep into Chrome OS configuration internals), you’re limited to L2TP, which is vulnerable to man-in-the-middle attacks. For devices that are intended to be used on the go with a network connection, presumably through some WiFi service that you don’t control (and therefore have a much greater risk of having someone snoop on your communication), good VPN support is absolutely critical. And even if you can get a working VPN and you’ve got a Chromebook that supports running Android apps (which I’ve got to admit does make Chrome OS much nicer), good luck getting those apps to use the VPN for their communication.

But today I encountered something that seems to take dumb to a new level. On Monday, Google released an Android Security Bulletin about new security vulnerabilities, including “a Critical security vulnerability that could enable remote code execution on an affected device through multiple methods such as email, web browsing, and MMS when processing media files.” So in theory, someone could send you a text message with a media attachment and take over your phone. That seems like a pretty big deal. So I went to see if there was a system update for my phone (a Google Pixel XL), and there was. So I clicked to download it, and I got an error message saying “This update can be downloaded via a WiFi network only until May 6. To continue download, connect to a WiFi network.”

What? This doesn’t make even the tiniest bit of sense. Why is this critical security update only available if you’re connected to WiFi? Why does Google care if I want to use my mobile data to download the patch? And what’s special about May 6 that all of a sudden will make it okay for me to download it then? It’s not like it costs Google any more money if the data ultimately ends up on the phone via 3G/4G/LTE than it does via WiFi. Even if I were using Google’s Fi service for my mobile data (and I’m not), I’d have to pay for the data that I used because Google Fi doesn’t have any kind of unlimited data play (it’s a flat rate of ten dollars per gigabyte, and it would actually be in their best interests to get people to use as much data as possible).

I can absolutely understand warning the user about using mobile data for a potentially large file (this update was about 60 megabytes) and wanting to get the user’s okay before starting the download. That would be a good thing. If you have a mobile data cap, or if the size of your bill depends on how much data mobile data you use, then, of course, you’d want to be warned about doing something that could use a significant amount of data. But this wasn’t a warning message that I could simply dismiss and get on with the download. This was an error message that told me that I just plain couldn’t get the update unless I connected to WiFi or unless I wanted to wait (and remain vulnerable) for several more days.

In the interest of security, I did kowtow to this stupid demand, and I downloaded the update over WiFi (secured by VPN). But if I’d been traveling somewhere where I had good mobile data coverage but WiFi wasn’t readily available, then I’d have been stuck either needing to find somewhere I could leech (or pay for) a connection, or remain vulnerable for a few more days (during which time I’m sure there would be plenty of bad guys trying to reverse-engineer the update and figure out how to exploit the vulnerabilities that it fixes).

Seriously, Google. Do security better.

Important updates about the upcoming 4.0.0 release of the UnboundID LDAP SDK for Java

TL;DR: The next release of the UnboundID LDAP SDK for Java will have a version number of 4.0.0, will require Java SE 7 or later, and there will be just one edition instead of the three editions that we currently maintain.

Although it’s still at least a month or two away, I wanted to make a couple of announcements about the next release of the UnboundID LDAP SDK for Java that might affect some of its users. These are some significant changes, so we’ll bump the version number to 4.0.0.

We’re going to start updating the LDAP SDK to reflect these changes immediately, but there’s still time before the release, so if you do have any concerns or questions about these changes, then now is the time to raise them. The best way to do that is to send us an email at ldapsdk-support@pingidentity.com. or use the SourceForge project discussion forum.

Requiring Java SE 7 or Later

The first change is that we’re going to require Java SE 7 or later to use the LDAP SDK.

All previous LDAP SDK releases have been compatible with Java SE 5.0 or later, but Java SE 5 is really old. According to http://www.oracle.com/technetwork/java/eol-135779.html, Oracle stopped providing public updates for it in 2009, and even extended support for it ended in 2015. There are a few things in the SDK that don’t work as well if you’re using Java SE 5, and for which we currently have to use reflection to access on newer VMs.

Dropping support for Java SE 5 allows us to simplify that code and potentially take advantage of new Java features that were added in Java SE 6 and 7. We’ll also be able to update some components that we use during the LDAP SDK build process, although this doesn’t have any impact on your ability to use the SDK. And as always, the LDAP SDK does not and will not depend on anything except Java SE, so you won’t need any third-party libraries to use it.

The older releases of the LDAP SDK aren’t going away, so if you really need to run on Java SE 5.0 or 6 for some reason, then you can continue to use one of the existing releases.

Only Releasing a Single Edition

Another notable change is that we’re only going to be providing a single edition of the LDAP SDK moving forward. Right now, we offer three editions:

  • Standard Edition (SE) — A fully-functional LDAP SDK for use with any type of LDAPv3 directory server.
  • Commercial Edition (CE) — Everything in the Standard Edition, plus additional features specifically intended for use in conjunction with the UnboundID/Ping Identity Directory Server, Directory Proxy Server, and other server products.
  • Minimal Edition (ME) — A very stripped-down version of the LDAP SDK that still provides core LDAPv3 support, but with a focus on keeping a very small jar file for space-constrained environments like Android or embedded systems.

Offering a separate Commercial Edition of the LDAP SDK was necessary in the past because it wasn’t open source and we only made it available to customers who had purchased our server software. But since then, we made it open source and publicly available. There were also concerns about a developer accidentally writing code that leveraged proprietary features that would prevent it from working against non-UnboundID/Ping Identity servers, but that’s easy enough to avoid by just staying away from classes in a package below com.unboundid.ldap.sdk.unboundidds.

Similarly, in the earlier days of Android and other Java-based embedded systems, you didn’t have as much room to work with as you do today, so having a Minimal Edition with a significantly smaller footprint was useful, but it did come at the cost of functionality and convenience. And even the Commercial Edition isn’t all that big (the jar file is around 3.5 megabytes, versus 650 kilobytes for the Minimal Edition, and two megabytes for the Standard Edition).

So from now on, we’re just going to have one edition, and we’ll just call it UnboundID LDAP SDK for Java. It’ll have everything in it that the Commercial Edition has, and it’ll continue to be open source under the terms of the GPLv2 and LGPLv2.1 (plus the UnboundID LDAP SDK Free Use License, which isn’t open source but lets you use and redistribute the LDAP SDK for just about any purpose as long as you don’t make any changes to it). The jar file will be named unboundid-ldapsdk.jar , and we’ll continue to publish it to Maven with a GroupId of com.unboundid and an ArtifactId of unboundid-ldapsdk.

UnboundID LDAP SDK for Java 3.2.1

We have just released the 3.2.1 version of the UnboundID LDAP SDK for Java. It is available for download from the LDAP.com website, as well as from GitHub, SourceForge, or the Maven Central Repository.

You can get a full list of changes included in this release from the release notes. The Commercial Edition release notes also provide information about additional changes only included in the Commercial Edition.

Some of the most significant changes in both the Standard Edition and the Commercial Edition include

  • Updated the documentation to indicate that, as a result of Ping Identity’s acquisition of UnboundID, all non-public feedback, feature enhancements, support requests, and other kinds of communication should now be sent to ldapsdk-support@pingidentity.com instead of ldapsdk-support@unboundid.com. We also now recommend using the GitHub issue tracker over the SourceForge mailing lists and discussion forums for bug reports and feature requests.
  • Fixed a bug in the RDN parsing code that could cause multiple consecutive spaces in the middle of an attribute value to be condensed down to a single space. The string representation of the RDN was preserved correctly, but the methods used to retrieve attribute values as a string or byte array could return values that were missing spaces.
  • Provided better handling for InterruptedException. A thread’s interrupted state will now be preserved for cases in which the LDAP SDK consumes an InterruptedException without doing something to handle it.
  • Fixed a bug in the support for the SASL ANONYMOUS mechanism that could cause the trace string to be omitted from the encoded bind request.
  • Updated the searchrate tool to provide support for generic controls, as well as specific support for the assertion, simple paged results, and server-side sort request controls.
  • Updated the authrate tool to add a new –bindOnly argument that allows you to indicate that the tool should only perform bind operations, rather than a search to find the entry and then a bind as that user. The base DN pattern will be used to construct the bind DN.
  • Updated the authrate tool to provided support for generic search and bind controls, as well as specific support for the authorization identity and password policy request controls.
  • Updated the search-and-modrate tool to provide support for generic search and modify controls, as well as specific support for the assertion, simple paged results, permissive modify, pre-read, and post-read request controls.
  • Added a Schema.getSchema method that can read schema information in LDIF form from an input stream.
  • Updated support for the GSSAPI SASL mechanism to make it possible to indicate in the generated configuration file whether the client should act as an initiator or an acceptor.
  • Updated the identify-unique-attribute-conflicts tool to include a time limit in search requests intended to determine whether a unique attribute value may also be in use in any other entries. This can help limit the effect of running the tool against a server that is not configured with the appropriate indexes needed to ensure that equality searches targeting the unique attributes can be processed efficiently.

Some of the additional changes only available in the Commercial Edition include:

  • Added a new version of the ldapsearch tool that provides a lot of additional functionality over the version provided in the Standard Edition. It includes much better output formatting (including support for alternate output formats like JSON, CSV, and tab-delimited text), support for a number of data transformations, more robust connection handling, support for referrals, support for a large number of search and bind controls, support for administrative sessions, support for unsolicited notifications, the ability to process multiple searches with search criteria provided in filter or LDAP URL files, rate limiting, and the ability to send results to a specified output file (or a separate output file per search).
  • Implemented caching for the matching rule instance used when requesting the jsonObjectExactMatch matching rule. This matching rule only exists in the Commercial Edition and needs to be loaded via reflection.
  • Updated the access and error log parsing APIs to include support for the triggeredByConn and triggeredByOp log fields used to indicate that the message is associated with the indicated operation.

UnboundID LDAP SDK for Java 2.2.0

UnboundID LDAP SDK for Java 2.2.0 has just been released and is available for download from the UnboundID website or the SourceForge project page, and is also available in the Maven central repository.

The release notes provide a full overview of the changes in this release over the previous 2.1.0 version. There are several bug fixes, but some of the most notable new features include:

  • A new Minimal Edition has been introduced. The Minimal Edition is available under the same licenses as the Standard Edition and provides support for all LDAP operations, but a number of capabilities have been removed (e.g., support for SASL authentication, a number of controls and extended operations, the persistence framework, the listener framework and in-memory directory server, JNDI and Netscape SDK migration support, etc.). The primary goal of the Minimal Edition is to provide a version of the LDAP SDK with a small jar file size which is desirable for resource-constrained environments like Android applications or other embedded use. The Minimal Edition is available as a separate download, from either the UnboundID website or SourceForge project.

  • Connection pooling support has been updated to provide the ability to automatically retry operations if the first attempt fails in a way that indicates the connection may no longer be valid. In such cases, a new connection will be established (potentially to a different server, based on the ServerSet in use for the pool) and the operation will be re-attempted on that connection. This can help isolate applications from failures if one of the target directory servers is shut down, crashes, hangs, or begins behaving erratically.

  • The in-memory directory server has been updated to add support for maintaining referential integrity (e.g., so that if an entry is deleted then that user can be automatically removed from any static groups in which the user was a member), to support LDAP transactions as described in RFC 5805, and to add support for inserting an arbitrary delay before processing operations (which can be useful in simulating environments with slower response times or higher network latencies). There have also been a couple of fixes for bugs that could cause the in-memory directory server to behave incorrectly.

  • The LDAP SDK persistence framework has been updated to provide better support for searches. Previously, it was difficult to search for entries using anything but equality searches. The generate-source-from-schema tool has been updated so that it will now generate additional methods that can make it easier to perform other kinds of searches, including presence, substring (starts with, ends with, and contains), greater-or-equal, less-or-equal, and approximately-equal-to.

  • New methods have been added which make it significantly easier to interact with response controls. Each response control class now has one or more static get methods that can be used to extract and decode a response control of that type from a given response object.

  • Support for GSSAPI authentication has been significantly improved to add support for a number of new options, including the ability to indicate whether to use (or even require) a ticket cache, to specify an alternate location for the ticket cache file, and to request that the TGT be renewed. Changes have also been introduced to make it easier to access GSSAPI debugging information.

  • A new option has been added that makes it possible to automatically send an abandon request to the directory server if a client-side timeout is encountered while waiting for a response to an operation. Previously, the LDAP SDK would throw an exception but did not have any option to attempt to abandon the operation in the directory server.

  • The LDAP SDK can now use schema information (if available) in the process of normalizing and comparing DNs and RDNs. This can provide more accurate matching for DNs that use attributes in which something other than case-inexact string matching should be used.

  • The LDIF reader has been updated to provide the ability to read data from multiple files. This can be useful for cases in which the complete set of data you want to process is broken up into multiple files (e.g., representing different portions of the DIT).

UnboundID LDAP SDK for Java 1.1.6

I have just made a new 1.1.6 release of the UnboundID LDAP SDK for Java available for download. You can get it on either the UnboundID LDAP SDK product page or on the SourceForge project page. It should also be available in the Maven Central Repository in the near future (probably within the next day or two).

There are only a couple of minor changes in this release over the previous 1.1.5 version, including:

  • I corrected an error in the documentation around the use of the content synchronization request control that incorrectly recommended using a response timeout of -1 rather than 0. A value of 0 indicates that no timeout should be used, while a value of -1 means that the connection-level timeout (which is 5 minutes by default) should be used.

  • I fixed a problem in the way that the string representation of RDNs was generated when a DN was parsed from a string. Previously, some extra spaces could have been removed. The resulting string representation was technically equivalent to the version that was originally provided, but the original formatting should have been preserved.

  • I updated the source for the Android LDAP client to match what was published as version 1.1 in the Android market.

Minor Updates to the Android LDAP Client

I have just uploaded a new version of the UnboundID LDAP client to the Android market. It’s kind of embarrassing that it took this long to put out such a minor update, but I had visions of a much more significant update that I never got around to coding and I kept putting off some simple stuff. Hopefully the minor improvements are worth the update, and maybe I’ll get around to the bigger version at some point in the future.

The changes included in this update are:

  • I’ve updated the application to use the latest version of the LDAP SDK. This includes several bug fixes over the version used in the previous release of the LDAP client, including some fixes around SSL and StartTLS.

  • It is now more liberal with what it considers a user entry (and will therefore allow special treatment for things like telephone numbers, e-mail addresses, postal addresses, etc.). Previously, it would only work for entries with an object class of “person”. It will now work for any entry that has a “cn” attribute and at least one of the following additional attributes: mail, mailAlternateAddress, telephoneNumber, homePhone, mobile, pager, and facsimileTelephoneNumber.

  • It should now be usable on devices with any screen size. Previously, it was only available for devices with what was considered a “normal” screen size, and it might not have been available on some devices with a very low resolution, or on devices with much higher resolutions. I don’t know how it looks on any of those other devices, but hopefully it’s at least usable.

  • It should now be possible to move the application to the SD card on devices running Android 2.2.

I’ve tested the application in the emulator for Android versions 1.5 and 2.2, and on actual phones running Android 1.6, 2.1, and 2.2, and I haven’t encountered any problems on any of them. If you run into a problem, please let me know.

UnboundID LDAP SDK for Java 1.1.3

We have just released version 1.1.3 of the UnboundID LDAP SDK for Java. The full release notes can be found at http://www.unboundid.com/products/ldapsdk/docs/release-notes.php, but some of the changes in this release include:

  • It now includes support for LDAP transactions as defined in the recently-released RFC 5805. You will need a directory server that provides support for this capability (like the UnboundID Directory Server) in order to be able to use it.
  • It is now possible to determine the number of operations in progress on a connection that is established and not operating in synchronous mode.
  • A new searchForEntry method has been added to LDAPInterface (implemented by connections and connection pools) to make it more convenient to perform searches that you expect to return at most one entry.
  • The add request object has been updated to make it easier to treat it as if it were an entry.
  • The schema parsing code has been updated to be more lenient about accepting quotes around OIDs and overlooking missing spaces after OID lists. These changes help make it possible for the LDAP SDK to parse the schema presented by Active Directory even though it is in violation of the LDAP specification.
  • It includes a fix for an obscure bug that could cause an exception to be thrown when trying to normalize a value containing only non-ASCII space characters.
  • It includes a fix for a bug that would cause the entry validator to throw an exception when provided with an entry that did not contain any object classes.
  • The searchrate tool has been updated to provide support for processing asynchronous operations so that there can be multiple outstanding requests on each connection.
  • The source for the Android LDAP client has been updated to be the source for the 1.0 version released to the Android Market.

A new “PlugProfile” Android app

Ever since I got my Droid working properly, it is by far the best phone that I’ve ever had. However, one notable deficiency is the fact that it lacks a good way to change ring profiles. There are a lot of applications in the Android Market that can help with this, but none of them did exactly what I wanted, so I decided to write my own.

Several years ago, I got an LG V phone, and it had a really nice and sensible feature that made it possible for you to change how it behaved when a call came in based on whether or not it was plugged in, and I used that to configure the phone to vibrate when it was unplugged (and presumably in my pocket) but to ring at maximum volume when it was plugged in (and obviously not in my pocket).

A couple of years ago, I traded in my V phone for a Blackberry. It didn’t directly support changing the ring profile based on whether it was plugged in or not, but it did support changing the profile based on whether it was in the holster. Since I carried the phone in my pocket and didn’t use the holster, that was good enough because I could put it in the holster whenever I plugged it in to achieve the same effect.

Late last year when I upgraded from the Blackberry to the Droid, it was an upgrade in nearly every way except ring profile management. The phone itself comes with basically nothing for changing the way it rings under different conditions. There are a lot of apps in the Android Market that try to address this problem, and there are some pretty inventive solutions like using information about your location or based on the time of day. However, none of these were a very good fit for my needs. I ended up using “Quick Profiles”, which just let you create different profiles and then manually switch between them, but that wasn’t ideal because I found that I frequently forgot to change the profile when unplugging my phone and putting it in my pocket in the morning and taking it out and plugging it back in in the evening, so it was frequently configured to ring when I didn’t want it to, or vibrate when I wasn’t around to feel it.

The model exhibited by the V phone was just about perfect for me, so I decided to go ahead and write an app to do that for Android. It was a pretty quick and painless process, and the app is now available for free in the Android Market with the name “PlugProfile”. It provides the ability to automatically set the phone to silent mode, vibrate-only mode, ring-only mode, or ring-and-vibrate mode based on whether it’s on battery, on AC power, or on USB power, and if ringing is enabled, you can set the volume from anywhere between 10% and 100% of the maximum volume in 10% increments. I have my phone set to use vibrate-only mode when it’s on battery, ring with 100% volume when it’s plugged into AC power, and ring with 50% volume when it’s plugged into USB (of a presumably nearby computer). It doesn’t mess with your ringtone, so if you’ve got different rings for different people, then that should still be preserved.

LDAP Client now in Android Market

Ever since I started looking at Android a little over a year ago, I’ve had a simple LDAP client in one form or another. Since the UnboundID LDAP SDK for Java works on Android, it wasn’t too difficult to put a simple GUI on top of it that allows you to perform LDAP searches. However, until recently it wasn’t in a state that I felt was suitable for publishing. Prompted by the Android Developer Labs (which I attended earlier tonight), I finally got around to making it presentable, and as of a few minutes ago, the app is now available for free in the Android Market. It’s far from a masterpiece, but it can be pretty useful if you want to access LDAP content. Some of the features it has include:

  • It has support for multiple servers. Each server definition includes an address, port, security mechanism (none, SSL, or StartTLS), optional bind DN and password, and optional base DN.
  • You can customize the type of search to perform. It has a drop-down that allows you to select the type of search (last name, first name, full name, e-mail address, or user ID), or if you want you can enter your own LDAP search filter.
  • If multiple entries are returned, you can see a brief summary of each. Tapping on one of them will take you to a more complete view of the entry. Long-tapping will pop up a menu with options for the entry (view a formatted representation, view an LDIF representation, copy the DN to the clipboard, or copy the LDIF representation to the clipboard).
  • When viewing a single entry, clicking on the header for that entry will allow you to view the entry as LDIF, copy the DN to the clipboard, or copy the LDIF representation to the clipboard.
  • Clicking on a telephone number in an entry will allow you to dial or send an SMS message to that number, or copy the number to the clipboard.
  • Clicking on an e-mail address in an entry will allow you to send an e-mail to that address, or copy the address to the clipboard.
  • Clicking on a postal address or ZIP code in an entry will allow you to show a map of that location, navigate to that location, or copy the address to the clipboard.
  • Clicking on any other attribute in an entry will allow you to copy the value of that attribute to the clipboard.
  • A button at the bottom of the panel for a user entry will allow you to add information about that user to your local contacts.

If you have an Android device, then you can find this application in the market just by searching for “LDAP” (it’s currently the only match). The full name is “LDAP Client” and the author is “Neil Wilson”. I hope to improve it further in the future, but I at least wanted to get this reasonably-functional version out there for people that have a use for it.