Pilot service for Yubikey two-factor authentication

November 22, 2015

Cosign ‘factors’ – a correction

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 3:12 pm
Tags: ,

In a previous post – ‘Cosign ‘factors’‘ – I wrote:

“Authorization by factor can be arranged via ‘AND‘ and ‘OR‘ combinations: a CosignRequireFactor directive which includes multiple factors implies that those factors are AND‘ed together; multiple CosignRequireFactor directives are OR‘ed.”

And, indeed, the “Cosign Multi-Factor Specification, 20 March 2006, Draft 6” contains the following statement:

“Filters may be configured with a list of required authentication factors. For Apache:

CosignRequireFactor UMICH.EDU OTP

or:

CosignRequireFactor LEVEL2

would indicate that either ( UMICH.EDU & OTP ) or just LEVEL2 are required to satisfy the filter’s multi-factor authentication criteria.”

To correct this: my statement regarding the OR‘ing of multiple CosignRequireFactor directives was incorrect; and the above-mentioned statement in “Cosign Multi-Factor Specification, 20 March 2006, Draft 6” is possibly misleading.

In fact, currently, the Apache Cosign filter does not allow the specification that a user must satisfy factor A OR factor B.

Testing shows that, if multiple CosignRequireFactor directives are declared in any particular case, the most ‘recently defined’ CosignRequireFactor directive wins.

In fact, this is probably the behaviour that we actually want: it means that a top-level CosignRequireFactor directive is completely supplanted by one at a lower-level one, rather than being OR‘ed with the previous declaration. In this way, we can safely enforce ‘stricter’ authentication conditions at the lower level.

November 10, 2015

A Yubikey Cosign authentication ‘factor’

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 3:34 pm
Tags: , , ,

Bearing the above specification in mind, we could now write a Cosign ‘factor’/authenticator which targets Yubikeys: we’d just need to feed it with the username, as well as the one-time-password produced by the Yubikey; have it perform the authentication – by slaving that off to a back-end authentication server; and then have it produce outputs as specified by the protocol.

However: we already have a Yubico PAM module which handles the details of the back-end authentication of the Yubikey one-time-password, and it turns out that a ‘universal Cosign PAM factor adaptor’ is available – see the relevant postings on the cosign-discuss mailing list. So we can use that instead.

The relevant C code file is now part of the Cosign download tarball, but it’s not autobuilt as part of the ./configure; make process. However:

  1. find it (as file pam_factor.c in the cgi/factors directory of the distribution);
  2. build it as follows:
    gcc -lpam -o pam_factor pam_factor.c
    
  3. copy the resulting binary factor to some suitable location, e.g., /usr/lib/cosign/factors; and
  4. edit /etc/cosign.conf to add the factor.

In the /etc/cosign.conf configuration file, all this finally takes the form:

factor /usr/lib/cosign/factors/otp login passcode

where otp is a symlink to the universal Cosign PAM factor adaptor pam_factor, and a new ‘otp‘ PAM service using the Yubico PAM module has also been declared.

Note: the name of the factor is significant, and is more than just, for example, self-documentation! Recall that the factor must, on successful authentication:

  • write the factor name to stdout; and
  • exit with 0.

The universal Cosign PAM ‘factor adaptor’ is coded to emit a factor name which corresponds to its basename – i.e. in our case, it will emit the factor name of ‘otp‘ on successful authentication. So the literal factor name ‘otp‘ is what the rest of the corresponding Cosign configuration client-side must be set up to expect.

In addition: the name of the corresponding local PAM service must match that of the factor: the factor is coded to call out to the local PAM service which corresponds to its basename.

Finally, however: why call this factor ‘otp‘ rather than, say, the more mnemonic name ‘yubikey‘? After all, both of the above-mentioned pieces of configuration could be fixed up accordingly. Well, as well as ‘leaking’ less internal configuration information, it turns out that the factor ‘otp‘ is already explicitly supported by the supporting HTML and Javascript distributed in the Cosign tarball. So ‘otp‘ is just better and easier all round.

Cosign ‘factors’ – continued …

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 3:06 pm
Tags: ,

Bearing in mind that ‘factor’ is an overloaded term within Cosign, the “Cosign Multi-Factor Specification, 20 March 2006, Draft 6” defines the necessary behaviour of a ‘factor’ as ‘external authenticator.’ Namely:

  1. External authenticator(s) are declared as follows in /etc/cosign.conf:
    factor <pathname> [-2] <form-field1> <formfield2> …
    
  2. Any such authenticator will be invoked if (and only if) all listed form-fields contain posted data.
  3. The value of each form-field is written to the authenticator on stdin, one per line, in the order in which they are listed in the configuration.
  4. If authentication is successful, the authenticator:
    • writes the factor name to stdout
    • exits with 0

    Otherwise, the authenticator:

    • writes an error message to stdout
    • exits with 1

The -2 option to the factor keyword means that this factor is only checked after another (non -2) factor has been satisfied. It’s intended for use with factors which are vulnerable to denial-of-service attacks due to repeated authentication failures.

Cosign ‘factors’

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 12:29 pm
Tags: ,

In Cosign, the word ‘factor’ fundamentally means an ‘authentication type.’ However, ‘factor’ is an overloaded term, which also refers to:

  • an arbitrary string which is returned by an external authenticator on success;
  • the external authenticator itself.

In addition, there are ‘Legacy factors’: e.g. if Kerberos is used to authenticate the account, the ‘factor’ is set to the Kerberos realm used.

(More information about all of this can be found in the “Cosign Multi-Factor Specification, 20 March 2006, Draft 6”.)

On the client Cosign website, authorization by factor is enforced by the Cosign filter directive CosignRequireFactor.

Authorization by factor can be arranged via ‘AND‘ and ‘OR‘ combinations: a CosignRequireFactor directive which includes multiple factors implies that those factors are AND‘ed together; multiple CosignRequireFactor directives are OR‘ed.

Edit: in fact, testing subsequent to this blog post shows it is not the case that “multiple CosignRequireFactor directives are OR‘ed”! It turns out that, in the case of multiple CosignRequireFactor directives, the most ‘recently defined’ CosignRequireFactor directive wins. See blog post Cosign ‘factors’ – a correction.

On Informatics sites, up until fairly recently CosignRequireFactor has typically been null – which means ‘accept any request which has been authenticated against any available factor.’

Nowadays, we generally declare

CosignRequireFactor INF.ED.AC.UK  

in order to allow Informatics users, but to exclude iFriend users.

Just to repeat: a null CosignRequireFactor means that authentication against any available factor is deemed sufficient. Be careful!

Theme: Rubric.