1.9. SMS Provider for SMS OTP Tokens / Mobile TANs#

Starting with version 2.2 LinOTP also supports sending one time passwords via SMS. In this case an SMS OTP token needs to be created. Internally this token is a HMAC token. The token object gets a mobile phone number and this token is assigned to the user.

Tip

For a convenient rollout of SMS token from the command line you can use linotp-enroll-smstoken

Tip

It is possible to automatically enroll SMS token when a user without token logs in first time: https://www.linotp.org/howtos/howto-autoenrollment.html

1.9.1. Overview#

Triggering SMS#

When calling the API /validate/smspin the user is authenticated by the username and OTP PIN. The sending of an SMS with a OTP value is triggered. This OTP value is valid for a configurable amount of time.

Another possibility of triggering SMS is when the user authenticates with username and PIN. When username and PIN are passed to the authentication URL like /validate/check or /validate/simplecheck, the user is rejected, but, if the PIN is correct, the sending of an SMS is triggered.

Note

SMS can be easily used in conjunction with the RADIUS protocol. The user first needs to authenticate at the RADIUS client with username and PIN. The user will be rejected. After that an SMS will be sent to the user. Then the user needs to authenticate with username and PIN+OTP (from the SMS) and the user will be successfully authenticated.

Starting with version 2.6 SMS can also be triggered using the new challenge-response mechanism described in Challenge Response. When using challenge-response only the OTP has to be provided by the user in the second authentication step instead of PIN+OTP.

Tip

LinOTP 2.10.1 introduced the possibility to change the challenge message. Details can be found here: Configure Challenge Message.

Configuration#

Starting with LinOTP 2.9 more than one SMS Provider can be configured. The configuration moved from “LinOTP Config” –> “Token Config” –> “SMS OTP Token” to an extra entry “LinOTP Config” –> “Provider Config” –> “SMS Provider Config” where the providers can be created, edited and deleted.


../_images/webui_drop_down_menu_provider1.png

New configuration menu for multiple SMS/Email Providers#


Note

If the system was updated to LinOTP version 2.9+ a SMS Provider previously configured is automatically transfered to the new configuration environment and named “imported_default”.

../_images/webui_sms_provider_imported_default.png

Imported SMS Provider from previous configuration#

Set up as many SMS Provider as required. Which one will be used to deliver the SMS can be configured by policies. If no policy exists or no existing policy applies the SMS Provider marked as “(Default)” will be used.

../_images/webui_popup_multiple_sms_provider_populated.png

Multiple SMS Provider configured#

Policy to choose SMS Provider#

  • Policy name: this is a unique name of the policy.

  • Scope: You need to set this to authentication.

  • Action: sms_provider=<NAME_OF_ONE_OF_THE_CONFIGURED_PROVIDERS>

  • User: This is a comma separated list of usernames or resolver names. Please see Users in policies.

  • Realm: Enter the name of the realm.

  • Client: This is a list of IP addresses or subnets this policy is valid for.

1.9.2. Configure SMS Provider#

The actual configuration of a SMS Providers:


../_images/webui_smsprovider_configuration1.png

An SMS Provider is a LinOTP module, that defines how SMS are sent.

These four values can be configured in the server configuration:

Name

Name of the SMS Provider as to be used in the policies.

Class

The SMS Provider module to be used for sending SMS. At the moment LinOTP comes with five different kinds of SMS Provider classes:

  • HttpSMSProvider

  • SmtpSMSProvider

  • SMPPSMSProvider

  • RestSMSProvider

  • DeviceSMSProvider

Their indidual configuration is described below.

Config

The configuration parameter for the SMS Provider Class.

Timeout

This configuration key holds the time that an OTP value that was sent via SMS is valid. The number is interpreted in seconds. The default value is 120 e.g. 2 minutes. That means that after a user requested a SMS OTP he will be able to use this OTP value within the next 2 minutes. If the SMS arrives later or the user will not use this OTP value within 2 minutes, it will not be valid anymore.

Generic Options#

Some configuration options apply to all four SMS Provider modules in the section “Config”:

MSISDN [optional]

