Using pam_yubico to validate yubikey against privacyidea

I’ve enrolled a Yubikey with:

privacyidea -U https://athene.jochen.org -a jochen@admin token yubikey_mass_enroll --yubimode YUBICO --yubislot 1 --description “Test” --yubiprefixrandom 6

If I don’t use 6 as the random length I get something like the following
in pam_yubico debug:

[pam_yubico.c:pam_sm_authenticate(816)] pam_yubico version: 2.21
[pam_yubico.c:pam_sm_authenticate(831)] get user returned: jochen
YubiKey for `jochen’: <string_with_32_characters>
[pam_yubico.c:pam_sm_authenticate(982)] conv returned 32 bytes
[pam_yubico.c:pam_sm_authenticate(990)] OTP too short to be considered : 32 < 44
[pam_yubico.c:pam_sm_authenticate(1106)] done. [Legitimierungsfehler]

So, now I have a yubikey that emits 44 characters:

[pam_yubico.c:pam_sm_authenticate(982)] conv returned 44 bytes
[pam_yubico.c:pam_sm_authenticate(1000)] Skipping first 0 bytes. Length is 44, token_id set to 12 and token OTP always 32.
[pam_yubico.c:pam_sm_authenticate(1007)] OTP: delnifbevfti<string_with_32_characters> ID: delnifbevfti
[pam_yubico.c:pam_sm_authenticate(1037)] ykclient return value (101): Could not parse server response
[pam_yubico.c:pam_sm_authenticate(1038)] ykclient url used: https://athene.jochen.org/ttype/yubikey?id=23453&nonce=npnyufcbmsjidzyblwxatvgseikwnwuc&otp=delnifbevfti<string_with_32_characters>&timestamp=1
[pam_yubico.c:pam_sm_authenticate(1106)] done. [Legitimierungsdienst kann Legitimierungsinformationen nicht abrufen]

If I enter the URL in my browser I get:

{“nonce”: “npnyufcbmsjidzyblwxatvgseikwnwuc”, “jsonrpc”: “2.0”,
“signature”:
“2542069859411243772936126744287249038228704735354594223227328749181486050834182923042812179590621538709337025319287646014339074313521543246808634509942681278261020756540501234149389725629963403589033487567250216361296681378023451148145372527041540701064149893610078471976103440519739964198590051832872818449021674100520637117851374273331687080733185527765756869162886904491797808214215711678741801753625349631296964269490063864546106500927621828795710510199973178717250459732315975750477429718128228442851198357848343270360538224457238859817994492798306478373925032289564954657105562532132054777009587651153962260706”,
“detail”: null, “version”: “privacyIDEA 2.10.2”, “result”: {“status”:
false, “error”: {“message”: “(OperationalError) (1267, “Illegal mix of
collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE)
for operation ‘=’”) ‘SELECT token.id AS token_id, token.description AS
token_description, token.serial AS token_serial, token.tokentype AS
token_tokentype, token.user_pin AS token_user_pin, token.user_pin_iv AS
token_user_pin_iv, token.so_pin AS token_so_pin, token.so_pin_iv AS
token_so_pin_iv, token.resolver AS token_resolver, token.resolver_type
AS token_resolver_type, token.user_id AS token_user_id, token.pin_seed
AS token_pin_seed, token.otplen AS token_otplen, token.pin_hash AS
token_pin_hash, token.key_enc AS token_key_enc, token.key_iv AS
token_key_iv, token.maxfail AS token_maxfail, token.active AS
token_active, token.revoked AS token_revoked, token.locked AS
token_locked, token.failcount AS token_failcount, token.count AS
token_count, token.count_window AS token_count_window, token.sync_window
AS token_sync_window, token.rollout_state AS token_rollout_state \nFROM
token \nWHERE token.serial = %s’ (‘UBAM#\xabt\x13\xf4\xd7’,)”,
“code”: -500}}, “time”: 1457267927.363808, “id”: 1}

So privacy looks for an UBAM token (which I created above), but there is
no token with that hex serial number. The only UBAM token I have is:

mysql> select id, serial, tokentype, otplen from token where serial like ‘UBAM%’;±—±---------------±----------±-------+
| id | serial | tokentype | otplen |
±—±---------------±----------±-------+
| 45 | UBAM04017813_1 | yubikey | 44 |
±—±---------------±----------±-------+
1 row in set (0.00 sec)

The error message pointed be to
http://airbladesoftware.com/notes/fixing-mysql-illegal-mix-of-collations/

On my system I have:
mysql> show variables like ‘char%’;
±-------------------------±---------------------------+
| Variable_name | Value |
±-------------------------±---------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
±-------------------------±---------------------------+
8 rows in set (0.00 sec)

and “show table status \G” has Collation: latin1_swedish_ci
for the tables.

Should we use something like in /etc/mysql/my.cnf?

[mysqld]

MySQL 5.5.3+

character-set-server=utf8
collation-server=utf8_general_ci

The mysql configuration might be wrong or just old-fashioned, but I
guess the error is in privacyidea, where we use
’UBAM#\xabt\x13\xf4\xd7’ as the serial number. Any idea where I
should look for more hints before I fight against mysql character sets?

Jochen


The only problem with troubleshooting is that the trouble shoots back.

Jochen Hein <@Jochen_Hein> writes:

[pam_yubico.c:pam_sm_authenticate(1038)] ykclient url used:
https://athene.jochen.org/ttype/yubikey?id=23453&nonce=npnyufcbmsjidzyblwxatvgseikwnwuc&otp=delnifbevfti<string_with_32_characters>&timestamp=1
[pam_yubico.c:pam_sm_authenticate(1106)] done. [Legitimierungsdienst kann Legitimierungsinformationen nicht abrufen]

If I enter the URL in my browser I get:

{“nonce”: “npnyufcbmsjidzyblwxatvgseikwnwuc”, “jsonrpc”: “2.0”,
“signature”:
“2542069859411243772936126744287249038228704735354594223227328749181486050834182923042812179590621538709337025319287646014339074313521543246808634509942681278261020756540501234149389725629963403589033487567250216361296681378023451148145372527041540701064149893610078471976103440519739964198590051832872818449021674100520637117851374273331687080733185527765756869162886904491797808214215711678741801753625349631296964269490063864546106500927621828795710510199973178717250459732315975750477429718128228442851198357848343270360538224457238859817994492798306478373925032289564954657105562532132054777009587651153962260706”,
“detail”: null, “version”: “privacyIDEA 2.10.2”, “result”: {“status”:
false, “error”: {“message”: "(OperationalError) (1267, “Illegal mix of
collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE)
for operation ‘=’”)

Just for reference: Using /validate/check the OTP matches:
https://athene.jochen.org/validate/check?serial=UBAM04017813_1&pass=delnifbevftiufntrjilnvbiudjthdcnkdcdbjdllicu

{“jsonrpc”: “2.0”, “signature”:
“1723234770573501422761285023508957391597155923128350385009338368357078102701173449646863610506750473044749743096308704612274054808314995341643357318808890859668846216132879771908313678063820051708137118541223286148414764154842581294349492797161649064789932664037463980040329540528341059868309582456546764313671426777002806324509571937699112213147597469800391384980338732485091841612317869708256620843101631348319116611677400596763644089769876818244716586135727567192790954138261557475473606665647015177631939705438552437271188230779430974405639037698919648993183384145459267957712004349523451811088526146463191037427”,
“detail”: {“message”: “matching 1 tokens”, “type”: “yubikey”, “serial”:
“UBAM04017813_1”}, “versionnumber”: “2.10.2”, “version”: “privacyIDEA
2.10.2”, “result”: {“status”: true, “value”: true}, “time”:
1457274163.654277, “id”: 1}

(‘UBAM#\xabt\x13\xf4\xd7’,)",

Some experiments show that delnifbevfti modhex is 23 ab 74 13 f4 d7 hex.
That seems to suggest that the code in
https://github.com/privacyidea/privacyidea/blob/master/privacyidea/lib/tokens/yubikeytoken.py:383
is not quite correct for me:

    # strip the yubico OTP and the PIN
    modhex_serial = passw[:-32][-16:]
    try:
        serialnum = "UBAM" + modhex_decode(modhex_serial)

I’m unsure what the correct solution is. Privacy seems to be confused
between the token serial number and the prefix. But I can’t us the
serial number as prefix, because otherwise pam_yubico will be confused
(OTP is too long…). Do we need an additional database column to store
the connection between prefix and serial number? Or do I miss something
more fundamental?

Jochen–
The only problem with troubleshooting is that the trouble shoots back.

Jochen Hein <@Jochen_Hein> writes:

(‘UBAM#\xabt\x13\xf4\xd7’,)",

Some experiments show that delnifbevfti modhex is 23 ab 74 13 f4 d7 hex.
That seems to suggest that the code in
https://github.com/privacyidea/privacyidea/blob/master/privacyidea/lib/tokens/yubikeytoken.py:383
is not quite correct for me:

    # strip the yubico OTP and the PIN
    modhex_serial = passw[:-32][-16:]
    try:
        serialnum = "UBAM" + modhex_decode(modhex_serial)

I’m unsure what the correct solution is.

I’ve thought about that a lot more. Here’s what I think will work.

Let’s start with what I’ve learned from pam_yubico. The yubikey needs
to send 44 characters in modhec, 12 as a public identity, the rest will
be OTP:
[pam_yubico.c:pam_sm_authenticate(990)] OTP too short to be considered : 32 < 44

In the Yubico manual concerning self programmed yubikeys and Cloud mode
https://www.yubico.com/wp-content/uploads/2013/07/YubiKey_YubiCloud_Configuration.pdf
we have the description what Yubico needs to handle such keys.

Privacyidea right now doesn’t store the public identity, but tries to
reconstruct the serial number from that - but as I wrote in my first
mail it fails for me. I think we need to first think about the right
initialization of the keys and then how to handle them in privacidea.
At least if we don’t want to enhance the token table in the database to
store the public identity. Which way would you prefer?

For the rest of my thoughts I’ll assume we won’t change the token table.
I’ll talk about UBAP as a prefix for the serial number, so we don’t
disturb working UBAM tokens. Whether or not that’s needed we’ll see.

So let’s see how we can initialize a token. In
http://forum.yubico.com/viewtopic.php?f=16&t=2110 there’s talk about the
first byte in the prefix. cc is used for factory programmed yubikeys,
vv is used for customer programmed keys uploaded to yubico:

We know that YubiCloud validates CC and VV names space. All other name
spaces are for customers to choose and use within internal validations

I propose to use 31 (hex) as a prefix for privacyides (PI), which would
give us an eb prefix in modhex. The next four bytes I’d propose to
translate the serial number interpreted as a hex number into modhex.
E.g. for my key 04017813 we get in modhex cfcbijbe. We now have one
byte left, so let’s encode slot 1 or 2 and translate in modhex as cb or
cd.

So my token UBAP04017813_1 would send a prefix ebcfcbijbecb, which
translates to hex 310401781301. If the first byte is 31, we’ll have
probably the right token type initializes. Then we have the serial
number and the slot number, so we can reconstruct the serial in
https://github.com/privacyidea/privacyidea/blob/master/privacyidea/lib/tokens/yubikeytoken.py:383

This will need changes to

  • privacyidea token yubikey_mass_enroll, probably a new token MODE
  • the token enrollment in the webui
  • the validation endpoint(s)

I hope that this would allow me to use my self programmed token with
privacyidea and pam_yubico (and hopefully later with Kolab as well).

Do you think this might be workable? Is it too complex/fragile, or
might there be another way to initialize a working YUBICO token?
Would it be easier to enhance the token table?

Jochen–
The only problem with troubleshooting is that the trouble shoots back.

Hello Jochen,

at the moment I am a bit into enable SAML SSO for privacyIDEA WebUI.

I also need to prepare two talks at Cebit and the Chemnitzer Linuxtage.
So i might take a look at it in two weeks.

Can you please file an issue at github with a reference to this issue?

So the public identifier/preifx can not be the serial number…?
I think it is not necessary to change the database model.
Especially not for one tokentype!

There is the table “tokeninfo” which can hold additional tokentype
dependent information.
The prefix is in fact already stored in the tokeninfo table:


So I think you are right, that we need to get the enrollment straight and
find a solution that keeps the backward compatibility.

Thanks a lot
CorneliusAm Montag, 7. März 2016 21:25:32 UTC+1 schrieb Jochen Hein:

Jochen Hein jochen@jochen.org writes:

(‘UBAM#\xabt\x13\xf4\xd7’,)",

Some experiments show that delnifbevfti modhex is 23 ab 74 13 f4 d7 hex.
That seems to suggest that the code in

https://github.com/privacyidea/privacyidea/blob/master/privacyidea/lib/tokens/yubikeytoken.py:383

is not quite correct for me:

    # strip the yubico OTP and the PIN 
    modhex_serial = passw[:-32][-16:] 
    try: 
        serialnum = "UBAM" + modhex_decode(modhex_serial) 

I’m unsure what the correct solution is.

I’ve thought about that a lot more. Here’s what I think will work.

Let’s start with what I’ve learned from pam_yubico. The yubikey needs
to send 44 characters in modhec, 12 as a public identity, the rest will
be OTP:
[pam_yubico.c:pam_sm_authenticate(990)] OTP too short to be considered :
32 < 44

In the Yubico manual concerning self programmed yubikeys and Cloud mode

https://www.yubico.com/wp-content/uploads/2013/07/YubiKey_YubiCloud_Configuration.pdf
we have the description what Yubico needs to handle such keys.

Privacyidea right now doesn’t store the public identity, but tries to
reconstruct the serial number from that - but as I wrote in my first
mail it fails for me. I think we need to first think about the right
initialization of the keys and then how to handle them in privacidea.
At least if we don’t want to enhance the token table in the database to
store the public identity. Which way would you prefer?

For the rest of my thoughts I’ll assume we won’t change the token table.
I’ll talk about UBAP as a prefix for the serial number, so we don’t
disturb working UBAM tokens. Whether or not that’s needed we’ll see.

So let’s see how we can initialize a token. In
http://forum.yubico.com/viewtopic.php?f=16&t=2110 there’s talk about the
first byte in the prefix. cc is used for factory programmed yubikeys,
vv is used for customer programmed keys uploaded to yubico:

We know that YubiCloud validates CC and VV names space. All other name
spaces are for customers to choose and use within internal validations

I propose to use 31 (hex) as a prefix for privacyides (PI), which would
give us an eb prefix in modhex. The next four bytes I’d propose to
translate the serial number interpreted as a hex number into modhex.
E.g. for my key 04017813 we get in modhex cfcbijbe. We now have one
byte left, so let’s encode slot 1 or 2 and translate in modhex as cb or
cd.

So my token UBAP04017813_1 would send a prefix ebcfcbijbecb, which
translates to hex 310401781301. If the first byte is 31, we’ll have
probably the right token type initializes. Then we have the serial
number and the slot number, so we can reconstruct the serial in

https://github.com/privacyidea/privacyidea/blob/master/privacyidea/lib/tokens/yubikeytoken.py:383

This will need changes to

  • privacyidea token yubikey_mass_enroll, probably a new token MODE
  • the token enrollment in the webui
  • the validation endpoint(s)

I hope that this would allow me to use my self programmed token with
privacyidea and pam_yubico (and hopefully later with Kolab as well).

Do you think this might be workable? Is it too complex/fragile, or
might there be another way to initialize a working YUBICO token?
Would it be easier to enhance the token table?

Jochen


The only problem with troubleshooting is that the trouble shoots back.

I also need to prepare two talks at Cebit and the Chemnitzer
Linuxtage.
So i might take a look at it in two weeks.

I’ll probably be at Cebit on Tuesday.

Can you please file an issue at github with a reference to this issue?

I’ll continue to investigate how we might handle the yubikey, but I’ll
file a placeholder issue at github and will add my comments there.

So the public identifier/preifx can not be the serial number…?

We could use the serial number, but will miss the slot info (might not
be needed). But at least we need to initialize the token in the right
way,
so mass_enroll must be fixed and manual enrollment must be documented
and prefix checked…

I tried to find the code that creates the UBAMxxx name when enrolling
the token in the webui, but was not successful. Any hint where I should
look?

I think it is not necessary to change the database model.
Especially not for one tokentype!

Ok.

There is the table “tokeninfo” which can hold additional tokentype
dependent information.

I’ll have a look.

So I think you are right, that we need to get the enrollment straight
and find a solution that keeps the backward compatibility.

Thanks for the feedback.

JochenAm 2016-03-08 08:49, schrieb Cornelius Kölbel:


The only problem with troubleshooting is that the trouble shoots back.

Cornelius Kölbel cornelius.koelbel@netknights.it writes:

Can you please file an issue at github with a reference to this issue?

So the public identifier/preifx can not be the serial number…?
I think it is not necessary to change the database model.
Especially not for one tokentype!

There is the table “tokeninfo” which can hold additional tokentype
dependent information.
The prefix is in fact already stored in the tokeninfo table:

https://github.com/privacyidea/privacyidea/blob/master/privacyidea/lib/tokens/yubikeytoken.py#L249
https://github.com/privacyidea/privacyidea/blob/master/privacyidea/lib/tokens/yubikeytoken.py#L369

I did enroll my token with privacyidea mass_enroll, and the tokeninfo
table has:

mysql> select id, tokeninfo.Key, Value, token_id from tokeninfo where token_id = 45;±----±-------------------±--------------------±---------+
| id | Key | Value | token_id |
±----±-------------------±--------------------±---------+
| 108 | count_auth | 1 | 45 |
| 109 | count_auth_success | 1 | 45 |
| 110 | last_auth | 2016-03-06 14:22:43 | 45 |
| 107 | yubikey.tokenid | 0a1e0a49e7a8 | 45 |
±----±-------------------±--------------------±---------+
4 rows in set (0.01 sec)

mysql> select id, serial, tokentype from token where id = 45;
±—±---------------±----------+
| id | serial | tokentype |
±—±---------------±----------+
| 45 | UBAM04017813_1 | yubikey |
±—±---------------±----------+
1 row in set (0.00 sec)

I had a look at the enrollment via webui:
mysql> select id, serial, tokentype from token where serial like “UBAM%”;
±—±---------------±----------+
| id | serial | tokentype |
±—±---------------±----------+
| 47 | UBAM00017297 | yubikey |
| 45 | UBAM04017813_1 | yubikey |
±—±---------------±----------+
2 rows in set (0.00 sec)

mysql> select id, tokeninfo.Key, Value, token_id from tokeninfo where token_id = 47;
±----±-------------------±--------------------±---------+
| id | Key | Value | token_id |
±----±-------------------±--------------------±---------+
| 112 | count_auth | 1 | 47 |
| 113 | count_auth_success | 1 | 47 |
| 114 | last_auth | 2016-03-08 19:49:57 | 47 |
| 111 | yubikey.tokenid | f6a5d0de670e | 47 |
±----±-------------------±--------------------±---------+

Authentication failed, but I faked the serial number (I don’t see how we
could get the right serial number from the data available here, so I
guess we already stored either not enough or wrong information when
enrolling the token):

— yubikeytoken.py.orig 2016-03-08 21:09:14.669076518 +0100
+++ yubikeytoken.py 2016-03-08 21:29:39.209045369 +0100
@@ -393,6 +393,7 @@
for i in range(1, 3):
serials.append("%s_%s" % (serialnum, i))

  •   serials = ["UBAM00017297"]
       from privacyidea.lib.token import get_tokens
       from privacyidea.lib.token import check_token_list
       for serial in serials:
    

After that I could authenticate successfully:

[pam_yubico.c:pam_sm_authenticate(816)] pam_yubico version: 2.21
[pam_yubico.c:pam_sm_authenticate(831)] get user returned: jochen
YubiKey for `jochen’: ebcfcbijbecbfgrhghvllkebnnrcbeguhvcvkrvldngb
[pam_yubico.c:pam_sm_authenticate(982)] conv returned 44 bytes
[pam_yubico.c:pam_sm_authenticate(1000)] Skipping first 0 bytes. Length is 44, token_id set to 12 and token OTP always 32.
[pam_yubico.c:pam_sm_authenticate(1007)] OTP: ebcfcbijbecbfgrhghvllkebnnrcbeguhvcvkrvldngb ID: ebcfcbijbecb
[pam_yubico.c:pam_sm_authenticate(1037)] ykclient return value (0): Success
[pam_yubico.c:pam_sm_authenticate(1038)] ykclient url used: https://athene.jochen.org/ttype/yubikey?id=23453&nonce=zuelrxmngsuegamwgpqzgvqpftlujpgj&otp=ebcfcbijbecbfgrhghvllkebnnrcbeguhvcvkrvldngb&timestamp=1
[pam_yubico.c:authorize_user_token(181)] Dropping privileges

