Mobile One Time Passwords

Mobile-OTP

strong, two-factor authentication with mobile phones

Standard phone and BlackBerry (J2ME) iPhone Google Android Windows Phone 7 PalmOS webOS Maemo Openmoko Universal Web App Windows Linux MacOS

SourceForge.net Logo

last update of this site: December 20th, 2014

News

(2014-12-20): Andreas Albang ported the verify function to C# (see Add-Ons section)
(2014-08-12): Mac OS token by Tom Early (see Links)
(2014-08-09): TOKEN2 - simple 2-factor authentication for web sites with Mobile-OTP support (see Links)
(2014-07-05): privacyIDEA - new authentication server with Mobile-OTP support (see Links)
(2014-05-17): mysql-motp - authentication function for MySQL (see Links)
(2014-04-27): QR code based provisioning - URI format and sample Android token app at Emin's site (see Links)
(2014-02-02): openvpn-otp - an OpenVPN plugin with Mobile-OTP support (see Links)
(2013-09-10): mOTP-CP - a Windows Credential Provider (CP) with Mobile-OTP support (see Links)
(2013-09-10): multiOTP version 4.0.7 released (see Links)
(2013-03-14): WgOTP - Mobile-OTP token client for Windows 7/XP (see Links)
(2013-01-19): motppasstore - an online password store with OTP protection (see Links)
(2012-11-01): Potato - a smart and free Mobile-OTP authentication server with in-LAN self-enrollment for users in AD (see Add-Ons)
(2012-11-01): M.ID Server by Swiss SafeLab supports Mobile-OTP (see Links)
(2012-10-03): Mobile-OTP extension for Firefox (see Links)
(2012-08-11): Yamotp - new Mobile-OTP client for Windows Phone 7.5 (see Links section)
(2012-02-29): Citrix and Mobile-OTP (see Links)
(2012-02-17): motpy - Modular Python script for PAM by Gyuris Szabolcs (see Links)
(2012-02-04): Mobile-OTP plug-in for WEB2PY released (see Links)
(2012-01-14): Mobile-OTP client in html5 by Marilen Corciovei (see Links section)
(2011-11-14): Mobile-OTP client for .NET (Windows or Mono) by Lester Hightower (see Links section)
(2011-11-08): Mobile-OTP client for Windows by Frank Brandner (see Links section)
(2011-09-12): pam_cookie by Sean Whitbeck (see Links section)
(2011-06-05): motp7 by Bjoern Brunner is a new Mobile-OTP client for Windows Phone 7 (see Links section)
(2011-06-04): Web-based, universal Mobile-OTP token client that runs on any Internet device with Javascript (see Add-Ons section)
(2011-06-02): Swiss online payment provider SwiKey SA implements Mobile-OTP (see Links section)
(2011-05-28): Edel donated a server side alternative to otpverify.sh in Python (see Add-Ons section)
(2011-03-31): SQL to authenticate users with PostgreSQL in Add-Ons section
(2011-03-27): Two more Mobile-OTP clients (for Linux and Mac OS X) (see Links section)
(2011-02-04): Mobile-OTP client for Maemo (Nokia N900) (see Links section)
(2011-02-04): RPMs for the PAM module, including script for user management (see Add-Ons section)
(2011-01-20): Mobile-OTP implemented in Ruby (see Links section)
(2011-01-15): Simon Langley submitted a bash version of the otpverify.sh script (Downloads)
Click for older news

Index

  1. Index
  2. Introduction
  3. Downloads
  4. Installation
  5. FAQ
  6. Limitations
  7. Add-Ons
  8. Links
  9. Email Contact

Introduction

Using static passwords for authentication, as it is commonly done, has quite a few security drawbacks: passwords can be guessed, forgotten, written down and stolen, eavesdropped or deliberately being told to other people.
A better, more secure way of authentication is the so called "two-factor" or "strong authentication" based on one time passwords. Instead of authenticating with a simple password, each user carries a device ("token") to generate passwords that are valid only one time. Commercially available tokens look like pocket calculators or key fobs with a display and a keypad. To generate a one time password, the user has to enter his personal PIN into the device. So the authentication is based on two factors: the token device and a PIN ("something you have and something you know"). This is obviously more secure than just a password, as an attacker needs to get hold of both the PIN as well as the token device. In addition, eavesdropping on a password that is valid only one time, is of no use to the attacker.
On the other hand, the drawback of strong authentication is, that every user has to be provided with a token device. This can be quite expensive. Fortunately mobile phones that are capable of running java applets are becoming more and more widely spread. It stands to reason to use your mobile phone as an authentication token ...

Mobile-OTP is a free "strong authentication" solution for java capable mobile devices like phones or PDAs. The solution is based on time synchronous one time passwords. It consists of a client component (a J2ME MIDlet) and a server component (a unix shell script). The server component can easily be plugged into free RADIUS servers like XTRadius to authenticate users at routers, firewalls, web servers, access points, unix machines, etc.
The shell script should run without modification on any BSD-Unix or Linux. The java MIDlet should be compatible to any java enabled mobile phone (Nokia, Siemens, Motorola, Sony, BlackBerry, etc.).
The MIDlet, server-script and RADIUS server are freely available under the terms of GPL.

Mobile-OTP was introduced in 2003. As of 2012 there are more than 40 independent implementations of the Mobile-OTP algorithm making it a de facto standard for strong mobile authentication. See Add-Ons and Links for various contributions to the project.

How it's done

The MIDlet generates one time passwords by hashing the following data with MD5:
  1. the current epoch-time in a 10 second granularity
  2. the 4-digit PIN that a user enters
  3. a 16-hex-digit secret that has been created when the device was initialized
When entering a PIN, the MIDlet displays the first 6 digits of the MD5-hash. This is the one time password. The password can be verified by the server, as the server also knows the current time, Init-Secret and PIN of the user. To compensate time differences, the server will accept passwords from 3 minutes in the past to 3 minutes in the future. In addition, different time offsets can be specified for each user on the token and/or the server. Each password will be accepted only once. After 8 successive failed authentication attempts a user gets locked out.
Authentication is based on two factors: a PIN known by the user and the Init-Secret stored on the mobile device.


Downloads

On the client side you will need the java MIDlet:

  • Version 1.07: MobileOTP.jar and MobileOTP.jad - Old version 1.061 jad and source

    On the server side you will need the shell script:

  • otpverify.sh version 1.04: for ksh / for bash.

    You should also download the RADIUS server found at XTRadius (FreeRADIUS is also possible, see below).

    There are also token clients for iPhone, Android, PalmOS and Openmoko in the Add-Ons and Links sections.

    OTA install

    Just open http://motp.sf.net/MobileOTP.jad in your phone's WAP-browser.

    The MIDlet is also available for direct download at www.getjar.com.
    Just enter 2990 at their WAP-Download-Page.

    Source

    You can also compile the java MIDlet yourself. Here is the source: MobileOTP.java. You will also need the MD5 implementation in java by Santeri Paavolainen MD5.java.


    Installation

    This section describes the installation and configuration of the MIDlet and the server. Installation of the MIDlet is straight forward. Installation of the server takes a little bit more time but can be done in under an hour.

    Client-Installation (token)

    Load the MIDlet on the devices you plan to use. Installation of the .jar and .jad file is vendor specific. Usually java enabled phones come with some kind of application installer for PCs that allows to install MIDlets over IrDA or serial cable.
    When the MIDlet is installed, run it. You can enter PINs to generate one time passwords, but to use them you will need to initialize the device first and write the Init-Secret into the appropriate user-record on the authentication server.
    To initialize the token, press 0000. Enter an arbitrary sequence of 25 keys as a random seed. The Init-Secret that will be shown is not to be written down anywhere else but the server itself. You cannot display it again. If you press 0000 any time later, the initialization string will change, i.e. the device will be re-initialized. The initialization of a device should always be done by the administrator of the authentication server, not the user himself. A user does not need to know the Init-Secret.

    Server-Installation (authentication server)

    This section describes how to install XTRadius with otpverify.sh. The result is a RADIUS server that supports strong authentication with Mobile-OTP tokens.
    Back in 2003 this was the original server implementation. As of today there are many alternatives. You might want to look at the Mobile-OTP Authentication Server (MOTP-AS) or the Mobile-OTP PAM module. Both can be found in the Add-Ons section.

    To install and configure your authentication server, take the following steps:

    1. Copy the otpverify.sh-script to /usr/local/bin and make it executable by chmod'ing it to +x
    2. The script needs to have read/write access rights on /var/motp. Running it as root will make sure of this.
    3. try to run it. It should report: USAGE: otpverify.sh Username, OTP, Init-Secret, PIN, Offset
    4. run it again, this time supplying 5 arguments: otpverify.sh 1 2 3 4 5
      it should return: FAIL
    5. initialize a token. Write down the Init-Secret. Generate a one time password by entering 5555 on the token. Try to verify this password by running "otpverify.sh testuser {password} {Init-Secret} 5555 0"
    6. The script should return "ACCEPT". If it returns "FAIL", the clocks of server and token might differ. Take a look at the FAQ section.
    7. As soon as you successfully authenticated a user, you should continue by installing the XTRadius-server. Keep to the instructions provided at XTRadius.
    8. After the installation of the RADIUS server there are only 4 configuration-files to modify in /etc/raddb
    9. Add a new dictionary file to /etc/raddb. It is called dictionary.motp and contains three new RADIUS-attributes: Secret, PIN and Offset. You can download the file here.
    10. Add a line "$INCLUDE dictionary.motp" to /etc/raddb/dictionary, so that the new dictionary file will be loaded at server start up.
    11. Add 3 macros to /etc/raddb/execparams or replace it by this file.
    12. To create a /etc/raddb/users file containing your users, stick to this sample file: users. You can add further RADIUS attributes to each user entry, of course.
    13. You are all set. Start the RADIUS server in debug-mode (radiusd -sxxy) and test the authentication with the "radtest" client provided with the RADIUS server.
    FreeRADIUS instead of XTRadius
    Thanks to a tip by Piotr Zazakowny it is also possibe to integrate the otpverify.sh-script with FreeRADIUS instead of the (old but working) XTRadius.
    Please take a look at this example user record for the /etc/raddb/users file.
    Jim Burrill provided us with a small How-To.

    Important security information for the use with FreeRADIUS:
    Please be aware that FreeRADIUS interprets the exit codes of otpverify.sh differently as intended:
    otpverify.sh returns exit codes from "0" to "7". Exit codes other than "0" are failure codes. Exit code "3" signals that authentication failed because the user has been locked. Unfortunately FreeRADIUS interprets "3" as "authentication accepted". It is therefore necessary to change the exit codes in otpverify.sh to something not in conflict with FreeRADIUS. Exit code "0" is still good for a successful authentication. Codes above "10" are safe to use for all failures (so change "exit 3" to "exit 13" in otpverify.sh (and so on)).


    FAQ

    How to test if authentication works?

    Before including the otpverify.sh-script into the RADIUS server, test it on the command-line:

    1. Make sure that the otpverify.sh-script has read/write-access to /var/motp
    2. Initialize a token by pressing "0000"
    3. Write down the generated Init-Secret, e.g. 7ac61d4736f51a2b
    4. Generate a one time password by entering a PIN, e.g. PIN=5555, result: af6543
    5. Verify the one time password with the otpverify.sh-script: "otpverify.sh test af6543 7ac61d4736f51a2b 5555 0"
    6. The script should return "ACCEPT". If it returns "FAIL" there might be a time difference between the token and the server. See How to synchronize server clock and token clock?
    7. After successful authentication, try to authenticate with the same OTP again. It should fail, as a lock-file named "af65a3" has been touched in /var/motp/cache

    How to synchronize server clock and token clock?

    Both server and token base their time calculations on the unix epoch time (which is based on UTC), so theoretically any token should be always in sync with the server. Unfortunately some mobile phone devices do not know which time zone they are in, so there might be in fact a difference of several hours between server and token clock.

    To find out the offset between a token and the server, do the following:

    1. Access the "Info"-screen on the token, write down the 9-digit number under "Epoch-Time"
    2. Enter "date +%s" on the server to display the current time in epoch notation. Write down the first 9 digits of the output.
    3. Subtract both values. The result is the offset in 10s of seconds, i.e. an hour would be 360, two hours 720, etc.
    4. The offset has to be configured in the "users" file of the RADIUS server for the specific user (Offset-Attribute).
    5. Since version 1.05 there is the ability to alternatively set the time zone on the token itself as an offset in hours from UTC. So a user traveling to New York City would set the time zone on his Nokia phone to UTC-5 and change it back to UTC+1 when coming back to Berlin. The Offset configured for this user on the RADIUS server would be 0 at all times.
    6. You can verify authentication on the command-line by "otpverify.sh test {OTP} {Init-Secret} {PIN} {offset}"

    How to trouble-shoot authentication on the RADIUS server?

    After configuring the RADIUS server for external authentication through the otpverify.sh-script, you can start the RADIUS server in debug-mode by entering "radiusd -sxxy" and try to authenticate users. Use the "radtest" program for local debugging, that comes with the XTRadius distribution.

    1. If authentication fails with a script-return-code of "1", make sure that PIN, Init-Secret and offset are correct. It is most likely that you have to configure an offset other than "0" for this user. See How to synchronize server clock and token clock? for details.
    2. If the script returns "3", the account of this user has been locked as there have been 8 or more failed authentication attempts by this user. Delete the corresponding file in /var/motp/users to unlock the user account again.
    3. A return code of "4" says that the otpverify.sh-script has not been called with 5 arguments. Check the configuration of the external authentication in the "users"-file of the RADIUS server.
    4. A return code of "5" states that the specified password has already been used. Generate a new one time password and try to authenticate again.
    5. A return code of "6" indicates that you do not have "md5" or "md5sum" installed on your system.
    6. A return code of "7" is returned if the otpverify.sh cannot access the /var/motp directory to write a file.


    Limitations

    The following limitations apply to Mobile-OTP. Not all of them are Mobile-OTP specific but are also inherent to commercial solutions.
    1. PINs and Init-Secrets are stored in clear text on the RADIUS server. It is hence obligatory to keep the server safe from unwanted access. This also applies to the log file of the RADIUS server /var/log/radius.log, that can contain authentication data.
    2. Mobile-OTP is based on a function of PIN x Init-Secret —> OTP. It is obvious, that anyone who has access to the Init-Secret and the PIN can authenticate with it. Neither PIN nor Init-Secret nor a thousand known one time passwords alone will let an attacker find both Init-Secret and PIN. If an attacker gains knowledge of either PIN or Init-Secret and one or more one time passwords, this information can be used in a brute-force attack that might be successful. As Mobile-OTP is an open software, there is no way around that. Increasing the number of digits in the PIN (a 16 digit Init-Secret is quite safe) would make a brute-force attack more difficult, but it would not be convenient for users to remember and type in a 10 digit PIN.
    3. For devices that do not take time zones and daylight-savings-time into account when doing their epoch-time calculations, it might be necessary to manually adjust the Offset-attribute in the user record on the RADIUS server or alternatively one the token itself. For devices that are aware of time zones and daylight-saving-times, server-clock and token-clock should always be in sync.
    4. MD5 is not a limitation - Mobile-OTP would not be any safer with any different hash algorithm. Even if we used SHA2, which is less readily available than MD5, an attack on Mobile-OTP would be equally (but not more) difficult. An attack would need to involve several sniffed one-time-passwords and a brute force attack on PIN and secret. The complexity of this brute-force attack depends on secret and PIN size rather than the chosen hash algorithm. I dare anyone, including the NSA, to brute-force a 16 character secret plus PIN (78 bits). If still in doubt, choose a Mobile-OTP implementation that allows for a 32 character secret (142 bits complexity, including PIN) and read this elaboration.


    Add-Ons

    Server-Side

  • Mobile-OTP Authentication Server (MOTP-AS) by Sebastian Korff and Adrian Huryn.

    Full blown RADIUS server specifically for Mobile-OTP. Features include:
    - authenticating users by RADIUS (and optionally PAM or Apache)
    - SQL database for user/device configuration
    - Administration Web Interface (for admins and users)

    Download it at github.
    Visit the demo site at http://security.edu.pl/motp-as/ to get a picture (but be nice, please).
    Static credentials are user:"admin" and password:"motp".

  • Potato - Mobile-OTP Authentication Server with AD based self-enrollment by Markus Berg.

    Potato is an authentication server integrated with Freeradius and Active Directory.
    It comes with a user-friendly front-end allowing users to register their own tokens (while at the office).
    Users enroll their tokens once while at the office and can automatically use them later for remote access.
    Enrollment can be done entirely without involvement of an administrator. Potato is currently used in a productive environment with 500 users.
    More information, documentation, and source code is available here: http://kelvin.nu/software/potato/
    There is also a demo site here:Potato demo

  • Mobile-OTP PAM module for Unix system access

    Sebastian Korff wrote a PAM module for Linux and Solaris that can be used for login authentication locally without a RADIUS server. You do not even need otpverify.sh. The package includes the complete server components. You can download it here. Use this PAM module to authenticate users for Unix shell access (typically via SSH). Thanks go to Per Dalgas Jakobsen for contributing to version 0.4 and to Adrian Huryn for 0.5 (see CHANGELOG for details).

    To simplify server integration, Vaidas Jablonskis provided us with RPMs (source, i386, x86_64) for the pam_mobile_otp module, including "motp-manager", a shell script to simplify user management.

  • Mobile-OTP with PAM-script

    As an alternative to a compiled PAM module you can also use PAM-script instead.
    Davidhai Gootvilig provided a script for Mobile-OTP.

    He also wrote a rlm_perl script to use with RADIUS.
    If you have difficulties getting it to work, take a look at Gyuris Szabolcs's modular Python script for PAM.

  • Mobile-OTP PAM module for Nokia IPSO

    Mobile-OTP is also available as a pre-compiled PAM-module for Nokia's IPSO operating system. Download the Nokia package here motp-0.2.tgz. It can be installed with 'newpkg' as any other Nokia package. Configuration can be done through the IPSO web interface Voyager!

  • Alternatives to the otpverify.sh-script

    Ralf Neumann donated a php function to authenticate Mobile-OTP tokens on web servers with PHP.
    Stanislav translated the php-version into Perl.
    Edel provided us with a Python version.
    Andreas Albang ported the code to C#.
    And thanks to Brendon D Allen there is also a version as an MS-SQL stored procedure.
    Marcus Kempe donated Mobile-OTP SQL code for PostgreSQL.

    Mind everyone that the Perl and php versions are not complete, as they do not verify if a password has already been used ...
    Thanks to K9Barry who modified the php-version to address this.

    André Liechti supplied us with an even more extended version, that plugs easily into FreeRADIUS (see description as well as security information for FreeRADIUS in section Installation).

  • Client-Side

  • Mobile-OTP port for PalmOS

    Anthony E provided us with a Mobile-OTP token client for PalmOS (new version 1.1).

  • Alternative Mobile-OTP midlet supporting multiple profiles for J2ME phones

    You can download and install an alternative J2ME midlet by Adam Kulagowski: jad jar src.

  • Mobile-OTP port for Google's Android

    After getting quite a lot of requests on this, I just had to write a native version for Android. It is not on the market but you can download it from here (point your phone's browser to http://motp.sf.net/Mobile-OTP.apk)
    To compile it yourself, you will need this source file and the xml-layout.

    You will also find two more Mobile-OTP for Android on the market, supporting multiple profiles (see Links).

  • Web-based Mobile-OTP token emulator

    To quickly test your server installations you can use this simple token emulator in javascript by Sebastian Korff.

  • Universal Mobile-OTP token as a Web App

    This is a Mobile-OTP token client that will run as a Web App on any device with a Javascript enabled browser and an Internet connection. It can be used to run on currently unsupported client devices (like phones with Windows Mobile/CE).
    To use it in a production environment, you should host the html-file on your own HTTPS based web server (as well as the file ./md5.js).
    Bookmark it in the web browsers of your client devices.
    The web app will store its personal secret in the cookie cache of the individual client device. This cookie will inevitably be sent to the web server, though (if not used offline). For this reason, the web server should be a trusted one and have HTTPS enabled.
    The devices will be (re-)initialized by entering a 20 digit random PIN.


  • Links

  • Mobile-OTP for DrayTek routers - Vigor 2955 routers natively support Mobile-OTP (watch video)
  • OpenID with Mobile-OTP - OpenID provider Clavid AG supports Mobile-OTP tokens. This enables free Mobile-OTP authentication for thousands of web sites (e.g. Facebook).
  • LinOTP - LinOTP by LSE supports Mobile-OTP tokens since v.2.0.1. There is also a commercial version with GUI: LinOTP Enterprise Edition and a demo site.
  • OpenOTP - OpenOTP supports Mobile-OTP tokens. It is a free, full blown authentication server with web based GUI and self service desk for users.
  • SwiKey SA - Swiss online payment provider with integrated Mobile-OTP authentication
  • M.ID Server - authentication server by Swiss SafeLab with Mobile-OTP support
  • privacyIDEA - authentication server spin-off from LinOTP with Mobile-OTP support
  • TOKEN2 - simple 2-factor authentication for web sites with Mobile-OTP support

    iPhone token clients

  • Mobile-OTP on iPhone - Thomas Lederer wrote a very nice iPhone token client (shake to initialize ...)
  • iOTP - Another version of Mobile-OTP on iPhone, supporting multiple profiles, by Gregor Ruttner
  • mobile otp By ASION IT-Services GmbH - Mobile-OTP for the iPhone with optional UDID security extension
  • CitrusOTP - Commercial version of Mobile-OTP for the iPhone by Citrus IT

    Android token clients

  • mOTP for Android - free Mobile-OTP with multiple profiles for Android on the market, by Miceli Bros.
  • DroidOTP for Android - Another nice and free Mobile-OTP client with multiple profiles for Android on the market.
  • mOTP token - mOTP token for Android in html5 with source.
  • Potato token - Mobile-OTP token for Android by Markus Berg - with source.

  • QR code token - Mobile-OTP token for Android with QR code based enrollment by Emin Huseynov.

    Windows Phone 7 token clients

  • (dead) MOTP Manager for Windows Phone 7 - A Mobile-OTP version for Windows Phone 7 ported by Dominic Wells.
  • motp7 by Bjoern Brunner - Another Mobile-OTP version for Windows Phone 7
  • Yamotp by Olle Westman - Mobile-OTP version for Windows Phone 7.5

    Palm token client

  • (dead) Mobile-OTP for webOS - Mobile-OTP compatible client for Palm Pre

    Maemo token client

  • otpn900 - Mobile-OTP compatible client for Maemo (Nokia N900)

    Windows/Linux/Mac token clients

  • Mobile-OTP token client for Windows - by Frank Brandner
  • WgOTP-Mobile - win32/win64 token client by Alexey Dobromyslov
  • mOTP4dotNet - Mobile-OTP token client for Windows and Mono

  • Mobile-OTP token client for Linux - with source for Linux/GTK-2 by Edgar Matzinger

  • Mobile-OTP token client for Mac OS - with source for Mac OS X 10.5+ by Edgar Matzinger
  • Mobile-OTP token client for Mac OS - by Tom Early

    Tokens for other platforms

  • html5 token - mOTP token in html5 with source.
  • Firefox extension - Mobile-OTP token for Mozilla's Firefox. source

    Other links

  • otp4neo - Mobile-OTP compatible client on Openmoko (in python/gtk) - site currently down

  • mOTP+ - Advanced Mobile-OTP MIDlet, hints and tips on www.freeauth.org

  • XTRadius - Free RADIUS Server with pluggable authentication
  • OSC Radiator RADIUS Server - RADIUS Server with native Mobile-OTP support since v4.6

  • multiOTP - A free LGPL PHP library and also a command line tool for Linux and for Windows to authenticate Mobile-OTP-Tokens. See white paper.
  • mOTP-CP - Credential Provider for Windows with multiOTP/Mobile-OTP support
  • mod-authn-otp - Apache module for one-time password authentication with Mobile-OTP support
  • DokuWiki plug-in - Mobile-OTP plug-in for DokuWiki
  • web2py-motp-auth - Mobile-OTP plug-in for WEB2PY
  • Soft token in Python - Mobile-OTP soft token in Python
  • Mobile-OTP in Ruby - Mobile-OTP for Ruby (and Rails) powered servers and client implementations
  • pam_cookie - PAM module to accept an OTP over a period of time, instead of just once. For websites.
  • motpy - modular Python script for PAM
  • motppasstore online password safe with OTP access by Emin Huseynov
  • openvpn-otp OpenVPN plugin with Mobile-OTP support by Evgeny Gridasov
  • mysql-motp authentication function for MySQL by Lars Timmann

  • Spring Security RADIUS Plugin and Mobile-OTP - RADIUS implementation for GRAILS
  • OpenVPN integration - Mobile-OTP with OpenVPN
  • Citrix XenApp and Mobile-OTP - Implementing two factor authentication with Citrix XenApp
  • Citrix Web Interface and Mobile-OTP - Citrix Web Interface 5.x in ASP/C#


    Email Contact

    For comments and suggestions send email to mobile-otp @web.de