Normalizes phone number to be MSISDN compliant. All characters except digits are removed. A leading prefix (e.g. +) will be preserved.

"MSISDN":"True"
SUPPRESS_PREFIX [optional]

Can be used to cut of unwanted leading characters as the + or a country code like +49.

"SUPPRESS_PREFIX":"+49"

Overview SMS Provider modules#

HttpSMSProvider#

In this case LinOTP uses public available SMS gateways. There are providers like clickatell.com or smsout.de that can create an SMS by calling a certain well formed URL. The LinOTP HttpSMSProvider module is designed very flexible, so that every SMS Gateway that either uses HTTP GET or HTTP POST request can be used to send SMS.

You need to enter smsprovider.HttpSMSProvider.HttpSMSProvider as Class.

SmtpSMSProvider#

LinOTP can also send SMS via SMTP-Gateways. This means an email is sent to a fixed email address with a certain subject and body. This is interpreted and the gateway sends an SMS to the phone number that is contained either in the subject or the body.

You need to enter smsprovider.SmtpSMSProvider.SmtpSMSProvider as Class.

SMPPSMSProvider#

Starting with version 2.8.1 LinOTP can send SMS via SMPP protocol as used by many large scale providers for SMS services.

You need to enter smsprovider.SMPPSMSProvider.SMPPSMSProvider as Class.

Note

The SMPP SMS Provider requires a library not directly available in some distributions - python-smpp. The library can e.g. be installed via pip.

RestSMSProvider#

Starting with LinOTP 2.10.0.5 LinOTP can submit SMS via the REST API of public available SMS gateways (like Swisscom).

You need to enter smsprovider.RestSMSProvider as Class.

DeviceSMSProvider#

LinOTP also comes with an SMS Provider module to enable the LinOTP server to send SMS itself. This can be achieved by connecting an appropriate phone to the LinOTP machine. The SMS are then send via this phone directly.

You need to enter smsprovider.DeviceSMSProvider.DeviceSMSProvider as Class.

1.9.3. SMSProviderConfig#

Depending on the type of the SMS Provider, this configuration key stores different values.

HttpSMSProvider#

For HttpSMSProvider this is:

Class:

smsprovider.HttpSMSProvider.HttpSMSProvider

Config:

{"URL":"http://smsgateway.com/sms_send_api.cgi",
 "PARAMETER": {
     "from":"0170111111",
     "password":"yoursecret",
     "sender":"name",
     "account":"company_ltd"
  },
 "SMS_TEXT_KEY":"text",
 "SMS_PHONENUMBER_KEY":"destination",
 "HTTP_Method":"GET",
 "PROXY":"http://username:password@your-proxy:8080",
 "RETURN_SUCCESS":"ID"
}

Parameter:

The URL holds the link to the API of the SMS Gateway. The PARAMETER can hold any number of fixed parameters, that allow you to use this SMS Gateway to send SMS. Usually this will at least be something like an account name and a password. The other parameters are either functional options like GET (to manipulate the request or configure the expected return values) or mappings for the SMS Provider specific parameters like the destination number. These are needed by LinOTP to know where to put certain necessary information in the request.

SMS_TEXT_KEY [mapping]

denotes, which parameter in the URL will hold the SMS text itself.

If the Provider requires the content of the SMS to be delivered in a parameter “message”:

"SMS_TEXT_KEY":"message"

The URL will be like this: https://PROVIDER?OTHER_PARAMETERS&message=”This is your OTP: 372873”

SMS_PHONENUMBER_KEY [mapping]

denotes, which parameter in the URL will be used to pass the mobile phone number to which the SMS should be sent.

If the Provider requires the recipient number in a parameter “phone”:

"SMS_PHONENUMBER_KEY":"phone"

The URL will be like this: https://PROVIDER?OTHER_PARAMETERS&phone=”+49123456789”

HTTP_Method [functional/optional]

denotes, if the API of the SMS Gateway should be used with HTTP GET or HTTP POST request.

USERNAME PASSWORD [functional/optional]

to support HTTP Basic Authentication the parameters USERNAME and PASSWORD can be set.

