https://man.liquidfiles.com
LiquidFiles Documentation

The aim of the LiquidFiles download authentication is as follows:

  • Don't break how email normally work
  • Enable both authenticated and unauthenticated downloads
  • Enable authentication with local database and LDAP
  • Allow authentication without creating accounts

Don't break how email normally work

This means that we need to send the same email to everyone. One alternative would be to send individual emails to each of the users, with individual links. This is how very early versions of the LiquidFiles worked. The problem doing that is that it's not possible for a recipient to see who else got the message (we can't set to, cc or bcc headers). There's also a problem that we trust that no one will forward the message as that will break the trust model.

Enable both authenticated and unauthenticated downloads

Often messages are required to be authenticated, but sometimes we can allow messages to be sent without authentication. This will allow messages to be forwarded.

Enable authentication with local database and LDAP

Self explanatory.

Allow authentication without creating accounts

This is a new feature as of 1.6.6. In many security conscious organisations, having external accounts with the associated management is challenging. If we're sending emails to a lot of external users, we also want to make it easy for external users, not requiring yet another account to keep track of. This feature can be turned off in the Admin → Settings page.

Overall Architecture

There's two basic architecture choices, either we create an account when the message is sent, or we let the user create the account themselves later. In both cases, we have to validate the users email address to ensure that no one creates accounts for an email they don't have access to.

The problem with pre-creating accounts is that it doesn't leave the option for non-account authenticated emails, and we have to send emails prompting for account creation at the time when the first message is sent to the particular user. This in turn makes it challenging if the account creation email gets lost, or if someone else manages to get access to the email. It's not really possible to assume that the recipient is going to click on the link within a particular timeframe so we have to leave the window open indefinitely.

The problem with not pre-creating accounts is that we cannot present a user with a normal login window. We have to validate the username first, to see if the user exists on the system or not. If the user exists, we present them with an authentication page. If the user does not exist, we send an email verification email. Please see the following flowchart.

images/security/download_auth/download_authentication_flow.png

When a user enters a username, the system will searched in the following order:

  1. Match the entered email address to list of recipients, and see if the user exists in the local database
  2. Search the LDAP directories, and match the user to the LDAP filter. If found, match the email address from the email key in the LDAP object to the list or recipients.
  3. Match the user to administrators in the local database.
  4. Match the entered email to the list of recipients, and send an email to verify that the user has access to the specified email account.

Example

Consider the following email:

From: burns@powerplant.com
To: homer@powerplant.com
Cc: smithers@powerplant.com
Bcc: kent.brockman@news.com
Subject: You are fired!

Homer, we can no longer have you working at the power plant. Your employment is
terminated effective immediately.

Please see the following securely attached termination letter.

Link: https://filtransfer.springfield.com/message/xDGBFv1cLFXE7gnN8K3Kt0

Furthermore, lets assume that:

  • homer@powerplant.com has an account in the Active Directory (LDAP)
  • smithers@powerplant.com has a local Admin account
  • kent.brockman@news.com does not have an account

Homer

When homer@ clicks on the link, he will be presented with the authorization page:

images/security/download_auth/authorization.png

When he enters homer@powerplant.com, the system will search the LDAP directory for the user, once found he gets presented with the authentication screen:

images/security/download_auth/authentication.png

If he enters the correct password, he will be presented with the message.

Smithers

Smithers account will be found as a local administrator, and be presented with an authentication screen.

Kent Brockman

Kent Brockman does not have an account on the system. He will be presented with the following screen:

images/security/download_auth/email_validate.png

When he clicks on the link in the email, he will be presented with either the message directly (default), or he will be prompted to create an account first.

LDAP Authentication

One potential challenging thing from a user experience point of view is if we have the following LDAP search filter:

(sAMAccountName=<user>)

In LiquidFiles v1.5 an earlier, we could only search for one LDAP key, and if organisations used AD, and wanted their users to authenticate with their shortname (“homer”, not “homer@powerplant.com”). The above search filter is what's being used.

This presents the problem, because in the example above, there's no such user (sAMAccountName=homer@powerplant.com), and since the prompt is for email address, having the user enter:

email: homer

can obviously be confusing. The best solution is to change the LDAP filter to be:

(&(|(sAMAccountName=<user>)(mail=<user>))(objectClass=user))

which is the default in v1.6 and above. This will search both the sAMAccountName field and the mail field, so the user can enter either “homer” or “homer@powerplant.com” and will be able to authenticate regardless.

The Application Log is your friend

The application log, either visible in /var/log/application.log or in Admin → System Log, in the web interface, has a lot of really useful information to what's going on. Example messages from above include:

User access: "Homer Simpson <homer@powerplant.com>" from ip: localhost (127.0.0.1) on message: Mj32DtO via LDAP
Using LDAP authentication: homer@powerplant.com
Connecting to LDAP server: ad.powerplant.com, authenticating user: (&(|(sAMAccountName=homer@powerplant.com)(mail=homer@powerplant.com))(objectClass=user))
LDAP User: homer@powerplant.com successfully authenticated
Local DB Authentication Successful: smithers@powerplant.com
Email validation email sent to: "kent.brockman@news.com" from ip: localhost (127.0.0.1) on message: Mj32DtO via email validation
Email validation for: "kent.brockman@news.com" from: user.example.com (192.1.2.5) for message: Mj32DtO
Email validation failed for: "hUDkV3yMvyQvab5AAJBync" from: user.example.com (192.1.2.5) invalid or expired token

Especially when it comes to the authentication, authorization and access aspects of LiquidFiles, the log displays almost everything thats going on. If anything is not behaving like you're expecting it to, you will most likely find the answer in the application log.

Examples include if you see the email validation message sent to a user, but no “validation for” message - you know the user hasn't clicked on the link the message.