Yubico / yubico-pam

Yubico Pluggable Authentication Module (PAM)
https://developers.yubico.com/yubico-pam
BSD 2-Clause "Simplified" License
687 stars 115 forks source link

Simple solution to support dvorak (and other) keymap #102

Open nealey opened 8 years ago

nealey commented 8 years ago

If you were to perform a translation operation on the provided input, you could support other keymaps. For instance, to support dvorak (in pseudocode):

if provided_string == expected_string:
    accept_authentication()
elif provided_string.replace("',.pyfgcrlaoeuidhtn;qjkxbm", "qwertyuiopasdfghjklzcxvbnm") == expected_string:
    accept_authentication()
else:
    reject_authentication()
klali commented 8 years ago

I think this is the same issue as Yubico/yubico-c-client#19 which discusses doing transcoding of otps in the library used in this project.

nealey commented 8 years ago

Yes, it appears to be the same.

genixpro commented 8 years ago

I support this issue. I just posted a duplicate which I am merging into this one.

See the code below for an example of an algorithm that does this detection. Its not perfect - there are a few OTPs which will fail to auto detect, but it works over 99.9% of the time:

var underscore = require('underscore');

/**
 *  This method is used to compensate for people having alternative keyboard layouts with their Yubikey.
 *
 *  In particular. Brad needed this because he uses the Colemak keyboard layout.
 */
module.exports.normalizeYubikeyFromAlternativeKeyboardLayouts = function normalizeYubikeyFromAlternativeKeyboardLayouts(yubikeyString)
{
    // Prepare the lists of characters that are used for qwerty vs colemak for yubikey modhex
    var qwertyModHexChars = ["c","b","d","e","f","g","h","i","j","k","l","n","r","t","u","v"];
    var colemakModHexChars = ["c","b","s","f","t","d","h","u","n","e","i","k","p","g","l","v"];

    // Create a list of characters which unambiguously determine that the string is colemak
    var colemakIdentChars = underscore.difference(colemakModHexChars, qwertyModHexChars);

    // First detect what keyboard layout the yubikey string is from
    var type = "qwerty";
    for(var n = 0; n < colemakIdentChars.length; n += 1)
    {
        if(yubikeyString.indexOf(colemakIdentChars[n]) != -1)
        {
            type = "colemak";
            break;
        }
    }

    // If mode is qwerty, just return the yubikey straight
    if(type == 'qwerty')
    {
        return yubikeyString;
    }
    else if(type == 'colemak')
    {
        return underscore.map(yubikeyString, function(char)
        {
            var index = colemakModHexChars.indexOf(char);
            return qwertyModHexChars[index];
        }).join("");
    }
};
nealey commented 7 years ago

It's been a year now. Should this be closed, or merged somehow in to #19 of the C Client? @genixpro, could you maybe submit your code in a merge proposal?