PREFERRED_HTTPLIB [functional/optional]

the internally used HTTP library. There are three valid options:

  • requests [default]

  • urllib

  • httplib

In rare cases it might be necessary to try a different library than the default. Please look at this configuration only if you are out of other options.

PROXY [functional/optional]

is an optional parameter that needs to be set when the LinOTP server accesses the internet via a proxy. This can be either HTTP or HTTPS and you may specify a username for authenticating to the proxy server.

RETURN_SUCCESS_REGEX [functional/optional]

matches the reply of the SMS gateway to indicate successful sending of the SMS with a regular expression.

The message was send successfully if the SMS server answers with a string starting with “ok”:

"RETURN_SUCCESS":"ok"
RETURN_SUCCESS_REGEX [functional/optional]

matches the reply of the SMS gateway to indicate successful sending of the SMS with a regular expression.

RETURN_SUCCESS [functional/optional]

matches the reply of the SMS Gateway to indicate successful sending of the SMS. The first characters of the reply are compared to this definition.

The message was send successfully if the SMS server answers with a string starting with “ok”:

"RETURN_SUCCESS":"ok"
RETURN_SUCCESS_REGEX [functional/optional]

matches the reply of the SMS gateway to indicate successful sending of the SMS with a regular expression.

The message was send successfully if the SMS server answers with a string containing somewhere “result:0” or “success”:

"RETURN_SUCCESS_REGEX":"(result:0|success)"
RETURN_FAIL [functional/optional]

matches the reply of the SMS Gateway to indicate the failed sending of the SMS. The first characters of the reply are compared to this definition. The RETURN_FAIL is only evaluated if the RETURN_SUCCESS is not defined.

RETURN_FAIL_REGEX [functional/option]

matches the reply of the SMS Gateway to indicate the failed sending of the SMS with a regular expression.

Note

At least one RETURN_ parameter must but configured. We recommend to configure only one of the RETURN_ parameters to avoid confusions.

This is an example configuration for the clickatell SMS Gateway:

{ "URL" : "http://api.clickatell.com/http/sendmsg",
 "PARAMETER" : {
 "user":"username",
 "password":"askme",
 "api_id":"12980436"
  },
  "SMS_TEXT_KEY":"text",
  "SMS_PHONENUMBER_KEY":"to",
  "HTTP_Method":"GET",
  "PROXY" : "http://user:pass@192.168.100.250:8080",
  "RETURN_SUCCESS" : "ID"
 }

Note

You need to use double quotes and not single quotes! Using single quotes will result in an error and sending SMS will not be possible.

SmtpSMSProvider#

The configuration for the SmtpSMSProvider looks like this:

Class:

smsprovider.SmtpSMSProvider.SmtpSMSProvider

Config:

{ "mailserver" : "smtp.yourdomain.com",
  "mailsender" : "linotp@yourdomain.com",
  "mailuser" : "account-to-login-to-smtp-server",
  "mailpassword" : "somesecret",
  "mailto": "mailadress@smstp-gateway",
  "subject" : "<phone>",
  "body" : "This is your OTP-value: <otp>"
}

Parameter:

The parameters mailuser and mailpassword are optional. The tag <phone> needs to be put where the smtp gateway expects it. This can either be the subject, the body or the mailto. The <phone> tag will be replaced with the mobile phone number of the user. The tag <otp> will be replaced by the generated OTP value. The tag can be places in the subject or in the body. The e-mail is submitted to port 25 by default.

start_tls [functional/optional]

use STARTTLS to secure transmission of e-mails to port 587. Defaults to “False”.

Enable STARTTLS:

"start_tls":"True"
certfile [functional / required if “start_tls”]

the certificate of the client.

"certfile":"/etc/ssl/certs/smtp_client.crt"
keyfile [functional / required if “start_tls”]

client key.

"certfile":"/etc/ssl/private/smtp_client.key"
mailserver_port [functional/optional]

Set the port of the mail server (25|587|465|integer).

Use port 587 for submitting the email.

"mailserver_port":"587"
use_ssl [functional/optional]

Use port 465 to establish a SSL secured connection. Defaults to “False”.

Enable SSL communication via port 465.

"user_ssl":"True"

SMPPSMSProvider#

The configuration for the SmtpSMSProvider looks like this:

Class:

smsprovider.SMPPSMSProvider.SMPPSMSProvider

Config:

{ "server":"smpp-server",
  "port":"smmp-port",
  "system_id":"login-name",
  "system_type":"",
  "password":"password",
  "source_addr":"displayed-source-address",
  "source_addr_npi":"0",
  "source_addr_ton":"5",
}

Parameter:

server

IP or hostname of the SMPP Gateway.

port

Destination port at the SMPP Gateway - defaults to 5100.

system_id

Identifies the ESME system requesting to bind s a transmitter with the MC. This field must contain the Short ID (shortcode).

password

Connection password.

system_type [optional]

The service_type parameter can be used to indicate the SMS Application service associated with the message. Specifying the service_type allows the ESME to avail of enhanced messaging services such as “replace by service_type” or to control the teleservice used on the air interface. Can be left empty.

source_addr

Source address. Can be a string instead of a number - this requires to configure source_addr_npi and source_addr_ton to be configured accordingly.

source_addr_npi [optional]

Numbering Plan Indicator for source address. Set this to “0” if your source_address contains anything else than numbers.

source_addr_ton [optional]

Type of number of the ESME source address. Set this to “5” if your source_address contains anything else than numbers.

RestSMSProvider#

This SMSProvider has been introduced with LinOTP 2.10.1. The configuration for the RestSMSProvider looks like this:

Class:

smsprovider.RestSMSProvider

Config:

{ "URL":"https://SMSPROVIDERFQDN",
 "PAYLOAD":{
      JSON-REST-DATA
  },
 "HEADERS": {
      REQUIRED-HEADER-DATA
     },
 "SMS_TEXT_KEY":"text",
 "SMS_PHONENUMBER_KEY":"to",
 "USERNAME":"NAME"
 "PASSWORD":"SECRET"
}

Parameter:

The URL [required]

holds the link to the API of the SMS Gateway.

"URL": "https://api.clxcommunications.com/xms/v1/1234567/batches",
PAYLOAD [required]

contains the JSON-Payload as it should be send to the SMS Gateway.

"PAYLOAD": {
        "to": ["<phone>"],
        "from": "123456789",
        "body":"Your OTP is: <message>"
        },
HEADERS [optional]

this holds header information e.g. required for authentication.

"HEADERS": {
      "Authorization": "Bearer d2b5acb29a103d7e7a98ff",
      "Content-Type": "application/json"
      },
SMS_TEXT_KEY [mapping]

defines a placeholder for the message which can be referenced at the required position in the JSON payload.

"SMS_TEXT_KEY":"message"

This key can be referenced in the JSON part as <message> in the required parameter.

SMS_PHONENUMBER_KEY [mapping]

defines a placeholder for the phone nubmer which can be referrenced at the required position in the JSON payload.

"SMS_PHONENUMBER_KEY":"phone"

This key can be referenced in the JSON part as <phone> in the required parameter.

USERNAME PASSWORD [functional/optional]

to support HTTP Basic Authentication the parameters USERNAME and PASSWORD can be set.

"USERNAME":"customernumber"
"PASSWORD":"secret"

AUTHENTICATION [optional]

Sets the type of authentication. Possible values are BASIC and DIGEST. Defaults to BASIC

"AUTHENTICATION":"DIGEST"
PROXY [functional/optional]

is an optional parameter that needs to be set when the LinOTP server accesses the internet via a proxy. This can be either HTTP or HTTPS and you may specify a username for authenticating to the proxy server.

"PROXY" : { "http": "http://10.10.1.10:3128", "https": "http://10.10.1.10:1080", }

or

"PROXY" : { 'http': 'socks5://user:pass@host:port', 'https': 'socks5://user:pass@host:port' }

TIMEOUT [optional]