After that:

[util.c:check_user_token(151)] Authorization line: jochen:4017813:4017832:17297
[util.c:check_user_token(156)] Matched user: jochen
[util.c:check_user_token(162)] Authorization token: 4017813
[util.c:check_user_token(162)] Authorization token: 4017832
[util.c:check_user_token(162)] Authorization token: 17297
[util.c:check_user_token(162)] Authorization token: (null)
[pam_yubico.c:pam_sm_authenticate(1071)] Unauthorized token for this user
[pam_yubico.c:pam_sm_authenticate(1106)] done. [Legitimierungsfehler]

So I’m a step further.

I guess there is still something missing. I’ll first try to get my
token to work with changes to the tokeninfo table, I’m still unsure
where we will end up.

Some more experiments brought me to the conclusion, that we don’t store
the prefix in tokeninfo’s yubikey.tokeninfo, but the uid. The following
patch stores the prefix instead of uid in the tokeninfo when enrolling
via Webui:

— yubikeytoken.py.orig 2016-03-08 21:09:14.669076518 +0100
+++ yubikeytoken.py 2016-03-08 22:25:26.508837984 +0100
@@ -248,14 +249,14 @@

     tokenid = self.get_tokeninfo("yubikey.tokenid")
     if not tokenid:
  •        log.debug("Got no tokenid for %r. Setting to %r." % (serial, uid))
    
  •        tokenid = uid
    
  •        log.debug("Got no tokenid for %r. Setting to %r." % (serial, yubi_prefix))
    
  •        tokenid = yubi_prefix
           self.add_tokeninfo("yubikey.tokenid", tokenid)
    
  •    if tokenid != uid:
    
  •    if tokenid != yubi_prefix:
           # wrong token!
           log.warning("The wrong token was presented for %r. Got %r, expected %r."
    
  •                    % (serial, uid, tokenid))
    
  •                    % (serial, yubi_prefix, tokenid))
           return -2
    

