Privacyidea3 Push Troubleshooting

I haven’t seen any posts about people who have successfully gotten Push authentication working, so I wanted to see if anyone who had could share some insight. I’ve created a project in Firebase, but the push token enrollment isn’t successful. I’m able to do the first part, with scanning the QR code, but part 2 doesn’t happen. I didn’t see anything in the privacyidea.log file about the attempt, and a tcpdump on the server doesn’t show any attempt to connect from my phone.

So, that said, I had a few questions that might narrow down the issue.

The PrivacyIDEA server has an outbound internet connection, but is not accessible from the internet. I’m currently using my phone on the local office wifi, and it can connect to the PrivacyIDEA server without issue. Does the Firebase service need to be able to connect to the PrivacyIDEA server? The PrivacyIDEA server has outbound internet access, and my phone can access both the PrivacyIDEA server as well as Firebase via the internet. The only “break” is if the Firebase service needs to access the PrivacyIDEA server.

I had to create a “fake” Android project within the Firebase console to get an AppID and JSON file. Was that the correct procedure, or do I need to actually have a legitimate Android App for this to work?

The field in the SMS Gateway Definition section, where it asks for the JSON file…can that be an absolute path to the file anywhere on the PrivacyIDEA server, or is there a specific directory I need to put that file in? In addition, are there special permissions/ownership I need to assign to it?

Thanks…hopefully answers to those questions will put me in the right direction.

I used another QR scanning App to check the Code URL to make sure the settings I entered in the SMS Gateway config were there. They were, and were correct, which makes me think the issue might be with the PrivacyIDEA Authenticator App for iOS (version 1.0.1 Build 2). It’s adding the token to it, but it doesn’t appear to be attempting to contact the PrivacyIDEA server for the 2nd part of the token registration.

I am sorry for your inconvenience. The iOS App currently does not support the push token, yet. We are working on it. With the android token we are in the beta phase. If you want to beta test the android app, please drop me a note.

1 Like

Ahhh, ok, good, that means I wasn’t missing something obvious. I don’t have access to Android, so I’ll just keep an eye out here for when the iOS version is updated to support. Thanks for the answer!

We added a howto for push.

Also the beta testing for the privacyIDEA Authenticator 2.0 is availble.

1 Like

That howto is fantastic, and exactly what I’ll need when the 2.0 iOS version is available. Thanks!

1 Like

There are a lot of components intertwining and thus a lot of room for errors.
So the idea is, that users can start with the first step to setup the system and check that it basically working.
Actually connecting applications, will be the next issue.

@bnort81 For which application are you planning to use push?

Perhaps my interpretation of how push will work is incorrect. Here’s how I’m using PI now:

A user connects to a Linux server, and the PAM authentication module sends the request back to the PI server. A user must enter their LDAP password, followed by the six digit code on the authenticator app of their choice, then they are logged in.

The way I envisioned using the push token in the above scenario is a user logs in with their LDAP password only, and the login process sends a push notification to the PI authenticator app. They accept, and the login is allowed to proceed. If they don’t, they get an access denied.

But, based on your question, I’m thinking now that this is not what it is intended for, but instead to integrate PI with a company/person’s mobile app.

Which PAM module are you currently using? It is not quite clear to me.

This is exactly the way how it would work.

No, the thing is, since we not originially “intercept” the authentication (problems with timeout and communication to user), we need the application where the user logs in (in your case PAM), to check if the user answered the challenge correctly. This is why I am asking, which PAM module you are using. Well, anyways, you will probably have to use privacyidea_pam anyways.

I use, which calls

I feel like I’m missing a piece here, specifically in the Firebase part of the authentication path.

PI_Client -> PI_Server -> Firebase -> Mobile PI Authenticator App

The part where Firebase knows how to communicate with the Mobile Authenticator App on my specific phone is where I’m getting lost.

I figured I would jump in here instead of making a new topic over similar troubleshooting. I’ve gotten my push tokens working to the point where I receive the push on the smartphone and can tap accept. I see the request go back to /ttype/push.

However when doing a /token/challenges, it does not appear to be updating to show that Accept has been tapped.