Configures the connection timeout and the wait time until the request is finished. Defaults to (3,30). Which means LinOTP will try to contact the server for three seconds. If the server answers there will be another 30 seconds for completing the submission of the SMS until the connection is closed by LinOTP.

"TIMEOUT":"(5,20)"

CLIENT_CERTIFICATE_FILE [optional]

A certificate file can be referenced which is then used to authenticate against the SMS Gateway.

"CLIENT_CERTIFICATE_FILE":"/etc/linotp2/sms_client_certificate.pem"

SERVER_CERTIFICATE [optional]

This contains the ROOT-CA to validate the identity of the SMS Gateway. If no server certificate is provided any certificate will be accepted in order to ensure encrypted communication.

"SERVER_CERTIFICATE":"/etc/linotp2/root_ca_bundle_sms_gateway.pem"

This is an example configuration for the Swisscom SMS Gateway:

{"URL":"https://messagingproxy.swisscom.ch:4300/rest/1.0.0/submit_sm/123456",
"PAYLOAD": {
  "destination_addr": "<phone>",
  "source_addr":"123456",
  "short_message": "Your OTP is: <message>",
  "source_addr_ton":6,
  "source_addr_npi":0,
  "dest_addr_ton":1,
  "dest_addr_npi":1},
"SMS_TEXT_KEY":"short_message",
"SMS_PHONENUMBER_KEY":"destination_addr",
"PASSWORD": "SECRET",
"USERNAME":"123456"
}

This is an example configuration for the CLX Communications SMS Gateway:

{"URL": "https://api.clxcommunications.com/xms/v1/customer27421/batches",
"PAYLOAD": {
"to": ["<phone>"],
"from": "123456789",
"body":"Your OTP is: <message>"
},
"HEADERS": {
"Authorization": "Bearer e215354ab28041daa3cbf2f11cbd1257",
"Content-Type": "application/json"
},
"SMS_TEXT_KEY": "body",
"SMS_PHONENUMBER_KEY": "to"
}

Note

You need to use double quotes and not single quotes! Using single quotes will result in an error and sending SMS will not be possible.

SMPPSMSProvider#

The configuration for the SmtpSMSProvider looks like this:

Class:

smsprovider.SMPPSMSProvider.SMPPSMSProvider

Config:

{ "server":"smpp-server",
  "port":"smmp-port",
  "system_id":"login-name",
  "system_type":"",
  "password":"password",
  "source_addr":"displayed-source-address",
  "source_addr_npi":"0",
  "source_addr_ton":"5",
}
server

IP or hostname of the SMPP Gateway.

port

Destination port at the SMPP Gateway - defaults to 5100.

system_id

Identifies the ESME system requesting to bind s a transmitter with the MC. This field must contain the Short ID (shortcode).

password

Connection password.

system_type [optional]

The service_type parameter can be used to indicate the SMS Application service associated with the message. Specifying the service_type allows the ESME to avail of enhanced messaging services such as “replace by service_type” or to control the teleservice used on the air interface. Can be left empty.

source_addr

Source address. Can be a string instead of a number - this requires to configure source_addr_npi and source_addr_ton to be configured accordingly.

source_addr_npi [optional]

Numbering Plan Indicator for source address. Set this to “0” if your source_address contains anything else than numbers.

source_addr_ton [optional]

Type of number of the ESME source address. Set this to “5” if your source_address contains anything else than numbers.

DeviceSMSProvider#

Class:

smsprovider.DeviceSMSProvider.DeviceSMSProvider

The DeviceSMSProvider module uses the tool gnokii [1] to send SMS. The configuration parameter looks like this:

Config:

{"CONFIGFILE":"/etc/linotp2/gnokiirc"}

where the value of CONFIGFILE reflects the location of the gnokiirc configuration file. A valid configuration file will look like this:

[global]
model = AT
port = /dev/ttyACM1
connection = serial

Note

  1. The LinOTP service account needs to have write access on the device defined

    in the port variable. In this case on /dev/ttyACM1. Usually this can be achieved by adding the LinOTP service account linotp to the group dialout.

  2. There were problems reported using gnokii version 0.6.28. It is recommended

    to use version 0.6.29.