API definition¶
Attention
This is the definition of the raw API. Chances are good that you can use our software development kit (SDK) written in PHP either on an external webserver or the preinstalled version on our custom webserver on an IACBOX. It hides away the low-level details you usually don’t need to implement yourself.
Contents
General¶
The Login-API uses indirect communication over HTTP redirects. All information is passed as URL GET parameters, so there’s no need for the external webserver to access the IACBOX directly and no port forwardings and no VPN tunnels are needed.
Protocol version¶
API versions are always in the format <major>.<minor>
and should be interpreted like
- two different major versions are maybe incompatible with each other
- having the same major but different minor version there is a compatible set of data fields and options based on the older version. Minor version updates just add but don’t remove data fields and options. Upgrading within the same major release will be safe.
Where to start?¶
- It’s very important to understand the communication flow, so take a look at the flow charts below to understand the redirects.
- Look at our PHP SDK (Software Development Kit) for a production ready implementation which is designed to get you up and running with just a few modifications. Therefore you need only little development skills to have a working implementation or test setup. Of course you are free to develop your own login page in any language with any framework you want.
- Really read this documentation!
Supported logon types¶
The LoginAPI supports multiple logon methods of the IACBOX but not all. The supported methods can be used all at the same time. Here is the complete list of supported types:
- Type to: Take the client online without any authentication (useful if you do the authentication on your external webserver yourself, or the user does not need to authenticate).
- Type cred: Normal ticket logon with username and password, local users (Navigate to Ticket/Users) and external authentication (Radius, LDAP, SQL DB, …)
- Type pms: Login with Roomnumber (mandatory) and other defined PMS data fields like birthday, arrivalday, …
- Type create: Create a ticket by sending a ticket template ID. The new SDK uses this for the local PMS version to create tickets based on the template but it could be used to use any authentication method.
- Type free: Create a with the free template. The big advantage of the “free” settings is the interval functionality like (30min per day) which can’t be done with just creating a free ticket with type to.
Communication flow - general version¶
In the following section the communication flows is described step by step. This document covers all non-PMS login types (type to (take online) and type cred (credentials), type free (free logon), type create (used for payed tickets) which is a more generic approach.
The PMS version is covered later in this document.
- The client is in state offline and wants to show an arbitrary page. Please note that it works only flawless if this is an unecrypted HTTP call, SSL/TLS works only if the “Redirect offline SSL Traffic” is active (which has other performance/load implications!)
- The IACBOX catches this connection, creates a new unique ID for this client and sends an HTTP 302 (moved temporary) redirect to the client. The redirect URL consists of the specified external landing page and additional parameters which contain data fields like IP/MACaddress, Vlan ID, …
- The client calls the redirect (1) URL on the external webserver.
- On your webserver a session (cookie based) has to be created to remember the client ID for this browser. The webserver responses with the login page (and the session cookie).
- The enduser fills out the login form and submits the form. A HTTP POST will be sent to the webserver.
- If there was an error on your side then the user gets your login page again and starts again with step 5. On success there are two basic scenarios depending on if you do the authentication at your webserver yourself or not
- type = to (take online): your webserver authenticates the client login data against its backend and sends the needed parameters to make the IACBOX generate a ticket and set this client online.
- type = cred (credentials): or you want the IACBOX to do the authentication. Currently supported logon types are normal tickets, local users, extauth modules. The redirect has to contain the user credentials with logintype to the IACBOX. The second redirect is made to the IACBOX which contains the needed parameters to either set this client online or try to authenticate it there.
- The client calls the redirect (2) URL.
- The IACBOX now takes this client online (case 6.1) or tries to authenticate it (case 6.2). If you wish another callback on success or the login failed, another redirect (3) is made. Otherwise the IACBOX landing page is shown with the success/error message.
- If a callback was configured then the client calls again the external webserver.
- Your landing page can now visualize the state success/error and display any other information.
Outgoing redirects (IACBOX/ext or loc. webserver)¶
The outgoing URL parameters are all setable by yourself. The default values match our SDK implementation and are identical with the parameters for incoming requests. The URL parameter names (default: lapi and si) are changeable to also support REST like URLs instead of the query style. You can change this parameters only for outgoing requests - incoming always need the query style format. Leave the default parameter names unchanged if you want to be compatible with the SDK.
Example with our default parameter names:
https://your.domain.com/path/login?lapi=vLQT8uyK1…gNIm4_Ec0w&si=Ezo5zswu…OxaNCepI
Allowed URL placeholders in outgoing redirects¶
Hint
- Redirect: You find the redirect numbers in the flow chart above.
- Required: Only in the scope of the redirects specified
- $VERSION
- Description: The protocol version.
- Required, Redirect: 1 and 3
- Format: <major>.<minor>
- Default field: ver
- Example: 2.1
- $ID
- Description: The ID which identifies the client. This is a random token.
- Required, Redirect: 1 and 3
- Format: 16 bytes in base64Url, 22 chars
- Default field: id
- Example: 7yXYL…1LlCw
- $ACTION
- Description: The action should be triggered. Redirect 1 is auth, Redirect 3 is cbk. Maybe gets extented in the future
- Required, Redirect: 1 and 3
- Format: Enum auth (1), cbk (3)
- Default field: ac
- Example: auth
- $IP
- Description: IP address of this client
- Optional, Redirect: 1
- Format: X.X.X.X
- Default field: ip
- Example: 172.29.0.15
- $MAC
- Description: MAC address of this client
- Optional, Redirect: 1
- Format: MAC address without colons, lowercase, 12 chars
- Default field: ma
- Example: 00359ac076c4
- $VLAN
- Description: VLAN-ID of this client or an empty string if this IACBOX has no VLANs configured. If the IACBOX runs in routing mode and you prefer the routing match, then you will get the route ID instead of the VLAN ID.
- Optional, Redirect: 1
- Format: 0-4096
- Default field: vl
- Example: 17
- $REGNR
- Description: The registration number of this IACBOX if more than on box calls your server
- Optional, Redirect: 1 and 3
- Format: Version Nr with 10 chars
- Default field: iac
- Example: 2014112233
- $USERSONL
- Description: Users online
- Optional, Redirect: 1
- Format: Number: 0-99999
- Default field: uo
- Example: 527
- Since: Version 1.1
- $USERSONLPERC
- Description: Users online as percentage (rounded to integers)
- Optional, Redirect: 1
- Format: Number: 0-100
- Default field: uop
- Example: 53
- Since: Version 1.1
- $MAXUSERS
- Description: A voluntary max. value. Usually the same value as LICUSERS. 0 < MAXUSERS <= LICUSERS
- Optional, Redirect: 1
- Format: Number: 10-99999
- Default field: mu
- Example: 800
- Since: Version 1.1
- $LICUSERS
- Description: Max. users defined in the license. Note: unlimited = 99999
- Optional, Redirect: 1
- Format: Number 10-99999
- Default field: lu
- Example: 1000
- Since: Version 1.1
- $RC
- Description: The return code that represents the state of this request. See all possible states below.
- Required, Redirect: 3
- Format: 1-4 digits state code
- Default field: rc
- Example: 0
- $ERROR
- Description: The error-message if the $STATE indicates an error
- Optional, Redirect: 3
- Format: Error message as text (translated if possible)
- Default field: err
- Example: Wrong username or password.
- $USERURL
- Description: The URL the user wanted to get before s/he got redirected to the lofin page. This is no always reliable especially for HTTPS URLs. Try to keep this at the end as it can get long.
- Optional, Redirect: 1
- Format: URL
- Default field: userurl
- Example: http://example.com
Incoming redirects (ext or loc. Webserver/IACBOX)¶
Incoming redirects to logon/authenticate a client need this parameters:
- lapi
- Description: The data fields (optionally encrypted)
- Required
- Format: Base64Url encoded
- si
- Description: Signature of the value sent in lapi
- Required
- Format: Base64Url encoded
Example with our default domain name - the parameters have to be that way:
Data fields¶
The data which is send between the IACBOX and your server is packed and encrypted/encoded
in the lapi URLParameter. The fields are ; (semicolon) separated key=value pairs in the
format: key1=value1;key2=value2;key3=value3;...
Ensure that you cut out all possible semicolons from the data fields!
- ver
- Description: The protocol version
- Required
- Format: <major>.<minor>
- id
- Description: The ID which identifies the client. Just send it the way you received it
- Required
- Format: 16 bytes in base64Url, 22 Chars
- ac
- Description: The action that should be triggered. Usually you use logon for all login related things. Since version2 there’s also a refresh (ref) action if you lost the client session and have to recover it with a refresh cycle.
- Required
- Format: Enum: logon, ref
- type
- Description: The type of authentication that was/should be used. In case of to and free you have done the authentication on the server yourself and tell the IACBOX it should simply take this client online without any further checks or are using the free logon service. In every other case the IACBOX does the authentication and you have to pass username and password or a template id.
- Required
- Format: Enum:
- to = Take online
- cred = Credentials - user/pwd logon
- pms = for PMS logons
- free = free logon
- create = template id
- lang
- The ISO language code which is used to translate the login error/success messages. This error messages are translated into many languages. Have a look at Client Logon/Terms of Use for a list of available languages.
- Required
- Format: 2 char language code like en, de, fr, it
- user
- Description: If the IACBOX does the authentication (type is not to) this is mandatory.
- Required
- Format: String
- pwd
- Description: If the IACBOX does the authentication (type is not to) this is mandatory.
- Required
- Format: String
- desc
- A custom text set as description of the generated ticket
- Required
- Format: String
- Since: Version 1.3
- userurl
- Description: If you use no final callback and the IACBOX should redirect the user to his/her original wanted URL. Only for successful logins.
- Required
- Format: URL
- ref
- Description: Used only for action ref. This can be a custom ID if you need to support a mapping of a returning refresh call to a certain sub page. See chapter Recover from lost session
- Required
- Format: String
Ticket overrides¶
You may also append these data fields which override values of the ticket template
- otc
- Description: Time credit
- Format: Number of seconds
- otl
- Description: Time limit
- Format: Number of MB
- omi
- Description: Max idle timeout
- Format: Number of seconds
- oep
- Description: Expiration persiod - just use time()+seconds to get an absolute timestamp
- Format: Unix timestamp, Number of seconds
- odl
- Description: Max download bandwidth (max value is the total download bandwidth under System/Network)
- Format: Number of kBit/s
- oul
- Description: Max upload bandwidth (max value is the total upload bandwidth under System/Network)
- Format: Number of kBit/s
- ode
- Description: Custom ticket description - useful if you want to add an external ID which can be used to search later for this ticket
- Format: String
PMS Logon¶
Communication flow - PMS version¶
- The client is in state offline and wants to show an arbitrary page.
- The IACBOX catches this connection, creates a new unique ID for this client and sends an HTTP 302 redirect to the client. The redirect URL consists of the specified external landing page and additional fields like IP/MACaddress, Vlan ID, …
- The client calls the redirect (1) URL on the external webserver.
- On your webserver a session has to be created to remember the client ID for this browser. The webserver responses with the login page (and the session cookie).
- The enduser fills out the login form and submits the form. An AJAX call via HTTP POST is send to the webserver with the login data.
- The IACBOX verifys the user data (roomnumber, name, PIN, …) by checking the PMS. If the user already has a valid ticket the success state online is send as response. In the normal offline state all ticket templates visible to this user (depending on optional configured VLANs) are returned as JSON structure. If there is only one free template and skipfreetemplates is active in the PMS configuration then the client is online rigth now. In any case starting with API version 1.3 there now can be additional PMS fields passed encrypted.
- If additional PMS data was sent the client browser now does an AJAX call to your webserver with the encrypted PMS data. Edit the Javascript if you don’t want that.
- Depending on the business logic on the server side there is now a chance to individualize the logon page by sending arbitrary data back which has to be interpreted by the Javascript (eg. Show the name or the roomnumber of this guest).
- If a template selection has to be made, the user now selects a ticket template which is send again as AJAX request to the IACBOX which tries to set this client online.
- The success/error state is returned as JSON response. The page can now shown the success/error message.
Please note the PMS system in local mode is handled completely different, because it does not need any javascript code.
Incoming AJAX requests (Browser -> IACBOX external only)¶
The external PMS version uses no incoming redirects like the normal version. It uses AJAX requests from the client browser which need the parameters below. Please note that because of a crossdomain situation here we have to use a JSONP call, which has to be an HTTP GET call.
Since version 2.1 we also support the PMS systems Himed and ASAj.
- lapi
- Description: JSON data
- Required
- Format: JSON string as POST data
- callback
- Description: Has to be dataCBK for the SDK to work
- Required
- Format: String
- userid
- Description: The Login-Api Id
- Required
- Format: 16 bytes in base64URL, 22 chars
- tt_id
- Description: The selected ticket template Id
- Required
- Format: Number
- pms_room
- Description: Room number
- Required
- Format: String
- pms_himed_room
- Description: Room number for the PMS Himed
- Required for the PMS Himed
- Format: String
- pms_name
- Description: Room number
- Required
- Format: String
- pms_fname
- Description: First name needed for PMS ASAj
- Required for the PMS ASAj
- Format: String
- pms_lname
- Description: Last name needed for PMS ASAj
- Required for the PMS ASAj
- Format: String
- pms_pin
- Description: Pin
- Optional
- Format: String
- pms_arrivalday
- Description: Arrival day
- Optional
- Format: String DD.MM.YYYY
- pms_departureday
- Description: Departure day
- Optional
- Format: String DD.MM.YYYY
- pms_birthday
- Description: Birthday
- Optional
- Format: String DD.MM.YYYY
Example with our default domain name - the parameters have to be that way:
JSON answer with the ticket templates
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | {
"rc" : 0,
"state" : "tsel",
"tt" : [
{
"id" : 435,
"name" : "Free Access",
"price" : "0.00 EUR",
"txttyp" : "Ticket Type: Flat Rate",
"lifetime" : "Time credit: 30 Minutes",
"expires" : "Expires: 1 Days",
"bw_out" : "Max. upload bandwidth: 512 kBit/s",
"bw_in" : "Max. download bandwidth: 1024 kBit/s",
"session_limit" : "Session Limit: 2000 MB"
},
{
"id" : 174,
"name" : "Premium Speed",
...
}
],
"pms" : "0Wdhuvpa...ufuPpn",
"pms_si" : "bGcpGgRt...diKAtY"
}
|
The strings in the example above are available in over 20 languages and get translated into the browser language.
Returning PMS data¶
Please note that this feature is only supported with certain PMS types (All FIAS based protocols like Fidelio, Protel). Some fields maybe also have different values with different PMS types (like VIP).
The PMS fields pms and pms_si (= HMAC signature of the encrypted pms field) are optional if configured in the login API settings. The javascript sends these fields to your webserver where the data can be decrypted and processed. The response can trigger custom visual changes on the logon page to react on the current user.
Possible data fields¶
- id
- Description: Id ffrom PMS
- names
- Description: First- and lastname
- Response field names:
- fname (first name)
- lname (last name)
- room
- Description: Room number
- adate
- Description: Arrival day
- ddate
- Description: Departure Day
- bdate
- Description: Birthday
- vip
- Description: VIP group name(s)
Below there’s a JSON answer if the client is online. This can be already the answer after the user sent the PMS data if there is still a valid ticket for this user or there is only one free ticket template active with enabled skipfreetemplates option in the PMS configuration. The PMS fields are only added if no ticket template selection was needed.
1 2 3 4 5 6 | {
"rc" : 0,
"state" : "online",
"pms" : "0Wdhuvpa...ufuPpn",
"pms_si" : "bGcpGgRt...diKAtY"
}
|
Recover from lost state/session¶
If you have pages/services a customer can reach when s/he is already online you will have the problem that the session is most propably lost - you can’t identify the client any more. This is the case because nowadays nearly all OS use a captive browser to do the authentication and so the session cookie is only available in this browser. If the user now comes back to your landing page with the normal browser the cookie is not there and so you don’t have the device info like MAC, IP, VLAN aso. To recover this information we provide a so called refresh call which are technically two redirects one to the IACBOX and the second back to the LoginAPI code including the missing device information. Just redirect the user to this URL (adapt the domain if you have a custom domain):
https://hotspot.internet-for-guests.com/logon/cgi/index.cgi?lapi=ref&ref=<refid>
Replace <refid> with 1 if you don’t need it or use a refresh ID that is used in a mapping.
Refresh ID mappings¶
On an incoming refresh call from the IACBOX the LoginAPI request router does not know anything what to do with this call and will show the normal login page. So if you want to show another page you will need a mapping in main.config like that (without the brackets < and >):
refreshidmapping = <refid>:<targetpage.php>
General information¶
URL length¶
Please remember that the URLs should be as short as possible. The IACBOX proxy can handle URLs with a total length up to 8000 chars. This is also the reason why we use Base64 encoding for the data fields to have the smallest encoding overhead possible.
Possible States¶
All non 0 states are errors.
State | Description |
---|---|
0 | OK request successfully processed |
1-9998 | Error codes - please have a look at our SDK for all possible values. |
9999 | General/unknown error |
Base64 URL safe encoding¶
We use base64Url (See [1]) as encoding at different places including URLs to save as much space as possible. Base64Url is the same as Base64 except that character 62 (plus +) and 63 (slash /) are replaced with the URL safe characters - (minus/dash) and _ (underscore). Decoding works the inverse way. See [2] for the whole alphabet. In addition to that the padding is truncated after encoding (all = chars at the end are removed) and gets appended to the string before the Base64 decoding is done (pad = until the string length is a multiple of 4). Please have a look at the SDK for a sample implementation in PHP.
User URL¶
User URL is the URL the user wanted to see before s/he was redirected to your login page (Step 1). If you want the user to be redirected to this page after a successful logon add the needed placeholder $USERURL to your login URL. Depending on if you have configsample_logonpage_viewured a final callback after the logon on side of the IACBOX (Step 8) the redirect has to be done at different places.
- If you want a final callback you have to do the redirect yourself (the PHPSDK includes this functionality already)
- If no callback is used, the IACBOX does the redirect if the data field userurl is provided.
Security¶
- It’s recommeded to use encryption. The URL parameter (lapi) which holds the data fields is encrypted and so is neither read nor changeable for the user or an attacker in between.
- But also if encryption is not used, all URLs have to be signed with a HMAC so both sides can trust the calls.
- It’s also recommended that your logonpage uses SSL/TLS to protect the communication, especially in wireless networks.
HMAC signature¶
Because the communication between the IACBOX and the external webserver is achieved by URL redirects we have to be sure that the data fields can’t be manipulated. To do so the data fields (content of the lapi parameter) of every call in each direction are signed with a HMAC signature. Compared to just hashing a key and the message a HMAC hash is safe against a lengthextension attack which easily allows you to create a valid MAC with different content.
In the current version this is a HMAC SHA256 (See [3]) encoded as Base64Url. The shared secret used for this HMAC is set in the configuration and has to be identical on the IACBOX and your webserver. For further informations see [4] and [5].
Salted keys for unencrypted communication¶
Attention
Attention - this is an incompatible change of version 2.x! In version 1.x no salt was added to the HMACs.
- If you use encryption then the key of the HMAC is not salted, because the encryption adds a salt anyway - so with encryption the HMAC is the same as in version 1.x.
- If you don’t use encryption starting with version 2.x you have to salt the key used for HMAC generation to get a different signature also if the clear text is the same. The salt gets prepended to the resulting HMAC and separated with a dollar $ like
<salt-b64>$<hmac-b64>
. Use 8 random bytes as salt which are base64Url encoded.HMAC = base64url(hmac_sha256(cleartxt, salt+secret))
Used shared secret:
v09q5JFPZCv_nwMRyKsRWtDS9JtFghzR
Clear text:
ver=2.1;id=dZDzvCrCdz2MxsN2GqlMtw;ac=auth;ip=172.29.0.1;ma=8fa72685eb68;vl=0;iac=2016010103
Salt Base64Url encoded:
V1fhYVxaj5w
HMAC with prepended salt Base64Url encoded:
V1fhYVxaj5w$boR-6lCDj1QXkIweZzoaGoA2PyCe8kQjyCipnTSyj0Q
Encryption¶
It’s recommeded to encrypt the URL parameters, especially if you transmit user credentials or PMS data to the IACBOX. In our SDK for PHP the encryption code is fully implemented and you simply have to turn it on (default).
If you develop the client code yourself use this settings:
- Algorithm is AES-256 in CBC mode (See [6])
- As key use
SHA256(sharedsecret)
what ensures the needed keylength of 32 bytes - Use 16 random bytes as IV (initialisation vector/salt) which have to be prepended to the encrypted text.
- PKCS7 Padding is used
- Encode the result with Base64Url
encrypted = base64url( IV + AES256(datafields) )
Implementation tests¶
Clear text used for the examples below:
ver=2.1;id=dZDzvCrCdz2MxsN2GqlMtw;ac=auth;ip=172.29.0.1;ma=8fa72685eb68;vl=0;iac=2016010103
Used shared secret:
v09q5JFPZCv_nwMRyKsRWtDS9JtFghzR
The result of every encryption (of the same text) is different because of the used IV/salt. Here are the 16 bytes Base64Url encoded used for the encryption and HMAC below:
hELE1zweeT2yT1JVLQ8auQ
Expected AES256 encryption incl. prepended IV (Base64Url encoded):
hELE1zweeT2yT1JVLQ8auQkn_CXQVEBj4SPEes0a8PDa0F2bU6-JFtH_SNAYJQb-Zd-RqGzvMIk
UbhhrU5Ll78h_UbDv4PfRVD5N5I37anPXvAi7__fO3yJ_ISFc3qf6baYjVx-cqZdlP36o6ODAGw
HMAC of the Base64Url encoded string:
kbihE5UaIIiT2q4P65qPfNUpw5cVtyZDxZKIiLFGb8E
Things to consider, common pitfalls¶
- You will get multiple requests per client to your webserver and some of them origin from all kinds of software or mobile apps operating on port 80 or 443, so don’t underestimate the number of requests to your server. Because of this it’s wise to avoid a heavy loaded login page with lots of images and other elements. You can show more advanced content on the final callback page if the client was successfully set online.
- Because all images, javascripts and possible iFrames included in your login page are loaded by the client browser (which is still in offline state) have to either come from your webserver with the same hostname or this URLs have to be whitelisted in the “Hidden Free to Use” section as well. Note, that whitelisting works only for assets with static URLs and will not work properly for web services of big companies with CDN (content delivery networks) like google (googleanalytics), facebook, twitter, aso. where the same domain name resolves to different IP addresses very quickly. This is especially a problem with javascript widgets (twitter, …) and user tracking tools like google analytics. You can have rich content on the final callback page where the client is in online state.
- Avoid URL rewriting for the login page at your webserver since this results again in HTTP 302 redirects which multiplies the problem of getting too many unwanted connections.
- Check your session timeout at your server - it should have a resonable value > 20min and < 3h.
- Consider some kind of load balancing or failover setup at your webserver to avoid downtime. When your webserver is not reachable, nobody can login.
Testing¶
Keep in mind that while your’re testing your implementation and you login/logoff frequently you have to revoke your ticket each time otherwise you will not see the login page again and the IACBOX will not apply new values like ticket overrides, etc..
Use non HTTPS URLs for testing because TLS traffic is handled completely different and will not even work if HTTPS redirects in offline state are disabled.
Monitoring¶
The IACBOX comes with builtin monitoring which you should use to monitor your external webserver. This tells you if your landing page is reachable or not.
Navigate to System/Monitoring, activate it if needed and add a New Device. As host define
the domain of your webserver. Then click on the edit icon on the right and click on the tab
Checks and add one with New. As Test Type select HTTP(S) and save.
You can append the path if you want to check the landing page instead of the host only by
adding the parameter -u /path/to/index.php?ping=1
.
The parameter ?ping=1
is only useful if you use our SDK because the script exits very early, causes least possible load and
does not pollute the log with errors.
If you want to get an email notification or a rsyslog message to your remote syslog server you
can configure that too. Navigate to System/Notifications and add the following line to the large text field:
ACCEPT " MONITORING STATE " my.name@example.com
With a rsylog server:
ACCEPT " MONITORING STATE " my.name@example.com rsyslog.example.com:514