I’m now experimenting to get the serial number back from the
yubikey.tokeninfo. I also need to check what happens when I use
mass_enroll. I now think we get away without a special prefix - we’ll
see.

Not yet there, but I think I’ll get there.

Jochen


The only problem with troubleshooting is that the trouble shoots back.

Cornelius Kölbel cornelius.koelbel@netknights.it writes:

Can you please file an issue at github with a reference to this issue?

So the public identifier/preifx can not be the serial number…?
I think it is not necessary to change the database model.
Especially not for one tokentype!

There is the table “tokeninfo” which can hold additional tokentype
dependent information.
The prefix is in fact already stored in the tokeninfo table:

https://github.com/privacyidea/privacyidea/blob/master/privacyidea/lib/tokens/yubikeytoken.py#L249
https://github.com/privacyidea/privacyidea/blob/master/privacyidea/lib/tokens/yubikeytoken.py#L369

I did enroll my token with privacyidea mass_enroll, and the tokeninfo
table has:

mysql> select id, tokeninfo.Key, Value, token_id from tokeninfo where token_id = 45;±----±-------------------±--------------------±---------+
| id | Key | Value | token_id |
±----±-------------------±--------------------±---------+
| 108 | count_auth | 1 | 45 |
| 109 | count_auth_success | 1 | 45 |
| 110 | last_auth | 2016-03-06 14:22:43 | 45 |
| 107 | yubikey.tokenid | 0a1e0a49e7a8 | 45 |
±----±-------------------±--------------------±---------+
4 rows in set (0.01 sec)

mysql> select id, serial, tokentype from token where id = 45;
±—±---------------±----------+
| id | serial | tokentype |
±—±---------------±----------+
| 45 | UBAM04017813_1 | yubikey |
±—±---------------±----------+
1 row in set (0.00 sec)

I had a look at the enrollment via webui:
mysql> select id, serial, tokentype from token where serial like “UBAM%”;
±—±---------------±----------+
| id | serial | tokentype |
±—±---------------±----------+
| 47 | UBAM00017297 | yubikey |
| 45 | UBAM04017813_1 | yubikey |
±—±---------------±----------+
2 rows in set (0.00 sec)

mysql> select id, tokeninfo.Key, Value, token_id from tokeninfo where token_id = 47;
±----±-------------------±--------------------±---------+
| id | Key | Value | token_id |
±----±-------------------±--------------------±---------+
| 112 | count_auth | 1 | 47 |
| 113 | count_auth_success | 1 | 47 |
| 114 | last_auth | 2016-03-08 19:49:57 | 47 |
| 111 | yubikey.tokenid | f6a5d0de670e | 47 |
±----±-------------------±--------------------±---------+

Authentication failed, but I faked the serial number (I don’t see how we
could get the right serial number from the data available here, so I
guess we already stored either not enough or wrong information when
enrolling the token):

— yubikeytoken.py.orig 2016-03-08 21:09:14.669076518 +0100
+++ yubikeytoken.py 2016-03-08 21:29:39.209045369 +0100
@@ -393,6 +393,7 @@
for i in range(1, 3):
serials.append("%s_%s" % (serialnum, i))

  •   serials = ["UBAM00017297"]
       from privacyidea.lib.token import get_tokens
       from privacyidea.lib.token import check_token_list
       for serial in serials:
    

After that I could authenticate successfully:

[pam_yubico.c:pam_sm_authenticate(816)] pam_yubico version: 2.21
[pam_yubico.c:pam_sm_authenticate(831)] get user returned: jochen
YubiKey for `jochen’: ebcfcbijbecbfgrhghvllkebnnrcbeguhvcvkrvldngb
[pam_yubico.c:pam_sm_authenticate(982)] conv returned 44 bytes
[pam_yubico.c:pam_sm_authenticate(1000)] Skipping first 0 bytes. Length is 44, token_id set to 12 and token OTP always 32.
[pam_yubico.c:pam_sm_authenticate(1007)] OTP: ebcfcbijbecbfgrhghvllkebnnrcbeguhvcvkrvldngb ID: ebcfcbijbecb
[pam_yubico.c:pam_sm_authenticate(1037)] ykclient return value (0): Success
[pam_yubico.c:pam_sm_authenticate(1038)] ykclient url used: https://athene.jochen.org/ttype/yubikey?id=23453&nonce=zuelrxmngsuegamwgpqzgvqpftlujpgj&otp=ebcfcbijbecbfgrhghvllkebnnrcbeguhvcvkrvldngb&timestamp=1
[pam_yubico.c:authorize_user_token(181)] Dropping privileges

After that:

[util.c:check_user_token(151)] Authorization line: jochen:4017813:4017832:17297
[util.c:check_user_token(156)] Matched user: jochen
[util.c:check_user_token(162)] Authorization token: 4017813
[util.c:check_user_token(162)] Authorization token: 4017832
[util.c:check_user_token(162)] Authorization token: 17297
[util.c:check_user_token(162)] Authorization token: (null)
[pam_yubico.c:pam_sm_authenticate(1071)] Unauthorized token for this user
[pam_yubico.c:pam_sm_authenticate(1106)] done. [Legitimierungsfehler]

So I’m a step further.

I guess there is still something missing. I’ll first try to get my
token to work with changes to the tokeninfo table, I’m still unsure
where we will end up.

Some more experiments brought me to the conclusion, that we don’t store
the prefix in tokeninfo’s yubikey.tokeninfo, but the uid. The following
patch stores the prefix instead of uid in the tokeninfo when enrolling
via Webui:

[please do not apply - I guess we’ll add a new yubikey.prefix]
— yubikeytoken.py.orig 2016-03-08 21:09:14.669076518 +0100
+++ yubikeytoken.py 2016-03-08 22:25:26.508837984 +0100
@@ -248,14 +249,14 @@

     tokenid = self.get_tokeninfo("yubikey.tokenid")
     if not tokenid:
  •        log.debug("Got no tokenid for %r. Setting to %r." % (serial, uid))
    
  •        tokenid = uid
    
  •        log.debug("Got no tokenid for %r. Setting to %r." % (serial, yubi_prefix))
    
  •        tokenid = yubi_prefix
           self.add_tokeninfo("yubikey.tokenid", tokenid)
    
  •    if tokenid != uid:
    
  •    if tokenid != yubi_prefix:
           # wrong token!
           log.warning("The wrong token was presented for %r. Got %r, expected %r."
    
  •                    % (serial, uid, tokenid))
    
  •                    % (serial, yubi_prefix, tokenid))
           return -2
    

I’m now experimenting to get the serial number back from the
yubikey.tokeninfo. I also need to check what happens when I use
mass_enroll. I now think we get away without a special prefix - we’ll
see.

Not yet there, but I think I’ll get there.

Jochen


The only problem with troubleshooting is that the trouble shoots back.