SMS token and smsautosend

Hi,
we test PrivacyIdea system as replacement of SecurEnvoy application which is used as 2F authentication for Microsoft TMG. TMG authenticates username/password against domain accounts and Radius client part of TMG authenticates username/OTP against SecurEnvoy/PrivacyIdea. SecurEnvoy uses so called “SMS Preload”. When you try to authenticate (ok/fail) you receive new token over sms (everytime).

There is similar function in PrivacyIdea. You can set “smsautosend” in authentication policy. Unfortunately it works only for successfull authentication and it doesn’t generate sms during SMS token enrollment. Our setup has authentication policy {“otppin”: “none”, “smsautosend”: true }. So you never receives SMS during enrollment and you never authenticates user because TMG “steels” user/pass credentials.

I tried Events but there is no such option on sending SMS token on auth failure. You can receive SMS with defined message but no token.

I made some updates to code of smstoken.py to fix it. I added new option smsonfail which generates new token. It’s not very nice. Is there any option to handle new SMS token on every request success or fail and during SMS token enrollment?

Thanks for help.

To cut a long story short: No.

You need some kind of trigger, to send an SMS.
Currently SMS can be triggered via a successful authentication at /validate/check or by the administrator via /validate/triggerchallenge. But the later is not accessable via RADIUS.

In my opinion there might be other options to investigate (change your authentication scheme, adapt code…) which we might discuss. After all we are also providing consulting services for these special way of integration.

Well - from a security standpoint I would recommend using a decent 2nd factor anyway! :wink:

Kind regards
Cornelius

You are right, Cornelius, that this is not the best solution and collegues work on TMG replacement. But so far this our only option. :frowning:
So we use that extra code in smstoken.py. Should I post that update here as well?

BTW. small off-topic. We have small update for Checkpoint / PrivacyIdea integration in LDAPresolver - parsing of groups which are part of memberOf LDAP values. It’s used for group assignments in Checkpoint remote access client.
Martin

So we use that extra code in smstoken.py. Should I post that update here as well?

This might help others.

BTW. small off-topic. We have small update for Checkpoint / PrivacyIdea integration in LDAPresolver - parsing of groups which are part of memberOf LDAP values. It’s used for group assignments in Checkpoint remote access client.

I think this would not be necessary.

Please note AGPLv3. If your privacyIDEA installation is accessable from the internet, you need to publish your changes.

Kind regards
Cornelius

smstoken.py updates for new sms token created and sent everytime you try to login with sms token both valid and invalid

-new SMS action created - smsonfail

class SMSACTION(object):
SMSTEXT = "smstext"
SMSAUTO = "smsautosend"
SMSONFAIL = “smsonfail”

-function def get_class_info(…, add web GUI option
’policy’: {
SCOPE.AUTH: {
SMSACTION.SMSTEXT: {
‘type’: ‘str’,
‘desc’: _(‘The text that will be send via SMS for’
’ an SMS token. Use and '
‘as parameters.’)},
SMSACTION.SMSAUTO: {
‘type’: ‘bool’,
‘desc’: _('If set, a new SMS OTP will be sent '
'after successful authentication with '
‘one SMS OTP.’)},
SMSACTION.SMSONFAIL: {
‘type’: ‘bool’,
‘desc’: _('If set, a new SMS OTP will be sent '
'after any unsuccessful authentication with '
‘one SMS OTP.’)},
}

-new handle function created def _get_sms_onfail(options): , it’s copy of _get_auto_sms(options), just checking different SMSACTION. It would be better to join both functions with SMSACTION parameter but not today.

def _get_sms_onfail(options):
    """
    This returns the SMSONFAIL setting.

    :param options: contains user and g object.
    :optins type: dict
    :return: True if an SMS should be sent automatically on failure
    :rtype: bool
    """
    smsonfail = False
    g = options.get("g")
    user_object = options.get("user")
    username = None
    realm = None
    if user_object:
        username = user_object.login
        realm = user_object.realm
    if g:
        clientip = options.get("clientip")
        policy_object = g.policy_object
        smsonfailpol = policy_object.\
            get_policies(action=SMSACTION.SMSONFAIL,
                         scope=SCOPE.AUTH,
                         realm=realm,
                         user=username,
                         client=clientip, active=True)
        smsonfail = len(smsonfailpol) >= 1

    return smsonfail

-last step is update of function def check_otp(self, anOtpVal, counter=None, window=None, options=None) and activate new option check.

    if ret >= 0 and self._get_auto_sms(options):
        message = self._get_sms_text(options)
        self.inc_otp_counter(ret, reset=False)
        success, message = self._send_sms(message=message)
        log.debug("AutoSMS: send new SMS: {0!s}".format(success))
        log.debug("AutoSMS: {0!r}".format(message))
    elif ret == -1 and self._get_sms_onfail(options):
        success, message, transId, attr = self.create_challenge(options = options)
        log.debug("OnfailSMS: send new SMS: {0!s}".format(success))
        log.debug("OnfailSMS: {0!r}".format(message))

-so SMS is sent when you authenticate successfully (former code) and there is addon with new option to send SMS with new OTP code on authetication failure. It make sense to use smsonfail option only with auto_sms option.

Cornelius, should I send that LDAPresolver update and necessary changes to you or should I create some howto and include code?

If you think this should be incorporated upstream, you are welcome to either open an issue at github or open the issue and also create a pull request.

I am curious, what you did in regards to the LDAP. I think this would also be possible with resolver RADIUS mappings.
Anyway, it might create some nice ideas about group handling.

Hi, can anyone tell me if the above 3 sections of code are updates to the one file smstoken.py or are there other files where the code is applied.

Thanks

To my knowledge it has not.