Output from my test Powershell script to /validate/check

pin_change      : True
next_pin_change : 2019-04-19T14:00-0500
transaction_ids : {03160508109750966615}
messages        : {Please confirm the authentication on your mobile device!}
multi_challenge : {@{pin_change=True; next_pin_change=2019-04-19T14:00-0500; attributes=; message=Please confirm the
                  authentication on your mobile device!; type=push; serial=PIPU0000D2CC;
threadid        : 140060348065536
attributes      :
message         : Please confirm the authentication on your mobile device!
type            : push
serial          : PIPU0000D2CC
transaction_id  : 03160508109750966615

At this point I received a push on the smartphone and tapped accept.

But when I list the challenges, this is the output.

challenges : {@{otp_received=False; timestamp=Fri, 19 Apr 2019 17:23:38 GMT;
             challenge=7HLNODEWWH4BYCTYYLO7JDTFBPDYXKFG; id=1151; expiration=Fri, 19 Apr 2019 17:25:38 GMT;
             serial=PIPU0000D2CC; data=; otp_valid=False; transaction_id=03160508109750966615; received_count=0}}

I’ve attached a snippet of debug logs showing the /ttype/push request timeframe.

[2019-04-19 17:23:45,520][13681][140060348065536][DEBUG][privacyidea.api.before_after:82] Begin handling of request u'/ttype/push?'
[2019-04-19 17:23:45,520][13681][140060348065536][DEBUG][privacyidea.lib.config:78] The singleton <class 'privacyidea.lib.config.ConfigClass'> already exists.
[2019-04-19 17:23:45,523][13681][140060348065536][DEBUG][privacyidea.api.lib.utils:219] Can not get param: No JSON object could be decoded
[2019-04-19 17:23:45,523][13681][140060348065536][DEBUG][privacyidea.lib.config:78] The singleton <class 'privacyidea.lib.policy.PolicyClass'> already exists.
[2019-04-19 17:23:45,525][13681][140060348065536][DEBUG][privacyidea.lib.audit:188] Entering getAudit with arguments HIDDEN and keywords HIDDEN
[2019-04-19 17:23:45,525][13681][140060348065536][DEBUG][privacyidea.lib.utils:1110] klass: <class 'privacyidea.lib.auditmodules.sqlaudit.Audit'>
[2019-04-19 17:23:45,525][13681][140060348065536][DEBUG][privacyidea.lib.auditmodules.base:185] Entering read_keys with arguments (<privacyidea.lib.auditmodules.sqlaudit.Audit object at 0x7f6244908790>, '/etc/privacyidea/public.pem', '/etc/privacyidea/private.pem') and keywords {}
[2019-04-19 17:23:45,525][13681][140060348065536][DEBUG][privacyidea.lib.auditmodules.base:197] Exiting read_keys with result None
[2019-04-19 17:23:45,526][13681][140060348065536][DEBUG][privacyidea.lib.auditmodules.sqlaudit:122] using the connect string mysql://pi:xxxx@localhost/pi?unix_socket=/var/run/mysqld/mysqld.sock
[2019-04-19 17:23:45,527][13681][140060348065536][DEBUG][privacyidea.lib.auditmodules.sqlaudit:129] Using SQL pool size of 20
[2019-04-19 17:23:45,527][13681][140060348065536][DEBUG][privacyidea.lib.audit:197] Exiting getAudit with result <privacyidea.lib.auditmodules.sqlaudit.Audit object at 0x7f6244908790>
[2019-04-19 17:23:45,527][13681][140060348065536][DEBUG][privacyidea.lib.config:185] Entering get_from_config with arguments ('OverrideAuthorizationClient',) and keywords {}
[2019-04-19 17:23:45,528][13681][140060348065536][DEBUG][privacyidea.lib.config:78] The singleton <class 'privacyidea.lib.config.ConfigClass'> already exists.
[2019-04-19 17:23:45,529][13681][140060348065536][DEBUG][privacyidea.lib.config:197] Exiting get_from_config with result x.x.x.x
[2019-04-19 17:23:45,529][13681][140060348065536][DEBUG][privacyidea.lib.auditmodules.base:185] Entering log with arguments (<privacyidea.lib.auditmodules.sqlaudit.Audit object at 0x7f6244908790>, {'info': '', 'success': False, 'privacyidea_server': '', 'client_user_agent': None, 'client': '', 'action_detail': '', 'action': 'POST /ttype/<ttype>'}) and keywords {}
[2019-04-19 17:23:45,530][13681][140060348065536][DEBUG][privacyidea.lib.auditmodules.base:197] Exiting log with result None
[2019-04-19 17:23:45,530][13681][140060348065536][DEBUG][privacyidea.api.ttype:185] Entering token with arguments () and keywords {'ttype': u'push'}
[2019-04-19 17:23:45,530][13681][140060348065536][DEBUG][privacyidea.lib.token:185] Entering get_tokens with arguments () and keywords {'serial': u'PIPU0000D2CC', 'tokentype': 'push'}
[2019-04-19 17:23:45,533][13681][140060348065536][DEBUG][privacyidea.lib.token:185] Entering create_tokenclass_object with arguments (<<class 'privacyidea.models.Token'> {"'active'": 'True', "'count_window'": '10L', "'key_enc'": "u'57d69dad477421c622038111e9f1be13b59b7a3d69e739c410eed271610aeca99bbb0eac1018ab696e274c16a8c9664d03dbe7c6648cf12d88dd43fbe2c66bf7bd5cf84dcf264059d34b37599396a70d2622a41a67418934926297bc9b29bcb4'", "'pin_hash'": "u'a2692bc05deb2b8eea1cddb1d6280287d7f83a765374ee0507b675ea0fd70691'", "'so_pin'": "u''", "'otplen'": '6L', "'so_pin_iv'": "u''", "'serial'": "u'PIPU0000D2CC'", "'revoked'": 'False', "'locked'": 'False', "'maxfail'": '10L', "'count'": '0L', "'pin_seed'": "u'7123cc58efd918855b90c36167f58e22'", "'description'": "u''", "'user_pin_iv'": "u''", "'user_pin'": "u''", "'rollout_state'": "u'enrolled'", "'failcount'": '7L', "'_sa_instance_state'": '<sqlalchemy.orm.state.InstanceState object at 0x7f6244878390>', "'id'": '73L', "'sync_window'": '1000L', "'key_iv'": "u'f9c4ebd0c0962bb59a48859a0cff086f'", "'tokentype'": "u'push'"}>,) and keywords {}
[2019-04-19 17:23:45,533][13681][140060348065536][DEBUG][privacyidea.lib.tokenclass:185] Entering __init__ with arguments (<<class 'privacyidea.lib.tokens.pushtoken.PushTokenClass'> {}>, <<class 'privacyidea.models.Token'> {"'active'": 'True', "'count_window'": '10L', "'key_enc'": "u'57d69dad477421c622038111e9f1be13b59b7a3d69e739c410eed271610aeca99bbb0eac1018ab696e274c16a8c9664d03dbe7c6648cf12d88dd43fbe2c66bf7bd5cf84dcf264059d34b37599396a70d2622a41a67418934926297bc9b29bcb4'", "'pin_hash'": "u'a2692bc05deb2b8eea1cddb1d6280287d7f83a765374ee0507b675ea0fd70691'", "'so_pin'": "u''", "'otplen'": '6L', "'so_pin_iv'": "u''", "'serial'": "u'PIPU0000D2CC'", "'revoked'": 'False', "'locked'": 'False', "'maxfail'": '10L', "'count'": '0L', "'pin_seed'": "u'7123cc58efd918855b90c36167f58e22'", "'description'": "u''", "'user_pin_iv'": "u''", "'user_pin'": "u''", "'rollout_state'": "u'enrolled'", "'failcount'": '7L', "'_sa_instance_state'": '<sqlalchemy.orm.state.InstanceState object at 0x7f6244878390>', "'id'": '73L', "'sync_window'": '1000L', "'key_iv'": "u'f9c4ebd0c0962bb59a48859a0cff086f'", "'tokentype'": "u'push'"}>) and keywords {}
[2019-04-19 17:23:45,533][13681][140060348065536][DEBUG][privacyidea.lib.tokenclass:197] Exiting __init__ with result None
[2019-04-19 17:23:45,534][13681][140060348065536][DEBUG][privacyidea.lib.token:197] Exiting create_tokenclass_object with result <<class 'privacyidea.lib.tokens.pushtoken.PushTokenClass'> {"'token'": '<<class \'privacyidea.models.Token\'> {"\'active\'": \'True\', "\'count_window\'": \'10L\', "\'key_enc\'": "u\'57d69dad477421c622038111e9f1be13b59b7a3d69e739c410eed271610aeca99bbb0eac1018ab696e274c16a8c9664d03dbe7c6648cf12d88dd43fbe2c66bf7bd5cf84dcf264059d34b37599396a70d2622a41a67418934926297bc9b29bcb4\'", "\'pin_hash\'": "u\'a2692bc05deb2b8eea1cddb1d6280287d7f83a765374ee0507b675ea0fd70691\'", "\'so_pin\'": "u\'\'", "\'otplen\'": \'6L\', "\'so_pin_iv\'": "u\'\'", "\'serial\'": "u\'PIPU0000D2CC\'", "\'revoked\'": \'False\', "\'locked\'": \'False\', "\'maxfail\'": \'10L\', "\'count\'": \'0L\', "\'pin_seed\'": "u\'7123cc58efd918855b90c36167f58e22\'", "\'description\'": "u\'\'", "\'user_pin_iv\'": "u\'\'", "\'user_pin\'": "u\'\'", "\'rollout_state\'": "u\'enrolled\'", "\'failcount\'": \'7L\', "\'_sa_instance_state\'": \'<sqlalchemy.orm.state.InstanceState object at 0x7f6244878390>\', "\'id\'": \'73L\', "\'sync_window\'": \'1000L\', "\'key_iv\'": "u\'f9c4ebd0c0962bb59a48859a0cff086f\'", "\'tokentype\'": "u\'push\'"}>', "'mode'": "['challenge']", "'init_details'": '{}', "'auth_details'": '{}', "'type'": "u'push'", "'hKeyRequired'": 'False'}>
[2019-04-19 17:23:45,534][13681][140060348065536][DEBUG][privacyidea.lib.token:197] Exiting get_tokens with result [<<class 'privacyidea.lib.tokens.pushtoken.PushTokenClass'> {"'token'": '<<class \'privacyidea.models.Token\'> {"\'active\'": \'True\', "\'count_window\'": \'10L\', "\'key_enc\'": "u\'57d69dad477421c622038111e9f1be13b59b7a3d69e739c410eed271610aeca99bbb0eac1018ab696e274c16a8c9664d03dbe7c6648cf12d88dd43fbe2c66bf7bd5cf84dcf264059d34b37599396a70d2622a41a67418934926297bc9b29bcb4\'", "\'pin_hash\'": "u\'a2692bc05deb2b8eea1cddb1d6280287d7f83a765374ee0507b675ea0fd70691\'", "\'so_pin\'": "u\'\'", "\'otplen\'": \'6L\', "\'so_pin_iv\'": "u\'\'", "\'serial\'": "u\'PIPU0000D2CC\'", "\'revoked\'": \'False\', "\'locked\'": \'False\', "\'maxfail\'": \'10L\', "\'count\'": \'0L\', "\'pin_seed\'": "u\'7123cc58efd918855b90c36167f58e22\'", "\'description\'": "u\'\'", "\'user_pin_iv\'": "u\'\'", "\'user_pin\'": "u\'\'", "\'rollout_state\'": "u\'enrolled\'", "\'failcount\'": \'7L\', "\'_sa_instance_state\'": \'<sqlalchemy.orm.state.InstanceState object at 0x7f6244878390>\', "\'id\'": \'73L\', "\'sync_window\'": \'1000L\', "\'key_iv\'": "u\'f9c4ebd0c0962bb59a48859a0cff086f\'", "\'tokentype\'": "u\'push\'"}>', "'mode'": "['challenge']", "'init_details'": '{}', "'auth_details'": '{}', "'type'": "u'push'", "'hKeyRequired'": 'False'}>]
[2019-04-19 17:23:45,536][13681][140060348065536][DEBUG][privacyidea.lib.challenge:185] Entering get_challenges with arguments () and keywords {'serial': u'PIPU0000D2CC', 'challenge': u'7HLNODEWWH4BYCTYYLO7JDTFBPDYXKFG'}
[2019-04-19 17:23:45,538][13681][140060348065536][DEBUG][privacyidea.lib.challenge:197] Exiting get_challenges with result [<Challenge 1151>]
[2019-04-19 17:23:45,540][13681][140060348065536][DEBUG][privacyidea.lib.user:185] Entering User with arguments () and keywords {'login': '', 'realm': '', 'resolver': None}
[2019-04-19 17:23:45,541][13681][140060348065536][DEBUG][privacyidea.lib.user:197] Exiting User with result <empty user>
[2019-04-19 17:23:45,541][13681][140060348065536][DEBUG][privacyidea.lib.user:197] Exiting get_user_from_param with result <empty user>
[2019-04-19 17:23:45,541][13681][140060348065536][DEBUG][privacyidea.lib.auditmodules.base:185] Entering log with arguments (<privacyidea.lib.auditmodules.sqlaudit.Audit object at 0x7f6244908790>, {'token_type': u'push', 'serial': u'PIPU0000D2CC', 'realm': '', 'user': '', 'success': 1}) and keywords {}
[2019-04-19 17:23:45,541][13681][140060348065536][DEBUG][privacyidea.lib.auditmodules.base:197] Exiting log with result None
[2019-04-19 17:23:45,542][13681][140060348065536][DEBUG][privacyidea.api.ttype:197] Exiting token with result <Response 138 bytes [200 OK]>
[2019-04-19 17:23:45,565][13681][140060348065536][DEBUG][privacyidea.api.lib.utils:219] Can not get param: No JSON object could be decoded
[2019-04-19 17:23:45,568][13681][140060348065536][DEBUG][privacyidea.api.before_after:88] End handling of request u'/ttype/push?'

@droo, did you create a “fake” android app in Firebase to get the JSON file and necessary settings to configure the SMS Gateway, or do you have an actual app you are developing that you used?

This is a bug in privacyIDEA with non-sqlite DBs we discovered this week:

You need to create a fake one. No need to programm your own app.
We choose this way, so every privacyIDEA installation can have its own separated firebase project even when using the privacyIDEA Authenticator!
You know… privacy! :wink:

OK, that’s what I thought, but I wasn’t sure.

So it sounds like the only step I got wrong was I was using the iOS version, which doesn’t support the push notifications yet. I’m going to set up Bluestacks and beta test the Android app, thanks for all the help!

Awesome! Adding the fixed that issue for me and I now have a functioning RADIUS plugin that works with push!

However I ran into an issue with the Android app. In this case it was a network connectivity problem where the phone was unable to reach my /ttype/push URL during the approve. It appears the app does not notify the user of any connectivity errors and/or allow a retry. It was failing silently and took me a while to diagnose.

In the future if anything related to the app is found while in beta, would you like it reported? If so, should it be reported on the Android app github?

Yes, please add an issue at github! This is easier for us to keep track.

Issue opened. I also have made a pull request which added push token support to the FreeRADIUS plugin in case it hadn’t been worked on yet. I followed a similar process to how Twilio’s OneTouch push token functions.

@cornelinux, I was able to get a hold of an Android unit for testing. I was able to set up the Push functionality, and enroll a token. However, when I attempt to authenticate, it seems like the request is missing some credential information. Using the API test, I receive this error:

detail": null, “version”: “privacyIDEA 3.0”, “result”: {“status”: false, “error”: {“message”: “(‘Unexpected credentials type’, None, ‘Expected’, ‘service_account’)”, “code”: -500}}

The same error is posted in the audit. Interestingly, the column that lists the token serial is blank.

Am I missing something?

Edit: In Debug mode, this jumped out at me:

[privacyidea.api.lib.utils:219] Can not get param: No JSON object could be decoded

I’ve verified the JSON file is where I specified in the config. I have tested with the following ownership: